OSDN Git Service

framework: add neon white list mechanism for applications installed with ABI2
[android-x86/frameworks-base.git] / services / 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 com.android.internal.util.ArrayUtils.appendInt;
27 import static com.android.internal.util.ArrayUtils.removeInt;
28 import static libcore.io.OsConstants.S_IRWXU;
29 import static libcore.io.OsConstants.S_IRGRP;
30 import static libcore.io.OsConstants.S_IXGRP;
31 import static libcore.io.OsConstants.S_IROTH;
32 import static libcore.io.OsConstants.S_IXOTH;
33
34 import com.android.internal.app.IMediaContainerService;
35 import com.android.internal.app.ResolverActivity;
36 import com.android.internal.content.NativeLibraryHelper;
37 import com.android.internal.content.PackageHelper;
38 import com.android.internal.util.FastXmlSerializer;
39 import com.android.internal.util.XmlUtils;
40 import com.android.server.DeviceStorageMonitorService;
41 import com.android.server.EventLogTags;
42 import com.android.server.IntentResolver;
43
44 import org.xmlpull.v1.XmlPullParser;
45 import org.xmlpull.v1.XmlPullParserException;
46 import org.xmlpull.v1.XmlSerializer;
47
48 import android.app.ActivityManager;
49 import android.app.ActivityManagerNative;
50 import android.app.IActivityManager;
51 import android.app.admin.IDevicePolicyManager;
52 import android.app.backup.IBackupManager;
53 import android.content.BroadcastReceiver;
54 import android.content.ComponentName;
55 import android.content.Context;
56 import android.content.IIntentReceiver;
57 import android.content.Intent;
58 import android.content.IntentFilter;
59 import android.content.IntentSender;
60 import android.content.ServiceConnection;
61 import android.content.IntentSender.SendIntentException;
62 import android.content.pm.ActivityInfo;
63 import android.content.pm.ApplicationInfo;
64 import android.content.pm.ContainerEncryptionParams;
65 import android.content.pm.FeatureInfo;
66 import android.content.pm.IPackageDataObserver;
67 import android.content.pm.IPackageDeleteObserver;
68 import android.content.pm.IPackageInstallObserver;
69 import android.content.pm.IPackageManager;
70 import android.content.pm.IPackageMoveObserver;
71 import android.content.pm.IPackageStatsObserver;
72 import android.content.pm.InstrumentationInfo;
73 import android.content.pm.PackageCleanItem;
74 import android.content.pm.PackageInfo;
75 import android.content.pm.PackageInfoLite;
76 import android.content.pm.PackageManager;
77 import android.content.pm.PackageParser;
78 import android.content.pm.PackageUserState;
79 import android.content.pm.PackageParser.ActivityIntentInfo;
80 import android.content.pm.PackageStats;
81 import android.content.pm.ParceledListSlice;
82 import android.content.pm.PermissionGroupInfo;
83 import android.content.pm.PermissionInfo;
84 import android.content.pm.ProviderInfo;
85 import android.content.pm.ResolveInfo;
86 import android.content.pm.ServiceInfo;
87 import android.content.pm.Signature;
88 import android.content.pm.ManifestDigest;
89 import android.content.pm.VerificationParams;
90 import android.content.pm.VerifierDeviceIdentity;
91 import android.content.pm.VerifierInfo;
92 import android.net.Uri;
93 import android.os.Binder;
94 import android.os.Build;
95 import android.os.Bundle;
96 import android.os.Environment;
97 import android.os.FileObserver;
98 import android.os.FileUtils;
99 import android.os.Handler;
100 import android.os.HandlerThread;
101 import android.os.IBinder;
102 import android.os.Looper;
103 import android.os.Message;
104 import android.os.Parcel;
105 import android.os.ParcelFileDescriptor;
106 import android.os.Process;
107 import android.os.RemoteException;
108 import android.os.SELinux;
109 import android.os.ServiceManager;
110 import android.os.SystemClock;
111 import android.os.SystemProperties;
112 import android.os.UserHandle;
113 import android.os.Environment.UserEnvironment;
114 import android.os.UserManager;
115 import android.provider.Settings.Secure;
116 import android.security.KeyStore;
117 import android.security.SystemKeyStore;
118 import android.util.DisplayMetrics;
119 import android.util.EventLog;
120 import android.util.Log;
121 import android.util.LogPrinter;
122 import android.util.Slog;
123 import android.util.SparseArray;
124 import android.util.Xml;
125 import android.view.Display;
126 import android.view.WindowManager;
127
128 import java.io.BufferedOutputStream;
129 import java.io.File;
130 import java.io.FileDescriptor;
131 import java.io.FileInputStream;
132 import java.io.FileNotFoundException;
133 import java.io.FileOutputStream;
134 import java.io.FileReader;
135 import java.io.FilenameFilter;
136 import java.io.IOException;
137 import java.io.ObjectOutputStream;
138 import java.io.PrintWriter;
139 import java.security.NoSuchAlgorithmException;
140 import java.security.PublicKey;
141 import java.security.cert.CertificateException;
142 import java.text.SimpleDateFormat;
143 import java.util.ArrayList;
144 import java.util.Arrays;
145 import java.util.Collection;
146 import java.util.Collections;
147 import java.util.Comparator;
148 import java.util.Date;
149 import java.util.HashMap;
150 import java.util.HashSet;
151 import java.util.Iterator;
152 import java.util.List;
153 import java.util.Map;
154 import java.util.Set;
155
156 import libcore.io.ErrnoException;
157 import libcore.io.IoUtils;
158 import libcore.io.Libcore;
159 import libcore.io.StructStat;
160
161 /**
162  * Keep track of all those .apks everywhere.
163  * 
164  * This is very central to the platform's security; please run the unit
165  * tests whenever making modifications here:
166  * 
167 mmm frameworks/base/tests/AndroidTests
168 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
169 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
170  * 
171  * {@hide}
172  */
173 public class PackageManagerService extends IPackageManager.Stub {
174     static final String TAG = "PackageManager";
175     static final boolean DEBUG_SETTINGS = false;
176     static final boolean DEBUG_PREFERRED = false;
177     static final boolean DEBUG_UPGRADE = false;
178     private static final boolean DEBUG_INSTALL = false;
179     private static final boolean DEBUG_REMOVE = false;
180     private static final boolean DEBUG_BROADCASTS = false;
181     private static final boolean DEBUG_SHOW_INFO = false;
182     private static final boolean DEBUG_PACKAGE_INFO = false;
183     private static final boolean DEBUG_INTENT_MATCHING = false;
184     private static final boolean DEBUG_PACKAGE_SCANNING = false;
185     private static final boolean DEBUG_APP_DIR_OBSERVER = false;
186     private static final boolean DEBUG_VERIFY = false;
187
188     private static final int RADIO_UID = Process.PHONE_UID;
189     private static final int LOG_UID = Process.LOG_UID;
190     private static final int NFC_UID = Process.NFC_UID;
191     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
192     private static final int SHELL_UID = Process.SHELL_UID;
193
194     private static final boolean GET_CERTIFICATES = true;
195
196     private static final int REMOVE_EVENTS =
197         FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
198     private static final int ADD_EVENTS =
199         FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;
200
201     private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;
202     // Suffix used during package installation when copying/moving
203     // package apks to install directory.
204     private static final String INSTALL_PACKAGE_SUFFIX = "-";
205
206     static final int SCAN_MONITOR = 1<<0;
207     static final int SCAN_NO_DEX = 1<<1;
208     static final int SCAN_FORCE_DEX = 1<<2;
209     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
210     static final int SCAN_NEW_INSTALL = 1<<4;
211     static final int SCAN_NO_PATHS = 1<<5;
212     static final int SCAN_UPDATE_TIME = 1<<6;
213     static final int SCAN_DEFER_DEX = 1<<7;
214     static final int SCAN_BOOTING = 1<<8;
215
216     static final int REMOVE_CHATTY = 1<<16;
217
218     /**
219      * Whether verification is enabled by default.
220      */
221     private static final boolean DEFAULT_VERIFY_ENABLE = true;
222
223     /**
224      * The default maximum time to wait for the verification agent to return in
225      * milliseconds.
226      */
227     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
228
229     /**
230      * The default response for package verification timeout.
231      *
232      * This can be either PackageManager.VERIFICATION_ALLOW or
233      * PackageManager.VERIFICATION_REJECT.
234      */
235     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
236
237     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
238
239     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
240             DEFAULT_CONTAINER_PACKAGE,
241             "com.android.defcontainer.DefaultContainerService");
242
243     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
244
245     private static final String LIB_DIR_NAME = "lib";
246
247     static final String mTempContainerPrefix = "smdl2tmp";
248
249     final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
250             Process.THREAD_PRIORITY_BACKGROUND);
251     final PackageHandler mHandler;
252
253     final int mSdkVersion = Build.VERSION.SDK_INT;
254     final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
255             ? null : Build.VERSION.CODENAME;
256
257     final Context mContext;
258     final boolean mFactoryTest;
259     final boolean mOnlyCore;
260     final boolean mNoDexOpt;
261     final DisplayMetrics mMetrics;
262     final int mDefParseFlags;
263     final String[] mSeparateProcesses;
264
265     // This is where all application persistent data goes.
266     final File mAppDataDir;
267
268     // This is where all application persistent data goes for secondary users.
269     final File mUserAppDataDir;
270
271     /** The location for ASEC container files on internal storage. */
272     final String mAsecInternalPath;
273
274     // This is the object monitoring the framework dir.
275     final FileObserver mFrameworkInstallObserver;
276
277     // This is the object monitoring the system app dir.
278     final FileObserver mSystemInstallObserver;
279
280     // This is the object monitoring the system app dir.
281     final FileObserver mVendorInstallObserver;
282
283     // This is the object monitoring mAppInstallDir.
284     final FileObserver mAppInstallObserver;
285
286     // This is the object monitoring mDrmAppPrivateInstallDir.
287     final FileObserver mDrmAppInstallObserver;
288
289     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
290     // LOCK HELD.  Can be called with mInstallLock held.
291     final Installer mInstaller;
292
293     final File mFrameworkDir;
294     final File mSystemAppDir;
295     final File mVendorAppDir;
296     final File mAppInstallDir;
297     final File mDalvikCacheDir;
298
299     /**
300      * Directory to which applications installed internally have native
301      * libraries copied.
302      */
303     private File mAppLibInstallDir;
304
305     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
306     // apps.
307     final File mDrmAppPrivateInstallDir;
308
309     // ----------------------------------------------------------------
310
311     // Lock for state used when installing and doing other long running
312     // operations.  Methods that must be called with this lock held have
313     // the prefix "LI".
314     final Object mInstallLock = new Object();
315
316     // These are the directories in the 3rd party applications installed dir
317     // that we have currently loaded packages from.  Keys are the application's
318     // installed zip file (absolute codePath), and values are Package.
319     final HashMap<String, PackageParser.Package> mAppDirs =
320             new HashMap<String, PackageParser.Package>();
321
322     // Information for the parser to write more useful error messages.
323     File mScanningPath;
324     int mLastScanError;
325
326     // ----------------------------------------------------------------
327
328     // Keys are String (package name), values are Package.  This also serves
329     // as the lock for the global state.  Methods that must be called with
330     // this lock held have the prefix "LP".
331     final HashMap<String, PackageParser.Package> mPackages =
332             new HashMap<String, PackageParser.Package>();
333
334     final Settings mSettings;
335     boolean mRestoredSettings;
336
337     // Group-ids that are given to all packages as read from etc/permissions/*.xml.
338     int[] mGlobalGids;
339
340     // These are the built-in uid -> permission mappings that were read from the
341     // etc/permissions.xml file.
342     final SparseArray<HashSet<String>> mSystemPermissions =
343             new SparseArray<HashSet<String>>();
344
345     static final class SharedLibraryEntry {
346         final String path;
347         final String apk;
348
349         SharedLibraryEntry(String _path, String _apk) {
350             path = _path;
351             apk = _apk;
352         }
353     }
354
355     // These are the built-in shared libraries that were read from the
356     // etc/permissions.xml file.
357     final HashMap<String, SharedLibraryEntry> mSharedLibraries
358             = new HashMap<String, SharedLibraryEntry>();
359
360     // Temporary for building the final shared libraries for an .apk.
361     String[] mTmpSharedLibraries = null;
362
363     // These are the features this devices supports that were read from the
364     // etc/permissions.xml file.
365     final HashMap<String, FeatureInfo> mAvailableFeatures =
366             new HashMap<String, FeatureInfo>();
367
368     // If mac_permissions.xml was found for seinfo labeling.
369     boolean mFoundPolicyFile;
370
371     // All available activities, for your resolving pleasure.
372     final ActivityIntentResolver mActivities =
373             new ActivityIntentResolver();
374
375     // All available receivers, for your resolving pleasure.
376     final ActivityIntentResolver mReceivers =
377             new ActivityIntentResolver();
378
379     // All available services, for your resolving pleasure.
380     final ServiceIntentResolver mServices = new ServiceIntentResolver();
381
382     // Keys are String (provider class name), values are Provider.
383     final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent =
384             new HashMap<ComponentName, PackageParser.Provider>();
385
386     // Mapping from provider base names (first directory in content URI codePath)
387     // to the provider information.
388     final HashMap<String, PackageParser.Provider> mProviders =
389             new HashMap<String, PackageParser.Provider>();
390
391     // Mapping from instrumentation class names to info about them.
392     final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
393             new HashMap<ComponentName, PackageParser.Instrumentation>();
394
395     // Mapping from permission names to info about them.
396     final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
397             new HashMap<String, PackageParser.PermissionGroup>();
398
399     // Packages whose data we have transfered into another package, thus
400     // should no longer exist.
401     final HashSet<String> mTransferedPackages = new HashSet<String>();
402     
403     // Broadcast actions that are only available to the system.
404     final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
405
406     /** List of packages waiting for verification. */
407     final SparseArray<PackageVerificationState> mPendingVerification
408             = new SparseArray<PackageVerificationState>();
409
410     HashSet<PackageParser.Package> mDeferredDexOpt = null;
411
412     /** Token for keys in mPendingVerification. */
413     private int mPendingVerificationToken = 0;
414
415     boolean mSystemReady;
416     boolean mSafeMode;
417     boolean mHasSystemUidErrors;
418
419     ApplicationInfo mAndroidApplication;
420     final ActivityInfo mResolveActivity = new ActivityInfo();
421     final ResolveInfo mResolveInfo = new ResolveInfo();
422     ComponentName mResolveComponentName;
423     PackageParser.Package mPlatformPackage;
424
425     // Set of pending broadcasts for aggregating enable/disable of components.
426     static class PendingPackageBroadcasts {
427         // for each user id, a map of <package name -> components within that package>
428         final SparseArray<HashMap<String, ArrayList<String>>> mUidMap;
429
430         public PendingPackageBroadcasts() {
431             mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>();
432         }
433
434         public ArrayList<String> get(int userId, String packageName) {
435             HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
436             return packages.get(packageName);
437         }
438
439         public void put(int userId, String packageName, ArrayList<String> components) {
440             HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
441             packages.put(packageName, components);
442         }
443
444         public void remove(int userId, String packageName) {
445             HashMap<String, ArrayList<String>> packages = mUidMap.get(userId);
446             if (packages != null) {
447                 packages.remove(packageName);
448             }
449         }
450
451         public void remove(int userId) {
452             mUidMap.remove(userId);
453         }
454
455         public int userIdCount() {
456             return mUidMap.size();
457         }
458
459         public int userIdAt(int n) {
460             return mUidMap.keyAt(n);
461         }
462
463         public HashMap<String, ArrayList<String>> packagesForUserId(int userId) {
464             return mUidMap.get(userId);
465         }
466
467         public int size() {
468             // total number of pending broadcast entries across all userIds
469             int num = 0;
470             for (int i = 0; i< mUidMap.size(); i++) {
471                 num += mUidMap.valueAt(i).size();
472             }
473             return num;
474         }
475
476         public void clear() {
477             mUidMap.clear();
478         }
479
480         private HashMap<String, ArrayList<String>> getOrAllocate(int userId) {
481             HashMap<String, ArrayList<String>> map = mUidMap.get(userId);
482             if (map == null) {
483                 map = new HashMap<String, ArrayList<String>>();
484                 mUidMap.put(userId, map);
485             }
486             return map;
487         }
488     }
489     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
490
491     // Service Connection to remote media container service to copy
492     // package uri's from external media onto secure containers
493     // or internal storage.
494     private IMediaContainerService mContainerService = null;
495
496     // Packages that have been installed with library matching 2nd ABI.
497     final HashMap<Integer, String> mPackagesMatchABI2 = new HashMap<Integer,String>();
498     // Packages that have been installed with library matching 2nd ABI and matching neon app list
499     final HashMap<Integer, String> mPackagesMatchABI2Neon = new HashMap<Integer,String>();
500
501     static final int SEND_PENDING_BROADCAST = 1;
502     static final int MCS_BOUND = 3;
503     static final int END_COPY = 4;
504     static final int INIT_COPY = 5;
505     static final int MCS_UNBIND = 6;
506     static final int START_CLEANING_PACKAGE = 7;
507     static final int FIND_INSTALL_LOC = 8;
508     static final int POST_INSTALL = 9;
509     static final int MCS_RECONNECT = 10;
510     static final int MCS_GIVE_UP = 11;
511     static final int UPDATED_MEDIA_STATUS = 12;
512     static final int WRITE_SETTINGS = 13;
513     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
514     static final int PACKAGE_VERIFIED = 15;
515     static final int CHECK_PENDING_VERIFICATION = 16;
516
517     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
518
519     // Delay time in millisecs
520     static final int BROADCAST_DELAY = 10 * 1000;
521
522     static UserManagerService sUserManager;
523
524     // Stores a list of users whose package restrictions file needs to be updated
525     private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
526
527     final private DefaultContainerConnection mDefContainerConn =
528             new DefaultContainerConnection();
529     class DefaultContainerConnection implements ServiceConnection {
530         public void onServiceConnected(ComponentName name, IBinder service) {
531             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
532             IMediaContainerService imcs =
533                 IMediaContainerService.Stub.asInterface(service);
534             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
535         }
536
537         public void onServiceDisconnected(ComponentName name) {
538             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
539         }
540     };
541
542     // Recordkeeping of restore-after-install operations that are currently in flight
543     // between the Package Manager and the Backup Manager
544     class PostInstallData {
545         public InstallArgs args;
546         public PackageInstalledInfo res;
547
548         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
549             args = _a;
550             res = _r;
551         }
552     };
553     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
554     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
555
556     private final String mRequiredVerifierPackage;
557
558     class PackageHandler extends Handler {
559         private boolean mBound = false;
560         final ArrayList<HandlerParams> mPendingInstalls =
561             new ArrayList<HandlerParams>();
562
563         private boolean connectToService() {
564             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
565                     " DefaultContainerService");
566             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
567             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
568             if (mContext.bindServiceAsUser(service, mDefContainerConn,
569                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
570                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
571                 mBound = true;
572                 return true;
573             }
574             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
575             return false;
576         }
577
578         private void disconnectService() {
579             mContainerService = null;
580             mBound = false;
581             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
582             mContext.unbindService(mDefContainerConn);
583             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
584         }
585
586         PackageHandler(Looper looper) {
587             super(looper);
588         }
589
590         public void handleMessage(Message msg) {
591             try {
592                 doHandleMessage(msg);
593             } finally {
594                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
595             }
596         }
597         
598         void doHandleMessage(Message msg) {
599             switch (msg.what) {
600                 case INIT_COPY: {
601                     HandlerParams params = (HandlerParams) msg.obj;
602                     int idx = mPendingInstalls.size();
603                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
604                     // If a bind was already initiated we dont really
605                     // need to do anything. The pending install
606                     // will be processed later on.
607                     if (!mBound) {
608                         // If this is the only one pending we might
609                         // have to bind to the service again.
610                         if (!connectToService()) {
611                             Slog.e(TAG, "Failed to bind to media container service");
612                             params.serviceError();
613                             return;
614                         } else {
615                             // Once we bind to the service, the first
616                             // pending request will be processed.
617                             mPendingInstalls.add(idx, params);
618                         }
619                     } else {
620                         mPendingInstalls.add(idx, params);
621                         // Already bound to the service. Just make
622                         // sure we trigger off processing the first request.
623                         if (idx == 0) {
624                             mHandler.sendEmptyMessage(MCS_BOUND);
625                         }
626                     }
627                     break;
628                 }
629                 case MCS_BOUND: {
630                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
631                     if (msg.obj != null) {
632                         mContainerService = (IMediaContainerService) msg.obj;
633                     }
634                     if (mContainerService == null) {
635                         // Something seriously wrong. Bail out
636                         Slog.e(TAG, "Cannot bind to media container service");
637                         for (HandlerParams params : mPendingInstalls) {
638                             // Indicate service bind error
639                             params.serviceError();
640                         }
641                         mPendingInstalls.clear();
642                     } else if (mPendingInstalls.size() > 0) {
643                         HandlerParams params = mPendingInstalls.get(0);
644                         if (params != null) {
645                             if (params.startCopy()) {
646                                 // We are done...  look for more work or to
647                                 // go idle.
648                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
649                                         "Checking for more work or unbind...");
650                                 // Delete pending install
651                                 if (mPendingInstalls.size() > 0) {
652                                     mPendingInstalls.remove(0);
653                                 }
654                                 if (mPendingInstalls.size() == 0) {
655                                     if (mBound) {
656                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
657                                                 "Posting delayed MCS_UNBIND");
658                                         removeMessages(MCS_UNBIND);
659                                         Message ubmsg = obtainMessage(MCS_UNBIND);
660                                         // Unbind after a little delay, to avoid
661                                         // continual thrashing.
662                                         sendMessageDelayed(ubmsg, 10000);
663                                     }
664                                 } else {
665                                     // There are more pending requests in queue.
666                                     // Just post MCS_BOUND message to trigger processing
667                                     // of next pending install.
668                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
669                                             "Posting MCS_BOUND for next woek");
670                                     mHandler.sendEmptyMessage(MCS_BOUND);
671                                 }
672                             }
673                         }
674                     } else {
675                         // Should never happen ideally.
676                         Slog.w(TAG, "Empty queue");
677                     }
678                     break;
679                 }
680                 case MCS_RECONNECT: {
681                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
682                     if (mPendingInstalls.size() > 0) {
683                         if (mBound) {
684                             disconnectService();
685                         }
686                         if (!connectToService()) {
687                             Slog.e(TAG, "Failed to bind to media container service");
688                             for (HandlerParams params : mPendingInstalls) {
689                                 // Indicate service bind error
690                                 params.serviceError();
691                             }
692                             mPendingInstalls.clear();
693                         }
694                     }
695                     break;
696                 }
697                 case MCS_UNBIND: {
698                     // If there is no actual work left, then time to unbind.
699                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
700
701                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
702                         if (mBound) {
703                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
704
705                             disconnectService();
706                         }
707                     } else if (mPendingInstalls.size() > 0) {
708                         // There are more pending requests in queue.
709                         // Just post MCS_BOUND message to trigger processing
710                         // of next pending install.
711                         mHandler.sendEmptyMessage(MCS_BOUND);
712                     }
713
714                     break;
715                 }
716                 case MCS_GIVE_UP: {
717                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
718                     mPendingInstalls.remove(0);
719                     break;
720                 }
721                 case SEND_PENDING_BROADCAST: {
722                     String packages[];
723                     ArrayList<String> components[];
724                     int size = 0;
725                     int uids[];
726                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
727                     synchronized (mPackages) {
728                         if (mPendingBroadcasts == null) {
729                             return;
730                         }
731                         size = mPendingBroadcasts.size();
732                         if (size <= 0) {
733                             // Nothing to be done. Just return
734                             return;
735                         }
736                         packages = new String[size];
737                         components = new ArrayList[size];
738                         uids = new int[size];
739                         int i = 0;  // filling out the above arrays
740
741                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
742                             int packageUserId = mPendingBroadcasts.userIdAt(n);
743                             Iterator<Map.Entry<String, ArrayList<String>>> it
744                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
745                                             .entrySet().iterator();
746                             while (it.hasNext() && i < size) {
747                                 Map.Entry<String, ArrayList<String>> ent = it.next();
748                                 packages[i] = ent.getKey();
749                                 components[i] = ent.getValue();
750                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
751                                 uids[i] = (ps != null)
752                                         ? UserHandle.getUid(packageUserId, ps.appId)
753                                         : -1;
754                                 i++;
755                             }
756                         }
757                         size = i;
758                         mPendingBroadcasts.clear();
759                     }
760                     // Send broadcasts
761                     for (int i = 0; i < size; i++) {
762                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
763                     }
764                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
765                     break;
766                 }
767                 case START_CLEANING_PACKAGE: {
768                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
769                     final String packageName = (String)msg.obj;
770                     final int userId = msg.arg1;
771                     final boolean andCode = msg.arg2 != 0;
772                     synchronized (mPackages) {
773                         if (userId == UserHandle.USER_ALL) {
774                             int[] users = sUserManager.getUserIds();
775                             for (int user : users) {
776                                 mSettings.addPackageToCleanLPw(
777                                         new PackageCleanItem(user, packageName, andCode));
778                             }
779                         } else {
780                             mSettings.addPackageToCleanLPw(
781                                     new PackageCleanItem(userId, packageName, andCode));
782                         }
783                     }
784                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
785                     startCleaningPackages();
786                 } break;
787                 case POST_INSTALL: {
788                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
789                     PostInstallData data = mRunningInstalls.get(msg.arg1);
790                     mRunningInstalls.delete(msg.arg1);
791                     boolean deleteOld = false;
792
793                     if (data != null) {
794                         InstallArgs args = data.args;
795                         PackageInstalledInfo res = data.res;
796
797                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
798                             res.removedInfo.sendBroadcast(false, true, false);
799                             Bundle extras = new Bundle(1);
800                             extras.putInt(Intent.EXTRA_UID, res.uid);
801                             // Determine the set of users who are adding this
802                             // package for the first time vs. those who are seeing
803                             // an update.
804                             int[] firstUsers;
805                             int[] updateUsers = new int[0];
806                             if (res.origUsers == null || res.origUsers.length == 0) {
807                                 firstUsers = res.newUsers;
808                             } else {
809                                 firstUsers = new int[0];
810                                 for (int i=0; i<res.newUsers.length; i++) {
811                                     int user = res.newUsers[i];
812                                     boolean isNew = true;
813                                     for (int j=0; j<res.origUsers.length; j++) {
814                                         if (res.origUsers[j] == user) {
815                                             isNew = false;
816                                             break;
817                                         }
818                                     }
819                                     if (isNew) {
820                                         int[] newFirst = new int[firstUsers.length+1];
821                                         System.arraycopy(firstUsers, 0, newFirst, 0,
822                                                 firstUsers.length);
823                                         newFirst[firstUsers.length] = user;
824                                         firstUsers = newFirst;
825                                     } else {
826                                         int[] newUpdate = new int[updateUsers.length+1];
827                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
828                                                 updateUsers.length);
829                                         newUpdate[updateUsers.length] = user;
830                                         updateUsers = newUpdate;
831                                     }
832                                 }
833                             }
834                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
835                                     res.pkg.applicationInfo.packageName,
836                                     extras, null, null, firstUsers);
837                             final boolean update = res.removedInfo.removedPackage != null;
838                             if (update) {
839                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
840                             }
841                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
842                                     res.pkg.applicationInfo.packageName,
843                                     extras, null, null, updateUsers);
844                             if (update) {
845                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
846                                         res.pkg.applicationInfo.packageName,
847                                         extras, null, null, updateUsers);
848                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
849                                         null, null,
850                                         res.pkg.applicationInfo.packageName, null, updateUsers);
851                             }
852                             if (res.removedInfo.args != null) {
853                                 // Remove the replaced package's older resources safely now
854                                 deleteOld = true;
855                             }
856
857                             // Log current value of "unknown sources" setting
858                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
859                                 getUnknownSourcesSettings());
860                         }
861                         // Force a gc to clear up things
862                         Runtime.getRuntime().gc();
863                         // We delete after a gc for applications  on sdcard.
864                         if (deleteOld) {
865                             synchronized (mInstallLock) {
866                                 res.removedInfo.args.doPostDeleteLI(true);
867                             }
868                         }
869                         if (args.observer != null) {
870                             try {
871                                 args.observer.packageInstalled(res.name, res.returnCode);
872                             } catch (RemoteException e) {
873                                 Slog.i(TAG, "Observer no longer exists.");
874                             }
875                         }
876                     } else {
877                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
878                     }
879                 } break;
880                 case UPDATED_MEDIA_STATUS: {
881                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
882                     boolean reportStatus = msg.arg1 == 1;
883                     boolean doGc = msg.arg2 == 1;
884                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
885                     if (doGc) {
886                         // Force a gc to clear up stale containers.
887                         Runtime.getRuntime().gc();
888                     }
889                     if (msg.obj != null) {
890                         @SuppressWarnings("unchecked")
891                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
892                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
893                         // Unload containers
894                         unloadAllContainers(args);
895                     }
896                     if (reportStatus) {
897                         try {
898                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
899                             PackageHelper.getMountService().finishMediaUpdate();
900                         } catch (RemoteException e) {
901                             Log.e(TAG, "MountService not running?");
902                         }
903                     }
904                 } break;
905                 case WRITE_SETTINGS: {
906                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
907                     synchronized (mPackages) {
908                         removeMessages(WRITE_SETTINGS);
909                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
910                         mSettings.writeLPr();
911                         mDirtyUsers.clear();
912                     }
913                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
914                 } break;
915                 case WRITE_PACKAGE_RESTRICTIONS: {
916                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
917                     synchronized (mPackages) {
918                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
919                         for (int userId : mDirtyUsers) {
920                             mSettings.writePackageRestrictionsLPr(userId);
921                         }
922                         mDirtyUsers.clear();
923                     }
924                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
925                 } break;
926                 case CHECK_PENDING_VERIFICATION: {
927                     final int verificationId = msg.arg1;
928                     final PackageVerificationState state = mPendingVerification.get(verificationId);
929
930                     if ((state != null) && !state.timeoutExtended()) {
931                         final InstallArgs args = state.getInstallArgs();
932                         Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
933                         mPendingVerification.remove(verificationId);
934
935                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
936
937                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
938                             Slog.i(TAG, "Continuing with installation of "
939                                     + args.packageURI.toString());
940                             state.setVerifierResponse(Binder.getCallingUid(),
941                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
942                             broadcastPackageVerified(verificationId, args.packageURI,
943                                     PackageManager.VERIFICATION_ALLOW,
944                                     state.getInstallArgs().getUser());
945                             try {
946                                 ret = args.copyApk(mContainerService, true);
947                             } catch (RemoteException e) {
948                                 Slog.e(TAG, "Could not contact the ContainerService");
949                             }
950                         } else {
951                             broadcastPackageVerified(verificationId, args.packageURI,
952                                     PackageManager.VERIFICATION_REJECT,
953                                     state.getInstallArgs().getUser());
954                         }
955
956                         processPendingInstall(args, ret);
957                         mHandler.sendEmptyMessage(MCS_UNBIND);
958                     }
959                     break;
960                 }
961                 case PACKAGE_VERIFIED: {
962                     final int verificationId = msg.arg1;
963
964                     final PackageVerificationState state = mPendingVerification.get(verificationId);
965                     if (state == null) {
966                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
967                         break;
968                     }
969
970                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
971
972                     state.setVerifierResponse(response.callerUid, response.code);
973
974                     if (state.isVerificationComplete()) {
975                         mPendingVerification.remove(verificationId);
976
977                         final InstallArgs args = state.getInstallArgs();
978
979                         int ret;
980                         if (state.isInstallAllowed()) {
981                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
982                             broadcastPackageVerified(verificationId, args.packageURI,
983                                     response.code, state.getInstallArgs().getUser());
984                             try {
985                                 ret = args.copyApk(mContainerService, true);
986                             } catch (RemoteException e) {
987                                 Slog.e(TAG, "Could not contact the ContainerService");
988                             }
989                         } else {
990                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
991                         }
992
993                         processPendingInstall(args, ret);
994
995                         mHandler.sendEmptyMessage(MCS_UNBIND);
996                     }
997
998                     break;
999                 }
1000             }
1001         }
1002     }
1003
1004     void scheduleWriteSettingsLocked() {
1005         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
1006             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
1007         }
1008     }
1009
1010     void scheduleWritePackageRestrictionsLocked(int userId) {
1011         if (!sUserManager.exists(userId)) return;
1012         mDirtyUsers.add(userId);
1013         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
1014             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
1015         }
1016     }
1017
1018     public static final IPackageManager main(Context context, Installer installer,
1019             boolean factoryTest, boolean onlyCore) {
1020         PackageManagerService m = new PackageManagerService(context, installer,
1021                 factoryTest, onlyCore);
1022         ServiceManager.addService("package", m);
1023         return m;
1024     }
1025
1026     static String[] splitString(String str, char sep) {
1027         int count = 1;
1028         int i = 0;
1029         while ((i=str.indexOf(sep, i)) >= 0) {
1030             count++;
1031             i++;
1032         }
1033
1034         String[] res = new String[count];
1035         i=0;
1036         count = 0;
1037         int lastI=0;
1038         while ((i=str.indexOf(sep, i)) >= 0) {
1039             res[count] = str.substring(lastI, i);
1040             count++;
1041             i++;
1042             lastI = i;
1043         }
1044         res[count] = str.substring(lastI, str.length());
1045         return res;
1046     }
1047
1048     public PackageManagerService(Context context, Installer installer,
1049             boolean factoryTest, boolean onlyCore) {
1050         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
1051                 SystemClock.uptimeMillis());
1052
1053         if (mSdkVersion <= 0) {
1054             Slog.w(TAG, "**** ro.build.version.sdk not set!");
1055         }
1056
1057         mContext = context;
1058         mFactoryTest = factoryTest;
1059         mOnlyCore = onlyCore;
1060         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
1061         mMetrics = new DisplayMetrics();
1062         mSettings = new Settings(context);
1063         mSettings.addSharedUserLPw("android.uid.system",
1064                 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
1065         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
1066         mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
1067         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
1068         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, ApplicationInfo.FLAG_SYSTEM);
1069         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, ApplicationInfo.FLAG_SYSTEM);
1070
1071         String separateProcesses = SystemProperties.get("debug.separate_processes");
1072         if (separateProcesses != null && separateProcesses.length() > 0) {
1073             if ("*".equals(separateProcesses)) {
1074                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
1075                 mSeparateProcesses = null;
1076                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
1077             } else {
1078                 mDefParseFlags = 0;
1079                 mSeparateProcesses = separateProcesses.split(",");
1080                 Slog.w(TAG, "Running with debug.separate_processes: "
1081                         + separateProcesses);
1082             }
1083         } else {
1084             mDefParseFlags = 0;
1085             mSeparateProcesses = null;
1086         }
1087
1088         mInstaller = installer;
1089
1090         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
1091         Display d = wm.getDefaultDisplay();
1092         d.getMetrics(mMetrics);
1093
1094         synchronized (mInstallLock) {
1095         // writer
1096         synchronized (mPackages) {
1097             mHandlerThread.start();
1098             mHandler = new PackageHandler(mHandlerThread.getLooper());
1099
1100             File dataDir = Environment.getDataDirectory();
1101             mAppDataDir = new File(dataDir, "data");
1102             mAppInstallDir = new File(dataDir, "app");
1103             mAppLibInstallDir = new File(dataDir, "app-lib");
1104             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
1105             mUserAppDataDir = new File(dataDir, "user");
1106             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
1107
1108             sUserManager = new UserManagerService(context, this,
1109                     mInstallLock, mPackages);
1110
1111             readPermissions();
1112
1113             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
1114
1115             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
1116                     mSdkVersion, mOnlyCore);
1117
1118             long startTime = SystemClock.uptimeMillis();
1119
1120             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
1121                     startTime);
1122
1123             // Set flag to monitor and not change apk file paths when
1124             // scanning install directories.
1125             int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
1126             if (mNoDexOpt) {
1127                 Slog.w(TAG, "Running ENG build: no pre-dexopt!");
1128                 scanMode |= SCAN_NO_DEX;
1129             }
1130
1131             final HashSet<String> libFiles = new HashSet<String>();
1132
1133             mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
1134             mDalvikCacheDir = new File(dataDir, "dalvik-cache");
1135
1136             boolean didDexOpt = false;
1137
1138             /**
1139              * Out of paranoia, ensure that everything in the boot class
1140              * path has been dexed.
1141              */
1142             String bootClassPath = System.getProperty("java.boot.class.path");
1143             if (bootClassPath != null) {
1144                 String[] paths = splitString(bootClassPath, ':');
1145                 for (int i=0; i<paths.length; i++) {
1146                     try {
1147                         if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
1148                             libFiles.add(paths[i]);
1149                             mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
1150                             didDexOpt = true;
1151                         }
1152                     } catch (FileNotFoundException e) {
1153                         Slog.w(TAG, "Boot class path not found: " + paths[i]);
1154                     } catch (IOException e) {
1155                         Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
1156                                 + e.getMessage());
1157                     }
1158                 }
1159             } else {
1160                 Slog.w(TAG, "No BOOTCLASSPATH found!");
1161             }
1162
1163             /**
1164              * Also ensure all external libraries have had dexopt run on them.
1165              */
1166             if (mSharedLibraries.size() > 0) {
1167                 Iterator<SharedLibraryEntry> libs = mSharedLibraries.values().iterator();
1168                 while (libs.hasNext()) {
1169                     String lib = libs.next().path;
1170                     if (lib == null) {
1171                         continue;
1172                     }
1173                     try {
1174                         if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
1175                             libFiles.add(lib);
1176                             mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
1177                             didDexOpt = true;
1178                         }
1179                     } catch (FileNotFoundException e) {
1180                         Slog.w(TAG, "Library not found: " + lib);
1181                     } catch (IOException e) {
1182                         Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
1183                                 + e.getMessage());
1184                     }
1185                 }
1186             }
1187
1188             // Gross hack for now: we know this file doesn't contain any
1189             // code, so don't dexopt it to avoid the resulting log spew.
1190             libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
1191
1192             /**
1193              * And there are a number of commands implemented in Java, which
1194              * we currently need to do the dexopt on so that they can be
1195              * run from a non-root shell.
1196              */
1197             String[] frameworkFiles = mFrameworkDir.list();
1198             if (frameworkFiles != null) {
1199                 for (int i=0; i<frameworkFiles.length; i++) {
1200                     File libPath = new File(mFrameworkDir, frameworkFiles[i]);
1201                     String path = libPath.getPath();
1202                     // Skip the file if we alrady did it.
1203                     if (libFiles.contains(path)) {
1204                         continue;
1205                     }
1206                     // Skip the file if it is not a type we want to dexopt.
1207                     if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1208                         continue;
1209                     }
1210                     try {
1211                         if (dalvik.system.DexFile.isDexOptNeeded(path)) {
1212                             mInstaller.dexopt(path, Process.SYSTEM_UID, true);
1213                             didDexOpt = true;
1214                         }
1215                     } catch (FileNotFoundException e) {
1216                         Slog.w(TAG, "Jar not found: " + path);
1217                     } catch (IOException e) {
1218                         Slog.w(TAG, "Exception reading jar: " + path, e);
1219                     }
1220                 }
1221             }
1222
1223             if (didDexOpt) {
1224                 // If we had to do a dexopt of one of the previous
1225                 // things, then something on the system has changed.
1226                 // Consider this significant, and wipe away all other
1227                 // existing dexopt files to ensure we don't leave any
1228                 // dangling around.
1229                 String[] files = mDalvikCacheDir.list();
1230                 if (files != null) {
1231                     for (int i=0; i<files.length; i++) {
1232                         String fn = files[i];
1233                         if (fn.startsWith("data@app@")
1234                                 || fn.startsWith("data@app-private@")) {
1235                             Slog.i(TAG, "Pruning dalvik file: " + fn);
1236                             (new File(mDalvikCacheDir, fn)).delete();
1237                         }
1238                     }
1239                 }
1240             }
1241
1242             // Find base frameworks (resource packages without code).
1243             mFrameworkInstallObserver = new AppDirObserver(
1244                 mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
1245             mFrameworkInstallObserver.startWatching();
1246             scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
1247                     | PackageParser.PARSE_IS_SYSTEM_DIR,
1248                     scanMode | SCAN_NO_DEX, 0);
1249
1250             // Collect all system packages.
1251             mSystemAppDir = new File(Environment.getRootDirectory(), "app");
1252             mSystemInstallObserver = new AppDirObserver(
1253                 mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
1254             mSystemInstallObserver.startWatching();
1255             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
1256                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1257
1258             // Collect all vendor packages.
1259             mVendorAppDir = new File("/vendor/app");
1260             mVendorInstallObserver = new AppDirObserver(
1261                 mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
1262             mVendorInstallObserver.startWatching();
1263             scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
1264                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1265
1266             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1267             mInstaller.moveFiles();
1268
1269             // Prune any system packages that no longer exist.
1270             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
1271             if (!mOnlyCore) {
1272                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1273                 while (psit.hasNext()) {
1274                     PackageSetting ps = psit.next();
1275
1276                     /*
1277                      * If this is not a system app, it can't be a
1278                      * disable system app.
1279                      */
1280                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
1281                         continue;
1282                     }
1283
1284                     /*
1285                      * If the package is scanned, it's not erased.
1286                      */
1287                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
1288                     if (scannedPkg != null) {
1289                         /*
1290                          * If the system app is both scanned and in the
1291                          * disabled packages list, then it must have been
1292                          * added via OTA. Remove it from the currently
1293                          * scanned package so the previously user-installed
1294                          * application can be scanned.
1295                          */
1296                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
1297                             Slog.i(TAG, "Expecting better updatd system app for " + ps.name
1298                                     + "; removing system app");
1299                             removePackageLI(ps, true);
1300                         }
1301
1302                         continue;
1303                     }
1304
1305                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
1306                         psit.remove();
1307                         String msg = "System package " + ps.name
1308                                 + " no longer exists; wiping its data";
1309                         reportSettingsProblem(Log.WARN, msg);
1310                         removeDataDirsLI(ps.name);
1311                     } else {
1312                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
1313                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
1314                             possiblyDeletedUpdatedSystemApps.add(ps.name);
1315                         }
1316                     }
1317                 }
1318             }
1319
1320             //look for any incomplete package installations
1321             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1322             //clean up list
1323             for(int i = 0; i < deletePkgsList.size(); i++) {
1324                 //clean up here
1325                 cleanupInstallFailedPackage(deletePkgsList.get(i));
1326             }
1327             //delete tmp files
1328             deleteTempPackageFiles();
1329
1330             if (!mOnlyCore) {
1331                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1332                         SystemClock.uptimeMillis());
1333                 mAppInstallObserver = new AppDirObserver(
1334                     mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
1335                 mAppInstallObserver.startWatching();
1336                 scanDirLI(mAppInstallDir, 0, scanMode, 0);
1337     
1338                 mDrmAppInstallObserver = new AppDirObserver(
1339                     mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
1340                 mDrmAppInstallObserver.startWatching();
1341                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1342                         scanMode, 0);
1343
1344                 /**
1345                  * Remove disable package settings for any updated system
1346                  * apps that were removed via an OTA. If they're not a
1347                  * previously-updated app, remove them completely.
1348                  * Otherwise, just revoke their system-level permissions.
1349                  */
1350                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
1351                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
1352                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
1353
1354                     String msg;
1355                     if (deletedPkg == null) {
1356                         msg = "Updated system package " + deletedAppName
1357                                 + " no longer exists; wiping its data";
1358                         removeDataDirsLI(deletedAppName);
1359                     } else {
1360                         msg = "Updated system app + " + deletedAppName
1361                                 + " no longer present; removing system privileges for "
1362                                 + deletedAppName;
1363
1364                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
1365
1366                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
1367                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
1368                     }
1369                     reportSettingsProblem(Log.WARN, msg);
1370                 }
1371             } else {
1372                 mAppInstallObserver = null;
1373                 mDrmAppInstallObserver = null;
1374             }
1375
1376             // Now that we know all of the shared libraries, update all clients to have
1377             // the correct library paths.
1378             updateAllSharedLibrariesLPw();
1379
1380             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1381                     SystemClock.uptimeMillis());
1382             Slog.i(TAG, "Time to scan packages: "
1383                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
1384                     + " seconds");
1385
1386             // If the platform SDK has changed since the last time we booted,
1387             // we need to re-grant app permission to catch any new ones that
1388             // appear.  This is really a hack, and means that apps can in some
1389             // cases get permissions that the user didn't initially explicitly
1390             // allow...  it would be nice to have some better way to handle
1391             // this situation.
1392             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1393                     != mSdkVersion;
1394             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1395                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1396                     + "; regranting permissions for internal storage");
1397             mSettings.mInternalSdkPlatform = mSdkVersion;
1398             
1399             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
1400                     | (regrantPermissions
1401                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
1402                             : 0));
1403
1404             // If this is the first boot, and it is a normal boot, then
1405             // we need to initialize the default preferred apps.
1406             if (!mRestoredSettings && !onlyCore) {
1407                 mSettings.readDefaultPreferredAppsLPw(this, 0);
1408             }
1409
1410             // can downgrade to reader
1411             mSettings.writeLPr();
1412
1413             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1414                     SystemClock.uptimeMillis());
1415
1416             // Now after opening every single application zip, make sure they
1417             // are all flushed.  Not really needed, but keeps things nice and
1418             // tidy.
1419             Runtime.getRuntime().gc();
1420
1421             mRequiredVerifierPackage = getRequiredVerifierLPr();
1422         } // synchronized (mPackages)
1423         } // synchronized (mInstallLock)
1424     }
1425
1426     public boolean isFirstBoot() {
1427         return !mRestoredSettings;
1428     }
1429
1430     public boolean isOnlyCoreApps() {
1431         return mOnlyCore;
1432     }
1433
1434     private String getRequiredVerifierLPr() {
1435         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1436         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1437                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
1438
1439         String requiredVerifier = null;
1440
1441         final int N = receivers.size();
1442         for (int i = 0; i < N; i++) {
1443             final ResolveInfo info = receivers.get(i);
1444
1445             if (info.activityInfo == null) {
1446                 continue;
1447             }
1448
1449             final String packageName = info.activityInfo.packageName;
1450
1451             final PackageSetting ps = mSettings.mPackages.get(packageName);
1452             if (ps == null) {
1453                 continue;
1454             }
1455
1456             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1457             if (!gp.grantedPermissions
1458                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1459                 continue;
1460             }
1461
1462             if (requiredVerifier != null) {
1463                 throw new RuntimeException("There can be only one required verifier");
1464             }
1465
1466             requiredVerifier = packageName;
1467         }
1468
1469         return requiredVerifier;
1470     }
1471
1472     @Override
1473     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1474             throws RemoteException {
1475         try {
1476             return super.onTransact(code, data, reply, flags);
1477         } catch (RuntimeException e) {
1478             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1479                 Slog.e(TAG, "Package Manager Crash", e);
1480             }
1481             throw e;
1482         }
1483     }
1484
1485     void cleanupInstallFailedPackage(PackageSetting ps) {
1486         Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
1487         removeDataDirsLI(ps.name);
1488         if (ps.codePath != null) {
1489             if (!ps.codePath.delete()) {
1490                 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
1491             }
1492         }
1493         if (ps.resourcePath != null) {
1494             if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
1495                 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
1496             }
1497         }
1498         mSettings.removePackageLPw(ps.name);
1499     }
1500
1501     void readPermissions() {
1502         // Read permissions from .../etc/permission directory.
1503         File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
1504         if (!libraryDir.exists() || !libraryDir.isDirectory()) {
1505             Slog.w(TAG, "No directory " + libraryDir + ", skipping");
1506             return;
1507         }
1508         if (!libraryDir.canRead()) {
1509             Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
1510             return;
1511         }
1512
1513         // Iterate over the files in the directory and scan .xml files
1514         for (File f : libraryDir.listFiles()) {
1515             // We'll read platform.xml last
1516             if (f.getPath().endsWith("etc/permissions/platform.xml")) {
1517                 continue;
1518             }
1519
1520             if (!f.getPath().endsWith(".xml")) {
1521                 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
1522                 continue;
1523             }
1524             if (!f.canRead()) {
1525                 Slog.w(TAG, "Permissions library file " + f + " cannot be read");
1526                 continue;
1527             }
1528
1529             readPermissionsFromXml(f);
1530         }
1531
1532         // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
1533         final File permFile = new File(Environment.getRootDirectory(),
1534                 "etc/permissions/platform.xml");
1535         readPermissionsFromXml(permFile);
1536     }
1537
1538     private void readPermissionsFromXml(File permFile) {
1539         FileReader permReader = null;
1540         try {
1541             permReader = new FileReader(permFile);
1542         } catch (FileNotFoundException e) {
1543             Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
1544             return;
1545         }
1546
1547         try {
1548             XmlPullParser parser = Xml.newPullParser();
1549             parser.setInput(permReader);
1550
1551             XmlUtils.beginDocument(parser, "permissions");
1552
1553             while (true) {
1554                 XmlUtils.nextElement(parser);
1555                 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
1556                     break;
1557                 }
1558
1559                 String name = parser.getName();
1560                 if ("group".equals(name)) {
1561                     String gidStr = parser.getAttributeValue(null, "gid");
1562                     if (gidStr != null) {
1563                         int gid = Process.getGidForName(gidStr);
1564                         mGlobalGids = appendInt(mGlobalGids, gid);
1565                     } else {
1566                         Slog.w(TAG, "<group> without gid at "
1567                                 + parser.getPositionDescription());
1568                     }
1569
1570                     XmlUtils.skipCurrentTag(parser);
1571                     continue;
1572                 } else if ("permission".equals(name)) {
1573                     String perm = parser.getAttributeValue(null, "name");
1574                     if (perm == null) {
1575                         Slog.w(TAG, "<permission> without name at "
1576                                 + parser.getPositionDescription());
1577                         XmlUtils.skipCurrentTag(parser);
1578                         continue;
1579                     }
1580                     perm = perm.intern();
1581                     readPermission(parser, perm);
1582
1583                 } else if ("assign-permission".equals(name)) {
1584                     String perm = parser.getAttributeValue(null, "name");
1585                     if (perm == null) {
1586                         Slog.w(TAG, "<assign-permission> without name at "
1587                                 + parser.getPositionDescription());
1588                         XmlUtils.skipCurrentTag(parser);
1589                         continue;
1590                     }
1591                     String uidStr = parser.getAttributeValue(null, "uid");
1592                     if (uidStr == null) {
1593                         Slog.w(TAG, "<assign-permission> without uid at "
1594                                 + parser.getPositionDescription());
1595                         XmlUtils.skipCurrentTag(parser);
1596                         continue;
1597                     }
1598                     int uid = Process.getUidForName(uidStr);
1599                     if (uid < 0) {
1600                         Slog.w(TAG, "<assign-permission> with unknown uid \""
1601                                 + uidStr + "\" at "
1602                                 + parser.getPositionDescription());
1603                         XmlUtils.skipCurrentTag(parser);
1604                         continue;
1605                     }
1606                     perm = perm.intern();
1607                     HashSet<String> perms = mSystemPermissions.get(uid);
1608                     if (perms == null) {
1609                         perms = new HashSet<String>();
1610                         mSystemPermissions.put(uid, perms);
1611                     }
1612                     perms.add(perm);
1613                     XmlUtils.skipCurrentTag(parser);
1614
1615                 } else if ("library".equals(name)) {
1616                     String lname = parser.getAttributeValue(null, "name");
1617                     String lfile = parser.getAttributeValue(null, "file");
1618                     if (lname == null) {
1619                         Slog.w(TAG, "<library> without name at "
1620                                 + parser.getPositionDescription());
1621                     } else if (lfile == null) {
1622                         Slog.w(TAG, "<library> without file at "
1623                                 + parser.getPositionDescription());
1624                     } else {
1625                         //Log.i(TAG, "Got library " + lname + " in " + lfile);
1626                         mSharedLibraries.put(lname, new SharedLibraryEntry(lfile, null));
1627                     }
1628                     XmlUtils.skipCurrentTag(parser);
1629                     continue;
1630
1631                 } else if ("feature".equals(name)) {
1632                     String fname = parser.getAttributeValue(null, "name");
1633                     if (fname == null) {
1634                         Slog.w(TAG, "<feature> without name at "
1635                                 + parser.getPositionDescription());
1636                     } else {
1637                         //Log.i(TAG, "Got feature " + fname);
1638                         FeatureInfo fi = new FeatureInfo();
1639                         fi.name = fname;
1640                         mAvailableFeatures.put(fname, fi);
1641                     }
1642                     XmlUtils.skipCurrentTag(parser);
1643                     continue;
1644
1645                 } else {
1646                     XmlUtils.skipCurrentTag(parser);
1647                     continue;
1648                 }
1649
1650             }
1651             permReader.close();
1652         } catch (XmlPullParserException e) {
1653             Slog.w(TAG, "Got execption parsing permissions.", e);
1654         } catch (IOException e) {
1655             Slog.w(TAG, "Got execption parsing permissions.", e);
1656         }
1657     }
1658
1659     void readPermission(XmlPullParser parser, String name)
1660             throws IOException, XmlPullParserException {
1661
1662         name = name.intern();
1663
1664         BasePermission bp = mSettings.mPermissions.get(name);
1665         if (bp == null) {
1666             bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
1667             mSettings.mPermissions.put(name, bp);
1668         }
1669         int outerDepth = parser.getDepth();
1670         int type;
1671         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1672                && (type != XmlPullParser.END_TAG
1673                        || parser.getDepth() > outerDepth)) {
1674             if (type == XmlPullParser.END_TAG
1675                     || type == XmlPullParser.TEXT) {
1676                 continue;
1677             }
1678
1679             String tagName = parser.getName();
1680             if ("group".equals(tagName)) {
1681                 String gidStr = parser.getAttributeValue(null, "gid");
1682                 if (gidStr != null) {
1683                     int gid = Process.getGidForName(gidStr);
1684                     bp.gids = appendInt(bp.gids, gid);
1685                 } else {
1686                     Slog.w(TAG, "<group> without gid at "
1687                             + parser.getPositionDescription());
1688                 }
1689             }
1690             XmlUtils.skipCurrentTag(parser);
1691         }
1692     }
1693
1694     static int[] appendInts(int[] cur, int[] add) {
1695         if (add == null) return cur;
1696         if (cur == null) return add;
1697         final int N = add.length;
1698         for (int i=0; i<N; i++) {
1699             cur = appendInt(cur, add[i]);
1700         }
1701         return cur;
1702     }
1703
1704     static int[] removeInts(int[] cur, int[] rem) {
1705         if (rem == null) return cur;
1706         if (cur == null) return cur;
1707         final int N = rem.length;
1708         for (int i=0; i<N; i++) {
1709             cur = removeInt(cur, rem[i]);
1710         }
1711         return cur;
1712     }
1713
1714     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
1715         if (!sUserManager.exists(userId)) return null;
1716         PackageInfo pi;
1717         final PackageSetting ps = (PackageSetting) p.mExtras;
1718         if (ps == null) {
1719             return null;
1720         }
1721         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1722         final PackageUserState state = ps.readUserState(userId);
1723         return PackageParser.generatePackageInfo(p, gp.gids, flags,
1724                 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
1725                 state, userId);
1726     }
1727
1728     @Override
1729     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
1730         if (!sUserManager.exists(userId)) return null;
1731         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info");
1732         // reader
1733         synchronized (mPackages) {
1734             PackageParser.Package p = mPackages.get(packageName);
1735             if (DEBUG_PACKAGE_INFO)
1736                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1737             if (p != null) {
1738                 return generatePackageInfo(p, flags, userId);
1739             }
1740             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1741                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
1742             }
1743         }
1744         return null;
1745     }
1746
1747     public String[] currentToCanonicalPackageNames(String[] names) {
1748         String[] out = new String[names.length];
1749         // reader
1750         synchronized (mPackages) {
1751             for (int i=names.length-1; i>=0; i--) {
1752                 PackageSetting ps = mSettings.mPackages.get(names[i]);
1753                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1754             }
1755         }
1756         return out;
1757     }
1758     
1759     public String[] canonicalToCurrentPackageNames(String[] names) {
1760         String[] out = new String[names.length];
1761         // reader
1762         synchronized (mPackages) {
1763             for (int i=names.length-1; i>=0; i--) {
1764                 String cur = mSettings.mRenamedPackages.get(names[i]);
1765                 out[i] = cur != null ? cur : names[i];
1766             }
1767         }
1768         return out;
1769     }
1770
1771     @Override
1772     public int getPackageUid(String packageName, int userId) {
1773         if (!sUserManager.exists(userId)) return -1;
1774         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid");
1775         // reader
1776         synchronized (mPackages) {
1777             PackageParser.Package p = mPackages.get(packageName);
1778             if(p != null) {
1779                 return UserHandle.getUid(userId, p.applicationInfo.uid);
1780             }
1781             PackageSetting ps = mSettings.mPackages.get(packageName);
1782             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1783                 return -1;
1784             }
1785             p = ps.pkg;
1786             return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
1787         }
1788     }
1789
1790     public int[] getPackageGids(String packageName) {
1791         final boolean enforcedDefault = isPermissionEnforcedDefault(READ_EXTERNAL_STORAGE);
1792         // reader
1793         synchronized (mPackages) {
1794             PackageParser.Package p = mPackages.get(packageName);
1795             if (DEBUG_PACKAGE_INFO)
1796                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1797             if (p != null) {
1798                 final PackageSetting ps = (PackageSetting)p.mExtras;
1799                 final SharedUserSetting suid = ps.sharedUser;
1800                 int[] gids = suid != null ? suid.gids : ps.gids;
1801
1802                 // include GIDs for any unenforced permissions
1803                 if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE, enforcedDefault)) {
1804                     final BasePermission basePerm = mSettings.mPermissions.get(
1805                             READ_EXTERNAL_STORAGE);
1806                     gids = appendInts(gids, basePerm.gids);
1807                 }
1808
1809                 return gids;
1810             }
1811         }
1812         // stupid thing to indicate an error.
1813         return new int[0];
1814     }
1815
1816     static final PermissionInfo generatePermissionInfo(
1817             BasePermission bp, int flags) {
1818         if (bp.perm != null) {
1819             return PackageParser.generatePermissionInfo(bp.perm, flags);
1820         }
1821         PermissionInfo pi = new PermissionInfo();
1822         pi.name = bp.name;
1823         pi.packageName = bp.sourcePackage;
1824         pi.nonLocalizedLabel = bp.name;
1825         pi.protectionLevel = bp.protectionLevel;
1826         return pi;
1827     }
1828     
1829     public PermissionInfo getPermissionInfo(String name, int flags) {
1830         // reader
1831         synchronized (mPackages) {
1832             final BasePermission p = mSettings.mPermissions.get(name);
1833             if (p != null) {
1834                 return generatePermissionInfo(p, flags);
1835             }
1836             return null;
1837         }
1838     }
1839
1840     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
1841         // reader
1842         synchronized (mPackages) {
1843             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
1844             for (BasePermission p : mSettings.mPermissions.values()) {
1845                 if (group == null) {
1846                     if (p.perm == null || p.perm.info.group == null) {
1847                         out.add(generatePermissionInfo(p, flags));
1848                     }
1849                 } else {
1850                     if (p.perm != null && group.equals(p.perm.info.group)) {
1851                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
1852                     }
1853                 }
1854             }
1855
1856             if (out.size() > 0) {
1857                 return out;
1858             }
1859             return mPermissionGroups.containsKey(group) ? out : null;
1860         }
1861     }
1862
1863     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
1864         // reader
1865         synchronized (mPackages) {
1866             return PackageParser.generatePermissionGroupInfo(
1867                     mPermissionGroups.get(name), flags);
1868         }
1869     }
1870
1871     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1872         // reader
1873         synchronized (mPackages) {
1874             final int N = mPermissionGroups.size();
1875             ArrayList<PermissionGroupInfo> out
1876                     = new ArrayList<PermissionGroupInfo>(N);
1877             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
1878                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
1879             }
1880             return out;
1881         }
1882     }
1883
1884     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
1885             int userId) {
1886         if (!sUserManager.exists(userId)) return null;
1887         PackageSetting ps = mSettings.mPackages.get(packageName);
1888         if (ps != null) {
1889             if (ps.pkg == null) {
1890                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
1891                         flags, userId);
1892                 if (pInfo != null) {
1893                     return pInfo.applicationInfo;
1894                 }
1895                 return null;
1896             }
1897             return PackageParser.generateApplicationInfo(ps.pkg, flags,
1898                     ps.readUserState(userId), userId);
1899         }
1900         return null;
1901     }
1902
1903     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
1904             int userId) {
1905         if (!sUserManager.exists(userId)) return null;
1906         PackageSetting ps = mSettings.mPackages.get(packageName);
1907         if (ps != null) {
1908             PackageParser.Package pkg = ps.pkg;
1909             if (pkg == null) {
1910                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
1911                     return null;
1912                 }
1913                 pkg = new PackageParser.Package(packageName);
1914                 pkg.applicationInfo.packageName = packageName;
1915                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
1916                 pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
1917                 pkg.applicationInfo.sourceDir = ps.codePathString;
1918                 pkg.applicationInfo.dataDir =
1919                         getDataPathForPackage(packageName, 0).getPath();
1920                 pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
1921             }
1922             // pkg.mSetEnabled = ps.getEnabled(userId);
1923             // pkg.mSetStopped = ps.getStopped(userId);
1924             return generatePackageInfo(pkg, flags, userId);
1925         }
1926         return null;
1927     }
1928
1929     @Override
1930     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
1931         if (!sUserManager.exists(userId)) return null;
1932         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info");
1933         // writer
1934         synchronized (mPackages) {
1935             PackageParser.Package p = mPackages.get(packageName);
1936             if (DEBUG_PACKAGE_INFO) Log.v(
1937                     TAG, "getApplicationInfo " + packageName
1938                     + ": " + p);
1939             if (p != null) {
1940                 PackageSetting ps = mSettings.mPackages.get(packageName);
1941                 if (ps == null) return null;
1942                 // Note: isEnabledLP() does not apply here - always return info
1943                 return PackageParser.generateApplicationInfo(
1944                         p, flags, ps.readUserState(userId), userId);
1945             }
1946             if ("android".equals(packageName)||"system".equals(packageName)) {
1947                 return mAndroidApplication;
1948             }
1949             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1950                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
1951             }
1952         }
1953         return null;
1954     }
1955
1956
1957     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
1958         mContext.enforceCallingOrSelfPermission(
1959                 android.Manifest.permission.CLEAR_APP_CACHE, null);
1960         // Queue up an async operation since clearing cache may take a little while.
1961         mHandler.post(new Runnable() {
1962             public void run() {
1963                 mHandler.removeCallbacks(this);
1964                 int retCode = -1;
1965                 synchronized (mInstallLock) {
1966                     retCode = mInstaller.freeCache(freeStorageSize);
1967                     if (retCode < 0) {
1968                         Slog.w(TAG, "Couldn't clear application caches");
1969                     }
1970                 }
1971                 if (observer != null) {
1972                     try {
1973                         observer.onRemoveCompleted(null, (retCode >= 0));
1974                     } catch (RemoteException e) {
1975                         Slog.w(TAG, "RemoveException when invoking call back");
1976                     }
1977                 }
1978             }
1979         });
1980     }
1981
1982     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
1983         mContext.enforceCallingOrSelfPermission(
1984                 android.Manifest.permission.CLEAR_APP_CACHE, null);
1985         // Queue up an async operation since clearing cache may take a little while.
1986         mHandler.post(new Runnable() {
1987             public void run() {
1988                 mHandler.removeCallbacks(this);
1989                 int retCode = -1;
1990                 synchronized (mInstallLock) {
1991                     retCode = mInstaller.freeCache(freeStorageSize);
1992                     if (retCode < 0) {
1993                         Slog.w(TAG, "Couldn't clear application caches");
1994                     }
1995                 }
1996                 if(pi != null) {
1997                     try {
1998                         // Callback via pending intent
1999                         int code = (retCode >= 0) ? 1 : 0;
2000                         pi.sendIntent(null, code, null,
2001                                 null, null);
2002                     } catch (SendIntentException e1) {
2003                         Slog.i(TAG, "Failed to send pending intent");
2004                     }
2005                 }
2006             }
2007         });
2008     }
2009
2010     @Override
2011     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
2012         if (!sUserManager.exists(userId)) return null;
2013         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info");
2014         synchronized (mPackages) {
2015             PackageParser.Activity a = mActivities.mActivities.get(component);
2016
2017             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
2018             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2019                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2020                 if (ps == null) return null;
2021                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2022                         userId);
2023             }
2024             if (mResolveComponentName.equals(component)) {
2025                 return mResolveActivity;
2026             }
2027         }
2028         return null;
2029     }
2030
2031     @Override
2032     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
2033         if (!sUserManager.exists(userId)) return null;
2034         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info");
2035         synchronized (mPackages) {
2036             PackageParser.Activity a = mReceivers.mActivities.get(component);
2037             if (DEBUG_PACKAGE_INFO) Log.v(
2038                 TAG, "getReceiverInfo " + component + ": " + a);
2039             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
2040                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2041                 if (ps == null) return null;
2042                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
2043                         userId);
2044             }
2045         }
2046         return null;
2047     }
2048
2049     @Override
2050     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
2051         if (!sUserManager.exists(userId)) return null;
2052         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info");
2053         synchronized (mPackages) {
2054             PackageParser.Service s = mServices.mServices.get(component);
2055             if (DEBUG_PACKAGE_INFO) Log.v(
2056                 TAG, "getServiceInfo " + component + ": " + s);
2057             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
2058                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2059                 if (ps == null) return null;
2060                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
2061                         userId);
2062             }
2063         }
2064         return null;
2065     }
2066
2067     @Override
2068     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
2069         if (!sUserManager.exists(userId)) return null;
2070         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info");
2071         synchronized (mPackages) {
2072             PackageParser.Provider p = mProvidersByComponent.get(component);
2073             if (DEBUG_PACKAGE_INFO) Log.v(
2074                 TAG, "getProviderInfo " + component + ": " + p);
2075             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
2076                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
2077                 if (ps == null) return null;
2078                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
2079                         userId);
2080             }
2081         }
2082         return null;
2083     }
2084
2085     public String[] getSystemSharedLibraryNames() {
2086         Set<String> libSet;
2087         synchronized (mPackages) {
2088             libSet = mSharedLibraries.keySet();
2089             int size = libSet.size();
2090             if (size > 0) {
2091                 String[] libs = new String[size];
2092                 libSet.toArray(libs);
2093                 return libs;
2094             }
2095         }
2096         return null;
2097     }
2098
2099     public FeatureInfo[] getSystemAvailableFeatures() {
2100         Collection<FeatureInfo> featSet;
2101         synchronized (mPackages) {
2102             featSet = mAvailableFeatures.values();
2103             int size = featSet.size();
2104             if (size > 0) {
2105                 FeatureInfo[] features = new FeatureInfo[size+1];
2106                 featSet.toArray(features);
2107                 FeatureInfo fi = new FeatureInfo();
2108                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
2109                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
2110                 features[size] = fi;
2111                 return features;
2112             }
2113         }
2114         return null;
2115     }
2116
2117     public boolean hasSystemFeature(String name) {
2118         synchronized (mPackages) {
2119             return mAvailableFeatures.containsKey(name);
2120         }
2121     }
2122
2123     private void checkValidCaller(int uid, int userId) {
2124         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
2125             return;
2126
2127         throw new SecurityException("Caller uid=" + uid
2128                 + " is not privileged to communicate with user=" + userId);
2129     }
2130
2131     public int checkPermission(String permName, String pkgName) {
2132         final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
2133         synchronized (mPackages) {
2134             PackageParser.Package p = mPackages.get(pkgName);
2135             if (p != null && p.mExtras != null) {
2136                 PackageSetting ps = (PackageSetting)p.mExtras;
2137                 if (ps.sharedUser != null) {
2138                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
2139                         return PackageManager.PERMISSION_GRANTED;
2140                     }
2141                 } else if (ps.grantedPermissions.contains(permName)) {
2142                     return PackageManager.PERMISSION_GRANTED;
2143                 }
2144             }
2145             if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
2146                 return PackageManager.PERMISSION_GRANTED;
2147             }
2148         }
2149         return PackageManager.PERMISSION_DENIED;
2150     }
2151
2152     public int checkUidPermission(String permName, int uid) {
2153         final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
2154         synchronized (mPackages) {
2155             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2156             if (obj != null) {
2157                 GrantedPermissions gp = (GrantedPermissions)obj;
2158                 if (gp.grantedPermissions.contains(permName)) {
2159                     return PackageManager.PERMISSION_GRANTED;
2160                 }
2161             } else {
2162                 HashSet<String> perms = mSystemPermissions.get(uid);
2163                 if (perms != null && perms.contains(permName)) {
2164                     return PackageManager.PERMISSION_GRANTED;
2165                 }
2166             }
2167             if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
2168                 return PackageManager.PERMISSION_GRANTED;
2169             }
2170         }
2171         return PackageManager.PERMISSION_DENIED;
2172     }
2173
2174     /**
2175      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2176      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2177      * @param message the message to log on security exception
2178      * @return
2179      */
2180     private void enforceCrossUserPermission(int callingUid, int userId,
2181             boolean requireFullPermission, String message) {
2182         if (userId < 0) {
2183             throw new IllegalArgumentException("Invalid userId " + userId);
2184         }
2185         if (userId == UserHandle.getUserId(callingUid)) return;
2186         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
2187             if (requireFullPermission) {
2188                 mContext.enforceCallingOrSelfPermission(
2189                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2190             } else {
2191                 try {
2192                     mContext.enforceCallingOrSelfPermission(
2193                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2194                 } catch (SecurityException se) {
2195                     mContext.enforceCallingOrSelfPermission(
2196                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2197                 }
2198             }
2199         }
2200     }
2201
2202     private BasePermission findPermissionTreeLP(String permName) {
2203         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
2204             if (permName.startsWith(bp.name) &&
2205                     permName.length() > bp.name.length() &&
2206                     permName.charAt(bp.name.length()) == '.') {
2207                 return bp;
2208             }
2209         }
2210         return null;
2211     }
2212
2213     private BasePermission checkPermissionTreeLP(String permName) {
2214         if (permName != null) {
2215             BasePermission bp = findPermissionTreeLP(permName);
2216             if (bp != null) {
2217                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
2218                     return bp;
2219                 }
2220                 throw new SecurityException("Calling uid "
2221                         + Binder.getCallingUid()
2222                         + " is not allowed to add to permission tree "
2223                         + bp.name + " owned by uid " + bp.uid);
2224             }
2225         }
2226         throw new SecurityException("No permission tree found for " + permName);
2227     }
2228
2229     static boolean compareStrings(CharSequence s1, CharSequence s2) {
2230         if (s1 == null) {
2231             return s2 == null;
2232         }
2233         if (s2 == null) {
2234             return false;
2235         }
2236         if (s1.getClass() != s2.getClass()) {
2237             return false;
2238         }
2239         return s1.equals(s2);
2240     }
2241     
2242     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
2243         if (pi1.icon != pi2.icon) return false;
2244         if (pi1.logo != pi2.logo) return false;
2245         if (pi1.protectionLevel != pi2.protectionLevel) return false;
2246         if (!compareStrings(pi1.name, pi2.name)) return false;
2247         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
2248         // We'll take care of setting this one.
2249         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
2250         // These are not currently stored in settings.
2251         //if (!compareStrings(pi1.group, pi2.group)) return false;
2252         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
2253         //if (pi1.labelRes != pi2.labelRes) return false;
2254         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
2255         return true;
2256     }
2257     
2258     boolean addPermissionLocked(PermissionInfo info, boolean async) {
2259         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
2260             throw new SecurityException("Label must be specified in permission");
2261         }
2262         BasePermission tree = checkPermissionTreeLP(info.name);
2263         BasePermission bp = mSettings.mPermissions.get(info.name);
2264         boolean added = bp == null;
2265         boolean changed = true;
2266         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
2267         if (added) {
2268             bp = new BasePermission(info.name, tree.sourcePackage,
2269                     BasePermission.TYPE_DYNAMIC);
2270         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
2271             throw new SecurityException(
2272                     "Not allowed to modify non-dynamic permission "
2273                     + info.name);
2274         } else {
2275             if (bp.protectionLevel == fixedLevel
2276                     && bp.perm.owner.equals(tree.perm.owner)
2277                     && bp.uid == tree.uid
2278                     && comparePermissionInfos(bp.perm.info, info)) {
2279                 changed = false;
2280             }
2281         }
2282         bp.protectionLevel = fixedLevel;
2283         info = new PermissionInfo(info);
2284         info.protectionLevel = fixedLevel;
2285         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
2286         bp.perm.info.packageName = tree.perm.info.packageName;
2287         bp.uid = tree.uid;
2288         if (added) {
2289             mSettings.mPermissions.put(info.name, bp);
2290         }
2291         if (changed) {
2292             if (!async) {
2293                 mSettings.writeLPr();
2294             } else {
2295                 scheduleWriteSettingsLocked();
2296             }
2297         }
2298         return added;
2299     }
2300
2301     public boolean addPermission(PermissionInfo info) {
2302         synchronized (mPackages) {
2303             return addPermissionLocked(info, false);
2304         }
2305     }
2306
2307     public boolean addPermissionAsync(PermissionInfo info) {
2308         synchronized (mPackages) {
2309             return addPermissionLocked(info, true);
2310         }
2311     }
2312
2313     public void removePermission(String name) {
2314         synchronized (mPackages) {
2315             checkPermissionTreeLP(name);
2316             BasePermission bp = mSettings.mPermissions.get(name);
2317             if (bp != null) {
2318                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
2319                     throw new SecurityException(
2320                             "Not allowed to modify non-dynamic permission "
2321                             + name);
2322                 }
2323                 mSettings.mPermissions.remove(name);
2324                 mSettings.writeLPr();
2325             }
2326         }
2327     }
2328
2329     private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
2330         int index = pkg.requestedPermissions.indexOf(bp.name);
2331         if (index == -1) {
2332             throw new SecurityException("Package " + pkg.packageName
2333                     + " has not requested permission " + bp.name);
2334         }
2335         boolean isNormal =
2336                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2337                         == PermissionInfo.PROTECTION_NORMAL);
2338         boolean isDangerous =
2339                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
2340                         == PermissionInfo.PROTECTION_DANGEROUS);
2341         boolean isDevelopment =
2342                 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
2343
2344         if (!isNormal && !isDangerous && !isDevelopment) {
2345             throw new SecurityException("Permission " + bp.name
2346                     + " is not a changeable permission type");
2347         }
2348
2349         if (isNormal || isDangerous) {
2350             if (pkg.requestedPermissionsRequired.get(index)) {
2351                 throw new SecurityException("Can't change " + bp.name
2352                         + ". It is required by the application");
2353             }
2354         }
2355     }
2356
2357     public void grantPermission(String packageName, String permissionName) {
2358         mContext.enforceCallingOrSelfPermission(
2359                 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2360         synchronized (mPackages) {
2361             final PackageParser.Package pkg = mPackages.get(packageName);
2362             if (pkg == null) {
2363                 throw new IllegalArgumentException("Unknown package: " + packageName);
2364             }
2365             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2366             if (bp == null) {
2367                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2368             }
2369
2370             checkGrantRevokePermissions(pkg, bp);
2371
2372             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2373             if (ps == null) {
2374                 return;
2375             }
2376             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2377             if (gp.grantedPermissions.add(permissionName)) {
2378                 if (ps.haveGids) {
2379                     gp.gids = appendInts(gp.gids, bp.gids);
2380                 }
2381                 mSettings.writeLPr();
2382             }
2383         }
2384     }
2385
2386     public void revokePermission(String packageName, String permissionName) {
2387         int changedAppId = -1;
2388
2389         synchronized (mPackages) {
2390             final PackageParser.Package pkg = mPackages.get(packageName);
2391             if (pkg == null) {
2392                 throw new IllegalArgumentException("Unknown package: " + packageName);
2393             }
2394             if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
2395                 mContext.enforceCallingOrSelfPermission(
2396                         android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
2397             }
2398             final BasePermission bp = mSettings.mPermissions.get(permissionName);
2399             if (bp == null) {
2400                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
2401             }
2402
2403             checkGrantRevokePermissions(pkg, bp);
2404
2405             final PackageSetting ps = (PackageSetting) pkg.mExtras;
2406             if (ps == null) {
2407                 return;
2408             }
2409             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
2410             if (gp.grantedPermissions.remove(permissionName)) {
2411                 gp.grantedPermissions.remove(permissionName);
2412                 if (ps.haveGids) {
2413                     gp.gids = removeInts(gp.gids, bp.gids);
2414                 }
2415                 mSettings.writeLPr();
2416                 changedAppId = ps.appId;
2417             }
2418         }
2419
2420         if (changedAppId >= 0) {
2421             // We changed the perm on someone, kill its processes.
2422             IActivityManager am = ActivityManagerNative.getDefault();
2423             if (am != null) {
2424                 final int callingUserId = UserHandle.getCallingUserId();
2425                 final long ident = Binder.clearCallingIdentity();
2426                 try {
2427                     //XXX we should only revoke for the calling user's app permissions,
2428                     // but for now we impact all users.
2429                     //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
2430                     //        "revoke " + permissionName);
2431                     int[] users = sUserManager.getUserIds();
2432                     for (int user : users) {
2433                         am.killUid(UserHandle.getUid(user, changedAppId),
2434                                 "revoke " + permissionName);
2435                     }
2436                 } catch (RemoteException e) {
2437                 } finally {
2438                     Binder.restoreCallingIdentity(ident);
2439                 }
2440             }
2441         }
2442     }
2443
2444     public boolean isProtectedBroadcast(String actionName) {
2445         synchronized (mPackages) {
2446             return mProtectedBroadcasts.contains(actionName);
2447         }
2448     }
2449
2450     public int checkSignatures(String pkg1, String pkg2) {
2451         synchronized (mPackages) {
2452             final PackageParser.Package p1 = mPackages.get(pkg1);
2453             final PackageParser.Package p2 = mPackages.get(pkg2);
2454             if (p1 == null || p1.mExtras == null
2455                     || p2 == null || p2.mExtras == null) {
2456                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2457             }
2458             return compareSignatures(p1.mSignatures, p2.mSignatures);
2459         }
2460     }
2461
2462     public int checkUidSignatures(int uid1, int uid2) {
2463         // Map to base uids.
2464         uid1 = UserHandle.getAppId(uid1);
2465         uid2 = UserHandle.getAppId(uid2);
2466         // reader
2467         synchronized (mPackages) {
2468             Signature[] s1;
2469             Signature[] s2;
2470             Object obj = mSettings.getUserIdLPr(uid1);
2471             if (obj != null) {
2472                 if (obj instanceof SharedUserSetting) {
2473                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2474                 } else if (obj instanceof PackageSetting) {
2475                     s1 = ((PackageSetting)obj).signatures.mSignatures;
2476                 } else {
2477                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2478                 }
2479             } else {
2480                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2481             }
2482             obj = mSettings.getUserIdLPr(uid2);
2483             if (obj != null) {
2484                 if (obj instanceof SharedUserSetting) {
2485                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2486                 } else if (obj instanceof PackageSetting) {
2487                     s2 = ((PackageSetting)obj).signatures.mSignatures;
2488                 } else {
2489                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2490                 }
2491             } else {
2492                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2493             }
2494             return compareSignatures(s1, s2);
2495         }
2496     }
2497
2498     static int compareSignatures(Signature[] s1, Signature[] s2) {
2499         if (s1 == null) {
2500             return s2 == null
2501                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
2502                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2503         }
2504         if (s2 == null) {
2505             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2506         }
2507         HashSet<Signature> set1 = new HashSet<Signature>();
2508         for (Signature sig : s1) {
2509             set1.add(sig);
2510         }
2511         HashSet<Signature> set2 = new HashSet<Signature>();
2512         for (Signature sig : s2) {
2513             set2.add(sig);
2514         }
2515         // Make sure s2 contains all signatures in s1.
2516         if (set1.equals(set2)) {
2517             return PackageManager.SIGNATURE_MATCH;
2518         }
2519         return PackageManager.SIGNATURE_NO_MATCH;
2520     }
2521
2522     public String[] getPackagesForUid(int uid) {
2523         uid = UserHandle.getAppId(uid);
2524         // reader
2525         synchronized (mPackages) {
2526             Object obj = mSettings.getUserIdLPr(uid);
2527             if (obj instanceof SharedUserSetting) {
2528                 final SharedUserSetting sus = (SharedUserSetting) obj;
2529                 final int N = sus.packages.size();
2530                 final String[] res = new String[N];
2531                 final Iterator<PackageSetting> it = sus.packages.iterator();
2532                 int i = 0;
2533                 while (it.hasNext()) {
2534                     res[i++] = it.next().name;
2535                 }
2536                 return res;
2537             } else if (obj instanceof PackageSetting) {
2538                 final PackageSetting ps = (PackageSetting) obj;
2539                 return new String[] { ps.name };
2540             }
2541         }
2542         return null;
2543     }
2544
2545     public String getNameForUid(int uid) {
2546         // reader
2547         synchronized (mPackages) {
2548             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
2549             if (obj instanceof SharedUserSetting) {
2550                 final SharedUserSetting sus = (SharedUserSetting) obj;
2551                 return sus.name + ":" + sus.userId;
2552             } else if (obj instanceof PackageSetting) {
2553                 final PackageSetting ps = (PackageSetting) obj;
2554                 return ps.name;
2555             }
2556         }
2557         return null;
2558     }
2559
2560     public int getUidForSharedUser(String sharedUserName) {
2561         if(sharedUserName == null) {
2562             return -1;
2563         }
2564         // reader
2565         synchronized (mPackages) {
2566             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2567             if (suid == null) {
2568                 return -1;
2569             }
2570             return suid.userId;
2571         }
2572     }
2573
2574     @Override
2575     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2576             int flags, int userId) {
2577         if (!sUserManager.exists(userId)) return null;
2578         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
2579         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
2580         return chooseBestActivity(intent, resolvedType, flags, query, userId);
2581     }
2582
2583     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
2584             int flags, List<ResolveInfo> query, int userId) {
2585         if (query != null) {
2586             final int N = query.size();
2587             if (N == 1) {
2588                 return query.get(0);
2589             } else if (N > 1) {
2590                 // If there is more than one activity with the same priority,
2591                 // then let the user decide between them.
2592                 ResolveInfo r0 = query.get(0);
2593                 ResolveInfo r1 = query.get(1);
2594                 if (DEBUG_INTENT_MATCHING) {
2595                     Log.d(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
2596                             + r1.activityInfo.name + "=" + r1.priority);
2597                 }
2598                 // If the first activity has a higher priority, or a different
2599                 // default, then it is always desireable to pick it.
2600                 if (r0.priority != r1.priority
2601                         || r0.preferredOrder != r1.preferredOrder
2602                         || r0.isDefault != r1.isDefault) {
2603                     return query.get(0);
2604                 }
2605                 // If we have saved a preference for a preferred activity for
2606                 // this Intent, use that.
2607                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
2608                         flags, query, r0.priority, userId);
2609                 if (ri != null) {
2610                     return ri;
2611                 }
2612                 if (userId != 0) {
2613                     ri = new ResolveInfo(mResolveInfo);
2614                     ri.activityInfo = new ActivityInfo(ri.activityInfo);
2615                     ri.activityInfo.applicationInfo = new ApplicationInfo(
2616                             ri.activityInfo.applicationInfo);
2617                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
2618                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
2619                     return ri;
2620                 }
2621                 return mResolveInfo;
2622             }
2623         }
2624         return null;
2625     }
2626
2627     ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
2628             int flags, List<ResolveInfo> query, int priority, int userId) {
2629         if (!sUserManager.exists(userId)) return null;
2630         // writer
2631         synchronized (mPackages) {
2632             if (intent.getSelector() != null) {
2633                 intent = intent.getSelector(); 
2634             }
2635             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
2636             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
2637             List<PreferredActivity> prefs = pir != null
2638                     ? pir.queryIntent(intent, resolvedType,
2639                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
2640                     : null;
2641             if (prefs != null && prefs.size() > 0) {
2642                 // First figure out how good the original match set is.
2643                 // We will only allow preferred activities that came
2644                 // from the same match quality.
2645                 int match = 0;
2646
2647                 if (DEBUG_PREFERRED) {
2648                     Log.v(TAG, "Figuring out best match...");
2649                 }
2650
2651                 final int N = query.size();
2652                 for (int j=0; j<N; j++) {
2653                     final ResolveInfo ri = query.get(j);
2654                     if (DEBUG_PREFERRED) {
2655                         Log.v(TAG, "Match for " + ri.activityInfo + ": 0x"
2656                                 + Integer.toHexString(match));
2657                     }
2658                     if (ri.match > match) {
2659                         match = ri.match;
2660                     }
2661                 }
2662
2663                 if (DEBUG_PREFERRED) {
2664                     Log.v(TAG, "Best match: 0x" + Integer.toHexString(match));
2665                 }
2666
2667                 match &= IntentFilter.MATCH_CATEGORY_MASK;
2668                 final int M = prefs.size();
2669                 for (int i=0; i<M; i++) {
2670                     final PreferredActivity pa = prefs.get(i);
2671                     if (pa.mPref.mMatch != match) {
2672                         continue;
2673                     }
2674                     final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
2675                             flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
2676                     if (DEBUG_PREFERRED) {
2677                         Log.v(TAG, "Got preferred activity:");
2678                         if (ai != null) {
2679                             ai.dump(new LogPrinter(Log.VERBOSE, TAG), "  ");
2680                         } else {
2681                             Log.v(TAG, "  null");
2682                         }
2683                     }
2684                     if (ai == null) {
2685                         // This previously registered preferred activity
2686                         // component is no longer known.  Most likely an update
2687                         // to the app was installed and in the new version this
2688                         // component no longer exists.  Clean it up by removing
2689                         // it from the preferred activities list, and skip it.
2690                         Slog.w(TAG, "Removing dangling preferred activity: "
2691                                 + pa.mPref.mComponent);
2692                         pir.removeFilter(pa);
2693                         continue;
2694                     }
2695                     for (int j=0; j<N; j++) {
2696                         final ResolveInfo ri = query.get(j);
2697                         if (!ri.activityInfo.applicationInfo.packageName
2698                                 .equals(ai.applicationInfo.packageName)) {
2699                             continue;
2700                         }
2701                         if (!ri.activityInfo.name.equals(ai.name)) {
2702                             continue;
2703                         }
2704
2705                         // Okay we found a previously set preferred app.
2706                         // If the result set is different from when this
2707                         // was created, we need to clear it and re-ask the
2708                         // user their preference.
2709                         if (!pa.mPref.sameSet(query, priority)) {
2710                             Slog.i(TAG, "Result set changed, dropping preferred activity for "
2711                                     + intent + " type " + resolvedType);
2712                             pir.removeFilter(pa);
2713                             return null;
2714                         }
2715
2716                         // Yay!
2717                         return ri;
2718                     }
2719                 }
2720             }
2721         }
2722         return null;
2723     }
2724
2725     @Override
2726     public List<ResolveInfo> queryIntentActivities(Intent intent,
2727             String resolvedType, int flags, int userId) {
2728         if (!sUserManager.exists(userId)) return Collections.emptyList();
2729         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities");
2730         ComponentName comp = intent.getComponent();
2731         if (comp == null) {
2732             if (intent.getSelector() != null) {
2733                 intent = intent.getSelector(); 
2734                 comp = intent.getComponent();
2735             }
2736         }
2737
2738         if (comp != null) {
2739             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2740             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
2741             if (ai != null) {
2742                 final ResolveInfo ri = new ResolveInfo();
2743                 ri.activityInfo = ai;
2744                 list.add(ri);
2745             }
2746             return list;
2747         }
2748
2749         // reader
2750         synchronized (mPackages) {
2751             final String pkgName = intent.getPackage();
2752             if (pkgName == null) {
2753                 return mActivities.queryIntent(intent, resolvedType, flags, userId);
2754             }
2755             final PackageParser.Package pkg = mPackages.get(pkgName);
2756             if (pkg != null) {
2757                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
2758                         pkg.activities, userId);
2759             }
2760             return new ArrayList<ResolveInfo>();
2761         }
2762     }
2763
2764     @Override
2765     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
2766             Intent[] specifics, String[] specificTypes, Intent intent,
2767             String resolvedType, int flags, int userId) {
2768         if (!sUserManager.exists(userId)) return Collections.emptyList();
2769         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
2770                 "query intent activity options");
2771         final String resultsAction = intent.getAction();
2772
2773         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
2774                 | PackageManager.GET_RESOLVED_FILTER, userId);
2775
2776         if (DEBUG_INTENT_MATCHING) {
2777             Log.v(TAG, "Query " + intent + ": " + results);
2778         }
2779
2780         int specificsPos = 0;
2781         int N;
2782
2783         // todo: note that the algorithm used here is O(N^2).  This
2784         // isn't a problem in our current environment, but if we start running
2785         // into situations where we have more than 5 or 10 matches then this
2786         // should probably be changed to something smarter...
2787
2788         // First we go through and resolve each of the specific items
2789         // that were supplied, taking care of removing any corresponding
2790         // duplicate items in the generic resolve list.
2791         if (specifics != null) {
2792             for (int i=0; i<specifics.length; i++) {
2793                 final Intent sintent = specifics[i];
2794                 if (sintent == null) {
2795                     continue;
2796                 }
2797
2798                 if (DEBUG_INTENT_MATCHING) {
2799                     Log.v(TAG, "Specific #" + i + ": " + sintent);
2800                 }
2801
2802                 String action = sintent.getAction();
2803                 if (resultsAction != null && resultsAction.equals(action)) {
2804                     // If this action was explicitly requested, then don't
2805                     // remove things that have it.
2806                     action = null;
2807                 }
2808
2809                 ResolveInfo ri = null;
2810                 ActivityInfo ai = null;
2811
2812                 ComponentName comp = sintent.getComponent();
2813                 if (comp == null) {
2814                     ri = resolveIntent(
2815                         sintent,
2816                         specificTypes != null ? specificTypes[i] : null,
2817                             flags, userId);
2818                     if (ri == null) {
2819                         continue;
2820                     }
2821                     if (ri == mResolveInfo) {
2822                         // ACK!  Must do something better with this.
2823                     }
2824                     ai = ri.activityInfo;
2825                     comp = new ComponentName(ai.applicationInfo.packageName,
2826                             ai.name);
2827                 } else {
2828                     ai = getActivityInfo(comp, flags, userId);
2829                     if (ai == null) {
2830                         continue;
2831                     }
2832                 }
2833
2834                 // Look for any generic query activities that are duplicates
2835                 // of this specific one, and remove them from the results.
2836                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
2837                 N = results.size();
2838                 int j;
2839                 for (j=specificsPos; j<N; j++) {
2840                     ResolveInfo sri = results.get(j);
2841                     if ((sri.activityInfo.name.equals(comp.getClassName())
2842                             && sri.activityInfo.applicationInfo.packageName.equals(
2843                                     comp.getPackageName()))
2844                         || (action != null && sri.filter.matchAction(action))) {
2845                         results.remove(j);
2846                         if (DEBUG_INTENT_MATCHING) Log.v(
2847                             TAG, "Removing duplicate item from " + j
2848                             + " due to specific " + specificsPos);
2849                         if (ri == null) {
2850                             ri = sri;
2851                         }
2852                         j--;
2853                         N--;
2854                     }
2855                 }
2856
2857                 // Add this specific item to its proper place.
2858                 if (ri == null) {
2859                     ri = new ResolveInfo();
2860                     ri.activityInfo = ai;
2861                 }
2862                 results.add(specificsPos, ri);
2863                 ri.specificIndex = i;
2864                 specificsPos++;
2865             }
2866         }
2867
2868         // Now we go through the remaining generic results and remove any
2869         // duplicate actions that are found here.
2870         N = results.size();
2871         for (int i=specificsPos; i<N-1; i++) {
2872             final ResolveInfo rii = results.get(i);
2873             if (rii.filter == null) {
2874                 continue;
2875             }
2876
2877             // Iterate over all of the actions of this result's intent
2878             // filter...  typically this should be just one.
2879             final Iterator<String> it = rii.filter.actionsIterator();
2880             if (it == null) {
2881                 continue;
2882             }
2883             while (it.hasNext()) {
2884                 final String action = it.next();
2885                 if (resultsAction != null && resultsAction.equals(action)) {
2886                     // If this action was explicitly requested, then don't
2887                     // remove things that have it.
2888                     continue;
2889                 }
2890                 for (int j=i+1; j<N; j++) {
2891                     final ResolveInfo rij = results.get(j);
2892                     if (rij.filter != null && rij.filter.hasAction(action)) {
2893                         results.remove(j);
2894                         if (DEBUG_INTENT_MATCHING) Log.v(
2895                             TAG, "Removing duplicate item from " + j
2896                             + " due to action " + action + " at " + i);
2897                         j--;
2898                         N--;
2899                     }
2900                 }
2901             }
2902
2903             // If the caller didn't request filter information, drop it now
2904             // so we don't have to marshall/unmarshall it.
2905             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
2906                 rii.filter = null;
2907             }
2908         }
2909
2910         // Filter out the caller activity if so requested.
2911         if (caller != null) {
2912             N = results.size();
2913             for (int i=0; i<N; i++) {
2914                 ActivityInfo ainfo = results.get(i).activityInfo;
2915                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
2916                         && caller.getClassName().equals(ainfo.name)) {
2917                     results.remove(i);
2918                     break;
2919                 }
2920             }
2921         }
2922
2923         // If the caller didn't request filter information,
2924         // drop them now so we don't have to
2925         // marshall/unmarshall it.
2926         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
2927             N = results.size();
2928             for (int i=0; i<N; i++) {
2929                 results.get(i).filter = null;
2930             }
2931         }
2932
2933         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
2934         return results;
2935     }
2936
2937     @Override
2938     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
2939             int userId) {
2940         if (!sUserManager.exists(userId)) return Collections.emptyList();
2941         ComponentName comp = intent.getComponent();
2942         if (comp == null) {
2943             if (intent.getSelector() != null) {
2944                 intent = intent.getSelector(); 
2945                 comp = intent.getComponent();
2946             }
2947         }
2948         if (comp != null) {
2949             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2950             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
2951             if (ai != null) {
2952                 ResolveInfo ri = new ResolveInfo();
2953                 ri.activityInfo = ai;
2954                 list.add(ri);
2955             }
2956             return list;
2957         }
2958
2959         // reader
2960         synchronized (mPackages) {
2961             String pkgName = intent.getPackage();
2962             if (pkgName == null) {
2963                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
2964             }
2965             final PackageParser.Package pkg = mPackages.get(pkgName);
2966             if (pkg != null) {
2967                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
2968                         userId);
2969             }
2970             return null;
2971         }
2972     }
2973
2974     @Override
2975     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
2976         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
2977         if (!sUserManager.exists(userId)) return null;
2978         if (query != null) {
2979             if (query.size() >= 1) {
2980                 // If there is more than one service with the same priority,
2981                 // just arbitrarily pick the first one.
2982                 return query.get(0);
2983             }
2984         }
2985         return null;
2986     }
2987
2988     @Override
2989     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
2990             int userId) {
2991         if (!sUserManager.exists(userId)) return Collections.emptyList();
2992         ComponentName comp = intent.getComponent();
2993         if (comp == null) {
2994             if (intent.getSelector() != null) {
2995                 intent = intent.getSelector(); 
2996                 comp = intent.getComponent();
2997             }
2998         }
2999         if (comp != null) {
3000             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
3001             final ServiceInfo si = getServiceInfo(comp, flags, userId);
3002             if (si != null) {
3003                 final ResolveInfo ri = new ResolveInfo();
3004                 ri.serviceInfo = si;
3005                 list.add(ri);
3006             }
3007             return list;
3008         }
3009
3010         // reader
3011         synchronized (mPackages) {
3012             String pkgName = intent.getPackage();
3013             if (pkgName == null) {
3014                 return mServices.queryIntent(intent, resolvedType, flags, userId);
3015             }
3016             final PackageParser.Package pkg = mPackages.get(pkgName);
3017             if (pkg != null) {
3018                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
3019                         userId);
3020             }
3021             return null;
3022         }
3023     }
3024
3025     @Override
3026     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
3027         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3028
3029         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages");
3030
3031         // writer
3032         synchronized (mPackages) {
3033             ArrayList<PackageInfo> list;
3034             if (listUninstalled) {
3035                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
3036                 for (PackageSetting ps : mSettings.mPackages.values()) {
3037                     PackageInfo pi;
3038                     if (ps.pkg != null) {
3039                         pi = generatePackageInfo(ps.pkg, flags, userId);
3040                     } else {
3041                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3042                     }
3043                     if (pi != null) {
3044                         list.add(pi);
3045                     }
3046                 }
3047             } else {
3048                 list = new ArrayList<PackageInfo>(mPackages.size());
3049                 for (PackageParser.Package p : mPackages.values()) {
3050                     PackageInfo pi = generatePackageInfo(p, flags, userId);
3051                     if (pi != null) {
3052                         list.add(pi);
3053                     }
3054                 }
3055             }
3056
3057             return new ParceledListSlice<PackageInfo>(list);
3058         }
3059     }
3060
3061     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
3062             String[] permissions, boolean[] tmp, int flags, int userId) {
3063         int numMatch = 0;
3064         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
3065         for (int i=0; i<permissions.length; i++) {
3066             if (gp.grantedPermissions.contains(permissions[i])) {
3067                 tmp[i] = true;
3068                 numMatch++;
3069             } else {
3070                 tmp[i] = false;
3071             }
3072         }
3073         if (numMatch == 0) {
3074             return;
3075         }
3076         PackageInfo pi;
3077         if (ps.pkg != null) {
3078             pi = generatePackageInfo(ps.pkg, flags, userId);
3079         } else {
3080             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
3081         }
3082         if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
3083             if (numMatch == permissions.length) {
3084                 pi.requestedPermissions = permissions;
3085             } else {
3086                 pi.requestedPermissions = new String[numMatch];
3087                 numMatch = 0;
3088                 for (int i=0; i<permissions.length; i++) {
3089                     if (tmp[i]) {
3090                         pi.requestedPermissions[numMatch] = permissions[i];
3091                         numMatch++;
3092                     }
3093                 }
3094             }
3095         }
3096         list.add(pi);
3097     }
3098
3099     @Override
3100     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
3101             String[] permissions, int flags, int userId) {
3102         if (!sUserManager.exists(userId)) return null;
3103         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3104
3105         // writer
3106         synchronized (mPackages) {
3107             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
3108             boolean[] tmpBools = new boolean[permissions.length];
3109             if (listUninstalled) {
3110                 for (PackageSetting ps : mSettings.mPackages.values()) {
3111                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
3112                 }
3113             } else {
3114                 for (PackageParser.Package pkg : mPackages.values()) {
3115                     PackageSetting ps = (PackageSetting)pkg.mExtras;
3116                     if (ps != null) {
3117                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
3118                                 userId);
3119                     }
3120                 }
3121             }
3122
3123             return new ParceledListSlice<PackageInfo>(list);
3124         }
3125     }
3126
3127     @Override
3128     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
3129         if (!sUserManager.exists(userId)) return null;
3130         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
3131
3132         // writer
3133         synchronized (mPackages) {
3134             ArrayList<ApplicationInfo> list;
3135             if (listUninstalled) {
3136                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
3137                 for (PackageSetting ps : mSettings.mPackages.values()) {
3138                     ApplicationInfo ai;
3139                     if (ps.pkg != null) {
3140                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
3141                                 ps.readUserState(userId), userId);
3142                     } else {
3143                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
3144                     }
3145                     if (ai != null) {
3146                         list.add(ai);
3147                     }
3148                 }
3149             } else {
3150                 list = new ArrayList<ApplicationInfo>(mPackages.size());
3151                 for (PackageParser.Package p : mPackages.values()) {
3152                     if (p.mExtras != null) {
3153                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3154                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
3155                         if (ai != null) {
3156                             list.add(ai);
3157                         }
3158                     }
3159                 }
3160             }
3161
3162             return new ParceledListSlice<ApplicationInfo>(list);
3163         }
3164     }
3165
3166     public List<ApplicationInfo> getPersistentApplications(int flags) {
3167         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
3168
3169         // reader
3170         synchronized (mPackages) {
3171             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
3172             final int userId = UserHandle.getCallingUserId();
3173             while (i.hasNext()) {
3174                 final PackageParser.Package p = i.next();
3175                 if (p.applicationInfo != null
3176                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
3177                         && (!mSafeMode || isSystemApp(p))) {
3178                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
3179                     if (ps != null) {
3180                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
3181                                 ps.readUserState(userId), userId);
3182                         if (ai != null) {
3183                             finalList.add(ai);
3184                         }
3185                     }
3186                 }
3187             }
3188         }
3189
3190         return finalList;
3191     }
3192
3193     @Override
3194     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
3195         if (!sUserManager.exists(userId)) return null;
3196         // reader
3197         synchronized (mPackages) {
3198             final PackageParser.Provider provider = mProviders.get(name);
3199             PackageSetting ps = provider != null
3200                     ? mSettings.mPackages.get(provider.owner.packageName)
3201                     : null;
3202             return ps != null
3203                     && mSettings.isEnabledLPr(provider.info, flags, userId)
3204                     && (!mSafeMode || (provider.info.applicationInfo.flags
3205                             &ApplicationInfo.FLAG_SYSTEM) != 0)
3206                     ? PackageParser.generateProviderInfo(provider, flags,
3207                             ps.readUserState(userId), userId)
3208                     : null;
3209         }
3210     }
3211
3212     /**
3213      * @deprecated
3214      */
3215     @Deprecated
3216     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
3217         // reader
3218         synchronized (mPackages) {
3219             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet()
3220                     .iterator();
3221             final int userId = UserHandle.getCallingUserId();
3222             while (i.hasNext()) {
3223                 Map.Entry<String, PackageParser.Provider> entry = i.next();
3224                 PackageParser.Provider p = entry.getValue();
3225                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3226
3227                 if (ps != null && p.syncable
3228                         && (!mSafeMode || (p.info.applicationInfo.flags
3229                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
3230                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
3231                             ps.readUserState(userId), userId);
3232                     if (info != null) {
3233                         outNames.add(entry.getKey());
3234                         outInfo.add(info);
3235                     }
3236                 }
3237             }
3238         }
3239     }
3240
3241     public List<ProviderInfo> queryContentProviders(String processName,
3242             int uid, int flags) {
3243         ArrayList<ProviderInfo> finalList = null;
3244
3245         // reader
3246         synchronized (mPackages) {
3247             final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
3248             final int userId = processName != null ?
3249                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
3250             while (i.hasNext()) {
3251                 final PackageParser.Provider p = i.next();
3252                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
3253                 if (ps != null && p.info.authority != null
3254                         && (processName == null
3255                                 || (p.info.processName.equals(processName)
3256                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
3257                         && mSettings.isEnabledLPr(p.info, flags, userId)
3258                         && (!mSafeMode
3259                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
3260                     if (finalList == null) {
3261                         finalList = new ArrayList<ProviderInfo>(3);
3262                     }
3263                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
3264                             ps.readUserState(userId), userId);
3265                     if (info != null) {
3266                         finalList.add(info);
3267                     }
3268                 }
3269             }
3270         }
3271
3272         if (finalList != null) {
3273             Collections.sort(finalList, mProviderInitOrderSorter);
3274         }
3275
3276         return finalList;
3277     }
3278
3279     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
3280             int flags) {
3281         // reader
3282         synchronized (mPackages) {
3283             final PackageParser.Instrumentation i = mInstrumentation.get(name);
3284             return PackageParser.generateInstrumentationInfo(i, flags);
3285         }
3286     }
3287
3288     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
3289             int flags) {
3290         ArrayList<InstrumentationInfo> finalList =
3291             new ArrayList<InstrumentationInfo>();
3292
3293         // reader
3294         synchronized (mPackages) {
3295             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
3296             while (i.hasNext()) {
3297                 final PackageParser.Instrumentation p = i.next();
3298                 if (targetPackage == null
3299                         || targetPackage.equals(p.info.targetPackage)) {
3300                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
3301                             flags);
3302                     if (ii != null) {
3303                         finalList.add(ii);
3304                     }
3305                 }
3306             }
3307         }
3308
3309         return finalList;
3310     }
3311
3312     private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
3313         String[] files = dir.list();
3314         if (files == null) {
3315             Log.d(TAG, "No files in app dir " + dir);
3316             return;
3317         }
3318
3319         if (DEBUG_PACKAGE_SCANNING) {
3320             Log.d(TAG, "Scanning app dir " + dir);
3321         }
3322
3323         int i;
3324         for (i=0; i<files.length; i++) {
3325             File file = new File(dir, files[i]);
3326             if (!isPackageFilename(files[i])) {
3327                 // Ignore entries which are not apk's
3328                 continue;
3329             }
3330             PackageParser.Package pkg = scanPackageLI(file,
3331                     flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
3332             // Don't mess around with apps in system partition.
3333             if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
3334                     mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
3335                 // Delete the apk
3336                 Slog.w(TAG, "Cleaning up failed install of " + file);
3337                 file.delete();
3338             }
3339         }
3340     }
3341
3342     private static File getSettingsProblemFile() {
3343         File dataDir = Environment.getDataDirectory();
3344         File systemDir = new File(dataDir, "system");
3345         File fname = new File(systemDir, "uiderrors.txt");
3346         return fname;
3347     }
3348     
3349     static void reportSettingsProblem(int priority, String msg) {
3350         try {
3351             File fname = getSettingsProblemFile();
3352             FileOutputStream out = new FileOutputStream(fname, true);
3353             PrintWriter pw = new PrintWriter(out);
3354             SimpleDateFormat formatter = new SimpleDateFormat();
3355             String dateString = formatter.format(new Date(System.currentTimeMillis()));
3356             pw.println(dateString + ": " + msg);
3357             pw.close();
3358             FileUtils.setPermissions(
3359                     fname.toString(),
3360                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
3361                     -1, -1);
3362         } catch (java.io.IOException e) {
3363         }
3364         Slog.println(priority, TAG, msg);
3365     }
3366
3367     private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
3368             PackageParser.Package pkg, File srcFile, int parseFlags) {
3369         if (GET_CERTIFICATES) {
3370             if (ps != null
3371                     && ps.codePath.equals(srcFile)
3372                     && ps.timeStamp == srcFile.lastModified()) {
3373                 if (ps.signatures.mSignatures != null
3374                         && ps.signatures.mSignatures.length != 0) {
3375                     // Optimization: reuse the existing cached certificates
3376                     // if the package appears to be unchanged.
3377                     pkg.mSignatures = ps.signatures.mSignatures;
3378                     return true;
3379                 }
3380                 
3381                 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures.  Collecting certs again to recover them.");
3382             } else {
3383                 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
3384             }
3385             
3386             if (!pp.collectCertificates(pkg, parseFlags)) {
3387                 mLastScanError = pp.getParseError();
3388                 return false;
3389             }
3390         }
3391         return true;
3392     }
3393
3394     /*
3395      *  Scan a package and return the newly parsed package.
3396      *  Returns null in case of errors and the error code is stored in mLastScanError
3397      */
3398     private PackageParser.Package scanPackageLI(File scanFile,
3399             int parseFlags, int scanMode, long currentTime, UserHandle user) {
3400         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
3401         String scanPath = scanFile.getPath();
3402         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath);
3403         parseFlags |= mDefParseFlags;
3404         PackageParser pp = new PackageParser(scanPath);
3405         pp.setSeparateProcesses(mSeparateProcesses);
3406         pp.setOnlyCoreApps(mOnlyCore);
3407         final PackageParser.Package pkg = pp.parsePackage(scanFile,
3408                 scanPath, mMetrics, parseFlags);
3409         if (pkg == null) {
3410             mLastScanError = pp.getParseError();
3411             return null;
3412         }
3413         PackageSetting ps = null;
3414         PackageSetting updatedPkg;
3415         // reader
3416         synchronized (mPackages) {
3417             // Look to see if we already know about this package.
3418             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
3419             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
3420                 // This package has been renamed to its original name.  Let's
3421                 // use that.
3422                 ps = mSettings.peekPackageLPr(oldName);
3423             }
3424             // If there was no original package, see one for the real package name.
3425             if (ps == null) {
3426                 ps = mSettings.peekPackageLPr(pkg.packageName);
3427             }
3428             // Check to see if this package could be hiding/updating a system
3429             // package.  Must look for it either under the original or real
3430             // package name depending on our state.
3431             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
3432             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
3433         }
3434         // First check if this is a system package that may involve an update
3435         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
3436             if (ps != null && !ps.codePath.equals(scanFile)) {
3437                 // The path has changed from what was last scanned...  check the
3438                 // version of the new path against what we have stored to determine
3439                 // what to do.
3440                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
3441                 if (pkg.mVersionCode < ps.versionCode) {
3442                     // The system package has been updated and the code path does not match
3443                     // Ignore entry. Skip it.
3444                     Log.i(TAG, "Package " + ps.name + " at " + scanFile
3445                             + " ignored: updated version " + ps.versionCode
3446                             + " better than this " + pkg.mVersionCode);
3447                     if (!updatedPkg.codePath.equals(scanFile)) {
3448                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
3449                                 + ps.name + " changing from " + updatedPkg.codePathString
3450                                 + " to " + scanFile);
3451                         updatedPkg.codePath = scanFile;
3452                         updatedPkg.codePathString = scanFile.toString();                        
3453                     }
3454                     updatedPkg.pkg = pkg;
3455                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
3456                     return null;
3457                 } else {
3458                     // The current app on the system partion is better than
3459                     // what we have updated to on the data partition; switch
3460                     // back to the system partition version.
3461                     // At this point, its safely assumed that package installation for
3462                     // apps in system partition will go through. If not there won't be a working
3463                     // version of the app
3464                     // writer
3465                     synchronized (mPackages) {
3466                         // Just remove the loaded entries from package lists.
3467                         mPackages.remove(ps.name);
3468                     }
3469                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile
3470                             + "reverting from " + ps.codePathString
3471                             + ": new version " + pkg.mVersionCode
3472                             + " better than installed " + ps.versionCode);
3473
3474                     InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
3475                             ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3476                     synchronized (mInstallLock) {
3477                         args.cleanUpResourcesLI();
3478                     }
3479                     synchronized (mPackages) {
3480                         mSettings.enableSystemPackageLPw(ps.name);
3481                     }
3482                 }
3483             }
3484         }
3485
3486         if (updatedPkg != null) {
3487             // An updated system app will not have the PARSE_IS_SYSTEM flag set
3488             // initially
3489             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
3490         }
3491         // Verify certificates against what was last scanned
3492         if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
3493             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
3494             return null;
3495         }
3496
3497         /*
3498          * A new system app appeared, but we already had a non-system one of the
3499          * same name installed earlier.
3500          */
3501         boolean shouldHideSystemApp = false;
3502         if (updatedPkg == null && ps != null
3503                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
3504             /*
3505              * Check to make sure the signatures match first. If they don't,
3506              * wipe the installed application and its data.
3507              */
3508             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
3509                     != PackageManager.SIGNATURE_MATCH) {
3510                 if (DEBUG_INSTALL) Slog.d(TAG, "Signature mismatch!");
3511                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
3512                 ps = null;
3513             } else {
3514                 /*
3515                  * If the newly-added system app is an older version than the
3516                  * already installed version, hide it. It will be scanned later
3517                  * and re-added like an update.
3518                  */
3519                 if (pkg.mVersionCode < ps.versionCode) {
3520                     shouldHideSystemApp = true;
3521                 } else {
3522                     /*
3523                      * The newly found system app is a newer version that the
3524                      * one previously installed. Simply remove the
3525                      * already-installed application and replace it with our own
3526                      * while keeping the application data.
3527                      */
3528                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
3529                             + ps.codePathString + ": new version " + pkg.mVersionCode
3530                             + " better than installed " + ps.versionCode);
3531                     InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
3532                             ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
3533                     synchronized (mInstallLock) {
3534                         args.cleanUpResourcesLI();
3535                     }
3536                 }
3537             }
3538         }
3539
3540         // The apk is forward locked (not public) if its code and resources
3541         // are kept in different files.
3542         // TODO grab this value from PackageSettings
3543         if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
3544             parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
3545         }
3546
3547         String codePath = null;
3548         String resPath = null;
3549         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
3550             if (ps != null && ps.resourcePathString != null) {
3551                 resPath = ps.resourcePathString;
3552             } else {
3553                 // Should not happen at all. Just log an error.
3554                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
3555             }
3556         } else {
3557             resPath = pkg.mScanPath;
3558         }
3559         codePath = pkg.mScanPath;
3560         // Set application objects path explicitly.
3561         setApplicationInfoPaths(pkg, codePath, resPath);
3562         // Note that we invoke the following method only if we are about to unpack an application
3563         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
3564                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
3565
3566         /*
3567          * If the system app should be overridden by a previously installed
3568          * data, hide the system app now and let the /data/app scan pick it up
3569          * again.
3570          */
3571         if (shouldHideSystemApp) {
3572             synchronized (mPackages) {
3573                 /*
3574                  * We have to grant systems permissions before we hide, because
3575                  * grantPermissions will assume the package update is trying to
3576                  * expand its permissions.
3577                  */
3578                 grantPermissionsLPw(pkg, true);
3579                 mSettings.disableSystemPackageLPw(pkg.packageName);
3580             }
3581         }
3582
3583         return scannedPkg;
3584     }
3585
3586     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
3587             String destResPath) {
3588         pkg.mPath = pkg.mScanPath = destCodePath;
3589         pkg.applicationInfo.sourceDir = destCodePath;
3590         pkg.applicationInfo.publicSourceDir = destResPath;
3591     }
3592
3593     private static String fixProcessName(String defProcessName,
3594             String processName, int uid) {
3595         if (processName == null) {
3596             return defProcessName;
3597         }
3598         return processName;
3599     }
3600
3601     private boolean verifySignaturesLP(PackageSetting pkgSetting,
3602             PackageParser.Package pkg) {
3603         if (pkgSetting.signatures.mSignatures != null) {
3604             // Already existing package. Make sure signatures match
3605             if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
3606                 PackageManager.SIGNATURE_MATCH) {
3607                     Slog.e(TAG, "Package " + pkg.packageName
3608                             + " signatures do not match the previously installed version; ignoring!");
3609                     mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
3610                     return false;
3611                 }
3612         }
3613         // Check for shared user signatures
3614         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
3615             if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
3616                     pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
3617                 Slog.e(TAG, "Package " + pkg.packageName
3618                         + " has no signatures that match those in shared user "
3619                         + pkgSetting.sharedUser.name + "; ignoring!");
3620                 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
3621                 return false;
3622             }
3623         }
3624         return true;
3625     }
3626
3627     /**
3628      * Enforces that only the system UID or root's UID can call a method exposed
3629      * via Binder.
3630      *
3631      * @param message used as message if SecurityException is thrown
3632      * @throws SecurityException if the caller is not system or root
3633      */
3634     private static final void enforceSystemOrRoot(String message) {
3635         final int uid = Binder.getCallingUid();
3636         if (uid != Process.SYSTEM_UID && uid != 0) {
3637             throw new SecurityException(message);
3638         }
3639     }
3640
3641     public void performBootDexOpt() {
3642         HashSet<PackageParser.Package> pkgs = null;
3643         synchronized (mPackages) {
3644             pkgs = mDeferredDexOpt;
3645             mDeferredDexOpt = null;
3646         }
3647         if (pkgs != null) {
3648             int i = 0;
3649             for (PackageParser.Package pkg : pkgs) {
3650                 if (!isFirstBoot()) {
3651                     i++;
3652                     try {
3653                         ActivityManagerNative.getDefault().showBootMessage(
3654                                 mContext.getResources().getString(
3655                                         com.android.internal.R.string.android_upgrading_apk,
3656                                         i, pkgs.size()), true);
3657                     } catch (RemoteException e) {
3658                     }
3659                 }
3660                 PackageParser.Package p = pkg;
3661                 synchronized (mInstallLock) {
3662                     if (!p.mDidDexOpt) {
3663                         performDexOptLI(p, false, false, true);
3664                     }
3665                 }
3666             }
3667         }
3668     }
3669
3670     public boolean performDexOpt(String packageName) {
3671         enforceSystemOrRoot("Only the system can request dexopt be performed");
3672
3673         if (!mNoDexOpt) {
3674             return false;
3675         }
3676
3677         PackageParser.Package p;
3678         synchronized (mPackages) {
3679             p = mPackages.get(packageName);
3680             if (p == null || p.mDidDexOpt) {
3681                 return false;
3682             }
3683         }
3684         synchronized (mInstallLock) {
3685             return performDexOptLI(p, false, false, true) == DEX_OPT_PERFORMED;
3686         }
3687     }
3688
3689     private void performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer,
3690             HashSet<String> done) {
3691         for (int i=0; i<libs.size(); i++) {
3692             PackageParser.Package libPkg;
3693             String libName;
3694             synchronized (mPackages) {
3695                 libName = libs.get(i);
3696                 SharedLibraryEntry lib = mSharedLibraries.get(libName);
3697                 if (lib != null && lib.apk != null) {
3698                     libPkg = mPackages.get(lib.apk);
3699                 } else {
3700                     libPkg = null;
3701                 }
3702             }
3703             if (libPkg != null && !done.contains(libName)) {
3704                 performDexOptLI(libPkg, forceDex, defer, done);
3705             }
3706         }
3707     }
3708
3709     static final int DEX_OPT_SKIPPED = 0;
3710     static final int DEX_OPT_PERFORMED = 1;
3711     static final int DEX_OPT_DEFERRED = 2;
3712     static final int DEX_OPT_FAILED = -1;
3713
3714     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
3715             HashSet<String> done) {
3716         boolean performed = false;
3717         if (done != null) {
3718             done.add(pkg.packageName);
3719             if (pkg.usesLibraries != null) {
3720                 performDexOptLibsLI(pkg.usesLibraries, forceDex, defer, done);
3721             }
3722             if (pkg.usesOptionalLibraries != null) {
3723                 performDexOptLibsLI(pkg.usesOptionalLibraries, forceDex, defer, done);
3724             }
3725         }
3726         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
3727             String path = pkg.mScanPath;
3728             int ret = 0;
3729             try {
3730                 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
3731                     if (!forceDex && defer) {
3732                         if (mDeferredDexOpt == null) {
3733                             mDeferredDexOpt = new HashSet<PackageParser.Package>();
3734                         }
3735                         mDeferredDexOpt.add(pkg);
3736                         return DEX_OPT_DEFERRED;
3737                     } else {
3738                         Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
3739                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
3740                         ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg));
3741                         pkg.mDidDexOpt = true;
3742                         performed = true;
3743                     }
3744                 }
3745             } catch (FileNotFoundException e) {
3746                 Slog.w(TAG, "Apk not found for dexopt: " + path);
3747                 ret = -1;
3748             } catch (IOException e) {
3749                 Slog.w(TAG, "IOException reading apk: " + path, e);
3750                 ret = -1;
3751             } catch (dalvik.system.StaleDexCacheError e) {
3752                 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
3753                 ret = -1;
3754             } catch (Exception e) {
3755                 Slog.w(TAG, "Exception when doing dexopt : ", e);
3756                 ret = -1;
3757             }
3758             if (ret < 0) {
3759                 //error from installer
3760                 return DEX_OPT_FAILED;
3761             }
3762         }
3763
3764         return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
3765     }
3766
3767     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
3768             boolean inclDependencies) {
3769         HashSet<String> done;
3770         boolean performed = false;
3771         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
3772             done = new HashSet<String>();
3773             done.add(pkg.packageName);
3774         } else {
3775             done = null;
3776         }
3777         return performDexOptLI(pkg, forceDex, defer, done);
3778     }
3779
3780     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
3781         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3782             Slog.w(TAG, "Unable to update from " + oldPkg.name
3783                     + " to " + newPkg.packageName
3784                     + ": old package not in system partition");
3785             return false;
3786         } else if (mPackages.get(oldPkg.name) != null) {
3787             Slog.w(TAG, "Unable to update from " + oldPkg.name
3788                     + " to " + newPkg.packageName
3789                     + ": old package still exists");
3790             return false;
3791         }
3792         return true;
3793     }
3794
3795     File getDataPathForUser(int userId) {
3796         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
3797     }
3798
3799     private void writeAppwithABI2Internal(String fileName, HashMap<Integer, String> map) {
3800         File outputFile;
3801         FileOutputStream out = null;
3802         File appDataDir = new File("/data/data");
3803
3804         try {
3805             File tempFile = File.createTempFile("tmp", "tmp", appDataDir);
3806             String tempFilePath = tempFile.getPath();
3807             outputFile = new File(fileName);
3808             if (FileUtils.setPermissions(tempFilePath,
3809                 FileUtils.S_IRUSR | FileUtils.S_IWUSR |
3810                 FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1) != 0
3811                 || !tempFile.renameTo(outputFile)) {
3812                 tempFile.delete();
3813             }
3814             out = new FileOutputStream(outputFile);
3815             Iterator<HashMap.Entry<Integer, String>>
3816             it = map.entrySet().iterator();
3817             while (it.hasNext()) {
3818                 HashMap.Entry<Integer, String> ent = it.next();
3819                 int userID = ent.getKey().intValue();
3820                 out.write(userID & 0xff);
3821                 out.write((userID>>8)  & 0xff);
3822                 out.write((userID>>16) & 0xff);
3823                 out.write((userID>>24) & 0xff);
3824                 Slog.i(TAG, "Data written:"+ userID);
3825             }
3826         } catch (Exception e) {
3827             Slog.e(TAG, "File Access Error: Not Able to write Data into " + fileName);
3828         } finally {
3829             try {
3830                 if (out != null) {
3831                     out.close();
3832                     Slog.i(TAG, "Data written into " + fileName);
3833                 }
3834             } catch (IOException e) {}
3835         }
3836     }
3837
3838     private void writeAppwithABI2() {
3839         writeAppwithABI2Internal(new String("/data/data/.appwithABI2"), mPackagesMatchABI2);
3840     }
3841
3842     private void writeAppwithABI2Neon() {
3843         writeAppwithABI2Internal(new String("/data/data/.appwithABI2neon"), mPackagesMatchABI2Neon);
3844     }
3845
3846     private File getDataPathForPackage(String packageName, int userId) {
3847         /*
3848          * Until we fully support multiple users, return the directory we
3849          * previously would have. The PackageManagerTests will need to be
3850          * revised when this is changed back..
3851          */
3852         if (userId == 0) {
3853             return new File(mAppDataDir, packageName);
3854         } else {
3855             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
3856                 + File.separator + packageName);
3857         }
3858     }
3859
3860     private int createDataDirsLI(String packageName, int uid, String seinfo) {
3861         int[] users = sUserManager.getUserIds();
3862         int res = mInstaller.install(packageName, uid, uid, seinfo);
3863         if (res < 0) {
3864             return res;
3865         }
3866         for (int user : users) {
3867             if (user != 0) {
3868                 res = mInstaller.createUserData(packageName,
3869                         UserHandle.getUid(user, uid), user);
3870                 if (res < 0) {
3871                     return res;
3872                 }
3873             }
3874         }
3875         return res;
3876     }
3877
3878     private int removeDataDirsLI(String packageName) {
3879         int[] users = sUserManager.getUserIds();
3880         int res = 0;
3881         for (int user : users) {
3882             int resInner = mInstaller.remove(packageName, user);
3883             if (resInner < 0) {
3884                 res = resInner;
3885             }
3886         }
3887
3888         final File nativeLibraryFile = new File(mAppLibInstallDir, packageName);
3889         NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
3890         if (!nativeLibraryFile.delete()) {
3891             Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath());
3892         }
3893
3894         return res;
3895     }
3896
3897     private int addSharedLibraryLPw(final SharedLibraryEntry file, int num,
3898             PackageParser.Package changingLib) {
3899         if (file.path != null) {
3900             mTmpSharedLibraries[num] = file.path;
3901             return num+1;
3902         }
3903         PackageParser.Package p = mPackages.get(file.apk);
3904         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
3905             // If we are doing this while in the middle of updating a library apk,
3906             // then we need to make sure to use that new apk for determining the
3907             // dependencies here.  (We haven't yet finished committing the new apk
3908             // to the package manager state.)
3909             if (p == null || p.packageName.equals(changingLib.packageName)) {
3910                 p = changingLib;
3911             }
3912         }
3913         if (p != null) {
3914             String path = p.mPath;
3915             for (int i=0; i<num; i++) {
3916                 if (mTmpSharedLibraries[i].equals(path)) {
3917                     return num;
3918                 }
3919             }
3920             mTmpSharedLibraries[num] = p.mPath;
3921             return num+1;
3922         }
3923         return num;
3924     }
3925
3926     private boolean updateSharedLibrariesLPw(PackageParser.Package pkg,
3927             PackageParser.Package changingLib) {
3928         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
3929             if (mTmpSharedLibraries == null ||
3930                     mTmpSharedLibraries.length < mSharedLibraries.size()) {
3931                 mTmpSharedLibraries = new String[mSharedLibraries.size()];
3932             }
3933             int num = 0;
3934             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
3935             for (int i=0; i<N; i++) {
3936                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
3937                 if (file == null) {
3938                     Slog.e(TAG, "Package " + pkg.packageName
3939                             + " requires unavailable shared library "
3940                             + pkg.usesLibraries.get(i) + "; failing!");
3941                     mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
3942                     return false;
3943                 }
3944                 num = addSharedLibraryLPw(file, num, changingLib);
3945             }
3946             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
3947             for (int i=0; i<N; i++) {
3948                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
3949                 if (file == null) {
3950                     Slog.w(TAG, "Package " + pkg.packageName
3951                             + " desires unavailable shared library "
3952                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
3953                 } else {
3954                     num = addSharedLibraryLPw(file, num, changingLib);
3955                 }
3956             }
3957             if (num > 0) {
3958                 pkg.usesLibraryFiles = new String[num];
3959                 System.arraycopy(mTmpSharedLibraries, 0,
3960                         pkg.usesLibraryFiles, 0, num);
3961             } else {
3962                 pkg.usesLibraryFiles = null;
3963             }
3964         }
3965         return true;
3966     }
3967
3968     private static boolean hasString(List<String> list, List<String> which) {
3969         if (list == null) {
3970             return false;
3971         }
3972         for (int i=list.size()-1; i>=0; i--) {
3973             for (int j=which.size()-1; j>=0; j--) {
3974                 if (which.get(j).equals(list.get(i))) {
3975                     return true;
3976                 }
3977             }
3978         }
3979         return false;
3980     }
3981
3982     private void updateAllSharedLibrariesLPw() {
3983         for (PackageParser.Package pkg : mPackages.values()) {
3984             updateSharedLibrariesLPw(pkg, null);
3985         }
3986     }
3987
3988     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
3989             PackageParser.Package changingPkg) {
3990         ArrayList<PackageParser.Package> res = null;
3991         for (PackageParser.Package pkg : mPackages.values()) {
3992             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
3993                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
3994                 if (res == null) {
3995                     res = new ArrayList<PackageParser.Package>();
3996                 }
3997                 res.add(pkg);
3998                 updateSharedLibrariesLPw(pkg, changingPkg);
3999             }
4000         }
4001         return res;
4002     }
4003
4004     private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
4005             int parseFlags, int scanMode, long currentTime, UserHandle user) {
4006         File scanFile = new File(pkg.mScanPath);
4007         if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
4008                 pkg.applicationInfo.publicSourceDir == null) {
4009             // Bail out. The resource and code paths haven't been set.
4010             Slog.w(TAG, " Code and resource paths haven't been set correctly");
4011             mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
4012             return null;
4013         }
4014         mScanningPath = scanFile;
4015
4016         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
4017             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
4018         }
4019
4020         if (pkg.packageName.equals("android")) {
4021             synchronized (mPackages) {
4022                 if (mAndroidApplication != null) {
4023                     Slog.w(TAG, "*************************************************");
4024                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
4025                     Slog.w(TAG, " file=" + mScanningPath);
4026                     Slog.w(TAG, "*************************************************");
4027                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4028                     return null;
4029                 }
4030
4031                 // Set up information for our fall-back user intent resolution
4032                 // activity.
4033                 mPlatformPackage = pkg;
4034                 pkg.mVersionCode = mSdkVersion;
4035                 mAndroidApplication = pkg.applicationInfo;
4036                 mResolveActivity.applicationInfo = mAndroidApplication;
4037                 mResolveActivity.name = ResolverActivity.class.getName();
4038                 mResolveActivity.packageName = mAndroidApplication.packageName;
4039                 mResolveActivity.processName = "system:ui";
4040                 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
4041                 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
4042                 mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
4043                 mResolveActivity.exported = true;
4044                 mResolveActivity.enabled = true;
4045                 mResolveInfo.activityInfo = mResolveActivity;
4046                 mResolveInfo.priority = 0;
4047                 mResolveInfo.preferredOrder = 0;
4048                 mResolveInfo.match = 0;
4049                 mResolveComponentName = new ComponentName(
4050                         mAndroidApplication.packageName, mResolveActivity.name);
4051             }
4052         }
4053
4054         if (DEBUG_PACKAGE_SCANNING) {
4055             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4056                 Log.d(TAG, "Scanning package " + pkg.packageName);
4057         }
4058
4059         if (mPackages.containsKey(pkg.packageName)
4060                 || mSharedLibraries.containsKey(pkg.packageName)) {
4061             Slog.w(TAG, "Application package " + pkg.packageName
4062                     + " already installed.  Skipping duplicate.");
4063             mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
4064             return null;
4065         }
4066
4067         // Initialize package source and resource directories
4068         File destCodeFile = new File(pkg.applicationInfo.sourceDir);
4069         File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
4070
4071         SharedUserSetting suid = null;
4072         PackageSetting pkgSetting = null;
4073
4074         if (!isSystemApp(pkg)) {
4075             // Only system apps can use these features.
4076             pkg.mOriginalPackages = null;
4077             pkg.mRealPackage = null;
4078             pkg.mAdoptPermissions = null;
4079         }
4080
4081         // writer
4082         synchronized (mPackages) {
4083             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4084                 // Check all shared libraries and map to their actual file path.
4085                 // We only do this here for apps not on a system dir, because those
4086                 // are the only ones that can fail an install due to this.  We
4087                 // will take care of the system apps by updating all of their
4088                 // library paths after the scan is done.
4089                 if (!updateSharedLibrariesLPw(pkg, null)) {
4090                     return null;
4091                 }
4092             }
4093
4094             if (pkg.mSharedUserId != null) {
4095                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId,
4096                         pkg.applicationInfo.flags, true);
4097                 if (suid == null) {
4098                     Slog.w(TAG, "Creating application package " + pkg.packageName
4099                             + " for shared user failed");
4100                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4101                     return null;
4102                 }
4103                 if (DEBUG_PACKAGE_SCANNING) {
4104                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4105                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
4106                                 + "): packages=" + suid.packages);
4107                 }
4108             }
4109             
4110             // Check if we are renaming from an original package name.
4111             PackageSetting origPackage = null;
4112             String realName = null;
4113             if (pkg.mOriginalPackages != null) {
4114                 // This package may need to be renamed to a previously
4115                 // installed name.  Let's check on that...
4116                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
4117                 if (pkg.mOriginalPackages.contains(renamed)) {
4118                     // This package had originally been installed as the
4119                     // original name, and we have already taken care of
4120                     // transitioning to the new one.  Just update the new
4121                     // one to continue using the old name.
4122                     realName = pkg.mRealPackage;
4123                     if (!pkg.packageName.equals(renamed)) {
4124                         // Callers into this function may have already taken
4125                         // care of renaming the package; only do it here if
4126                         // it is not already done.
4127                         pkg.setPackageName(renamed);
4128                     }
4129                     
4130                 } else {
4131                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
4132                         if ((origPackage = mSettings.peekPackageLPr(
4133                                 pkg.mOriginalPackages.get(i))) != null) {
4134                             // We do have the package already installed under its
4135                             // original name...  should we use it?
4136                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
4137                                 // New package is not compatible with original.
4138                                 origPackage = null;
4139                                 continue;
4140                             } else if (origPackage.sharedUser != null) {
4141                                 // Make sure uid is compatible between packages.
4142                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
4143                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
4144                                             + " to " + pkg.packageName + ": old uid "
4145                                             + origPackage.sharedUser.name
4146                                             + " differs from " + pkg.mSharedUserId);
4147                                     origPackage = null;
4148                                     continue;
4149                                 }
4150                             } else {
4151                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
4152                                         + pkg.packageName + " to old name " + origPackage.name);
4153                             }
4154                             break;
4155                         }
4156                     }
4157                 }
4158             }
4159             
4160             if (mTransferedPackages.contains(pkg.packageName)) {
4161                 Slog.w(TAG, "Package " + pkg.packageName
4162                         + " was transferred to another, but its .apk remains");
4163             }
4164
4165             String abi2 = SystemProperties.get("ro.product.cpu.abi2");
4166             if (abi2.length() != 0) {
4167                 // abi2 is set, houdini is enabled
4168                 PackageSetting p = mSettings.mPackages.get(pkg.packageName);
4169                 if ((p != null) && (!p.codePath.equals(destCodeFile))){
4170
4171                    // Already existing package. Make sure not upgrade to black list
4172                     int result = NativeLibraryHelper.listNativeBinariesLI(scanFile);
4173
4174                     if (result == PackageManager.INSTALL_ABI2_SUCCEEDED) {
4175                         ICheckExt check = new CheckExt();
4176                         if(check.doCheck(pkg.packageName, new String("filter"))){
4177                             Slog.i(TAG, "Reject application in black list::" + pkg.packageName);
4178                             mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
4179                             return null;
4180                         }
4181                     }
4182
4183                 }
4184             }
4185             
4186             // Just create the setting, don't add it yet. For already existing packages
4187             // the PkgSetting exists already and doesn't have to be created.
4188             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
4189                     destResourceFile, pkg.applicationInfo.nativeLibraryDir,
4190                     pkg.applicationInfo.flags, user, false);
4191             if (pkgSetting == null) {
4192                 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
4193                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4194                 return null;
4195             }
4196             
4197             if (pkgSetting.origPackage != null) {
4198                 // If we are first transitioning from an original package,
4199                 // fix up the new package's name now.  We need to do this after
4200                 // looking up the package under its new name, so getPackageLP
4201                 // can take care of fiddling things correctly.
4202                 pkg.setPackageName(origPackage.name);
4203                 
4204                 // File a report about this.
4205                 String msg = "New package " + pkgSetting.realName
4206                         + " renamed to replace old package " + pkgSetting.name;
4207                 reportSettingsProblem(Log.WARN, msg);
4208                 
4209                 // Make a note of it.
4210                 mTransferedPackages.add(origPackage.name);
4211                 
4212                 // No longer need to retain this.
4213                 pkgSetting.origPackage = null;
4214             }
4215             
4216             if (realName != null) {
4217                 // Make a note of it.
4218                 mTransferedPackages.add(pkg.packageName);
4219             }
4220             
4221             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
4222                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
4223             }
4224
4225             if (mFoundPolicyFile) {
4226                 SELinuxMMAC.assignSeinfoValue(pkg);
4227             }
4228
4229             pkg.applicationInfo.uid = pkgSetting.appId;
4230             pkg.mExtras = pkgSetting;
4231
4232             if (!verifySignaturesLP(pkgSetting, pkg)) {
4233                 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
4234                     return null;
4235                 }
4236                 // The signature has changed, but this package is in the system
4237                 // image...  let's recover!
4238                 pkgSetting.signatures.mSignatures = pkg.mSignatures;
4239                 // However...  if this package is part of a shared user, but it
4240                 // doesn't match the signature of the shared user, let's fail.
4241                 // What this means is that you can't change the signatures
4242                 // associated with an overall shared user, which doesn't seem all
4243                 // that unreasonable.
4244                 if (pkgSetting.sharedUser != null) {
4245                     if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
4246                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
4247                         Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
4248                         mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
4249                         return null;
4250                     }
4251                 }
4252                 // File a report about this.
4253                 String msg = "System package " + pkg.packageName
4254                         + " signature changed; retaining data.";
4255                 reportSettingsProblem(Log.WARN, msg);
4256             }
4257
4258             // Verify that this new package doesn't have any content providers
4259             // that conflict with existing packages.  Only do this if the
4260             // package isn't already installed, since we don't want to break
4261             // things that are installed.
4262             if ((scanMode&SCAN_NEW_INSTALL) != 0) {
4263                 final int N = pkg.providers.size();
4264                 int i;
4265                 for (i=0; i<N; i++) {
4266                     PackageParser.Provider p = pkg.providers.get(i);
4267                     if (p.info.authority != null) {
4268                         String names[] = p.info.authority.split(";");
4269                         for (int j = 0; j < names.length; j++) {
4270                             if (mProviders.containsKey(names[j])) {
4271                                 PackageParser.Provider other = mProviders.get(names[j]);
4272                                 Slog.w(TAG, "Can't install because provider name " + names[j] +
4273                                         " (in package " + pkg.applicationInfo.packageName +
4274                                         ") is already used by "
4275                                         + ((other != null && other.getComponentName() != null)
4276                                                 ? other.getComponentName().getPackageName() : "?"));
4277                                 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
4278                                 return null;
4279                             }
4280                         }
4281                     }
4282                 }
4283             }
4284
4285             if (pkg.mAdoptPermissions != null) {
4286                 // This package wants to adopt ownership of permissions from
4287                 // another package.
4288                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
4289                     final String origName = pkg.mAdoptPermissions.get(i);
4290                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
4291                     if (orig != null) {
4292                         if (verifyPackageUpdateLPr(orig, pkg)) {
4293                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
4294                                     + pkg.packageName);
4295                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
4296                         }
4297                     }
4298                 }
4299             }
4300         }
4301
4302         final String pkgName = pkg.packageName;
4303         
4304         final long scanFileTime = scanFile.lastModified();
4305         final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
4306         pkg.applicationInfo.processName = fixProcessName(
4307                 pkg.applicationInfo.packageName,
4308                 pkg.applicationInfo.processName,
4309                 pkg.applicationInfo.uid);
4310
4311         File dataPath;
4312         if (mPlatformPackage == pkg) {
4313             // The system package is special.
4314             dataPath = new File (Environment.getDataDirectory(), "system");
4315             pkg.applicationInfo.dataDir = dataPath.getPath();
4316         } else {
4317             // This is a normal package, need to make its data directory.
4318             dataPath = getDataPathForPackage(pkg.packageName, 0);
4319
4320             boolean uidError = false;
4321
4322             if (dataPath.exists()) {
4323                 int currentUid = 0;
4324                 try {
4325                     StructStat stat = Libcore.os.stat(dataPath.getPath());
4326                     currentUid = stat.st_uid;
4327                 } catch (ErrnoException e) {
4328                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
4329                 }
4330
4331                 // If we have mismatched owners for the data path, we have a problem.
4332                 if (currentUid != pkg.applicationInfo.uid) {
4333                     boolean recovered = false;
4334                     if (currentUid == 0) {
4335                         // The directory somehow became owned by root.  Wow.
4336                         // This is probably because the system was stopped while
4337                         // installd was in the middle of messing with its libs
4338                         // directory.  Ask installd to fix that.
4339                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
4340                                 pkg.applicationInfo.uid);
4341                         if (ret >= 0) {
4342                             recovered = true;
4343                             String msg = "Package " + pkg.packageName
4344                                     + " unexpectedly changed to uid 0; recovered to " +
4345                                     + pkg.applicationInfo.uid;
4346                             reportSettingsProblem(Log.WARN, msg);
4347                         }
4348                     }
4349                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
4350                             || (scanMode&SCAN_BOOTING) != 0)) {
4351                         // If this is a system app, we can at least delete its
4352                         // current data so the application will still work.
4353                         int ret = removeDataDirsLI(pkgName);
4354                         if (ret >= 0) {
4355                             // TODO: Kill the processes first
4356                             // Old data gone!
4357                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
4358                                     ? "System package " : "Third party package ";
4359                             String msg = prefix + pkg.packageName
4360                                     + " has changed from uid: "
4361                                     + currentUid + " to "
4362                                     + pkg.applicationInfo.uid + "; old data erased";
4363                             reportSettingsProblem(Log.WARN, msg);
4364                             recovered = true;
4365
4366                             // And now re-install the app.
4367                             ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
4368                                                    pkg.applicationInfo.seinfo);
4369                             if (ret == -1) {
4370                                 // Ack should not happen!
4371                                 msg = prefix + pkg.packageName
4372                                         + " could not have data directory re-created after delete.";
4373                                 reportSettingsProblem(Log.WARN, msg);
4374                                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4375                                 return null;
4376                             }
4377                         }
4378                         if (!recovered) {
4379                             mHasSystemUidErrors = true;
4380                         }
4381                     } else if (!recovered) {
4382                         // If we allow this install to proceed, we will be broken.
4383                         // Abort, abort!
4384                         mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
4385                         return null;
4386                     }
4387                     if (!recovered) {
4388                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
4389                             + pkg.applicationInfo.uid + "/fs_"
4390                             + currentUid;
4391                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
4392                         String msg = "Package " + pkg.packageName
4393                                 + " has mismatched uid: "
4394                                 + currentUid + " on disk, "
4395                                 + pkg.applicationInfo.uid + " in settings";
4396                         // writer
4397                         synchronized (mPackages) {
4398                             mSettings.mReadMessages.append(msg);
4399                             mSettings.mReadMessages.append('\n');
4400                             uidError = true;
4401                             if (!pkgSetting.uidError) {
4402                                 reportSettingsProblem(Log.ERROR, msg);
4403                             }
4404                         }
4405                     }
4406                 }
4407                 pkg.applicationInfo.dataDir = dataPath.getPath();
4408             } else {
4409                 if (DEBUG_PACKAGE_SCANNING) {
4410                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4411                         Log.v(TAG, "Want this data dir: " + dataPath);
4412                 }
4413                 //invoke installer to do the actual installation
4414                 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
4415                                            pkg.applicationInfo.seinfo);
4416                 if (ret < 0) {
4417                     // Error from installer
4418                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
4419                     return null;
4420                 }
4421
4422                 if (dataPath.exists()) {
4423                     pkg.applicationInfo.dataDir = dataPath.getPath();
4424                 } else {
4425                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
4426                     pkg.applicationInfo.dataDir = null;
4427                 }
4428             }
4429
4430             /*
4431              * Set the data dir to the default "/data/data/<package name>/lib"
4432              * if we got here without anyone telling us different (e.g., apps
4433              * stored on SD card have their native libraries stored in the ASEC
4434              * container with the APK).
4435              *
4436              * This happens during an upgrade from a package settings file that
4437              * doesn't have a native library path attribute at all.
4438              */
4439             if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
4440                 if (pkgSetting.nativeLibraryPathString == null) {
4441                     setInternalAppNativeLibraryPath(pkg, pkgSetting);
4442                 } else {
4443                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
4444                 }
4445             }
4446
4447             pkgSetting.uidError = uidError;
4448         }
4449
4450         String path = scanFile.getPath();
4451         /* Note: We don't want to unpack the native binaries for
4452          *        system applications, unless they have been updated
4453          *        (the binaries are already under /system/lib).
4454          *        Also, don't unpack libs for apps on the external card
4455          *        since they should have their libraries in the ASEC
4456          *        container already.
4457          *
4458          *        In other words, we're going to unpack the binaries
4459          *        only for non-system apps and system app upgrades.
4460          */
4461         if (pkg.applicationInfo.nativeLibraryDir != null) {
4462             try {
4463                 File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
4464                 final String dataPathString = dataPath.getCanonicalPath();
4465
4466                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
4467                     /*
4468                      * Upgrading from a previous version of the OS sometimes
4469                      * leaves native libraries in the /data/data/<app>/lib
4470                      * directory for system apps even when they shouldn't be.
4471                      * Recent changes in the JNI library search path
4472                      * necessitates we remove those to match previous behavior.
4473                      */
4474                     if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
4475                         Log.i(TAG, "removed obsolete native libraries for system package "
4476                                 + path);
4477                     }
4478                 } else {
4479                     if (!isForwardLocked(pkg) && !isExternal(pkg)) {
4480                         /*
4481                          * Update native library dir if it starts with
4482                          * /data/data
4483                          */
4484                         if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
4485                             setInternalAppNativeLibraryPath(pkg, pkgSetting);
4486                             nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
4487                         }
4488
4489                         try {
4490                             int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir);
4491                             Integer pkgUidInt = new Integer(pkg.applicationInfo.uid);
4492                             if (copyRet == PackageManager.INSTALL_SUCCEEDED) {
4493                                 String abi2 = SystemProperties.get("ro.product.cpu.abi2");
4494                                 if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(pkgUidInt)) {
4495                                     Slog.i(TAG, "Replace package with primary ABI Library");
4496                                     mPackagesMatchABI2.remove(pkgUidInt);
4497                                     writeAppwithABI2();
4498                                     if (mPackagesMatchABI2Neon.containsKey(pkgUidInt)) {
4499                                         mPackagesMatchABI2Neon.remove(pkgUidInt);
4500                                         writeAppwithABI2Neon();
4501                                     }
4502                                 }
4503                             } else if (copyRet == PackageManager.INSTALL_ABI2_SUCCEEDED) {
4504                                 ICheckExt check = new CheckExt();
4505                                 if(check.doCheck(pkgName, new String("filter"))) {
4506                                     Slog.i(TAG, "Package with second ABI is in black list: " + pkgUidInt + pkg.applicationInfo.processName);
4507                                     mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
4508                                     return null;
4509                                 }
4510                                 Slog.i(TAG, "Package installed with second ABI Library: " + pkgUidInt + pkg.applicationInfo.processName);
4511                                 mPackagesMatchABI2.put(pkgUidInt, pkg.applicationInfo.processName);
4512                                 writeAppwithABI2();
4513                                 if (check.doCheck(pkgName, new String("neon"))) {
4514                                     mPackagesMatchABI2Neon.put(pkgUidInt, pkg.applicationInfo.processName);
4515                                     writeAppwithABI2Neon();
4516                                 }
4517                             } else {
4518                                 Slog.e(TAG, "Unable to copy native libraries");
4519                                 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4520                                 return null;
4521                             }
4522                         } catch (IOException e) {
4523                             Slog.e(TAG, "Unable to copy native libraries", e);
4524                             mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4525                             return null;
4526                         }
4527                     }
4528
4529                     if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
4530                     final int[] userIds = sUserManager.getUserIds();
4531                     synchronized (mInstallLock) {
4532                         for (int userId : userIds) {
4533                             if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
4534                                     pkg.applicationInfo.nativeLibraryDir, userId) < 0) {
4535                                 Slog.w(TAG, "Failed linking native library dir (user=" + userId
4536                                         + ")");
4537                                 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
4538                                 return null;
4539                             }
4540                         }
4541                     }
4542                 }
4543             } catch (IOException ioe) {
4544                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
4545             }
4546         }
4547         pkg.mScanPath = path;
4548
4549         if ((scanMode&SCAN_NO_DEX) == 0) {
4550             if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
4551                     == DEX_OPT_FAILED) {
4552                 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
4553                 return null;
4554             }
4555         }
4556
4557         if (mFactoryTest && pkg.requestedPermissions.contains(
4558                 android.Manifest.permission.FACTORY_TEST)) {
4559             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
4560         }
4561
4562         ArrayList<PackageParser.Package> clientLibPkgs = null;
4563
4564         // writer
4565         synchronized (mPackages) {
4566             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
4567                 // Only system apps can add new shared libraries.
4568                 if (pkg.libraryNames != null) {
4569                     for (int i=0; i<pkg.libraryNames.size(); i++) {
4570                         String name = pkg.libraryNames.get(i);
4571                         boolean allowed = false;
4572                         if (isUpdatedSystemApp(pkg)) {
4573                             // New library entries can only be added through the
4574                             // system image.  This is important to get rid of a lot
4575                             // of nasty edge cases: for example if we allowed a non-
4576                             // system update of the app to add a library, then uninstalling
4577                             // the update would make the library go away, and assumptions
4578                             // we made such as through app install filtering would now
4579                             // have allowed apps on the device which aren't compatible
4580                             // with it.  Better to just have the restriction here, be
4581                             // conservative, and create many fewer cases that can negatively
4582                             // impact the user experience.
4583                             final PackageSetting sysPs = mSettings
4584                                     .getDisabledSystemPkgLPr(pkg.packageName);
4585                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
4586                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
4587                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
4588                                         allowed = true;
4589                                         allowed = true;
4590                                         break;
4591                                     }
4592                                 }
4593                             }
4594                         } else {
4595                             allowed = true;
4596                         }
4597                         if (allowed) {
4598                             if (!mSharedLibraries.containsKey(name)) {
4599                                 mSharedLibraries.put(name, new SharedLibraryEntry(null,
4600                                         pkg.packageName));
4601                             } else if (!name.equals(pkg.packageName)) {
4602                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
4603                                         + name + " already exists; skipping");
4604                             }
4605                         } else {
4606                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
4607                                     + name + " that is not declared on system image; skipping");
4608                         }
4609                     }
4610                     if ((scanMode&SCAN_BOOTING) == 0) {
4611                         // If we are not booting, we need to update any applications
4612                         // that are clients of our shared library.  If we are booting,
4613                         // this will all be done once the scan is complete.
4614                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
4615                     }
4616                 }
4617             }
4618         }
4619
4620         // We also need to dexopt any apps that are dependent on this library.  Note that
4621         // if these fail, we should abort the install since installing the library will
4622         // result in some apps being broken.
4623         if (clientLibPkgs != null) {
4624             if ((scanMode&SCAN_NO_DEX) == 0) {
4625                 for (int i=0; i<clientLibPkgs.size(); i++) {
4626                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
4627                     if (performDexOptLI(clientPkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
4628                             == DEX_OPT_FAILED) {
4629                         mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
4630                         return null;
4631                     }
4632                 }
4633             }
4634         }
4635
4636         // Request the ActivityManager to kill the process(only for existing packages)
4637         // so that we do not end up in a confused state while the user is still using the older
4638         // version of the application while the new one gets installed.
4639         if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
4640             killApplication(pkg.applicationInfo.packageName,
4641                         pkg.applicationInfo.uid);
4642         }
4643
4644         // Also need to kill any apps that are dependent on the library.
4645         if (clientLibPkgs != null) {
4646             for (int i=0; i<clientLibPkgs.size(); i++) {
4647                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
4648                 killApplication(clientPkg.applicationInfo.packageName,
4649                         clientPkg.applicationInfo.uid);
4650             }
4651         }
4652
4653         // writer
4654         synchronized (mPackages) {
4655             // We don't expect installation to fail beyond this point,
4656             if ((scanMode&SCAN_MONITOR) != 0) {
4657                 mAppDirs.put(pkg.mPath, pkg);
4658             }
4659             // Add the new setting to mSettings
4660             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
4661             // Add the new setting to mPackages
4662             mPackages.put(pkg.applicationInfo.packageName, pkg);
4663             // Make sure we don't accidentally delete its data.
4664             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
4665             while (iter.hasNext()) {
4666                 PackageCleanItem item = iter.next();
4667                 if (pkgName.equals(item.packageName)) {
4668                     iter.remove();
4669                 }
4670             }
4671
4672             // Take care of first install / last update times.
4673             if (currentTime != 0) {
4674                 if (pkgSetting.firstInstallTime == 0) {
4675                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
4676                 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
4677                     pkgSetting.lastUpdateTime = currentTime;
4678                 }
4679             } else if (pkgSetting.firstInstallTime == 0) {
4680                 // We need *something*.  Take time time stamp of the file.
4681                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
4682             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
4683                 if (scanFileTime != pkgSetting.timeStamp) {
4684                     // A package on the system image has changed; consider this
4685                     // to be an update.
4686                     pkgSetting.lastUpdateTime = scanFileTime;
4687                 }
4688             }
4689
4690             int N = pkg.providers.size();
4691             StringBuilder r = null;
4692             int i;
4693             for (i=0; i<N; i++) {
4694                 PackageParser.Provider p = pkg.providers.get(i);
4695                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
4696                         p.info.processName, pkg.applicationInfo.uid);
4697                 mProvidersByComponent.put(new ComponentName(p.info.packageName,
4698                         p.info.name), p);
4699                 p.syncable = p.info.isSyncable;
4700                 if (p.info.authority != null) {
4701                     String names[] = p.info.authority.split(";");
4702                     p.info.authority = null;
4703                     for (int j = 0; j < names.length; j++) {
4704                         if (j == 1 && p.syncable) {
4705                             // We only want the first authority for a provider to possibly be
4706                             // syncable, so if we already added this provider using a different
4707                             // authority clear the syncable flag. We copy the provider before
4708                             // changing it because the mProviders object contains a reference
4709                             // to a provider that we don't want to change.
4710                             // Only do this for the second authority since the resulting provider
4711                             // object can be the same for all future authorities for this provider.
4712                             p = new PackageParser.Provider(p);
4713                             p.syncable = false;
4714                         }
4715                         if (!mProviders.containsKey(names[j])) {
4716                             mProviders.put(names[j], p);
4717                             if (p.info.authority == null) {
4718                                 p.info.authority = names[j];
4719                             } else {
4720                                 p.info.authority = p.info.authority + ";" + names[j];
4721                             }
4722                             if (DEBUG_PACKAGE_SCANNING) {
4723                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
4724                                     Log.d(TAG, "Registered content provider: " + names[j]
4725                                             + ", className = " + p.info.name + ", isSyncable = "
4726                                             + p.info.isSyncable);
4727                             }
4728                         } else {
4729                             PackageParser.Provider other = mProviders.get(names[j]);
4730                             Slog.w(TAG, "Skipping provider name " + names[j] +
4731                                     " (in package " + pkg.applicationInfo.packageName +
4732                                     "): name already used by "
4733                                     + ((other != null && other.getComponentName() != null)
4734                                             ? other.getComponentName().getPackageName() : "?"));
4735                         }
4736                     }
4737                 }
4738                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4739                     if (r == null) {
4740                         r = new StringBuilder(256);
4741                     } else {
4742                         r.append(' ');
4743                     }
4744                     r.append(p.info.name);
4745                 }
4746             }
4747             if (r != null) {
4748                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
4749             }
4750
4751             N = pkg.services.size();
4752             r = null;
4753             for (i=0; i<N; i++) {
4754                 PackageParser.Service s = pkg.services.get(i);
4755                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
4756                         s.info.processName, pkg.applicationInfo.uid);
4757                 mServices.addService(s);
4758                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4759                     if (r == null) {
4760                         r = new StringBuilder(256);
4761                     } else {
4762                         r.append(' ');
4763                     }
4764                     r.append(s.info.name);
4765                 }
4766             }
4767             if (r != null) {
4768                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
4769             }
4770
4771             N = pkg.receivers.size();
4772             r = null;
4773             for (i=0; i<N; i++) {
4774                 PackageParser.Activity a = pkg.receivers.get(i);
4775                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
4776                         a.info.processName, pkg.applicationInfo.uid);
4777                 mReceivers.addActivity(a, "receiver");
4778                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4779                     if (r == null) {
4780                         r = new StringBuilder(256);
4781                     } else {
4782                         r.append(' ');
4783                     }
4784                     r.append(a.info.name);
4785                 }
4786             }
4787             if (r != null) {
4788                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
4789             }
4790
4791             N = pkg.activities.size();
4792             r = null;
4793             for (i=0; i<N; i++) {
4794                 PackageParser.Activity a = pkg.activities.get(i);
4795                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
4796                         a.info.processName, pkg.applicationInfo.uid);
4797                 mActivities.addActivity(a, "activity");
4798                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4799                     if (r == null) {
4800                         r = new StringBuilder(256);
4801                     } else {
4802                         r.append(' ');
4803                     }
4804                     r.append(a.info.name);
4805                 }
4806             }
4807             if (r != null) {
4808                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
4809             }
4810
4811             N = pkg.permissionGroups.size();
4812             r = null;
4813             for (i=0; i<N; i++) {
4814                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
4815                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
4816                 if (cur == null) {
4817                     mPermissionGroups.put(pg.info.name, pg);
4818                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4819                         if (r == null) {
4820                             r = new StringBuilder(256);
4821                         } else {
4822                             r.append(' ');
4823                         }
4824                         r.append(pg.info.name);
4825                     }
4826                 } else {
4827                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
4828                             + pg.info.packageName + " ignored: original from "
4829                             + cur.info.packageName);
4830                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4831                         if (r == null) {
4832                             r = new StringBuilder(256);
4833                         } else {
4834                             r.append(' ');
4835                         }
4836                         r.append("DUP:");
4837                         r.append(pg.info.name);
4838                     }
4839                 }
4840             }
4841             if (r != null) {
4842                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
4843             }
4844
4845             N = pkg.permissions.size();
4846             r = null;
4847             for (i=0; i<N; i++) {
4848                 PackageParser.Permission p = pkg.permissions.get(i);
4849                 HashMap<String, BasePermission> permissionMap =
4850                         p.tree ? mSettings.mPermissionTrees
4851                         : mSettings.mPermissions;
4852                 p.group = mPermissionGroups.get(p.info.group);
4853                 if (p.info.group == null || p.group != null) {
4854                     BasePermission bp = permissionMap.get(p.info.name);
4855                     if (bp == null) {
4856                         bp = new BasePermission(p.info.name, p.info.packageName,
4857                                 BasePermission.TYPE_NORMAL);
4858                         permissionMap.put(p.info.name, bp);
4859                     }
4860                     if (bp.perm == null) {
4861                         if (bp.sourcePackage == null
4862                                 || bp.sourcePackage.equals(p.info.packageName)) {
4863                             BasePermission tree = findPermissionTreeLP(p.info.name);
4864                             if (tree == null
4865                                     || tree.sourcePackage.equals(p.info.packageName)) {
4866                                 bp.packageSetting = pkgSetting;
4867                                 bp.perm = p;
4868                                 bp.uid = pkg.applicationInfo.uid;
4869                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4870                                     if (r == null) {
4871                                         r = new StringBuilder(256);
4872                                     } else {
4873                                         r.append(' ');
4874                                     }
4875                                     r.append(p.info.name);
4876                                 }
4877                             } else {
4878                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
4879                                         + p.info.packageName + " ignored: base tree "
4880                                         + tree.name + " is from package "
4881                                         + tree.sourcePackage);
4882                             }
4883                         } else {
4884                             Slog.w(TAG, "Permission " + p.info.name + " from package "
4885                                     + p.info.packageName + " ignored: original from "
4886                                     + bp.sourcePackage);
4887                         }
4888                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4889                         if (r == null) {
4890                             r = new StringBuilder(256);
4891                         } else {
4892                             r.append(' ');
4893                         }
4894                         r.append("DUP:");
4895                         r.append(p.info.name);
4896                     }
4897                     if (bp.perm == p) {
4898                         bp.protectionLevel = p.info.protectionLevel;
4899                     }
4900                 } else {
4901                     Slog.w(TAG, "Permission " + p.info.name + " from package "
4902                             + p.info.packageName + " ignored: no group "
4903                             + p.group);
4904                 }
4905             }
4906             if (r != null) {
4907                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
4908             }
4909
4910             N = pkg.instrumentation.size();
4911             r = null;
4912             for (i=0; i<N; i++) {
4913                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
4914                 a.info.packageName = pkg.applicationInfo.packageName;
4915                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
4916                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
4917                 a.info.dataDir = pkg.applicationInfo.dataDir;
4918                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
4919                 mInstrumentation.put(a.getComponentName(), a);
4920                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
4921                     if (r == null) {
4922                         r = new StringBuilder(256);
4923                     } else {
4924                         r.append(' ');
4925                     }
4926                     r.append(a.info.name);
4927                 }
4928             }
4929             if (r != null) {
4930                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
4931             }
4932
4933             if (pkg.protectedBroadcasts != null) {
4934                 N = pkg.protectedBroadcasts.size();
4935                 for (i=0; i<N; i++) {
4936                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
4937                 }
4938             }
4939
4940             pkgSetting.setTimeStamp(scanFileTime);
4941         }
4942
4943         return pkg;
4944     }
4945
4946     private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
4947             PackageSetting pkgSetting) {
4948         final String apkLibPath = getApkName(pkgSetting.codePathString);
4949         final String nativeLibraryPath = new File(mAppLibInstallDir, apkLibPath).getPath();
4950         pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
4951         pkgSetting.nativeLibraryPathString = nativeLibraryPath;
4952     }
4953
4954     private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
4955             throws IOException {
4956         if (!nativeLibraryDir.isDirectory()) {
4957             nativeLibraryDir.delete();
4958
4959             if (!nativeLibraryDir.mkdir()) {
4960                 throw new IOException("Cannot create " + nativeLibraryDir.getPath());
4961             }
4962
4963             try {
4964                 Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
4965                         | S_IXOTH);
4966             } catch (ErrnoException e) {
4967                 throw new IOException("Cannot chmod native library directory "
4968                         + nativeLibraryDir.getPath(), e);
4969             }
4970         } else if (!SELinux.restorecon(nativeLibraryDir)) {
4971             throw new IOException("Cannot set SELinux context for " + nativeLibraryDir.getPath());
4972         }
4973
4974         /*
4975          * If this is an internal application or our nativeLibraryPath points to
4976          * the app-lib directory, unpack the libraries if necessary.
4977          */
4978         return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
4979     }
4980
4981     private void killApplication(String pkgName, int appId) {
4982         // Request the ActivityManager to kill the process(only for existing packages)
4983         // so that we do not end up in a confused state while the user is still using the older
4984         // version of the application while the new one gets installed.
4985         IActivityManager am = ActivityManagerNative.getDefault();
4986         if (am != null) {
4987             try {
4988                 am.killApplicationWithAppId(pkgName, appId);
4989             } catch (RemoteException e) {
4990             }
4991         }
4992     }
4993
4994     void removePackageLI(PackageSetting ps, boolean chatty) {
4995         if (DEBUG_INSTALL) {
4996             if (chatty)
4997                 Log.d(TAG, "Removing package " + ps.name);
4998         }
4999
5000         // writer
5001         synchronized (mPackages) {
5002             mPackages.remove(ps.name);
5003             if (ps.codePathString != null) {
5004                 mAppDirs.remove(ps.codePathString);
5005             }
5006
5007             final PackageParser.Package pkg = ps.pkg;
5008             if (pkg != null) {
5009                 cleanPackageDataStructuresLILPw(pkg, chatty);
5010
5011                 String abi2 = SystemProperties.get("ro.product.cpu.abi2");
5012                 Integer pkgUidInt = new Integer(pkg.applicationInfo.uid);
5013                 if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(pkgUidInt)) {
5014                     Slog.i(TAG, "Uninstall package with second ABI Library");
5015                     mPackagesMatchABI2.remove(pkgUidInt);
5016                     writeAppwithABI2();
5017                     if (mPackagesMatchABI2Neon.containsKey(pkgUidInt)) {
5018                         mPackagesMatchABI2Neon.remove(pkgUidInt);
5019                         writeAppwithABI2Neon();
5020                     }
5021                 }
5022
5023             }
5024         }
5025     }
5026
5027     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
5028         if (DEBUG_INSTALL) {
5029             if (chatty)
5030                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
5031         }
5032
5033         // writer
5034         synchronized (mPackages) {
5035             mPackages.remove(pkg.applicationInfo.packageName);
5036             if (pkg.mPath != null) {
5037                 mAppDirs.remove(pkg.mPath);
5038             }
5039             cleanPackageDataStructuresLILPw(pkg, chatty);
5040
5041             String abi2 = SystemProperties.get("ro.product.cpu.abi2");
5042             if (abi2.length() != 0 && mPackagesMatchABI2.containsKey(new Integer(pkg.applicationInfo.uid))) {
5043                 Slog.i(TAG, "Uninstall package with second ABI Library");
5044                 mPackagesMatchABI2.remove(new Integer(pkg.applicationInfo.uid));
5045                 writeAppwithABI2();
5046                 if (mPackagesMatchABI2Neon.containsKey(new Integer(pkg.applicationInfo.uid))) {
5047                     mPackagesMatchABI2Neon.remove(new Integer(pkg.applicationInfo.uid));
5048                     writeAppwithABI2Neon();
5049                 }
5050             }
5051
5052         }
5053     }
5054
5055     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
5056         int N = pkg.providers.size();
5057         StringBuilder r = null;
5058         int i;
5059         for (i=0; i<N; i++) {
5060             PackageParser.Provider p = pkg.providers.get(i);
5061             mProvidersByComponent.remove(new ComponentName(p.info.packageName,
5062                     p.info.name));
5063             if (p.info.authority == null) {
5064
5065                 /* There was another ContentProvider with this authority when
5066                  * this app was installed so this authority is null,
5067                  * Ignore it as we don't have to unregister the provider.
5068                  */
5069                 continue;
5070             }
5071             String names[] = p.info.authority.split(";");
5072             for (int j = 0; j < names.length; j++) {
5073                 if (mProviders.get(names[j]) == p) {
5074                     mProviders.remove(names[j]);
5075                     if (DEBUG_REMOVE) {
5076                         if (chatty)
5077                             Log.d(TAG, "Unregistered content provider: " + names[j]
5078                                     + ", className = " + p.info.name + ", isSyncable = "
5079                                     + p.info.isSyncable);
5080                     }
5081                 }
5082             }
5083             if (DEBUG_REMOVE && chatty) {
5084                 if (r == null) {
5085                     r = new StringBuilder(256);
5086                 } else {
5087                     r.append(' ');
5088                 }
5089                 r.append(p.info.name);
5090             }
5091         }
5092         if (r != null) {
5093             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
5094         }
5095
5096         N = pkg.services.size();
5097         r = null;
5098         for (i=0; i<N; i++) {
5099             PackageParser.Service s = pkg.services.get(i);
5100             mServices.removeService(s);
5101             if (chatty) {
5102                 if (r == null) {
5103                     r = new StringBuilder(256);
5104                 } else {
5105                     r.append(' ');
5106                 }
5107                 r.append(s.info.name);
5108             }
5109         }
5110         if (r != null) {
5111             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
5112         }
5113
5114         N = pkg.receivers.size();
5115         r = null;
5116         for (i=0; i<N; i++) {
5117             PackageParser.Activity a = pkg.receivers.get(i);
5118             mReceivers.removeActivity(a, "receiver");
5119             if (DEBUG_REMOVE && chatty) {
5120                 if (r == null) {
5121                     r = new StringBuilder(256);
5122                 } else {
5123                     r.append(' ');
5124                 }
5125                 r.append(a.info.name);
5126             }
5127         }
5128         if (r != null) {
5129             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
5130         }
5131
5132         N = pkg.activities.size();
5133         r = null;
5134         for (i=0; i<N; i++) {
5135             PackageParser.Activity a = pkg.activities.get(i);
5136             mActivities.removeActivity(a, "activity");
5137             if (DEBUG_REMOVE && chatty) {
5138                 if (r == null) {
5139                     r = new StringBuilder(256);
5140                 } else {
5141                     r.append(' ');
5142                 }
5143                 r.append(a.info.name);
5144             }
5145         }
5146         if (r != null) {
5147             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
5148         }
5149
5150         N = pkg.permissions.size();
5151         r = null;
5152         for (i=0; i<N; i++) {
5153             PackageParser.Permission p = pkg.permissions.get(i);
5154             BasePermission bp = mSettings.mPermissions.get(p.info.name);
5155             if (bp == null) {
5156                 bp = mSettings.mPermissionTrees.get(p.info.name);
5157             }
5158             if (bp != null && bp.perm == p) {
5159                 bp.perm = null;
5160                 if (DEBUG_REMOVE && chatty) {
5161                     if (r == null) {
5162                         r = new StringBuilder(256);
5163                     } else {
5164                         r.append(' ');
5165                     }
5166                     r.append(p.info.name);
5167                 }
5168             }
5169         }
5170         if (r != null) {
5171             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
5172         }
5173
5174         N = pkg.instrumentation.size();
5175         r = null;
5176         for (i=0; i<N; i++) {
5177             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
5178             mInstrumentation.remove(a.getComponentName());
5179             if (DEBUG_REMOVE && chatty) {
5180                 if (r == null) {
5181                     r = new StringBuilder(256);
5182                 } else {
5183                     r.append(' ');
5184                 }
5185                 r.append(a.info.name);
5186             }
5187         }
5188         if (r != null) {
5189             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
5190         }
5191
5192         r = null;
5193         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
5194             // Only system apps can hold shared libraries.
5195             if (pkg.libraryNames != null) {
5196                 for (i=0; i<pkg.libraryNames.size(); i++) {
5197                     String name = pkg.libraryNames.get(i);
5198                     SharedLibraryEntry cur = mSharedLibraries.get(name);
5199                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
5200                         mSharedLibraries.remove(name);
5201                         if (DEBUG_REMOVE && chatty) {
5202                             if (r == null) {
5203                                 r = new StringBuilder(256);
5204                             } else {
5205                                 r.append(' ');
5206                             }
5207                             r.append(name);
5208                         }
5209                     }
5210                 }
5211             }
5212         }
5213         if (r != null) {
5214             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
5215         }
5216     }
5217
5218     private static final boolean isPackageFilename(String name) {
5219         return name != null && name.endsWith(".apk");
5220     }
5221
5222     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
5223         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
5224             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
5225                 return true;
5226             }
5227         }
5228         return false;
5229     }
5230
5231     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
5232     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
5233     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
5234
5235     private void updatePermissionsLPw(String changingPkg,
5236             PackageParser.Package pkgInfo, int flags) {
5237         // Make sure there are no dangling permission trees.
5238         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
5239         while (it.hasNext()) {
5240             final BasePermission bp = it.next();
5241             if (bp.packageSetting == null) {
5242                 // We may not yet have parsed the package, so just see if
5243                 // we still know about its settings.
5244                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
5245             }
5246             if (bp.packageSetting == null) {
5247                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
5248                         + " from package " + bp.sourcePackage);
5249                 it.remove();
5250             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
5251                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
5252                     Slog.i(TAG, "Removing old permission tree: " + bp.name
5253                             + " from package " + bp.sourcePackage);
5254                     flags |= UPDATE_PERMISSIONS_ALL;
5255                     it.remove();
5256                 }
5257             }
5258         }
5259
5260         // Make sure all dynamic permissions have been assigned to a package,
5261         // and make sure there are no dangling permissions.
5262         it = mSettings.mPermissions.values().iterator();
5263         while (it.hasNext()) {
5264             final BasePermission bp = it.next();
5265             if (bp.type == BasePermission.TYPE_DYNAMIC) {
5266                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
5267                         + bp.name + " pkg=" + bp.sourcePackage
5268                         + " info=" + bp.pendingInfo);
5269                 if (bp.packageSetting == null && bp.pendingInfo != null) {
5270                     final BasePermission tree = findPermissionTreeLP(bp.name);
5271                     if (tree != null && tree.perm != null) {
5272                         bp.packageSetting = tree.packageSetting;
5273                         bp.perm = new PackageParser.Permission(tree.perm.owner,
5274                                 new PermissionInfo(bp.pendingInfo));
5275                         bp.perm.info.packageName = tree.perm.info.packageName;
5276                         bp.perm.info.name = bp.name;
5277                         bp.uid = tree.uid;
5278                     }
5279                 }
5280             }
5281             if (bp.packageSetting == null) {
5282                 // We may not yet have parsed the package, so just see if
5283                 // we still know about its settings.
5284                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
5285             }
5286             if (bp.packageSetting == null) {
5287                 Slog.w(TAG, "Removing dangling permission: " + bp.name
5288                         + " from package " + bp.sourcePackage);
5289                 it.remove();
5290             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
5291                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
5292                     Slog.i(TAG, "Removing old permission: " + bp.name
5293                             + " from package " + bp.sourcePackage);
5294                     flags |= UPDATE_PERMISSIONS_ALL;
5295                     it.remove();
5296                 }
5297             }
5298         }
5299
5300         // Now update the permissions for all packages, in particular
5301         // replace the granted permissions of the system packages.
5302         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
5303             for (PackageParser.Package pkg : mPackages.values()) {
5304                 if (pkg != pkgInfo) {
5305                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
5306                 }
5307             }
5308         }
5309         
5310         if (pkgInfo != null) {
5311             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
5312         }
5313     }
5314
5315     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
5316         final PackageSetting ps = (PackageSetting) pkg.mExtras;
5317         if (ps == null) {
5318             return;
5319         }
5320         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
5321         HashSet<String> origPermissions = gp.grantedPermissions;
5322         boolean changedPermission = false;
5323
5324         if (replace) {
5325             ps.permissionsFixed = false;
5326             if (gp == ps) {
5327                 origPermissions = new HashSet<String>(gp.grantedPermissions);
5328                 gp.grantedPermissions.clear();
5329                 gp.gids = mGlobalGids;
5330             }
5331         }
5332
5333         if (gp.gids == null) {
5334             gp.gids = mGlobalGids;
5335         }
5336
5337         final int N = pkg.requestedPermissions.size();
5338         for (int i=0; i<N; i++) {
5339             final String name = pkg.requestedPermissions.get(i);
5340             final boolean required = pkg.requestedPermissionsRequired.get(i);
5341             final BasePermission bp = mSettings.mPermissions.get(name);
5342             if (DEBUG_INSTALL) {
5343                 if (gp != ps) {
5344                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
5345                 }
5346             }
5347
5348             if (bp == null || bp.packageSetting == null) {
5349                 Slog.w(TAG, "Unknown permission " + name
5350                         + " in package " + pkg.packageName);
5351                 continue;
5352             }
5353
5354             final String perm = bp.name;
5355             boolean allowed;
5356             boolean allowedSig = false;
5357             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
5358             if (level == PermissionInfo.PROTECTION_NORMAL
5359                     || level == PermissionInfo.PROTECTION_DANGEROUS) {
5360                 // We grant a normal or dangerous permission if any of the following
5361                 // are true:
5362                 // 1) The permission is required
5363                 // 2) The permission is optional, but was granted in the past
5364                 // 3) The permission is optional, but was requested by an
5365                 //    app in /system (not /data)
5366                 //
5367                 // Otherwise, reject the permission.
5368                 allowed = (required || origPermissions.contains(perm)
5369                         || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
5370             } else if (bp.packageSetting == null) {
5371                 // This permission is invalid; skip it.
5372                 allowed = false;
5373             } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
5374                 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
5375                 if (allowed) {
5376                     allowedSig = true;
5377                 }
5378             } else {
5379                 allowed = false;
5380             }
5381             if (DEBUG_INSTALL) {
5382                 if (gp != ps) {
5383                     Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
5384                 }
5385             }
5386             if (allowed) {
5387                 if (!isSystemApp(ps) && ps.permissionsFixed) {
5388                     // If this is an existing, non-system package, then
5389                     // we can't add any new permissions to it.
5390                     if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
5391                         // Except...  if this is a permission that was added
5392                         // to the platform (note: need to only do this when
5393                         // updating the platform).
5394                         allowed = isNewPlatformPermissionForPackage(perm, pkg);
5395                     }
5396                 }
5397                 if (allowed) {
5398                     if (!gp.grantedPermissions.contains(perm)) {
5399                         changedPermission = true;
5400                         gp.grantedPermissions.add(perm);
5401                         gp.gids = appendInts(gp.gids, bp.gids);
5402                     } else if (!ps.haveGids) {
5403                         gp.gids = appendInts(gp.gids, bp.gids);
5404                     }
5405                 } else {
5406                     Slog.w(TAG, "Not granting permission " + perm
5407                             + " to package " + pkg.packageName
5408                             + " because it was previously installed without");
5409                 }
5410             } else {
5411                 if (gp.grantedPermissions.remove(perm)) {
5412                     changedPermission = true;
5413                     gp.gids = removeInts(gp.gids, bp.gids);
5414                     Slog.i(TAG, "Un-granting permission " + perm
5415                             + " from package " + pkg.packageName
5416                             + " (protectionLevel=" + bp.protectionLevel
5417                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
5418                             + ")");
5419                 } else {
5420                     Slog.w(TAG, "Not granting permission " + perm
5421                             + " to package " + pkg.packageName
5422                             + " (protectionLevel=" + bp.protectionLevel
5423                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
5424                             + ")");
5425                 }
5426             }
5427         }
5428
5429         if ((changedPermission || replace) && !ps.permissionsFixed &&
5430                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
5431             // This is the first that we have heard about this package, so the
5432             // permissions we have now selected are fixed until explicitly
5433             // changed.
5434             ps.permissionsFixed = true;
5435         }
5436         ps.haveGids = true;
5437     }
5438
5439     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
5440         boolean allowed = false;
5441         final int NP = PackageParser.NEW_PERMISSIONS.length;
5442         for (int ip=0; ip<NP; ip++) {
5443             final PackageParser.NewPermissionInfo npi
5444                     = PackageParser.NEW_PERMISSIONS[ip];
5445             if (npi.name.equals(perm)
5446                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
5447                 allowed = true;
5448                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
5449                         + pkg.packageName);
5450                 break;
5451             }
5452         }
5453         return allowed;
5454     }
5455
5456     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
5457                                           BasePermission bp, HashSet<String> origPermissions) {
5458         boolean allowed;
5459         allowed = (compareSignatures(
5460                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
5461                         == PackageManager.SIGNATURE_MATCH)
5462                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
5463                         == PackageManager.SIGNATURE_MATCH);
5464         if (!allowed && (bp.protectionLevel
5465                 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
5466             if (isSystemApp(pkg)) {
5467                 // For updated system applications, a system permission
5468                 // is granted only if it had been defined by the original application.
5469                 if (isUpdatedSystemApp(pkg)) {
5470                     final PackageSetting sysPs = mSettings
5471                             .getDisabledSystemPkgLPr(pkg.packageName);
5472                     final GrantedPermissions origGp = sysPs.sharedUser != null
5473                             ? sysPs.sharedUser : sysPs;
5474                     if (origGp.grantedPermissions.contains(perm)) {
5475                         allowed = true;
5476                     } else {
5477                         // The system apk may have been updated with an older
5478                         // version of the one on the data partition, but which
5479                         // granted a new system permission that it didn't have
5480                         // before.  In this case we do want to allow the app to
5481                         // now get the new permission, because it is allowed by
5482                         // the system image.
5483                         allowed = false;
5484                         if (sysPs.pkg != null) {
5485                             for (int j=0;
5486                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
5487                                 if (perm.equals(
5488                                         sysPs.pkg.requestedPermissions.get(j))) {
5489                                     allowed = true;
5490                                     break;
5491                                 }
5492                             }
5493                         }
5494                     }
5495                 } else {
5496                     allowed = true;
5497                 }
5498             }
5499         }
5500         if (!allowed && (bp.protectionLevel
5501                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
5502             // For development permissions, a development permission
5503             // is granted only if it was already granted.
5504             allowed = origPermissions.contains(perm);
5505         }
5506         return allowed;
5507     }
5508
5509     final class ActivityIntentResolver
5510             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
5511         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
5512                 boolean defaultOnly, int userId) {
5513             if (!sUserManager.exists(userId)) return null;
5514             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
5515             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
5516         }
5517
5518         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
5519                 int userId) {
5520             if (!sUserManager.exists(userId)) return null;
5521             mFlags = flags;
5522             return super.queryIntent(intent, resolvedType,
5523                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
5524         }
5525
5526         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
5527                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
5528             if (!sUserManager.exists(userId)) return null;
5529             if (packageActivities == null) {
5530                 return null;
5531             }
5532             mFlags = flags;
5533             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
5534             final int N = packageActivities.size();
5535             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
5536                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
5537
5538             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
5539             for (int i = 0; i < N; ++i) {
5540                 intentFilters = packageActivities.get(i).intents;
5541                 if (intentFilters != null && intentFilters.size() > 0) {
5542                     PackageParser.ActivityIntentInfo[] array =
5543                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
5544                     intentFilters.toArray(array);
5545                     listCut.add(array);
5546                 }
5547             }
5548             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
5549         }
5550
5551         public final void addActivity(PackageParser.Activity a, String type) {
5552             final boolean systemApp = isSystemApp(a.info.applicationInfo);
5553             mActivities.put(a.getComponentName(), a);
5554             if (DEBUG_SHOW_INFO)
5555                 Log.v(
5556                 TAG, "  " + type + " " +
5557                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
5558             if (DEBUG_SHOW_INFO)
5559                 Log.v(TAG, "    Class=" + a.info.name);
5560             final int NI = a.intents.size();
5561             for (int j=0; j<NI; j++) {
5562                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
5563                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
5564                     intent.setPriority(0);
5565                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
5566                             + a.className + " with priority > 0, forcing to 0");
5567                 }
5568                 if (DEBUG_SHOW_INFO) {
5569                     Log.v(TAG, "    IntentFilter:");
5570                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5571                 }
5572                 if (!intent.debugCheck()) {
5573                     Log.w(TAG, "==> For Activity " + a.info.name);
5574                 }
5575                 addFilter(intent);
5576             }
5577         }
5578
5579         public final void removeActivity(PackageParser.Activity a, String type) {
5580             mActivities.remove(a.getComponentName());
5581             if (DEBUG_SHOW_INFO) {
5582                 Log.v(TAG, "  " + type + " "
5583                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
5584                                 : a.info.name) + ":");
5585                 Log.v(TAG, "    Class=" + a.info.name);
5586             }
5587             final int NI = a.intents.size();
5588             for (int j=0; j<NI; j++) {
5589                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
5590                 if (DEBUG_SHOW_INFO) {
5591                     Log.v(TAG, "    IntentFilter:");
5592                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5593                 }
5594                 removeFilter(intent);
5595             }
5596         }
5597
5598         @Override
5599         protected boolean allowFilterResult(
5600                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
5601             ActivityInfo filterAi = filter.activity.info;
5602             for (int i=dest.size()-1; i>=0; i--) {
5603                 ActivityInfo destAi = dest.get(i).activityInfo;
5604                 if (destAi.name == filterAi.name
5605                         && destAi.packageName == filterAi.packageName) {
5606                     return false;
5607                 }
5608             }
5609             return true;
5610         }
5611
5612         @Override
5613         protected ActivityIntentInfo[] newArray(int size) {
5614             return new ActivityIntentInfo[size];
5615         }
5616
5617         @Override
5618         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
5619             if (!sUserManager.exists(userId)) return true;
5620             PackageParser.Package p = filter.activity.owner;
5621             if (p != null) {
5622                 PackageSetting ps = (PackageSetting)p.mExtras;
5623                 if (ps != null) {
5624                     // System apps are never considered stopped for purposes of
5625                     // filtering, because there may be no way for the user to
5626                     // actually re-launch them.
5627                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
5628                             && ps.getStopped(userId);
5629                 }
5630             }
5631             return false;
5632         }
5633
5634         @Override
5635         protected boolean isPackageForFilter(String packageName,
5636                 PackageParser.ActivityIntentInfo info) {
5637             return packageName.equals(info.activity.owner.packageName);
5638         }
5639         
5640         @Override
5641         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
5642                 int match, int userId) {
5643             if (!sUserManager.exists(userId)) return null;
5644             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
5645                 return null;
5646             }
5647             final PackageParser.Activity activity = info.activity;
5648             if (mSafeMode && (activity.info.applicationInfo.flags
5649                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
5650                 return null;
5651             }
5652             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
5653             if (ps == null) {
5654                 return null;
5655             }
5656             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
5657                     ps.readUserState(userId), userId);
5658             if (ai == null) {
5659                 return null;
5660             }
5661             final ResolveInfo res = new ResolveInfo();
5662             res.activityInfo = ai;
5663             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
5664                 res.filter = info;
5665             }
5666             res.priority = info.getPriority();
5667             res.preferredOrder = activity.owner.mPreferredOrder;
5668             //System.out.println("Result: " + res.activityInfo.className +
5669             //                   " = " + res.priority);
5670             res.match = match;
5671             res.isDefault = info.hasDefault;
5672             res.labelRes = info.labelRes;
5673             res.nonLocalizedLabel = info.nonLocalizedLabel;
5674             res.icon = info.icon;
5675             res.system = isSystemApp(res.activityInfo.applicationInfo);
5676             return res;
5677         }
5678
5679         @Override
5680         protected void sortResults(List<ResolveInfo> results) {
5681             Collections.sort(results, mResolvePrioritySorter);
5682         }
5683
5684         @Override
5685         protected void dumpFilter(PrintWriter out, String prefix,
5686                 PackageParser.ActivityIntentInfo filter) {
5687             out.print(prefix); out.print(
5688                     Integer.toHexString(System.identityHashCode(filter.activity)));
5689                     out.print(' ');
5690                     out.print(filter.activity.getComponentShortName());
5691                     out.print(" filter ");
5692                     out.println(Integer.toHexString(System.identityHashCode(filter)));
5693         }
5694
5695 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
5696 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
5697 //            final List<ResolveInfo> retList = Lists.newArrayList();
5698 //            while (i.hasNext()) {
5699 //                final ResolveInfo resolveInfo = i.next();
5700 //                if (isEnabledLP(resolveInfo.activityInfo)) {
5701 //                    retList.add(resolveInfo);
5702 //                }
5703 //            }
5704 //            return retList;
5705 //        }
5706
5707         // Keys are String (activity class name), values are Activity.
5708         private final HashMap<ComponentName, PackageParser.Activity> mActivities
5709                 = new HashMap<ComponentName, PackageParser.Activity>();
5710         private int mFlags;
5711     }
5712
5713     private final class ServiceIntentResolver
5714             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
5715         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
5716                 boolean defaultOnly, int userId) {
5717             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
5718             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
5719         }
5720
5721         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
5722                 int userId) {
5723             if (!sUserManager.exists(userId)) return null;
5724             mFlags = flags;
5725             return super.queryIntent(intent, resolvedType,
5726                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
5727         }
5728
5729         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
5730                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
5731             if (!sUserManager.exists(userId)) return null;
5732             if (packageServices == null) {
5733                 return null;
5734             }
5735             mFlags = flags;
5736             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
5737             final int N = packageServices.size();
5738             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
5739                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
5740
5741             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
5742             for (int i = 0; i < N; ++i) {
5743                 intentFilters = packageServices.get(i).intents;
5744                 if (intentFilters != null && intentFilters.size() > 0) {
5745                     PackageParser.ServiceIntentInfo[] array =
5746                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
5747                     intentFilters.toArray(array);
5748                     listCut.add(array);
5749                 }
5750             }
5751             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
5752         }
5753
5754         public final void addService(PackageParser.Service s) {
5755             mServices.put(s.getComponentName(), s);
5756             if (DEBUG_SHOW_INFO) {
5757                 Log.v(TAG, "  "
5758                         + (s.info.nonLocalizedLabel != null
5759                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
5760                 Log.v(TAG, "    Class=" + s.info.name);
5761             }
5762             final int NI = s.intents.size();
5763             int j;
5764             for (j=0; j<NI; j++) {
5765                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
5766                 if (DEBUG_SHOW_INFO) {
5767                     Log.v(TAG, "    IntentFilter:");
5768                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5769                 }
5770                 if (!intent.debugCheck()) {
5771                     Log.w(TAG, "==> For Service " + s.info.name);
5772                 }
5773                 addFilter(intent);
5774             }
5775         }
5776
5777         public final void removeService(PackageParser.Service s) {
5778             mServices.remove(s.getComponentName());
5779             if (DEBUG_SHOW_INFO) {
5780                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
5781                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
5782                 Log.v(TAG, "    Class=" + s.info.name);
5783             }
5784             final int NI = s.intents.size();
5785             int j;
5786             for (j=0; j<NI; j++) {
5787                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
5788                 if (DEBUG_SHOW_INFO) {
5789                     Log.v(TAG, "    IntentFilter:");
5790                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
5791                 }
5792                 removeFilter(intent);
5793             }
5794         }
5795
5796         @Override
5797         protected boolean allowFilterResult(
5798                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
5799             ServiceInfo filterSi = filter.service.info;
5800             for (int i=dest.size()-1; i>=0; i--) {
5801                 ServiceInfo destAi = dest.get(i).serviceInfo;
5802                 if (destAi.name == filterSi.name
5803                         && destAi.packageName == filterSi.packageName) {
5804                     return false;
5805                 }
5806             }
5807             return true;
5808         }
5809
5810         @Override
5811         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
5812             return new PackageParser.ServiceIntentInfo[size];
5813         }
5814
5815         @Override
5816         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
5817             if (!sUserManager.exists(userId)) return true;
5818             PackageParser.Package p = filter.service.owner;
5819             if (p != null) {
5820                 PackageSetting ps = (PackageSetting)p.mExtras;
5821                 if (ps != null) {
5822                     // System apps are never considered stopped for purposes of
5823                     // filtering, because there may be no way for the user to
5824                     // actually re-launch them.
5825                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
5826                             && ps.getStopped(userId);
5827                 }
5828             }
5829             return false;
5830         }
5831
5832         @Override
5833         protected boolean isPackageForFilter(String packageName,
5834                 PackageParser.ServiceIntentInfo info) {
5835             return packageName.equals(info.service.owner.packageName);
5836         }
5837         
5838         @Override
5839         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
5840                 int match, int userId) {
5841             if (!sUserManager.exists(userId)) return null;
5842             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
5843             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
5844                 return null;
5845             }
5846             final PackageParser.Service service = info.service;
5847             if (mSafeMode && (service.info.applicationInfo.flags
5848                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
5849                 return null;
5850             }
5851             PackageSetting ps = (PackageSetting) service.owner.mExtras;
5852             if (ps == null) {
5853                 return null;
5854             }
5855             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
5856                     ps.readUserState(userId), userId);
5857             if (si == null) {
5858                 return null;
5859             }
5860             final ResolveInfo res = new ResolveInfo();
5861             res.serviceInfo = si;
5862             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
5863                 res.filter = filter;
5864             }
5865             res.priority = info.getPriority();
5866             res.preferredOrder = service.owner.mPreferredOrder;
5867             //System.out.println("Result: " + res.activityInfo.className +
5868             //                   " = " + res.priority);
5869             res.match = match;
5870             res.isDefault = info.hasDefault;
5871             res.labelRes = info.labelRes;
5872             res.nonLocalizedLabel = info.nonLocalizedLabel;
5873             res.icon = info.icon;
5874             res.system = isSystemApp(res.serviceInfo.applicationInfo);
5875             return res;
5876         }
5877
5878         @Override
5879         protected void sortResults(List<ResolveInfo> results) {
5880             Collections.sort(results, mResolvePrioritySorter);
5881         }
5882
5883         @Override
5884         protected void dumpFilter(PrintWriter out, String prefix,
5885                 PackageParser.ServiceIntentInfo filter) {
5886             out.print(prefix); out.print(
5887                     Integer.toHexString(System.identityHashCode(filter.service)));
5888                     out.print(' ');
5889                     out.print(filter.service.getComponentShortName());
5890                     out.print(" filter ");
5891                     out.println(Integer.toHexString(System.identityHashCode(filter)));
5892         }
5893
5894 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
5895 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
5896 //            final List<ResolveInfo> retList = Lists.newArrayList();
5897 //            while (i.hasNext()) {
5898 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
5899 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
5900 //                    retList.add(resolveInfo);
5901 //                }
5902 //            }
5903 //            return retList;
5904 //        }
5905
5906         // Keys are String (activity class name), values are Activity.
5907         private final HashMap<ComponentName, PackageParser.Service> mServices
5908                 = new HashMap<ComponentName, PackageParser.Service>();
5909         private int mFlags;
5910     };
5911
5912     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
5913             new Comparator<ResolveInfo>() {
5914         public int compare(ResolveInfo r1, ResolveInfo r2) {
5915             int v1 = r1.priority;
5916             int v2 = r2.priority;
5917             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
5918             if (v1 != v2) {
5919                 return (v1 > v2) ? -1 : 1;
5920             }
5921             v1 = r1.preferredOrder;
5922             v2 = r2.preferredOrder;
5923             if (v1 != v2) {
5924                 return (v1 > v2) ? -1 : 1;
5925             }
5926             if (r1.isDefault != r2.isDefault) {
5927                 return r1.isDefault ? -1 : 1;
5928             }
5929             v1 = r1.match;
5930             v2 = r2.match;
5931             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
5932             if (v1 != v2) {
5933                 return (v1 > v2) ? -1 : 1;
5934             }
5935             if (r1.system != r2.system) {
5936                 return r1.system ? -1 : 1;
5937             }
5938             return 0;
5939         }
5940     };
5941
5942     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
5943             new Comparator<ProviderInfo>() {
5944         public int compare(ProviderInfo p1, ProviderInfo p2) {
5945             final int v1 = p1.initOrder;
5946             final int v2 = p2.initOrder;
5947             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
5948         }
5949     };
5950
5951     static final void sendPackageBroadcast(String action, String pkg,
5952             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
5953             int[] userIds) {
5954         IActivityManager am = ActivityManagerNative.getDefault();
5955         if (am != null) {
5956             try {
5957                 if (userIds == null) {
5958                     userIds = am.getRunningUserIds();
5959                 }
5960                 for (int id : userIds) {
5961                     final Intent intent = new Intent(action,
5962                             pkg != null ? Uri.fromParts("package", pkg, null) : null);
5963                     if (extras != null) {
5964                         intent.putExtras(extras);
5965                     }
5966                     if (targetPkg != null) {
5967                         intent.setPackage(targetPkg);
5968                     }
5969                     // Modify the UID when posting to other users
5970                     int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
5971                     if (uid > 0 && UserHandle.getUserId(uid) != id) {
5972                         uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
5973                         intent.putExtra(Intent.EXTRA_UID, uid);
5974                     }
5975                     intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
5976                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
5977                     if (DEBUG_BROADCASTS) {
5978                         RuntimeException here = new RuntimeException("here");
5979                         here.fillInStackTrace();
5980                         Slog.d(TAG, "Sending to user " + id + ": "
5981                                 + intent.toShortString(false, true, false, false)
5982                                 + " " + intent.getExtras(), here);
5983                     }
5984                     am.broadcastIntent(null, intent, null, finishedReceiver,
5985                             0, null, null, null, android.app.AppOpsManager.OP_NONE,
5986                             finishedReceiver != null, false, id);
5987                 }
5988             } catch (RemoteException ex) {
5989             }
5990         }
5991     }
5992
5993     /**
5994      * Check if the external storage media is available. This is true if there
5995      * is a mounted external storage medium or if the external storage is
5996      * emulated.
5997      */
5998     private boolean isExternalMediaAvailable() {
5999         return mMediaMounted || Environment.isExternalStorageEmulated();
6000     }
6001
6002     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
6003         // writer
6004         synchronized (mPackages) {
6005             if (!isExternalMediaAvailable()) {
6006                 // If the external storage is no longer mounted at this point,
6007                 // the caller may not have been able to delete all of this
6008                 // packages files and can not delete any more.  Bail.
6009                 return null;
6010             }
6011             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
6012             if (lastPackage != null) {
6013                 pkgs.remove(lastPackage);
6014             }
6015             if (pkgs.size() > 0) {
6016                 return pkgs.get(0);
6017             }
6018         }
6019         return null;
6020     }
6021
6022     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
6023         if (false) {
6024             RuntimeException here = new RuntimeException("here");
6025             here.fillInStackTrace();
6026             Slog.d(TAG, "Schedule cleaning " + packageName + " user=" + userId
6027                     + " andCode=" + andCode, here);
6028         }
6029         mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE,
6030                 userId, andCode ? 1 : 0, packageName));
6031     }
6032     
6033     void startCleaningPackages() {
6034         // reader
6035         synchronized (mPackages) {
6036             if (!isExternalMediaAvailable()) {
6037                 return;
6038             }
6039             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
6040                 return;
6041             }
6042         }
6043         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
6044         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
6045         IActivityManager am = ActivityManagerNative.getDefault();
6046         if (am != null) {
6047             try {
6048                 am.startService(null, intent, null, UserHandle.USER_OWNER);
6049             } catch (RemoteException e) {
6050             }
6051         }
6052     }
6053     
6054     private final class AppDirObserver extends FileObserver {
6055         public AppDirObserver(String path, int mask, boolean isrom) {
6056             super(path, mask);
6057             mRootDir = path;
6058             mIsRom = isrom;
6059         }
6060
6061         public void onEvent(int event, String path) {
6062             String removedPackage = null;
6063             int removedAppId = -1;
6064             int[] removedUsers = null;
6065             String addedPackage = null;
6066             int addedAppId = -1;
6067             int[] addedUsers = null;
6068
6069             // TODO post a message to the handler to obtain serial ordering
6070             synchronized (mInstallLock) {
6071                 String fullPathStr = null;
6072                 File fullPath = null;
6073                 if (path != null) {
6074                     fullPath = new File(mRootDir, path);
6075                     fullPathStr = fullPath.getPath();
6076                 }
6077
6078                 if (DEBUG_APP_DIR_OBSERVER)
6079                     Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event));
6080
6081                 if (!isPackageFilename(path)) {
6082                     if (DEBUG_APP_DIR_OBSERVER)
6083                         Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr);
6084                     return;
6085                 }
6086
6087                 // Ignore packages that are being installed or
6088                 // have just been installed.
6089                 if (ignoreCodePath(fullPathStr)) {
6090                     return;
6091                 }
6092                 PackageParser.Package p = null;
6093                 PackageSetting ps = null;
6094                 // reader
6095                 synchronized (mPackages) {
6096                     p = mAppDirs.get(fullPathStr);
6097                     if (p != null) {
6098                         ps = mSettings.mPackages.get(p.applicationInfo.packageName);
6099                         if (ps != null) {
6100                             removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
6101                         } else {
6102                             removedUsers = sUserManager.getUserIds();
6103                         }
6104                     }
6105                     addedUsers = sUserManager.getUserIds();
6106                 }
6107                 if ((event&REMOVE_EVENTS) != 0) {
6108                     if (ps != null) {
6109                         if (DEBUG_REMOVE) Slog.d(TAG, "Package disappeared: " + ps);
6110                         removePackageLI(ps, true);
6111                         removedPackage = ps.name;
6112                         removedAppId = ps.appId;
6113                     }
6114                 }
6115
6116                 if ((event&ADD_EVENTS) != 0) {
6117                     if (p == null) {
6118                         if (DEBUG_INSTALL) Slog.d(TAG, "New file appeared: " + fullPath);
6119                         p = scanPackageLI(fullPath,
6120                                 (mIsRom ? PackageParser.PARSE_IS_SYSTEM
6121                                         | PackageParser.PARSE_IS_SYSTEM_DIR: 0) |
6122                                 PackageParser.PARSE_CHATTY |
6123                                 PackageParser.PARSE_MUST_BE_APK,
6124                                 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
6125                                 System.currentTimeMillis(), UserHandle.ALL);
6126                         if (p != null) {
6127                             /*
6128                              * TODO this seems dangerous as the package may have
6129                              * changed since we last acquired the mPackages
6130                              * lock.
6131                              */
6132                             // writer
6133                             synchronized (mPackages) {
6134                                 updatePermissionsLPw(p.packageName, p,
6135                                         p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0);
6136                             }
6137                             addedPackage = p.applicationInfo.packageName;
6138                             addedAppId = UserHandle.getAppId(p.applicationInfo.uid);
6139                         }
6140                     }
6141                 }
6142
6143                 // reader
6144                 synchronized (mPackages) {
6145                     mSettings.writeLPr();
6146                 }
6147             }
6148
6149             if (removedPackage != null) {
6150                 Bundle extras = new Bundle(1);
6151                 extras.putInt(Intent.EXTRA_UID, removedAppId);
6152                 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
6153                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
6154                         extras, null, null, removedUsers);
6155             }
6156             if (addedPackage != null) {
6157                 Bundle extras = new Bundle(1);
6158                 extras.putInt(Intent.EXTRA_UID, addedAppId);
6159                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
6160                         extras, null, null, addedUsers);
6161             }
6162         }
6163
6164         private final String mRootDir;
6165         private final boolean mIsRom;
6166     }
6167
6168     /* Called when a downloaded package installation has been confirmed by the user */
6169     public void installPackage(
6170             final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
6171         installPackage(packageURI, observer, flags, null);
6172     }
6173
6174     /* Called when a downloaded package installation has been confirmed by the user */
6175     public void installPackage(
6176             final Uri packageURI, final IPackageInstallObserver observer, final int flags,
6177             final String installerPackageName) {
6178         installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
6179                 null, null);
6180     }
6181
6182     @Override
6183     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
6184             int flags, String installerPackageName, Uri verificationURI,
6185             ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
6186         VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
6187                 VerificationParams.NO_UID, manifestDigest);
6188         installPackageWithVerificationAndEncryption(packageURI, observer, flags,
6189                 installerPackageName, verificationParams, encryptionParams);
6190     }
6191
6192     public void installPackageWithVerificationAndEncryption(Uri packageURI,
6193             IPackageInstallObserver observer, int flags, String installerPackageName,
6194             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
6195         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
6196                 null);
6197
6198         final int uid = Binder.getCallingUid();
6199         if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
6200             try {
6201                 observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED);
6202             } catch (RemoteException re) {
6203             }
6204             return;
6205         }
6206
6207         UserHandle user;
6208         if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) {
6209             user = UserHandle.ALL;
6210         } else {
6211             user = new UserHandle(UserHandle.getUserId(uid));
6212         }
6213
6214         final int filteredFlags;
6215
6216         if (uid == Process.SHELL_UID || uid == 0) {
6217             if (DEBUG_INSTALL) {
6218                 Slog.v(TAG, "Install from ADB");
6219             }
6220             filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
6221         } else {
6222             filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
6223         }
6224
6225         verificationParams.setInstallerUid(uid);
6226
6227         final Message msg = mHandler.obtainMessage(INIT_COPY);
6228         msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
6229                 verificationParams, encryptionParams, user);
6230         mHandler.sendMessage(msg);
6231     }
6232
6233     /**
6234      * @hide
6235      */
6236     @Override
6237     public int installExistingPackageAsUser(String packageName, int userId) {
6238         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
6239                 null);
6240         PackageSetting pkgSetting;
6241         final int uid = Binder.getCallingUid();
6242         if (UserHandle.getUserId(uid) != userId) {
6243             mContext.enforceCallingPermission(
6244                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6245                     "installExistingPackage for user " + userId);
6246         }
6247         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
6248             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
6249         }
6250
6251         long callingId = Binder.clearCallingIdentity();
6252         try {
6253             boolean sendAdded = false;
6254             Bundle extras = new Bundle(1);
6255
6256             // writer
6257             synchronized (mPackages) {
6258                 pkgSetting = mSettings.mPackages.get(packageName);
6259                 if (pkgSetting == null) {
6260                     return PackageManager.INSTALL_FAILED_INVALID_URI;
6261                 }
6262                 if (!pkgSetting.getInstalled(userId)) {
6263                     pkgSetting.setInstalled(true, userId);
6264                     mSettings.writePackageRestrictionsLPr(userId);
6265                     extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
6266                     sendAdded = true;
6267                 }
6268             }
6269
6270             if (sendAdded) {
6271                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
6272                         packageName, extras, null, null, new int[] {userId});
6273                 try {
6274                     IActivityManager am = ActivityManagerNative.getDefault();
6275                     final boolean isSystem =
6276                             isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
6277                     if (isSystem && am.isUserRunning(userId, false)) {
6278                         // The just-installed/enabled app is bundled on the system, so presumed
6279                         // to be able to run automatically without needing an explicit launch.
6280                         // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
6281                         Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
6282                                 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
6283                                 .setPackage(packageName);
6284                         am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
6285                                 android.app.AppOpsManager.OP_NONE, false, false, userId);
6286                     }
6287                 } catch (RemoteException e) {
6288                     // shouldn't happen
6289                     Slog.w(TAG, "Unable to bootstrap installed package", e);
6290                 }
6291             }
6292         } finally {
6293             Binder.restoreCallingIdentity(callingId);
6294         }
6295
6296         return PackageManager.INSTALL_SUCCEEDED;
6297     }
6298
6299     private boolean isUserRestricted(int userId, String restrictionKey) {
6300         Bundle restrictions = sUserManager.getUserRestrictions(userId);
6301         if (restrictions.getBoolean(restrictionKey, false)) {
6302             Log.w(TAG, "User is restricted: " + restrictionKey);
6303             return true;
6304         }
6305         return false;
6306     }
6307
6308     @Override
6309     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
6310         mContext.enforceCallingOrSelfPermission(
6311                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
6312                 "Only package verification agents can verify applications");
6313
6314         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
6315         final PackageVerificationResponse response = new PackageVerificationResponse(
6316                 verificationCode, Binder.getCallingUid());
6317         msg.arg1 = id;
6318         msg.obj = response;
6319         mHandler.sendMessage(msg);
6320     }
6321
6322     @Override
6323     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
6324             long millisecondsToDelay) {
6325         mContext.enforceCallingOrSelfPermission(
6326                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
6327                 "Only package verification agents can extend verification timeouts");
6328
6329         final PackageVerificationState state = mPendingVerification.get(id);
6330         final PackageVerificationResponse response = new PackageVerificationResponse(
6331                 verificationCodeAtTimeout, Binder.getCallingUid());
6332
6333         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
6334             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
6335         }
6336         if (millisecondsToDelay < 0) {
6337             millisecondsToDelay = 0;
6338         }
6339         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
6340                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
6341             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
6342         }
6343
6344         if ((state != null) && !state.timeoutExtended()) {
6345             state.extendTimeout();
6346
6347             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
6348             msg.arg1 = id;
6349             msg.obj = response;
6350             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
6351         }
6352     }
6353
6354     private void broadcastPackageVerified(int verificationId, Uri packageUri,
6355             int verificationCode, UserHandle user) {
6356         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
6357         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
6358         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
6359         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
6360         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
6361
6362         mContext.sendBroadcastAsUser(intent, user,
6363                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
6364     }
6365
6366     private ComponentName matchComponentForVerifier(String packageName,
6367             List<ResolveInfo> receivers) {
6368         ActivityInfo targetReceiver = null;
6369
6370         final int NR = receivers.size();
6371         for (int i = 0; i < NR; i++) {
6372             final ResolveInfo info = receivers.get(i);
6373             if (info.activityInfo == null) {
6374                 continue;
6375             }
6376
6377             if (packageName.equals(info.activityInfo.packageName)) {
6378                 targetReceiver = info.activityInfo;
6379                 break;
6380             }
6381         }
6382
6383         if (targetReceiver == null) {
6384             return null;
6385         }
6386
6387         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
6388     }
6389
6390     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
6391             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
6392         if (pkgInfo.verifiers.length == 0) {
6393             return null;
6394         }
6395
6396         final int N = pkgInfo.verifiers.length;
6397         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
6398         for (int i = 0; i < N; i++) {
6399             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
6400
6401             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
6402                     receivers);
6403             if (comp == null) {
6404                 continue;
6405             }
6406
6407             final int verifierUid = getUidForVerifier(verifierInfo);
6408             if (verifierUid == -1) {
6409                 continue;
6410             }
6411
6412             if (DEBUG_VERIFY) {
6413                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
6414                         + " with the correct signature");
6415             }
6416             sufficientVerifiers.add(comp);
6417             verificationState.addSufficientVerifier(verifierUid);
6418         }
6419
6420         return sufficientVerifiers;
6421     }
6422
6423     private int getUidForVerifier(VerifierInfo verifierInfo) {
6424         synchronized (mPackages) {
6425             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
6426             if (pkg == null) {
6427                 return -1;
6428             } else if (pkg.mSignatures.length != 1) {
6429                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
6430                         + " has more than one signature; ignoring");
6431                 return -1;
6432             }
6433
6434             /*
6435              * If the public key of the package's signature does not match
6436              * our expected public key, then this is a different package and
6437              * we should skip.
6438              */
6439
6440             final byte[] expectedPublicKey;
6441             try {
6442                 final Signature verifierSig = pkg.mSignatures[0];
6443                 final PublicKey publicKey = verifierSig.getPublicKey();
6444                 expectedPublicKey = publicKey.getEncoded();
6445             } catch (CertificateException e) {
6446                 return -1;
6447             }
6448
6449             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
6450
6451             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
6452                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
6453                         + " does not have the expected public key; ignoring");
6454                 return -1;
6455             }
6456
6457             return pkg.applicationInfo.uid;
6458         }
6459     }
6460
6461     public void finishPackageInstall(int token) {
6462         enforceSystemOrRoot("Only the system is allowed to finish installs");
6463
6464         if (DEBUG_INSTALL) {
6465             Slog.v(TAG, "BM finishing package install for " + token);
6466         }
6467
6468         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
6469         mHandler.sendMessage(msg);
6470     }
6471
6472     /**
6473      * Get the verification agent timeout.
6474      *
6475      * @return verification timeout in milliseconds
6476      */
6477     private long getVerificationTimeout() {
6478         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
6479                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
6480                 DEFAULT_VERIFICATION_TIMEOUT);
6481     }
6482
6483     /**
6484      * Get the default verification agent response code.
6485      *
6486      * @return default verification response code
6487      */
6488     private int getDefaultVerificationResponse() {
6489         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6490                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
6491                 DEFAULT_VERIFICATION_RESPONSE);
6492     }
6493
6494     /**
6495      * Check whether or not package verification has been enabled.
6496      *
6497      * @return true if verification should be performed
6498      */
6499     private boolean isVerificationEnabled(int flags) {
6500         if (!DEFAULT_VERIFY_ENABLE) {
6501             return false;
6502         }
6503
6504         // Check if installing from ADB
6505         if ((flags & PackageManager.INSTALL_FROM_ADB) != 0) {
6506             // Do not run verification in a test harness environment
6507             if (ActivityManager.isRunningInTestHarness()) {
6508                 return false;
6509             }
6510             // Check if the developer does not want package verification for ADB installs
6511             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6512                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
6513                 return false;
6514             }
6515         }
6516
6517         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6518                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
6519     }
6520
6521     /**
6522      * Get the "allow unknown sources" setting.
6523      *
6524      * @return the current "allow unknown sources" setting
6525      */
6526     private int getUnknownSourcesSettings() {
6527         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
6528                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
6529                 -1);
6530     }
6531
6532     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
6533         final int uid = Binder.getCallingUid();
6534         // writer
6535         synchronized (mPackages) {
6536             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
6537             if (targetPackageSetting == null) {
6538                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
6539             }
6540
6541             PackageSetting installerPackageSetting;
6542             if (installerPackageName != null) {
6543                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
6544                 if (installerPackageSetting == null) {
6545                     throw new IllegalArgumentException("Unknown installer package: "
6546                             + installerPackageName);
6547                 }
6548             } else {
6549                 installerPackageSetting = null;
6550             }
6551
6552             Signature[] callerSignature;
6553             Object obj = mSettings.getUserIdLPr(uid);
6554             if (obj != null) {
6555                 if (obj instanceof SharedUserSetting) {
6556                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
6557                 } else if (obj instanceof PackageSetting) {
6558                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
6559                 } else {
6560                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
6561                 }
6562             } else {
6563                 throw new SecurityException("Unknown calling uid " + uid);
6564             }
6565
6566             // Verify: can't set installerPackageName to a package that is
6567             // not signed with the same cert as the caller.
6568             if (installerPackageSetting != null) {
6569                 if (compareSignatures(callerSignature,
6570                         installerPackageSetting.signatures.mSignatures)
6571                         != PackageManager.SIGNATURE_MATCH) {
6572                     throw new SecurityException(
6573                             "Caller does not have same cert as new installer package "
6574                             + installerPackageName);
6575                 }
6576             }
6577
6578             // Verify: if target already has an installer package, it must
6579             // be signed with the same cert as the caller.
6580             if (targetPackageSetting.installerPackageName != null) {
6581                 PackageSetting setting = mSettings.mPackages.get(
6582                         targetPackageSetting.installerPackageName);
6583                 // If the currently set package isn't valid, then it's always
6584                 // okay to change it.
6585                 if (setting != null) {
6586                     if (compareSignatures(callerSignature,
6587                             setting.signatures.mSignatures)
6588                             != PackageManager.SIGNATURE_MATCH) {
6589                         throw new SecurityException(
6590                                 "Caller does not have same cert as old installer package "
6591                                 + targetPackageSetting.installerPackageName);
6592                     }
6593                 }
6594             }
6595
6596             // Okay!
6597             targetPackageSetting.installerPackageName = installerPackageName;
6598             scheduleWriteSettingsLocked();
6599         }
6600     }
6601
6602     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
6603         // Queue up an async operation since the package installation may take a little while.
6604         mHandler.post(new Runnable() {
6605             public void run() {
6606                 mHandler.removeCallbacks(this);
6607                  // Result object to be returned
6608                 PackageInstalledInfo res = new PackageInstalledInfo();
6609                 res.returnCode = currentStatus;
6610                 res.uid = -1;
6611                 res.pkg = null;
6612                 res.removedInfo = new PackageRemovedInfo();
6613                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
6614                     args.doPreInstall(res.returnCode);
6615                     synchronized (mInstallLock) {
6616                         installPackageLI(args, true, res);
6617                     }
6618                     args.doPostInstall(res.returnCode, res.uid);
6619                 }
6620
6621                 // A restore should be performed at this point if (a) the install
6622                 // succeeded, (b) the operation is not an update, and (c) the new
6623                 // package has a backupAgent defined.
6624                 final boolean update = res.removedInfo.removedPackage != null;
6625                 boolean doRestore = (!update
6626                         && res.pkg != null
6627                         && res.pkg.applicationInfo.backupAgentName != null);
6628
6629                 // Set up the post-install work request bookkeeping.  This will be used
6630                 // and cleaned up by the post-install event handling regardless of whether
6631                 // there's a restore pass performed.  Token values are >= 1.
6632                 int token;
6633                 if (mNextInstallToken < 0) mNextInstallToken = 1;
6634                 token = mNextInstallToken++;
6635
6636                 PostInstallData data = new PostInstallData(args, res);
6637                 mRunningInstalls.put(token, data);
6638                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
6639
6640                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
6641                     // Pass responsibility to the Backup Manager.  It will perform a
6642                     // restore if appropriate, then pass responsibility back to the
6643                     // Package Manager to run the post-install observer callbacks
6644                     // and broadcasts.
6645                     IBackupManager bm = IBackupManager.Stub.asInterface(
6646                             ServiceManager.getService(Context.BACKUP_SERVICE));
6647                     if (bm != null) {
6648                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
6649                                 + " to BM for possible restore");
6650                         try {
6651                             bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
6652                         } catch (RemoteException e) {
6653                             // can't happen; the backup manager is local
6654                         } catch (Exception e) {
6655                             Slog.e(TAG, "Exception trying to enqueue restore", e);
6656                             doRestore = false;
6657                         }
6658                     } else {
6659                         Slog.e(TAG, "Backup Manager not found!");
6660                         doRestore = false;
6661                     }
6662                 }
6663
6664                 if (!doRestore) {
6665                     // No restore possible, or the Backup Manager was mysteriously not
6666                     // available -- just fire the post-install work request directly.
6667                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
6668                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
6669                     mHandler.sendMessage(msg);
6670                 }
6671             }
6672         });
6673     }
6674
6675     private abstract class HandlerParams {
6676         private static final int MAX_RETRIES = 4;
6677
6678         /**
6679          * Number of times startCopy() has been attempted and had a non-fatal
6680          * error.
6681          */
6682         private int mRetries = 0;
6683
6684         /** User handle for the user requesting the information or installation. */
6685         private final UserHandle mUser;
6686
6687         HandlerParams(UserHandle user) {
6688             mUser = user;
6689         }
6690
6691         UserHandle getUser() {
6692             return mUser;
6693         }
6694
6695         final boolean startCopy() {
6696             boolean res;
6697             try {
6698                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
6699
6700                 if (++mRetries > MAX_RETRIES) {
6701                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
6702                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
6703                     handleServiceError();
6704                     return false;
6705                 } else {
6706                     handleStartCopy();
6707                     res = true;
6708                 }
6709             } catch (RemoteException e) {
6710                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
6711                 mHandler.sendEmptyMessage(MCS_RECONNECT);
6712                 res = false;
6713             }
6714             handleReturnCode();
6715             return res;
6716         }
6717
6718         final void serviceError() {
6719             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
6720             handleServiceError();
6721             handleReturnCode();
6722         }
6723
6724         abstract void handleStartCopy() throws RemoteException;
6725         abstract void handleServiceError();
6726         abstract void handleReturnCode();
6727     }
6728
6729     class MeasureParams extends HandlerParams {
6730         private final PackageStats mStats;
6731         private boolean mSuccess;
6732
6733         private final IPackageStatsObserver mObserver;
6734
6735         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
6736             super(new UserHandle(stats.userHandle));
6737             mObserver = observer;
6738             mStats = stats;
6739         }
6740
6741         @Override
6742         public String toString() {
6743             return "MeasureParams{"
6744                 + Integer.toHexString(System.identityHashCode(this))
6745                 + " " + mStats.packageName + "}";
6746         }
6747
6748         @Override
6749         void handleStartCopy() throws RemoteException {
6750             synchronized (mInstallLock) {
6751                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
6752             }
6753
6754             final boolean mounted;
6755             if (Environment.isExternalStorageEmulated()) {
6756                 mounted = true;
6757             } else {
6758                 final String status = Environment.getExternalStorageState();
6759                 mounted = (Environment.MEDIA_MOUNTED.equals(status)
6760                         || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
6761             }
6762
6763             if (mounted) {
6764                 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
6765
6766                 final File externalCacheDir = userEnv
6767                         .getExternalStorageAppCacheDirectory(mStats.packageName);
6768                 final long externalCacheSize = mContainerService
6769                         .calculateDirectorySize(externalCacheDir.getPath());
6770                 mStats.externalCacheSize = externalCacheSize;
6771
6772                 final File externalDataDir = userEnv
6773                         .getExternalStorageAppDataDirectory(mStats.packageName);
6774                 long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
6775                         .getPath());
6776
6777                 if (externalCacheDir.getParentFile().equals(externalDataDir)) {
6778                     externalDataSize -= externalCacheSize;
6779                 }
6780                 mStats.externalDataSize = externalDataSize;
6781
6782                 final File externalMediaDir = userEnv
6783                         .getExternalStorageAppMediaDirectory(mStats.packageName);
6784                 mStats.externalMediaSize = mContainerService
6785                         .calculateDirectorySize(externalMediaDir.getPath());
6786
6787                 final File externalObbDir = userEnv
6788                         .getExternalStorageAppObbDirectory(mStats.packageName);
6789                 mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir
6790                         .getPath());
6791             }
6792         }
6793
6794         @Override
6795         void handleReturnCode() {
6796             if (mObserver != null) {
6797                 try {
6798                     mObserver.onGetStatsCompleted(mStats, mSuccess);
6799                 } catch (RemoteException e) {
6800                     Slog.i(TAG, "Observer no longer exists.");
6801                 }
6802             }
6803         }
6804
6805         @Override
6806         void handleServiceError() {
6807             Slog.e(TAG, "Could not measure application " + mStats.packageName
6808                             + " external storage");
6809         }
6810     }
6811
6812     class InstallParams extends HandlerParams {
6813         final IPackageInstallObserver observer;
6814         int flags;
6815
6816         private final Uri mPackageURI;
6817         final String installerPackageName;
6818         final VerificationParams verificationParams;
6819         private InstallArgs mArgs;
6820         private int mRet;
6821         private File mTempPackage;
6822         final ContainerEncryptionParams encryptionParams;
6823
6824         InstallParams(Uri packageURI,
6825                 IPackageInstallObserver observer, int flags,
6826                 String installerPackageName, VerificationParams verificationParams,
6827                 ContainerEncryptionParams encryptionParams, UserHandle user) {
6828             super(user);
6829             this.mPackageURI = packageURI;
6830             this.flags = flags;
6831             this.observer = observer;
6832             this.installerPackageName = installerPackageName;
6833             this.verificationParams = verificationParams;
6834             this.encryptionParams = encryptionParams;
6835         }
6836
6837         @Override
6838         public String toString() {
6839             return "InstallParams{"
6840                 + Integer.toHexString(System.identityHashCode(this))
6841                 + " " + mPackageURI + "}";
6842         }
6843
6844         public ManifestDigest getManifestDigest() {
6845             if (verificationParams == null) {
6846                 return null;
6847             }
6848             return verificationParams.getManifestDigest();
6849         }
6850
6851         private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
6852             String packageName = pkgLite.packageName;
6853             int installLocation = pkgLite.installLocation;
6854             boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
6855             // reader
6856             synchronized (mPackages) {
6857                 PackageParser.Package pkg = mPackages.get(packageName);
6858                 if (pkg != null) {
6859                     if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
6860                         // Check for downgrading.
6861                         if ((flags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
6862                             if (pkgLite.versionCode < pkg.mVersionCode) {
6863                                 Slog.w(TAG, "Can't install update of " + packageName
6864                                         + " update version " + pkgLite.versionCode
6865                                         + " is older than installed version "
6866                                         + pkg.mVersionCode);
6867                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
6868                             }
6869                         }
6870                         // Check for updated system application.
6871                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
6872                             if (onSd) {
6873                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
6874                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
6875                             }
6876                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6877                         } else {
6878                             if (onSd) {
6879                                 // Install flag overrides everything.
6880                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6881                             }
6882                             // If current upgrade specifies particular preference
6883                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
6884                                 // Application explicitly specified internal.
6885                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6886                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
6887                                 // App explictly prefers external. Let policy decide
6888                             } else {
6889                                 // Prefer previous location
6890                                 if (isExternal(pkg)) {
6891                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6892                                 }
6893                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
6894                             }
6895                         }
6896                     } else {
6897                         // Invalid install. Return error code
6898                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
6899                     }
6900                 }
6901             }
6902             // All the special cases have been taken care of.
6903             // Return result based on recommended install location.
6904             if (onSd) {
6905                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
6906             }
6907             return pkgLite.recommendedInstallLocation;
6908         }
6909
6910         /*
6911          * Invoke remote method to get package information and install
6912          * location values. Override install location based on default
6913          * policy if needed and then create install arguments based
6914          * on the install location.
6915          */
6916         public void handleStartCopy() throws RemoteException {
6917             int ret = PackageManager.INSTALL_SUCCEEDED;
6918             final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
6919             final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
6920             PackageInfoLite pkgLite = null;
6921
6922             if (onInt && onSd) {
6923                 // Check if both bits are set.
6924                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
6925                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
6926             } else {
6927                 final long lowThreshold;
6928
6929                 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
6930                         .getService(DeviceStorageMonitorService.SERVICE);
6931                 if (dsm == null) {
6932                     Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
6933                     lowThreshold = 0L;
6934                 } else {
6935                     lowThreshold = dsm.getMemoryLowThreshold();
6936                 }
6937
6938                 try {
6939                     mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, mPackageURI,
6940                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
6941
6942                     final File packageFile;
6943                     if (encryptionParams != null || !"file".equals(mPackageURI.getScheme())) {
6944                         mTempPackage = createTempPackageFile(mDrmAppPrivateInstallDir);
6945                         if (mTempPackage != null) {
6946                             ParcelFileDescriptor out;
6947                             try {
6948                                 out = ParcelFileDescriptor.open(mTempPackage,
6949                                         ParcelFileDescriptor.MODE_READ_WRITE);
6950                             } catch (FileNotFoundException e) {
6951                                 out = null;
6952                                 Slog.e(TAG, "Failed to create temporary file for : " + mPackageURI);
6953                             }
6954
6955                             // Make a temporary file for decryption.
6956                             ret = mContainerService
6957                                     .copyResource(mPackageURI, encryptionParams, out);
6958                             IoUtils.closeQuietly(out);
6959
6960                             packageFile = mTempPackage;
6961
6962                             FileUtils.setPermissions(packageFile.getAbsolutePath(),
6963                                     FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP
6964                                             | FileUtils.S_IROTH,
6965                                     -1, -1);
6966                         } else {
6967                             packageFile = null;
6968                         }
6969                     } else {
6970                         packageFile = new File(mPackageURI.getPath());
6971                     }
6972
6973                     if (packageFile != null) {
6974                         // Remote call to find out default install location
6975                         final String packageFilePath = packageFile.getAbsolutePath();
6976                         pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags,
6977                                 lowThreshold);
6978
6979                         /*
6980                          * If we have too little free space, try to free cache
6981                          * before giving up.
6982                          */
6983                         if (pkgLite.recommendedInstallLocation
6984                                 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
6985                             final long size = mContainerService.calculateInstalledSize(
6986                                     packageFilePath, isForwardLocked());
6987                             if (mInstaller.freeCache(size + lowThreshold) >= 0) {
6988                                 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath,
6989                                         flags, lowThreshold);
6990                             }
6991                             /*
6992                              * The cache free must have deleted the file we
6993                              * downloaded to install.
6994                              *
6995                              * TODO: fix the "freeCache" call to not delete
6996                              *       the file we care about.
6997                              */
6998                             if (pkgLite.recommendedInstallLocation
6999                                     == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
7000                                 pkgLite.recommendedInstallLocation
7001                                     = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
7002                             }
7003                         }
7004                     }
7005                 } finally {
7006                     mContext.revokeUriPermission(mPackageURI,
7007                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
7008                 }
7009             }
7010
7011             if (ret == PackageManager.INSTALL_SUCCEEDED) {
7012                 int loc = pkgLite.recommendedInstallLocation;
7013                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
7014                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
7015                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
7016                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
7017                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
7018                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7019                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
7020                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
7021                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
7022                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
7023                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
7024                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
7025                 } else {
7026                     // Override with defaults if needed.
7027                     loc = installLocationPolicy(pkgLite, flags);
7028                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
7029                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
7030                     } else if (!onSd && !onInt) {
7031                         // Override install location with flags
7032                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
7033                             // Set the flag to install on external media.
7034                             flags |= PackageManager.INSTALL_EXTERNAL;
7035                             flags &= ~PackageManager.INSTALL_INTERNAL;
7036                         } else {
7037                             // Make sure the flag for installing on external
7038                             // media is unset
7039                             flags |= PackageManager.INSTALL_INTERNAL;
7040                             flags &= ~PackageManager.INSTALL_EXTERNAL;
7041                         }
7042                     }
7043                 }
7044             }
7045
7046             final InstallArgs args = createInstallArgs(this);
7047             mArgs = args;
7048
7049             if (ret == PackageManager.INSTALL_SUCCEEDED) {
7050                  /*
7051                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
7052                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
7053                  */
7054                 int userIdentifier = getUser().getIdentifier();
7055                 if (userIdentifier == UserHandle.USER_ALL
7056                         && ((flags & PackageManager.INSTALL_FROM_ADB) != 0)) {
7057                     userIdentifier = UserHandle.USER_OWNER;
7058                 }
7059
7060                 /*
7061                  * Determine if we have any installed package verifiers. If we
7062                  * do, then we'll defer to them to verify the packages.
7063                  */
7064                 final int requiredUid = mRequiredVerifierPackage == null ? -1
7065                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
7066                 if (requiredUid != -1 && isVerificationEnabled(flags)) {
7067                     final Intent verification = new Intent(
7068                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
7069                     verification.setDataAndType(getPackageUri(), PACKAGE_MIME_TYPE);
7070                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
7071
7072                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
7073                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
7074                             0 /* TODO: Which userId? */);
7075
7076                     if (DEBUG_VERIFY) {
7077                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
7078                                 + verification.toString() + " with " + pkgLite.verifiers.length
7079                                 + " optional verifiers");
7080                     }
7081
7082                     final int verificationId = mPendingVerificationToken++;
7083
7084                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
7085
7086                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
7087                             installerPackageName);
7088
7089                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
7090
7091                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
7092                             pkgLite.packageName);
7093
7094                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
7095                             pkgLite.versionCode);
7096
7097                     if (verificationParams != null) {
7098                         if (verificationParams.getVerificationURI() != null) {
7099                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
7100                                  verificationParams.getVerificationURI());
7101                         }
7102                         if (verificationParams.getOriginatingURI() != null) {
7103                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
7104                                   verificationParams.getOriginatingURI());
7105                         }
7106                         if (verificationParams.getReferrer() != null) {
7107                             verification.putExtra(Intent.EXTRA_REFERRER,
7108                                   verificationParams.getReferrer());
7109                         }
7110                         if (verificationParams.getOriginatingUid() >= 0) {
7111                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
7112                                   verificationParams.getOriginatingUid());
7113                         }
7114                         if (verificationParams.getInstallerUid() >= 0) {
7115                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
7116                                   verificationParams.getInstallerUid());
7117                         }
7118                     }
7119
7120                     final PackageVerificationState verificationState = new PackageVerificationState(
7121                             requiredUid, args);
7122
7123                     mPendingVerification.append(verificationId, verificationState);
7124
7125                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
7126                             receivers, verificationState);
7127
7128                     /*
7129                      * If any sufficient verifiers were listed in the package
7130                      * manifest, attempt to ask them.
7131                      */
7132                     if (sufficientVerifiers != null) {
7133                         final int N = sufficientVerifiers.size();
7134                         if (N == 0) {
7135                             Slog.i(TAG, "Additional verifiers required, but none installed.");
7136                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
7137                         } else {
7138                             for (int i = 0; i < N; i++) {
7139                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
7140
7141                                 final Intent sufficientIntent = new Intent(verification);
7142                                 sufficientIntent.setComponent(verifierComponent);
7143
7144                                 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
7145                             }
7146                         }
7147                     }
7148
7149                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
7150                             mRequiredVerifierPackage, receivers);
7151                     if (ret == PackageManager.INSTALL_SUCCEEDED
7152                             && mRequiredVerifierPackage != null) {
7153                         /*
7154                          * Send the intent to the required verification agent,
7155                          * but only start the verification timeout after the
7156                          * target BroadcastReceivers have run.
7157                          */
7158                         verification.setComponent(requiredVerifierComponent);
7159                         mContext.sendOrderedBroadcastAsUser(verification, getUser(),
7160                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
7161                                 new BroadcastReceiver() {
7162                                     @Override
7163                                     public void onReceive(Context context, Intent intent) {
7164                                         final Message msg = mHandler
7165                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
7166                                         msg.arg1 = verificationId;
7167                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
7168                                     }
7169                                 }, null, 0, null, null);
7170
7171                         /*
7172                          * We don't want the copy to proceed until verification
7173                          * succeeds, so null out this field.
7174                          */
7175                         mArgs = null;
7176                     }
7177                 } else {
7178                     /*
7179                      * No package verification is enabled, so immediately start
7180                      * the remote call to initiate copy using temporary file.
7181                      */
7182                     ret = args.copyApk(mContainerService, true);
7183                 }
7184             }
7185
7186             mRet = ret;
7187         }
7188
7189         @Override
7190         void handleReturnCode() {
7191             // If mArgs is null, then MCS couldn't be reached. When it
7192             // reconnects, it will try again to install. At that point, this
7193             // will succeed.
7194             if (mArgs != null) {
7195                 processPendingInstall(mArgs, mRet);
7196
7197                 if (mTempPackage != null) {
7198                     if (!mTempPackage.delete()) {
7199                         Slog.w(TAG, "Couldn't delete temporary file: " +
7200                                 mTempPackage.getAbsolutePath());
7201                     }
7202                 }
7203             }
7204         }
7205
7206         @Override
7207         void handleServiceError() {
7208             mArgs = createInstallArgs(this);
7209             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
7210         }
7211
7212         public boolean isForwardLocked() {
7213             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7214         }
7215
7216         public Uri getPackageUri() {
7217             if (mTempPackage != null) {
7218                 return Uri.fromFile(mTempPackage);
7219             } else {
7220                 return mPackageURI;
7221             }
7222         }
7223     }
7224
7225     /*
7226      * Utility class used in movePackage api.
7227      * srcArgs and targetArgs are not set for invalid flags and make
7228      * sure to do null checks when invoking methods on them.
7229      * We probably want to return ErrorPrams for both failed installs
7230      * and moves.
7231      */
7232     class MoveParams extends HandlerParams {
7233         final IPackageMoveObserver observer;
7234         final int flags;
7235         final String packageName;
7236         final InstallArgs srcArgs;
7237         final InstallArgs targetArgs;
7238         int uid;
7239         int mRet;
7240
7241         MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
7242                 String packageName, String dataDir, int uid, UserHandle user) {
7243             super(user);
7244             this.srcArgs = srcArgs;
7245             this.observer = observer;
7246             this.flags = flags;
7247             this.packageName = packageName;
7248             this.uid = uid;
7249             if (srcArgs != null) {
7250                 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
7251                 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
7252             } else {
7253                 targetArgs = null;
7254             }
7255         }
7256
7257         @Override
7258         public String toString() {
7259             return "MoveParams{"
7260                 + Integer.toHexString(System.identityHashCode(this))
7261                 + " " + packageName + "}";
7262         }
7263
7264         public void handleStartCopy() throws RemoteException {
7265             mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7266             // Check for storage space on target medium
7267             if (!targetArgs.checkFreeStorage(mContainerService)) {
7268                 Log.w(TAG, "Insufficient storage to install");
7269                 return;
7270             }
7271
7272             mRet = srcArgs.doPreCopy();
7273             if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7274                 return;
7275             }
7276
7277             mRet = targetArgs.copyApk(mContainerService, false);
7278             if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7279                 srcArgs.doPostCopy(uid);
7280                 return;
7281             }
7282
7283             mRet = srcArgs.doPostCopy(uid);
7284             if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7285                 return;
7286             }
7287
7288             mRet = targetArgs.doPreInstall(mRet);
7289             if (mRet != PackageManager.INSTALL_SUCCEEDED) {
7290                 return;
7291             }
7292
7293             if (DEBUG_SD_INSTALL) {
7294                 StringBuilder builder = new StringBuilder();
7295                 if (srcArgs != null) {
7296                     builder.append("src: ");
7297                     builder.append(srcArgs.getCodePath());
7298                 }
7299                 if (targetArgs != null) {
7300                     builder.append(" target : ");
7301                     builder.append(targetArgs.getCodePath());
7302                 }
7303                 Log.i(TAG, builder.toString());
7304             }
7305         }
7306
7307         @Override
7308         void handleReturnCode() {
7309             targetArgs.doPostInstall(mRet, uid);
7310             int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
7311             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
7312                 currentStatus = PackageManager.MOVE_SUCCEEDED;
7313             } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
7314                 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
7315             }
7316             processPendingMove(this, currentStatus);
7317         }
7318
7319         @Override
7320         void handleServiceError() {
7321             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
7322         }
7323     }
7324
7325     /**
7326      * Used during creation of InstallArgs
7327      *
7328      * @param flags package installation flags
7329      * @return true if should be installed on external storage
7330      */
7331     private static boolean installOnSd(int flags) {
7332         if ((flags & PackageManager.INSTALL_INTERNAL) != 0) {
7333             return false;
7334         }
7335         if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
7336             return true;
7337         }
7338         return false;
7339     }
7340
7341     /**
7342      * Used during creation of InstallArgs
7343      *
7344      * @param flags package installation flags
7345      * @return true if should be installed as forward locked
7346      */
7347     private static boolean installForwardLocked(int flags) {
7348         return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7349     }
7350
7351     private InstallArgs createInstallArgs(InstallParams params) {
7352         if (installOnSd(params.flags) || params.isForwardLocked()) {
7353             return new AsecInstallArgs(params);
7354         } else {
7355             return new FileInstallArgs(params);
7356         }
7357     }
7358
7359     private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
7360             String nativeLibraryPath) {
7361         final boolean isInAsec;
7362         if (installOnSd(flags)) {
7363             /* Apps on SD card are always in ASEC containers. */
7364             isInAsec = true;
7365         } else if (installForwardLocked(flags)
7366                 && !fullCodePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
7367             /*
7368              * Forward-locked apps are only in ASEC containers if they're the
7369              * new style
7370              */
7371             isInAsec = true;
7372         } else {
7373             isInAsec = false;
7374         }
7375
7376         if (isInAsec) {
7377             return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath,
7378                     installOnSd(flags), installForwardLocked(flags));
7379         } else {
7380             return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
7381         }
7382     }
7383
7384     // Used by package mover
7385     private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
7386         if (installOnSd(flags) || installForwardLocked(flags)) {
7387             String cid = getNextCodePath(packageURI.getPath(), pkgName, "/"
7388                     + AsecInstallArgs.RES_FILE_NAME);
7389             return new AsecInstallArgs(packageURI, cid, installOnSd(flags),
7390                     installForwardLocked(flags));
7391         } else {
7392             return new FileInstallArgs(packageURI, pkgName, dataDir);
7393         }
7394     }
7395
7396     static abstract class InstallArgs {
7397         final IPackageInstallObserver observer;
7398         // Always refers to PackageManager flags only
7399         final int flags;
7400         final Uri packageURI;
7401         final String installerPackageName;
7402         final ManifestDigest manifestDigest;
7403         final UserHandle user;
7404
7405         InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
7406                 String installerPackageName, ManifestDigest manifestDigest,
7407                 UserHandle user) {
7408             this.packageURI = packageURI;
7409             this.flags = flags;
7410             this.observer = observer;
7411             this.installerPackageName = installerPackageName;
7412             this.manifestDigest = manifestDigest;
7413             this.user = user;
7414         }
7415
7416         abstract void createCopyFile();
7417         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
7418         abstract int doPreInstall(int status);
7419         abstract boolean doRename(int status, String pkgName, String oldCodePath);
7420
7421         abstract int doPostInstall(int status, int uid);
7422         abstract String getCodePath();
7423         abstract String getResourcePath();
7424         abstract String getNativeLibraryPath();
7425         // Need installer lock especially for dex file removal.
7426         abstract void cleanUpResourcesLI();
7427         abstract boolean doPostDeleteLI(boolean delete);
7428         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
7429
7430         /**
7431          * Called before the source arguments are copied. This is used mostly
7432          * for MoveParams when it needs to read the source file to put it in the
7433          * destination.
7434          */
7435         int doPreCopy() {
7436             return PackageManager.INSTALL_SUCCEEDED;
7437         }
7438
7439         /**
7440          * Called after the source arguments are copied. This is used mostly for
7441          * MoveParams when it needs to read the source file to put it in the
7442          * destination.
7443          *
7444          * @return
7445          */
7446         int doPostCopy(int uid) {
7447             return PackageManager.INSTALL_SUCCEEDED;
7448         }
7449
7450         protected boolean isFwdLocked() {
7451             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
7452         }
7453
7454         UserHandle getUser() {
7455             return user;
7456         }
7457     }
7458
7459     class FileInstallArgs extends InstallArgs {
7460         File installDir;
7461         String codeFileName;
7462         String resourceFileName;
7463         String libraryPath;
7464         boolean created = false;
7465
7466         FileInstallArgs(InstallParams params) {
7467             super(params.getPackageUri(), params.observer, params.flags,
7468                     params.installerPackageName, params.getManifestDigest(),
7469                     params.getUser());
7470         }
7471
7472         FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
7473             super(null, null, 0, null, null, null);
7474             File codeFile = new File(fullCodePath);
7475             installDir = codeFile.getParentFile();
7476             codeFileName = fullCodePath;
7477             resourceFileName = fullResourcePath;
7478             libraryPath = nativeLibraryPath;
7479         }
7480
7481         FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
7482             super(packageURI, null, 0, null, null, null);
7483             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
7484             String apkName = getNextCodePath(null, pkgName, ".apk");
7485             codeFileName = new File(installDir, apkName + ".apk").getPath();
7486             resourceFileName = getResourcePathFromCodePath();
7487             libraryPath = new File(mAppLibInstallDir, pkgName).getPath();
7488         }
7489
7490         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
7491             final long lowThreshold;
7492
7493             final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
7494                     .getService(DeviceStorageMonitorService.SERVICE);
7495             if (dsm == null) {
7496                 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
7497                 lowThreshold = 0L;
7498             } else {
7499                 if (dsm.isMemoryLow()) {
7500                     Log.w(TAG, "Memory is reported as being too low; aborting package install");
7501                     return false;
7502                 }
7503
7504                 lowThreshold = dsm.getMemoryLowThreshold();
7505             }
7506
7507             try {
7508                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7509                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
7510                 return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold);
7511             } finally {
7512                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7513             }
7514         }
7515
7516         String getCodePath() {
7517             return codeFileName;
7518         }
7519
7520         void createCopyFile() {
7521             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
7522             codeFileName = createTempPackageFile(installDir).getPath();
7523             resourceFileName = getResourcePathFromCodePath();
7524             libraryPath = getLibraryPathFromCodePath();
7525             created = true;
7526         }
7527
7528         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
7529             if (temp) {
7530                 // Generate temp file name
7531                 createCopyFile();
7532             }
7533             // Get a ParcelFileDescriptor to write to the output file
7534             File codeFile = new File(codeFileName);
7535             if (!created) {
7536                 try {
7537                     codeFile.createNewFile();
7538                     // Set permissions
7539                     if (!setPermissions()) {
7540                         // Failed setting permissions.
7541                         return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7542                     }
7543                 } catch (IOException e) {
7544                    Slog.w(TAG, "Failed to create file " + codeFile);
7545                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7546                 }
7547             }
7548             ParcelFileDescriptor out = null;
7549             try {
7550                 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE);
7551             } catch (FileNotFoundException e) {
7552                 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName);
7553                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7554             }
7555             // Copy the resource now
7556             int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7557             try {
7558                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7559                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
7560                 ret = imcs.copyResource(packageURI, null, out);
7561             } finally {
7562                 IoUtils.closeQuietly(out);
7563                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7564             }
7565
7566             if (isFwdLocked()) {
7567                 final File destResourceFile = new File(getResourcePath());
7568
7569                 // Copy the public files
7570                 try {
7571                     PackageHelper.extractPublicFiles(codeFileName, destResourceFile);
7572                 } catch (IOException e) {
7573                     Slog.e(TAG, "Couldn't create a new zip file for the public parts of a"
7574                             + " forward-locked app.");
7575                     destResourceFile.delete();
7576                     return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
7577                 }
7578             }
7579
7580             final File nativeLibraryFile = new File(getNativeLibraryPath());
7581             Slog.i(TAG, "Copying native libraries to " + nativeLibraryFile.getPath());
7582             if (nativeLibraryFile.exists()) {
7583                 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
7584                 nativeLibraryFile.delete();
7585             }
7586             try {
7587                 int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile);
7588                 if (copyRet != PackageManager.INSTALL_SUCCEEDED && copyRet != PackageManager.INSTALL_ABI2_SUCCEEDED) {
7589                     return copyRet;
7590                 }
7591             } catch (IOException e) {
7592                 Slog.e(TAG, "Copying native libraries failed", e);
7593                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
7594             }
7595
7596             return ret;
7597         }
7598
7599         int doPreInstall(int status) {
7600             if (status != PackageManager.INSTALL_SUCCEEDED) {
7601                 cleanUp();
7602             }
7603             return status;
7604         }
7605
7606         boolean doRename(int status, final String pkgName, String oldCodePath) {
7607             if (status != PackageManager.INSTALL_SUCCEEDED) {
7608                 cleanUp();
7609                 return false;
7610             } else {
7611                 final File oldCodeFile = new File(getCodePath());
7612                 final File oldResourceFile = new File(getResourcePath());
7613                 final File oldLibraryFile = new File(getNativeLibraryPath());
7614
7615                 // Rename APK file based on packageName
7616                 final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
7617                 final File newCodeFile = new File(installDir, apkName + ".apk");
7618                 if (!oldCodeFile.renameTo(newCodeFile)) {
7619                     return false;
7620                 }
7621                 codeFileName = newCodeFile.getPath();
7622
7623                 // Rename public resource file if it's forward-locked.
7624                 final File newResFile = new File(getResourcePathFromCodePath());
7625                 if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) {
7626                     return false;
7627                 }
7628                 resourceFileName = newResFile.getPath();
7629
7630                 // Rename library path
7631                 final File newLibraryFile = new File(getLibraryPathFromCodePath());
7632                 if (newLibraryFile.exists()) {
7633                     NativeLibraryHelper.removeNativeBinariesFromDirLI(newLibraryFile);
7634                     newLibraryFile.delete();
7635                 }
7636                 if (!oldLibraryFile.renameTo(newLibraryFile)) {
7637                     Slog.e(TAG, "Cannot rename native library directory "
7638                             + oldLibraryFile.getPath() + " to " + newLibraryFile.getPath());
7639                     return false;
7640                 }
7641                 libraryPath = newLibraryFile.getPath();
7642
7643                 // Attempt to set permissions
7644                 if (!setPermissions()) {
7645                     return false;
7646                 }
7647
7648                 if (!SELinux.restorecon(newCodeFile)) {
7649                     return false;
7650                 }
7651
7652                 return true;
7653             }
7654         }
7655
7656         int doPostInstall(int status, int uid) {
7657             if (status != PackageManager.INSTALL_SUCCEEDED) {
7658                 cleanUp();
7659             }
7660             return status;
7661         }
7662
7663         String getResourcePath() {
7664             return resourceFileName;
7665         }
7666
7667         private String getResourcePathFromCodePath() {
7668             final String codePath = getCodePath();
7669             if (isFwdLocked()) {
7670                 final StringBuilder sb = new StringBuilder();
7671
7672                 sb.append(mAppInstallDir.getPath());
7673                 sb.append('/');
7674                 sb.append(getApkName(codePath));
7675                 sb.append(".zip");
7676
7677                 /*
7678                  * If our APK is a temporary file, mark the resource as a
7679                  * temporary file as well so it can be cleaned up after
7680                  * catastrophic failure.
7681                  */
7682                 if (codePath.endsWith(".tmp")) {
7683                     sb.append(".tmp");
7684                 }
7685
7686                 return sb.toString();
7687             } else {
7688                 return codePath;
7689             }
7690         }
7691
7692         private String getLibraryPathFromCodePath() {
7693             return new File(mAppLibInstallDir, getApkName(getCodePath())).getPath();
7694         }
7695
7696         @Override
7697         String getNativeLibraryPath() {
7698             if (libraryPath == null) {
7699                 libraryPath = getLibraryPathFromCodePath();
7700             }
7701             return libraryPath;
7702         }
7703
7704         private boolean cleanUp() {
7705             boolean ret = true;
7706             String sourceDir = getCodePath();
7707             String publicSourceDir = getResourcePath();
7708             if (sourceDir != null) {
7709                 File sourceFile = new File(sourceDir);
7710                 if (!sourceFile.exists()) {
7711                     Slog.w(TAG, "Package source " + sourceDir + " does not exist.");
7712                     ret = false;
7713                 }
7714                 // Delete application's code and resources
7715                 sourceFile.delete();
7716             }
7717             if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) {
7718                 final File publicSourceFile = new File(publicSourceDir);
7719                 if (!publicSourceFile.exists()) {
7720                     Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist.");
7721                 }
7722                 if (publicSourceFile.exists()) {
7723                     publicSourceFile.delete();
7724                 }
7725             }
7726
7727             if (libraryPath != null) {
7728                 File nativeLibraryFile = new File(libraryPath);
7729                 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
7730                 if (!nativeLibraryFile.delete()) {
7731                     Slog.w(TAG, "Couldn't delete native library directory " + libraryPath);
7732                 }
7733             }
7734
7735             return ret;
7736         }
7737
7738         void cleanUpResourcesLI() {
7739             String sourceDir = getCodePath();
7740             if (cleanUp()) {
7741                 int retCode = mInstaller.rmdex(sourceDir);
7742                 if (retCode < 0) {
7743                     Slog.w(TAG, "Couldn't remove dex file for package: "
7744                             +  " at location "
7745                             + sourceDir + ", retcode=" + retCode);
7746                     // we don't consider this to be a failure of the core package deletion
7747                 }
7748             }
7749         }
7750
7751         private boolean setPermissions() {
7752             // TODO Do this in a more elegant way later on. for now just a hack
7753             if (!isFwdLocked()) {
7754                 final int filePermissions =
7755                     FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
7756                     |FileUtils.S_IROTH;
7757                 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1);
7758                 if (retCode != 0) {
7759                     Slog.e(TAG, "Couldn't set new package file permissions for " +
7760                             getCodePath()
7761                             + ". The return code was: " + retCode);
7762                     // TODO Define new internal error
7763                     return false;
7764                 }
7765                 return true;
7766             }
7767             return true;
7768         }
7769
7770         boolean doPostDeleteLI(boolean delete) {
7771             // XXX err, shouldn't we respect the delete flag?
7772             cleanUpResourcesLI();
7773             return true;
7774         }
7775     }
7776
7777     private boolean isAsecExternal(String cid) {
7778         final String asecPath = PackageHelper.getSdFilesystem(cid);
7779         return !asecPath.startsWith(mAsecInternalPath);
7780     }
7781
7782     /**
7783      * Extract the MountService "container ID" from the full code path of an
7784      * .apk.
7785      */
7786     static String cidFromCodePath(String fullCodePath) {
7787         int eidx = fullCodePath.lastIndexOf("/");
7788         String subStr1 = fullCodePath.substring(0, eidx);
7789         int sidx = subStr1.lastIndexOf("/");
7790         return subStr1.substring(sidx+1, eidx);
7791     }
7792
7793     class AsecInstallArgs extends InstallArgs {
7794         static final String RES_FILE_NAME = "pkg.apk";
7795         static final String PUBLIC_RES_FILE_NAME = "res.zip";
7796
7797         String cid;
7798         String packagePath;
7799         String resourcePath;
7800         String libraryPath;
7801
7802         AsecInstallArgs(InstallParams params) {
7803             super(params.getPackageUri(), params.observer, params.flags,
7804                     params.installerPackageName, params.getManifestDigest(),
7805                     params.getUser());
7806         }
7807
7808         AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
7809                 boolean isExternal, boolean isForwardLocked) {
7810             super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
7811                     | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
7812                     null, null, null);
7813             // Extract cid from fullCodePath
7814             int eidx = fullCodePath.lastIndexOf("/");
7815             String subStr1 = fullCodePath.substring(0, eidx);
7816             int sidx = subStr1.lastIndexOf("/");
7817             cid = subStr1.substring(sidx+1, eidx);
7818             setCachePath(subStr1);
7819         }
7820
7821         AsecInstallArgs(String cid, boolean isForwardLocked) {
7822             super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0)
7823                     | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
7824                     null, null, null);
7825             this.cid = cid;
7826             setCachePath(PackageHelper.getSdDir(cid));
7827         }
7828
7829         AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) {
7830             super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0)
7831                     | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0),
7832                     null, null, null);
7833             this.cid = cid;
7834         }
7835
7836         void createCopyFile() {
7837             cid = getTempContainerId();
7838         }
7839
7840         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
7841             try {
7842                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7843                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
7844                 return imcs.checkExternalFreeStorage(packageURI, isFwdLocked());
7845             } finally {
7846                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7847             }
7848         }
7849
7850         private final boolean isExternal() {
7851             return (flags & PackageManager.INSTALL_EXTERNAL) != 0;
7852         }
7853
7854         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
7855             if (temp) {
7856                 createCopyFile();
7857             } else {
7858                 /*
7859                  * Pre-emptively destroy the container since it's destroyed if
7860                  * copying fails due to it existing anyway.
7861                  */
7862                 PackageHelper.destroySdDir(cid);
7863             }
7864
7865             final String newCachePath;
7866             try {
7867                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
7868                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
7869                 newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(),
7870                         RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked());
7871             } finally {
7872                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
7873             }
7874
7875             if (newCachePath != null) {
7876                 setCachePath(newCachePath);
7877                 return PackageManager.INSTALL_SUCCEEDED;
7878             } else {
7879                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7880             }
7881         }
7882
7883         @Override
7884         String getCodePath() {
7885             return packagePath;
7886         }
7887
7888         @Override
7889         String getResourcePath() {
7890             return resourcePath;
7891         }
7892
7893         @Override
7894         String getNativeLibraryPath() {
7895             return libraryPath;
7896         }
7897
7898         int doPreInstall(int status) {
7899             if (status != PackageManager.INSTALL_SUCCEEDED) {
7900                 // Destroy container
7901                 PackageHelper.destroySdDir(cid);
7902             } else {
7903                 boolean mounted = PackageHelper.isContainerMounted(cid);
7904                 if (!mounted) {
7905                     String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
7906                             Process.SYSTEM_UID);
7907                     if (newCachePath != null) {
7908                         setCachePath(newCachePath);
7909                     } else {
7910                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7911                     }
7912                 }
7913             }
7914             return status;
7915         }
7916
7917         boolean doRename(int status, final String pkgName,
7918                 String oldCodePath) {
7919             String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
7920             String newCachePath = null;
7921             if (PackageHelper.isContainerMounted(cid)) {
7922                 // Unmount the container
7923                 if (!PackageHelper.unMountSdDir(cid)) {
7924                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
7925                     return false;
7926                 }
7927             }
7928             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
7929                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
7930                         " which might be stale. Will try to clean up.");
7931                 // Clean up the stale container and proceed to recreate.
7932                 if (!PackageHelper.destroySdDir(newCacheId)) {
7933                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
7934                     return false;
7935                 }
7936                 // Successfully cleaned up stale container. Try to rename again.
7937                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
7938                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
7939                             + " inspite of cleaning it up.");
7940                     return false;
7941                 }
7942             }
7943             if (!PackageHelper.isContainerMounted(newCacheId)) {
7944                 Slog.w(TAG, "Mounting container " + newCacheId);
7945                 newCachePath = PackageHelper.mountSdDir(newCacheId,
7946                         getEncryptKey(), Process.SYSTEM_UID);
7947             } else {
7948                 newCachePath = PackageHelper.getSdDir(newCacheId);
7949             }
7950             if (newCachePath == null) {
7951                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
7952                 return false;
7953             }
7954             Log.i(TAG, "Succesfully renamed " + cid +
7955                     " to " + newCacheId +
7956                     " at new path: " + newCachePath);
7957             cid = newCacheId;
7958             setCachePath(newCachePath);
7959             return true;
7960         }
7961
7962         private void setCachePath(String newCachePath) {
7963             File cachePath = new File(newCachePath);
7964             libraryPath = new File(cachePath, LIB_DIR_NAME).getPath();
7965             packagePath = new File(cachePath, RES_FILE_NAME).getPath();
7966
7967             if (isFwdLocked()) {
7968                 resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath();
7969             } else {
7970                 resourcePath = packagePath;
7971             }
7972         }
7973
7974         int doPostInstall(int status, int uid) {
7975             if (status != PackageManager.INSTALL_SUCCEEDED) {
7976                 cleanUp();
7977             } else {
7978                 final int groupOwner;
7979                 final String protectedFile;
7980                 if (isFwdLocked()) {
7981                     groupOwner = UserHandle.getSharedAppGid(uid);
7982                     protectedFile = RES_FILE_NAME;
7983                 } else {
7984                     groupOwner = -1;
7985                     protectedFile = null;
7986                 }
7987
7988                 if (uid < Process.FIRST_APPLICATION_UID
7989                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
7990                     Slog.e(TAG, "Failed to finalize " + cid);
7991                     PackageHelper.destroySdDir(cid);
7992                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
7993                 }
7994
7995                 boolean mounted = PackageHelper.isContainerMounted(cid);
7996                 if (!mounted) {
7997                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
7998                 }
7999             }
8000             return status;
8001         }
8002
8003         private void cleanUp() {
8004             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
8005
8006             // Destroy secure container
8007             PackageHelper.destroySdDir(cid);
8008         }
8009
8010         void cleanUpResourcesLI() {
8011             String sourceFile = getCodePath();
8012             // Remove dex file
8013             int retCode = mInstaller.rmdex(sourceFile);
8014             if (retCode < 0) {
8015                 Slog.w(TAG, "Couldn't remove dex file for package: "
8016                         + " at location "
8017                         + sourceFile.toString() + ", retcode=" + retCode);
8018                 // we don't consider this to be a failure of the core package deletion
8019             }
8020             cleanUp();
8021         }
8022
8023         boolean matchContainer(String app) {
8024             if (cid.startsWith(app)) {
8025                 return true;
8026             }
8027             return false;
8028         }
8029
8030         String getPackageName() {
8031             return getAsecPackageName(cid);
8032         }
8033
8034         boolean doPostDeleteLI(boolean delete) {
8035             boolean ret = false;
8036             boolean mounted = PackageHelper.isContainerMounted(cid);
8037             if (mounted) {
8038                 // Unmount first
8039                 ret = PackageHelper.unMountSdDir(cid);
8040             }
8041             if (ret && delete) {
8042                 cleanUpResourcesLI();
8043             }
8044             return ret;
8045         }
8046
8047         @Override
8048         int doPreCopy() {
8049             if (isFwdLocked()) {
8050                 if (!PackageHelper.fixSdPermissions(cid,
8051                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
8052                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8053                 }
8054             }
8055
8056             return PackageManager.INSTALL_SUCCEEDED;
8057         }
8058
8059         @Override
8060         int doPostCopy(int uid) {
8061             if (isFwdLocked()) {
8062                 if (uid < Process.FIRST_APPLICATION_UID
8063                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
8064                                 RES_FILE_NAME)) {
8065                     Slog.e(TAG, "Failed to finalize " + cid);
8066                     PackageHelper.destroySdDir(cid);
8067                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8068                 }
8069             }
8070
8071             return PackageManager.INSTALL_SUCCEEDED;
8072         }
8073     };
8074
8075     static String getAsecPackageName(String packageCid) {
8076         int idx = packageCid.lastIndexOf("-");
8077         if (idx == -1) {
8078             return packageCid;
8079         }
8080         return packageCid.substring(0, idx);
8081     }
8082
8083     // Utility method used to create code paths based on package name and available index.
8084     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
8085         String idxStr = "";
8086         int idx = 1;
8087         // Fall back to default value of idx=1 if prefix is not
8088         // part of oldCodePath
8089         if (oldCodePath != null) {
8090             String subStr = oldCodePath;
8091             // Drop the suffix right away
8092             if (subStr.endsWith(suffix)) {
8093                 subStr = subStr.substring(0, subStr.length() - suffix.length());
8094             }
8095             // If oldCodePath already contains prefix find out the
8096             // ending index to either increment or decrement.
8097             int sidx = subStr.lastIndexOf(prefix);
8098             if (sidx != -1) {
8099                 subStr = subStr.substring(sidx + prefix.length());
8100                 if (subStr != null) {
8101                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
8102                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
8103                     }
8104                     try {
8105                         idx = Integer.parseInt(subStr);
8106                         if (idx <= 1) {
8107                             idx++;
8108                         } else {
8109                             idx--;
8110                         }
8111                     } catch(NumberFormatException e) {
8112                     }
8113                 }
8114             }
8115         }
8116         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
8117         return prefix + idxStr;
8118     }
8119
8120     // Utility method used to ignore ADD/REMOVE events
8121     // by directory observer.
8122     private static boolean ignoreCodePath(String fullPathStr) {
8123         String apkName = getApkName(fullPathStr);
8124         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
8125         if (idx != -1 && ((idx+1) < apkName.length())) {
8126             // Make sure the package ends with a numeral
8127             String version = apkName.substring(idx+1);
8128             try {
8129                 Integer.parseInt(version);
8130                 return true;
8131             } catch (NumberFormatException e) {}
8132         }
8133         return false;
8134     }
8135     
8136     // Utility method that returns the relative package path with respect
8137     // to the installation directory. Like say for /data/data/com.test-1.apk
8138     // string com.test-1 is returned.
8139     static String getApkName(String codePath) {
8140         if (codePath == null) {
8141             return null;
8142         }
8143         int sidx = codePath.lastIndexOf("/");
8144         int eidx = codePath.lastIndexOf(".");
8145         if (eidx == -1) {
8146             eidx = codePath.length();
8147         } else if (eidx == 0) {
8148             Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name");
8149             return null;
8150         }
8151         return codePath.substring(sidx+1, eidx);
8152     }
8153
8154     class PackageInstalledInfo {
8155         String name;
8156         int uid;
8157         // The set of users that originally had this package installed.
8158         int[] origUsers;
8159         // The set of users that now have this package installed.
8160         int[] newUsers;
8161         PackageParser.Package pkg;
8162         int returnCode;
8163         PackageRemovedInfo removedInfo;
8164     }
8165
8166     /*
8167      * Install a non-existing package.
8168      */
8169     private void installNewPackageLI(PackageParser.Package pkg,
8170             int parseFlags, int scanMode, UserHandle user,
8171             String installerPackageName, PackageInstalledInfo res) {
8172         // Remember this for later, in case we need to rollback this install
8173         String pkgName = pkg.packageName;
8174
8175         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
8176         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
8177         synchronized(mPackages) {
8178             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
8179                 // A package with the same name is already installed, though
8180                 // it has been renamed to an older name.  The package we
8181                 // are trying to install should be installed as an update to
8182                 // the existing one, but that has not been requested, so bail.
8183                 Slog.w(TAG, "Attempt to re-install " + pkgName
8184                         + " without first uninstalling package running as "
8185                         + mSettings.mRenamedPackages.get(pkgName));
8186                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8187                 return;
8188             }
8189             if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) {
8190                 // Don't allow installation over an existing package with the same name.
8191                 Slog.w(TAG, "Attempt to re-install " + pkgName
8192                         + " without first uninstalling.");
8193                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
8194                 return;
8195             }
8196         }
8197         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8198         PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
8199                 System.currentTimeMillis(), user);
8200         if (newPackage == null) {
8201             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8202             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8203                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8204             }
8205         } else {
8206             updateSettingsLI(newPackage,
8207                     installerPackageName,
8208                     null, null,
8209                     res);
8210             // delete the partially installed application. the data directory will have to be
8211             // restored if it was already existing
8212             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8213                 // remove package from internal structures.  Note that we want deletePackageX to
8214                 // delete the package data and cache directories that it created in
8215                 // scanPackageLocked, unless those directories existed before we even tried to
8216                 // install.
8217                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
8218                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
8219                                 res.removedInfo, true);
8220             }
8221         }
8222     }
8223
8224     private void replacePackageLI(PackageParser.Package pkg,
8225             int parseFlags, int scanMode, UserHandle user,
8226             String installerPackageName, PackageInstalledInfo res) {
8227
8228         PackageParser.Package oldPackage;
8229         String pkgName = pkg.packageName;
8230         int[] allUsers;
8231         boolean[] perUserInstalled;
8232
8233         // First find the old package info and check signatures
8234         synchronized(mPackages) {
8235             oldPackage = mPackages.get(pkgName);
8236             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
8237             if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
8238                     != PackageManager.SIGNATURE_MATCH) {
8239                 Slog.w(TAG, "New package has a different signature: " + pkgName);
8240                 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
8241                 return;
8242             }
8243
8244             // In case of rollback, remember per-user/profile install state
8245             PackageSetting ps = mSettings.mPackages.get(pkgName);
8246             allUsers = sUserManager.getUserIds();
8247             perUserInstalled = new boolean[allUsers.length];
8248             for (int i = 0; i < allUsers.length; i++) {
8249                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
8250             }
8251         }
8252         boolean sysPkg = (isSystemApp(oldPackage));
8253         if (sysPkg) {
8254             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
8255                     user, allUsers, perUserInstalled, installerPackageName, res);
8256         } else {
8257             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
8258                     user, allUsers, perUserInstalled, installerPackageName, res);
8259         }
8260     }
8261
8262     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
8263             PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
8264             int[] allUsers, boolean[] perUserInstalled,
8265             String installerPackageName, PackageInstalledInfo res) {
8266         PackageParser.Package newPackage = null;
8267         String pkgName = deletedPackage.packageName;
8268         boolean deletedPkg = true;
8269         boolean updatedSettings = false;
8270
8271         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
8272                 + deletedPackage);
8273         long origUpdateTime;
8274         if (pkg.mExtras != null) {
8275             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
8276         } else {
8277             origUpdateTime = 0;
8278         }
8279
8280         // First delete the existing package while retaining the data directory
8281         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
8282                 res.removedInfo, true)) {
8283             // If the existing package wasn't successfully deleted
8284             res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
8285             deletedPkg = false;
8286         } else {
8287             // Successfully deleted the old package. Now proceed with re-installation
8288             mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8289             newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
8290                     System.currentTimeMillis(), user);
8291             if (newPackage == null) {
8292                 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8293                 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8294                     res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8295                 }
8296             } else {
8297                 updateSettingsLI(newPackage,
8298                         installerPackageName,
8299                         allUsers, perUserInstalled,
8300                         res);
8301                 updatedSettings = true;
8302             }
8303         }
8304
8305         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8306             // remove package from internal structures.  Note that we want deletePackageX to
8307             // delete the package data and cache directories that it created in
8308             // scanPackageLocked, unless those directories existed before we even tried to
8309             // install.
8310             if(updatedSettings) {
8311                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
8312                 deletePackageLI(
8313                         pkgName, null, true, allUsers, perUserInstalled,
8314                         PackageManager.DELETE_KEEP_DATA,
8315                                 res.removedInfo, true);
8316             }
8317             // Since we failed to install the new package we need to restore the old
8318             // package that we deleted.
8319             if(deletedPkg) {
8320                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
8321                 File restoreFile = new File(deletedPackage.mPath);
8322                 // Parse old package
8323                 boolean oldOnSd = isExternal(deletedPackage);
8324                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
8325                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
8326                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
8327                 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
8328                         | SCAN_UPDATE_TIME;
8329                 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
8330                         origUpdateTime, null) == null) {
8331                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
8332                     return;
8333                 }
8334                 // Restore of old package succeeded. Update permissions.
8335                 // writer
8336                 synchronized (mPackages) {
8337                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
8338                             UPDATE_PERMISSIONS_ALL);
8339                     // can downgrade to reader
8340                     mSettings.writeLPr();
8341                 }
8342                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
8343             }
8344         }
8345     }
8346
8347     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
8348             PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
8349             int[] allUsers, boolean[] perUserInstalled,
8350             String installerPackageName, PackageInstalledInfo res) {
8351         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
8352                 + ", old=" + deletedPackage);
8353         PackageParser.Package newPackage = null;
8354         boolean updatedSettings = false;
8355         parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
8356                 PackageParser.PARSE_IS_SYSTEM;
8357         String packageName = deletedPackage.packageName;
8358         res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
8359         if (packageName == null) {
8360             Slog.w(TAG, "Attempt to delete null packageName.");
8361             return;
8362         }
8363         PackageParser.Package oldPkg;
8364         PackageSetting oldPkgSetting;
8365         // reader
8366         synchronized (mPackages) {
8367             oldPkg = mPackages.get(packageName);
8368             oldPkgSetting = mSettings.mPackages.get(packageName);
8369             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
8370                     (oldPkgSetting == null)) {
8371                 Slog.w(TAG, "Couldn't find package:"+packageName+" information");
8372                 return;
8373             }
8374         }
8375
8376         killApplication(packageName, oldPkg.applicationInfo.uid);
8377
8378         res.removedInfo.uid = oldPkg.applicationInfo.uid;
8379         res.removedInfo.removedPackage = packageName;
8380         // Remove existing system package
8381         removePackageLI(oldPkgSetting, true);
8382         // writer
8383         synchronized (mPackages) {
8384             if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
8385                 // We didn't need to disable the .apk as a current system package,
8386                 // which means we are replacing another update that is already
8387                 // installed.  We need to make sure to delete the older one's .apk.
8388                 res.removedInfo.args = createInstallArgs(0,
8389                         deletedPackage.applicationInfo.sourceDir,
8390                         deletedPackage.applicationInfo.publicSourceDir,
8391                         deletedPackage.applicationInfo.nativeLibraryDir);
8392             } else {
8393                 res.removedInfo.args = null;
8394             }
8395         }
8396         
8397         // Successfully disabled the old package. Now proceed with re-installation
8398         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
8399         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
8400         newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user);
8401         if (newPackage == null) {
8402             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
8403             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
8404                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
8405             }
8406         } else {
8407             if (newPackage.mExtras != null) {
8408                 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;
8409                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
8410                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
8411             }
8412             updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
8413             updatedSettings = true;
8414         }
8415
8416         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
8417             // Re installation failed. Restore old information
8418             // Remove new pkg information
8419             if (newPackage != null) {
8420                 removeInstalledPackageLI(newPackage, true);
8421             }
8422             // Add back the old system package
8423             scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
8424             // Restore the old system information in Settings
8425             synchronized(mPackages) {
8426                 if (updatedSettings) {
8427                     mSettings.enableSystemPackageLPw(packageName);
8428                     mSettings.setInstallerPackageName(packageName,
8429                             oldPkgSetting.installerPackageName);
8430                 }
8431                 mSettings.writeLPr();
8432             }
8433         }
8434     }
8435
8436     // Utility method used to move dex files during install.
8437     private int moveDexFilesLI(PackageParser.Package newPackage) {
8438         int retCode;
8439         if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
8440             retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
8441             if (retCode != 0) {
8442                 if (mNoDexOpt) {
8443                     /*
8444                      * If we're in an engineering build, programs are lazily run
8445                      * through dexopt. If the .dex file doesn't exist yet, it
8446                      * will be created when the program is run next.
8447                      */
8448                     Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath);
8449                 } else {
8450                     Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath);
8451                     return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8452                 }
8453             }
8454         }
8455         return PackageManager.INSTALL_SUCCEEDED;
8456     }
8457
8458     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
8459             int[] allUsers, boolean[] perUserInstalled,
8460             PackageInstalledInfo res) {
8461         String pkgName = newPackage.packageName;
8462         synchronized (mPackages) {
8463             //write settings. the installStatus will be incomplete at this stage.
8464             //note that the new package setting would have already been
8465             //added to mPackages. It hasn't been persisted yet.
8466             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
8467             mSettings.writeLPr();
8468         }
8469
8470         if ((res.returnCode = moveDexFilesLI(newPackage))
8471                 != PackageManager.INSTALL_SUCCEEDED) {
8472             // Discontinue if moving dex files failed.
8473             return;
8474         }
8475
8476         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.mPath);
8477
8478         synchronized (mPackages) {
8479             updatePermissionsLPw(newPackage.packageName, newPackage,
8480                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
8481                             ? UPDATE_PERMISSIONS_ALL : 0));
8482             // For system-bundled packages, we assume that installing an upgraded version
8483             // of the package implies that the user actually wants to run that new code,
8484             // so we enable the package.
8485             if (isSystemApp(newPackage)) {
8486                 // NB: implicit assumption that system package upgrades apply to all users
8487                 if (DEBUG_INSTALL) {
8488                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
8489                 }
8490                 PackageSetting ps = mSettings.mPackages.get(pkgName);
8491                 if (ps != null) {
8492                     if (res.origUsers != null) {
8493                         for (int userHandle : res.origUsers) {
8494                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
8495                                     userHandle, installerPackageName);
8496                         }
8497                     }
8498                     // Also convey the prior install/uninstall state
8499                     if (allUsers != null && perUserInstalled != null) {
8500                         for (int i = 0; i < allUsers.length; i++) {
8501                             if (DEBUG_INSTALL) {
8502                                 Slog.d(TAG, "    user " + allUsers[i]
8503                                         + " => " + perUserInstalled[i]);
8504                             }
8505                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
8506                         }
8507                         // these install state changes will be persisted in the
8508                         // upcoming call to mSettings.writeLPr().
8509                     }
8510                 }
8511             }
8512             res.name = pkgName;
8513             res.uid = newPackage.applicationInfo.uid;
8514             res.pkg = newPackage;
8515             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
8516             mSettings.setInstallerPackageName(pkgName, installerPackageName);
8517             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
8518             //to update install status
8519             mSettings.writeLPr();
8520         }
8521     }
8522
8523     private void installPackageLI(InstallArgs args,
8524             boolean newInstall, PackageInstalledInfo res) {
8525         int pFlags = args.flags;
8526         String installerPackageName = args.installerPackageName;
8527         File tmpPackageFile = new File(args.getCodePath());
8528         boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
8529         boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
8530         boolean replace = false;
8531         int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
8532                 | (newInstall ? SCAN_NEW_INSTALL : 0);
8533         // Result object to be returned
8534         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
8535
8536         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
8537         // Retrieve PackageSettings and parse package
8538         int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
8539                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
8540                 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
8541         PackageParser pp = new PackageParser(tmpPackageFile.getPath());
8542         pp.setSeparateProcesses(mSeparateProcesses);
8543         final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
8544                 null, mMetrics, parseFlags);
8545         if (pkg == null) {
8546             res.returnCode = pp.getParseError();
8547             return;
8548         }
8549         String pkgName = res.name = pkg.packageName;
8550         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
8551             if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
8552                 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
8553                 return;
8554             }
8555         }
8556         if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
8557             res.returnCode = pp.getParseError();
8558             return;
8559         }
8560
8561         /* If the installer passed in a manifest digest, compare it now. */
8562         if (args.manifestDigest != null) {
8563             if (DEBUG_INSTALL) {
8564                 final String parsedManifest = pkg.manifestDigest == null ? "null"
8565                         : pkg.manifestDigest.toString();
8566                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
8567                         + parsedManifest);
8568             }
8569
8570             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
8571                 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
8572                 return;
8573             }
8574         } else if (DEBUG_INSTALL) {
8575             final String parsedManifest = pkg.manifestDigest == null
8576                     ? "null" : pkg.manifestDigest.toString();
8577             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
8578         }
8579
8580         // Get rid of all references to package scan path via parser.
8581         pp = null;
8582         String oldCodePath = null;
8583         boolean systemApp = false;
8584         synchronized (mPackages) {
8585             // Check if installing already existing package
8586             if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
8587                 String oldName = mSettings.mRenamedPackages.get(pkgName);
8588                 if (pkg.mOriginalPackages != null
8589                         && pkg.mOriginalPackages.contains(oldName)
8590                         && mPackages.containsKey(oldName)) {
8591                     // This package is derived from an original package,
8592                     // and this device has been updating from that original
8593                     // name.  We must continue using the original name, so
8594                     // rename the new package here.
8595                     pkg.setPackageName(oldName);
8596                     pkgName = pkg.packageName;
8597                     replace = true;
8598                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
8599                             + oldName + " pkgName=" + pkgName);
8600                 } else if (mPackages.containsKey(pkgName)) {
8601                     // This package, under its official name, already exists
8602                     // on the device; we should replace it.
8603                     replace = true;
8604                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
8605                 }
8606             }
8607             PackageSetting ps = mSettings.mPackages.get(pkgName);
8608             if (ps != null) {
8609                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
8610                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
8611                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
8612                     systemApp = (ps.pkg.applicationInfo.flags &
8613                             ApplicationInfo.FLAG_SYSTEM) != 0;
8614                 }
8615                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
8616             }
8617         }
8618
8619         if (systemApp && onSd) {
8620             // Disable updates to system apps on sdcard
8621             Slog.w(TAG, "Cannot install updates to system apps on sdcard");
8622             res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
8623             return;
8624         }
8625
8626         if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
8627             res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
8628             return;
8629         }
8630         // Set application objects path explicitly after the rename
8631         setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
8632         pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
8633         if (replace) {
8634             replacePackageLI(pkg, parseFlags, scanMode, args.user,
8635                     installerPackageName, res);
8636         } else {
8637             installNewPackageLI(pkg, parseFlags, scanMode, args.user,
8638                     installerPackageName, res);
8639         }
8640         synchronized (mPackages) {
8641             final PackageSetting ps = mSettings.mPackages.get(pkgName);
8642             if (ps != null) {
8643                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
8644             }
8645         }
8646     }
8647
8648     private static boolean isForwardLocked(PackageParser.Package pkg) {
8649         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
8650     }
8651
8652
8653     private boolean isForwardLocked(PackageSetting ps) {
8654         return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
8655     }
8656
8657     private static boolean isExternal(PackageParser.Package pkg) {
8658         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
8659     }
8660
8661     private static boolean isExternal(PackageSetting ps) {
8662         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
8663     }
8664
8665     private static boolean isSystemApp(PackageParser.Package pkg) {
8666         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8667     }
8668
8669     private static boolean isSystemApp(ApplicationInfo info) {
8670         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8671     }
8672
8673     private static boolean isSystemApp(PackageSetting ps) {
8674         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
8675     }
8676
8677     private static boolean isUpdatedSystemApp(PackageSetting ps) {
8678         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
8679     }
8680
8681     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
8682         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
8683     }
8684
8685     private int packageFlagsToInstallFlags(PackageSetting ps) {
8686         int installFlags = 0;
8687         if (isExternal(ps)) {
8688             installFlags |= PackageManager.INSTALL_EXTERNAL;
8689         }
8690         if (isForwardLocked(ps)) {
8691             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
8692         }
8693         return installFlags;
8694     }
8695
8696     private void deleteTempPackageFiles() {
8697         final FilenameFilter filter = new FilenameFilter() {
8698             public boolean accept(File dir, String name) {
8699                 return name.startsWith("vmdl") && name.endsWith(".tmp");
8700             }
8701         };
8702         deleteTempPackageFilesInDirectory(mAppInstallDir, filter);
8703         deleteTempPackageFilesInDirectory(mDrmAppPrivateInstallDir, filter);
8704     }
8705
8706     private static final void deleteTempPackageFilesInDirectory(File directory,
8707             FilenameFilter filter) {
8708         final String[] tmpFilesList = directory.list(filter);
8709         if (tmpFilesList == null) {
8710             return;
8711         }
8712         for (int i = 0; i < tmpFilesList.length; i++) {
8713             final File tmpFile = new File(directory, tmpFilesList[i]);
8714             tmpFile.delete();
8715         }
8716     }
8717
8718     private File createTempPackageFile(File installDir) {
8719         File tmpPackageFile;
8720         try {
8721             tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir);
8722         } catch (IOException e) {
8723             Slog.e(TAG, "Couldn't create temp file for downloaded package file.");
8724             return null;
8725         }
8726         try {
8727             FileUtils.setPermissions(
8728                     tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
8729                     -1, -1);
8730             if (!SELinux.restorecon(tmpPackageFile)) {
8731                 return null;
8732             }
8733         } catch (IOException e) {
8734             Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
8735             return null;
8736         }
8737         return tmpPackageFile;
8738     }
8739
8740     @Override
8741     public void deletePackageAsUser(final String packageName,
8742                                     final IPackageDeleteObserver observer,
8743                                     final int userId, final int flags) {
8744         mContext.enforceCallingOrSelfPermission(
8745                 android.Manifest.permission.DELETE_PACKAGES, null);
8746         final int uid = Binder.getCallingUid();
8747         if (UserHandle.getUserId(uid) != userId) {
8748             mContext.enforceCallingPermission(
8749                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8750                     "deletePackage for user " + userId);
8751         }
8752         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
8753             try {
8754                 observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED);
8755             } catch (RemoteException re) {
8756             }
8757             return;
8758         }
8759
8760         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
8761         // Queue up an async operation since the package deletion may take a little while.
8762         mHandler.post(new Runnable() {
8763             public void run() {
8764                 mHandler.removeCallbacks(this);
8765                 final int returnCode = deletePackageX(packageName, userId, flags);
8766                 if (observer != null) {
8767                     try {
8768                         observer.packageDeleted(packageName, returnCode);
8769                     } catch (RemoteException e) {
8770                         Log.i(TAG, "Observer no longer exists.");
8771                     } //end catch
8772                 } //end if
8773             } //end run
8774         });
8775     }
8776
8777     /**
8778      *  This method is an internal method that could be get invoked either
8779      *  to delete an installed package or to clean up a failed installation.
8780      *  After deleting an installed package, a broadcast is sent to notify any
8781      *  listeners that the package has been installed. For cleaning up a failed
8782      *  installation, the broadcast is not necessary since the package's
8783      *  installation wouldn't have sent the initial broadcast either
8784      *  The key steps in deleting a package are
8785      *  deleting the package information in internal structures like mPackages,
8786      *  deleting the packages base directories through installd
8787      *  updating mSettings to reflect current status
8788      *  persisting settings for later use
8789      *  sending a broadcast if necessary
8790      */
8791     private int deletePackageX(String packageName, int userId, int flags) {
8792         final PackageRemovedInfo info = new PackageRemovedInfo();
8793         final boolean res;
8794
8795         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
8796                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
8797         try {
8798             if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId)
8799                     || dpm.isDeviceOwner(packageName))) {
8800                 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
8801                 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
8802             }
8803         } catch (RemoteException e) {
8804         }
8805
8806         boolean removedForAllUsers = false;
8807         boolean systemUpdate = false;
8808
8809         // for the uninstall-updates case and restricted profiles, remember the per-
8810         // userhandle installed state
8811         int[] allUsers;
8812         boolean[] perUserInstalled;
8813         synchronized (mPackages) {
8814             PackageSetting ps = mSettings.mPackages.get(packageName);
8815             allUsers = sUserManager.getUserIds();
8816             perUserInstalled = new boolean[allUsers.length];
8817             for (int i = 0; i < allUsers.length; i++) {
8818                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
8819             }
8820         }
8821
8822         synchronized (mInstallLock) {
8823             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
8824             res = deletePackageLI(packageName,
8825                     (flags & PackageManager.DELETE_ALL_USERS) != 0
8826                             ? UserHandle.ALL : new UserHandle(userId),
8827                     true, allUsers, perUserInstalled,
8828                     flags | REMOVE_CHATTY, info, true);
8829             systemUpdate = info.isRemovedPackageSystemUpdate;
8830             if (res && !systemUpdate && mPackages.get(packageName) == null) {
8831                 removedForAllUsers = true;
8832             }
8833             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
8834                     + " removedForAllUsers=" + removedForAllUsers);
8835         }
8836
8837         if (res) {
8838             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
8839
8840             // If the removed package was a system update, the old system package
8841             // was re-enabled; we need to broadcast this information
8842             if (systemUpdate) {
8843                 Bundle extras = new Bundle(1);
8844                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
8845                         ? info.removedAppId : info.uid);
8846                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
8847
8848                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
8849                         extras, null, null, null);
8850                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
8851                         extras, null, null, null);
8852                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
8853                         null, packageName, null, null);
8854             }
8855         }
8856         // Force a gc here.
8857         Runtime.getRuntime().gc();
8858         // Delete the resources here after sending the broadcast to let
8859         // other processes clean up before deleting resources.
8860         if (info.args != null) {
8861             synchronized (mInstallLock) {
8862                 info.args.doPostDeleteLI(true);
8863             }
8864         }
8865
8866         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
8867     }
8868
8869     static class PackageRemovedInfo {
8870         String removedPackage;
8871         int uid = -1;
8872         int removedAppId = -1;
8873         int[] removedUsers = null;
8874         boolean isRemovedPackageSystemUpdate = false;
8875         // Clean up resources deleted packages.
8876         InstallArgs args = null;
8877
8878         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
8879             Bundle extras = new Bundle(1);
8880             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
8881             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
8882             if (replacing) {
8883                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
8884             }
8885             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
8886             if (removedPackage != null) {
8887                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
8888                         extras, null, null, removedUsers);
8889                 if (fullRemove && !replacing) {
8890                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
8891                             extras, null, null, removedUsers);
8892                 }
8893             }
8894             if (removedAppId >= 0) {
8895                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
8896                         removedUsers);
8897             }
8898         }
8899     }
8900
8901     /*
8902      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
8903      * flag is not set, the data directory is removed as well.
8904      * make sure this flag is set for partially installed apps. If not its meaningless to
8905      * delete a partially installed application.
8906      */
8907     private void removePackageDataLI(PackageSetting ps,
8908             int[] allUserHandles, boolean[] perUserInstalled,
8909             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
8910         String packageName = ps.name;
8911         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
8912         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
8913         // Retrieve object to delete permissions for shared user later on
8914         final PackageSetting deletedPs;
8915         // reader
8916         synchronized (mPackages) {
8917             deletedPs = mSettings.mPackages.get(packageName);
8918             if (outInfo != null) {
8919                 outInfo.removedPackage = packageName;
8920                 outInfo.removedUsers = deletedPs != null
8921                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
8922                         : null;
8923             }
8924         }
8925         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
8926             removeDataDirsLI(packageName);
8927             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
8928         }
8929         // writer
8930         synchronized (mPackages) {
8931             if (deletedPs != null) {
8932                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
8933                     if (outInfo != null) {
8934                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
8935                     }
8936                     if (deletedPs != null) {
8937                         updatePermissionsLPw(deletedPs.name, null, 0);
8938                         if (deletedPs.sharedUser != null) {
8939                             // remove permissions associated with package
8940                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
8941                         }
8942                     }
8943                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
8944                 }
8945                 // make sure to preserve per-user disabled state if this removal was just
8946                 // a downgrade of a system app to the factory package
8947                 if (allUserHandles != null && perUserInstalled != null) {
8948                     if (DEBUG_REMOVE) {
8949                         Slog.d(TAG, "Propagating install state across downgrade");
8950                     }
8951                     for (int i = 0; i < allUserHandles.length; i++) {
8952                         if (DEBUG_REMOVE) {
8953                             Slog.d(TAG, "    user " + allUserHandles[i]
8954                                     + " => " + perUserInstalled[i]);
8955                         }
8956                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
8957                     }
8958                 }
8959             }
8960             // can downgrade to reader
8961             if (writeSettings) {
8962                 // Save settings now
8963                 mSettings.writeLPr();
8964             }
8965         }
8966         if (outInfo != null) {
8967             // A user ID was deleted here. Go through all users and remove it
8968             // from KeyStore.
8969             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
8970         }
8971     }
8972
8973     /*
8974      * Tries to delete system package.
8975      */
8976     private boolean deleteSystemPackageLI(PackageSetting newPs,
8977             int[] allUserHandles, boolean[] perUserInstalled,
8978             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
8979         final boolean applyUserRestrictions
8980                 = (allUserHandles != null) && (perUserInstalled != null);
8981         PackageSetting disabledPs = null;
8982         // Confirm if the system package has been updated
8983         // An updated system app can be deleted. This will also have to restore
8984         // the system pkg from system partition
8985         // reader
8986         synchronized (mPackages) {
8987             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
8988         }
8989         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
8990                 + " disabledPs=" + disabledPs);
8991         if (disabledPs == null) {
8992             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
8993             return false;
8994         } else if (DEBUG_REMOVE) {
8995             Slog.d(TAG, "Deleting system pkg from data partition");
8996         }
8997         if (DEBUG_REMOVE) {
8998             if (applyUserRestrictions) {
8999                 Slog.d(TAG, "Remembering install states:");
9000                 for (int i = 0; i < allUserHandles.length; i++) {
9001                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
9002                 }
9003             }
9004         }
9005         // Delete the updated package
9006         outInfo.isRemovedPackageSystemUpdate = true;
9007         if (disabledPs.versionCode < newPs.versionCode) {
9008             // Delete data for downgrades
9009             flags &= ~PackageManager.DELETE_KEEP_DATA;
9010         } else {
9011             // Preserve data by setting flag
9012             flags |= PackageManager.DELETE_KEEP_DATA;
9013         }
9014         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
9015                 allUserHandles, perUserInstalled, outInfo, writeSettings);
9016         if (!ret) {
9017             return false;
9018         }
9019         // writer
9020         synchronized (mPackages) {
9021             // Reinstate the old system package
9022             mSettings.enableSystemPackageLPw(newPs.name);
9023             // Remove any native libraries from the upgraded package.
9024             NativeLibraryHelper.removeNativeBinariesLI(newPs.nativeLibraryPathString);
9025         }
9026         // Install the system package
9027         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
9028         PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath,
9029                 PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM,
9030                 SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
9031
9032         if (newPkg == null) {
9033             Slog.w(TAG, "Failed to restore system package:" + newPs.name
9034                     + " with error:" + mLastScanError);
9035             return false;
9036         }
9037         // writer
9038         synchronized (mPackages) {
9039             updatePermissionsLPw(newPkg.packageName, newPkg,
9040                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
9041             if (applyUserRestrictions) {
9042                 if (DEBUG_REMOVE) {
9043                     Slog.d(TAG, "Propagating install state across reinstall");
9044                 }
9045                 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
9046                 for (int i = 0; i < allUserHandles.length; i++) {
9047                     if (DEBUG_REMOVE) {
9048                         Slog.d(TAG, "    user " + allUserHandles[i]
9049                                 + " => " + perUserInstalled[i]);
9050                     }
9051                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
9052                 }
9053                 // Regardless of writeSettings we need to ensure that this restriction
9054                 // state propagation is persisted
9055                 mSettings.writeAllUsersPackageRestrictionsLPr();
9056             }
9057             // can downgrade to reader here
9058             if (writeSettings) {
9059                 mSettings.writeLPr();
9060             }
9061         }
9062         return true;
9063     }
9064
9065     private boolean deleteInstalledPackageLI(PackageSetting ps,
9066             boolean deleteCodeAndResources, int flags,
9067             int[] allUserHandles, boolean[] perUserInstalled,
9068             PackageRemovedInfo outInfo, boolean writeSettings) {
9069         if (outInfo != null) {
9070             outInfo.uid = ps.appId;
9071         }
9072
9073         // Delete package data from internal structures and also remove data if flag is set
9074         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
9075
9076         // Delete application code and resources
9077         if (deleteCodeAndResources && (outInfo != null)) {
9078             outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString,
9079                     ps.resourcePathString, ps.nativeLibraryPathString);
9080         }
9081         return true;
9082     }
9083
9084     /*
9085      * This method handles package deletion in general
9086      */
9087     private boolean deletePackageLI(String packageName, UserHandle user,
9088             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
9089             int flags, PackageRemovedInfo outInfo,
9090             boolean writeSettings) {
9091         if (packageName == null) {
9092             Slog.w(TAG, "Attempt to delete null packageName.");
9093             return false;
9094         }
9095         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
9096         PackageSetting ps;
9097         boolean dataOnly = false;
9098         int removeUser = -1;
9099         int appId = -1;
9100         synchronized (mPackages) {
9101             ps = mSettings.mPackages.get(packageName);
9102             if (ps == null) {
9103                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9104                 return false;
9105             }
9106             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
9107                     && user.getIdentifier() != UserHandle.USER_ALL) {
9108                 // The caller is asking that the package only be deleted for a single
9109                 // user.  To do this, we just mark its uninstalled state and delete
9110                 // its data.  If this is a system app, we only allow this to happen if
9111                 // they have set the special DELETE_SYSTEM_APP which requests different
9112                 // semantics than normal for uninstalling system apps.
9113                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
9114                 ps.setUserState(user.getIdentifier(),
9115                         COMPONENT_ENABLED_STATE_DEFAULT,
9116                         false, //installed
9117                         true,  //stopped
9118                         true,  //notLaunched
9119                         null, null, null);
9120                 if (!isSystemApp(ps)) {
9121                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
9122                         // Other user still have this package installed, so all
9123                         // we need to do is clear this user's data and save that
9124                         // it is uninstalled.
9125                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
9126                         removeUser = user.getIdentifier();
9127                         appId = ps.appId;
9128                         mSettings.writePackageRestrictionsLPr(removeUser);
9129                     } else {
9130                         // We need to set it back to 'installed' so the uninstall
9131                         // broadcasts will be sent correctly.
9132                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
9133                         ps.setInstalled(true, user.getIdentifier());
9134                     }
9135                 } else {
9136                     // This is a system app, so we assume that the
9137                     // other users still have this package installed, so all
9138                     // we need to do is clear this user's data and save that
9139                     // it is uninstalled.
9140                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
9141                     removeUser = user.getIdentifier();
9142                     appId = ps.appId;
9143                     mSettings.writePackageRestrictionsLPr(removeUser);
9144                 }
9145             }
9146         }
9147
9148         if (removeUser >= 0) {
9149             // From above, we determined that we are deleting this only
9150             // for a single user.  Continue the work here.
9151             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
9152             if (outInfo != null) {
9153                 outInfo.removedPackage = packageName;
9154                 outInfo.removedAppId = appId;
9155                 outInfo.removedUsers = new int[] {removeUser};
9156             }
9157             mInstaller.clearUserData(packageName, removeUser);
9158             removeKeystoreDataIfNeeded(removeUser, appId);
9159             schedulePackageCleaning(packageName, removeUser, false);
9160             return true;
9161         }
9162
9163         if (dataOnly) {
9164             // Delete application data first
9165             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
9166             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
9167             return true;
9168         }
9169         boolean ret = false;
9170         if (isSystemApp(ps)) {
9171             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
9172             // When an updated system application is deleted we delete the existing resources as well and
9173             // fall back to existing code in system partition
9174             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
9175                     flags, outInfo, writeSettings);
9176         } else {
9177             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
9178             // Kill application pre-emptively especially for apps on sd.
9179             killApplication(packageName, ps.appId);
9180             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
9181                     allUserHandles, perUserInstalled,
9182                     outInfo, writeSettings);
9183         }
9184         return ret;
9185     }
9186
9187     private final class ClearStorageConnection implements ServiceConnection {
9188         IMediaContainerService mContainerService;
9189
9190         @Override
9191         public void onServiceConnected(ComponentName name, IBinder service) {
9192             synchronized (this) {
9193                 mContainerService = IMediaContainerService.Stub.asInterface(service);
9194                 notifyAll();
9195             }
9196         }
9197
9198         @Override
9199         public void onServiceDisconnected(ComponentName name) {
9200         }
9201     }
9202
9203     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
9204         final boolean mounted;
9205         if (Environment.isExternalStorageEmulated()) {
9206             mounted = true;
9207         } else {
9208             final String status = Environment.getExternalStorageState();
9209
9210             mounted = status.equals(Environment.MEDIA_MOUNTED)
9211                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
9212         }
9213
9214         if (!mounted) {
9215             return;
9216         }
9217
9218         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
9219         int[] users;
9220         if (userId == UserHandle.USER_ALL) {
9221             users = sUserManager.getUserIds();
9222         } else {
9223             users = new int[] { userId };
9224         }
9225         final ClearStorageConnection conn = new ClearStorageConnection();
9226         if (mContext.bindServiceAsUser(
9227                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
9228             try {
9229                 for (int curUser : users) {
9230                     long timeout = SystemClock.uptimeMillis() + 5000;
9231                     synchronized (conn) {
9232                         long now = SystemClock.uptimeMillis();
9233                         while (conn.mContainerService == null && now < timeout) {
9234                             try {
9235                                 conn.wait(timeout - now);
9236                             } catch (InterruptedException e) {
9237                             }
9238                         }
9239                     }
9240                     if (conn.mContainerService == null) {
9241                         return;
9242                     }
9243
9244                     final UserEnvironment userEnv = new UserEnvironment(curUser);
9245                     final File externalCacheDir = userEnv
9246                             .getExternalStorageAppCacheDirectory(packageName);
9247                     try {
9248                         conn.mContainerService.clearDirectory(externalCacheDir.toString());
9249                     } catch (RemoteException e) {
9250                     }
9251                     if (allData) {
9252                         final File externalDataDir = userEnv
9253                                 .getExternalStorageAppDataDirectory(packageName);
9254                         try {
9255                             conn.mContainerService.clearDirectory(externalDataDir.toString());
9256                         } catch (RemoteException e) {
9257                         }
9258                         final File externalMediaDir = userEnv
9259                                 .getExternalStorageAppMediaDirectory(packageName);
9260                         try {
9261                             conn.mContainerService.clearDirectory(externalMediaDir.toString());
9262                         } catch (RemoteException e) {
9263                         }
9264                     }
9265                 }
9266             } finally {
9267                 mContext.unbindService(conn);
9268             }
9269         }
9270     }
9271
9272     @Override
9273     public void clearApplicationUserData(final String packageName,
9274             final IPackageDataObserver observer, final int userId) {
9275         mContext.enforceCallingOrSelfPermission(
9276                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
9277         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data");
9278         // Queue up an async operation since the package deletion may take a little while.
9279         mHandler.post(new Runnable() {
9280             public void run() {
9281                 mHandler.removeCallbacks(this);
9282                 final boolean succeeded;
9283                 synchronized (mInstallLock) {
9284                     succeeded = clearApplicationUserDataLI(packageName, userId);
9285                 }
9286                 clearExternalStorageDataSync(packageName, userId, true);
9287                 if (succeeded) {
9288                     // invoke DeviceStorageMonitor's update method to clear any notifications
9289                     DeviceStorageMonitorService dsm = (DeviceStorageMonitorService)
9290                             ServiceManager.getService(DeviceStorageMonitorService.SERVICE);
9291                     if (dsm != null) {
9292                         dsm.updateMemory();
9293                     }
9294                 }
9295                 if(observer != null) {
9296                     try {
9297                         observer.onRemoveCompleted(packageName, succeeded);
9298                     } catch (RemoteException e) {
9299                         Log.i(TAG, "Observer no longer exists.");
9300                     }
9301                 } //end if observer
9302             } //end run
9303         });
9304     }
9305
9306     private boolean clearApplicationUserDataLI(String packageName, int userId) {
9307         if (packageName == null) {
9308             Slog.w(TAG, "Attempt to delete null packageName.");
9309             return false;
9310         }
9311         PackageParser.Package p;
9312         boolean dataOnly = false;
9313         final int appId;
9314         synchronized (mPackages) {
9315             p = mPackages.get(packageName);
9316             if (p == null) {
9317                 dataOnly = true;
9318                 PackageSetting ps = mSettings.mPackages.get(packageName);
9319                 if ((ps == null) || (ps.pkg == null)) {
9320                     Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9321                     return false;
9322                 }
9323                 p = ps.pkg;
9324             }
9325             if (!dataOnly) {
9326                 // need to check this only for fully installed applications
9327                 if (p == null) {
9328                     Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
9329                     return false;
9330                 }
9331                 final ApplicationInfo applicationInfo = p.applicationInfo;
9332                 if (applicationInfo == null) {
9333                     Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9334                     return false;
9335                 }
9336             }
9337             if (p != null && p.applicationInfo != null) {
9338                 appId = p.applicationInfo.uid;
9339             } else {
9340                 appId = -1;
9341             }
9342         }
9343         int retCode = mInstaller.clearUserData(packageName, userId);
9344         if (retCode < 0) {
9345             Slog.w(TAG, "Couldn't remove cache files for package: "
9346                     + packageName);
9347             return false;
9348         }
9349         removeKeystoreDataIfNeeded(userId, appId);
9350         return true;
9351     }
9352
9353     /**
9354      * Remove entries from the keystore daemon. Will only remove it if the
9355      * {@code appId} is valid.
9356      */
9357     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
9358         if (appId < 0) {
9359             return;
9360         }
9361
9362         final KeyStore keyStore = KeyStore.getInstance();
9363         if (keyStore != null) {
9364             if (userId == UserHandle.USER_ALL) {
9365                 for (final int individual : sUserManager.getUserIds()) {
9366                     keyStore.clearUid(UserHandle.getUid(individual, appId));
9367                 }
9368             } else {
9369                 keyStore.clearUid(UserHandle.getUid(userId, appId));
9370             }
9371         } else {
9372             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
9373         }
9374     }
9375
9376     public void deleteApplicationCacheFiles(final String packageName,
9377             final IPackageDataObserver observer) {
9378         mContext.enforceCallingOrSelfPermission(
9379                 android.Manifest.permission.DELETE_CACHE_FILES, null);
9380         // Queue up an async operation since the package deletion may take a little while.
9381         final int userId = UserHandle.getCallingUserId();
9382         mHandler.post(new Runnable() {
9383             public void run() {
9384                 mHandler.removeCallbacks(this);
9385                 final boolean succeded;
9386                 synchronized (mInstallLock) {
9387                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
9388                 }
9389                 clearExternalStorageDataSync(packageName, userId, false);
9390                 if(observer != null) {
9391                     try {
9392                         observer.onRemoveCompleted(packageName, succeded);
9393                     } catch (RemoteException e) {
9394                         Log.i(TAG, "Observer no longer exists.");
9395                     }
9396                 } //end if observer
9397             } //end run
9398         });
9399     }
9400
9401     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
9402         if (packageName == null) {
9403             Slog.w(TAG, "Attempt to delete null packageName.");
9404             return false;
9405         }
9406         PackageParser.Package p;
9407         synchronized (mPackages) {
9408             p = mPackages.get(packageName);
9409         }
9410         if (p == null) {
9411             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
9412             return false;
9413         }
9414         final ApplicationInfo applicationInfo = p.applicationInfo;
9415         if (applicationInfo == null) {
9416             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9417             return false;
9418         }
9419         int retCode = mInstaller.deleteCacheFiles(packageName, userId);
9420         if (retCode < 0) {
9421             Slog.w(TAG, "Couldn't remove cache files for package: "
9422                        + packageName + " u" + userId);
9423             return false;
9424         }
9425         return true;
9426     }
9427
9428     public void getPackageSizeInfo(final String packageName, int userHandle,
9429             final IPackageStatsObserver observer) {
9430         mContext.enforceCallingOrSelfPermission(
9431                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
9432
9433         PackageStats stats = new PackageStats(packageName, userHandle);
9434
9435         /*
9436          * Queue up an async operation since the package measurement may take a
9437          * little while.
9438          */
9439         Message msg = mHandler.obtainMessage(INIT_COPY);
9440         msg.obj = new MeasureParams(stats, observer);
9441         mHandler.sendMessage(msg);
9442     }
9443
9444     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
9445             PackageStats pStats) {
9446         if (packageName == null) {
9447             Slog.w(TAG, "Attempt to get size of null packageName.");
9448             return false;
9449         }
9450         PackageParser.Package p;
9451         boolean dataOnly = false;
9452         String libDirPath = null;
9453         String asecPath = null;
9454         synchronized (mPackages) {
9455             p = mPackages.get(packageName);
9456             PackageSetting ps = mSettings.mPackages.get(packageName);
9457             if(p == null) {
9458                 dataOnly = true;
9459                 if((ps == null) || (ps.pkg == null)) {
9460                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
9461                     return false;
9462                 }
9463                 p = ps.pkg;
9464             }
9465             if (ps != null) {
9466                 libDirPath = ps.nativeLibraryPathString;
9467             }
9468             if (p != null && (isExternal(p) || isForwardLocked(p))) {
9469                 String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir);
9470                 if (secureContainerId != null) {
9471                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
9472                 }
9473             }
9474         }
9475         String publicSrcDir = null;
9476         if(!dataOnly) {
9477             final ApplicationInfo applicationInfo = p.applicationInfo;
9478             if (applicationInfo == null) {
9479                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
9480                 return false;
9481             }
9482             if (isForwardLocked(p)) {
9483                 publicSrcDir = applicationInfo.publicSourceDir;
9484             }
9485         }
9486         int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath,
9487                 publicSrcDir, asecPath, pStats);
9488         if (res < 0) {
9489             return false;
9490         }
9491
9492         // Fix-up for forward-locked applications in ASEC containers.
9493         if (!isExternal(p)) {
9494             pStats.codeSize += pStats.externalCodeSize;
9495             pStats.externalCodeSize = 0L;
9496         }
9497
9498         return true;
9499     }
9500
9501
9502     public void addPackageToPreferred(String packageName) {
9503         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
9504     }
9505
9506     public void removePackageFromPreferred(String packageName) {
9507         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
9508     }
9509
9510     public List<PackageInfo> getPreferredPackages(int flags) {
9511         return new ArrayList<PackageInfo>();
9512     }
9513
9514     private int getUidTargetSdkVersionLockedLPr(int uid) {
9515         Object obj = mSettings.getUserIdLPr(uid);
9516         if (obj instanceof SharedUserSetting) {
9517             final SharedUserSetting sus = (SharedUserSetting) obj;
9518             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
9519             final Iterator<PackageSetting> it = sus.packages.iterator();
9520             while (it.hasNext()) {
9521                 final PackageSetting ps = it.next();
9522                 if (ps.pkg != null) {
9523                     int v = ps.pkg.applicationInfo.targetSdkVersion;
9524                     if (v < vers) vers = v;
9525                 }
9526             }
9527             return vers;
9528         } else if (obj instanceof PackageSetting) {
9529             final PackageSetting ps = (PackageSetting) obj;
9530             if (ps.pkg != null) {
9531                 return ps.pkg.applicationInfo.targetSdkVersion;
9532             }
9533         }
9534         return Build.VERSION_CODES.CUR_DEVELOPMENT;
9535     }
9536     
9537     public void addPreferredActivity(IntentFilter filter, int match,
9538             ComponentName[] set, ComponentName activity, int userId) {
9539         // writer
9540         int callingUid = Binder.getCallingUid();
9541         enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
9542         synchronized (mPackages) {
9543             if (mContext.checkCallingOrSelfPermission(
9544                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
9545                     != PackageManager.PERMISSION_GRANTED) {
9546                 if (getUidTargetSdkVersionLockedLPr(callingUid)
9547                         < Build.VERSION_CODES.FROYO) {
9548                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
9549                             + callingUid);
9550                     return;
9551                 }
9552                 mContext.enforceCallingOrSelfPermission(
9553                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
9554             }
9555
9556             Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
9557             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
9558             mSettings.editPreferredActivitiesLPw(userId).addFilter(
9559                     new PreferredActivity(filter, match, set, activity));
9560             mSettings.writePackageRestrictionsLPr(userId);
9561         }
9562     }
9563
9564     public void replacePreferredActivity(IntentFilter filter, int match,
9565             ComponentName[] set, ComponentName activity) {
9566         if (filter.countActions() != 1) {
9567             throw new IllegalArgumentException(
9568                     "replacePreferredActivity expects filter to have only 1 action.");
9569         }
9570         if (filter.countCategories() != 1) {
9571             throw new IllegalArgumentException(
9572                     "replacePreferredActivity expects filter to have only 1 category.");
9573         }
9574         if (filter.countDataAuthorities() != 0
9575                 || filter.countDataPaths() != 0
9576                 || filter.countDataSchemes() != 0
9577                 || filter.countDataTypes() != 0) {
9578             throw new IllegalArgumentException(
9579                     "replacePreferredActivity expects filter to have no data authorities, " +
9580                     "paths, schemes or types.");
9581         }
9582         synchronized (mPackages) {
9583             if (mContext.checkCallingOrSelfPermission(
9584                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
9585                     != PackageManager.PERMISSION_GRANTED) {
9586                 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
9587                         < Build.VERSION_CODES.FROYO) {
9588                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
9589                             + Binder.getCallingUid());
9590                     return;
9591                 }
9592                 mContext.enforceCallingOrSelfPermission(
9593                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
9594             }
9595
9596             final int callingUserId = UserHandle.getCallingUserId();
9597             ArrayList<PreferredActivity> removed = null;
9598             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId);
9599             if (pir != null) {
9600                 Iterator<PreferredActivity> it = pir.filterIterator();
9601                 String action = filter.getAction(0);
9602                 String category = filter.getCategory(0);
9603                 while (it.hasNext()) {
9604                     PreferredActivity pa = it.next();
9605                     if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
9606                         if (removed == null) {
9607                             removed = new ArrayList<PreferredActivity>();
9608                         }
9609                         removed.add(pa);
9610                         Log.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":");
9611                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
9612                     }
9613                 }
9614                 if (removed != null) {
9615                     for (int i=0; i<removed.size(); i++) {
9616                         PreferredActivity pa = removed.get(i);
9617                         pir.removeFilter(pa);
9618                     }
9619                 }
9620             }
9621             addPreferredActivity(filter, match, set, activity, callingUserId);
9622         }
9623     }
9624
9625     public void clearPackagePreferredActivities(String packageName) {
9626         final int uid = Binder.getCallingUid();
9627         // writer
9628         synchronized (mPackages) {
9629             PackageParser.Package pkg = mPackages.get(packageName);
9630             if (pkg == null || pkg.applicationInfo.uid != uid) {
9631                 if (mContext.checkCallingOrSelfPermission(
9632                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
9633                         != PackageManager.PERMISSION_GRANTED) {
9634                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
9635                             < Build.VERSION_CODES.FROYO) {
9636                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
9637                                 + Binder.getCallingUid());
9638                         return;
9639                     }
9640                     mContext.enforceCallingOrSelfPermission(
9641                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
9642                 }
9643             }
9644
9645             int user = UserHandle.getCallingUserId();
9646             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
9647                 mSettings.writePackageRestrictionsLPr(user);
9648                 scheduleWriteSettingsLocked();
9649             }
9650         }
9651     }
9652
9653     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
9654     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
9655         ArrayList<PreferredActivity> removed = null;
9656         boolean changed = false;
9657         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
9658             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
9659             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
9660             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
9661                 continue;
9662             }
9663             Iterator<PreferredActivity> it = pir.filterIterator();
9664             while (it.hasNext()) {
9665                 PreferredActivity pa = it.next();
9666                 if (packageName == null ||
9667                         pa.mPref.mComponent.getPackageName().equals(packageName)) {
9668                     if (removed == null) {
9669                         removed = new ArrayList<PreferredActivity>();
9670                     }
9671                     removed.add(pa);
9672                 }
9673             }
9674             if (removed != null) {
9675                 for (int j=0; j<removed.size(); j++) {
9676                     PreferredActivity pa = removed.get(j);
9677                     pir.removeFilter(pa);
9678                 }
9679                 changed = true;
9680             }
9681         }
9682         return changed;
9683     }
9684
9685     public void resetPreferredActivities(int userId) {
9686         mContext.enforceCallingOrSelfPermission(
9687                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
9688         // writer
9689         synchronized (mPackages) {
9690             int user = UserHandle.getCallingUserId();
9691             clearPackagePreferredActivitiesLPw(null, user);
9692             mSettings.readDefaultPreferredAppsLPw(this, user);
9693             mSettings.writePackageRestrictionsLPr(user);
9694             scheduleWriteSettingsLocked();
9695         }
9696     }
9697
9698     public int getPreferredActivities(List<IntentFilter> outFilters,
9699             List<ComponentName> outActivities, String packageName) {
9700
9701         int num = 0;
9702         final int userId = UserHandle.getCallingUserId();
9703         // reader
9704         synchronized (mPackages) {
9705             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
9706             if (pir != null) {
9707                 final Iterator<PreferredActivity> it = pir.filterIterator();
9708                 while (it.hasNext()) {
9709                     final PreferredActivity pa = it.next();
9710                     if (packageName == null
9711                             || pa.mPref.mComponent.getPackageName().equals(packageName)) {
9712                         if (outFilters != null) {
9713                             outFilters.add(new IntentFilter(pa));
9714                         }
9715                         if (outActivities != null) {
9716                             outActivities.add(pa.mPref.mComponent);
9717                         }
9718                     }
9719                 }
9720             }
9721         }
9722
9723         return num;
9724     }
9725
9726     @Override
9727     public void setApplicationEnabledSetting(String appPackageName,
9728             int newState, int flags, int userId, String callingPackage) {
9729         if (!sUserManager.exists(userId)) return;
9730         if (callingPackage == null) {
9731             callingPackage = Integer.toString(Binder.getCallingUid());
9732         }
9733         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
9734     }
9735
9736     @Override
9737     public void setComponentEnabledSetting(ComponentName componentName,
9738             int newState, int flags, int userId) {
9739         if (!sUserManager.exists(userId)) return;
9740         setEnabledSetting(componentName.getPackageName(),
9741                 componentName.getClassName(), newState, flags, userId, null);
9742     }
9743
9744     private void setEnabledSetting(final String packageName, String className, int newState,
9745             final int flags, int userId, String callingPackage) {
9746         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
9747               || newState == COMPONENT_ENABLED_STATE_ENABLED
9748               || newState == COMPONENT_ENABLED_STATE_DISABLED
9749               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
9750               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
9751             throw new IllegalArgumentException("Invalid new component state: "
9752                     + newState);
9753         }
9754         PackageSetting pkgSetting;
9755         final int uid = Binder.getCallingUid();
9756         final int permission = mContext.checkCallingOrSelfPermission(
9757                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
9758         enforceCrossUserPermission(uid, userId, false, "set enabled");
9759         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
9760         boolean sendNow = false;
9761         boolean isApp = (className == null);
9762         String componentName = isApp ? packageName : className;
9763         int packageUid = -1;
9764         ArrayList<String> components;
9765
9766         // writer
9767         synchronized (mPackages) {
9768             pkgSetting = mSettings.mPackages.get(packageName);
9769             if (pkgSetting == null) {
9770                 if (className == null) {
9771                     throw new IllegalArgumentException(
9772                             "Unknown package: " + packageName);
9773                 }
9774                 throw new IllegalArgumentException(
9775                         "Unknown component: " + packageName
9776                         + "/" + className);
9777             }
9778             // Allow root and verify that userId is not being specified by a different user
9779             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
9780                 throw new SecurityException(
9781                         "Permission Denial: attempt to change component state from pid="
9782                         + Binder.getCallingPid()
9783                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
9784             }
9785             if (className == null) {
9786                 // We're dealing with an application/package level state change
9787                 if (pkgSetting.getEnabled(userId) == newState) {
9788                     // Nothing to do
9789                     return;
9790                 }
9791                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
9792                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
9793                     // Don't care about who enables an app.
9794                     callingPackage = null;
9795                 }
9796                 pkgSetting.setEnabled(newState, userId, callingPackage);
9797                 // pkgSetting.pkg.mSetEnabled = newState;
9798             } else {
9799                 // We're dealing with a component level state change
9800                 // First, verify that this is a valid class name.
9801                 PackageParser.Package pkg = pkgSetting.pkg;
9802                 if (pkg == null || !pkg.hasComponentClassName(className)) {
9803                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
9804                         throw new IllegalArgumentException("Component class " + className
9805                                 + " does not exist in " + packageName);
9806                     } else {
9807                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
9808                                 + className + " does not exist in " + packageName);
9809                     }
9810                 }
9811                 switch (newState) {
9812                 case COMPONENT_ENABLED_STATE_ENABLED:
9813                     if (!pkgSetting.enableComponentLPw(className, userId)) {
9814                         return;
9815                     }
9816                     break;
9817                 case COMPONENT_ENABLED_STATE_DISABLED:
9818                     if (!pkgSetting.disableComponentLPw(className, userId)) {
9819                         return;
9820                     }
9821                     break;
9822                 case COMPONENT_ENABLED_STATE_DEFAULT:
9823                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
9824                         return;
9825                     }
9826                     break;
9827                 default:
9828                     Slog.e(TAG, "Invalid new component state: " + newState);
9829                     return;
9830                 }
9831             }
9832             mSettings.writePackageRestrictionsLPr(userId);
9833             components = mPendingBroadcasts.get(userId, packageName);
9834             final boolean newPackage = components == null;
9835             if (newPackage) {
9836                 components = new ArrayList<String>();
9837             }
9838             if (!components.contains(componentName)) {
9839                 components.add(componentName);
9840             }
9841             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
9842                 sendNow = true;
9843                 // Purge entry from pending broadcast list if another one exists already
9844                 // since we are sending one right away.
9845                 mPendingBroadcasts.remove(userId, packageName);
9846             } else {
9847                 if (newPackage) {
9848                     mPendingBroadcasts.put(userId, packageName, components);
9849                 }
9850                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
9851                     // Schedule a message
9852                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
9853                 }
9854             }
9855         }
9856
9857         long callingId = Binder.clearCallingIdentity();
9858         try {
9859             if (sendNow) {
9860                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
9861                 sendPackageChangedBroadcast(packageName,
9862                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
9863             }
9864         } finally {
9865             Binder.restoreCallingIdentity(callingId);
9866         }
9867     }
9868
9869     private void sendPackageChangedBroadcast(String packageName,
9870             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
9871         if (DEBUG_INSTALL)
9872             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
9873                     + componentNames);
9874         Bundle extras = new Bundle(4);
9875         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
9876         String nameList[] = new String[componentNames.size()];
9877         componentNames.toArray(nameList);
9878         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
9879         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
9880         extras.putInt(Intent.EXTRA_UID, packageUid);
9881         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
9882                 new int[] {UserHandle.getUserId(packageUid)});
9883     }
9884
9885     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
9886         if (!sUserManager.exists(userId)) return;
9887         final int uid = Binder.getCallingUid();
9888         final int permission = mContext.checkCallingOrSelfPermission(
9889                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
9890         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
9891         enforceCrossUserPermission(uid, userId, true, "stop package");
9892         // writer
9893         synchronized (mPackages) {
9894             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
9895                     uid, userId)) {
9896                 scheduleWritePackageRestrictionsLocked(userId);
9897             }
9898         }
9899     }
9900
9901     public String getInstallerPackageName(String packageName) {
9902         // reader
9903         synchronized (mPackages) {
9904             return mSettings.getInstallerPackageNameLPr(packageName);
9905         }
9906     }
9907
9908     @Override
9909     public int getApplicationEnabledSetting(String packageName, int userId) {
9910         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
9911         int uid = Binder.getCallingUid();
9912         enforceCrossUserPermission(uid, userId, false, "get enabled");
9913         // reader
9914         synchronized (mPackages) {
9915             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
9916         }
9917     }
9918
9919     @Override
9920     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
9921         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
9922         int uid = Binder.getCallingUid();
9923         enforceCrossUserPermission(uid, userId, false, "get component enabled");
9924         // reader
9925         synchronized (mPackages) {
9926             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
9927         }
9928     }
9929
9930     public void enterSafeMode() {
9931         enforceSystemOrRoot("Only the system can request entering safe mode");
9932
9933         if (!mSystemReady) {
9934             mSafeMode = true;
9935         }
9936     }
9937
9938     public void systemReady() {
9939         mSystemReady = true;
9940
9941         // Read the compatibilty setting when the system is ready.
9942         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
9943                 mContext.getContentResolver(),
9944                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
9945         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
9946         if (DEBUG_SETTINGS) {
9947             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
9948         }
9949
9950         synchronized (mPackages) {
9951             // Verify that all of the preferred activity components actually
9952             // exist.  It is possible for applications to be updated and at
9953             // that point remove a previously declared activity component that
9954             // had been set as a preferred activity.  We try to clean this up
9955             // the next time we encounter that preferred activity, but it is
9956             // possible for the user flow to never be able to return to that
9957             // situation so here we do a sanity check to make sure we haven't
9958             // left any junk around.
9959             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
9960             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
9961                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
9962                 removed.clear();
9963                 for (PreferredActivity pa : pir.filterSet()) {
9964                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
9965                         removed.add(pa);
9966                     }
9967                 }
9968                 if (removed.size() > 0) {
9969                     for (int j=0; j<removed.size(); j++) {
9970                         PreferredActivity pa = removed.get(i);
9971                         Slog.w(TAG, "Removing dangling preferred activity: "
9972                                 + pa.mPref.mComponent);
9973                         pir.removeFilter(pa);
9974                     }
9975                     mSettings.writePackageRestrictionsLPr(
9976                             mSettings.mPreferredActivities.keyAt(i));
9977                 }
9978             }
9979         }
9980     }
9981
9982     public boolean isSafeMode() {
9983         return mSafeMode;
9984     }
9985
9986     public boolean hasSystemUidErrors() {
9987         return mHasSystemUidErrors;
9988     }
9989
9990     static String arrayToString(int[] array) {
9991         StringBuffer buf = new StringBuffer(128);
9992         buf.append('[');
9993         if (array != null) {
9994             for (int i=0; i<array.length; i++) {
9995                 if (i > 0) buf.append(", ");
9996                 buf.append(array[i]);
9997             }
9998         }
9999         buf.append(']');
10000         return buf.toString();
10001     }
10002
10003     static class DumpState {
10004         public static final int DUMP_LIBS = 1 << 0;
10005
10006         public static final int DUMP_FEATURES = 1 << 1;
10007
10008         public static final int DUMP_RESOLVERS = 1 << 2;
10009
10010         public static final int DUMP_PERMISSIONS = 1 << 3;
10011
10012         public static final int DUMP_PACKAGES = 1 << 4;
10013
10014         public static final int DUMP_SHARED_USERS = 1 << 5;
10015
10016         public static final int DUMP_MESSAGES = 1 << 6;
10017
10018         public static final int DUMP_PROVIDERS = 1 << 7;
10019
10020         public static final int DUMP_VERIFIERS = 1 << 8;
10021
10022         public static final int DUMP_PREFERRED = 1 << 9;
10023
10024         public static final int DUMP_PREFERRED_XML = 1 << 10;
10025
10026         public static final int OPTION_SHOW_FILTERS = 1 << 0;
10027
10028         private int mTypes;
10029
10030         private int mOptions;
10031
10032         private boolean mTitlePrinted;
10033
10034         private SharedUserSetting mSharedUser;
10035
10036         public boolean isDumping(int type) {
10037             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
10038                 return true;
10039             }
10040
10041             return (mTypes & type) != 0;
10042         }
10043
10044         public void setDump(int type) {
10045             mTypes |= type;
10046         }
10047
10048         public boolean isOptionEnabled(int option) {
10049             return (mOptions & option) != 0;
10050         }
10051
10052         public void setOptionEnabled(int option) {
10053             mOptions |= option;
10054         }
10055
10056         public boolean onTitlePrinted() {
10057             final boolean printed = mTitlePrinted;
10058             mTitlePrinted = true;
10059             return printed;
10060         }
10061
10062         public boolean getTitlePrinted() {
10063             return mTitlePrinted;
10064         }
10065
10066         public void setTitlePrinted(boolean enabled) {
10067             mTitlePrinted = enabled;
10068         }
10069
10070         public SharedUserSetting getSharedUser() {
10071             return mSharedUser;
10072         }
10073
10074         public void setSharedUser(SharedUserSetting user) {
10075             mSharedUser = user;
10076         }
10077     }
10078
10079     @Override
10080     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10081         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
10082                 != PackageManager.PERMISSION_GRANTED) {
10083             pw.println("Permission Denial: can't dump ActivityManager from from pid="
10084                     + Binder.getCallingPid()
10085                     + ", uid=" + Binder.getCallingUid()
10086                     + " without permission "
10087                     + android.Manifest.permission.DUMP);
10088             return;
10089         }
10090
10091         DumpState dumpState = new DumpState();
10092         boolean fullPreferred = false;
10093         
10094         String packageName = null;
10095         
10096         int opti = 0;
10097         while (opti < args.length) {
10098             String opt = args[opti];
10099             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10100                 break;
10101             }
10102             opti++;
10103             if ("-a".equals(opt)) {
10104                 // Right now we only know how to print all.
10105             } else if ("-h".equals(opt)) {
10106                 pw.println("Package manager dump options:");
10107                 pw.println("  [-h] [-f] [cmd] ...");
10108                 pw.println("    -f: print details of intent filters");
10109                 pw.println("    -h: print this help");
10110                 pw.println("  cmd may be one of:");
10111                 pw.println("    l[ibraries]: list known shared libraries");
10112                 pw.println("    f[ibraries]: list device features");
10113                 pw.println("    r[esolvers]: dump intent resolvers");
10114                 pw.println("    perm[issions]: dump permissions");
10115                 pw.println("    pref[erred]: print preferred package settings");
10116                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
10117                 pw.println("    prov[iders]: dump content providers");
10118                 pw.println("    p[ackages]: dump installed packages");
10119                 pw.println("    s[hared-users]: dump shared user IDs");
10120                 pw.println("    m[essages]: print collected runtime messages");
10121                 pw.println("    v[erifiers]: print package verifier info");
10122                 pw.println("    <package.name>: info about given package");
10123                 return;
10124             } else if ("-f".equals(opt)) {
10125                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
10126             } else {
10127                 pw.println("Unknown argument: " + opt + "; use -h for help");
10128             }
10129         }
10130         
10131         // Is the caller requesting to dump a particular piece of data?
10132         if (opti < args.length) {
10133             String cmd = args[opti];
10134             opti++;
10135             // Is this a package name?
10136             if ("android".equals(cmd) || cmd.contains(".")) {
10137                 packageName = cmd;
10138             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
10139                 dumpState.setDump(DumpState.DUMP_LIBS);
10140             } else if ("f".equals(cmd) || "features".equals(cmd)) {
10141                 dumpState.setDump(DumpState.DUMP_FEATURES);
10142             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
10143                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
10144             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
10145                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
10146             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
10147                 dumpState.setDump(DumpState.DUMP_PREFERRED);
10148             } else if ("preferred-xml".equals(cmd)) {
10149                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
10150                 if (opti < args.length && "--full".equals(args[opti])) {
10151                     fullPreferred = true;
10152                     opti++;
10153                 }
10154             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
10155                 dumpState.setDump(DumpState.DUMP_PACKAGES);
10156             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
10157                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
10158             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
10159                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
10160             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
10161                 dumpState.setDump(DumpState.DUMP_MESSAGES);
10162             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
10163                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
10164             }
10165         }
10166
10167         // reader
10168         synchronized (mPackages) {
10169             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
10170                 if (dumpState.onTitlePrinted())
10171                     pw.println(" ");
10172                 pw.println("Verifiers:");
10173                 pw.print("  Required: ");
10174                 pw.print(mRequiredVerifierPackage);
10175                 pw.print(" (uid=");
10176                 pw.print(getPackageUid(mRequiredVerifierPackage, 0));
10177                 pw.println(")");
10178             }
10179
10180             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
10181                 if (dumpState.onTitlePrinted())
10182                     pw.println(" ");
10183                 pw.println("Libraries:");
10184                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
10185                 while (it.hasNext()) {
10186                     String name = it.next();
10187                     pw.print("  ");
10188                     pw.print(name);
10189                     pw.print(" -> ");
10190                     SharedLibraryEntry ent = mSharedLibraries.get(name);
10191                     if (ent.path != null) {
10192                         pw.print("(jar) ");
10193                         pw.print(ent.path);
10194                     } else {
10195                         pw.print("(apk) ");
10196                         pw.print(ent.apk);
10197                     }
10198                     pw.println();
10199                 }
10200             }
10201
10202             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
10203                 if (dumpState.onTitlePrinted())
10204                     pw.println(" ");
10205                 pw.println("Features:");
10206                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
10207                 while (it.hasNext()) {
10208                     String name = it.next();
10209                     pw.print("  ");
10210                     pw.println(name);
10211                 }
10212             }
10213
10214             if (dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
10215                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
10216                         : "Activity Resolver Table:", "  ", packageName,
10217                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10218                     dumpState.setTitlePrinted(true);
10219                 }
10220                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
10221                         : "Receiver Resolver Table:", "  ", packageName,
10222                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10223                     dumpState.setTitlePrinted(true);
10224                 }
10225                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
10226                         : "Service Resolver Table:", "  ", packageName,
10227                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10228                     dumpState.setTitlePrinted(true);
10229                 }
10230             }
10231
10232             if (dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
10233                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
10234                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
10235                     int user = mSettings.mPreferredActivities.keyAt(i);
10236                     if (pir.dump(pw,
10237                             dumpState.getTitlePrinted()
10238                                 ? "\nPreferred Activities User " + user + ":"
10239                                 : "Preferred Activities User " + user + ":", "  ",
10240                             packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
10241                         dumpState.setTitlePrinted(true);
10242                     }
10243                 }
10244             }
10245
10246             if (dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
10247                 pw.flush();
10248                 FileOutputStream fout = new FileOutputStream(fd);
10249                 BufferedOutputStream str = new BufferedOutputStream(fout);
10250                 XmlSerializer serializer = new FastXmlSerializer();
10251                 try {
10252                     serializer.setOutput(str, "utf-8");
10253                     serializer.startDocument(null, true);
10254                     serializer.setFeature(
10255                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
10256                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
10257                     serializer.endDocument();
10258                     serializer.flush();
10259                 } catch (IllegalArgumentException e) {
10260                     pw.println("Failed writing: " + e);
10261                 } catch (IllegalStateException e) {
10262                     pw.println("Failed writing: " + e);
10263                 } catch (IOException e) {
10264                     pw.println("Failed writing: " + e);
10265                 }
10266             }
10267
10268             if (dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
10269                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
10270             }
10271
10272             if (dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
10273                 boolean printedSomething = false;
10274                 for (PackageParser.Provider p : mProvidersByComponent.values()) {
10275                     if (packageName != null && !packageName.equals(p.info.packageName)) {
10276                         continue;
10277                     }
10278                     if (!printedSomething) {
10279                         if (dumpState.onTitlePrinted())
10280                             pw.println(" ");
10281                         pw.println("Registered ContentProviders:");
10282                         printedSomething = true;
10283                     }
10284                     pw.print("  "); pw.print(p.getComponentShortName()); pw.println(":");
10285                     pw.print("    "); pw.println(p.toString());
10286                 }
10287                 printedSomething = false;
10288                 for (Map.Entry<String, PackageParser.Provider> entry : mProviders.entrySet()) {
10289                     PackageParser.Provider p = entry.getValue();
10290                     if (packageName != null && !packageName.equals(p.info.packageName)) {
10291                         continue;
10292                     }
10293                     if (!printedSomething) {
10294                         if (dumpState.onTitlePrinted())
10295                             pw.println(" ");
10296                         pw.println("ContentProvider Authorities:");
10297                         printedSomething = true;
10298                     }
10299                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
10300                     pw.print("    "); pw.println(p.toString());
10301                     if (p.info != null && p.info.applicationInfo != null) {
10302                         final String appInfo = p.info.applicationInfo.toString();
10303                         pw.print("      applicationInfo="); pw.println(appInfo);
10304                     }
10305                 }
10306             }
10307             
10308             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
10309                 mSettings.dumpPackagesLPr(pw, packageName, dumpState);
10310             }
10311
10312             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
10313                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
10314             }
10315
10316             if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
10317                 if (dumpState.onTitlePrinted())
10318                     pw.println(" ");
10319                 mSettings.dumpReadMessagesLPr(pw, dumpState);
10320
10321                 pw.println(" ");
10322                 pw.println("Package warning messages:");
10323                 final File fname = getSettingsProblemFile();
10324                 FileInputStream in = null;
10325                 try {
10326                     in = new FileInputStream(fname);
10327                     final int avail = in.available();
10328                     final byte[] data = new byte[avail];
10329                     in.read(data);
10330                     pw.print(new String(data));
10331                 } catch (FileNotFoundException e) {
10332                 } catch (IOException e) {
10333                 } finally {
10334                     if (in != null) {
10335                         try {
10336                             in.close();
10337                         } catch (IOException e) {
10338                         }
10339                     }
10340                 }
10341             }
10342         }
10343     }
10344
10345     // ------- apps on sdcard specific code -------
10346     static final boolean DEBUG_SD_INSTALL = false;
10347
10348     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
10349
10350     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
10351
10352     private boolean mMediaMounted = false;
10353
10354     private String getEncryptKey() {
10355         try {
10356             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
10357                     SD_ENCRYPTION_KEYSTORE_NAME);
10358             if (sdEncKey == null) {
10359                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
10360                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
10361                 if (sdEncKey == null) {
10362                     Slog.e(TAG, "Failed to create encryption keys");
10363                     return null;
10364                 }
10365             }
10366             return sdEncKey;
10367         } catch (NoSuchAlgorithmException nsae) {
10368             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
10369             return null;
10370         } catch (IOException ioe) {
10371             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
10372             return null;
10373         }
10374
10375     }
10376
10377     /* package */static String getTempContainerId() {
10378         int tmpIdx = 1;
10379         String list[] = PackageHelper.getSecureContainerList();
10380         if (list != null) {
10381             for (final String name : list) {
10382                 // Ignore null and non-temporary container entries
10383                 if (name == null || !name.startsWith(mTempContainerPrefix)) {
10384                     continue;
10385                 }
10386
10387                 String subStr = name.substring(mTempContainerPrefix.length());
10388                 try {
10389                     int cid = Integer.parseInt(subStr);
10390                     if (cid >= tmpIdx) {
10391                         tmpIdx = cid + 1;
10392                     }
10393                 } catch (NumberFormatException e) {
10394                 }
10395             }
10396         }
10397         return mTempContainerPrefix + tmpIdx;
10398     }
10399
10400     /*
10401      * Update media status on PackageManager.
10402      */
10403     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
10404         int callingUid = Binder.getCallingUid();
10405         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10406             throw new SecurityException("Media status can only be updated by the system");
10407         }
10408         // reader; this apparently protects mMediaMounted, but should probably
10409         // be a different lock in that case.
10410         synchronized (mPackages) {
10411             Log.i(TAG, "Updating external media status from "
10412                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
10413                     + (mediaStatus ? "mounted" : "unmounted"));
10414             if (DEBUG_SD_INSTALL)
10415                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
10416                         + ", mMediaMounted=" + mMediaMounted);
10417             if (mediaStatus == mMediaMounted) {
10418                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
10419                         : 0, -1);
10420                 mHandler.sendMessage(msg);
10421                 return;
10422             }
10423             mMediaMounted = mediaStatus;
10424         }
10425         // Queue up an async operation since the package installation may take a
10426         // little while.
10427         mHandler.post(new Runnable() {
10428             public void run() {
10429                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
10430             }
10431         });
10432     }
10433
10434     /**
10435      * Called by MountService when the initial ASECs to scan are available.
10436      * Should block until all the ASEC containers are finished being scanned.
10437      */
10438     public void scanAvailableAsecs() {
10439         updateExternalMediaStatusInner(true, false, false);
10440     }
10441
10442     /*
10443      * Collect information of applications on external media, map them against
10444      * existing containers and update information based on current mount status.
10445      * Please note that we always have to report status if reportStatus has been
10446      * set to true especially when unloading packages.
10447      */
10448     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
10449             boolean externalStorage) {
10450         // Collection of uids
10451         int uidArr[] = null;
10452         // Collection of stale containers
10453         HashSet<String> removeCids = new HashSet<String>();
10454         // Collection of packages on external media with valid containers.
10455         HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>();
10456         // Get list of secure containers.
10457         final String list[] = PackageHelper.getSecureContainerList();
10458         if (list == null || list.length == 0) {
10459             Log.i(TAG, "No secure containers on sdcard");
10460         } else {
10461             // Process list of secure containers and categorize them
10462             // as active or stale based on their package internal state.
10463             int uidList[] = new int[list.length];
10464             int num = 0;
10465             // reader
10466             synchronized (mPackages) {
10467                 for (String cid : list) {
10468                     if (DEBUG_SD_INSTALL)
10469                         Log.i(TAG, "Processing container " + cid);
10470                     String pkgName = getAsecPackageName(cid);
10471                     if (pkgName == null) {
10472                         if (DEBUG_SD_INSTALL)
10473                             Log.i(TAG, "Container : " + cid + " stale");
10474                         removeCids.add(cid);
10475                         continue;
10476                     }
10477                     if (DEBUG_SD_INSTALL)
10478                         Log.i(TAG, "Looking for pkg : " + pkgName);
10479
10480                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
10481                     if (ps == null) {
10482                         Log.i(TAG, "Deleting container with no matching settings " + cid);
10483                         removeCids.add(cid);
10484                         continue;
10485                     }
10486
10487                     /*
10488                      * Skip packages that are not external if we're unmounting
10489                      * external storage.
10490                      */
10491                     if (externalStorage && !isMounted && !isExternal(ps)) {
10492                         continue;
10493                     }
10494
10495                     final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps));
10496                     // The package status is changed only if the code path
10497                     // matches between settings and the container id.
10498                     if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) {
10499                         if (DEBUG_SD_INSTALL) {
10500                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
10501                                     + " at code path: " + ps.codePathString);
10502                         }
10503
10504                         // We do have a valid package installed on sdcard
10505                         processCids.put(args, ps.codePathString);
10506                         final int uid = ps.appId;
10507                         if (uid != -1) {
10508                             uidList[num++] = uid;
10509                         }
10510                     } else {
10511                         Log.i(TAG, "Deleting stale container for " + cid);
10512                         removeCids.add(cid);
10513                     }
10514                 }
10515             }
10516
10517             if (num > 0) {
10518                 // Sort uid list
10519                 Arrays.sort(uidList, 0, num);
10520                 // Throw away duplicates
10521                 uidArr = new int[num];
10522                 uidArr[0] = uidList[0];
10523                 int di = 0;
10524                 for (int i = 1; i < num; i++) {
10525                     if (uidList[i - 1] != uidList[i]) {
10526                         uidArr[di++] = uidList[i];
10527                     }
10528                 }
10529             }
10530         }
10531         // Process packages with valid entries.
10532         if (isMounted) {
10533             if (DEBUG_SD_INSTALL)
10534                 Log.i(TAG, "Loading packages");
10535             loadMediaPackages(processCids, uidArr, removeCids);
10536             startCleaningPackages();
10537         } else {
10538             if (DEBUG_SD_INSTALL)
10539                 Log.i(TAG, "Unloading packages");
10540             unloadMediaPackages(processCids, uidArr, reportStatus);
10541         }
10542     }
10543
10544    private void sendResourcesChangedBroadcast(boolean mediaStatus, ArrayList<String> pkgList,
10545             int uidArr[], IIntentReceiver finishedReceiver) {
10546         int size = pkgList.size();
10547         if (size > 0) {
10548             // Send broadcasts here
10549             Bundle extras = new Bundle();
10550             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
10551                     .toArray(new String[size]));
10552             if (uidArr != null) {
10553                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
10554             }
10555             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
10556                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
10557             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
10558         }
10559     }
10560
10561    /*
10562      * Look at potentially valid container ids from processCids If package
10563      * information doesn't match the one on record or package scanning fails,
10564      * the cid is added to list of removeCids. We currently don't delete stale
10565      * containers.
10566      */
10567    private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
10568             HashSet<String> removeCids) {
10569         ArrayList<String> pkgList = new ArrayList<String>();
10570         Set<AsecInstallArgs> keys = processCids.keySet();
10571         boolean doGc = false;
10572         for (AsecInstallArgs args : keys) {
10573             String codePath = processCids.get(args);
10574             if (DEBUG_SD_INSTALL)
10575                 Log.i(TAG, "Loading container : " + args.cid);
10576             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
10577             try {
10578                 // Make sure there are no container errors first.
10579                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
10580                     Slog.e(TAG, "Failed to mount cid : " + args.cid
10581                             + " when installing from sdcard");
10582                     continue;
10583                 }
10584                 // Check code path here.
10585                 if (codePath == null || !codePath.equals(args.getCodePath())) {
10586                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
10587                             + " does not match one in settings " + codePath);
10588                     continue;
10589                 }
10590                 // Parse package
10591                 int parseFlags = mDefParseFlags;
10592                 if (args.isExternal()) {
10593                     parseFlags |= PackageParser.PARSE_ON_SDCARD;
10594                 }
10595                 if (args.isFwdLocked()) {
10596                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
10597                 }
10598
10599                 doGc = true;
10600                 synchronized (mInstallLock) {
10601                     final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags,
10602                             0, 0, null);
10603                     // Scan the package
10604                     if (pkg != null) {
10605                         /*
10606                          * TODO why is the lock being held? doPostInstall is
10607                          * called in other places without the lock. This needs
10608                          * to be straightened out.
10609                          */
10610                         // writer
10611                         synchronized (mPackages) {
10612                             retCode = PackageManager.INSTALL_SUCCEEDED;
10613                             pkgList.add(pkg.packageName);
10614                             // Post process args
10615                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
10616                                     pkg.applicationInfo.uid);
10617                         }
10618                     } else {
10619                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
10620                     }
10621                 }
10622
10623             } finally {
10624                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
10625                     // Don't destroy container here. Wait till gc clears things
10626                     // up.
10627                     removeCids.add(args.cid);
10628                 }
10629             }
10630         }
10631         // writer
10632         synchronized (mPackages) {
10633             // If the platform SDK has changed since the last time we booted,
10634             // we need to re-grant app permission to catch any new ones that
10635             // appear. This is really a hack, and means that apps can in some
10636             // cases get permissions that the user didn't initially explicitly
10637             // allow... it would be nice to have some better way to handle
10638             // this situation.
10639             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
10640             if (regrantPermissions)
10641                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
10642                         + mSdkVersion + "; regranting permissions for external storage");
10643             mSettings.mExternalSdkPlatform = mSdkVersion;
10644
10645             // Make sure group IDs have been assigned, and any permission
10646             // changes in other apps are accounted for
10647             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
10648                     | (regrantPermissions
10649                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
10650                             : 0));
10651             // can downgrade to reader
10652             // Persist settings
10653             mSettings.writeLPr();
10654         }
10655         // Send a broadcast to let everyone know we are done processing
10656         if (pkgList.size() > 0) {
10657             sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
10658         }
10659         // Force gc to avoid any stale parser references that we might have.
10660         if (doGc) {
10661             Runtime.getRuntime().gc();
10662         }
10663         // List stale containers and destroy stale temporary containers.
10664         if (removeCids != null) {
10665             for (String cid : removeCids) {
10666                 if (cid.startsWith(mTempContainerPrefix)) {
10667                     Log.i(TAG, "Destroying stale temporary container " + cid);
10668                     PackageHelper.destroySdDir(cid);
10669                 } else {
10670                     Log.w(TAG, "Container " + cid + " is stale");
10671                }
10672            }
10673         }
10674     }
10675
10676    /*
10677      * Utility method to unload a list of specified containers
10678      */
10679     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
10680         // Just unmount all valid containers.
10681         for (AsecInstallArgs arg : cidArgs) {
10682             synchronized (mInstallLock) {
10683                 arg.doPostDeleteLI(false);
10684            }
10685        }
10686    }
10687
10688     /*
10689      * Unload packages mounted on external media. This involves deleting package
10690      * data from internal structures, sending broadcasts about diabled packages,
10691      * gc'ing to free up references, unmounting all secure containers
10692      * corresponding to packages on external media, and posting a
10693      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
10694      * that we always have to post this message if status has been requested no
10695      * matter what.
10696      */
10697     private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[],
10698             final boolean reportStatus) {
10699         if (DEBUG_SD_INSTALL)
10700             Log.i(TAG, "unloading media packages");
10701         ArrayList<String> pkgList = new ArrayList<String>();
10702         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
10703         final Set<AsecInstallArgs> keys = processCids.keySet();
10704         for (AsecInstallArgs args : keys) {
10705             String pkgName = args.getPackageName();
10706             if (DEBUG_SD_INSTALL)
10707                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
10708             // Delete package internally
10709             PackageRemovedInfo outInfo = new PackageRemovedInfo();
10710             synchronized (mInstallLock) {
10711                 boolean res = deletePackageLI(pkgName, null, false, null, null,
10712                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
10713                 if (res) {
10714                     pkgList.add(pkgName);
10715                 } else {
10716                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
10717                     failedList.add(args);
10718                 }
10719             }
10720         }
10721
10722         // reader
10723         synchronized (mPackages) {
10724             // We didn't update the settings after removing each package;
10725             // write them now for all packages.
10726             mSettings.writeLPr();
10727         }
10728
10729         // We have to absolutely send UPDATED_MEDIA_STATUS only
10730         // after confirming that all the receivers processed the ordered
10731         // broadcast when packages get disabled, force a gc to clean things up.
10732         // and unload all the containers.
10733         if (pkgList.size() > 0) {
10734             sendResourcesChangedBroadcast(false, pkgList, uidArr, new IIntentReceiver.Stub() {
10735                 public void performReceive(Intent intent, int resultCode, String data,
10736                         Bundle extras, boolean ordered, boolean sticky,
10737                         int sendingUser) throws RemoteException {
10738                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
10739                             reportStatus ? 1 : 0, 1, keys);
10740                     mHandler.sendMessage(msg);
10741                 }
10742             });
10743         } else {
10744             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
10745                     keys);
10746             mHandler.sendMessage(msg);
10747         }
10748     }
10749
10750     /** Binder call */
10751     @Override
10752     public void movePackage(final String packageName, final IPackageMoveObserver observer,
10753             final int flags) {
10754         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
10755         UserHandle user = new UserHandle(UserHandle.getCallingUserId());
10756         int returnCode = PackageManager.MOVE_SUCCEEDED;
10757         int currFlags = 0;
10758         int newFlags = 0;
10759         // reader
10760         synchronized (mPackages) {
10761             PackageParser.Package pkg = mPackages.get(packageName);
10762             if (pkg == null) {
10763                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
10764             } else {
10765                 // Disable moving fwd locked apps and system packages
10766                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
10767                     Slog.w(TAG, "Cannot move system application");
10768                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
10769                 } else if (pkg.mOperationPending) {
10770                     Slog.w(TAG, "Attempt to move package which has pending operations");
10771                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
10772                 } else {
10773                     // Find install location first
10774                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
10775                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
10776                         Slog.w(TAG, "Ambigous flags specified for move location.");
10777                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
10778                     } else {
10779                         newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL
10780                                 : PackageManager.INSTALL_INTERNAL;
10781                         currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
10782                                 : PackageManager.INSTALL_INTERNAL;
10783
10784                         if (newFlags == currFlags) {
10785                             Slog.w(TAG, "No move required. Trying to move to same location");
10786                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
10787                         } else {
10788                             if (isForwardLocked(pkg)) {
10789                                 currFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10790                                 newFlags |= PackageManager.INSTALL_FORWARD_LOCK;
10791                             }
10792                         }
10793                     }
10794                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
10795                         pkg.mOperationPending = true;
10796                     }
10797                 }
10798             }
10799
10800             /*
10801              * TODO this next block probably shouldn't be inside the lock. We
10802              * can't guarantee these won't change after this is fired off
10803              * anyway.
10804              */
10805             if (returnCode != PackageManager.MOVE_SUCCEEDED) {
10806                 processPendingMove(new MoveParams(null, observer, 0, packageName,
10807                         null, -1, user),
10808                         returnCode);
10809             } else {
10810                 Message msg = mHandler.obtainMessage(INIT_COPY);
10811                 InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
10812                         pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
10813                 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
10814                         pkg.applicationInfo.dataDir, pkg.applicationInfo.uid, user);
10815                 msg.obj = mp;
10816                 mHandler.sendMessage(msg);
10817             }
10818         }
10819     }
10820
10821     private void processPendingMove(final MoveParams mp, final int currentStatus) {
10822         // Queue up an async operation since the package deletion may take a
10823         // little while.
10824         mHandler.post(new Runnable() {
10825             public void run() {
10826                 // TODO fix this; this does nothing.
10827                 mHandler.removeCallbacks(this);
10828                 int returnCode = currentStatus;
10829                 if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
10830                     int uidArr[] = null;
10831                     ArrayList<String> pkgList = null;
10832                     synchronized (mPackages) {
10833                         PackageParser.Package pkg = mPackages.get(mp.packageName);
10834                         if (pkg == null) {
10835                             Slog.w(TAG, " Package " + mp.packageName
10836                                     + " doesn't exist. Aborting move");
10837                             returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
10838                         } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
10839                             Slog.w(TAG, "Package " + mp.packageName + " code path changed from "
10840                                     + mp.srcArgs.getCodePath() + " to "
10841                                     + pkg.applicationInfo.sourceDir
10842                                     + " Aborting move and returning error");
10843                             returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
10844                         } else {
10845                             uidArr = new int[] {
10846                                 pkg.applicationInfo.uid
10847                             };
10848                             pkgList = new ArrayList<String>();
10849                             pkgList.add(mp.packageName);
10850                         }
10851                     }
10852                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
10853                         // Send resources unavailable broadcast
10854                         sendResourcesChangedBroadcast(false, pkgList, uidArr, null);
10855                         // Update package code and resource paths
10856                         synchronized (mInstallLock) {
10857                             synchronized (mPackages) {
10858                                 PackageParser.Package pkg = mPackages.get(mp.packageName);
10859                                 // Recheck for package again.
10860                                 if (pkg == null) {
10861                                     Slog.w(TAG, " Package " + mp.packageName
10862                                             + " doesn't exist. Aborting move");
10863                                     returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
10864                                 } else if (!mp.srcArgs.getCodePath().equals(
10865                                         pkg.applicationInfo.sourceDir)) {
10866                                     Slog.w(TAG, "Package " + mp.packageName
10867                                             + " code path changed from " + mp.srcArgs.getCodePath()
10868                                             + " to " + pkg.applicationInfo.sourceDir
10869                                             + " Aborting move and returning error");
10870                                     returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
10871                                 } else {
10872                                     final String oldCodePath = pkg.mPath;
10873                                     final String newCodePath = mp.targetArgs.getCodePath();
10874                                     final String newResPath = mp.targetArgs.getResourcePath();
10875                                     final String newNativePath = mp.targetArgs
10876                                             .getNativeLibraryPath();
10877
10878                                     final File newNativeDir = new File(newNativePath);
10879
10880                                     if (!isForwardLocked(pkg) && !isExternal(pkg)) {
10881                                         NativeLibraryHelper.copyNativeBinariesIfNeededLI(
10882                                                 new File(newCodePath), newNativeDir);
10883                                     }
10884                                     final int[] users = sUserManager.getUserIds();
10885                                     for (int user : users) {
10886                                         if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
10887                                                 newNativePath, user) < 0) {
10888                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
10889                                         }
10890                                     }
10891
10892                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
10893                                         pkg.mPath = newCodePath;
10894                                         // Move dex files around
10895                                         if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) {
10896                                             // Moving of dex files failed. Set
10897                                             // error code and abort move.
10898                                             pkg.mPath = pkg.mScanPath;
10899                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
10900                                         }
10901                                     }
10902
10903                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
10904                                         pkg.mScanPath = newCodePath;
10905                                         pkg.applicationInfo.sourceDir = newCodePath;
10906                                         pkg.applicationInfo.publicSourceDir = newResPath;
10907                                         pkg.applicationInfo.nativeLibraryDir = newNativePath;
10908                                         PackageSetting ps = (PackageSetting) pkg.mExtras;
10909                                         ps.codePath = new File(pkg.applicationInfo.sourceDir);
10910                                         ps.codePathString = ps.codePath.getPath();
10911                                         ps.resourcePath = new File(
10912                                                 pkg.applicationInfo.publicSourceDir);
10913                                         ps.resourcePathString = ps.resourcePath.getPath();
10914                                         ps.nativeLibraryPathString = newNativePath;
10915                                         // Set the application info flag
10916                                         // correctly.
10917                                         if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
10918                                             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
10919                                         } else {
10920                                             pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
10921                                         }
10922                                         ps.setFlags(pkg.applicationInfo.flags);
10923                                         mAppDirs.remove(oldCodePath);
10924                                         mAppDirs.put(newCodePath, pkg);
10925                                         // Persist settings
10926                                         mSettings.writeLPr();
10927                                     }
10928                                 }
10929                             }
10930                         }
10931                         // Send resources available broadcast
10932                         sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
10933                     }
10934                 }
10935                 if (returnCode != PackageManager.MOVE_SUCCEEDED) {
10936                     // Clean up failed installation
10937                     if (mp.targetArgs != null) {
10938                         mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
10939                                 -1);
10940                     }
10941                 } else {
10942                     // Force a gc to clear things up.
10943                     Runtime.getRuntime().gc();
10944                     // Delete older code
10945                     synchronized (mInstallLock) {
10946                         mp.srcArgs.doPostDeleteLI(true);
10947                     }
10948                 }
10949
10950                 // Allow more operations on this file if we didn't fail because
10951                 // an operation was already pending for this package.
10952                 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) {
10953                     synchronized (mPackages) {
10954                         PackageParser.Package pkg = mPackages.get(mp.packageName);
10955                         if (pkg != null) {
10956                             pkg.mOperationPending = false;
10957                        }
10958                    }
10959                 }
10960
10961                 IPackageMoveObserver observer = mp.observer;
10962                 if (observer != null) {
10963                     try {
10964                         observer.packageMoved(mp.packageName, returnCode);
10965                     } catch (RemoteException e) {
10966                         Log.i(TAG, "Observer no longer exists.");
10967                     }
10968                 }
10969             }
10970         });
10971     }
10972
10973     public boolean setInstallLocation(int loc) {
10974         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
10975                 null);
10976         if (getInstallLocation() == loc) {
10977             return true;
10978         }
10979         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
10980                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
10981             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
10982                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
10983             return true;
10984         }
10985         return false;
10986    }
10987
10988     public int getInstallLocation() {
10989         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
10990                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
10991                 PackageHelper.APP_INSTALL_AUTO);
10992     }
10993
10994     /** Called by UserManagerService */
10995     void cleanUpUserLILPw(int userHandle) {
10996         mDirtyUsers.remove(userHandle);
10997         mSettings.removeUserLPr(userHandle);
10998         mPendingBroadcasts.remove(userHandle);
10999         if (mInstaller != null) {
11000             // Technically, we shouldn't be doing this with the package lock
11001             // held.  However, this is very rare, and there is already so much
11002             // other disk I/O going on, that we'll let it slide for now.
11003             mInstaller.removeUserDataDirs(userHandle);
11004         }
11005     }
11006
11007     /** Called by UserManagerService */
11008     void createNewUserLILPw(int userHandle, File path) {
11009         if (mInstaller != null) {
11010             mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
11011         }
11012     }
11013
11014     @Override
11015     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
11016         mContext.enforceCallingOrSelfPermission(
11017                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
11018                 "Only package verification agents can read the verifier device identity");
11019
11020         synchronized (mPackages) {
11021             return mSettings.getVerifierDeviceIdentityLPw();
11022         }
11023     }
11024
11025     @Override
11026     public void setPermissionEnforced(String permission, boolean enforced) {
11027         mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
11028         if (READ_EXTERNAL_STORAGE.equals(permission)) {
11029             synchronized (mPackages) {
11030                 if (mSettings.mReadExternalStorageEnforced == null
11031                         || mSettings.mReadExternalStorageEnforced != enforced) {
11032                     mSettings.mReadExternalStorageEnforced = enforced;
11033                     mSettings.writeLPr();
11034                 }
11035             }
11036             // kill any non-foreground processes so we restart them and
11037             // grant/revoke the GID.
11038             final IActivityManager am = ActivityManagerNative.getDefault();
11039             if (am != null) {
11040                 final long token = Binder.clearCallingIdentity();
11041                 try {
11042                     am.killProcessesBelowForeground("setPermissionEnforcement");
11043                 } catch (RemoteException e) {
11044                 } finally {
11045                     Binder.restoreCallingIdentity(token);
11046                 }
11047             }
11048         } else {
11049             throw new IllegalArgumentException("No selective enforcement for " + permission);
11050         }
11051     }
11052
11053     @Override
11054     public boolean isPermissionEnforced(String permission) {
11055         final boolean enforcedDefault = isPermissionEnforcedDefault(permission);
11056         synchronized (mPackages) {
11057             return isPermissionEnforcedLocked(permission, enforcedDefault);
11058         }
11059     }
11060
11061     /**
11062      * Check if given permission should be enforced by default. Should always be
11063      * called outside of {@link #mPackages} lock.
11064      */
11065     private boolean isPermissionEnforcedDefault(String permission) {
11066         if (READ_EXTERNAL_STORAGE.equals(permission)) {
11067             return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
11068                     android.provider.Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT, 0)
11069                     != 0;
11070         } else {
11071             return true;
11072         }
11073     }
11074
11075     /**
11076      * Check if user has requested that given permission be enforced, using
11077      * given default if undefined.
11078      */
11079     private boolean isPermissionEnforcedLocked(String permission, boolean enforcedDefault) {
11080         if (READ_EXTERNAL_STORAGE.equals(permission)) {
11081             if (mSettings.mReadExternalStorageEnforced != null) {
11082                 return mSettings.mReadExternalStorageEnforced;
11083             } else {
11084                 // User hasn't defined; fall back to secure default
11085                 return enforcedDefault;
11086             }
11087         } else {
11088             return true;
11089         }
11090     }
11091
11092     public boolean isStorageLow() {
11093         final long token = Binder.clearCallingIdentity();
11094         try {
11095             final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
11096                     .getService(DeviceStorageMonitorService.SERVICE);
11097             return dsm.isMemoryLow();
11098         } finally {
11099             Binder.restoreCallingIdentity(token);
11100         }
11101     }
11102 }