• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
20 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
23 import static libcore.io.OsConstants.S_ISLNK;
24 
25 import com.android.internal.app.IMediaContainerService;
26 import com.android.internal.app.ResolverActivity;
27 import com.android.internal.content.NativeLibraryHelper;
28 import com.android.internal.content.PackageHelper;
29 import com.android.internal.util.XmlUtils;
30 import com.android.server.DeviceStorageMonitorService;
31 import com.android.server.EventLogTags;
32 import com.android.server.IntentResolver;
33 
34 import org.xmlpull.v1.XmlPullParser;
35 import org.xmlpull.v1.XmlPullParserException;
36 
37 import android.app.ActivityManagerNative;
38 import android.app.IActivityManager;
39 import android.app.admin.IDevicePolicyManager;
40 import android.app.backup.IBackupManager;
41 import android.content.BroadcastReceiver;
42 import android.content.ComponentName;
43 import android.content.Context;
44 import android.content.IIntentReceiver;
45 import android.content.Intent;
46 import android.content.IntentFilter;
47 import android.content.IntentSender;
48 import android.content.ServiceConnection;
49 import android.content.IntentSender.SendIntentException;
50 import android.content.pm.ActivityInfo;
51 import android.content.pm.ApplicationInfo;
52 import android.content.pm.FeatureInfo;
53 import android.content.pm.IPackageDataObserver;
54 import android.content.pm.IPackageDeleteObserver;
55 import android.content.pm.IPackageInstallObserver;
56 import android.content.pm.IPackageManager;
57 import android.content.pm.IPackageMoveObserver;
58 import android.content.pm.IPackageStatsObserver;
59 import android.content.pm.InstrumentationInfo;
60 import android.content.pm.PackageInfo;
61 import android.content.pm.PackageInfoLite;
62 import android.content.pm.PackageManager;
63 import android.content.pm.PackageParser;
64 import android.content.pm.PackageStats;
65 import android.content.pm.ParceledListSlice;
66 import android.content.pm.PermissionGroupInfo;
67 import android.content.pm.PermissionInfo;
68 import android.content.pm.ProviderInfo;
69 import android.content.pm.ResolveInfo;
70 import android.content.pm.ServiceInfo;
71 import android.content.pm.Signature;
72 import android.content.pm.UserInfo;
73 import android.content.pm.ManifestDigest;
74 import android.content.pm.VerifierDeviceIdentity;
75 import android.content.pm.VerifierInfo;
76 import android.net.Uri;
77 import android.os.Binder;
78 import android.os.Build;
79 import android.os.Bundle;
80 import android.os.Environment;
81 import android.os.FileObserver;
82 import android.os.FileUtils;
83 import android.os.Handler;
84 import android.os.HandlerThread;
85 import android.os.IBinder;
86 import android.os.Looper;
87 import android.os.Message;
88 import android.os.Parcel;
89 import android.os.ParcelFileDescriptor;
90 import android.os.Process;
91 import android.os.RemoteException;
92 import android.os.ServiceManager;
93 import android.os.SystemClock;
94 import android.os.SystemProperties;
95 import android.security.SystemKeyStore;
96 import android.util.DisplayMetrics;
97 import android.util.EventLog;
98 import android.util.Log;
99 import android.util.LogPrinter;
100 import android.util.Slog;
101 import android.util.SparseArray;
102 import android.util.Xml;
103 import android.view.Display;
104 import android.view.WindowManager;
105 
106 import java.io.File;
107 import java.io.FileDescriptor;
108 import java.io.FileInputStream;
109 import java.io.FileNotFoundException;
110 import java.io.FileOutputStream;
111 import java.io.FileReader;
112 import java.io.FilenameFilter;
113 import java.io.IOException;
114 import java.io.InputStream;
115 import java.io.PrintWriter;
116 import java.security.NoSuchAlgorithmException;
117 import java.security.PublicKey;
118 import java.security.cert.CertificateException;
119 import java.text.SimpleDateFormat;
120 import java.util.ArrayList;
121 import java.util.Arrays;
122 import java.util.Collection;
123 import java.util.Collections;
124 import java.util.Comparator;
125 import java.util.Date;
126 import java.util.Enumeration;
127 import java.util.HashMap;
128 import java.util.HashSet;
129 import java.util.Iterator;
130 import java.util.List;
131 import java.util.Map;
132 import java.util.Set;
133 import java.util.zip.ZipEntry;
134 import java.util.zip.ZipFile;
135 import java.util.zip.ZipOutputStream;
136 
137 import libcore.io.ErrnoException;
138 import libcore.io.Libcore;
139 
140 /**
141  * Keep track of all those .apks everywhere.
142  *
143  * This is very central to the platform's security; please run the unit
144  * tests whenever making modifications here:
145  *
146 mmm frameworks/base/tests/AndroidTests
147 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
148 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
149  *
150  * {@hide}
151  */
152 public class PackageManagerService extends IPackageManager.Stub {
153     static final String TAG = "PackageManager";
154     static final boolean DEBUG_SETTINGS = false;
155     private static final boolean DEBUG_PREFERRED = false;
156     static final boolean DEBUG_UPGRADE = false;
157     private static final boolean DEBUG_INSTALL = false;
158     private static final boolean DEBUG_REMOVE = false;
159     private static final boolean DEBUG_SHOW_INFO = false;
160     private static final boolean DEBUG_PACKAGE_INFO = false;
161     private static final boolean DEBUG_INTENT_MATCHING = false;
162     private static final boolean DEBUG_PACKAGE_SCANNING = false;
163     private static final boolean DEBUG_APP_DIR_OBSERVER = false;
164     private static final boolean DEBUG_VERIFY = false;
165 
166     static final boolean MULTIPLE_APPLICATION_UIDS = true;
167     private static final int RADIO_UID = Process.PHONE_UID;
168     private static final int LOG_UID = Process.LOG_UID;
169     private static final int NFC_UID = Process.NFC_UID;
170     static final int FIRST_APPLICATION_UID =
171         Process.FIRST_APPLICATION_UID;
172     static final int MAX_APPLICATION_UIDS = 1000;
173 
174     private static final boolean GET_CERTIFICATES = true;
175 
176     private static final int REMOVE_EVENTS =
177         FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
178     private static final int ADD_EVENTS =
179         FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;
180 
181     private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;
182     // Suffix used during package installation when copying/moving
183     // package apks to install directory.
184     private static final String INSTALL_PACKAGE_SUFFIX = "-";
185 
186     static final int SCAN_MONITOR = 1<<0;
187     static final int SCAN_NO_DEX = 1<<1;
188     static final int SCAN_FORCE_DEX = 1<<2;
189     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
190     static final int SCAN_NEW_INSTALL = 1<<4;
191     static final int SCAN_NO_PATHS = 1<<5;
192     static final int SCAN_UPDATE_TIME = 1<<6;
193     static final int SCAN_DEFER_DEX = 1<<7;
194 
195     static final int REMOVE_CHATTY = 1<<16;
196 
197     /**
198      * Whether verification is enabled by default.
199      */
200     // STOPSHIP: change this to true
201     private static final boolean DEFAULT_VERIFY_ENABLE = false;
202 
203     /**
204      * The default maximum time to wait for the verification agent to return in
205      * milliseconds.
206      */
207     private static final long DEFAULT_VERIFICATION_TIMEOUT = 60 * 1000;
208 
209     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
210 
211     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
212             DEFAULT_CONTAINER_PACKAGE,
213             "com.android.defcontainer.DefaultContainerService");
214 
215     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
216 
217     private static final String LIB_DIR_NAME = "lib";
218 
219     static final String mTempContainerPrefix = "smdl2tmp";
220 
221     final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
222             Process.THREAD_PRIORITY_BACKGROUND);
223     final PackageHandler mHandler;
224 
225     final int mSdkVersion = Build.VERSION.SDK_INT;
226     final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
227             ? null : Build.VERSION.CODENAME;
228 
229     final Context mContext;
230     final boolean mFactoryTest;
231     final boolean mOnlyCore;
232     final boolean mNoDexOpt;
233     final DisplayMetrics mMetrics;
234     final int mDefParseFlags;
235     final String[] mSeparateProcesses;
236 
237     // This is where all application persistent data goes.
238     final File mAppDataDir;
239 
240     // This is where all application persistent data goes for secondary users.
241     final File mUserAppDataDir;
242 
243     // This is the object monitoring the framework dir.
244     final FileObserver mFrameworkInstallObserver;
245 
246     // This is the object monitoring the system app dir.
247     final FileObserver mSystemInstallObserver;
248 
249     // This is the object monitoring the system app dir.
250     final FileObserver mVendorInstallObserver;
251 
252     // This is the object monitoring mAppInstallDir.
253     final FileObserver mAppInstallObserver;
254 
255     // This is the object monitoring mDrmAppPrivateInstallDir.
256     final FileObserver mDrmAppInstallObserver;
257 
258     // Used for priviledge escalation.  MUST NOT BE CALLED WITH mPackages
259     // LOCK HELD.  Can be called with mInstallLock held.
260     final Installer mInstaller;
261 
262     final File mFrameworkDir;
263     final File mSystemAppDir;
264     final File mVendorAppDir;
265     final File mAppInstallDir;
266     final File mDalvikCacheDir;
267 
268     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
269     // apps.
270     final File mDrmAppPrivateInstallDir;
271 
272     // ----------------------------------------------------------------
273 
274     // Lock for state used when installing and doing other long running
275     // operations.  Methods that must be called with this lock held have
276     // the prefix "LI".
277     final Object mInstallLock = new Object();
278 
279     // These are the directories in the 3rd party applications installed dir
280     // that we have currently loaded packages from.  Keys are the application's
281     // installed zip file (absolute codePath), and values are Package.
282     final HashMap<String, PackageParser.Package> mAppDirs =
283             new HashMap<String, PackageParser.Package>();
284 
285     // Information for the parser to write more useful error messages.
286     File mScanningPath;
287     int mLastScanError;
288 
289     final int[] mOutPermissions = new int[3];
290 
291     // ----------------------------------------------------------------
292 
293     // Keys are String (package name), values are Package.  This also serves
294     // as the lock for the global state.  Methods that must be called with
295     // this lock held have the prefix "LP".
296     final HashMap<String, PackageParser.Package> mPackages =
297             new HashMap<String, PackageParser.Package>();
298 
299     final Settings mSettings;
300     boolean mRestoredSettings;
301 
302     // Group-ids that are given to all packages as read from etc/permissions/*.xml.
303     int[] mGlobalGids;
304 
305     // These are the built-in uid -> permission mappings that were read from the
306     // etc/permissions.xml file.
307     final SparseArray<HashSet<String>> mSystemPermissions =
308             new SparseArray<HashSet<String>>();
309 
310     // These are the built-in shared libraries that were read from the
311     // etc/permissions.xml file.
312     final HashMap<String, String> mSharedLibraries = new HashMap<String, String>();
313 
314     // Temporary for building the final shared libraries for an .apk.
315     String[] mTmpSharedLibraries = null;
316 
317     // These are the features this devices supports that were read from the
318     // etc/permissions.xml file.
319     final HashMap<String, FeatureInfo> mAvailableFeatures =
320             new HashMap<String, FeatureInfo>();
321 
322     // All available activities, for your resolving pleasure.
323     final ActivityIntentResolver mActivities =
324             new ActivityIntentResolver();
325 
326     // All available receivers, for your resolving pleasure.
327     final ActivityIntentResolver mReceivers =
328             new ActivityIntentResolver();
329 
330     // All available services, for your resolving pleasure.
331     final ServiceIntentResolver mServices = new ServiceIntentResolver();
332 
333     // Keys are String (provider class name), values are Provider.
334     final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent =
335             new HashMap<ComponentName, PackageParser.Provider>();
336 
337     // Mapping from provider base names (first directory in content URI codePath)
338     // to the provider information.
339     final HashMap<String, PackageParser.Provider> mProviders =
340             new HashMap<String, PackageParser.Provider>();
341 
342     // Mapping from instrumentation class names to info about them.
343     final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
344             new HashMap<ComponentName, PackageParser.Instrumentation>();
345 
346     // Mapping from permission names to info about them.
347     final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
348             new HashMap<String, PackageParser.PermissionGroup>();
349 
350     // Packages whose data we have transfered into another package, thus
351     // should no longer exist.
352     final HashSet<String> mTransferedPackages = new HashSet<String>();
353 
354     // Broadcast actions that are only available to the system.
355     final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
356 
357     /** List of packages waiting for verification. */
358     final SparseArray<PackageVerificationState> mPendingVerification
359             = new SparseArray<PackageVerificationState>();
360 
361     final ArrayList<PackageParser.Package> mDeferredDexOpt =
362             new ArrayList<PackageParser.Package>();
363 
364     /** Token for keys in mPendingVerification. */
365     private int mPendingVerificationToken = 0;
366 
367     boolean mSystemReady;
368     boolean mSafeMode;
369     boolean mHasSystemUidErrors;
370 
371     ApplicationInfo mAndroidApplication;
372     final ActivityInfo mResolveActivity = new ActivityInfo();
373     final ResolveInfo mResolveInfo = new ResolveInfo();
374     ComponentName mResolveComponentName;
375     PackageParser.Package mPlatformPackage;
376 
377     // Set of pending broadcasts for aggregating enable/disable of components.
378     final HashMap<String, ArrayList<String>> mPendingBroadcasts
379             = new HashMap<String, ArrayList<String>>();
380     // Service Connection to remote media container service to copy
381     // package uri's from external media onto secure containers
382     // or internal storage.
383     private IMediaContainerService mContainerService = null;
384 
385     static final int SEND_PENDING_BROADCAST = 1;
386     static final int MCS_BOUND = 3;
387     static final int END_COPY = 4;
388     static final int INIT_COPY = 5;
389     static final int MCS_UNBIND = 6;
390     static final int START_CLEANING_PACKAGE = 7;
391     static final int FIND_INSTALL_LOC = 8;
392     static final int POST_INSTALL = 9;
393     static final int MCS_RECONNECT = 10;
394     static final int MCS_GIVE_UP = 11;
395     static final int UPDATED_MEDIA_STATUS = 12;
396     static final int WRITE_SETTINGS = 13;
397     static final int WRITE_STOPPED_PACKAGES = 14;
398     static final int PACKAGE_VERIFIED = 15;
399     static final int CHECK_PENDING_VERIFICATION = 16;
400 
401     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
402 
403     // Delay time in millisecs
404     static final int BROADCAST_DELAY = 10 * 1000;
405 
406     final UserManager mUserManager;
407 
408     final private DefaultContainerConnection mDefContainerConn =
409             new DefaultContainerConnection();
410     class DefaultContainerConnection implements ServiceConnection {
onServiceConnected(ComponentName name, IBinder service)411         public void onServiceConnected(ComponentName name, IBinder service) {
412             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
413             IMediaContainerService imcs =
414                 IMediaContainerService.Stub.asInterface(service);
415             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
416         }
417 
onServiceDisconnected(ComponentName name)418         public void onServiceDisconnected(ComponentName name) {
419             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
420         }
421     };
422 
423     // Recordkeeping of restore-after-install operations that are currently in flight
424     // between the Package Manager and the Backup Manager
425     class PostInstallData {
426         public InstallArgs args;
427         public PackageInstalledInfo res;
428 
PostInstallData(InstallArgs _a, PackageInstalledInfo _r)429         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
430             args = _a;
431             res = _r;
432         }
433     };
434     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
435     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
436 
437     private final String mRequiredVerifierPackage;
438 
439     class PackageHandler extends Handler {
440         private boolean mBound = false;
441         final ArrayList<HandlerParams> mPendingInstalls =
442             new ArrayList<HandlerParams>();
443 
connectToService()444         private boolean connectToService() {
445             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
446                     " DefaultContainerService");
447             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
448             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
449             if (mContext.bindService(service, mDefContainerConn,
450                     Context.BIND_AUTO_CREATE)) {
451                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
452                 mBound = true;
453                 return true;
454             }
455             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
456             return false;
457         }
458 
disconnectService()459         private void disconnectService() {
460             mContainerService = null;
461             mBound = false;
462             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
463             mContext.unbindService(mDefContainerConn);
464             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
465         }
466 
PackageHandler(Looper looper)467         PackageHandler(Looper looper) {
468             super(looper);
469         }
470 
handleMessage(Message msg)471         public void handleMessage(Message msg) {
472             try {
473                 doHandleMessage(msg);
474             } finally {
475                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
476             }
477         }
478 
doHandleMessage(Message msg)479         void doHandleMessage(Message msg) {
480             switch (msg.what) {
481                 case INIT_COPY: {
482                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy");
483                     HandlerParams params = (HandlerParams) msg.obj;
484                     int idx = mPendingInstalls.size();
485                     if (DEBUG_INSTALL) Slog.i(TAG, "idx=" + idx);
486                     // If a bind was already initiated we dont really
487                     // need to do anything. The pending install
488                     // will be processed later on.
489                     if (!mBound) {
490                         // If this is the only one pending we might
491                         // have to bind to the service again.
492                         if (!connectToService()) {
493                             Slog.e(TAG, "Failed to bind to media container service");
494                             params.serviceError();
495                             return;
496                         } else {
497                             // Once we bind to the service, the first
498                             // pending request will be processed.
499                             mPendingInstalls.add(idx, params);
500                         }
501                     } else {
502                         mPendingInstalls.add(idx, params);
503                         // Already bound to the service. Just make
504                         // sure we trigger off processing the first request.
505                         if (idx == 0) {
506                             mHandler.sendEmptyMessage(MCS_BOUND);
507                         }
508                     }
509                     break;
510                 }
511                 case MCS_BOUND: {
512                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
513                     if (msg.obj != null) {
514                         mContainerService = (IMediaContainerService) msg.obj;
515                     }
516                     if (mContainerService == null) {
517                         // Something seriously wrong. Bail out
518                         Slog.e(TAG, "Cannot bind to media container service");
519                         for (HandlerParams params : mPendingInstalls) {
520                             mPendingInstalls.remove(0);
521                             // Indicate service bind error
522                             params.serviceError();
523                         }
524                         mPendingInstalls.clear();
525                     } else if (mPendingInstalls.size() > 0) {
526                         HandlerParams params = mPendingInstalls.get(0);
527                         if (params != null) {
528                             if (params.startCopy()) {
529                                 // We are done...  look for more work or to
530                                 // go idle.
531                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
532                                         "Checking for more work or unbind...");
533                                 // Delete pending install
534                                 if (mPendingInstalls.size() > 0) {
535                                     mPendingInstalls.remove(0);
536                                 }
537                                 if (mPendingInstalls.size() == 0) {
538                                     if (mBound) {
539                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
540                                                 "Posting delayed MCS_UNBIND");
541                                         removeMessages(MCS_UNBIND);
542                                         Message ubmsg = obtainMessage(MCS_UNBIND);
543                                         // Unbind after a little delay, to avoid
544                                         // continual thrashing.
545                                         sendMessageDelayed(ubmsg, 10000);
546                                     }
547                                 } else {
548                                     // There are more pending requests in queue.
549                                     // Just post MCS_BOUND message to trigger processing
550                                     // of next pending install.
551                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
552                                             "Posting MCS_BOUND for next woek");
553                                     mHandler.sendEmptyMessage(MCS_BOUND);
554                                 }
555                             }
556                         }
557                     } else {
558                         // Should never happen ideally.
559                         Slog.w(TAG, "Empty queue");
560                     }
561                     break;
562                 }
563                 case MCS_RECONNECT: {
564                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
565                     if (mPendingInstalls.size() > 0) {
566                         if (mBound) {
567                             disconnectService();
568                         }
569                         if (!connectToService()) {
570                             Slog.e(TAG, "Failed to bind to media container service");
571                             for (HandlerParams params : mPendingInstalls) {
572                                 mPendingInstalls.remove(0);
573                                 // Indicate service bind error
574                                 params.serviceError();
575                             }
576                             mPendingInstalls.clear();
577                         }
578                     }
579                     break;
580                 }
581                 case MCS_UNBIND: {
582                     // If there is no actual work left, then time to unbind.
583                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
584 
585                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
586                         if (mBound) {
587                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
588 
589                             disconnectService();
590                         }
591                     } else if (mPendingInstalls.size() > 0) {
592                         // There are more pending requests in queue.
593                         // Just post MCS_BOUND message to trigger processing
594                         // of next pending install.
595                         mHandler.sendEmptyMessage(MCS_BOUND);
596                     }
597 
598                     break;
599                 }
600                 case MCS_GIVE_UP: {
601                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
602                     mPendingInstalls.remove(0);
603                     break;
604                 }
605                 case SEND_PENDING_BROADCAST: {
606                     String packages[];
607                     ArrayList<String> components[];
608                     int size = 0;
609                     int uids[];
610                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
611                     synchronized (mPackages) {
612                         if (mPendingBroadcasts == null) {
613                             return;
614                         }
615                         size = mPendingBroadcasts.size();
616                         if (size <= 0) {
617                             // Nothing to be done. Just return
618                             return;
619                         }
620                         packages = new String[size];
621                         components = new ArrayList[size];
622                         uids = new int[size];
623                         Iterator<HashMap.Entry<String, ArrayList<String>>>
624                                 it = mPendingBroadcasts.entrySet().iterator();
625                         int i = 0;
626                         while (it.hasNext() && i < size) {
627                             HashMap.Entry<String, ArrayList<String>> ent = it.next();
628                             packages[i] = ent.getKey();
629                             components[i] = ent.getValue();
630                             PackageSetting ps = mSettings.mPackages.get(ent.getKey());
631                             uids[i] = (ps != null) ? ps.userId : -1;
632                             i++;
633                         }
634                         size = i;
635                         mPendingBroadcasts.clear();
636                     }
637                     // Send broadcasts
638                     for (int i = 0; i < size; i++) {
639                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
640                     }
641                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
642                     break;
643                 }
644                 case START_CLEANING_PACKAGE: {
645                     String packageName = (String)msg.obj;
646                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
647                     synchronized (mPackages) {
648                         if (!mSettings.mPackagesToBeCleaned.contains(packageName)) {
649                             mSettings.mPackagesToBeCleaned.add(packageName);
650                         }
651                     }
652                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
653                     startCleaningPackages();
654                 } break;
655                 case POST_INSTALL: {
656                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
657                     PostInstallData data = mRunningInstalls.get(msg.arg1);
658                     mRunningInstalls.delete(msg.arg1);
659                     boolean deleteOld = false;
660 
661                     if (data != null) {
662                         InstallArgs args = data.args;
663                         PackageInstalledInfo res = data.res;
664 
665                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
666                             res.removedInfo.sendBroadcast(false, true);
667                             Bundle extras = new Bundle(1);
668                             extras.putInt(Intent.EXTRA_UID, res.uid);
669                             final boolean update = res.removedInfo.removedPackage != null;
670                             if (update) {
671                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
672                             }
673                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
674                                     res.pkg.applicationInfo.packageName,
675                                     extras, null, null);
676                             if (update) {
677                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
678                                         res.pkg.applicationInfo.packageName,
679                                         extras, null, null);
680                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
681                                         null, null,
682                                         res.pkg.applicationInfo.packageName, null);
683                             }
684                             if (res.removedInfo.args != null) {
685                                 // Remove the replaced package's older resources safely now
686                                 deleteOld = true;
687                             }
688                         }
689                         // Force a gc to clear up things
690                         Runtime.getRuntime().gc();
691                         // We delete after a gc for applications  on sdcard.
692                         if (deleteOld) {
693                             synchronized (mInstallLock) {
694                                 res.removedInfo.args.doPostDeleteLI(true);
695                             }
696                         }
697                         if (args.observer != null) {
698                             try {
699                                 args.observer.packageInstalled(res.name, res.returnCode);
700                             } catch (RemoteException e) {
701                                 Slog.i(TAG, "Observer no longer exists.");
702                             }
703                         }
704                     } else {
705                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
706                     }
707                 } break;
708                 case UPDATED_MEDIA_STATUS: {
709                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
710                     boolean reportStatus = msg.arg1 == 1;
711                     boolean doGc = msg.arg2 == 1;
712                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
713                     if (doGc) {
714                         // Force a gc to clear up stale containers.
715                         Runtime.getRuntime().gc();
716                     }
717                     if (msg.obj != null) {
718                         @SuppressWarnings("unchecked")
719                         Set<SdInstallArgs> args = (Set<SdInstallArgs>) msg.obj;
720                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
721                         // Unload containers
722                         unloadAllContainers(args);
723                     }
724                     if (reportStatus) {
725                         try {
726                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
727                             PackageHelper.getMountService().finishMediaUpdate();
728                         } catch (RemoteException e) {
729                             Log.e(TAG, "MountService not running?");
730                         }
731                     }
732                 } break;
733                 case WRITE_SETTINGS: {
734                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
735                     synchronized (mPackages) {
736                         removeMessages(WRITE_SETTINGS);
737                         removeMessages(WRITE_STOPPED_PACKAGES);
738                         mSettings.writeLPr();
739                     }
740                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
741                 } break;
742                 case WRITE_STOPPED_PACKAGES: {
743                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
744                     synchronized (mPackages) {
745                         removeMessages(WRITE_STOPPED_PACKAGES);
746                         mSettings.writeStoppedLPr();
747                     }
748                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
749                 } break;
750                 case CHECK_PENDING_VERIFICATION: {
751                     final int verificationId = msg.arg1;
752                     final PackageVerificationState state = mPendingVerification.get(verificationId);
753 
754                     if (state != null) {
755                         final InstallArgs args = state.getInstallArgs();
756                         Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
757                         mPendingVerification.remove(verificationId);
758 
759                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT;
760                         processPendingInstall(args, ret);
761 
762                         mHandler.sendEmptyMessage(MCS_UNBIND);
763                     }
764 
765                     break;
766                 }
767                 case PACKAGE_VERIFIED: {
768                     final int verificationId = msg.arg1;
769 
770                     final PackageVerificationState state = mPendingVerification.get(verificationId);
771                     if (state == null) {
772                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
773                         break;
774                     }
775 
776                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
777 
778                     state.setVerifierResponse(response.callerUid, response.code);
779 
780                     if (state.isVerificationComplete()) {
781                         mPendingVerification.remove(verificationId);
782 
783                         final InstallArgs args = state.getInstallArgs();
784 
785                         int ret;
786                         if (state.isInstallAllowed()) {
787                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
788                             try {
789                                 ret = args.copyApk(mContainerService, true);
790                             } catch (RemoteException e) {
791                                 Slog.e(TAG, "Could not contact the ContainerService");
792                             }
793                         } else {
794                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
795                         }
796 
797                         processPendingInstall(args, ret);
798 
799                         mHandler.sendEmptyMessage(MCS_UNBIND);
800                     }
801 
802                     break;
803                 }
804             }
805         }
806     }
807 
scheduleWriteSettingsLocked()808     void scheduleWriteSettingsLocked() {
809         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
810             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
811         }
812     }
813 
scheduleWriteStoppedPackagesLocked()814     void scheduleWriteStoppedPackagesLocked() {
815         if (!mHandler.hasMessages(WRITE_STOPPED_PACKAGES)) {
816             mHandler.sendEmptyMessageDelayed(WRITE_STOPPED_PACKAGES, WRITE_SETTINGS_DELAY);
817         }
818     }
819 
installOnSd(int flags)820     static boolean installOnSd(int flags) {
821         if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) ||
822                 ((flags & PackageManager.INSTALL_INTERNAL) != 0)) {
823             return false;
824         }
825         if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
826             return true;
827         }
828         return false;
829     }
830 
main(Context context, boolean factoryTest, boolean onlyCore)831     public static final IPackageManager main(Context context, boolean factoryTest,
832             boolean onlyCore) {
833         PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
834         ServiceManager.addService("package", m);
835         return m;
836     }
837 
splitString(String str, char sep)838     static String[] splitString(String str, char sep) {
839         int count = 1;
840         int i = 0;
841         while ((i=str.indexOf(sep, i)) >= 0) {
842             count++;
843             i++;
844         }
845 
846         String[] res = new String[count];
847         i=0;
848         count = 0;
849         int lastI=0;
850         while ((i=str.indexOf(sep, i)) >= 0) {
851             res[count] = str.substring(lastI, i);
852             count++;
853             i++;
854             lastI = i;
855         }
856         res[count] = str.substring(lastI, str.length());
857         return res;
858     }
859 
PackageManagerService(Context context, boolean factoryTest, boolean onlyCore)860     public PackageManagerService(Context context, boolean factoryTest, boolean onlyCore) {
861         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
862                 SystemClock.uptimeMillis());
863 
864         if (mSdkVersion <= 0) {
865             Slog.w(TAG, "**** ro.build.version.sdk not set!");
866         }
867 
868         mContext = context;
869         mFactoryTest = factoryTest;
870         mOnlyCore = onlyCore;
871         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
872         mMetrics = new DisplayMetrics();
873         mSettings = new Settings();
874         mSettings.addSharedUserLPw("android.uid.system",
875                 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
876         mSettings.addSharedUserLPw("android.uid.phone",
877                 MULTIPLE_APPLICATION_UIDS
878                         ? RADIO_UID : FIRST_APPLICATION_UID,
879                 ApplicationInfo.FLAG_SYSTEM);
880         mSettings.addSharedUserLPw("android.uid.log",
881                 MULTIPLE_APPLICATION_UIDS
882                         ? LOG_UID : FIRST_APPLICATION_UID,
883                 ApplicationInfo.FLAG_SYSTEM);
884         mSettings.addSharedUserLPw("android.uid.nfc",
885                 MULTIPLE_APPLICATION_UIDS
886                         ? NFC_UID : FIRST_APPLICATION_UID,
887                 ApplicationInfo.FLAG_SYSTEM);
888 
889         String separateProcesses = SystemProperties.get("debug.separate_processes");
890         if (separateProcesses != null && separateProcesses.length() > 0) {
891             if ("*".equals(separateProcesses)) {
892                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
893                 mSeparateProcesses = null;
894                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
895             } else {
896                 mDefParseFlags = 0;
897                 mSeparateProcesses = separateProcesses.split(",");
898                 Slog.w(TAG, "Running with debug.separate_processes: "
899                         + separateProcesses);
900             }
901         } else {
902             mDefParseFlags = 0;
903             mSeparateProcesses = null;
904         }
905 
906         mInstaller = new Installer();
907 
908         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
909         Display d = wm.getDefaultDisplay();
910         d.getMetrics(mMetrics);
911 
912         synchronized (mInstallLock) {
913         // writer
914         synchronized (mPackages) {
915             mHandlerThread.start();
916             mHandler = new PackageHandler(mHandlerThread.getLooper());
917 
918             File dataDir = Environment.getDataDirectory();
919             mAppDataDir = new File(dataDir, "data");
920             mUserAppDataDir = new File(dataDir, "user");
921             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
922 
923             mUserManager = new UserManager(mInstaller, mUserAppDataDir);
924 
925             readPermissions();
926 
927             mRestoredSettings = mSettings.readLPw();
928             long startTime = SystemClock.uptimeMillis();
929 
930             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
931                     startTime);
932 
933             // Set flag to monitor and not change apk file paths when
934             // scanning install directories.
935             int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX;
936             if (mNoDexOpt) {
937                 Slog.w(TAG, "Running ENG build: no pre-dexopt!");
938                 scanMode |= SCAN_NO_DEX;
939             }
940 
941             final HashSet<String> libFiles = new HashSet<String>();
942 
943             mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
944             mDalvikCacheDir = new File(dataDir, "dalvik-cache");
945 
946             boolean didDexOpt = false;
947 
948             /**
949              * Out of paranoia, ensure that everything in the boot class
950              * path has been dexed.
951              */
952             String bootClassPath = System.getProperty("java.boot.class.path");
953             if (bootClassPath != null) {
954                 String[] paths = splitString(bootClassPath, ':');
955                 for (int i=0; i<paths.length; i++) {
956                     try {
957                         if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
958                             libFiles.add(paths[i]);
959                             mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
960                             didDexOpt = true;
961                         }
962                     } catch (FileNotFoundException e) {
963                         Slog.w(TAG, "Boot class path not found: " + paths[i]);
964                     } catch (IOException e) {
965                         Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
966                                 + e.getMessage());
967                     }
968                 }
969             } else {
970                 Slog.w(TAG, "No BOOTCLASSPATH found!");
971             }
972 
973             /**
974              * Also ensure all external libraries have had dexopt run on them.
975              */
976             if (mSharedLibraries.size() > 0) {
977                 Iterator<String> libs = mSharedLibraries.values().iterator();
978                 while (libs.hasNext()) {
979                     String lib = libs.next();
980                     try {
981                         if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
982                             libFiles.add(lib);
983                             mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
984                             didDexOpt = true;
985                         }
986                     } catch (FileNotFoundException e) {
987                         Slog.w(TAG, "Library not found: " + lib);
988                     } catch (IOException e) {
989                         Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
990                                 + e.getMessage());
991                     }
992                 }
993             }
994 
995             // Gross hack for now: we know this file doesn't contain any
996             // code, so don't dexopt it to avoid the resulting log spew.
997             libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
998 
999             /**
1000              * And there are a number of commands implemented in Java, which
1001              * we currently need to do the dexopt on so that they can be
1002              * run from a non-root shell.
1003              */
1004             String[] frameworkFiles = mFrameworkDir.list();
1005             if (frameworkFiles != null) {
1006                 for (int i=0; i<frameworkFiles.length; i++) {
1007                     File libPath = new File(mFrameworkDir, frameworkFiles[i]);
1008                     String path = libPath.getPath();
1009                     // Skip the file if we alrady did it.
1010                     if (libFiles.contains(path)) {
1011                         continue;
1012                     }
1013                     // Skip the file if it is not a type we want to dexopt.
1014                     if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
1015                         continue;
1016                     }
1017                     try {
1018                         if (dalvik.system.DexFile.isDexOptNeeded(path)) {
1019                             mInstaller.dexopt(path, Process.SYSTEM_UID, true);
1020                             didDexOpt = true;
1021                         }
1022                     } catch (FileNotFoundException e) {
1023                         Slog.w(TAG, "Jar not found: " + path);
1024                     } catch (IOException e) {
1025                         Slog.w(TAG, "Exception reading jar: " + path, e);
1026                     }
1027                 }
1028             }
1029 
1030             if (didDexOpt) {
1031                 // If we had to do a dexopt of one of the previous
1032                 // things, then something on the system has changed.
1033                 // Consider this significant, and wipe away all other
1034                 // existing dexopt files to ensure we don't leave any
1035                 // dangling around.
1036                 String[] files = mDalvikCacheDir.list();
1037                 if (files != null) {
1038                     for (int i=0; i<files.length; i++) {
1039                         String fn = files[i];
1040                         if (fn.startsWith("data@app@")
1041                                 || fn.startsWith("data@app-private@")) {
1042                             Slog.i(TAG, "Pruning dalvik file: " + fn);
1043                             (new File(mDalvikCacheDir, fn)).delete();
1044                         }
1045                     }
1046                 }
1047             }
1048 
1049             // Find base frameworks (resource packages without code).
1050             mFrameworkInstallObserver = new AppDirObserver(
1051                 mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
1052             mFrameworkInstallObserver.startWatching();
1053             scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
1054                     | PackageParser.PARSE_IS_SYSTEM_DIR,
1055                     scanMode | SCAN_NO_DEX, 0);
1056 
1057             // Collect all system packages.
1058             mSystemAppDir = new File(Environment.getRootDirectory(), "app");
1059             mSystemInstallObserver = new AppDirObserver(
1060                 mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
1061             mSystemInstallObserver.startWatching();
1062             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
1063                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1064 
1065             // Collect all vendor packages.
1066             mVendorAppDir = new File("/vendor/app");
1067             mVendorInstallObserver = new AppDirObserver(
1068                 mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
1069             mVendorInstallObserver.startWatching();
1070             scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
1071                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
1072 
1073             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
1074             mInstaller.moveFiles();
1075 
1076             // Prune any system packages that no longer exist.
1077             if (!mOnlyCore) {
1078                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
1079                 while (psit.hasNext()) {
1080                     PackageSetting ps = psit.next();
1081                     if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0
1082                             && !mPackages.containsKey(ps.name)
1083                             && !mSettings.mDisabledSysPackages.containsKey(ps.name)) {
1084                         psit.remove();
1085                         String msg = "System package " + ps.name
1086                                 + " no longer exists; wiping its data";
1087                         reportSettingsProblem(Log.WARN, msg);
1088                         mInstaller.remove(ps.name, 0);
1089                         mUserManager.removePackageForAllUsers(ps.name);
1090                     }
1091                 }
1092             }
1093 
1094             mAppInstallDir = new File(dataDir, "app");
1095             //look for any incomplete package installations
1096             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
1097             //clean up list
1098             for(int i = 0; i < deletePkgsList.size(); i++) {
1099                 //clean up here
1100                 cleanupInstallFailedPackage(deletePkgsList.get(i));
1101             }
1102             //delete tmp files
1103             deleteTempPackageFiles();
1104 
1105             if (!mOnlyCore) {
1106                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
1107                         SystemClock.uptimeMillis());
1108                 mAppInstallObserver = new AppDirObserver(
1109                     mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
1110                 mAppInstallObserver.startWatching();
1111                 scanDirLI(mAppInstallDir, 0, scanMode, 0);
1112 
1113                 mDrmAppInstallObserver = new AppDirObserver(
1114                     mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
1115                 mDrmAppInstallObserver.startWatching();
1116                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
1117                         scanMode, 0);
1118             } else {
1119                 mAppInstallObserver = null;
1120                 mDrmAppInstallObserver = null;
1121             }
1122 
1123             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
1124                     SystemClock.uptimeMillis());
1125             Slog.i(TAG, "Time to scan packages: "
1126                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
1127                     + " seconds");
1128 
1129             // If the platform SDK has changed since the last time we booted,
1130             // we need to re-grant app permission to catch any new ones that
1131             // appear.  This is really a hack, and means that apps can in some
1132             // cases get permissions that the user didn't initially explicitly
1133             // allow...  it would be nice to have some better way to handle
1134             // this situation.
1135             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
1136                     != mSdkVersion;
1137             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
1138                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
1139                     + "; regranting permissions for internal storage");
1140             mSettings.mInternalSdkPlatform = mSdkVersion;
1141 
1142             updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions);
1143 
1144             // can downgrade to reader
1145             mSettings.writeLPr();
1146 
1147             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
1148                     SystemClock.uptimeMillis());
1149 
1150             // Now after opening every single application zip, make sure they
1151             // are all flushed.  Not really needed, but keeps things nice and
1152             // tidy.
1153             Runtime.getRuntime().gc();
1154 
1155             mRequiredVerifierPackage = getRequiredVerifierLPr();
1156         } // synchronized (mPackages)
1157         } // synchronized (mInstallLock)
1158     }
1159 
isFirstBoot()1160     public boolean isFirstBoot() {
1161         return !mRestoredSettings;
1162     }
1163 
getRequiredVerifierLPr()1164     private String getRequiredVerifierLPr() {
1165         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1166         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
1167                 PackageManager.GET_DISABLED_COMPONENTS);
1168 
1169         String requiredVerifier = null;
1170 
1171         final int N = receivers.size();
1172         for (int i = 0; i < N; i++) {
1173             final ResolveInfo info = receivers.get(i);
1174 
1175             if (info.activityInfo == null) {
1176                 continue;
1177             }
1178 
1179             final String packageName = info.activityInfo.packageName;
1180 
1181             final PackageSetting ps = mSettings.mPackages.get(packageName);
1182             if (ps == null) {
1183                 continue;
1184             }
1185 
1186             if (!ps.grantedPermissions
1187                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
1188                 continue;
1189             }
1190 
1191             if (requiredVerifier != null) {
1192                 throw new RuntimeException("There can be only one required verifier");
1193             }
1194 
1195             requiredVerifier = packageName;
1196         }
1197 
1198         return requiredVerifier;
1199     }
1200 
1201     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)1202     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1203             throws RemoteException {
1204         try {
1205             return super.onTransact(code, data, reply, flags);
1206         } catch (RuntimeException e) {
1207             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
1208                 Slog.e(TAG, "Package Manager Crash", e);
1209             }
1210             throw e;
1211         }
1212     }
1213 
cleanupInstallFailedPackage(PackageSetting ps)1214     void cleanupInstallFailedPackage(PackageSetting ps) {
1215         Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
1216         int retCode = mInstaller.remove(ps.name, 0);
1217         if (retCode < 0) {
1218             Slog.w(TAG, "Couldn't remove app data directory for package: "
1219                        + ps.name + ", retcode=" + retCode);
1220         } else {
1221             mUserManager.removePackageForAllUsers(ps.name);
1222         }
1223         if (ps.codePath != null) {
1224             if (!ps.codePath.delete()) {
1225                 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
1226             }
1227         }
1228         if (ps.resourcePath != null) {
1229             if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
1230                 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
1231             }
1232         }
1233         mSettings.removePackageLPw(ps.name);
1234     }
1235 
readPermissions()1236     void readPermissions() {
1237         // Read permissions from .../etc/permission directory.
1238         File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
1239         if (!libraryDir.exists() || !libraryDir.isDirectory()) {
1240             Slog.w(TAG, "No directory " + libraryDir + ", skipping");
1241             return;
1242         }
1243         if (!libraryDir.canRead()) {
1244             Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
1245             return;
1246         }
1247 
1248         // Iterate over the files in the directory and scan .xml files
1249         for (File f : libraryDir.listFiles()) {
1250             // We'll read platform.xml last
1251             if (f.getPath().endsWith("etc/permissions/platform.xml")) {
1252                 continue;
1253             }
1254 
1255             if (!f.getPath().endsWith(".xml")) {
1256                 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
1257                 continue;
1258             }
1259             if (!f.canRead()) {
1260                 Slog.w(TAG, "Permissions library file " + f + " cannot be read");
1261                 continue;
1262             }
1263 
1264             readPermissionsFromXml(f);
1265         }
1266 
1267         // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
1268         final File permFile = new File(Environment.getRootDirectory(),
1269                 "etc/permissions/platform.xml");
1270         readPermissionsFromXml(permFile);
1271     }
1272 
readPermissionsFromXml(File permFile)1273     private void readPermissionsFromXml(File permFile) {
1274         FileReader permReader = null;
1275         try {
1276             permReader = new FileReader(permFile);
1277         } catch (FileNotFoundException e) {
1278             Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
1279             return;
1280         }
1281 
1282         try {
1283             XmlPullParser parser = Xml.newPullParser();
1284             parser.setInput(permReader);
1285 
1286             XmlUtils.beginDocument(parser, "permissions");
1287 
1288             while (true) {
1289                 XmlUtils.nextElement(parser);
1290                 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
1291                     break;
1292                 }
1293 
1294                 String name = parser.getName();
1295                 if ("group".equals(name)) {
1296                     String gidStr = parser.getAttributeValue(null, "gid");
1297                     if (gidStr != null) {
1298                         int gid = Integer.parseInt(gidStr);
1299                         mGlobalGids = appendInt(mGlobalGids, gid);
1300                     } else {
1301                         Slog.w(TAG, "<group> without gid at "
1302                                 + parser.getPositionDescription());
1303                     }
1304 
1305                     XmlUtils.skipCurrentTag(parser);
1306                     continue;
1307                 } else if ("permission".equals(name)) {
1308                     String perm = parser.getAttributeValue(null, "name");
1309                     if (perm == null) {
1310                         Slog.w(TAG, "<permission> without name at "
1311                                 + parser.getPositionDescription());
1312                         XmlUtils.skipCurrentTag(parser);
1313                         continue;
1314                     }
1315                     perm = perm.intern();
1316                     readPermission(parser, perm);
1317 
1318                 } else if ("assign-permission".equals(name)) {
1319                     String perm = parser.getAttributeValue(null, "name");
1320                     if (perm == null) {
1321                         Slog.w(TAG, "<assign-permission> without name at "
1322                                 + parser.getPositionDescription());
1323                         XmlUtils.skipCurrentTag(parser);
1324                         continue;
1325                     }
1326                     String uidStr = parser.getAttributeValue(null, "uid");
1327                     if (uidStr == null) {
1328                         Slog.w(TAG, "<assign-permission> without uid at "
1329                                 + parser.getPositionDescription());
1330                         XmlUtils.skipCurrentTag(parser);
1331                         continue;
1332                     }
1333                     int uid = Process.getUidForName(uidStr);
1334                     if (uid < 0) {
1335                         Slog.w(TAG, "<assign-permission> with unknown uid \""
1336                                 + uidStr + "\" at "
1337                                 + parser.getPositionDescription());
1338                         XmlUtils.skipCurrentTag(parser);
1339                         continue;
1340                     }
1341                     perm = perm.intern();
1342                     HashSet<String> perms = mSystemPermissions.get(uid);
1343                     if (perms == null) {
1344                         perms = new HashSet<String>();
1345                         mSystemPermissions.put(uid, perms);
1346                     }
1347                     perms.add(perm);
1348                     XmlUtils.skipCurrentTag(parser);
1349 
1350                 } else if ("library".equals(name)) {
1351                     String lname = parser.getAttributeValue(null, "name");
1352                     String lfile = parser.getAttributeValue(null, "file");
1353                     if (lname == null) {
1354                         Slog.w(TAG, "<library> without name at "
1355                                 + parser.getPositionDescription());
1356                     } else if (lfile == null) {
1357                         Slog.w(TAG, "<library> without file at "
1358                                 + parser.getPositionDescription());
1359                     } else {
1360                         //Log.i(TAG, "Got library " + lname + " in " + lfile);
1361                         mSharedLibraries.put(lname, lfile);
1362                     }
1363                     XmlUtils.skipCurrentTag(parser);
1364                     continue;
1365 
1366                 } else if ("feature".equals(name)) {
1367                     String fname = parser.getAttributeValue(null, "name");
1368                     if (fname == null) {
1369                         Slog.w(TAG, "<feature> without name at "
1370                                 + parser.getPositionDescription());
1371                     } else {
1372                         //Log.i(TAG, "Got feature " + fname);
1373                         FeatureInfo fi = new FeatureInfo();
1374                         fi.name = fname;
1375                         mAvailableFeatures.put(fname, fi);
1376                     }
1377                     XmlUtils.skipCurrentTag(parser);
1378                     continue;
1379 
1380                 } else {
1381                     XmlUtils.skipCurrentTag(parser);
1382                     continue;
1383                 }
1384 
1385             }
1386             permReader.close();
1387         } catch (XmlPullParserException e) {
1388             Slog.w(TAG, "Got execption parsing permissions.", e);
1389         } catch (IOException e) {
1390             Slog.w(TAG, "Got execption parsing permissions.", e);
1391         }
1392     }
1393 
readPermission(XmlPullParser parser, String name)1394     void readPermission(XmlPullParser parser, String name)
1395             throws IOException, XmlPullParserException {
1396 
1397         name = name.intern();
1398 
1399         BasePermission bp = mSettings.mPermissions.get(name);
1400         if (bp == null) {
1401             bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
1402             mSettings.mPermissions.put(name, bp);
1403         }
1404         int outerDepth = parser.getDepth();
1405         int type;
1406         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
1407                && (type != XmlPullParser.END_TAG
1408                        || parser.getDepth() > outerDepth)) {
1409             if (type == XmlPullParser.END_TAG
1410                     || type == XmlPullParser.TEXT) {
1411                 continue;
1412             }
1413 
1414             String tagName = parser.getName();
1415             if ("group".equals(tagName)) {
1416                 String gidStr = parser.getAttributeValue(null, "gid");
1417                 if (gidStr != null) {
1418                     int gid = Process.getGidForName(gidStr);
1419                     bp.gids = appendInt(bp.gids, gid);
1420                 } else {
1421                     Slog.w(TAG, "<group> without gid at "
1422                             + parser.getPositionDescription());
1423                 }
1424             }
1425             XmlUtils.skipCurrentTag(parser);
1426         }
1427     }
1428 
appendInt(int[] cur, int val)1429     static int[] appendInt(int[] cur, int val) {
1430         if (cur == null) {
1431             return new int[] { val };
1432         }
1433         final int N = cur.length;
1434         for (int i=0; i<N; i++) {
1435             if (cur[i] == val) {
1436                 return cur;
1437             }
1438         }
1439         int[] ret = new int[N+1];
1440         System.arraycopy(cur, 0, ret, 0, N);
1441         ret[N] = val;
1442         return ret;
1443     }
1444 
appendInts(int[] cur, int[] add)1445     static int[] appendInts(int[] cur, int[] add) {
1446         if (add == null) return cur;
1447         if (cur == null) return add;
1448         final int N = add.length;
1449         for (int i=0; i<N; i++) {
1450             cur = appendInt(cur, add[i]);
1451         }
1452         return cur;
1453     }
1454 
removeInt(int[] cur, int val)1455     static int[] removeInt(int[] cur, int val) {
1456         if (cur == null) {
1457             return null;
1458         }
1459         final int N = cur.length;
1460         for (int i=0; i<N; i++) {
1461             if (cur[i] == val) {
1462                 int[] ret = new int[N-1];
1463                 if (i > 0) {
1464                     System.arraycopy(cur, 0, ret, 0, i);
1465                 }
1466                 if (i < (N-1)) {
1467                     System.arraycopy(cur, i + 1, ret, i, N - i - 1);
1468                 }
1469                 return ret;
1470             }
1471         }
1472         return cur;
1473     }
1474 
removeInts(int[] cur, int[] rem)1475     static int[] removeInts(int[] cur, int[] rem) {
1476         if (rem == null) return cur;
1477         if (cur == null) return cur;
1478         final int N = rem.length;
1479         for (int i=0; i<N; i++) {
1480             cur = removeInt(cur, rem[i]);
1481         }
1482         return cur;
1483     }
1484 
generatePackageInfo(PackageParser.Package p, int flags)1485     PackageInfo generatePackageInfo(PackageParser.Package p, int flags) {
1486         if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1487             // The package has been uninstalled but has retained data and resources.
1488             return PackageParser.generatePackageInfo(p, null, flags, 0, 0);
1489         }
1490         final PackageSetting ps = (PackageSetting)p.mExtras;
1491         if (ps == null) {
1492             return null;
1493         }
1494         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
1495         return PackageParser.generatePackageInfo(p, gp.gids, flags,
1496                 ps.firstInstallTime, ps.lastUpdateTime);
1497     }
1498 
getPackageInfo(String packageName, int flags)1499     public PackageInfo getPackageInfo(String packageName, int flags) {
1500         // reader
1501         synchronized (mPackages) {
1502             PackageParser.Package p = mPackages.get(packageName);
1503             if (DEBUG_PACKAGE_INFO)
1504                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
1505             if (p != null) {
1506                 return generatePackageInfo(p, flags);
1507             }
1508             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1509                 return generatePackageInfoFromSettingsLPw(packageName, flags);
1510             }
1511         }
1512         return null;
1513     }
1514 
currentToCanonicalPackageNames(String[] names)1515     public String[] currentToCanonicalPackageNames(String[] names) {
1516         String[] out = new String[names.length];
1517         // reader
1518         synchronized (mPackages) {
1519             for (int i=names.length-1; i>=0; i--) {
1520                 PackageSetting ps = mSettings.mPackages.get(names[i]);
1521                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
1522             }
1523         }
1524         return out;
1525     }
1526 
canonicalToCurrentPackageNames(String[] names)1527     public String[] canonicalToCurrentPackageNames(String[] names) {
1528         String[] out = new String[names.length];
1529         // reader
1530         synchronized (mPackages) {
1531             for (int i=names.length-1; i>=0; i--) {
1532                 String cur = mSettings.mRenamedPackages.get(names[i]);
1533                 out[i] = cur != null ? cur : names[i];
1534             }
1535         }
1536         return out;
1537     }
1538 
getPackageUid(String packageName)1539     public int getPackageUid(String packageName) {
1540         // reader
1541         synchronized (mPackages) {
1542             PackageParser.Package p = mPackages.get(packageName);
1543             if(p != null) {
1544                 return p.applicationInfo.uid;
1545             }
1546             PackageSetting ps = mSettings.mPackages.get(packageName);
1547             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
1548                 return -1;
1549             }
1550             p = ps.pkg;
1551             return p != null ? p.applicationInfo.uid : -1;
1552         }
1553     }
1554 
getPackageGids(String packageName)1555     public int[] getPackageGids(String packageName) {
1556         // reader
1557         synchronized (mPackages) {
1558             PackageParser.Package p = mPackages.get(packageName);
1559             if (DEBUG_PACKAGE_INFO)
1560                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
1561             if (p != null) {
1562                 final PackageSetting ps = (PackageSetting)p.mExtras;
1563                 final SharedUserSetting suid = ps.sharedUser;
1564                 return suid != null ? suid.gids : ps.gids;
1565             }
1566         }
1567         // stupid thing to indicate an error.
1568         return new int[0];
1569     }
1570 
generatePermissionInfo( BasePermission bp, int flags)1571     static final PermissionInfo generatePermissionInfo(
1572             BasePermission bp, int flags) {
1573         if (bp.perm != null) {
1574             return PackageParser.generatePermissionInfo(bp.perm, flags);
1575         }
1576         PermissionInfo pi = new PermissionInfo();
1577         pi.name = bp.name;
1578         pi.packageName = bp.sourcePackage;
1579         pi.nonLocalizedLabel = bp.name;
1580         pi.protectionLevel = bp.protectionLevel;
1581         return pi;
1582     }
1583 
getPermissionInfo(String name, int flags)1584     public PermissionInfo getPermissionInfo(String name, int flags) {
1585         // reader
1586         synchronized (mPackages) {
1587             final BasePermission p = mSettings.mPermissions.get(name);
1588             if (p != null) {
1589                 return generatePermissionInfo(p, flags);
1590             }
1591             return null;
1592         }
1593     }
1594 
queryPermissionsByGroup(String group, int flags)1595     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
1596         // reader
1597         synchronized (mPackages) {
1598             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
1599             for (BasePermission p : mSettings.mPermissions.values()) {
1600                 if (group == null) {
1601                     if (p.perm == null || p.perm.info.group == null) {
1602                         out.add(generatePermissionInfo(p, flags));
1603                     }
1604                 } else {
1605                     if (p.perm != null && group.equals(p.perm.info.group)) {
1606                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
1607                     }
1608                 }
1609             }
1610 
1611             if (out.size() > 0) {
1612                 return out;
1613             }
1614             return mPermissionGroups.containsKey(group) ? out : null;
1615         }
1616     }
1617 
getPermissionGroupInfo(String name, int flags)1618     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
1619         // reader
1620         synchronized (mPackages) {
1621             return PackageParser.generatePermissionGroupInfo(
1622                     mPermissionGroups.get(name), flags);
1623         }
1624     }
1625 
getAllPermissionGroups(int flags)1626     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1627         // reader
1628         synchronized (mPackages) {
1629             final int N = mPermissionGroups.size();
1630             ArrayList<PermissionGroupInfo> out
1631                     = new ArrayList<PermissionGroupInfo>(N);
1632             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
1633                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
1634             }
1635             return out;
1636         }
1637     }
1638 
generateApplicationInfoFromSettingsLPw(String packageName, int flags)1639     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags) {
1640         PackageSetting ps = mSettings.mPackages.get(packageName);
1641         if (ps != null) {
1642             if (ps.pkg == null) {
1643                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, flags);
1644                 if (pInfo != null) {
1645                     return pInfo.applicationInfo;
1646                 }
1647                 return null;
1648             }
1649             return PackageParser.generateApplicationInfo(ps.pkg, flags);
1650         }
1651         return null;
1652     }
1653 
generatePackageInfoFromSettingsLPw(String packageName, int flags)1654     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags) {
1655         PackageSetting ps = mSettings.mPackages.get(packageName);
1656         if (ps != null) {
1657             if (ps.pkg == null) {
1658                 ps.pkg = new PackageParser.Package(packageName);
1659                 ps.pkg.applicationInfo.packageName = packageName;
1660                 ps.pkg.applicationInfo.flags = ps.pkgFlags;
1661                 ps.pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
1662                 ps.pkg.applicationInfo.sourceDir = ps.codePathString;
1663                 ps.pkg.applicationInfo.dataDir =
1664                         getDataPathForPackage(ps.pkg.packageName, 0).getPath();
1665                 ps.pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
1666                 ps.pkg.mSetEnabled = ps.enabled;
1667                 ps.pkg.mSetStopped = ps.stopped;
1668             }
1669             return generatePackageInfo(ps.pkg, flags);
1670         }
1671         return null;
1672     }
1673 
getApplicationInfo(String packageName, int flags)1674     public ApplicationInfo getApplicationInfo(String packageName, int flags) {
1675         // writer
1676         synchronized (mPackages) {
1677             PackageParser.Package p = mPackages.get(packageName);
1678             if (DEBUG_PACKAGE_INFO) Log.v(
1679                     TAG, "getApplicationInfo " + packageName
1680                     + ": " + p);
1681             if (p != null) {
1682                 // Note: isEnabledLP() does not apply here - always return info
1683                 return PackageParser.generateApplicationInfo(p, flags);
1684             }
1685             if ("android".equals(packageName)||"system".equals(packageName)) {
1686                 return mAndroidApplication;
1687             }
1688             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
1689                 return generateApplicationInfoFromSettingsLPw(packageName, flags);
1690             }
1691         }
1692         return null;
1693     }
1694 
1695 
freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer)1696     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
1697         mContext.enforceCallingOrSelfPermission(
1698                 android.Manifest.permission.CLEAR_APP_CACHE, null);
1699         // Queue up an async operation since clearing cache may take a little while.
1700         mHandler.post(new Runnable() {
1701             public void run() {
1702                 mHandler.removeCallbacks(this);
1703                 int retCode = -1;
1704                 retCode = mInstaller.freeCache(freeStorageSize);
1705                 if (retCode < 0) {
1706                     Slog.w(TAG, "Couldn't clear application caches");
1707                 }
1708                 if (observer != null) {
1709                     try {
1710                         observer.onRemoveCompleted(null, (retCode >= 0));
1711                     } catch (RemoteException e) {
1712                         Slog.w(TAG, "RemoveException when invoking call back");
1713                     }
1714                 }
1715             }
1716         });
1717     }
1718 
freeStorage(final long freeStorageSize, final IntentSender pi)1719     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
1720         mContext.enforceCallingOrSelfPermission(
1721                 android.Manifest.permission.CLEAR_APP_CACHE, null);
1722         // Queue up an async operation since clearing cache may take a little while.
1723         mHandler.post(new Runnable() {
1724             public void run() {
1725                 mHandler.removeCallbacks(this);
1726                 int retCode = -1;
1727                 retCode = mInstaller.freeCache(freeStorageSize);
1728                 if (retCode < 0) {
1729                     Slog.w(TAG, "Couldn't clear application caches");
1730                 }
1731                 if(pi != null) {
1732                     try {
1733                         // Callback via pending intent
1734                         int code = (retCode >= 0) ? 1 : 0;
1735                         pi.sendIntent(null, code, null,
1736                                 null, null);
1737                     } catch (SendIntentException e1) {
1738                         Slog.i(TAG, "Failed to send pending intent");
1739                     }
1740                 }
1741             }
1742         });
1743     }
1744 
getActivityInfo(ComponentName component, int flags)1745     public ActivityInfo getActivityInfo(ComponentName component, int flags) {
1746         synchronized (mPackages) {
1747             PackageParser.Activity a = mActivities.mActivities.get(component);
1748 
1749             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
1750             if (a != null && mSettings.isEnabledLPr(a.info, flags)) {
1751                 return PackageParser.generateActivityInfo(a, flags);
1752             }
1753             if (mResolveComponentName.equals(component)) {
1754                 return mResolveActivity;
1755             }
1756         }
1757         return null;
1758     }
1759 
getReceiverInfo(ComponentName component, int flags)1760     public ActivityInfo getReceiverInfo(ComponentName component, int flags) {
1761         synchronized (mPackages) {
1762             PackageParser.Activity a = mReceivers.mActivities.get(component);
1763             if (DEBUG_PACKAGE_INFO) Log.v(
1764                 TAG, "getReceiverInfo " + component + ": " + a);
1765             if (a != null && mSettings.isEnabledLPr(a.info, flags)) {
1766                 return PackageParser.generateActivityInfo(a, flags);
1767             }
1768         }
1769         return null;
1770     }
1771 
getServiceInfo(ComponentName component, int flags)1772     public ServiceInfo getServiceInfo(ComponentName component, int flags) {
1773         synchronized (mPackages) {
1774             PackageParser.Service s = mServices.mServices.get(component);
1775             if (DEBUG_PACKAGE_INFO) Log.v(
1776                 TAG, "getServiceInfo " + component + ": " + s);
1777             if (s != null && mSettings.isEnabledLPr(s.info, flags)) {
1778                 return PackageParser.generateServiceInfo(s, flags);
1779             }
1780         }
1781         return null;
1782     }
1783 
getProviderInfo(ComponentName component, int flags)1784     public ProviderInfo getProviderInfo(ComponentName component, int flags) {
1785         synchronized (mPackages) {
1786             PackageParser.Provider p = mProvidersByComponent.get(component);
1787             if (DEBUG_PACKAGE_INFO) Log.v(
1788                 TAG, "getProviderInfo " + component + ": " + p);
1789             if (p != null && mSettings.isEnabledLPr(p.info, flags)) {
1790                 return PackageParser.generateProviderInfo(p, flags);
1791             }
1792         }
1793         return null;
1794     }
1795 
getSystemSharedLibraryNames()1796     public String[] getSystemSharedLibraryNames() {
1797         Set<String> libSet;
1798         synchronized (mPackages) {
1799             libSet = mSharedLibraries.keySet();
1800             int size = libSet.size();
1801             if (size > 0) {
1802                 String[] libs = new String[size];
1803                 libSet.toArray(libs);
1804                 return libs;
1805             }
1806         }
1807         return null;
1808     }
1809 
getSystemAvailableFeatures()1810     public FeatureInfo[] getSystemAvailableFeatures() {
1811         Collection<FeatureInfo> featSet;
1812         synchronized (mPackages) {
1813             featSet = mAvailableFeatures.values();
1814             int size = featSet.size();
1815             if (size > 0) {
1816                 FeatureInfo[] features = new FeatureInfo[size+1];
1817                 featSet.toArray(features);
1818                 FeatureInfo fi = new FeatureInfo();
1819                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
1820                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
1821                 features[size] = fi;
1822                 return features;
1823             }
1824         }
1825         return null;
1826     }
1827 
hasSystemFeature(String name)1828     public boolean hasSystemFeature(String name) {
1829         synchronized (mPackages) {
1830             return mAvailableFeatures.containsKey(name);
1831         }
1832     }
1833 
checkPermission(String permName, String pkgName)1834     public int checkPermission(String permName, String pkgName) {
1835         synchronized (mPackages) {
1836             PackageParser.Package p = mPackages.get(pkgName);
1837             if (p != null && p.mExtras != null) {
1838                 PackageSetting ps = (PackageSetting)p.mExtras;
1839                 if (ps.sharedUser != null) {
1840                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
1841                         return PackageManager.PERMISSION_GRANTED;
1842                     }
1843                 } else if (ps.grantedPermissions.contains(permName)) {
1844                     return PackageManager.PERMISSION_GRANTED;
1845                 }
1846             }
1847         }
1848         return PackageManager.PERMISSION_DENIED;
1849     }
1850 
checkUidPermission(String permName, int uid)1851     public int checkUidPermission(String permName, int uid) {
1852         synchronized (mPackages) {
1853             Object obj = mSettings.getUserIdLPr(uid);
1854             if (obj != null) {
1855                 GrantedPermissions gp = (GrantedPermissions)obj;
1856                 if (gp.grantedPermissions.contains(permName)) {
1857                     return PackageManager.PERMISSION_GRANTED;
1858                 }
1859             } else {
1860                 HashSet<String> perms = mSystemPermissions.get(uid);
1861                 if (perms != null && perms.contains(permName)) {
1862                     return PackageManager.PERMISSION_GRANTED;
1863                 }
1864             }
1865         }
1866         return PackageManager.PERMISSION_DENIED;
1867     }
1868 
findPermissionTreeLP(String permName)1869     private BasePermission findPermissionTreeLP(String permName) {
1870         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
1871             if (permName.startsWith(bp.name) &&
1872                     permName.length() > bp.name.length() &&
1873                     permName.charAt(bp.name.length()) == '.') {
1874                 return bp;
1875             }
1876         }
1877         return null;
1878     }
1879 
checkPermissionTreeLP(String permName)1880     private BasePermission checkPermissionTreeLP(String permName) {
1881         if (permName != null) {
1882             BasePermission bp = findPermissionTreeLP(permName);
1883             if (bp != null) {
1884                 if (bp.uid == Binder.getCallingUid()) {
1885                     return bp;
1886                 }
1887                 throw new SecurityException("Calling uid "
1888                         + Binder.getCallingUid()
1889                         + " is not allowed to add to permission tree "
1890                         + bp.name + " owned by uid " + bp.uid);
1891             }
1892         }
1893         throw new SecurityException("No permission tree found for " + permName);
1894     }
1895 
compareStrings(CharSequence s1, CharSequence s2)1896     static boolean compareStrings(CharSequence s1, CharSequence s2) {
1897         if (s1 == null) {
1898             return s2 == null;
1899         }
1900         if (s2 == null) {
1901             return false;
1902         }
1903         if (s1.getClass() != s2.getClass()) {
1904             return false;
1905         }
1906         return s1.equals(s2);
1907     }
1908 
comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2)1909     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
1910         if (pi1.icon != pi2.icon) return false;
1911         if (pi1.logo != pi2.logo) return false;
1912         if (pi1.protectionLevel != pi2.protectionLevel) return false;
1913         if (!compareStrings(pi1.name, pi2.name)) return false;
1914         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
1915         // We'll take care of setting this one.
1916         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
1917         // These are not currently stored in settings.
1918         //if (!compareStrings(pi1.group, pi2.group)) return false;
1919         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
1920         //if (pi1.labelRes != pi2.labelRes) return false;
1921         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
1922         return true;
1923     }
1924 
addPermissionLocked(PermissionInfo info, boolean async)1925     boolean addPermissionLocked(PermissionInfo info, boolean async) {
1926         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
1927             throw new SecurityException("Label must be specified in permission");
1928         }
1929         BasePermission tree = checkPermissionTreeLP(info.name);
1930         BasePermission bp = mSettings.mPermissions.get(info.name);
1931         boolean added = bp == null;
1932         boolean changed = true;
1933         if (added) {
1934             bp = new BasePermission(info.name, tree.sourcePackage,
1935                     BasePermission.TYPE_DYNAMIC);
1936         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
1937             throw new SecurityException(
1938                     "Not allowed to modify non-dynamic permission "
1939                     + info.name);
1940         } else {
1941             if (bp.protectionLevel == info.protectionLevel
1942                     && bp.perm.owner.equals(tree.perm.owner)
1943                     && bp.uid == tree.uid
1944                     && comparePermissionInfos(bp.perm.info, info)) {
1945                 changed = false;
1946             }
1947         }
1948         bp.protectionLevel = info.protectionLevel;
1949         bp.perm = new PackageParser.Permission(tree.perm.owner,
1950                 new PermissionInfo(info));
1951         bp.perm.info.packageName = tree.perm.info.packageName;
1952         bp.uid = tree.uid;
1953         if (added) {
1954             mSettings.mPermissions.put(info.name, bp);
1955         }
1956         if (changed) {
1957             if (!async) {
1958                 mSettings.writeLPr();
1959             } else {
1960                 scheduleWriteSettingsLocked();
1961             }
1962         }
1963         return added;
1964     }
1965 
addPermission(PermissionInfo info)1966     public boolean addPermission(PermissionInfo info) {
1967         synchronized (mPackages) {
1968             return addPermissionLocked(info, false);
1969         }
1970     }
1971 
addPermissionAsync(PermissionInfo info)1972     public boolean addPermissionAsync(PermissionInfo info) {
1973         synchronized (mPackages) {
1974             return addPermissionLocked(info, true);
1975         }
1976     }
1977 
removePermission(String name)1978     public void removePermission(String name) {
1979         synchronized (mPackages) {
1980             checkPermissionTreeLP(name);
1981             BasePermission bp = mSettings.mPermissions.get(name);
1982             if (bp != null) {
1983                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
1984                     throw new SecurityException(
1985                             "Not allowed to modify non-dynamic permission "
1986                             + name);
1987                 }
1988                 mSettings.mPermissions.remove(name);
1989                 mSettings.writeLPr();
1990             }
1991         }
1992     }
1993 
isProtectedBroadcast(String actionName)1994     public boolean isProtectedBroadcast(String actionName) {
1995         synchronized (mPackages) {
1996             return mProtectedBroadcasts.contains(actionName);
1997         }
1998     }
1999 
checkSignatures(String pkg1, String pkg2)2000     public int checkSignatures(String pkg1, String pkg2) {
2001         synchronized (mPackages) {
2002             final PackageParser.Package p1 = mPackages.get(pkg1);
2003             final PackageParser.Package p2 = mPackages.get(pkg2);
2004             if (p1 == null || p1.mExtras == null
2005                     || p2 == null || p2.mExtras == null) {
2006                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2007             }
2008             return compareSignatures(p1.mSignatures, p2.mSignatures);
2009         }
2010     }
2011 
checkUidSignatures(int uid1, int uid2)2012     public int checkUidSignatures(int uid1, int uid2) {
2013         // reader
2014         synchronized (mPackages) {
2015             Signature[] s1;
2016             Signature[] s2;
2017             Object obj = mSettings.getUserIdLPr(uid1);
2018             if (obj != null) {
2019                 if (obj instanceof SharedUserSetting) {
2020                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
2021                 } else if (obj instanceof PackageSetting) {
2022                     s1 = ((PackageSetting)obj).signatures.mSignatures;
2023                 } else {
2024                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2025                 }
2026             } else {
2027                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2028             }
2029             obj = mSettings.getUserIdLPr(uid2);
2030             if (obj != null) {
2031                 if (obj instanceof SharedUserSetting) {
2032                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
2033                 } else if (obj instanceof PackageSetting) {
2034                     s2 = ((PackageSetting)obj).signatures.mSignatures;
2035                 } else {
2036                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2037                 }
2038             } else {
2039                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
2040             }
2041             return compareSignatures(s1, s2);
2042         }
2043     }
2044 
compareSignatures(Signature[] s1, Signature[] s2)2045     static int compareSignatures(Signature[] s1, Signature[] s2) {
2046         if (s1 == null) {
2047             return s2 == null
2048                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
2049                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
2050         }
2051         if (s2 == null) {
2052             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
2053         }
2054         HashSet<Signature> set1 = new HashSet<Signature>();
2055         for (Signature sig : s1) {
2056             set1.add(sig);
2057         }
2058         HashSet<Signature> set2 = new HashSet<Signature>();
2059         for (Signature sig : s2) {
2060             set2.add(sig);
2061         }
2062         // Make sure s2 contains all signatures in s1.
2063         if (set1.equals(set2)) {
2064             return PackageManager.SIGNATURE_MATCH;
2065         }
2066         return PackageManager.SIGNATURE_NO_MATCH;
2067     }
2068 
getPackagesForUid(int uid)2069     public String[] getPackagesForUid(int uid) {
2070         // reader
2071         synchronized (mPackages) {
2072             Object obj = mSettings.getUserIdLPr(uid);
2073             if (obj instanceof SharedUserSetting) {
2074                 final SharedUserSetting sus = (SharedUserSetting) obj;
2075                 final int N = sus.packages.size();
2076                 final String[] res = new String[N];
2077                 final Iterator<PackageSetting> it = sus.packages.iterator();
2078                 int i = 0;
2079                 while (it.hasNext()) {
2080                     res[i++] = it.next().name;
2081                 }
2082                 return res;
2083             } else if (obj instanceof PackageSetting) {
2084                 final PackageSetting ps = (PackageSetting) obj;
2085                 return new String[] { ps.name };
2086             }
2087         }
2088         return null;
2089     }
2090 
getNameForUid(int uid)2091     public String getNameForUid(int uid) {
2092         // reader
2093         synchronized (mPackages) {
2094             Object obj = mSettings.getUserIdLPr(uid);
2095             if (obj instanceof SharedUserSetting) {
2096                 final SharedUserSetting sus = (SharedUserSetting) obj;
2097                 return sus.name + ":" + sus.userId;
2098             } else if (obj instanceof PackageSetting) {
2099                 final PackageSetting ps = (PackageSetting) obj;
2100                 return ps.name;
2101             }
2102         }
2103         return null;
2104     }
2105 
getUidForSharedUser(String sharedUserName)2106     public int getUidForSharedUser(String sharedUserName) {
2107         if(sharedUserName == null) {
2108             return -1;
2109         }
2110         // reader
2111         synchronized (mPackages) {
2112             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
2113             if(suid == null) {
2114                 return -1;
2115             }
2116             return suid.userId;
2117         }
2118     }
2119 
resolveIntent(Intent intent, String resolvedType, int flags)2120     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
2121             int flags) {
2122         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags);
2123         return chooseBestActivity(intent, resolvedType, flags, query);
2124     }
2125 
chooseBestActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query)2126     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
2127                                            int flags, List<ResolveInfo> query) {
2128         if (query != null) {
2129             final int N = query.size();
2130             if (N == 1) {
2131                 return query.get(0);
2132             } else if (N > 1) {
2133                 // If there is more than one activity with the same priority,
2134                 // then let the user decide between them.
2135                 ResolveInfo r0 = query.get(0);
2136                 ResolveInfo r1 = query.get(1);
2137                 if (DEBUG_INTENT_MATCHING) {
2138                     Log.d(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
2139                             + r1.activityInfo.name + "=" + r1.priority);
2140                 }
2141                 // If the first activity has a higher priority, or a different
2142                 // default, then it is always desireable to pick it.
2143                 if (r0.priority != r1.priority
2144                         || r0.preferredOrder != r1.preferredOrder
2145                         || r0.isDefault != r1.isDefault) {
2146                     return query.get(0);
2147                 }
2148                 // If we have saved a preference for a preferred activity for
2149                 // this Intent, use that.
2150                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
2151                         flags, query, r0.priority);
2152                 if (ri != null) {
2153                     return ri;
2154                 }
2155                 return mResolveInfo;
2156             }
2157         }
2158         return null;
2159     }
2160 
findPreferredActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority)2161     ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
2162             int flags, List<ResolveInfo> query, int priority) {
2163         // writer
2164         synchronized (mPackages) {
2165             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
2166             List<PreferredActivity> prefs =
2167                     mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
2168                             (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
2169             if (prefs != null && prefs.size() > 0) {
2170                 // First figure out how good the original match set is.
2171                 // We will only allow preferred activities that came
2172                 // from the same match quality.
2173                 int match = 0;
2174 
2175                 if (DEBUG_PREFERRED) {
2176                     Log.v(TAG, "Figuring out best match...");
2177                 }
2178 
2179                 final int N = query.size();
2180                 for (int j=0; j<N; j++) {
2181                     final ResolveInfo ri = query.get(j);
2182                     if (DEBUG_PREFERRED) {
2183                         Log.v(TAG, "Match for " + ri.activityInfo + ": 0x"
2184                                 + Integer.toHexString(match));
2185                     }
2186                     if (ri.match > match) {
2187                         match = ri.match;
2188                     }
2189                 }
2190 
2191                 if (DEBUG_PREFERRED) {
2192                     Log.v(TAG, "Best match: 0x" + Integer.toHexString(match));
2193                 }
2194 
2195                 match &= IntentFilter.MATCH_CATEGORY_MASK;
2196                 final int M = prefs.size();
2197                 for (int i=0; i<M; i++) {
2198                     final PreferredActivity pa = prefs.get(i);
2199                     if (pa.mPref.mMatch != match) {
2200                         continue;
2201                     }
2202                     final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags);
2203                     if (DEBUG_PREFERRED) {
2204                         Log.v(TAG, "Got preferred activity:");
2205                         if (ai != null) {
2206                             ai.dump(new LogPrinter(Log.VERBOSE, TAG), "  ");
2207                         } else {
2208                             Log.v(TAG, "  null");
2209                         }
2210                     }
2211                     if (ai != null) {
2212                         for (int j=0; j<N; j++) {
2213                             final ResolveInfo ri = query.get(j);
2214                             if (!ri.activityInfo.applicationInfo.packageName
2215                                     .equals(ai.applicationInfo.packageName)) {
2216                                 continue;
2217                             }
2218                             if (!ri.activityInfo.name.equals(ai.name)) {
2219                                 continue;
2220                             }
2221 
2222                             // Okay we found a previously set preferred app.
2223                             // If the result set is different from when this
2224                             // was created, we need to clear it and re-ask the
2225                             // user their preference.
2226                             if (!pa.mPref.sameSet(query, priority)) {
2227                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
2228                                         + intent + " type " + resolvedType);
2229                                 mSettings.mPreferredActivities.removeFilter(pa);
2230                                 return null;
2231                             }
2232 
2233                             // Yay!
2234                             return ri;
2235                         }
2236                     }
2237                 }
2238             }
2239         }
2240         return null;
2241     }
2242 
queryIntentActivities(Intent intent, String resolvedType, int flags)2243     public List<ResolveInfo> queryIntentActivities(Intent intent,
2244             String resolvedType, int flags) {
2245         final ComponentName comp = intent.getComponent();
2246         if (comp != null) {
2247             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2248             final ActivityInfo ai = getActivityInfo(comp, flags);
2249             if (ai != null) {
2250                 final ResolveInfo ri = new ResolveInfo();
2251                 ri.activityInfo = ai;
2252                 list.add(ri);
2253             }
2254             return list;
2255         }
2256 
2257         // reader
2258         synchronized (mPackages) {
2259             final String pkgName = intent.getPackage();
2260             if (pkgName == null) {
2261                 return mActivities.queryIntent(intent, resolvedType, flags);
2262             }
2263             final PackageParser.Package pkg = mPackages.get(pkgName);
2264             if (pkg != null) {
2265                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
2266                         pkg.activities);
2267             }
2268             return new ArrayList<ResolveInfo>();
2269         }
2270     }
2271 
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags)2272     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
2273             Intent[] specifics, String[] specificTypes, Intent intent,
2274             String resolvedType, int flags) {
2275         final String resultsAction = intent.getAction();
2276 
2277         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
2278                 | PackageManager.GET_RESOLVED_FILTER);
2279 
2280         if (DEBUG_INTENT_MATCHING) {
2281             Log.v(TAG, "Query " + intent + ": " + results);
2282         }
2283 
2284         int specificsPos = 0;
2285         int N;
2286 
2287         // todo: note that the algorithm used here is O(N^2).  This
2288         // isn't a problem in our current environment, but if we start running
2289         // into situations where we have more than 5 or 10 matches then this
2290         // should probably be changed to something smarter...
2291 
2292         // First we go through and resolve each of the specific items
2293         // that were supplied, taking care of removing any corresponding
2294         // duplicate items in the generic resolve list.
2295         if (specifics != null) {
2296             for (int i=0; i<specifics.length; i++) {
2297                 final Intent sintent = specifics[i];
2298                 if (sintent == null) {
2299                     continue;
2300                 }
2301 
2302                 if (DEBUG_INTENT_MATCHING) {
2303                     Log.v(TAG, "Specific #" + i + ": " + sintent);
2304                 }
2305 
2306                 String action = sintent.getAction();
2307                 if (resultsAction != null && resultsAction.equals(action)) {
2308                     // If this action was explicitly requested, then don't
2309                     // remove things that have it.
2310                     action = null;
2311                 }
2312 
2313                 ResolveInfo ri = null;
2314                 ActivityInfo ai = null;
2315 
2316                 ComponentName comp = sintent.getComponent();
2317                 if (comp == null) {
2318                     ri = resolveIntent(
2319                         sintent,
2320                         specificTypes != null ? specificTypes[i] : null,
2321                         flags);
2322                     if (ri == null) {
2323                         continue;
2324                     }
2325                     if (ri == mResolveInfo) {
2326                         // ACK!  Must do something better with this.
2327                     }
2328                     ai = ri.activityInfo;
2329                     comp = new ComponentName(ai.applicationInfo.packageName,
2330                             ai.name);
2331                 } else {
2332                     ai = getActivityInfo(comp, flags);
2333                     if (ai == null) {
2334                         continue;
2335                     }
2336                 }
2337 
2338                 // Look for any generic query activities that are duplicates
2339                 // of this specific one, and remove them from the results.
2340                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
2341                 N = results.size();
2342                 int j;
2343                 for (j=specificsPos; j<N; j++) {
2344                     ResolveInfo sri = results.get(j);
2345                     if ((sri.activityInfo.name.equals(comp.getClassName())
2346                             && sri.activityInfo.applicationInfo.packageName.equals(
2347                                     comp.getPackageName()))
2348                         || (action != null && sri.filter.matchAction(action))) {
2349                         results.remove(j);
2350                         if (DEBUG_INTENT_MATCHING) Log.v(
2351                             TAG, "Removing duplicate item from " + j
2352                             + " due to specific " + specificsPos);
2353                         if (ri == null) {
2354                             ri = sri;
2355                         }
2356                         j--;
2357                         N--;
2358                     }
2359                 }
2360 
2361                 // Add this specific item to its proper place.
2362                 if (ri == null) {
2363                     ri = new ResolveInfo();
2364                     ri.activityInfo = ai;
2365                 }
2366                 results.add(specificsPos, ri);
2367                 ri.specificIndex = i;
2368                 specificsPos++;
2369             }
2370         }
2371 
2372         // Now we go through the remaining generic results and remove any
2373         // duplicate actions that are found here.
2374         N = results.size();
2375         for (int i=specificsPos; i<N-1; i++) {
2376             final ResolveInfo rii = results.get(i);
2377             if (rii.filter == null) {
2378                 continue;
2379             }
2380 
2381             // Iterate over all of the actions of this result's intent
2382             // filter...  typically this should be just one.
2383             final Iterator<String> it = rii.filter.actionsIterator();
2384             if (it == null) {
2385                 continue;
2386             }
2387             while (it.hasNext()) {
2388                 final String action = it.next();
2389                 if (resultsAction != null && resultsAction.equals(action)) {
2390                     // If this action was explicitly requested, then don't
2391                     // remove things that have it.
2392                     continue;
2393                 }
2394                 for (int j=i+1; j<N; j++) {
2395                     final ResolveInfo rij = results.get(j);
2396                     if (rij.filter != null && rij.filter.hasAction(action)) {
2397                         results.remove(j);
2398                         if (DEBUG_INTENT_MATCHING) Log.v(
2399                             TAG, "Removing duplicate item from " + j
2400                             + " due to action " + action + " at " + i);
2401                         j--;
2402                         N--;
2403                     }
2404                 }
2405             }
2406 
2407             // If the caller didn't request filter information, drop it now
2408             // so we don't have to marshall/unmarshall it.
2409             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
2410                 rii.filter = null;
2411             }
2412         }
2413 
2414         // Filter out the caller activity if so requested.
2415         if (caller != null) {
2416             N = results.size();
2417             for (int i=0; i<N; i++) {
2418                 ActivityInfo ainfo = results.get(i).activityInfo;
2419                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
2420                         && caller.getClassName().equals(ainfo.name)) {
2421                     results.remove(i);
2422                     break;
2423                 }
2424             }
2425         }
2426 
2427         // If the caller didn't request filter information,
2428         // drop them now so we don't have to
2429         // marshall/unmarshall it.
2430         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
2431             N = results.size();
2432             for (int i=0; i<N; i++) {
2433                 results.get(i).filter = null;
2434             }
2435         }
2436 
2437         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
2438         return results;
2439     }
2440 
queryIntentReceivers(Intent intent, String resolvedType, int flags)2441     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags) {
2442         ComponentName comp = intent.getComponent();
2443         if (comp != null) {
2444             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2445             ActivityInfo ai = getReceiverInfo(comp, flags);
2446             if (ai != null) {
2447                 ResolveInfo ri = new ResolveInfo();
2448                 ri.activityInfo = ai;
2449                 list.add(ri);
2450             }
2451             return list;
2452         }
2453 
2454         // reader
2455         synchronized (mPackages) {
2456             String pkgName = intent.getPackage();
2457             if (pkgName == null) {
2458                 return mReceivers.queryIntent(intent, resolvedType, flags);
2459             }
2460             final PackageParser.Package pkg = mPackages.get(pkgName);
2461             if (pkg != null) {
2462                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers);
2463             }
2464             return null;
2465         }
2466     }
2467 
resolveService(Intent intent, String resolvedType, int flags)2468     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags) {
2469         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags);
2470         if (query != null) {
2471             if (query.size() >= 1) {
2472                 // If there is more than one service with the same priority,
2473                 // just arbitrarily pick the first one.
2474                 return query.get(0);
2475             }
2476         }
2477         return null;
2478     }
2479 
queryIntentServices(Intent intent, String resolvedType, int flags)2480     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags) {
2481         final ComponentName comp = intent.getComponent();
2482         if (comp != null) {
2483             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
2484             final ServiceInfo si = getServiceInfo(comp, flags);
2485             if (si != null) {
2486                 final ResolveInfo ri = new ResolveInfo();
2487                 ri.serviceInfo = si;
2488                 list.add(ri);
2489             }
2490             return list;
2491         }
2492 
2493         // reader
2494         synchronized (mPackages) {
2495             String pkgName = intent.getPackage();
2496             if (pkgName == null) {
2497                 return mServices.queryIntent(intent, resolvedType, flags);
2498             }
2499             final PackageParser.Package pkg = mPackages.get(pkgName);
2500             if (pkg != null) {
2501                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services);
2502             }
2503             return null;
2504         }
2505     }
2506 
getContinuationPoint(final String[] keys, final String key)2507     private static final int getContinuationPoint(final String[] keys, final String key) {
2508         final int index;
2509         if (key == null) {
2510             index = 0;
2511         } else {
2512             final int insertPoint = Arrays.binarySearch(keys, key);
2513             if (insertPoint < 0) {
2514                 index = -insertPoint;
2515             } else {
2516                 index = insertPoint + 1;
2517             }
2518         }
2519         return index;
2520     }
2521 
getInstalledPackages(int flags, String lastRead)2522     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead) {
2523         final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
2524         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
2525         final String[] keys;
2526 
2527         // writer
2528         synchronized (mPackages) {
2529             if (listUninstalled) {
2530                 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
2531             } else {
2532                 keys = mPackages.keySet().toArray(new String[mPackages.size()]);
2533             }
2534 
2535             Arrays.sort(keys);
2536             int i = getContinuationPoint(keys, lastRead);
2537             final int N = keys.length;
2538 
2539             while (i < N) {
2540                 final String packageName = keys[i++];
2541 
2542                 PackageInfo pi = null;
2543                 if (listUninstalled) {
2544                     final PackageSetting ps = mSettings.mPackages.get(packageName);
2545                     if (ps != null) {
2546                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags);
2547                     }
2548                 } else {
2549                     final PackageParser.Package p = mPackages.get(packageName);
2550                     if (p != null) {
2551                         pi = generatePackageInfo(p, flags);
2552                     }
2553                 }
2554 
2555                 if (pi != null && !list.append(pi)) {
2556                     break;
2557                 }
2558             }
2559 
2560             if (i == N) {
2561                 list.setLastSlice(true);
2562             }
2563         }
2564 
2565         return list;
2566     }
2567 
getInstalledApplications(int flags, String lastRead)2568     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
2569             String lastRead) {
2570         final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>();
2571         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
2572         final String[] keys;
2573 
2574         // writer
2575         synchronized (mPackages) {
2576             if (listUninstalled) {
2577                 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
2578             } else {
2579                 keys = mPackages.keySet().toArray(new String[mPackages.size()]);
2580             }
2581 
2582             Arrays.sort(keys);
2583             int i = getContinuationPoint(keys, lastRead);
2584             final int N = keys.length;
2585 
2586             while (i < N) {
2587                 final String packageName = keys[i++];
2588 
2589                 ApplicationInfo ai = null;
2590                 if (listUninstalled) {
2591                     final PackageSetting ps = mSettings.mPackages.get(packageName);
2592                     if (ps != null) {
2593                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags);
2594                     }
2595                 } else {
2596                     final PackageParser.Package p = mPackages.get(packageName);
2597                     if (p != null) {
2598                         ai = PackageParser.generateApplicationInfo(p, flags);
2599                     }
2600                 }
2601 
2602                 if (ai != null && !list.append(ai)) {
2603                     break;
2604                 }
2605             }
2606 
2607             if (i == N) {
2608                 list.setLastSlice(true);
2609             }
2610         }
2611 
2612         return list;
2613     }
2614 
getPersistentApplications(int flags)2615     public List<ApplicationInfo> getPersistentApplications(int flags) {
2616         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
2617 
2618         // reader
2619         synchronized (mPackages) {
2620             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
2621             while (i.hasNext()) {
2622                 final PackageParser.Package p = i.next();
2623                 if (p.applicationInfo != null
2624                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
2625                         && (!mSafeMode || isSystemApp(p))) {
2626                     finalList.add(PackageParser.generateApplicationInfo(p, flags));
2627                 }
2628             }
2629         }
2630 
2631         return finalList;
2632     }
2633 
resolveContentProvider(String name, int flags)2634     public ProviderInfo resolveContentProvider(String name, int flags) {
2635         // reader
2636         synchronized (mPackages) {
2637             final PackageParser.Provider provider = mProviders.get(name);
2638             return provider != null
2639                     && mSettings.isEnabledLPr(provider.info, flags)
2640                     && (!mSafeMode || (provider.info.applicationInfo.flags
2641                             &ApplicationInfo.FLAG_SYSTEM) != 0)
2642                     ? PackageParser.generateProviderInfo(provider, flags)
2643                     : null;
2644         }
2645     }
2646 
2647     /**
2648      * @deprecated
2649      */
2650     @Deprecated
querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)2651     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
2652         // reader
2653         synchronized (mPackages) {
2654             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet()
2655                     .iterator();
2656 
2657             while (i.hasNext()) {
2658                 Map.Entry<String, PackageParser.Provider> entry = i.next();
2659                 PackageParser.Provider p = entry.getValue();
2660 
2661                 if (p.syncable
2662                         && (!mSafeMode || (p.info.applicationInfo.flags
2663                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
2664                     outNames.add(entry.getKey());
2665                     outInfo.add(PackageParser.generateProviderInfo(p, 0));
2666                 }
2667             }
2668         }
2669     }
2670 
queryContentProviders(String processName, int uid, int flags)2671     public List<ProviderInfo> queryContentProviders(String processName,
2672             int uid, int flags) {
2673         ArrayList<ProviderInfo> finalList = null;
2674 
2675         // reader
2676         synchronized (mPackages) {
2677             final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
2678             while (i.hasNext()) {
2679                 final PackageParser.Provider p = i.next();
2680                 if (p.info.authority != null
2681                         && (processName == null
2682                                 || (p.info.processName.equals(processName)
2683                                         && p.info.applicationInfo.uid == uid))
2684                         && mSettings.isEnabledLPr(p.info, flags)
2685                         && (!mSafeMode
2686                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
2687                     if (finalList == null) {
2688                         finalList = new ArrayList<ProviderInfo>(3);
2689                     }
2690                     finalList.add(PackageParser.generateProviderInfo(p, flags));
2691                 }
2692             }
2693         }
2694 
2695         if (finalList != null) {
2696             Collections.sort(finalList, mProviderInitOrderSorter);
2697         }
2698 
2699         return finalList;
2700     }
2701 
getInstrumentationInfo(ComponentName name, int flags)2702     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
2703             int flags) {
2704         // reader
2705         synchronized (mPackages) {
2706             final PackageParser.Instrumentation i = mInstrumentation.get(name);
2707             return PackageParser.generateInstrumentationInfo(i, flags);
2708         }
2709     }
2710 
queryInstrumentation(String targetPackage, int flags)2711     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
2712             int flags) {
2713         ArrayList<InstrumentationInfo> finalList =
2714             new ArrayList<InstrumentationInfo>();
2715 
2716         // reader
2717         synchronized (mPackages) {
2718             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
2719             while (i.hasNext()) {
2720                 final PackageParser.Instrumentation p = i.next();
2721                 if (targetPackage == null
2722                         || targetPackage.equals(p.info.targetPackage)) {
2723                     finalList.add(PackageParser.generateInstrumentationInfo(p,
2724                             flags));
2725                 }
2726             }
2727         }
2728 
2729         return finalList;
2730     }
2731 
scanDirLI(File dir, int flags, int scanMode, long currentTime)2732     private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
2733         String[] files = dir.list();
2734         if (files == null) {
2735             Log.d(TAG, "No files in app dir " + dir);
2736             return;
2737         }
2738 
2739         if (DEBUG_PACKAGE_SCANNING) {
2740             Log.d(TAG, "Scanning app dir " + dir);
2741         }
2742 
2743         int i;
2744         for (i=0; i<files.length; i++) {
2745             File file = new File(dir, files[i]);
2746             if (!isPackageFilename(files[i])) {
2747                 // Ignore entries which are not apk's
2748                 continue;
2749             }
2750             PackageParser.Package pkg = scanPackageLI(file,
2751                     flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);
2752             // Don't mess around with apps in system partition.
2753             if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
2754                     mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
2755                 // Delete the apk
2756                 Slog.w(TAG, "Cleaning up failed install of " + file);
2757                 file.delete();
2758             }
2759         }
2760     }
2761 
getSettingsProblemFile()2762     private static File getSettingsProblemFile() {
2763         File dataDir = Environment.getDataDirectory();
2764         File systemDir = new File(dataDir, "system");
2765         File fname = new File(systemDir, "uiderrors.txt");
2766         return fname;
2767     }
2768 
reportSettingsProblem(int priority, String msg)2769     static void reportSettingsProblem(int priority, String msg) {
2770         try {
2771             File fname = getSettingsProblemFile();
2772             FileOutputStream out = new FileOutputStream(fname, true);
2773             PrintWriter pw = new PrintWriter(out);
2774             SimpleDateFormat formatter = new SimpleDateFormat();
2775             String dateString = formatter.format(new Date(System.currentTimeMillis()));
2776             pw.println(dateString + ": " + msg);
2777             pw.close();
2778             FileUtils.setPermissions(
2779                     fname.toString(),
2780                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
2781                     -1, -1);
2782         } catch (java.io.IOException e) {
2783         }
2784         Slog.println(priority, TAG, msg);
2785     }
2786 
collectCertificatesLI(PackageParser pp, PackageSetting ps, PackageParser.Package pkg, File srcFile, int parseFlags)2787     private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
2788             PackageParser.Package pkg, File srcFile, int parseFlags) {
2789         if (GET_CERTIFICATES) {
2790             if (ps != null
2791                     && ps.codePath.equals(srcFile)
2792                     && ps.timeStamp == srcFile.lastModified()) {
2793                 if (ps.signatures.mSignatures != null
2794                         && ps.signatures.mSignatures.length != 0) {
2795                     // Optimization: reuse the existing cached certificates
2796                     // if the package appears to be unchanged.
2797                     pkg.mSignatures = ps.signatures.mSignatures;
2798                     return true;
2799                 }
2800 
2801                 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures.  Collecting certs again to recover them.");
2802             } else {
2803                 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
2804             }
2805 
2806             if (!pp.collectCertificates(pkg, parseFlags)) {
2807                 mLastScanError = pp.getParseError();
2808                 return false;
2809             }
2810         }
2811         return true;
2812     }
2813 
2814     /*
2815      *  Scan a package and return the newly parsed package.
2816      *  Returns null in case of errors and the error code is stored in mLastScanError
2817      */
scanPackageLI(File scanFile, int parseFlags, int scanMode, long currentTime)2818     private PackageParser.Package scanPackageLI(File scanFile,
2819             int parseFlags, int scanMode, long currentTime) {
2820         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
2821         String scanPath = scanFile.getPath();
2822         parseFlags |= mDefParseFlags;
2823         PackageParser pp = new PackageParser(scanPath);
2824         pp.setSeparateProcesses(mSeparateProcesses);
2825         pp.setOnlyCoreApps(mOnlyCore);
2826         final PackageParser.Package pkg = pp.parsePackage(scanFile,
2827                 scanPath, mMetrics, parseFlags);
2828         if (pkg == null) {
2829             mLastScanError = pp.getParseError();
2830             return null;
2831         }
2832         PackageSetting ps = null;
2833         PackageSetting updatedPkg;
2834         // reader
2835         synchronized (mPackages) {
2836             // Look to see if we already know about this package.
2837             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
2838             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
2839                 // This package has been renamed to its original name.  Let's
2840                 // use that.
2841                 ps = mSettings.peekPackageLPr(oldName);
2842             }
2843             // If there was no original package, see one for the real package name.
2844             if (ps == null) {
2845                 ps = mSettings.peekPackageLPr(pkg.packageName);
2846             }
2847             // Check to see if this package could be hiding/updating a system
2848             // package.  Must look for it either under the original or real
2849             // package name depending on our state.
2850             updatedPkg = mSettings.mDisabledSysPackages.get(
2851                     ps != null ? ps.name : pkg.packageName);
2852         }
2853         // First check if this is a system package that may involve an update
2854         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
2855             if (ps != null && !ps.codePath.equals(scanFile)) {
2856                 // The path has changed from what was last scanned...  check the
2857                 // version of the new path against what we have stored to determine
2858                 // what to do.
2859                 if (pkg.mVersionCode < ps.versionCode) {
2860                     // The system package has been updated and the code path does not match
2861                     // Ignore entry. Skip it.
2862                     Log.i(TAG, "Package " + ps.name + " at " + scanFile
2863                             + " ignored: updated version " + ps.versionCode
2864                             + " better than this " + pkg.mVersionCode);
2865                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
2866                     return null;
2867                 } else {
2868                     // The current app on the system partion is better than
2869                     // what we have updated to on the data partition; switch
2870                     // back to the system partition version.
2871                     // At this point, its safely assumed that package installation for
2872                     // apps in system partition will go through. If not there won't be a working
2873                     // version of the app
2874                     // writer
2875                     synchronized (mPackages) {
2876                         // Just remove the loaded entries from package lists.
2877                         mPackages.remove(ps.name);
2878                     }
2879                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile
2880                             + "reverting from " + ps.codePathString
2881                             + ": new version " + pkg.mVersionCode
2882                             + " better than installed " + ps.versionCode);
2883                     InstallArgs args = new FileInstallArgs(ps.codePathString,
2884                             ps.resourcePathString, ps.nativeLibraryPathString);
2885                     args.cleanUpResourcesLI();
2886                     mSettings.enableSystemPackageLPw(ps.name);
2887                 }
2888             }
2889         }
2890         if (updatedPkg != null) {
2891             // An updated system app will not have the PARSE_IS_SYSTEM flag set initially
2892             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
2893         }
2894         // Verify certificates against what was last scanned
2895         if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
2896             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
2897             return null;
2898         }
2899         // The apk is forward locked (not public) if its code and resources
2900         // are kept in different files.
2901         // TODO grab this value from PackageSettings
2902         if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
2903             parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
2904         }
2905 
2906         String codePath = null;
2907         String resPath = null;
2908         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
2909             if (ps != null && ps.resourcePathString != null) {
2910                 resPath = ps.resourcePathString;
2911             } else {
2912                 // Should not happen at all. Just log an error.
2913                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
2914             }
2915         } else {
2916             resPath = pkg.mScanPath;
2917         }
2918         codePath = pkg.mScanPath;
2919         // Set application objects path explicitly.
2920         setApplicationInfoPaths(pkg, codePath, resPath);
2921         // Note that we invoke the following method only if we are about to unpack an application
2922         return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);
2923     }
2924 
setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath, String destResPath)2925     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
2926             String destResPath) {
2927         pkg.mPath = pkg.mScanPath = destCodePath;
2928         pkg.applicationInfo.sourceDir = destCodePath;
2929         pkg.applicationInfo.publicSourceDir = destResPath;
2930     }
2931 
fixProcessName(String defProcessName, String processName, int uid)2932     private static String fixProcessName(String defProcessName,
2933             String processName, int uid) {
2934         if (processName == null) {
2935             return defProcessName;
2936         }
2937         return processName;
2938     }
2939 
verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)2940     private boolean verifySignaturesLP(PackageSetting pkgSetting,
2941             PackageParser.Package pkg) {
2942         if (pkgSetting.signatures.mSignatures != null) {
2943             // Already existing package. Make sure signatures match
2944             if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
2945                 PackageManager.SIGNATURE_MATCH) {
2946                     Slog.e(TAG, "Package " + pkg.packageName
2947                             + " signatures do not match the previously installed version; ignoring!");
2948                     mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
2949                     return false;
2950                 }
2951         }
2952         // Check for shared user signatures
2953         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
2954             if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
2955                     pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
2956                 Slog.e(TAG, "Package " + pkg.packageName
2957                         + " has no signatures that match those in shared user "
2958                         + pkgSetting.sharedUser.name + "; ignoring!");
2959                 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
2960                 return false;
2961             }
2962         }
2963         return true;
2964     }
2965 
2966     /**
2967      * Enforces that only the system UID or root's UID can call a method exposed
2968      * via Binder.
2969      *
2970      * @param message used as message if SecurityException is thrown
2971      * @throws SecurityException if the caller is not system or root
2972      */
enforceSystemOrRoot(String message)2973     private static final void enforceSystemOrRoot(String message) {
2974         final int uid = Binder.getCallingUid();
2975         if (uid != Process.SYSTEM_UID && uid != 0) {
2976             throw new SecurityException(message);
2977         }
2978     }
2979 
performBootDexOpt()2980     public void performBootDexOpt() {
2981         ArrayList<PackageParser.Package> pkgs = null;
2982         synchronized (mPackages) {
2983             if (mDeferredDexOpt.size() > 0) {
2984                 pkgs = new ArrayList<PackageParser.Package>(mDeferredDexOpt);
2985                 mDeferredDexOpt.clear();
2986             }
2987         }
2988         if (pkgs != null) {
2989             for (int i=0; i<pkgs.size(); i++) {
2990                 if (!isFirstBoot()) {
2991                     try {
2992                         ActivityManagerNative.getDefault().showBootMessage(
2993                                 mContext.getResources().getString(
2994                                         com.android.internal.R.string.android_upgrading_apk,
2995                                         i+1, pkgs.size()), true);
2996                     } catch (RemoteException e) {
2997                     }
2998                 }
2999                 PackageParser.Package p = pkgs.get(i);
3000                 synchronized (mInstallLock) {
3001                     if (!p.mDidDexOpt) {
3002                         performDexOptLI(p, false, false);
3003                     }
3004                 }
3005             }
3006         }
3007     }
3008 
performDexOpt(String packageName)3009     public boolean performDexOpt(String packageName) {
3010         enforceSystemOrRoot("Only the system can request dexopt be performed");
3011 
3012         if (!mNoDexOpt) {
3013             return false;
3014         }
3015 
3016         PackageParser.Package p;
3017         synchronized (mPackages) {
3018             p = mPackages.get(packageName);
3019             if (p == null || p.mDidDexOpt) {
3020                 return false;
3021             }
3022         }
3023         synchronized (mInstallLock) {
3024             return performDexOptLI(p, false, false) == DEX_OPT_PERFORMED;
3025         }
3026     }
3027 
3028     static final int DEX_OPT_SKIPPED = 0;
3029     static final int DEX_OPT_PERFORMED = 1;
3030     static final int DEX_OPT_DEFERRED = 2;
3031     static final int DEX_OPT_FAILED = -1;
3032 
performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer)3033     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer) {
3034         boolean performed = false;
3035         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
3036             String path = pkg.mScanPath;
3037             int ret = 0;
3038             try {
3039                 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
3040                     if (!forceDex && defer) {
3041                         mDeferredDexOpt.add(pkg);
3042                         return DEX_OPT_DEFERRED;
3043                     } else {
3044                         Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
3045                         ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
3046                                 !isForwardLocked(pkg));
3047                         pkg.mDidDexOpt = true;
3048                         performed = true;
3049                     }
3050                 }
3051             } catch (FileNotFoundException e) {
3052                 Slog.w(TAG, "Apk not found for dexopt: " + path);
3053                 ret = -1;
3054             } catch (IOException e) {
3055                 Slog.w(TAG, "IOException reading apk: " + path, e);
3056                 ret = -1;
3057             } catch (dalvik.system.StaleDexCacheError e) {
3058                 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
3059                 ret = -1;
3060             } catch (Exception e) {
3061                 Slog.w(TAG, "Exception when doing dexopt : ", e);
3062                 ret = -1;
3063             }
3064             if (ret < 0) {
3065                 //error from installer
3066                 return DEX_OPT_FAILED;
3067             }
3068         }
3069 
3070         return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
3071     }
3072 
verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)3073     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
3074         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
3075             Slog.w(TAG, "Unable to update from " + oldPkg.name
3076                     + " to " + newPkg.packageName
3077                     + ": old package not in system partition");
3078             return false;
3079         } else if (mPackages.get(oldPkg.name) != null) {
3080             Slog.w(TAG, "Unable to update from " + oldPkg.name
3081                     + " to " + newPkg.packageName
3082                     + ": old package still exists");
3083             return false;
3084         }
3085         return true;
3086     }
3087 
getDataPathForUser(int userId)3088     File getDataPathForUser(int userId) {
3089         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
3090     }
3091 
getDataPathForPackage(String packageName, int userId)3092     private File getDataPathForPackage(String packageName, int userId) {
3093         /*
3094          * Until we fully support multiple users, return the directory we
3095          * previously would have. The PackageManagerTests will need to be
3096          * revised when this is changed back..
3097          */
3098         if (userId == 0) {
3099             return new File(mAppDataDir, packageName);
3100         } else {
3101             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
3102                 + File.separator + packageName);
3103         }
3104     }
3105 
scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, long currentTime)3106     private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
3107             int parseFlags, int scanMode, long currentTime) {
3108         File scanFile = new File(pkg.mScanPath);
3109         if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
3110                 pkg.applicationInfo.publicSourceDir == null) {
3111             // Bail out. The resource and code paths haven't been set.
3112             Slog.w(TAG, " Code and resource paths haven't been set correctly");
3113             mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
3114             return null;
3115         }
3116         mScanningPath = scanFile;
3117 
3118         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
3119             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
3120         }
3121 
3122         if (pkg.packageName.equals("android")) {
3123             synchronized (mPackages) {
3124                 if (mAndroidApplication != null) {
3125                     Slog.w(TAG, "*************************************************");
3126                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
3127                     Slog.w(TAG, " file=" + mScanningPath);
3128                     Slog.w(TAG, "*************************************************");
3129                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
3130                     return null;
3131                 }
3132 
3133                 // Set up information for our fall-back user intent resolution
3134                 // activity.
3135                 mPlatformPackage = pkg;
3136                 pkg.mVersionCode = mSdkVersion;
3137                 mAndroidApplication = pkg.applicationInfo;
3138                 mResolveActivity.applicationInfo = mAndroidApplication;
3139                 mResolveActivity.name = ResolverActivity.class.getName();
3140                 mResolveActivity.packageName = mAndroidApplication.packageName;
3141                 mResolveActivity.processName = mAndroidApplication.processName;
3142                 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
3143                 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
3144                 mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
3145                 mResolveActivity.exported = true;
3146                 mResolveActivity.enabled = true;
3147                 mResolveInfo.activityInfo = mResolveActivity;
3148                 mResolveInfo.priority = 0;
3149                 mResolveInfo.preferredOrder = 0;
3150                 mResolveInfo.match = 0;
3151                 mResolveComponentName = new ComponentName(
3152                         mAndroidApplication.packageName, mResolveActivity.name);
3153             }
3154         }
3155 
3156         if (DEBUG_PACKAGE_SCANNING) {
3157             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
3158                 Log.d(TAG, "Scanning package " + pkg.packageName);
3159         }
3160 
3161         if (mPackages.containsKey(pkg.packageName)
3162                 || mSharedLibraries.containsKey(pkg.packageName)) {
3163             Slog.w(TAG, "Application package " + pkg.packageName
3164                     + " already installed.  Skipping duplicate.");
3165             mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
3166             return null;
3167         }
3168 
3169         // Initialize package source and resource directories
3170         File destCodeFile = new File(pkg.applicationInfo.sourceDir);
3171         File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
3172 
3173         SharedUserSetting suid = null;
3174         PackageSetting pkgSetting = null;
3175 
3176         if (!isSystemApp(pkg)) {
3177             // Only system apps can use these features.
3178             pkg.mOriginalPackages = null;
3179             pkg.mRealPackage = null;
3180             pkg.mAdoptPermissions = null;
3181         }
3182 
3183         // writer
3184         synchronized (mPackages) {
3185             // Check all shared libraries and map to their actual file path.
3186             if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
3187                 if (mTmpSharedLibraries == null ||
3188                         mTmpSharedLibraries.length < mSharedLibraries.size()) {
3189                     mTmpSharedLibraries = new String[mSharedLibraries.size()];
3190                 }
3191                 int num = 0;
3192                 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
3193                 for (int i=0; i<N; i++) {
3194                     final String file = mSharedLibraries.get(pkg.usesLibraries.get(i));
3195                     if (file == null) {
3196                         Slog.e(TAG, "Package " + pkg.packageName
3197                                 + " requires unavailable shared library "
3198                                 + pkg.usesLibraries.get(i) + "; failing!");
3199                         mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
3200                         return null;
3201                     }
3202                     mTmpSharedLibraries[num] = file;
3203                     num++;
3204                 }
3205                 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
3206                 for (int i=0; i<N; i++) {
3207                     final String file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
3208                     if (file == null) {
3209                         Slog.w(TAG, "Package " + pkg.packageName
3210                                 + " desires unavailable shared library "
3211                                 + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
3212                     } else {
3213                         mTmpSharedLibraries[num] = file;
3214                         num++;
3215                     }
3216                 }
3217                 if (num > 0) {
3218                     pkg.usesLibraryFiles = new String[num];
3219                     System.arraycopy(mTmpSharedLibraries, 0,
3220                             pkg.usesLibraryFiles, 0, num);
3221                 }
3222             }
3223 
3224             if (pkg.mSharedUserId != null) {
3225                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId,
3226                         pkg.applicationInfo.flags, true);
3227                 if (suid == null) {
3228                     Slog.w(TAG, "Creating application package " + pkg.packageName
3229                             + " for shared user failed");
3230                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
3231                     return null;
3232                 }
3233                 if (DEBUG_PACKAGE_SCANNING) {
3234                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
3235                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
3236                                 + "): packages=" + suid.packages);
3237                 }
3238             }
3239 
3240             // Check if we are renaming from an original package name.
3241             PackageSetting origPackage = null;
3242             String realName = null;
3243             if (pkg.mOriginalPackages != null) {
3244                 // This package may need to be renamed to a previously
3245                 // installed name.  Let's check on that...
3246                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
3247                 if (pkg.mOriginalPackages.contains(renamed)) {
3248                     // This package had originally been installed as the
3249                     // original name, and we have already taken care of
3250                     // transitioning to the new one.  Just update the new
3251                     // one to continue using the old name.
3252                     realName = pkg.mRealPackage;
3253                     if (!pkg.packageName.equals(renamed)) {
3254                         // Callers into this function may have already taken
3255                         // care of renaming the package; only do it here if
3256                         // it is not already done.
3257                         pkg.setPackageName(renamed);
3258                     }
3259 
3260                 } else {
3261                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
3262                         if ((origPackage = mSettings.peekPackageLPr(
3263                                 pkg.mOriginalPackages.get(i))) != null) {
3264                             // We do have the package already installed under its
3265                             // original name...  should we use it?
3266                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
3267                                 // New package is not compatible with original.
3268                                 origPackage = null;
3269                                 continue;
3270                             } else if (origPackage.sharedUser != null) {
3271                                 // Make sure uid is compatible between packages.
3272                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
3273                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
3274                                             + " to " + pkg.packageName + ": old uid "
3275                                             + origPackage.sharedUser.name
3276                                             + " differs from " + pkg.mSharedUserId);
3277                                     origPackage = null;
3278                                     continue;
3279                                 }
3280                             } else {
3281                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
3282                                         + pkg.packageName + " to old name " + origPackage.name);
3283                             }
3284                             break;
3285                         }
3286                     }
3287                 }
3288             }
3289 
3290             if (mTransferedPackages.contains(pkg.packageName)) {
3291                 Slog.w(TAG, "Package " + pkg.packageName
3292                         + " was transferred to another, but its .apk remains");
3293             }
3294 
3295             // Just create the setting, don't add it yet. For already existing packages
3296             // the PkgSetting exists already and doesn't have to be created.
3297             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
3298                     destResourceFile, pkg.applicationInfo.nativeLibraryDir,
3299                     pkg.applicationInfo.flags, true, false);
3300             if (pkgSetting == null) {
3301                 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
3302                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
3303                 return null;
3304             }
3305 
3306             if (pkgSetting.origPackage != null) {
3307                 // If we are first transitioning from an original package,
3308                 // fix up the new package's name now.  We need to do this after
3309                 // looking up the package under its new name, so getPackageLP
3310                 // can take care of fiddling things correctly.
3311                 pkg.setPackageName(origPackage.name);
3312 
3313                 // File a report about this.
3314                 String msg = "New package " + pkgSetting.realName
3315                         + " renamed to replace old package " + pkgSetting.name;
3316                 reportSettingsProblem(Log.WARN, msg);
3317 
3318                 // Make a note of it.
3319                 mTransferedPackages.add(origPackage.name);
3320 
3321                 // No longer need to retain this.
3322                 pkgSetting.origPackage = null;
3323             }
3324 
3325             if (realName != null) {
3326                 // Make a note of it.
3327                 mTransferedPackages.add(pkg.packageName);
3328             }
3329 
3330             if (mSettings.mDisabledSysPackages.get(pkg.packageName) != null) {
3331                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
3332             }
3333 
3334             pkg.applicationInfo.uid = pkgSetting.userId;
3335             pkg.mExtras = pkgSetting;
3336 
3337             if (!verifySignaturesLP(pkgSetting, pkg)) {
3338                 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
3339                     return null;
3340                 }
3341                 // The signature has changed, but this package is in the system
3342                 // image...  let's recover!
3343                 pkgSetting.signatures.mSignatures = pkg.mSignatures;
3344                 // However...  if this package is part of a shared user, but it
3345                 // doesn't match the signature of the shared user, let's fail.
3346                 // What this means is that you can't change the signatures
3347                 // associated with an overall shared user, which doesn't seem all
3348                 // that unreasonable.
3349                 if (pkgSetting.sharedUser != null) {
3350                     if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
3351                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
3352                         Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
3353                         mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
3354                         return null;
3355                     }
3356                 }
3357                 // File a report about this.
3358                 String msg = "System package " + pkg.packageName
3359                         + " signature changed; retaining data.";
3360                 reportSettingsProblem(Log.WARN, msg);
3361             }
3362 
3363             // Verify that this new package doesn't have any content providers
3364             // that conflict with existing packages.  Only do this if the
3365             // package isn't already installed, since we don't want to break
3366             // things that are installed.
3367             if ((scanMode&SCAN_NEW_INSTALL) != 0) {
3368                 final int N = pkg.providers.size();
3369                 int i;
3370                 for (i=0; i<N; i++) {
3371                     PackageParser.Provider p = pkg.providers.get(i);
3372                     if (p.info.authority != null) {
3373                         String names[] = p.info.authority.split(";");
3374                         for (int j = 0; j < names.length; j++) {
3375                             if (mProviders.containsKey(names[j])) {
3376                                 PackageParser.Provider other = mProviders.get(names[j]);
3377                                 Slog.w(TAG, "Can't install because provider name " + names[j] +
3378                                         " (in package " + pkg.applicationInfo.packageName +
3379                                         ") is already used by "
3380                                         + ((other != null && other.getComponentName() != null)
3381                                                 ? other.getComponentName().getPackageName() : "?"));
3382                                 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
3383                                 return null;
3384                             }
3385                         }
3386                     }
3387                 }
3388             }
3389 
3390             if (pkg.mAdoptPermissions != null) {
3391                 // This package wants to adopt ownership of permissions from
3392                 // another package.
3393                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
3394                     final String origName = pkg.mAdoptPermissions.get(i);
3395                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
3396                     if (orig != null) {
3397                         if (verifyPackageUpdateLPr(orig, pkg)) {
3398                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
3399                                     + pkg.packageName);
3400                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
3401                         }
3402                     }
3403                 }
3404             }
3405         }
3406 
3407         final String pkgName = pkg.packageName;
3408 
3409         final long scanFileTime = scanFile.lastModified();
3410         final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
3411         pkg.applicationInfo.processName = fixProcessName(
3412                 pkg.applicationInfo.packageName,
3413                 pkg.applicationInfo.processName,
3414                 pkg.applicationInfo.uid);
3415 
3416         File dataPath;
3417         if (mPlatformPackage == pkg) {
3418             // The system package is special.
3419             dataPath = new File (Environment.getDataDirectory(), "system");
3420             pkg.applicationInfo.dataDir = dataPath.getPath();
3421         } else {
3422             // This is a normal package, need to make its data directory.
3423             dataPath = getDataPathForPackage(pkg.packageName, 0);
3424 
3425             boolean uidError = false;
3426 
3427             if (dataPath.exists()) {
3428                 mOutPermissions[1] = 0;
3429                 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
3430 
3431                 // If we have mismatched owners for the data path, we have a problem.
3432                 if (mOutPermissions[1] != pkg.applicationInfo.uid) {
3433                     boolean recovered = false;
3434                     if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
3435                         // If this is a system app, we can at least delete its
3436                         // current data so the application will still work.
3437                         int ret = mInstaller.remove(pkgName, 0);
3438                         if (ret >= 0) {
3439                             // TODO: Kill the processes first
3440                             // Remove the data directories for all users
3441                             mUserManager.removePackageForAllUsers(pkgName);
3442                             // Old data gone!
3443                             String msg = "System package " + pkg.packageName
3444                                     + " has changed from uid: "
3445                                     + mOutPermissions[1] + " to "
3446                                     + pkg.applicationInfo.uid + "; old data erased";
3447                             reportSettingsProblem(Log.WARN, msg);
3448                             recovered = true;
3449 
3450                             // And now re-install the app.
3451                             ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
3452                                     pkg.applicationInfo.uid);
3453                             if (ret == -1) {
3454                                 // Ack should not happen!
3455                                 msg = "System package " + pkg.packageName
3456                                         + " could not have data directory re-created after delete.";
3457                                 reportSettingsProblem(Log.WARN, msg);
3458                                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
3459                                 return null;
3460                             }
3461                             // Create data directories for all users
3462                             mUserManager.installPackageForAllUsers(pkgName,
3463                                     pkg.applicationInfo.uid);
3464                         }
3465                         if (!recovered) {
3466                             mHasSystemUidErrors = true;
3467                         }
3468                     }
3469                     if (!recovered) {
3470                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
3471                             + pkg.applicationInfo.uid + "/fs_"
3472                             + mOutPermissions[1];
3473                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
3474                         String msg = "Package " + pkg.packageName
3475                                 + " has mismatched uid: "
3476                                 + mOutPermissions[1] + " on disk, "
3477                                 + pkg.applicationInfo.uid + " in settings";
3478                         // writer
3479                         synchronized (mPackages) {
3480                             mSettings.mReadMessages.append(msg);
3481                             mSettings.mReadMessages.append('\n');
3482                             uidError = true;
3483                             if (!pkgSetting.uidError) {
3484                                 reportSettingsProblem(Log.ERROR, msg);
3485                             }
3486                         }
3487                     }
3488                 }
3489                 pkg.applicationInfo.dataDir = dataPath.getPath();
3490             } else {
3491                 if (DEBUG_PACKAGE_SCANNING) {
3492                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
3493                         Log.v(TAG, "Want this data dir: " + dataPath);
3494                 }
3495                 //invoke installer to do the actual installation
3496                 int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
3497                         pkg.applicationInfo.uid);
3498                 if (ret < 0) {
3499                     // Error from installer
3500                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
3501                     return null;
3502                 }
3503                 // Create data directories for all users
3504                 mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);
3505 
3506                 if (dataPath.exists()) {
3507                     pkg.applicationInfo.dataDir = dataPath.getPath();
3508                 } else {
3509                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
3510                     pkg.applicationInfo.dataDir = null;
3511                 }
3512             }
3513 
3514             /*
3515              * Set the data dir to the default "/data/data/<package name>/lib"
3516              * if we got here without anyone telling us different (e.g., apps
3517              * stored on SD card have their native libraries stored in the ASEC
3518              * container with the APK).
3519              *
3520              * This happens during an upgrade from a package settings file that
3521              * doesn't have a native library path attribute at all.
3522              */
3523             if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
3524                 if (pkgSetting.nativeLibraryPathString == null) {
3525                     final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
3526                     pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
3527                     pkgSetting.nativeLibraryPathString = nativeLibraryPath;
3528                 } else {
3529                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
3530                 }
3531             }
3532 
3533             pkgSetting.uidError = uidError;
3534         }
3535 
3536         String path = scanFile.getPath();
3537         /* Note: We don't want to unpack the native binaries for
3538          *        system applications, unless they have been updated
3539          *        (the binaries are already under /system/lib).
3540          *        Also, don't unpack libs for apps on the external card
3541          *        since they should have their libraries in the ASEC
3542          *        container already.
3543          *
3544          *        In other words, we're going to unpack the binaries
3545          *        only for non-system apps and system app upgrades.
3546          */
3547         if (pkg.applicationInfo.nativeLibraryDir != null) {
3548             try {
3549                 final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
3550                 final String dataPathString = dataPath.getCanonicalPath();
3551 
3552                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
3553                     /*
3554                      * Upgrading from a previous version of the OS sometimes
3555                      * leaves native libraries in the /data/data/<app>/lib
3556                      * directory for system apps even when they shouldn't be.
3557                      * Recent changes in the JNI library search path
3558                      * necessitates we remove those to match previous behavior.
3559                      */
3560                     if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
3561                         Log.i(TAG, "removed obsolete native libraries for system package "
3562                                 + path);
3563                     }
3564                 } else if (nativeLibraryDir.getParentFile().getCanonicalPath()
3565                         .equals(dataPathString)) {
3566                     /*
3567                      * Make sure the native library dir isn't a symlink to
3568                      * something. If it is, ask installd to remove it and create
3569                      * a directory so we can copy to it afterwards.
3570                      */
3571                     boolean isSymLink;
3572                     try {
3573                         isSymLink = S_ISLNK(Libcore.os.lstat(nativeLibraryDir.getPath()).st_mode);
3574                     } catch (ErrnoException e) {
3575                         // This shouldn't happen, but we'll fail-safe.
3576                         isSymLink = true;
3577                     }
3578                     if (isSymLink) {
3579                         mInstaller.unlinkNativeLibraryDirectory(dataPathString);
3580                     }
3581 
3582                     /*
3583                      * If this is an internal application or our
3584                      * nativeLibraryPath points to our data directory, unpack
3585                      * the libraries if necessary.
3586                      */
3587                     NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
3588                 } else {
3589                     Slog.i(TAG, "Linking native library dir for " + path);
3590                     mInstaller.linkNativeLibraryDirectory(dataPathString,
3591                             pkg.applicationInfo.nativeLibraryDir);
3592                 }
3593             } catch (IOException ioe) {
3594                 Log.e(TAG, "Unable to get canonical file " + ioe.toString());
3595             }
3596         }
3597         pkg.mScanPath = path;
3598 
3599         if ((scanMode&SCAN_NO_DEX) == 0) {
3600             if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0)
3601                     == DEX_OPT_FAILED) {
3602                 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
3603                 return null;
3604             }
3605         }
3606 
3607         if (mFactoryTest && pkg.requestedPermissions.contains(
3608                 android.Manifest.permission.FACTORY_TEST)) {
3609             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
3610         }
3611 
3612         // Request the ActivityManager to kill the process(only for existing packages)
3613         // so that we do not end up in a confused state while the user is still using the older
3614         // version of the application while the new one gets installed.
3615         if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
3616             killApplication(pkg.applicationInfo.packageName,
3617                         pkg.applicationInfo.uid);
3618         }
3619 
3620         // writer
3621         synchronized (mPackages) {
3622             // We don't expect installation to fail beyond this point,
3623             if ((scanMode&SCAN_MONITOR) != 0) {
3624                 mAppDirs.put(pkg.mPath, pkg);
3625             }
3626             // Add the new setting to mSettings
3627             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
3628             // Add the new setting to mPackages
3629             mPackages.put(pkg.applicationInfo.packageName, pkg);
3630             // Make sure we don't accidentally delete its data.
3631             mSettings.mPackagesToBeCleaned.remove(pkgName);
3632 
3633             // Take care of first install / last update times.
3634             if (currentTime != 0) {
3635                 if (pkgSetting.firstInstallTime == 0) {
3636                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
3637                 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
3638                     pkgSetting.lastUpdateTime = currentTime;
3639                 }
3640             } else if (pkgSetting.firstInstallTime == 0) {
3641                 // We need *something*.  Take time time stamp of the file.
3642                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
3643             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
3644                 if (scanFileTime != pkgSetting.timeStamp) {
3645                     // A package on the system image has changed; consider this
3646                     // to be an update.
3647                     pkgSetting.lastUpdateTime = scanFileTime;
3648                 }
3649             }
3650 
3651             int N = pkg.providers.size();
3652             StringBuilder r = null;
3653             int i;
3654             for (i=0; i<N; i++) {
3655                 PackageParser.Provider p = pkg.providers.get(i);
3656                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
3657                         p.info.processName, pkg.applicationInfo.uid);
3658                 mProvidersByComponent.put(new ComponentName(p.info.packageName,
3659                         p.info.name), p);
3660                 p.syncable = p.info.isSyncable;
3661                 if (p.info.authority != null) {
3662                     String names[] = p.info.authority.split(";");
3663                     p.info.authority = null;
3664                     for (int j = 0; j < names.length; j++) {
3665                         if (j == 1 && p.syncable) {
3666                             // We only want the first authority for a provider to possibly be
3667                             // syncable, so if we already added this provider using a different
3668                             // authority clear the syncable flag. We copy the provider before
3669                             // changing it because the mProviders object contains a reference
3670                             // to a provider that we don't want to change.
3671                             // Only do this for the second authority since the resulting provider
3672                             // object can be the same for all future authorities for this provider.
3673                             p = new PackageParser.Provider(p);
3674                             p.syncable = false;
3675                         }
3676                         if (!mProviders.containsKey(names[j])) {
3677                             mProviders.put(names[j], p);
3678                             if (p.info.authority == null) {
3679                                 p.info.authority = names[j];
3680                             } else {
3681                                 p.info.authority = p.info.authority + ";" + names[j];
3682                             }
3683                             if (DEBUG_PACKAGE_SCANNING) {
3684                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
3685                                     Log.d(TAG, "Registered content provider: " + names[j]
3686                                             + ", className = " + p.info.name + ", isSyncable = "
3687                                             + p.info.isSyncable);
3688                             }
3689                         } else {
3690                             PackageParser.Provider other = mProviders.get(names[j]);
3691                             Slog.w(TAG, "Skipping provider name " + names[j] +
3692                                     " (in package " + pkg.applicationInfo.packageName +
3693                                     "): name already used by "
3694                                     + ((other != null && other.getComponentName() != null)
3695                                             ? other.getComponentName().getPackageName() : "?"));
3696                         }
3697                     }
3698                 }
3699                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3700                     if (r == null) {
3701                         r = new StringBuilder(256);
3702                     } else {
3703                         r.append(' ');
3704                     }
3705                     r.append(p.info.name);
3706                 }
3707             }
3708             if (r != null) {
3709                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
3710             }
3711 
3712             N = pkg.services.size();
3713             r = null;
3714             for (i=0; i<N; i++) {
3715                 PackageParser.Service s = pkg.services.get(i);
3716                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
3717                         s.info.processName, pkg.applicationInfo.uid);
3718                 mServices.addService(s);
3719                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3720                     if (r == null) {
3721                         r = new StringBuilder(256);
3722                     } else {
3723                         r.append(' ');
3724                     }
3725                     r.append(s.info.name);
3726                 }
3727             }
3728             if (r != null) {
3729                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
3730             }
3731 
3732             N = pkg.receivers.size();
3733             r = null;
3734             for (i=0; i<N; i++) {
3735                 PackageParser.Activity a = pkg.receivers.get(i);
3736                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
3737                         a.info.processName, pkg.applicationInfo.uid);
3738                 mReceivers.addActivity(a, "receiver");
3739                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3740                     if (r == null) {
3741                         r = new StringBuilder(256);
3742                     } else {
3743                         r.append(' ');
3744                     }
3745                     r.append(a.info.name);
3746                 }
3747             }
3748             if (r != null) {
3749                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
3750             }
3751 
3752             N = pkg.activities.size();
3753             r = null;
3754             for (i=0; i<N; i++) {
3755                 PackageParser.Activity a = pkg.activities.get(i);
3756                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
3757                         a.info.processName, pkg.applicationInfo.uid);
3758                 mActivities.addActivity(a, "activity");
3759                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3760                     if (r == null) {
3761                         r = new StringBuilder(256);
3762                     } else {
3763                         r.append(' ');
3764                     }
3765                     r.append(a.info.name);
3766                 }
3767             }
3768             if (r != null) {
3769                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
3770             }
3771 
3772             N = pkg.permissionGroups.size();
3773             r = null;
3774             for (i=0; i<N; i++) {
3775                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
3776                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
3777                 if (cur == null) {
3778                     mPermissionGroups.put(pg.info.name, pg);
3779                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3780                         if (r == null) {
3781                             r = new StringBuilder(256);
3782                         } else {
3783                             r.append(' ');
3784                         }
3785                         r.append(pg.info.name);
3786                     }
3787                 } else {
3788                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
3789                             + pg.info.packageName + " ignored: original from "
3790                             + cur.info.packageName);
3791                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3792                         if (r == null) {
3793                             r = new StringBuilder(256);
3794                         } else {
3795                             r.append(' ');
3796                         }
3797                         r.append("DUP:");
3798                         r.append(pg.info.name);
3799                     }
3800                 }
3801             }
3802             if (r != null) {
3803                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
3804             }
3805 
3806             N = pkg.permissions.size();
3807             r = null;
3808             for (i=0; i<N; i++) {
3809                 PackageParser.Permission p = pkg.permissions.get(i);
3810                 HashMap<String, BasePermission> permissionMap =
3811                         p.tree ? mSettings.mPermissionTrees
3812                         : mSettings.mPermissions;
3813                 p.group = mPermissionGroups.get(p.info.group);
3814                 if (p.info.group == null || p.group != null) {
3815                     BasePermission bp = permissionMap.get(p.info.name);
3816                     if (bp == null) {
3817                         bp = new BasePermission(p.info.name, p.info.packageName,
3818                                 BasePermission.TYPE_NORMAL);
3819                         permissionMap.put(p.info.name, bp);
3820                     }
3821                     if (bp.perm == null) {
3822                         if (bp.sourcePackage == null
3823                                 || bp.sourcePackage.equals(p.info.packageName)) {
3824                             BasePermission tree = findPermissionTreeLP(p.info.name);
3825                             if (tree == null
3826                                     || tree.sourcePackage.equals(p.info.packageName)) {
3827                                 bp.packageSetting = pkgSetting;
3828                                 bp.perm = p;
3829                                 bp.uid = pkg.applicationInfo.uid;
3830                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3831                                     if (r == null) {
3832                                         r = new StringBuilder(256);
3833                                     } else {
3834                                         r.append(' ');
3835                                     }
3836                                     r.append(p.info.name);
3837                                 }
3838                             } else {
3839                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
3840                                         + p.info.packageName + " ignored: base tree "
3841                                         + tree.name + " is from package "
3842                                         + tree.sourcePackage);
3843                             }
3844                         } else {
3845                             Slog.w(TAG, "Permission " + p.info.name + " from package "
3846                                     + p.info.packageName + " ignored: original from "
3847                                     + bp.sourcePackage);
3848                         }
3849                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3850                         if (r == null) {
3851                             r = new StringBuilder(256);
3852                         } else {
3853                             r.append(' ');
3854                         }
3855                         r.append("DUP:");
3856                         r.append(p.info.name);
3857                     }
3858                     if (bp.perm == p) {
3859                         bp.protectionLevel = p.info.protectionLevel;
3860                     }
3861                 } else {
3862                     Slog.w(TAG, "Permission " + p.info.name + " from package "
3863                             + p.info.packageName + " ignored: no group "
3864                             + p.group);
3865                 }
3866             }
3867             if (r != null) {
3868                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
3869             }
3870 
3871             N = pkg.instrumentation.size();
3872             r = null;
3873             for (i=0; i<N; i++) {
3874                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
3875                 a.info.packageName = pkg.applicationInfo.packageName;
3876                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
3877                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
3878                 a.info.dataDir = pkg.applicationInfo.dataDir;
3879                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
3880                 mInstrumentation.put(a.getComponentName(), a);
3881                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
3882                     if (r == null) {
3883                         r = new StringBuilder(256);
3884                     } else {
3885                         r.append(' ');
3886                     }
3887                     r.append(a.info.name);
3888                 }
3889             }
3890             if (r != null) {
3891                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
3892             }
3893 
3894             if (pkg.protectedBroadcasts != null) {
3895                 N = pkg.protectedBroadcasts.size();
3896                 for (i=0; i<N; i++) {
3897                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
3898                 }
3899             }
3900 
3901             pkgSetting.setTimeStamp(scanFileTime);
3902         }
3903 
3904         return pkg;
3905     }
3906 
killApplication(String pkgName, int uid)3907     private void killApplication(String pkgName, int uid) {
3908         // Request the ActivityManager to kill the process(only for existing packages)
3909         // so that we do not end up in a confused state while the user is still using the older
3910         // version of the application while the new one gets installed.
3911         IActivityManager am = ActivityManagerNative.getDefault();
3912         if (am != null) {
3913             try {
3914                 am.killApplicationWithUid(pkgName, uid);
3915             } catch (RemoteException e) {
3916             }
3917         }
3918     }
3919 
removePackageLI(PackageParser.Package pkg, boolean chatty)3920     void removePackageLI(PackageParser.Package pkg, boolean chatty) {
3921         if (DEBUG_INSTALL) {
3922             if (chatty)
3923                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
3924         }
3925 
3926         // writer
3927         synchronized (mPackages) {
3928             clearPackagePreferredActivitiesLPw(pkg.packageName);
3929 
3930             mPackages.remove(pkg.applicationInfo.packageName);
3931             if (pkg.mPath != null) {
3932                 mAppDirs.remove(pkg.mPath);
3933             }
3934 
3935             int N = pkg.providers.size();
3936             StringBuilder r = null;
3937             int i;
3938             for (i=0; i<N; i++) {
3939                 PackageParser.Provider p = pkg.providers.get(i);
3940                 mProvidersByComponent.remove(new ComponentName(p.info.packageName,
3941                         p.info.name));
3942                 if (p.info.authority == null) {
3943 
3944                     /* The is another ContentProvider with this authority when
3945                      * this app was installed so this authority is null,
3946                      * Ignore it as we don't have to unregister the provider.
3947                      */
3948                     continue;
3949                 }
3950                 String names[] = p.info.authority.split(";");
3951                 for (int j = 0; j < names.length; j++) {
3952                     if (mProviders.get(names[j]) == p) {
3953                         mProviders.remove(names[j]);
3954                         if (DEBUG_REMOVE) {
3955                             if (chatty)
3956                                 Log.d(TAG, "Unregistered content provider: " + names[j]
3957                                         + ", className = " + p.info.name + ", isSyncable = "
3958                                         + p.info.isSyncable);
3959                         }
3960                     }
3961                 }
3962                 if (chatty) {
3963                     if (r == null) {
3964                         r = new StringBuilder(256);
3965                     } else {
3966                         r.append(' ');
3967                     }
3968                     r.append(p.info.name);
3969                 }
3970             }
3971             if (r != null) {
3972                 if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
3973             }
3974 
3975             N = pkg.services.size();
3976             r = null;
3977             for (i=0; i<N; i++) {
3978                 PackageParser.Service s = pkg.services.get(i);
3979                 mServices.removeService(s);
3980                 if (chatty) {
3981                     if (r == null) {
3982                         r = new StringBuilder(256);
3983                     } else {
3984                         r.append(' ');
3985                     }
3986                     r.append(s.info.name);
3987                 }
3988             }
3989             if (r != null) {
3990                 if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
3991             }
3992 
3993             N = pkg.receivers.size();
3994             r = null;
3995             for (i=0; i<N; i++) {
3996                 PackageParser.Activity a = pkg.receivers.get(i);
3997                 mReceivers.removeActivity(a, "receiver");
3998                 if (chatty) {
3999                     if (r == null) {
4000                         r = new StringBuilder(256);
4001                     } else {
4002                         r.append(' ');
4003                     }
4004                     r.append(a.info.name);
4005                 }
4006             }
4007             if (r != null) {
4008                 if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
4009             }
4010 
4011             N = pkg.activities.size();
4012             r = null;
4013             for (i=0; i<N; i++) {
4014                 PackageParser.Activity a = pkg.activities.get(i);
4015                 mActivities.removeActivity(a, "activity");
4016                 if (chatty) {
4017                     if (r == null) {
4018                         r = new StringBuilder(256);
4019                     } else {
4020                         r.append(' ');
4021                     }
4022                     r.append(a.info.name);
4023                 }
4024             }
4025             if (r != null) {
4026                 if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
4027             }
4028 
4029             N = pkg.permissions.size();
4030             r = null;
4031             for (i=0; i<N; i++) {
4032                 PackageParser.Permission p = pkg.permissions.get(i);
4033                 BasePermission bp = mSettings.mPermissions.get(p.info.name);
4034                 if (bp == null) {
4035                     bp = mSettings.mPermissionTrees.get(p.info.name);
4036                 }
4037                 if (bp != null && bp.perm == p) {
4038                     bp.perm = null;
4039                     if (chatty) {
4040                         if (r == null) {
4041                             r = new StringBuilder(256);
4042                         } else {
4043                             r.append(' ');
4044                         }
4045                         r.append(p.info.name);
4046                     }
4047                 }
4048             }
4049             if (r != null) {
4050                 if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
4051             }
4052 
4053             N = pkg.instrumentation.size();
4054             r = null;
4055             for (i=0; i<N; i++) {
4056                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
4057                 mInstrumentation.remove(a.getComponentName());
4058                 if (chatty) {
4059                     if (r == null) {
4060                         r = new StringBuilder(256);
4061                     } else {
4062                         r.append(' ');
4063                     }
4064                     r.append(a.info.name);
4065                 }
4066             }
4067             if (r != null) {
4068                 if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
4069             }
4070         }
4071     }
4072 
isPackageFilename(String name)4073     private static final boolean isPackageFilename(String name) {
4074         return name != null && name.endsWith(".apk");
4075     }
4076 
hasPermission(PackageParser.Package pkgInfo, String perm)4077     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
4078         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
4079             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
4080                 return true;
4081             }
4082         }
4083         return false;
4084     }
4085 
updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, boolean grantPermissions, boolean replace, boolean replaceAll)4086     private void updatePermissionsLPw(String changingPkg,
4087             PackageParser.Package pkgInfo, boolean grantPermissions,
4088             boolean replace, boolean replaceAll) {
4089         // Make sure there are no dangling permission trees.
4090         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
4091         while (it.hasNext()) {
4092             final BasePermission bp = it.next();
4093             if (bp.packageSetting == null) {
4094                 // We may not yet have parsed the package, so just see if
4095                 // we still know about its settings.
4096                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
4097             }
4098             if (bp.packageSetting == null) {
4099                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
4100                         + " from package " + bp.sourcePackage);
4101                 it.remove();
4102             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
4103                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
4104                     Slog.i(TAG, "Removing old permission tree: " + bp.name
4105                             + " from package " + bp.sourcePackage);
4106                     grantPermissions = true;
4107                     it.remove();
4108                 }
4109             }
4110         }
4111 
4112         // Make sure all dynamic permissions have been assigned to a package,
4113         // and make sure there are no dangling permissions.
4114         it = mSettings.mPermissions.values().iterator();
4115         while (it.hasNext()) {
4116             final BasePermission bp = it.next();
4117             if (bp.type == BasePermission.TYPE_DYNAMIC) {
4118                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
4119                         + bp.name + " pkg=" + bp.sourcePackage
4120                         + " info=" + bp.pendingInfo);
4121                 if (bp.packageSetting == null && bp.pendingInfo != null) {
4122                     final BasePermission tree = findPermissionTreeLP(bp.name);
4123                     if (tree != null && tree.perm != null) {
4124                         bp.packageSetting = tree.packageSetting;
4125                         bp.perm = new PackageParser.Permission(tree.perm.owner,
4126                                 new PermissionInfo(bp.pendingInfo));
4127                         bp.perm.info.packageName = tree.perm.info.packageName;
4128                         bp.perm.info.name = bp.name;
4129                         bp.uid = tree.uid;
4130                     }
4131                 }
4132             }
4133             if (bp.packageSetting == null) {
4134                 // We may not yet have parsed the package, so just see if
4135                 // we still know about its settings.
4136                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
4137             }
4138             if (bp.packageSetting == null) {
4139                 Slog.w(TAG, "Removing dangling permission: " + bp.name
4140                         + " from package " + bp.sourcePackage);
4141                 it.remove();
4142             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
4143                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
4144                     Slog.i(TAG, "Removing old permission: " + bp.name
4145                             + " from package " + bp.sourcePackage);
4146                     grantPermissions = true;
4147                     it.remove();
4148                 }
4149             }
4150         }
4151 
4152         // Now update the permissions for all packages, in particular
4153         // replace the granted permissions of the system packages.
4154         if (grantPermissions) {
4155             for (PackageParser.Package pkg : mPackages.values()) {
4156                 if (pkg != pkgInfo) {
4157                     grantPermissionsLPw(pkg, replaceAll);
4158                 }
4159             }
4160         }
4161 
4162         if (pkgInfo != null) {
4163             grantPermissionsLPw(pkgInfo, replace);
4164         }
4165     }
4166 
grantPermissionsLPw(PackageParser.Package pkg, boolean replace)4167     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
4168         final PackageSetting ps = (PackageSetting) pkg.mExtras;
4169         if (ps == null) {
4170             return;
4171         }
4172         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
4173         boolean changedPermission = false;
4174 
4175         if (replace) {
4176             ps.permissionsFixed = false;
4177             if (gp == ps) {
4178                 gp.grantedPermissions.clear();
4179                 gp.gids = mGlobalGids;
4180             }
4181         }
4182 
4183         if (gp.gids == null) {
4184             gp.gids = mGlobalGids;
4185         }
4186 
4187         final int N = pkg.requestedPermissions.size();
4188         for (int i=0; i<N; i++) {
4189             final String name = pkg.requestedPermissions.get(i);
4190             final BasePermission bp = mSettings.mPermissions.get(name);
4191             if (DEBUG_INSTALL) {
4192                 if (gp != ps) {
4193                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
4194                 }
4195             }
4196             if (bp != null && bp.packageSetting != null) {
4197                 final String perm = bp.name;
4198                 boolean allowed;
4199                 boolean allowedSig = false;
4200                 if (bp.protectionLevel == PermissionInfo.PROTECTION_NORMAL
4201                         || bp.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
4202                     allowed = true;
4203                 } else if (bp.packageSetting == null) {
4204                     // This permission is invalid; skip it.
4205                     allowed = false;
4206                 } else if (bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE
4207                         || bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
4208                     allowed = (compareSignatures(
4209                             bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
4210                                     == PackageManager.SIGNATURE_MATCH)
4211                             || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
4212                                     == PackageManager.SIGNATURE_MATCH);
4213                     if (!allowed && bp.protectionLevel
4214                             == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
4215                         if (isSystemApp(pkg)) {
4216                             // For updated system applications, the signatureOrSystem permission
4217                             // is granted only if it had been defined by the original application.
4218                             if (isUpdatedSystemApp(pkg)) {
4219                                 final PackageSetting sysPs = mSettings
4220                                         .getDisabledSystemPkgLPr(pkg.packageName);
4221                                 final GrantedPermissions origGp = sysPs.sharedUser != null
4222                                         ? sysPs.sharedUser : sysPs;
4223                                 if (origGp.grantedPermissions.contains(perm)) {
4224                                     allowed = true;
4225                                 } else {
4226                                     allowed = false;
4227                                 }
4228                             } else {
4229                                 allowed = true;
4230                             }
4231                         }
4232                     }
4233                     if (allowed) {
4234                         allowedSig = true;
4235                     }
4236                 } else {
4237                     allowed = false;
4238                 }
4239                 if (DEBUG_INSTALL) {
4240                     if (gp != ps) {
4241                         Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
4242                     }
4243                 }
4244                 if (allowed) {
4245                     if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
4246                             && ps.permissionsFixed) {
4247                         // If this is an existing, non-system package, then
4248                         // we can't add any new permissions to it.
4249                         if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
4250                             allowed = false;
4251                             // Except...  if this is a permission that was added
4252                             // to the platform (note: need to only do this when
4253                             // updating the platform).
4254                             final int NP = PackageParser.NEW_PERMISSIONS.length;
4255                             for (int ip=0; ip<NP; ip++) {
4256                                 final PackageParser.NewPermissionInfo npi
4257                                         = PackageParser.NEW_PERMISSIONS[ip];
4258                                 if (npi.name.equals(perm)
4259                                         && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
4260                                     allowed = true;
4261                                     Log.i(TAG, "Auto-granting " + perm + " to old pkg "
4262                                             + pkg.packageName);
4263                                     break;
4264                                 }
4265                             }
4266                         }
4267                     }
4268                     if (allowed) {
4269                         if (!gp.grantedPermissions.contains(perm)) {
4270                             changedPermission = true;
4271                             gp.grantedPermissions.add(perm);
4272                             gp.gids = appendInts(gp.gids, bp.gids);
4273                         } else if (!ps.haveGids) {
4274                             gp.gids = appendInts(gp.gids, bp.gids);
4275                         }
4276                     } else {
4277                         Slog.w(TAG, "Not granting permission " + perm
4278                                 + " to package " + pkg.packageName
4279                                 + " because it was previously installed without");
4280                     }
4281                 } else {
4282                     if (gp.grantedPermissions.remove(perm)) {
4283                         changedPermission = true;
4284                         gp.gids = removeInts(gp.gids, bp.gids);
4285                         Slog.i(TAG, "Un-granting permission " + perm
4286                                 + " from package " + pkg.packageName
4287                                 + " (protectionLevel=" + bp.protectionLevel
4288                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
4289                                 + ")");
4290                     } else {
4291                         Slog.w(TAG, "Not granting permission " + perm
4292                                 + " to package " + pkg.packageName
4293                                 + " (protectionLevel=" + bp.protectionLevel
4294                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
4295                                 + ")");
4296                     }
4297                 }
4298             } else {
4299                 Slog.w(TAG, "Unknown permission " + name
4300                         + " in package " + pkg.packageName);
4301             }
4302         }
4303 
4304         if ((changedPermission || replace) && !ps.permissionsFixed &&
4305                 ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) ||
4306                 ((ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)){
4307             // This is the first that we have heard about this package, so the
4308             // permissions we have now selected are fixed until explicitly
4309             // changed.
4310             ps.permissionsFixed = true;
4311         }
4312         ps.haveGids = true;
4313     }
4314 
4315     private final class ActivityIntentResolver
4316             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly)4317         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
4318                 boolean defaultOnly) {
4319             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
4320             return super.queryIntent(intent, resolvedType, defaultOnly);
4321         }
4322 
queryIntent(Intent intent, String resolvedType, int flags)4323         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags) {
4324             mFlags = flags;
4325             return super.queryIntent(intent, resolvedType,
4326                 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
4327         }
4328 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities)4329         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
4330                 int flags, ArrayList<PackageParser.Activity> packageActivities) {
4331             if (packageActivities == null) {
4332                 return null;
4333             }
4334             mFlags = flags;
4335             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
4336             final int N = packageActivities.size();
4337             ArrayList<ArrayList<PackageParser.ActivityIntentInfo>> listCut =
4338                 new ArrayList<ArrayList<PackageParser.ActivityIntentInfo>>(N);
4339 
4340             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
4341             for (int i = 0; i < N; ++i) {
4342                 intentFilters = packageActivities.get(i).intents;
4343                 if (intentFilters != null && intentFilters.size() > 0) {
4344                     listCut.add(intentFilters);
4345                 }
4346             }
4347             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
4348         }
4349 
addActivity(PackageParser.Activity a, String type)4350         public final void addActivity(PackageParser.Activity a, String type) {
4351             final boolean systemApp = isSystemApp(a.info.applicationInfo);
4352             mActivities.put(a.getComponentName(), a);
4353             if (DEBUG_SHOW_INFO)
4354                 Log.v(
4355                 TAG, "  " + type + " " +
4356                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
4357             if (DEBUG_SHOW_INFO)
4358                 Log.v(TAG, "    Class=" + a.info.name);
4359             final int NI = a.intents.size();
4360             for (int j=0; j<NI; j++) {
4361                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
4362                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
4363                     intent.setPriority(0);
4364                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
4365                             + a.className + " with priority > 0, forcing to 0");
4366                 }
4367                 if (DEBUG_SHOW_INFO) {
4368                     Log.v(TAG, "    IntentFilter:");
4369                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
4370                 }
4371                 if (!intent.debugCheck()) {
4372                     Log.w(TAG, "==> For Activity " + a.info.name);
4373                 }
4374                 addFilter(intent);
4375             }
4376         }
4377 
removeActivity(PackageParser.Activity a, String type)4378         public final void removeActivity(PackageParser.Activity a, String type) {
4379             mActivities.remove(a.getComponentName());
4380             if (DEBUG_SHOW_INFO) {
4381                 Log.v(TAG, "  " + type + " "
4382                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
4383                                 : a.info.name) + ":");
4384                 Log.v(TAG, "    Class=" + a.info.name);
4385             }
4386             final int NI = a.intents.size();
4387             for (int j=0; j<NI; j++) {
4388                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
4389                 if (DEBUG_SHOW_INFO) {
4390                     Log.v(TAG, "    IntentFilter:");
4391                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
4392                 }
4393                 removeFilter(intent);
4394             }
4395         }
4396 
4397         @Override
allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)4398         protected boolean allowFilterResult(
4399                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
4400             ActivityInfo filterAi = filter.activity.info;
4401             for (int i=dest.size()-1; i>=0; i--) {
4402                 ActivityInfo destAi = dest.get(i).activityInfo;
4403                 if (destAi.name == filterAi.name
4404                         && destAi.packageName == filterAi.packageName) {
4405                     return false;
4406                 }
4407             }
4408             return true;
4409         }
4410 
4411         @Override
isFilterStopped(PackageParser.ActivityIntentInfo filter)4412         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter) {
4413             PackageParser.Package p = filter.activity.owner;
4414             if (p != null) {
4415                 PackageSetting ps = (PackageSetting)p.mExtras;
4416                 if (ps != null) {
4417                     // System apps are never considered stopped for purposes of
4418                     // filtering, because there may be no way for the user to
4419                     // actually re-launch them.
4420                     return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0;
4421                 }
4422             }
4423             return false;
4424         }
4425 
4426         @Override
packageForFilter(PackageParser.ActivityIntentInfo info)4427         protected String packageForFilter(PackageParser.ActivityIntentInfo info) {
4428             return info.activity.owner.packageName;
4429         }
4430 
4431         @Override
newResult(PackageParser.ActivityIntentInfo info, int match)4432         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
4433                 int match) {
4434             if (!mSettings.isEnabledLPr(info.activity.info, mFlags)) {
4435                 return null;
4436             }
4437             final PackageParser.Activity activity = info.activity;
4438             if (mSafeMode && (activity.info.applicationInfo.flags
4439                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
4440                 return null;
4441             }
4442             final ResolveInfo res = new ResolveInfo();
4443             res.activityInfo = PackageParser.generateActivityInfo(activity,
4444                     mFlags);
4445             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
4446                 res.filter = info;
4447             }
4448             res.priority = info.getPriority();
4449             res.preferredOrder = activity.owner.mPreferredOrder;
4450             //System.out.println("Result: " + res.activityInfo.className +
4451             //                   " = " + res.priority);
4452             res.match = match;
4453             res.isDefault = info.hasDefault;
4454             res.labelRes = info.labelRes;
4455             res.nonLocalizedLabel = info.nonLocalizedLabel;
4456             res.icon = info.icon;
4457             res.system = isSystemApp(res.activityInfo.applicationInfo);
4458             return res;
4459         }
4460 
4461         @Override
sortResults(List<ResolveInfo> results)4462         protected void sortResults(List<ResolveInfo> results) {
4463             Collections.sort(results, mResolvePrioritySorter);
4464         }
4465 
4466         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)4467         protected void dumpFilter(PrintWriter out, String prefix,
4468                 PackageParser.ActivityIntentInfo filter) {
4469             out.print(prefix); out.print(
4470                     Integer.toHexString(System.identityHashCode(filter.activity)));
4471                     out.print(' ');
4472                     out.print(filter.activity.getComponentShortName());
4473                     out.print(" filter ");
4474                     out.println(Integer.toHexString(System.identityHashCode(filter)));
4475         }
4476 
4477 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
4478 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
4479 //            final List<ResolveInfo> retList = Lists.newArrayList();
4480 //            while (i.hasNext()) {
4481 //                final ResolveInfo resolveInfo = i.next();
4482 //                if (isEnabledLP(resolveInfo.activityInfo)) {
4483 //                    retList.add(resolveInfo);
4484 //                }
4485 //            }
4486 //            return retList;
4487 //        }
4488 
4489         // Keys are String (activity class name), values are Activity.
4490         private final HashMap<ComponentName, PackageParser.Activity> mActivities
4491                 = new HashMap<ComponentName, PackageParser.Activity>();
4492         private int mFlags;
4493     }
4494 
4495     private final class ServiceIntentResolver
4496             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
queryIntent(Intent intent, String resolvedType, boolean defaultOnly)4497         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
4498                 boolean defaultOnly) {
4499             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
4500             return super.queryIntent(intent, resolvedType, defaultOnly);
4501         }
4502 
queryIntent(Intent intent, String resolvedType, int flags)4503         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags) {
4504             mFlags = flags;
4505             return super.queryIntent(intent, resolvedType,
4506                 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
4507         }
4508 
queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices)4509         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
4510                 int flags, ArrayList<PackageParser.Service> packageServices) {
4511             if (packageServices == null) {
4512                 return null;
4513             }
4514             mFlags = flags;
4515             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
4516             final int N = packageServices.size();
4517             ArrayList<ArrayList<PackageParser.ServiceIntentInfo>> listCut =
4518                 new ArrayList<ArrayList<PackageParser.ServiceIntentInfo>>(N);
4519 
4520             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
4521             for (int i = 0; i < N; ++i) {
4522                 intentFilters = packageServices.get(i).intents;
4523                 if (intentFilters != null && intentFilters.size() > 0) {
4524                     listCut.add(intentFilters);
4525                 }
4526             }
4527             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
4528         }
4529 
addService(PackageParser.Service s)4530         public final void addService(PackageParser.Service s) {
4531             mServices.put(s.getComponentName(), s);
4532             if (DEBUG_SHOW_INFO) {
4533                 Log.v(TAG, "  "
4534                         + (s.info.nonLocalizedLabel != null
4535                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
4536                 Log.v(TAG, "    Class=" + s.info.name);
4537             }
4538             final int NI = s.intents.size();
4539             int j;
4540             for (j=0; j<NI; j++) {
4541                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
4542                 if (DEBUG_SHOW_INFO) {
4543                     Log.v(TAG, "    IntentFilter:");
4544                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
4545                 }
4546                 if (!intent.debugCheck()) {
4547                     Log.w(TAG, "==> For Service " + s.info.name);
4548                 }
4549                 addFilter(intent);
4550             }
4551         }
4552 
removeService(PackageParser.Service s)4553         public final void removeService(PackageParser.Service s) {
4554             mServices.remove(s.getComponentName());
4555             if (DEBUG_SHOW_INFO) {
4556                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
4557                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
4558                 Log.v(TAG, "    Class=" + s.info.name);
4559             }
4560             final int NI = s.intents.size();
4561             int j;
4562             for (j=0; j<NI; j++) {
4563                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
4564                 if (DEBUG_SHOW_INFO) {
4565                     Log.v(TAG, "    IntentFilter:");
4566                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
4567                 }
4568                 removeFilter(intent);
4569             }
4570         }
4571 
4572         @Override
allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)4573         protected boolean allowFilterResult(
4574                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
4575             ServiceInfo filterSi = filter.service.info;
4576             for (int i=dest.size()-1; i>=0; i--) {
4577                 ServiceInfo destAi = dest.get(i).serviceInfo;
4578                 if (destAi.name == filterSi.name
4579                         && destAi.packageName == filterSi.packageName) {
4580                     return false;
4581                 }
4582             }
4583             return true;
4584         }
4585 
4586         @Override
isFilterStopped(PackageParser.ServiceIntentInfo filter)4587         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter) {
4588             PackageParser.Package p = filter.service.owner;
4589             if (p != null) {
4590                 PackageSetting ps = (PackageSetting)p.mExtras;
4591                 if (ps != null) {
4592                     // System apps are never considered stopped for purposes of
4593                     // filtering, because there may be no way for the user to
4594                     // actually re-launch them.
4595                     return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0;
4596                 }
4597             }
4598             return false;
4599         }
4600 
4601         @Override
packageForFilter(PackageParser.ServiceIntentInfo info)4602         protected String packageForFilter(PackageParser.ServiceIntentInfo info) {
4603             return info.service.owner.packageName;
4604         }
4605 
4606         @Override
newResult(PackageParser.ServiceIntentInfo filter, int match)4607         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
4608                 int match) {
4609             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
4610             if (!mSettings.isEnabledLPr(info.service.info, mFlags)) {
4611                 return null;
4612             }
4613             final PackageParser.Service service = info.service;
4614             if (mSafeMode && (service.info.applicationInfo.flags
4615                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
4616                 return null;
4617             }
4618             final ResolveInfo res = new ResolveInfo();
4619             res.serviceInfo = PackageParser.generateServiceInfo(service,
4620                     mFlags);
4621             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
4622                 res.filter = filter;
4623             }
4624             res.priority = info.getPriority();
4625             res.preferredOrder = service.owner.mPreferredOrder;
4626             //System.out.println("Result: " + res.activityInfo.className +
4627             //                   " = " + res.priority);
4628             res.match = match;
4629             res.isDefault = info.hasDefault;
4630             res.labelRes = info.labelRes;
4631             res.nonLocalizedLabel = info.nonLocalizedLabel;
4632             res.icon = info.icon;
4633             res.system = isSystemApp(res.serviceInfo.applicationInfo);
4634             return res;
4635         }
4636 
4637         @Override
sortResults(List<ResolveInfo> results)4638         protected void sortResults(List<ResolveInfo> results) {
4639             Collections.sort(results, mResolvePrioritySorter);
4640         }
4641 
4642         @Override
dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)4643         protected void dumpFilter(PrintWriter out, String prefix,
4644                 PackageParser.ServiceIntentInfo filter) {
4645             out.print(prefix); out.print(
4646                     Integer.toHexString(System.identityHashCode(filter.service)));
4647                     out.print(' ');
4648                     out.print(filter.service.getComponentShortName());
4649                     out.print(" filter ");
4650                     out.println(Integer.toHexString(System.identityHashCode(filter)));
4651         }
4652 
4653 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
4654 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
4655 //            final List<ResolveInfo> retList = Lists.newArrayList();
4656 //            while (i.hasNext()) {
4657 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
4658 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
4659 //                    retList.add(resolveInfo);
4660 //                }
4661 //            }
4662 //            return retList;
4663 //        }
4664 
4665         // Keys are String (activity class name), values are Activity.
4666         private final HashMap<ComponentName, PackageParser.Service> mServices
4667                 = new HashMap<ComponentName, PackageParser.Service>();
4668         private int mFlags;
4669     };
4670 
4671     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
4672             new Comparator<ResolveInfo>() {
4673         public int compare(ResolveInfo r1, ResolveInfo r2) {
4674             int v1 = r1.priority;
4675             int v2 = r2.priority;
4676             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
4677             if (v1 != v2) {
4678                 return (v1 > v2) ? -1 : 1;
4679             }
4680             v1 = r1.preferredOrder;
4681             v2 = r2.preferredOrder;
4682             if (v1 != v2) {
4683                 return (v1 > v2) ? -1 : 1;
4684             }
4685             if (r1.isDefault != r2.isDefault) {
4686                 return r1.isDefault ? -1 : 1;
4687             }
4688             v1 = r1.match;
4689             v2 = r2.match;
4690             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
4691             if (v1 != v2) {
4692                 return (v1 > v2) ? -1 : 1;
4693             }
4694             if (r1.system != r2.system) {
4695                 return r1.system ? -1 : 1;
4696             }
4697             return 0;
4698         }
4699     };
4700 
4701     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
4702             new Comparator<ProviderInfo>() {
4703         public int compare(ProviderInfo p1, ProviderInfo p2) {
4704             final int v1 = p1.initOrder;
4705             final int v2 = p2.initOrder;
4706             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
4707         }
4708     };
4709 
sendPackageBroadcast(String action, String pkg, Bundle extras, String targetPkg, IIntentReceiver finishedReceiver)4710     static final void sendPackageBroadcast(String action, String pkg,
4711             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver) {
4712         IActivityManager am = ActivityManagerNative.getDefault();
4713         if (am != null) {
4714             try {
4715                 final Intent intent = new Intent(action,
4716                         pkg != null ? Uri.fromParts("package", pkg, null) : null);
4717                 if (extras != null) {
4718                     intent.putExtras(extras);
4719                 }
4720                 if (targetPkg != null) {
4721                     intent.setPackage(targetPkg);
4722                 }
4723                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
4724                 am.broadcastIntent(null, intent, null, finishedReceiver,
4725                         0, null, null, null, finishedReceiver != null, false);
4726             } catch (RemoteException ex) {
4727             }
4728         }
4729     }
4730 
4731     /**
4732      * Check if the external storage media is available. This is true if there
4733      * is a mounted external storage medium or if the external storage is
4734      * emulated.
4735      */
isExternalMediaAvailable()4736     private boolean isExternalMediaAvailable() {
4737         return mMediaMounted || Environment.isExternalStorageEmulated();
4738     }
4739 
nextPackageToClean(String lastPackage)4740     public String nextPackageToClean(String lastPackage) {
4741         // writer
4742         synchronized (mPackages) {
4743             if (!isExternalMediaAvailable()) {
4744                 // If the external storage is no longer mounted at this point,
4745                 // the caller may not have been able to delete all of this
4746                 // packages files and can not delete any more.  Bail.
4747                 return null;
4748             }
4749             if (lastPackage != null) {
4750                 mSettings.mPackagesToBeCleaned.remove(lastPackage);
4751             }
4752             return mSettings.mPackagesToBeCleaned.size() > 0
4753                     ? mSettings.mPackagesToBeCleaned.get(0) : null;
4754         }
4755     }
4756 
schedulePackageCleaning(String packageName)4757     void schedulePackageCleaning(String packageName) {
4758         mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE, packageName));
4759     }
4760 
startCleaningPackages()4761     void startCleaningPackages() {
4762         // reader
4763         synchronized (mPackages) {
4764             if (!isExternalMediaAvailable()) {
4765                 return;
4766             }
4767             if (mSettings.mPackagesToBeCleaned.size() <= 0) {
4768                 return;
4769             }
4770         }
4771         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
4772         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
4773         IActivityManager am = ActivityManagerNative.getDefault();
4774         if (am != null) {
4775             try {
4776                 am.startService(null, intent, null);
4777             } catch (RemoteException e) {
4778             }
4779         }
4780     }
4781 
4782     private final class AppDirObserver extends FileObserver {
AppDirObserver(String path, int mask, boolean isrom)4783         public AppDirObserver(String path, int mask, boolean isrom) {
4784             super(path, mask);
4785             mRootDir = path;
4786             mIsRom = isrom;
4787         }
4788 
onEvent(int event, String path)4789         public void onEvent(int event, String path) {
4790             String removedPackage = null;
4791             int removedUid = -1;
4792             String addedPackage = null;
4793             int addedUid = -1;
4794 
4795             // TODO post a message to the handler to obtain serial ordering
4796             synchronized (mInstallLock) {
4797                 String fullPathStr = null;
4798                 File fullPath = null;
4799                 if (path != null) {
4800                     fullPath = new File(mRootDir, path);
4801                     fullPathStr = fullPath.getPath();
4802                 }
4803 
4804                 if (DEBUG_APP_DIR_OBSERVER)
4805                     Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event));
4806 
4807                 if (!isPackageFilename(path)) {
4808                     if (DEBUG_APP_DIR_OBSERVER)
4809                         Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr);
4810                     return;
4811                 }
4812 
4813                 // Ignore packages that are being installed or
4814                 // have just been installed.
4815                 if (ignoreCodePath(fullPathStr)) {
4816                     return;
4817                 }
4818                 PackageParser.Package p = null;
4819                 // reader
4820                 synchronized (mPackages) {
4821                     p = mAppDirs.get(fullPathStr);
4822                 }
4823                 if ((event&REMOVE_EVENTS) != 0) {
4824                     if (p != null) {
4825                         removePackageLI(p, true);
4826                         removedPackage = p.applicationInfo.packageName;
4827                         removedUid = p.applicationInfo.uid;
4828                     }
4829                 }
4830 
4831                 if ((event&ADD_EVENTS) != 0) {
4832                     if (p == null) {
4833                         p = scanPackageLI(fullPath,
4834                                 (mIsRom ? PackageParser.PARSE_IS_SYSTEM
4835                                         | PackageParser.PARSE_IS_SYSTEM_DIR: 0) |
4836                                 PackageParser.PARSE_CHATTY |
4837                                 PackageParser.PARSE_MUST_BE_APK,
4838                                 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
4839                                 System.currentTimeMillis());
4840                         if (p != null) {
4841                             /*
4842                              * TODO this seems dangerous as the package may have
4843                              * changed since we last acquired the mPackages
4844                              * lock.
4845                              */
4846                             // writer
4847                             synchronized (mPackages) {
4848                                 updatePermissionsLPw(p.packageName, p,
4849                                         p.permissions.size() > 0, false, false);
4850                             }
4851                             addedPackage = p.applicationInfo.packageName;
4852                             addedUid = p.applicationInfo.uid;
4853                         }
4854                     }
4855                 }
4856 
4857                 // reader
4858                 synchronized (mPackages) {
4859                     mSettings.writeLPr();
4860                 }
4861             }
4862 
4863             if (removedPackage != null) {
4864                 Bundle extras = new Bundle(1);
4865                 extras.putInt(Intent.EXTRA_UID, removedUid);
4866                 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
4867                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
4868                         extras, null, null);
4869             }
4870             if (addedPackage != null) {
4871                 Bundle extras = new Bundle(1);
4872                 extras.putInt(Intent.EXTRA_UID, addedUid);
4873                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
4874                         extras, null, null);
4875             }
4876         }
4877 
4878         private final String mRootDir;
4879         private final boolean mIsRom;
4880     }
4881 
4882     /* Called when a downloaded package installation has been confirmed by the user */
installPackage( final Uri packageURI, final IPackageInstallObserver observer, final int flags)4883     public void installPackage(
4884             final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
4885         installPackage(packageURI, observer, flags, null);
4886     }
4887 
4888     /* Called when a downloaded package installation has been confirmed by the user */
installPackage( final Uri packageURI, final IPackageInstallObserver observer, final int flags, final String installerPackageName)4889     public void installPackage(
4890             final Uri packageURI, final IPackageInstallObserver observer, final int flags,
4891             final String installerPackageName) {
4892         installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
4893                 null);
4894     }
4895 
4896     @Override
installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest)4897     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
4898             int flags, String installerPackageName, Uri verificationURI,
4899             ManifestDigest manifestDigest) {
4900         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
4901 
4902         final int uid = Binder.getCallingUid();
4903 
4904         final int filteredFlags;
4905 
4906         if (uid == Process.SHELL_UID || uid == 0) {
4907             if (DEBUG_INSTALL) {
4908                 Slog.v(TAG, "Install from ADB");
4909             }
4910             filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
4911         } else {
4912             filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
4913         }
4914 
4915         final Message msg = mHandler.obtainMessage(INIT_COPY);
4916         msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
4917                 verificationURI, manifestDigest);
4918         mHandler.sendMessage(msg);
4919     }
4920 
4921     @Override
verifyPendingInstall(int id, int verificationCode)4922     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
4923         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
4924         final PackageVerificationResponse response = new PackageVerificationResponse(
4925                 verificationCode, Binder.getCallingUid());
4926         msg.arg1 = id;
4927         msg.obj = response;
4928         mHandler.sendMessage(msg);
4929     }
4930 
matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)4931     private ComponentName matchComponentForVerifier(String packageName,
4932             List<ResolveInfo> receivers) {
4933         ActivityInfo targetReceiver = null;
4934 
4935         final int NR = receivers.size();
4936         for (int i = 0; i < NR; i++) {
4937             final ResolveInfo info = receivers.get(i);
4938             if (info.activityInfo == null) {
4939                 continue;
4940             }
4941 
4942             if (packageName.equals(info.activityInfo.packageName)) {
4943                 targetReceiver = info.activityInfo;
4944                 break;
4945             }
4946         }
4947 
4948         if (targetReceiver == null) {
4949             return null;
4950         }
4951 
4952         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
4953     }
4954 
matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)4955     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
4956             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
4957         if (pkgInfo.verifiers.length == 0) {
4958             return null;
4959         }
4960 
4961         final int N = pkgInfo.verifiers.length;
4962         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
4963         for (int i = 0; i < N; i++) {
4964             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
4965 
4966             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
4967                     receivers);
4968             if (comp == null) {
4969                 continue;
4970             }
4971 
4972             final int verifierUid = getUidForVerifier(verifierInfo);
4973             if (verifierUid == -1) {
4974                 continue;
4975             }
4976 
4977             if (DEBUG_VERIFY) {
4978                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
4979                         + " with the correct signature");
4980             }
4981             sufficientVerifiers.add(comp);
4982             verificationState.addSufficientVerifier(verifierUid);
4983         }
4984 
4985         return sufficientVerifiers;
4986     }
4987 
getUidForVerifier(VerifierInfo verifierInfo)4988     private int getUidForVerifier(VerifierInfo verifierInfo) {
4989         synchronized (mPackages) {
4990             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
4991             if (pkg == null) {
4992                 return -1;
4993             } else if (pkg.mSignatures.length != 1) {
4994                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
4995                         + " has more than one signature; ignoring");
4996                 return -1;
4997             }
4998 
4999             /*
5000              * If the public key of the package's signature does not match
5001              * our expected public key, then this is a different package and
5002              * we should skip.
5003              */
5004 
5005             final byte[] expectedPublicKey;
5006             try {
5007                 final Signature verifierSig = pkg.mSignatures[0];
5008                 final PublicKey publicKey = verifierSig.getPublicKey();
5009                 expectedPublicKey = publicKey.getEncoded();
5010             } catch (CertificateException e) {
5011                 return -1;
5012             }
5013 
5014             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
5015 
5016             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
5017                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
5018                         + " does not have the expected public key; ignoring");
5019                 return -1;
5020             }
5021 
5022             return pkg.applicationInfo.uid;
5023         }
5024     }
5025 
finishPackageInstall(int token)5026     public void finishPackageInstall(int token) {
5027         enforceSystemOrRoot("Only the system is allowed to finish installs");
5028 
5029         if (DEBUG_INSTALL) {
5030             Slog.v(TAG, "BM finishing package install for " + token);
5031         }
5032 
5033         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
5034         mHandler.sendMessage(msg);
5035     }
5036 
5037     /**
5038      * Get the verification agent timeout.
5039      *
5040      * @return verification timeout in milliseconds
5041      */
getVerificationTimeout()5042     private long getVerificationTimeout() {
5043         return android.provider.Settings.Secure.getLong(mContext.getContentResolver(),
5044                 android.provider.Settings.Secure.PACKAGE_VERIFIER_TIMEOUT,
5045                 DEFAULT_VERIFICATION_TIMEOUT);
5046     }
5047 
5048     /**
5049      * Check whether or not package verification has been enabled.
5050      *
5051      * @return true if verification should be performed
5052      */
isVerificationEnabled()5053     private boolean isVerificationEnabled() {
5054         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
5055                 android.provider.Settings.Secure.PACKAGE_VERIFIER_ENABLE,
5056                 DEFAULT_VERIFY_ENABLE ? 1 : 0) == 1 ? true : false;
5057     }
5058 
setInstallerPackageName(String targetPackage, String installerPackageName)5059     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
5060         final int uid = Binder.getCallingUid();
5061         // writer
5062         synchronized (mPackages) {
5063             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
5064             if (targetPackageSetting == null) {
5065                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
5066             }
5067 
5068             PackageSetting installerPackageSetting;
5069             if (installerPackageName != null) {
5070                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
5071                 if (installerPackageSetting == null) {
5072                     throw new IllegalArgumentException("Unknown installer package: "
5073                             + installerPackageName);
5074                 }
5075             } else {
5076                 installerPackageSetting = null;
5077             }
5078 
5079             Signature[] callerSignature;
5080             Object obj = mSettings.getUserIdLPr(uid);
5081             if (obj != null) {
5082                 if (obj instanceof SharedUserSetting) {
5083                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
5084                 } else if (obj instanceof PackageSetting) {
5085                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
5086                 } else {
5087                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
5088                 }
5089             } else {
5090                 throw new SecurityException("Unknown calling uid " + uid);
5091             }
5092 
5093             // Verify: can't set installerPackageName to a package that is
5094             // not signed with the same cert as the caller.
5095             if (installerPackageSetting != null) {
5096                 if (compareSignatures(callerSignature,
5097                         installerPackageSetting.signatures.mSignatures)
5098                         != PackageManager.SIGNATURE_MATCH) {
5099                     throw new SecurityException(
5100                             "Caller does not have same cert as new installer package "
5101                             + installerPackageName);
5102                 }
5103             }
5104 
5105             // Verify: if target already has an installer package, it must
5106             // be signed with the same cert as the caller.
5107             if (targetPackageSetting.installerPackageName != null) {
5108                 PackageSetting setting = mSettings.mPackages.get(
5109                         targetPackageSetting.installerPackageName);
5110                 // If the currently set package isn't valid, then it's always
5111                 // okay to change it.
5112                 if (setting != null) {
5113                     if (compareSignatures(callerSignature,
5114                             setting.signatures.mSignatures)
5115                             != PackageManager.SIGNATURE_MATCH) {
5116                         throw new SecurityException(
5117                                 "Caller does not have same cert as old installer package "
5118                                 + targetPackageSetting.installerPackageName);
5119                     }
5120                 }
5121             }
5122 
5123             // Okay!
5124             targetPackageSetting.installerPackageName = installerPackageName;
5125             scheduleWriteSettingsLocked();
5126         }
5127     }
5128 
processPendingInstall(final InstallArgs args, final int currentStatus)5129     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
5130         // Queue up an async operation since the package installation may take a little while.
5131         mHandler.post(new Runnable() {
5132             public void run() {
5133                 mHandler.removeCallbacks(this);
5134                  // Result object to be returned
5135                 PackageInstalledInfo res = new PackageInstalledInfo();
5136                 res.returnCode = currentStatus;
5137                 res.uid = -1;
5138                 res.pkg = null;
5139                 res.removedInfo = new PackageRemovedInfo();
5140                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
5141                     args.doPreInstall(res.returnCode);
5142                     synchronized (mInstallLock) {
5143                         installPackageLI(args, true, res);
5144                     }
5145                     args.doPostInstall(res.returnCode);
5146                 }
5147 
5148                 // A restore should be performed at this point if (a) the install
5149                 // succeeded, (b) the operation is not an update, and (c) the new
5150                 // package has a backupAgent defined.
5151                 final boolean update = res.removedInfo.removedPackage != null;
5152                 boolean doRestore = (!update
5153                         && res.pkg != null
5154                         && res.pkg.applicationInfo.backupAgentName != null);
5155 
5156                 // Set up the post-install work request bookkeeping.  This will be used
5157                 // and cleaned up by the post-install event handling regardless of whether
5158                 // there's a restore pass performed.  Token values are >= 1.
5159                 int token;
5160                 if (mNextInstallToken < 0) mNextInstallToken = 1;
5161                 token = mNextInstallToken++;
5162 
5163                 PostInstallData data = new PostInstallData(args, res);
5164                 mRunningInstalls.put(token, data);
5165                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
5166 
5167                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
5168                     // Pass responsibility to the Backup Manager.  It will perform a
5169                     // restore if appropriate, then pass responsibility back to the
5170                     // Package Manager to run the post-install observer callbacks
5171                     // and broadcasts.
5172                     IBackupManager bm = IBackupManager.Stub.asInterface(
5173                             ServiceManager.getService(Context.BACKUP_SERVICE));
5174                     if (bm != null) {
5175                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
5176                                 + " to BM for possible restore");
5177                         try {
5178                             bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
5179                         } catch (RemoteException e) {
5180                             // can't happen; the backup manager is local
5181                         } catch (Exception e) {
5182                             Slog.e(TAG, "Exception trying to enqueue restore", e);
5183                             doRestore = false;
5184                         }
5185                     } else {
5186                         Slog.e(TAG, "Backup Manager not found!");
5187                         doRestore = false;
5188                     }
5189                 }
5190 
5191                 if (!doRestore) {
5192                     // No restore possible, or the Backup Manager was mysteriously not
5193                     // available -- just fire the post-install work request directly.
5194                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
5195                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
5196                     mHandler.sendMessage(msg);
5197                 }
5198             }
5199         });
5200     }
5201 
5202     private abstract class HandlerParams {
5203         private static final int MAX_RETRIES = 4;
5204 
5205         /**
5206          * Number of times startCopy() has been attempted and had a non-fatal
5207          * error.
5208          */
5209         private int mRetries = 0;
5210 
startCopy()5211         final boolean startCopy() {
5212             boolean res;
5213             try {
5214                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy");
5215 
5216                 if (++mRetries > MAX_RETRIES) {
5217                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
5218                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
5219                     handleServiceError();
5220                     return false;
5221                 } else {
5222                     handleStartCopy();
5223                     res = true;
5224                 }
5225             } catch (RemoteException e) {
5226                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
5227                 mHandler.sendEmptyMessage(MCS_RECONNECT);
5228                 res = false;
5229             }
5230             handleReturnCode();
5231             return res;
5232         }
5233 
serviceError()5234         final void serviceError() {
5235             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
5236             handleServiceError();
5237             handleReturnCode();
5238         }
5239 
handleStartCopy()5240         abstract void handleStartCopy() throws RemoteException;
handleServiceError()5241         abstract void handleServiceError();
handleReturnCode()5242         abstract void handleReturnCode();
5243     }
5244 
5245     class MeasureParams extends HandlerParams {
5246         private final PackageStats mStats;
5247         private boolean mSuccess;
5248 
5249         private final IPackageStatsObserver mObserver;
5250 
MeasureParams(PackageStats stats, boolean success, IPackageStatsObserver observer)5251         public MeasureParams(PackageStats stats, boolean success, IPackageStatsObserver observer) {
5252             mObserver = observer;
5253             mStats = stats;
5254             mSuccess = success;
5255         }
5256 
5257         @Override
handleStartCopy()5258         void handleStartCopy() throws RemoteException {
5259             final boolean mounted;
5260 
5261             if (Environment.isExternalStorageEmulated()) {
5262                 mounted = true;
5263             } else {
5264                 final String status = Environment.getExternalStorageState();
5265 
5266                 mounted = status.equals(Environment.MEDIA_MOUNTED)
5267                         || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
5268             }
5269 
5270             if (mounted) {
5271                 final File externalCacheDir = Environment
5272                         .getExternalStorageAppCacheDirectory(mStats.packageName);
5273                 final long externalCacheSize = mContainerService
5274                         .calculateDirectorySize(externalCacheDir.getPath());
5275                 mStats.externalCacheSize = externalCacheSize;
5276 
5277                 final File externalDataDir = Environment
5278                         .getExternalStorageAppDataDirectory(mStats.packageName);
5279                 long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
5280                         .getPath());
5281 
5282                 if (externalCacheDir.getParentFile().equals(externalDataDir)) {
5283                     externalDataSize -= externalCacheSize;
5284                 }
5285                 mStats.externalDataSize = externalDataSize;
5286 
5287                 final File externalMediaDir = Environment
5288                         .getExternalStorageAppMediaDirectory(mStats.packageName);
5289                 mStats.externalMediaSize = mContainerService
5290                         .calculateDirectorySize(externalMediaDir.getPath());
5291 
5292                 final File externalObbDir = Environment
5293                         .getExternalStorageAppObbDirectory(mStats.packageName);
5294                 mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir
5295                         .getPath());
5296             }
5297         }
5298 
5299         @Override
handleReturnCode()5300         void handleReturnCode() {
5301             if (mObserver != null) {
5302                 try {
5303                     mObserver.onGetStatsCompleted(mStats, mSuccess);
5304                 } catch (RemoteException e) {
5305                     Slog.i(TAG, "Observer no longer exists.");
5306                 }
5307             }
5308         }
5309 
5310         @Override
handleServiceError()5311         void handleServiceError() {
5312             Slog.e(TAG, "Could not measure application " + mStats.packageName
5313                             + " external storage");
5314         }
5315     }
5316 
5317     class InstallParams extends HandlerParams {
5318         final IPackageInstallObserver observer;
5319         int flags;
5320         final Uri packageURI;
5321         final String installerPackageName;
5322         final Uri verificationURI;
5323         final ManifestDigest manifestDigest;
5324         private InstallArgs mArgs;
5325         private int mRet;
5326 
InstallParams(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest)5327         InstallParams(Uri packageURI,
5328                 IPackageInstallObserver observer, int flags,
5329                 String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest) {
5330             this.packageURI = packageURI;
5331             this.flags = flags;
5332             this.observer = observer;
5333             this.installerPackageName = installerPackageName;
5334             this.verificationURI = verificationURI;
5335             this.manifestDigest = manifestDigest;
5336         }
5337 
installLocationPolicy(PackageInfoLite pkgLite, int flags)5338         private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
5339             String packageName = pkgLite.packageName;
5340             int installLocation = pkgLite.installLocation;
5341             boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
5342             // reader
5343             synchronized (mPackages) {
5344                 PackageParser.Package pkg = mPackages.get(packageName);
5345                 if (pkg != null) {
5346                     if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
5347                         // Check for updated system application.
5348                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
5349                             if (onSd) {
5350                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
5351                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
5352                             }
5353                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
5354                         } else {
5355                             if (onSd) {
5356                                 // Install flag overrides everything.
5357                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
5358                             }
5359                             // If current upgrade specifies particular preference
5360                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
5361                                 // Application explicitly specified internal.
5362                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
5363                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
5364                                 // App explictly prefers external. Let policy decide
5365                             } else {
5366                                 // Prefer previous location
5367                                 if (isExternal(pkg)) {
5368                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
5369                                 }
5370                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
5371                             }
5372                         }
5373                     } else {
5374                         // Invalid install. Return error code
5375                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
5376                     }
5377                 }
5378             }
5379             // All the special cases have been taken care of.
5380             // Return result based on recommended install location.
5381             if (onSd) {
5382                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
5383             }
5384             return pkgLite.recommendedInstallLocation;
5385         }
5386 
5387         /*
5388          * Invoke remote method to get package information and install
5389          * location values. Override install location based on default
5390          * policy if needed and then create install arguments based
5391          * on the install location.
5392          */
handleStartCopy()5393         public void handleStartCopy() throws RemoteException {
5394             int ret = PackageManager.INSTALL_SUCCEEDED;
5395             final boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
5396             final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
5397             final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
5398             PackageInfoLite pkgLite = null;
5399 
5400             if (onInt && onSd) {
5401                 // Check if both bits are set.
5402                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
5403                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
5404             } else if (fwdLocked && onSd) {
5405                 // Check for forward locked apps
5406                 Slog.w(TAG, "Cannot install fwd locked apps on sdcard");
5407                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
5408             } else {
5409                 final long lowThreshold;
5410 
5411                 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
5412                         .getService(DeviceStorageMonitorService.SERVICE);
5413                 if (dsm == null) {
5414                     Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
5415                     lowThreshold = 0L;
5416                 } else {
5417                     lowThreshold = dsm.getMemoryLowThreshold();
5418                 }
5419 
5420                 // Remote call to find out default install location
5421                 try {
5422                     mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
5423                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
5424                     pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags,
5425                             lowThreshold);
5426                 } finally {
5427                     mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
5428                 }
5429 
5430                 int loc = pkgLite.recommendedInstallLocation;
5431                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
5432                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
5433                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
5434                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
5435                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
5436                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
5437                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
5438                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
5439                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
5440                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
5441                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
5442                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
5443                 } else {
5444                     // Override with defaults if needed.
5445                     loc = installLocationPolicy(pkgLite, flags);
5446                     if (!onSd && !onInt) {
5447                         // Override install location with flags
5448                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
5449                             // Set the flag to install on external media.
5450                             flags |= PackageManager.INSTALL_EXTERNAL;
5451                             flags &= ~PackageManager.INSTALL_INTERNAL;
5452                         } else {
5453                             // Make sure the flag for installing on external
5454                             // media is unset
5455                             flags |= PackageManager.INSTALL_INTERNAL;
5456                             flags &= ~PackageManager.INSTALL_EXTERNAL;
5457                         }
5458                     }
5459                 }
5460             }
5461 
5462             final InstallArgs args = createInstallArgs(this);
5463             mArgs = args;
5464 
5465             if (ret == PackageManager.INSTALL_SUCCEEDED) {
5466                 /*
5467                  * Determine if we have any installed package verifiers. If we
5468                  * do, then we'll defer to them to verify the packages.
5469                  */
5470                 final int requiredUid = mRequiredVerifierPackage == null ? -1
5471                         : getPackageUid(mRequiredVerifierPackage);
5472                 if (requiredUid != -1 && isVerificationEnabled()) {
5473                     final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
5474                     verification.setDataAndType(packageURI, PACKAGE_MIME_TYPE);
5475                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
5476 
5477                     final List<ResolveInfo> receivers = queryIntentReceivers(verification, null,
5478                             PackageManager.GET_DISABLED_COMPONENTS);
5479 
5480                     if (DEBUG_VERIFY) {
5481                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
5482                                 + verification.toString() + " with " + pkgLite.verifiers.length
5483                                 + " optional verifiers");
5484                     }
5485 
5486                     final int verificationId = mPendingVerificationToken++;
5487 
5488                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
5489 
5490                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
5491                             installerPackageName);
5492 
5493                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
5494 
5495                     if (verificationURI != null) {
5496                         verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
5497                                 verificationURI);
5498                     }
5499 
5500                     final PackageVerificationState verificationState = new PackageVerificationState(
5501                             requiredUid, args);
5502 
5503                     mPendingVerification.append(verificationId, verificationState);
5504 
5505                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
5506                             receivers, verificationState);
5507 
5508                     /*
5509                      * If any sufficient verifiers were listed in the package
5510                      * manifest, attempt to ask them.
5511                      */
5512                     if (sufficientVerifiers != null) {
5513                         final int N = sufficientVerifiers.size();
5514                         if (N == 0) {
5515                             Slog.i(TAG, "Additional verifiers required, but none installed.");
5516                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
5517                         } else {
5518                             for (int i = 0; i < N; i++) {
5519                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
5520 
5521                                 final Intent sufficientIntent = new Intent(verification);
5522                                 sufficientIntent.setComponent(verifierComponent);
5523 
5524                                 mContext.sendBroadcast(sufficientIntent);
5525                             }
5526                         }
5527                     }
5528 
5529                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
5530                             mRequiredVerifierPackage, receivers);
5531                     if (ret == PackageManager.INSTALL_SUCCEEDED
5532                             && mRequiredVerifierPackage != null) {
5533                         /*
5534                          * Send the intent to the required verification agent,
5535                          * but only start the verification timeout after the
5536                          * target BroadcastReceivers have run.
5537                          */
5538                         verification.setComponent(requiredVerifierComponent);
5539                         mContext.sendOrderedBroadcast(verification,
5540                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
5541                                 new BroadcastReceiver() {
5542                                     @Override
5543                                     public void onReceive(Context context, Intent intent) {
5544                                         final Message msg = mHandler
5545                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
5546                                         msg.arg1 = verificationId;
5547                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
5548                                     }
5549                                 }, null, 0, null, null);
5550 
5551                         /*
5552                          * We don't want the copy to proceed until verification
5553                          * succeeds, so null out this field.
5554                          */
5555                         mArgs = null;
5556                     }
5557                 } else {
5558                     /*
5559                      * No package verification is enabled, so immediately start
5560                      * the remote call to initiate copy using temporary file.
5561                      */
5562                     ret = args.copyApk(mContainerService, true);
5563                 }
5564             }
5565 
5566             mRet = ret;
5567         }
5568 
5569         @Override
handleReturnCode()5570         void handleReturnCode() {
5571             // If mArgs is null, then MCS couldn't be reached. When it
5572             // reconnects, it will try again to install. At that point, this
5573             // will succeed.
5574             if (mArgs != null) {
5575                 processPendingInstall(mArgs, mRet);
5576             }
5577         }
5578 
5579         @Override
handleServiceError()5580         void handleServiceError() {
5581             mArgs = createInstallArgs(this);
5582             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
5583         }
5584     }
5585 
5586     /*
5587      * Utility class used in movePackage api.
5588      * srcArgs and targetArgs are not set for invalid flags and make
5589      * sure to do null checks when invoking methods on them.
5590      * We probably want to return ErrorPrams for both failed installs
5591      * and moves.
5592      */
5593     class MoveParams extends HandlerParams {
5594         final IPackageMoveObserver observer;
5595         final int flags;
5596         final String packageName;
5597         final InstallArgs srcArgs;
5598         final InstallArgs targetArgs;
5599         int mRet;
5600 
MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, String packageName, String dataDir)5601         MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
5602                 String packageName, String dataDir) {
5603             this.srcArgs = srcArgs;
5604             this.observer = observer;
5605             this.flags = flags;
5606             this.packageName = packageName;
5607             if (srcArgs != null) {
5608                 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
5609                 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
5610             } else {
5611                 targetArgs = null;
5612             }
5613         }
5614 
handleStartCopy()5615         public void handleStartCopy() throws RemoteException {
5616             mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
5617             // Check for storage space on target medium
5618             if (!targetArgs.checkFreeStorage(mContainerService)) {
5619                 Log.w(TAG, "Insufficient storage to install");
5620                 return;
5621             }
5622             // Create the file args now.
5623             mRet = targetArgs.copyApk(mContainerService, false);
5624             targetArgs.doPreInstall(mRet);
5625             if (DEBUG_SD_INSTALL) {
5626                 StringBuilder builder = new StringBuilder();
5627                 if (srcArgs != null) {
5628                     builder.append("src: ");
5629                     builder.append(srcArgs.getCodePath());
5630                 }
5631                 if (targetArgs != null) {
5632                     builder.append(" target : ");
5633                     builder.append(targetArgs.getCodePath());
5634                 }
5635                 Log.i(TAG, builder.toString());
5636             }
5637         }
5638 
5639         @Override
handleReturnCode()5640         void handleReturnCode() {
5641             targetArgs.doPostInstall(mRet);
5642             int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
5643             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
5644                 currentStatus = PackageManager.MOVE_SUCCEEDED;
5645             } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
5646                 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
5647             }
5648             processPendingMove(this, currentStatus);
5649         }
5650 
5651         @Override
handleServiceError()5652         void handleServiceError() {
5653             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
5654         }
5655     }
5656 
createInstallArgs(InstallParams params)5657     private InstallArgs createInstallArgs(InstallParams params) {
5658         if (installOnSd(params.flags)) {
5659             return new SdInstallArgs(params);
5660         } else {
5661             return new FileInstallArgs(params);
5662         }
5663     }
5664 
createInstallArgs(int flags, String fullCodePath, String fullResourcePath, String nativeLibraryPath)5665     private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
5666             String nativeLibraryPath) {
5667         if (installOnSd(flags)) {
5668             return new SdInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
5669         } else {
5670             return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
5671         }
5672     }
5673 
5674     // Used by package mover
createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir)5675     private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
5676         if (installOnSd(flags)) {
5677             String cid = getNextCodePath(null, pkgName, "/" + SdInstallArgs.RES_FILE_NAME);
5678             return new SdInstallArgs(packageURI, cid);
5679         } else {
5680             return new FileInstallArgs(packageURI, pkgName, dataDir);
5681         }
5682     }
5683 
5684     static abstract class InstallArgs {
5685         final IPackageInstallObserver observer;
5686         // Always refers to PackageManager flags only
5687         final int flags;
5688         final Uri packageURI;
5689         final String installerPackageName;
5690         final ManifestDigest manifestDigest;
5691 
InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, ManifestDigest manifestDigest)5692         InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
5693                 String installerPackageName, ManifestDigest manifestDigest) {
5694             this.packageURI = packageURI;
5695             this.flags = flags;
5696             this.observer = observer;
5697             this.installerPackageName = installerPackageName;
5698             this.manifestDigest = manifestDigest;
5699         }
5700 
createCopyFile()5701         abstract void createCopyFile();
copyApk(IMediaContainerService imcs, boolean temp)5702         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
doPreInstall(int status)5703         abstract int doPreInstall(int status);
doRename(int status, String pkgName, String oldCodePath)5704         abstract boolean doRename(int status, String pkgName, String oldCodePath);
doPostInstall(int status)5705         abstract int doPostInstall(int status);
getCodePath()5706         abstract String getCodePath();
getResourcePath()5707         abstract String getResourcePath();
getNativeLibraryPath()5708         abstract String getNativeLibraryPath();
5709         // Need installer lock especially for dex file removal.
cleanUpResourcesLI()5710         abstract void cleanUpResourcesLI();
doPostDeleteLI(boolean delete)5711         abstract boolean doPostDeleteLI(boolean delete);
checkFreeStorage(IMediaContainerService imcs)5712         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
5713     }
5714 
5715     class FileInstallArgs extends InstallArgs {
5716         File installDir;
5717         String codeFileName;
5718         String resourceFileName;
5719         String libraryPath;
5720         boolean created = false;
5721 
FileInstallArgs(InstallParams params)5722         FileInstallArgs(InstallParams params) {
5723             super(params.packageURI, params.observer, params.flags, params.installerPackageName,
5724                     params.manifestDigest);
5725         }
5726 
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath)5727         FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
5728             super(null, null, 0, null, null);
5729             File codeFile = new File(fullCodePath);
5730             installDir = codeFile.getParentFile();
5731             codeFileName = fullCodePath;
5732             resourceFileName = fullResourcePath;
5733             libraryPath = nativeLibraryPath;
5734         }
5735 
FileInstallArgs(Uri packageURI, String pkgName, String dataDir)5736         FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
5737             super(packageURI, null, 0, null, null);
5738             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
5739             String apkName = getNextCodePath(null, pkgName, ".apk");
5740             codeFileName = new File(installDir, apkName + ".apk").getPath();
5741             resourceFileName = getResourcePathFromCodePath();
5742             libraryPath = new File(dataDir, LIB_DIR_NAME).getPath();
5743         }
5744 
checkFreeStorage(IMediaContainerService imcs)5745         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
5746             final long lowThreshold;
5747 
5748             final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
5749                     .getService(DeviceStorageMonitorService.SERVICE);
5750             if (dsm == null) {
5751                 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
5752                 lowThreshold = 0L;
5753             } else {
5754                 if (dsm.isMemoryLow()) {
5755                     Log.w(TAG, "Memory is reported as being too low; aborting package install");
5756                     return false;
5757                 }
5758 
5759                 lowThreshold = dsm.getMemoryLowThreshold();
5760             }
5761 
5762             try {
5763                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
5764                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
5765                 return imcs.checkInternalFreeStorage(packageURI, lowThreshold);
5766             } finally {
5767                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
5768             }
5769         }
5770 
getCodePath()5771         String getCodePath() {
5772             return codeFileName;
5773         }
5774 
createCopyFile()5775         void createCopyFile() {
5776             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
5777             codeFileName = createTempPackageFile(installDir).getPath();
5778             resourceFileName = getResourcePathFromCodePath();
5779             created = true;
5780         }
5781 
copyApk(IMediaContainerService imcs, boolean temp)5782         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
5783             if (temp) {
5784                 // Generate temp file name
5785                 createCopyFile();
5786             }
5787             // Get a ParcelFileDescriptor to write to the output file
5788             File codeFile = new File(codeFileName);
5789             if (!created) {
5790                 try {
5791                     codeFile.createNewFile();
5792                     // Set permissions
5793                     if (!setPermissions()) {
5794                         // Failed setting permissions.
5795                         return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
5796                     }
5797                 } catch (IOException e) {
5798                    Slog.w(TAG, "Failed to create file " + codeFile);
5799                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
5800                 }
5801             }
5802             ParcelFileDescriptor out = null;
5803             try {
5804                 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE);
5805             } catch (FileNotFoundException e) {
5806                 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName);
5807                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
5808             }
5809             // Copy the resource now
5810             int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
5811             try {
5812                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
5813                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
5814                 ret = imcs.copyResource(packageURI, out);
5815             } finally {
5816                 try { if (out != null) out.close(); } catch (IOException e) {}
5817                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
5818             }
5819 
5820             return ret;
5821         }
5822 
doPreInstall(int status)5823         int doPreInstall(int status) {
5824             if (status != PackageManager.INSTALL_SUCCEEDED) {
5825                 cleanUp();
5826             }
5827             return status;
5828         }
5829 
doRename(int status, final String pkgName, String oldCodePath)5830         boolean doRename(int status, final String pkgName, String oldCodePath) {
5831             if (status != PackageManager.INSTALL_SUCCEEDED) {
5832                 cleanUp();
5833                 return false;
5834             } else {
5835                 // Rename based on packageName
5836                 File codeFile = new File(getCodePath());
5837                 String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
5838                 File desFile = new File(installDir, apkName + ".apk");
5839                 if (!codeFile.renameTo(desFile)) {
5840                     return false;
5841                 }
5842                 // Reset paths since the file has been renamed.
5843                 codeFileName = desFile.getPath();
5844                 resourceFileName = getResourcePathFromCodePath();
5845                 // Set permissions
5846                 if (!setPermissions()) {
5847                     // Failed setting permissions.
5848                     return false;
5849                 }
5850                 return true;
5851             }
5852         }
5853 
doPostInstall(int status)5854         int doPostInstall(int status) {
5855             if (status != PackageManager.INSTALL_SUCCEEDED) {
5856                 cleanUp();
5857             }
5858             return status;
5859         }
5860 
getResourcePath()5861         String getResourcePath() {
5862             return resourceFileName;
5863         }
5864 
getResourcePathFromCodePath()5865         String getResourcePathFromCodePath() {
5866             String codePath = getCodePath();
5867             if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
5868                 String apkNameOnly = getApkName(codePath);
5869                 return mAppInstallDir.getPath() + "/" + apkNameOnly + ".zip";
5870             } else {
5871                 return codePath;
5872             }
5873         }
5874 
5875         @Override
getNativeLibraryPath()5876         String getNativeLibraryPath() {
5877             return libraryPath;
5878         }
5879 
cleanUp()5880         private boolean cleanUp() {
5881             boolean ret = true;
5882             String sourceDir = getCodePath();
5883             String publicSourceDir = getResourcePath();
5884             if (sourceDir != null) {
5885                 File sourceFile = new File(sourceDir);
5886                 if (!sourceFile.exists()) {
5887                     Slog.w(TAG, "Package source " + sourceDir + " does not exist.");
5888                     ret = false;
5889                 }
5890                 // Delete application's code and resources
5891                 sourceFile.delete();
5892             }
5893             if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) {
5894                 final File publicSourceFile = new File(publicSourceDir);
5895                 if (!publicSourceFile.exists()) {
5896                     Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist.");
5897                 }
5898                 if (publicSourceFile.exists()) {
5899                     publicSourceFile.delete();
5900                 }
5901             }
5902             return ret;
5903         }
5904 
cleanUpResourcesLI()5905         void cleanUpResourcesLI() {
5906             String sourceDir = getCodePath();
5907             if (cleanUp()) {
5908                 int retCode = mInstaller.rmdex(sourceDir);
5909                 if (retCode < 0) {
5910                     Slog.w(TAG, "Couldn't remove dex file for package: "
5911                             +  " at location "
5912                             + sourceDir + ", retcode=" + retCode);
5913                     // we don't consider this to be a failure of the core package deletion
5914                 }
5915             }
5916         }
5917 
setPermissions()5918         private boolean setPermissions() {
5919             // TODO Do this in a more elegant way later on. for now just a hack
5920             if (!isFwdLocked()) {
5921                 final int filePermissions =
5922                     FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
5923                     |FileUtils.S_IROTH;
5924                 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1);
5925                 if (retCode != 0) {
5926                     Slog.e(TAG, "Couldn't set new package file permissions for " +
5927                             getCodePath()
5928                             + ". The return code was: " + retCode);
5929                     // TODO Define new internal error
5930                     return false;
5931                 }
5932                 return true;
5933             }
5934             return true;
5935         }
5936 
doPostDeleteLI(boolean delete)5937         boolean doPostDeleteLI(boolean delete) {
5938             // XXX err, shouldn't we respect the delete flag?
5939             cleanUpResourcesLI();
5940             return true;
5941         }
5942 
isFwdLocked()5943         private boolean isFwdLocked() {
5944             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
5945         }
5946     }
5947 
5948     /**
5949      * Extract the MountService "container ID" from the full code path of an
5950      * .apk.
5951      */
cidFromCodePath(String fullCodePath)5952     static String cidFromCodePath(String fullCodePath) {
5953         int eidx = fullCodePath.lastIndexOf("/");
5954         String subStr1 = fullCodePath.substring(0, eidx);
5955         int sidx = subStr1.lastIndexOf("/");
5956         return subStr1.substring(sidx+1, eidx);
5957     }
5958 
5959     class SdInstallArgs extends InstallArgs {
5960         static final String RES_FILE_NAME = "pkg.apk";
5961 
5962         String cid;
5963         String packagePath;
5964         String libraryPath;
5965 
SdInstallArgs(InstallParams params)5966         SdInstallArgs(InstallParams params) {
5967             super(params.packageURI, params.observer, params.flags, params.installerPackageName,
5968                     params.manifestDigest);
5969         }
5970 
SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath)5971         SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
5972             super(null, null, PackageManager.INSTALL_EXTERNAL, null, null);
5973             // Extract cid from fullCodePath
5974             int eidx = fullCodePath.lastIndexOf("/");
5975             String subStr1 = fullCodePath.substring(0, eidx);
5976             int sidx = subStr1.lastIndexOf("/");
5977             cid = subStr1.substring(sidx+1, eidx);
5978             setCachePath(subStr1);
5979         }
5980 
SdInstallArgs(String cid)5981         SdInstallArgs(String cid) {
5982             super(null, null, PackageManager.INSTALL_EXTERNAL, null, null);
5983             this.cid = cid;
5984             setCachePath(PackageHelper.getSdDir(cid));
5985         }
5986 
SdInstallArgs(Uri packageURI, String cid)5987         SdInstallArgs(Uri packageURI, String cid) {
5988             super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null, null);
5989             this.cid = cid;
5990         }
5991 
createCopyFile()5992         void createCopyFile() {
5993             cid = getTempContainerId();
5994         }
5995 
checkFreeStorage(IMediaContainerService imcs)5996         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
5997             try {
5998                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
5999                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
6000                 return imcs.checkExternalFreeStorage(packageURI);
6001             } finally {
6002                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
6003             }
6004         }
6005 
copyApk(IMediaContainerService imcs, boolean temp)6006         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
6007             if (temp) {
6008                 createCopyFile();
6009             } else {
6010                 /*
6011                  * Pre-emptively destroy the container since it's destroyed if
6012                  * copying fails due to it existing anyway.
6013                  */
6014                 PackageHelper.destroySdDir(cid);
6015             }
6016 
6017             final String newCachePath;
6018             try {
6019                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
6020                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
6021                 newCachePath = imcs.copyResourceToContainer(packageURI, cid,
6022                         getEncryptKey(), RES_FILE_NAME);
6023             } finally {
6024                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
6025             }
6026 
6027             if (newCachePath != null) {
6028                 setCachePath(newCachePath);
6029                 return PackageManager.INSTALL_SUCCEEDED;
6030             } else {
6031                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
6032             }
6033         }
6034 
6035         @Override
getCodePath()6036         String getCodePath() {
6037             return packagePath;
6038         }
6039 
6040         @Override
getResourcePath()6041         String getResourcePath() {
6042             return packagePath;
6043         }
6044 
6045         @Override
getNativeLibraryPath()6046         String getNativeLibraryPath() {
6047             return libraryPath;
6048         }
6049 
doPreInstall(int status)6050         int doPreInstall(int status) {
6051             if (status != PackageManager.INSTALL_SUCCEEDED) {
6052                 // Destroy container
6053                 PackageHelper.destroySdDir(cid);
6054             } else {
6055                 boolean mounted = PackageHelper.isContainerMounted(cid);
6056                 if (!mounted) {
6057                     String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
6058                             Process.SYSTEM_UID);
6059                     if (newCachePath != null) {
6060                         setCachePath(newCachePath);
6061                     } else {
6062                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
6063                     }
6064                 }
6065             }
6066             return status;
6067         }
6068 
doRename(int status, final String pkgName, String oldCodePath)6069         boolean doRename(int status, final String pkgName,
6070                 String oldCodePath) {
6071             String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
6072             String newCachePath = null;
6073             if (PackageHelper.isContainerMounted(cid)) {
6074                 // Unmount the container
6075                 if (!PackageHelper.unMountSdDir(cid)) {
6076                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
6077                     return false;
6078                 }
6079             }
6080             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
6081                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
6082                         " which might be stale. Will try to clean up.");
6083                 // Clean up the stale container and proceed to recreate.
6084                 if (!PackageHelper.destroySdDir(newCacheId)) {
6085                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
6086                     return false;
6087                 }
6088                 // Successfully cleaned up stale container. Try to rename again.
6089                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
6090                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
6091                             + " inspite of cleaning it up.");
6092                     return false;
6093                 }
6094             }
6095             if (!PackageHelper.isContainerMounted(newCacheId)) {
6096                 Slog.w(TAG, "Mounting container " + newCacheId);
6097                 newCachePath = PackageHelper.mountSdDir(newCacheId,
6098                         getEncryptKey(), Process.SYSTEM_UID);
6099             } else {
6100                 newCachePath = PackageHelper.getSdDir(newCacheId);
6101             }
6102             if (newCachePath == null) {
6103                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
6104                 return false;
6105             }
6106             Log.i(TAG, "Succesfully renamed " + cid +
6107                     " to " + newCacheId +
6108                     " at new path: " + newCachePath);
6109             cid = newCacheId;
6110             setCachePath(newCachePath);
6111             return true;
6112         }
6113 
setCachePath(String newCachePath)6114         private void setCachePath(String newCachePath) {
6115             File cachePath = new File(newCachePath);
6116             libraryPath = new File(cachePath, LIB_DIR_NAME).getPath();
6117             packagePath = new File(cachePath, RES_FILE_NAME).getPath();
6118         }
6119 
doPostInstall(int status)6120         int doPostInstall(int status) {
6121             if (status != PackageManager.INSTALL_SUCCEEDED) {
6122                 cleanUp();
6123             } else {
6124                 boolean mounted = PackageHelper.isContainerMounted(cid);
6125                 if (!mounted) {
6126                     PackageHelper.mountSdDir(cid,
6127                             getEncryptKey(), Process.myUid());
6128                 }
6129             }
6130             return status;
6131         }
6132 
cleanUp()6133         private void cleanUp() {
6134             // Destroy secure container
6135             PackageHelper.destroySdDir(cid);
6136         }
6137 
cleanUpResourcesLI()6138         void cleanUpResourcesLI() {
6139             String sourceFile = getCodePath();
6140             // Remove dex file
6141             int retCode = mInstaller.rmdex(sourceFile);
6142             if (retCode < 0) {
6143                 Slog.w(TAG, "Couldn't remove dex file for package: "
6144                         + " at location "
6145                         + sourceFile.toString() + ", retcode=" + retCode);
6146                 // we don't consider this to be a failure of the core package deletion
6147             }
6148             cleanUp();
6149         }
6150 
matchContainer(String app)6151         boolean matchContainer(String app) {
6152             if (cid.startsWith(app)) {
6153                 return true;
6154             }
6155             return false;
6156         }
6157 
getPackageName()6158         String getPackageName() {
6159             int idx = cid.lastIndexOf("-");
6160             if (idx == -1) {
6161                 return cid;
6162             }
6163             return cid.substring(0, idx);
6164         }
6165 
doPostDeleteLI(boolean delete)6166         boolean doPostDeleteLI(boolean delete) {
6167             boolean ret = false;
6168             boolean mounted = PackageHelper.isContainerMounted(cid);
6169             if (mounted) {
6170                 // Unmount first
6171                 ret = PackageHelper.unMountSdDir(cid);
6172             }
6173             if (ret && delete) {
6174                 cleanUpResourcesLI();
6175             }
6176             return ret;
6177         }
6178     };
6179 
6180     // Utility method used to create code paths based on package name and available index.
getNextCodePath(String oldCodePath, String prefix, String suffix)6181     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
6182         String idxStr = "";
6183         int idx = 1;
6184         // Fall back to default value of idx=1 if prefix is not
6185         // part of oldCodePath
6186         if (oldCodePath != null) {
6187             String subStr = oldCodePath;
6188             // Drop the suffix right away
6189             if (subStr.endsWith(suffix)) {
6190                 subStr = subStr.substring(0, subStr.length() - suffix.length());
6191             }
6192             // If oldCodePath already contains prefix find out the
6193             // ending index to either increment or decrement.
6194             int sidx = subStr.lastIndexOf(prefix);
6195             if (sidx != -1) {
6196                 subStr = subStr.substring(sidx + prefix.length());
6197                 if (subStr != null) {
6198                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
6199                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
6200                     }
6201                     try {
6202                         idx = Integer.parseInt(subStr);
6203                         if (idx <= 1) {
6204                             idx++;
6205                         } else {
6206                             idx--;
6207                         }
6208                     } catch(NumberFormatException e) {
6209                     }
6210                 }
6211             }
6212         }
6213         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
6214         return prefix + idxStr;
6215     }
6216 
6217     // Utility method used to ignore ADD/REMOVE events
6218     // by directory observer.
ignoreCodePath(String fullPathStr)6219     private static boolean ignoreCodePath(String fullPathStr) {
6220         String apkName = getApkName(fullPathStr);
6221         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
6222         if (idx != -1 && ((idx+1) < apkName.length())) {
6223             // Make sure the package ends with a numeral
6224             String version = apkName.substring(idx+1);
6225             try {
6226                 Integer.parseInt(version);
6227                 return true;
6228             } catch (NumberFormatException e) {}
6229         }
6230         return false;
6231     }
6232 
6233     // Utility method that returns the relative package path with respect
6234     // to the installation directory. Like say for /data/data/com.test-1.apk
6235     // string com.test-1 is returned.
getApkName(String codePath)6236     static String getApkName(String codePath) {
6237         if (codePath == null) {
6238             return null;
6239         }
6240         int sidx = codePath.lastIndexOf("/");
6241         int eidx = codePath.lastIndexOf(".");
6242         if (eidx == -1) {
6243             eidx = codePath.length();
6244         } else if (eidx == 0) {
6245             Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name");
6246             return null;
6247         }
6248         return codePath.substring(sidx+1, eidx);
6249     }
6250 
6251     class PackageInstalledInfo {
6252         String name;
6253         int uid;
6254         PackageParser.Package pkg;
6255         int returnCode;
6256         PackageRemovedInfo removedInfo;
6257     }
6258 
6259     /*
6260      * Install a non-existing package.
6261      */
installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, String installerPackageName, PackageInstalledInfo res)6262     private void installNewPackageLI(PackageParser.Package pkg,
6263             int parseFlags,
6264             int scanMode,
6265             String installerPackageName, PackageInstalledInfo res) {
6266         // Remember this for later, in case we need to rollback this install
6267         String pkgName = pkg.packageName;
6268 
6269         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
6270         res.name = pkgName;
6271         synchronized(mPackages) {
6272             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
6273                 // A package with the same name is already installed, though
6274                 // it has been renamed to an older name.  The package we
6275                 // are trying to install should be installed as an update to
6276                 // the existing one, but that has not been requested, so bail.
6277                 Slog.w(TAG, "Attempt to re-install " + pkgName
6278                         + " without first uninstalling package running as "
6279                         + mSettings.mRenamedPackages.get(pkgName));
6280                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
6281                 return;
6282             }
6283             if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) {
6284                 // Don't allow installation over an existing package with the same name.
6285                 Slog.w(TAG, "Attempt to re-install " + pkgName
6286                         + " without first uninstalling.");
6287                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
6288                 return;
6289             }
6290         }
6291         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
6292         PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
6293                 System.currentTimeMillis());
6294         if (newPackage == null) {
6295             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
6296             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
6297                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
6298             }
6299         } else {
6300             updateSettingsLI(newPackage,
6301                     installerPackageName,
6302                     res);
6303             // delete the partially installed application. the data directory will have to be
6304             // restored if it was already existing
6305             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
6306                 // remove package from internal structures.  Note that we want deletePackageX to
6307                 // delete the package data and cache directories that it created in
6308                 // scanPackageLocked, unless those directories existed before we even tried to
6309                 // install.
6310                 deletePackageLI(
6311                         pkgName, false,
6312                         dataDirExists ? PackageManager.DONT_DELETE_DATA : 0,
6313                                 res.removedInfo, true);
6314             }
6315         }
6316     }
6317 
replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, String installerPackageName, PackageInstalledInfo res)6318     private void replacePackageLI(PackageParser.Package pkg,
6319             int parseFlags,
6320             int scanMode,
6321             String installerPackageName, PackageInstalledInfo res) {
6322 
6323         PackageParser.Package oldPackage;
6324         String pkgName = pkg.packageName;
6325         // First find the old package info and check signatures
6326         synchronized(mPackages) {
6327             oldPackage = mPackages.get(pkgName);
6328             if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
6329                     != PackageManager.SIGNATURE_MATCH) {
6330                 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
6331                 return;
6332             }
6333         }
6334         boolean sysPkg = (isSystemApp(oldPackage));
6335         if (sysPkg) {
6336             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res);
6337         } else {
6338             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res);
6339         }
6340     }
6341 
replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanMode, String installerPackageName, PackageInstalledInfo res)6342     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
6343             PackageParser.Package pkg,
6344             int parseFlags, int scanMode,
6345             String installerPackageName, PackageInstalledInfo res) {
6346         PackageParser.Package newPackage = null;
6347         String pkgName = deletedPackage.packageName;
6348         boolean deletedPkg = true;
6349         boolean updatedSettings = false;
6350 
6351         long origUpdateTime;
6352         if (pkg.mExtras != null) {
6353             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
6354         } else {
6355             origUpdateTime = 0;
6356         }
6357 
6358         // First delete the existing package while retaining the data directory
6359         if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA,
6360                 res.removedInfo, true)) {
6361             // If the existing package wasn't successfully deleted
6362             res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
6363             deletedPkg = false;
6364         } else {
6365             // Successfully deleted the old package. Now proceed with re-installation
6366             mLastScanError = PackageManager.INSTALL_SUCCEEDED;
6367             newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
6368                     System.currentTimeMillis());
6369             if (newPackage == null) {
6370                 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
6371                 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
6372                     res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
6373                 }
6374             } else {
6375                 updateSettingsLI(newPackage,
6376                         installerPackageName,
6377                         res);
6378                 updatedSettings = true;
6379             }
6380         }
6381 
6382         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
6383             // remove package from internal structures.  Note that we want deletePackageX to
6384             // delete the package data and cache directories that it created in
6385             // scanPackageLocked, unless those directories existed before we even tried to
6386             // install.
6387             if(updatedSettings) {
6388                 deletePackageLI(
6389                         pkgName, true,
6390                         PackageManager.DONT_DELETE_DATA,
6391                                 res.removedInfo, true);
6392             }
6393             // Since we failed to install the new package we need to restore the old
6394             // package that we deleted.
6395             if(deletedPkg) {
6396                 File restoreFile = new File(deletedPackage.mPath);
6397                 if (restoreFile == null) {
6398                     Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName);
6399                     return;
6400                 }
6401                 // Parse old package
6402                 boolean oldOnSd = isExternal(deletedPackage);
6403                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
6404                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
6405                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
6406                 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
6407                         | SCAN_UPDATE_TIME;
6408                 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
6409                         origUpdateTime) == null) {
6410                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
6411                     return;
6412                 }
6413                 // Restore of old package succeeded. Update permissions.
6414                 // writer
6415                 synchronized (mPackages) {
6416                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
6417                             true, false, false);
6418                     // can downgrade to reader
6419                     mSettings.writeLPr();
6420                 }
6421                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
6422             }
6423         }
6424     }
6425 
replaceSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanMode, String installerPackageName, PackageInstalledInfo res)6426     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
6427             PackageParser.Package pkg,
6428             int parseFlags, int scanMode,
6429             String installerPackageName, PackageInstalledInfo res) {
6430         PackageParser.Package newPackage = null;
6431         boolean updatedSettings = false;
6432         parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
6433                 PackageParser.PARSE_IS_SYSTEM;
6434         String packageName = deletedPackage.packageName;
6435         res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
6436         if (packageName == null) {
6437             Slog.w(TAG, "Attempt to delete null packageName.");
6438             return;
6439         }
6440         PackageParser.Package oldPkg;
6441         PackageSetting oldPkgSetting;
6442         // reader
6443         synchronized (mPackages) {
6444             oldPkg = mPackages.get(packageName);
6445             oldPkgSetting = mSettings.mPackages.get(packageName);
6446             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
6447                     (oldPkgSetting == null)) {
6448                 Slog.w(TAG, "Couldn't find package:"+packageName+" information");
6449                 return;
6450             }
6451         }
6452 
6453         killApplication(packageName, oldPkg.applicationInfo.uid);
6454 
6455         res.removedInfo.uid = oldPkg.applicationInfo.uid;
6456         res.removedInfo.removedPackage = packageName;
6457         // Remove existing system package
6458         removePackageLI(oldPkg, true);
6459         // writer
6460         synchronized (mPackages) {
6461             if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
6462                 // We didn't need to disable the .apk as a current system package,
6463                 // which means we are replacing another update that is already
6464                 // installed.  We need to make sure to delete the older one's .apk.
6465                 res.removedInfo.args = createInstallArgs(isExternal(pkg)
6466                         ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL,
6467                         deletedPackage.applicationInfo.sourceDir,
6468                         deletedPackage.applicationInfo.publicSourceDir,
6469                         deletedPackage.applicationInfo.nativeLibraryDir);
6470             } else {
6471                 res.removedInfo.args = null;
6472             }
6473         }
6474 
6475         // Successfully disabled the old package. Now proceed with re-installation
6476         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
6477         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
6478         newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0);
6479         if (newPackage == null) {
6480             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
6481             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
6482                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
6483             }
6484         } else {
6485             if (newPackage.mExtras != null) {
6486                 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;
6487                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
6488                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
6489             }
6490             updateSettingsLI(newPackage, installerPackageName, res);
6491             updatedSettings = true;
6492         }
6493 
6494         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
6495             // Re installation failed. Restore old information
6496             // Remove new pkg information
6497             if (newPackage != null) {
6498                 removePackageLI(newPackage, true);
6499             }
6500             // Add back the old system package
6501             scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0);
6502             // Restore the old system information in Settings
6503             synchronized(mPackages) {
6504                 if (updatedSettings) {
6505                     mSettings.enableSystemPackageLPw(packageName);
6506                     mSettings.setInstallerPackageName(packageName,
6507                             oldPkgSetting.installerPackageName);
6508                 }
6509                 mSettings.writeLPr();
6510             }
6511         }
6512     }
6513 
6514     // Utility method used to move dex files during install.
moveDexFilesLI(PackageParser.Package newPackage)6515     private int moveDexFilesLI(PackageParser.Package newPackage) {
6516         int retCode;
6517         if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
6518             retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
6519             if (retCode != 0) {
6520                 if (mNoDexOpt) {
6521                     /*
6522                      * If we're in an engineering build, programs are lazily run
6523                      * through dexopt. If the .dex file doesn't exist yet, it
6524                      * will be created when the program is run next.
6525                      */
6526                     Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath);
6527                 } else {
6528                     Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath);
6529                     return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6530                 }
6531             }
6532         }
6533         return PackageManager.INSTALL_SUCCEEDED;
6534     }
6535 
updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, PackageInstalledInfo res)6536     private void updateSettingsLI(PackageParser.Package newPackage,
6537             String installerPackageName, PackageInstalledInfo res) {
6538         String pkgName = newPackage.packageName;
6539         synchronized (mPackages) {
6540             //write settings. the installStatus will be incomplete at this stage.
6541             //note that the new package setting would have already been
6542             //added to mPackages. It hasn't been persisted yet.
6543             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
6544             mSettings.writeLPr();
6545         }
6546 
6547         if ((res.returnCode = moveDexFilesLI(newPackage))
6548                 != PackageManager.INSTALL_SUCCEEDED) {
6549             // Discontinue if moving dex files failed.
6550             return;
6551         }
6552         if((res.returnCode = setPermissionsLI(newPackage))
6553                 != PackageManager.INSTALL_SUCCEEDED) {
6554             mInstaller.rmdex(newPackage.mScanPath);
6555             return;
6556         } else {
6557             Log.d(TAG, "New package installed in " + newPackage.mPath);
6558         }
6559         synchronized (mPackages) {
6560             updatePermissionsLPw(newPackage.packageName, newPackage,
6561                     newPackage.permissions.size() > 0, true, false);
6562             res.name = pkgName;
6563             res.uid = newPackage.applicationInfo.uid;
6564             res.pkg = newPackage;
6565             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
6566             mSettings.setInstallerPackageName(pkgName, installerPackageName);
6567             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
6568             //to update install status
6569             mSettings.writeLPr();
6570         }
6571     }
6572 
installPackageLI(InstallArgs args, boolean newInstall, PackageInstalledInfo res)6573     private void installPackageLI(InstallArgs args,
6574             boolean newInstall, PackageInstalledInfo res) {
6575         int pFlags = args.flags;
6576         String installerPackageName = args.installerPackageName;
6577         File tmpPackageFile = new File(args.getCodePath());
6578         boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
6579         boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
6580         boolean replace = false;
6581         int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
6582                 | (newInstall ? SCAN_NEW_INSTALL : 0);
6583         // Result object to be returned
6584         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
6585 
6586         // Retrieve PackageSettings and parse package
6587         int parseFlags = PackageParser.PARSE_CHATTY |
6588         (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) |
6589         (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
6590         parseFlags |= mDefParseFlags;
6591         PackageParser pp = new PackageParser(tmpPackageFile.getPath());
6592         pp.setSeparateProcesses(mSeparateProcesses);
6593         final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
6594                 null, mMetrics, parseFlags);
6595         if (pkg == null) {
6596             res.returnCode = pp.getParseError();
6597             return;
6598         }
6599         String pkgName = res.name = pkg.packageName;
6600         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
6601             if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
6602                 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
6603                 return;
6604             }
6605         }
6606         if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
6607             res.returnCode = pp.getParseError();
6608             return;
6609         }
6610 
6611         /* If the installer passed in a manifest digest, compare it now. */
6612         if (args.manifestDigest != null) {
6613             if (DEBUG_INSTALL) {
6614                 final String parsedManifest = pkg.manifestDigest == null ? "null"
6615                         : pkg.manifestDigest.toString();
6616                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
6617                         + parsedManifest);
6618             }
6619 
6620             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
6621                 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
6622                 return;
6623             }
6624         } else if (DEBUG_INSTALL) {
6625             final String parsedManifest = pkg.manifestDigest == null
6626                     ? "null" : pkg.manifestDigest.toString();
6627             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
6628         }
6629 
6630         // Get rid of all references to package scan path via parser.
6631         pp = null;
6632         String oldCodePath = null;
6633         boolean systemApp = false;
6634         synchronized (mPackages) {
6635             // Check if installing already existing package
6636             if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
6637                 String oldName = mSettings.mRenamedPackages.get(pkgName);
6638                 if (pkg.mOriginalPackages != null
6639                         && pkg.mOriginalPackages.contains(oldName)
6640                         && mPackages.containsKey(oldName)) {
6641                     // This package is derived from an original package,
6642                     // and this device has been updating from that original
6643                     // name.  We must continue using the original name, so
6644                     // rename the new package here.
6645                     pkg.setPackageName(oldName);
6646                     pkgName = pkg.packageName;
6647                     replace = true;
6648                 } else if (mPackages.containsKey(pkgName)) {
6649                     // This package, under its official name, already exists
6650                     // on the device; we should replace it.
6651                     replace = true;
6652                 }
6653             }
6654             PackageSetting ps = mSettings.mPackages.get(pkgName);
6655             if (ps != null) {
6656                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
6657                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
6658                     systemApp = (ps.pkg.applicationInfo.flags &
6659                             ApplicationInfo.FLAG_SYSTEM) != 0;
6660                 }
6661             }
6662         }
6663 
6664         if (systemApp && onSd) {
6665             // Disable updates to system apps on sdcard
6666             Slog.w(TAG, "Cannot install updates to system apps on sdcard");
6667             res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
6668             return;
6669         }
6670 
6671         if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
6672             res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6673             return;
6674         }
6675         // Set application objects path explicitly after the rename
6676         setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
6677         pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
6678         if (replace) {
6679             replacePackageLI(pkg, parseFlags, scanMode,
6680                     installerPackageName, res);
6681         } else {
6682             installNewPackageLI(pkg, parseFlags, scanMode,
6683                     installerPackageName,res);
6684         }
6685     }
6686 
setPermissionsLI(PackageParser.Package newPackage)6687     private int setPermissionsLI(PackageParser.Package newPackage) {
6688         int retCode = 0;
6689         // TODO Gross hack but fix later. Ideally move this to be a post installation
6690         // check after alloting uid.
6691         if (isForwardLocked(newPackage)) {
6692             File destResourceFile = new File(newPackage.applicationInfo.publicSourceDir);
6693             try {
6694                 extractPublicFiles(newPackage, destResourceFile);
6695             } catch (IOException e) {
6696                 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" +
6697                            " forward-locked app.");
6698                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6699             } finally {
6700                 //TODO clean up the extracted public files
6701             }
6702             retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath),
6703                     newPackage.applicationInfo.uid);
6704         } else {
6705             // The permissions on the resource file was set when it was copied for
6706             // non forward locked apps and apps on sdcard
6707         }
6708 
6709         if (retCode != 0) {
6710             Slog.e(TAG, "Couldn't set new package file permissions for " + newPackage.mPath
6711                     + ". The return code was: " + retCode);
6712             // TODO Define new internal error
6713             return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
6714         }
6715         return PackageManager.INSTALL_SUCCEEDED;
6716     }
6717 
isForwardLocked(PackageParser.Package pkg)6718     private static boolean isForwardLocked(PackageParser.Package pkg) {
6719         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
6720     }
6721 
isExternal(PackageParser.Package pkg)6722     private static boolean isExternal(PackageParser.Package pkg) {
6723         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
6724     }
6725 
isSystemApp(PackageParser.Package pkg)6726     private static boolean isSystemApp(PackageParser.Package pkg) {
6727         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
6728     }
6729 
isSystemApp(ApplicationInfo info)6730     private static boolean isSystemApp(ApplicationInfo info) {
6731         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
6732     }
6733 
isUpdatedSystemApp(PackageParser.Package pkg)6734     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
6735         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
6736     }
6737 
extractPublicFiles(PackageParser.Package newPackage, File publicZipFile)6738     private void extractPublicFiles(PackageParser.Package newPackage,
6739                                     File publicZipFile) throws IOException {
6740         final FileOutputStream fstr = new FileOutputStream(publicZipFile);
6741         final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr);
6742         final ZipFile privateZip = new ZipFile(newPackage.mPath);
6743 
6744         // Copy manifest, resources.arsc and res directory to public zip
6745 
6746         final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries();
6747         while (privateZipEntries.hasMoreElements()) {
6748             final ZipEntry zipEntry = privateZipEntries.nextElement();
6749             final String zipEntryName = zipEntry.getName();
6750             if ("AndroidManifest.xml".equals(zipEntryName)
6751                 || "resources.arsc".equals(zipEntryName)
6752                 || zipEntryName.startsWith("res/")) {
6753                 try {
6754                     copyZipEntry(zipEntry, privateZip, publicZipOutStream);
6755                 } catch (IOException e) {
6756                     try {
6757                         publicZipOutStream.close();
6758                         throw e;
6759                     } finally {
6760                         publicZipFile.delete();
6761                     }
6762                 }
6763             }
6764         }
6765 
6766         publicZipOutStream.finish();
6767         publicZipOutStream.flush();
6768         FileUtils.sync(fstr);
6769         publicZipOutStream.close();
6770         FileUtils.setPermissions(
6771                 publicZipFile.getAbsolutePath(),
6772                 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP|FileUtils.S_IROTH,
6773                 -1, -1);
6774     }
6775 
copyZipEntry(ZipEntry zipEntry, ZipFile inZipFile, ZipOutputStream outZipStream)6776     private static void copyZipEntry(ZipEntry zipEntry,
6777                                      ZipFile inZipFile,
6778                                      ZipOutputStream outZipStream) throws IOException {
6779         byte[] buffer = new byte[4096];
6780         int num;
6781 
6782         ZipEntry newEntry;
6783         if (zipEntry.getMethod() == ZipEntry.STORED) {
6784             // Preserve the STORED method of the input entry.
6785             newEntry = new ZipEntry(zipEntry);
6786         } else {
6787             // Create a new entry so that the compressed len is recomputed.
6788             newEntry = new ZipEntry(zipEntry.getName());
6789         }
6790         outZipStream.putNextEntry(newEntry);
6791 
6792         InputStream data = inZipFile.getInputStream(zipEntry);
6793         while ((num = data.read(buffer)) > 0) {
6794             outZipStream.write(buffer, 0, num);
6795         }
6796         outZipStream.flush();
6797     }
6798 
deleteTempPackageFiles()6799     private void deleteTempPackageFiles() {
6800         FilenameFilter filter = new FilenameFilter() {
6801             public boolean accept(File dir, String name) {
6802                 return name.startsWith("vmdl") && name.endsWith(".tmp");
6803             }
6804         };
6805         String tmpFilesList[] = mAppInstallDir.list(filter);
6806         if(tmpFilesList == null) {
6807             return;
6808         }
6809         for(int i = 0; i < tmpFilesList.length; i++) {
6810             File tmpFile = new File(mAppInstallDir, tmpFilesList[i]);
6811             tmpFile.delete();
6812         }
6813     }
6814 
createTempPackageFile(File installDir)6815     private File createTempPackageFile(File installDir) {
6816         File tmpPackageFile;
6817         try {
6818             tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir);
6819         } catch (IOException e) {
6820             Slog.e(TAG, "Couldn't create temp file for downloaded package file.");
6821             return null;
6822         }
6823         try {
6824             FileUtils.setPermissions(
6825                     tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
6826                     -1, -1);
6827         } catch (IOException e) {
6828             Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
6829             return null;
6830         }
6831         return tmpPackageFile;
6832     }
6833 
deletePackage(final String packageName, final IPackageDeleteObserver observer, final int flags)6834     public void deletePackage(final String packageName,
6835                               final IPackageDeleteObserver observer,
6836                               final int flags) {
6837         mContext.enforceCallingOrSelfPermission(
6838                 android.Manifest.permission.DELETE_PACKAGES, null);
6839         // Queue up an async operation since the package deletion may take a little while.
6840         mHandler.post(new Runnable() {
6841             public void run() {
6842                 mHandler.removeCallbacks(this);
6843                 final int returnCode = deletePackageX(packageName, true, true, flags);
6844                 if (observer != null) {
6845                     try {
6846                         observer.packageDeleted(packageName, returnCode);
6847                     } catch (RemoteException e) {
6848                         Log.i(TAG, "Observer no longer exists.");
6849                     } //end catch
6850                 } //end if
6851             } //end run
6852         });
6853     }
6854 
6855     /**
6856      *  This method is an internal method that could be get invoked either
6857      *  to delete an installed package or to clean up a failed installation.
6858      *  After deleting an installed package, a broadcast is sent to notify any
6859      *  listeners that the package has been installed. For cleaning up a failed
6860      *  installation, the broadcast is not necessary since the package's
6861      *  installation wouldn't have sent the initial broadcast either
6862      *  The key steps in deleting a package are
6863      *  deleting the package information in internal structures like mPackages,
6864      *  deleting the packages base directories through installd
6865      *  updating mSettings to reflect current status
6866      *  persisting settings for later use
6867      *  sending a broadcast if necessary
6868      */
deletePackageX(String packageName, boolean sendBroadCast, boolean deleteCodeAndResources, int flags)6869     private int deletePackageX(String packageName, boolean sendBroadCast,
6870                                    boolean deleteCodeAndResources, int flags) {
6871         final PackageRemovedInfo info = new PackageRemovedInfo();
6872         final boolean res;
6873 
6874         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
6875                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
6876         try {
6877             if (dpm != null && dpm.packageHasActiveAdmins(packageName)) {
6878                 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
6879                 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
6880             }
6881         } catch (RemoteException e) {
6882         }
6883 
6884         synchronized (mInstallLock) {
6885             res = deletePackageLI(packageName, deleteCodeAndResources,
6886                     flags | REMOVE_CHATTY, info, true);
6887         }
6888 
6889         if (res && sendBroadCast) {
6890             boolean systemUpdate = info.isRemovedPackageSystemUpdate;
6891             info.sendBroadcast(deleteCodeAndResources, systemUpdate);
6892 
6893             // If the removed package was a system update, the old system packaged
6894             // was re-enabled; we need to broadcast this information
6895             if (systemUpdate) {
6896                 Bundle extras = new Bundle(1);
6897                 extras.putInt(Intent.EXTRA_UID, info.removedUid >= 0 ? info.removedUid : info.uid);
6898                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
6899 
6900                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
6901                         extras, null, null);
6902                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
6903                         extras, null, null);
6904                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
6905                         null, packageName, null);
6906             }
6907         }
6908         // Force a gc here.
6909         Runtime.getRuntime().gc();
6910         // Delete the resources here after sending the broadcast to let
6911         // other processes clean up before deleting resources.
6912         if (info.args != null) {
6913             synchronized (mInstallLock) {
6914                 info.args.doPostDeleteLI(deleteCodeAndResources);
6915             }
6916         }
6917 
6918         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
6919     }
6920 
6921     static class PackageRemovedInfo {
6922         String removedPackage;
6923         int uid = -1;
6924         int removedUid = -1;
6925         boolean isRemovedPackageSystemUpdate = false;
6926         // Clean up resources deleted packages.
6927         InstallArgs args = null;
6928 
sendBroadcast(boolean fullRemove, boolean replacing)6929         void sendBroadcast(boolean fullRemove, boolean replacing) {
6930             Bundle extras = new Bundle(1);
6931             extras.putInt(Intent.EXTRA_UID, removedUid >= 0 ? removedUid : uid);
6932             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
6933             if (replacing) {
6934                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
6935             }
6936             if (removedPackage != null) {
6937                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
6938                         extras, null, null);
6939                 if (fullRemove && !replacing) {
6940                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
6941                             extras, null, null);
6942                 }
6943             }
6944             if (removedUid >= 0) {
6945                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null);
6946             }
6947         }
6948     }
6949 
6950     /*
6951      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
6952      * flag is not set, the data directory is removed as well.
6953      * make sure this flag is set for partially installed apps. If not its meaningless to
6954      * delete a partially installed application.
6955      */
removePackageDataLI(PackageParser.Package p, PackageRemovedInfo outInfo, int flags, boolean writeSettings)6956     private void removePackageDataLI(PackageParser.Package p, PackageRemovedInfo outInfo,
6957             int flags, boolean writeSettings) {
6958         String packageName = p.packageName;
6959         if (outInfo != null) {
6960             outInfo.removedPackage = packageName;
6961         }
6962         removePackageLI(p, (flags&REMOVE_CHATTY) != 0);
6963         // Retrieve object to delete permissions for shared user later on
6964         final PackageSetting deletedPs;
6965         // reader
6966         synchronized (mPackages) {
6967             deletedPs = mSettings.mPackages.get(packageName);
6968         }
6969         if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
6970             int retCode = mInstaller.remove(packageName, 0);
6971             if (retCode < 0) {
6972                 Slog.w(TAG, "Couldn't remove app data or cache directory for package: "
6973                            + packageName + ", retcode=" + retCode);
6974                 // we don't consider this to be a failure of the core package deletion
6975             } else {
6976                 // TODO: Kill the processes first
6977                 mUserManager.removePackageForAllUsers(packageName);
6978             }
6979             schedulePackageCleaning(packageName);
6980         }
6981         // writer
6982         synchronized (mPackages) {
6983             if (deletedPs != null) {
6984                 if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
6985                     if (outInfo != null) {
6986                         outInfo.removedUid = mSettings.removePackageLPw(packageName);
6987                     }
6988                     if (deletedPs != null) {
6989                         updatePermissionsLPw(deletedPs.name, null, false, false, false);
6990                         if (deletedPs.sharedUser != null) {
6991                             // remove permissions associated with package
6992                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
6993                         }
6994                     }
6995                 }
6996                 // remove from preferred activities.
6997                 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
6998                 for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
6999                     if (pa.mPref.mComponent.getPackageName().equals(deletedPs.name)) {
7000                         removed.add(pa);
7001                     }
7002                 }
7003                 for (PreferredActivity pa : removed) {
7004                     mSettings.mPreferredActivities.removeFilter(pa);
7005                 }
7006             }
7007             // can downgrade to reader
7008             if (writeSettings) {
7009                 // Save settings now
7010                 mSettings.writeLPr();
7011             }
7012         }
7013     }
7014 
7015     /*
7016      * Tries to delete system package.
7017      */
deleteSystemPackageLI(PackageParser.Package p, int flags, PackageRemovedInfo outInfo, boolean writeSettings)7018     private boolean deleteSystemPackageLI(PackageParser.Package p,
7019             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
7020         ApplicationInfo applicationInfo = p.applicationInfo;
7021         //applicable for non-partially installed applications only
7022         if (applicationInfo == null) {
7023             Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
7024             return false;
7025         }
7026         PackageSetting ps = null;
7027         // Confirm if the system package has been updated
7028         // An updated system app can be deleted. This will also have to restore
7029         // the system pkg from system partition
7030         // reader
7031         synchronized (mPackages) {
7032             ps = mSettings.getDisabledSystemPkgLPr(p.packageName);
7033         }
7034         if (ps == null) {
7035             Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName);
7036             return false;
7037         } else {
7038             Log.i(TAG, "Deleting system pkg from data partition");
7039         }
7040         // Delete the updated package
7041         outInfo.isRemovedPackageSystemUpdate = true;
7042         if (ps.versionCode < p.mVersionCode) {
7043             // Delete data for downgrades
7044             flags &= ~PackageManager.DONT_DELETE_DATA;
7045         } else {
7046             // Preserve data by setting flag
7047             flags |= PackageManager.DONT_DELETE_DATA;
7048         }
7049         boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo,
7050                 writeSettings);
7051         if (!ret) {
7052             return false;
7053         }
7054         // writer
7055         synchronized (mPackages) {
7056             // Reinstate the old system package
7057             mSettings.enableSystemPackageLPw(p.packageName);
7058             // Remove any native libraries from the upgraded package.
7059             NativeLibraryHelper.removeNativeBinariesLI(p.applicationInfo.nativeLibraryDir);
7060         }
7061         // Install the system package
7062         PackageParser.Package newPkg = scanPackageLI(ps.codePath,
7063                 PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM,
7064                 SCAN_MONITOR | SCAN_NO_PATHS, 0);
7065 
7066         if (newPkg == null) {
7067             Slog.w(TAG, "Failed to restore system package:"+p.packageName+" with error:" + mLastScanError);
7068             return false;
7069         }
7070         // writer
7071         synchronized (mPackages) {
7072             updatePermissionsLPw(newPkg.packageName, newPkg, true, true, false);
7073             // can downgrade to reader here
7074             if (writeSettings) {
7075                 mSettings.writeLPr();
7076             }
7077         }
7078         return true;
7079     }
7080 
deleteInstalledPackageLI(PackageParser.Package p, boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo, boolean writeSettings)7081     private boolean deleteInstalledPackageLI(PackageParser.Package p,
7082             boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo,
7083             boolean writeSettings) {
7084         ApplicationInfo applicationInfo = p.applicationInfo;
7085         if (applicationInfo == null) {
7086             Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
7087             return false;
7088         }
7089         if (outInfo != null) {
7090             outInfo.uid = applicationInfo.uid;
7091         }
7092 
7093         // Delete package data from internal structures and also remove data if flag is set
7094         removePackageDataLI(p, outInfo, flags, writeSettings);
7095 
7096         // Delete application code and resources
7097         if (deleteCodeAndResources) {
7098             // TODO can pick up from PackageSettings as well
7099             int installFlags = isExternal(p) ? PackageManager.INSTALL_EXTERNAL : 0;
7100             installFlags |= isForwardLocked(p) ? PackageManager.INSTALL_FORWARD_LOCK : 0;
7101             outInfo.args = createInstallArgs(installFlags, applicationInfo.sourceDir,
7102                     applicationInfo.publicSourceDir, applicationInfo.nativeLibraryDir);
7103         }
7104         return true;
7105     }
7106 
7107     /*
7108      * This method handles package deletion in general
7109      */
deletePackageLI(String packageName, boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo, boolean writeSettings)7110     private boolean deletePackageLI(String packageName,
7111             boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo,
7112             boolean writeSettings) {
7113         if (packageName == null) {
7114             Slog.w(TAG, "Attempt to delete null packageName.");
7115             return false;
7116         }
7117         PackageParser.Package p;
7118         boolean dataOnly = false;
7119         synchronized (mPackages) {
7120             p = mPackages.get(packageName);
7121             if (p == null) {
7122                 //this retrieves partially installed apps
7123                 dataOnly = true;
7124                 PackageSetting ps = mSettings.mPackages.get(packageName);
7125                 if (ps == null) {
7126                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
7127                     return false;
7128                 }
7129                 p = ps.pkg;
7130             }
7131         }
7132         if (p == null) {
7133             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
7134             return false;
7135         }
7136 
7137         if (dataOnly) {
7138             // Delete application data first
7139             removePackageDataLI(p, outInfo, flags, writeSettings);
7140             return true;
7141         }
7142         // At this point the package should have ApplicationInfo associated with it
7143         if (p.applicationInfo == null) {
7144             Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
7145             return false;
7146         }
7147         boolean ret = false;
7148         if (isSystemApp(p)) {
7149             Log.i(TAG, "Removing system package:"+p.packageName);
7150             // When an updated system application is deleted we delete the existing resources as well and
7151             // fall back to existing code in system partition
7152             ret = deleteSystemPackageLI(p, flags, outInfo, writeSettings);
7153         } else {
7154             Log.i(TAG, "Removing non-system package:"+p.packageName);
7155             // Kill application pre-emptively especially for apps on sd.
7156             killApplication(packageName, p.applicationInfo.uid);
7157             ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo,
7158                     writeSettings);
7159         }
7160         return ret;
7161     }
7162 
clearApplicationUserData(final String packageName, final IPackageDataObserver observer)7163     public void clearApplicationUserData(final String packageName,
7164             final IPackageDataObserver observer) {
7165         mContext.enforceCallingOrSelfPermission(
7166                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
7167         // Queue up an async operation since the package deletion may take a little while.
7168         mHandler.post(new Runnable() {
7169             public void run() {
7170                 mHandler.removeCallbacks(this);
7171                 final boolean succeeded;
7172                 synchronized (mInstallLock) {
7173                     succeeded = clearApplicationUserDataLI(packageName);
7174                 }
7175                 if (succeeded) {
7176                     // invoke DeviceStorageMonitor's update method to clear any notifications
7177                     DeviceStorageMonitorService dsm = (DeviceStorageMonitorService)
7178                             ServiceManager.getService(DeviceStorageMonitorService.SERVICE);
7179                     if (dsm != null) {
7180                         dsm.updateMemory();
7181                     }
7182                 }
7183                 if(observer != null) {
7184                     try {
7185                         observer.onRemoveCompleted(packageName, succeeded);
7186                     } catch (RemoteException e) {
7187                         Log.i(TAG, "Observer no longer exists.");
7188                     }
7189                 } //end if observer
7190             } //end run
7191         });
7192     }
7193 
clearApplicationUserDataLI(String packageName)7194     private boolean clearApplicationUserDataLI(String packageName) {
7195         if (packageName == null) {
7196             Slog.w(TAG, "Attempt to delete null packageName.");
7197             return false;
7198         }
7199         PackageParser.Package p;
7200         boolean dataOnly = false;
7201         synchronized (mPackages) {
7202             p = mPackages.get(packageName);
7203             if(p == null) {
7204                 dataOnly = true;
7205                 PackageSetting ps = mSettings.mPackages.get(packageName);
7206                 if((ps == null) || (ps.pkg == null)) {
7207                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
7208                     return false;
7209                 }
7210                 p = ps.pkg;
7211             }
7212         }
7213 
7214         if (!dataOnly) {
7215             //need to check this only for fully installed applications
7216             if (p == null) {
7217                 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
7218                 return false;
7219             }
7220             final ApplicationInfo applicationInfo = p.applicationInfo;
7221             if (applicationInfo == null) {
7222                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
7223                 return false;
7224             }
7225         }
7226         int retCode = mInstaller.clearUserData(packageName, 0); // TODO - correct userId
7227         if (retCode < 0) {
7228             Slog.w(TAG, "Couldn't remove cache files for package: "
7229                     + packageName);
7230             return false;
7231         }
7232         return true;
7233     }
7234 
deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)7235     public void deleteApplicationCacheFiles(final String packageName,
7236             final IPackageDataObserver observer) {
7237         mContext.enforceCallingOrSelfPermission(
7238                 android.Manifest.permission.DELETE_CACHE_FILES, null);
7239         // Queue up an async operation since the package deletion may take a little while.
7240         mHandler.post(new Runnable() {
7241             public void run() {
7242                 mHandler.removeCallbacks(this);
7243                 final boolean succeded;
7244                 synchronized (mInstallLock) {
7245                     succeded = deleteApplicationCacheFilesLI(packageName);
7246                 }
7247                 if(observer != null) {
7248                     try {
7249                         observer.onRemoveCompleted(packageName, succeded);
7250                     } catch (RemoteException e) {
7251                         Log.i(TAG, "Observer no longer exists.");
7252                     }
7253                 } //end if observer
7254             } //end run
7255         });
7256     }
7257 
deleteApplicationCacheFilesLI(String packageName)7258     private boolean deleteApplicationCacheFilesLI(String packageName) {
7259         if (packageName == null) {
7260             Slog.w(TAG, "Attempt to delete null packageName.");
7261             return false;
7262         }
7263         PackageParser.Package p;
7264         synchronized (mPackages) {
7265             p = mPackages.get(packageName);
7266         }
7267         if (p == null) {
7268             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
7269             return false;
7270         }
7271         final ApplicationInfo applicationInfo = p.applicationInfo;
7272         if (applicationInfo == null) {
7273             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
7274             return false;
7275         }
7276         int retCode = mInstaller.deleteCacheFiles(packageName);
7277         if (retCode < 0) {
7278             Slog.w(TAG, "Couldn't remove cache files for package: "
7279                        + packageName);
7280             return false;
7281         }
7282         return true;
7283     }
7284 
getPackageSizeInfo(final String packageName, final IPackageStatsObserver observer)7285     public void getPackageSizeInfo(final String packageName,
7286             final IPackageStatsObserver observer) {
7287         mContext.enforceCallingOrSelfPermission(
7288                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
7289         // Queue up an async operation since the package deletion may take a little while.
7290         mHandler.post(new Runnable() {
7291             public void run() {
7292                 mHandler.removeCallbacks(this);
7293                 PackageStats stats = new PackageStats(packageName);
7294 
7295                 final boolean success;
7296                 synchronized (mInstallLock) {
7297                     success = getPackageSizeInfoLI(packageName, stats);
7298                 }
7299 
7300                 Message msg = mHandler.obtainMessage(INIT_COPY);
7301                 msg.obj = new MeasureParams(stats, success, observer);
7302                 mHandler.sendMessage(msg);
7303             } //end run
7304         });
7305     }
7306 
getPackageSizeInfoLI(String packageName, PackageStats pStats)7307     private boolean getPackageSizeInfoLI(String packageName, PackageStats pStats) {
7308         if (packageName == null) {
7309             Slog.w(TAG, "Attempt to get size of null packageName.");
7310             return false;
7311         }
7312         PackageParser.Package p;
7313         boolean dataOnly = false;
7314         String asecPath = null;
7315         synchronized (mPackages) {
7316             p = mPackages.get(packageName);
7317             if(p == null) {
7318                 dataOnly = true;
7319                 PackageSetting ps = mSettings.mPackages.get(packageName);
7320                 if((ps == null) || (ps.pkg == null)) {
7321                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
7322                     return false;
7323                 }
7324                 p = ps.pkg;
7325             }
7326             if (p != null && isExternal(p)) {
7327                 String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir);
7328                 if (secureContainerId != null) {
7329                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
7330                 }
7331             }
7332         }
7333         String publicSrcDir = null;
7334         if(!dataOnly) {
7335             final ApplicationInfo applicationInfo = p.applicationInfo;
7336             if (applicationInfo == null) {
7337                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
7338                 return false;
7339             }
7340             if (isForwardLocked(p)) {
7341                 publicSrcDir = applicationInfo.publicSourceDir;
7342             }
7343         }
7344         int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir,
7345                 asecPath, pStats);
7346         if (res < 0) {
7347             return false;
7348         }
7349         return true;
7350     }
7351 
7352 
addPackageToPreferred(String packageName)7353     public void addPackageToPreferred(String packageName) {
7354         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
7355     }
7356 
removePackageFromPreferred(String packageName)7357     public void removePackageFromPreferred(String packageName) {
7358         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
7359     }
7360 
getPreferredPackages(int flags)7361     public List<PackageInfo> getPreferredPackages(int flags) {
7362         return new ArrayList<PackageInfo>();
7363     }
7364 
getUidTargetSdkVersionLockedLPr(int uid)7365     private int getUidTargetSdkVersionLockedLPr(int uid) {
7366         Object obj = mSettings.getUserIdLPr(uid);
7367         if (obj instanceof SharedUserSetting) {
7368             final SharedUserSetting sus = (SharedUserSetting) obj;
7369             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
7370             final Iterator<PackageSetting> it = sus.packages.iterator();
7371             while (it.hasNext()) {
7372                 final PackageSetting ps = it.next();
7373                 if (ps.pkg != null) {
7374                     int v = ps.pkg.applicationInfo.targetSdkVersion;
7375                     if (v < vers) vers = v;
7376                 }
7377             }
7378             return vers;
7379         } else if (obj instanceof PackageSetting) {
7380             final PackageSetting ps = (PackageSetting) obj;
7381             if (ps.pkg != null) {
7382                 return ps.pkg.applicationInfo.targetSdkVersion;
7383             }
7384         }
7385         return Build.VERSION_CODES.CUR_DEVELOPMENT;
7386     }
7387 
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)7388     public void addPreferredActivity(IntentFilter filter, int match,
7389             ComponentName[] set, ComponentName activity) {
7390         // writer
7391         synchronized (mPackages) {
7392             if (mContext.checkCallingOrSelfPermission(
7393                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
7394                     != PackageManager.PERMISSION_GRANTED) {
7395                 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
7396                         < Build.VERSION_CODES.FROYO) {
7397                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
7398                             + Binder.getCallingUid());
7399                     return;
7400                 }
7401                 mContext.enforceCallingOrSelfPermission(
7402                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
7403             }
7404 
7405             Slog.i(TAG, "Adding preferred activity " + activity + ":");
7406             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
7407             mSettings.mPreferredActivities.addFilter(
7408                     new PreferredActivity(filter, match, set, activity));
7409             scheduleWriteSettingsLocked();
7410         }
7411     }
7412 
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)7413     public void replacePreferredActivity(IntentFilter filter, int match,
7414             ComponentName[] set, ComponentName activity) {
7415         if (filter.countActions() != 1) {
7416             throw new IllegalArgumentException(
7417                     "replacePreferredActivity expects filter to have only 1 action.");
7418         }
7419         if (filter.countCategories() != 1) {
7420             throw new IllegalArgumentException(
7421                     "replacePreferredActivity expects filter to have only 1 category.");
7422         }
7423         if (filter.countDataAuthorities() != 0
7424                 || filter.countDataPaths() != 0
7425                 || filter.countDataSchemes() != 0
7426                 || filter.countDataTypes() != 0) {
7427             throw new IllegalArgumentException(
7428                     "replacePreferredActivity expects filter to have no data authorities, " +
7429                     "paths, schemes or types.");
7430         }
7431         synchronized (mPackages) {
7432             if (mContext.checkCallingOrSelfPermission(
7433                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
7434                     != PackageManager.PERMISSION_GRANTED) {
7435                 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
7436                         < Build.VERSION_CODES.FROYO) {
7437                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
7438                             + Binder.getCallingUid());
7439                     return;
7440                 }
7441                 mContext.enforceCallingOrSelfPermission(
7442                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
7443             }
7444 
7445             Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
7446             String action = filter.getAction(0);
7447             String category = filter.getCategory(0);
7448             while (it.hasNext()) {
7449                 PreferredActivity pa = it.next();
7450                 if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
7451                     it.remove();
7452                     Log.i(TAG, "Removed preferred activity " + pa.mPref.mComponent + ":");
7453                     filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
7454                 }
7455             }
7456             addPreferredActivity(filter, match, set, activity);
7457         }
7458     }
7459 
clearPackagePreferredActivities(String packageName)7460     public void clearPackagePreferredActivities(String packageName) {
7461         final int uid = Binder.getCallingUid();
7462         // writer
7463         synchronized (mPackages) {
7464             PackageParser.Package pkg = mPackages.get(packageName);
7465             if (pkg == null || pkg.applicationInfo.uid != uid) {
7466                 if (mContext.checkCallingOrSelfPermission(
7467                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
7468                         != PackageManager.PERMISSION_GRANTED) {
7469                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
7470                             < Build.VERSION_CODES.FROYO) {
7471                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
7472                                 + Binder.getCallingUid());
7473                         return;
7474                     }
7475                     mContext.enforceCallingOrSelfPermission(
7476                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
7477                 }
7478             }
7479 
7480             if (clearPackagePreferredActivitiesLPw(packageName)) {
7481                 scheduleWriteSettingsLocked();
7482             }
7483         }
7484     }
7485 
clearPackagePreferredActivitiesLPw(String packageName)7486     boolean clearPackagePreferredActivitiesLPw(String packageName) {
7487         boolean changed = false;
7488         Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
7489         while (it.hasNext()) {
7490             PreferredActivity pa = it.next();
7491             if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
7492                 it.remove();
7493                 changed = true;
7494             }
7495         }
7496         return changed;
7497     }
7498 
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)7499     public int getPreferredActivities(List<IntentFilter> outFilters,
7500             List<ComponentName> outActivities, String packageName) {
7501 
7502         int num = 0;
7503         // reader
7504         synchronized (mPackages) {
7505             final Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
7506             while (it.hasNext()) {
7507                 final PreferredActivity pa = it.next();
7508                 if (packageName == null
7509                         || pa.mPref.mComponent.getPackageName().equals(packageName)) {
7510                     if (outFilters != null) {
7511                         outFilters.add(new IntentFilter(pa));
7512                     }
7513                     if (outActivities != null) {
7514                         outActivities.add(pa.mPref.mComponent);
7515                     }
7516                 }
7517             }
7518         }
7519 
7520         return num;
7521     }
7522 
setApplicationEnabledSetting(String appPackageName, int newState, int flags)7523     public void setApplicationEnabledSetting(String appPackageName,
7524             int newState, int flags) {
7525         setEnabledSetting(appPackageName, null, newState, flags);
7526     }
7527 
setComponentEnabledSetting(ComponentName componentName, int newState, int flags)7528     public void setComponentEnabledSetting(ComponentName componentName,
7529             int newState, int flags) {
7530         setEnabledSetting(componentName.getPackageName(),
7531                 componentName.getClassName(), newState, flags);
7532     }
7533 
setEnabledSetting( final String packageName, String className, int newState, final int flags)7534     private void setEnabledSetting(
7535             final String packageName, String className, int newState, final int flags) {
7536         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
7537               || newState == COMPONENT_ENABLED_STATE_ENABLED
7538               || newState == COMPONENT_ENABLED_STATE_DISABLED
7539               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER)) {
7540             throw new IllegalArgumentException("Invalid new component state: "
7541                     + newState);
7542         }
7543         PackageSetting pkgSetting;
7544         final int uid = Binder.getCallingUid();
7545         final int permission = mContext.checkCallingPermission(
7546                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
7547         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
7548         boolean sendNow = false;
7549         boolean isApp = (className == null);
7550         String componentName = isApp ? packageName : className;
7551         int packageUid = -1;
7552         ArrayList<String> components;
7553 
7554         // writer
7555         synchronized (mPackages) {
7556             pkgSetting = mSettings.mPackages.get(packageName);
7557             if (pkgSetting == null) {
7558                 if (className == null) {
7559                     throw new IllegalArgumentException(
7560                             "Unknown package: " + packageName);
7561                 }
7562                 throw new IllegalArgumentException(
7563                         "Unknown component: " + packageName
7564                         + "/" + className);
7565             }
7566             if (!allowedByPermission && (uid != pkgSetting.userId)) {
7567                 throw new SecurityException(
7568                         "Permission Denial: attempt to change component state from pid="
7569                         + Binder.getCallingPid()
7570                         + ", uid=" + uid + ", package uid=" + pkgSetting.userId);
7571             }
7572             if (className == null) {
7573                 // We're dealing with an application/package level state change
7574                 if (pkgSetting.enabled == newState) {
7575                     // Nothing to do
7576                     return;
7577                 }
7578                 pkgSetting.enabled = newState;
7579                 pkgSetting.pkg.mSetEnabled = newState;
7580             } else {
7581                 // We're dealing with a component level state change
7582                 switch (newState) {
7583                 case COMPONENT_ENABLED_STATE_ENABLED:
7584                     if (!pkgSetting.enableComponentLPw(className)) {
7585                         return;
7586                     }
7587                     break;
7588                 case COMPONENT_ENABLED_STATE_DISABLED:
7589                     if (!pkgSetting.disableComponentLPw(className)) {
7590                         return;
7591                     }
7592                     break;
7593                 case COMPONENT_ENABLED_STATE_DEFAULT:
7594                     if (!pkgSetting.restoreComponentLPw(className)) {
7595                         return;
7596                     }
7597                     break;
7598                 default:
7599                     Slog.e(TAG, "Invalid new component state: " + newState);
7600                     return;
7601                 }
7602             }
7603             mSettings.writeLPr();
7604             packageUid = pkgSetting.userId;
7605             components = mPendingBroadcasts.get(packageName);
7606             final boolean newPackage = components == null;
7607             if (newPackage) {
7608                 components = new ArrayList<String>();
7609             }
7610             if (!components.contains(componentName)) {
7611                 components.add(componentName);
7612             }
7613             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
7614                 sendNow = true;
7615                 // Purge entry from pending broadcast list if another one exists already
7616                 // since we are sending one right away.
7617                 mPendingBroadcasts.remove(packageName);
7618             } else {
7619                 if (newPackage) {
7620                     mPendingBroadcasts.put(packageName, components);
7621                 }
7622                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
7623                     // Schedule a message
7624                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
7625                 }
7626             }
7627         }
7628 
7629         long callingId = Binder.clearCallingIdentity();
7630         try {
7631             if (sendNow) {
7632                 sendPackageChangedBroadcast(packageName,
7633                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
7634             }
7635         } finally {
7636             Binder.restoreCallingIdentity(callingId);
7637         }
7638     }
7639 
sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)7640     private void sendPackageChangedBroadcast(String packageName,
7641             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
7642         if (DEBUG_INSTALL)
7643             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
7644                     + componentNames);
7645         Bundle extras = new Bundle(4);
7646         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
7647         String nameList[] = new String[componentNames.size()];
7648         componentNames.toArray(nameList);
7649         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
7650         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
7651         extras.putInt(Intent.EXTRA_UID, packageUid);
7652         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null);
7653     }
7654 
setPackageStoppedState(String packageName, boolean stopped)7655     public void setPackageStoppedState(String packageName, boolean stopped) {
7656         final int uid = Binder.getCallingUid();
7657         final int permission = mContext.checkCallingOrSelfPermission(
7658                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
7659         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
7660         // writer
7661         synchronized (mPackages) {
7662             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
7663                     uid)) {
7664                 scheduleWriteStoppedPackagesLocked();
7665             }
7666         }
7667     }
7668 
getInstallerPackageName(String packageName)7669     public String getInstallerPackageName(String packageName) {
7670         // reader
7671         synchronized (mPackages) {
7672             return mSettings.getInstallerPackageNameLPr(packageName);
7673         }
7674     }
7675 
getApplicationEnabledSetting(String packageName)7676     public int getApplicationEnabledSetting(String packageName) {
7677         // reader
7678         synchronized (mPackages) {
7679             return mSettings.getApplicationEnabledSettingLPr(packageName);
7680         }
7681     }
7682 
getComponentEnabledSetting(ComponentName componentName)7683     public int getComponentEnabledSetting(ComponentName componentName) {
7684         // reader
7685         synchronized (mPackages) {
7686             return mSettings.getComponentEnabledSettingLPr(componentName);
7687         }
7688     }
7689 
enterSafeMode()7690     public void enterSafeMode() {
7691         enforceSystemOrRoot("Only the system can request entering safe mode");
7692 
7693         if (!mSystemReady) {
7694             mSafeMode = true;
7695         }
7696     }
7697 
systemReady()7698     public void systemReady() {
7699         mSystemReady = true;
7700 
7701         // Read the compatibilty setting when the system is ready.
7702         boolean compatibilityModeEnabled = android.provider.Settings.System.getInt(
7703                 mContext.getContentResolver(),
7704                 android.provider.Settings.System.COMPATIBILITY_MODE, 1) == 1;
7705         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
7706         if (DEBUG_SETTINGS) {
7707             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
7708         }
7709     }
7710 
isSafeMode()7711     public boolean isSafeMode() {
7712         return mSafeMode;
7713     }
7714 
hasSystemUidErrors()7715     public boolean hasSystemUidErrors() {
7716         return mHasSystemUidErrors;
7717     }
7718 
arrayToString(int[] array)7719     static String arrayToString(int[] array) {
7720         StringBuffer buf = new StringBuffer(128);
7721         buf.append('[');
7722         if (array != null) {
7723             for (int i=0; i<array.length; i++) {
7724                 if (i > 0) buf.append(", ");
7725                 buf.append(array[i]);
7726             }
7727         }
7728         buf.append(']');
7729         return buf.toString();
7730     }
7731 
7732     static class DumpState {
7733         public static final int DUMP_LIBS = 1 << 0;
7734 
7735         public static final int DUMP_FEATURES = 1 << 1;
7736 
7737         public static final int DUMP_RESOLVERS = 1 << 2;
7738 
7739         public static final int DUMP_PERMISSIONS = 1 << 3;
7740 
7741         public static final int DUMP_PACKAGES = 1 << 4;
7742 
7743         public static final int DUMP_SHARED_USERS = 1 << 5;
7744 
7745         public static final int DUMP_MESSAGES = 1 << 6;
7746 
7747         public static final int DUMP_PROVIDERS = 1 << 7;
7748 
7749         public static final int DUMP_VERIFIERS = 1 << 8;
7750 
7751         public static final int OPTION_SHOW_FILTERS = 1 << 0;
7752 
7753         private int mTypes;
7754 
7755         private int mOptions;
7756 
7757         private boolean mTitlePrinted;
7758 
7759         private SharedUserSetting mSharedUser;
7760 
isDumping(int type)7761         public boolean isDumping(int type) {
7762             if (mTypes == 0) {
7763                 return true;
7764             }
7765 
7766             return (mTypes & type) != 0;
7767         }
7768 
setDump(int type)7769         public void setDump(int type) {
7770             mTypes |= type;
7771         }
7772 
isOptionEnabled(int option)7773         public boolean isOptionEnabled(int option) {
7774             return (mOptions & option) != 0;
7775         }
7776 
setOptionEnabled(int option)7777         public void setOptionEnabled(int option) {
7778             mOptions |= option;
7779         }
7780 
onTitlePrinted()7781         public boolean onTitlePrinted() {
7782             final boolean printed = mTitlePrinted;
7783             mTitlePrinted = true;
7784             return printed;
7785         }
7786 
getTitlePrinted()7787         public boolean getTitlePrinted() {
7788             return mTitlePrinted;
7789         }
7790 
setTitlePrinted(boolean enabled)7791         public void setTitlePrinted(boolean enabled) {
7792             mTitlePrinted = enabled;
7793         }
7794 
getSharedUser()7795         public SharedUserSetting getSharedUser() {
7796             return mSharedUser;
7797         }
7798 
setSharedUser(SharedUserSetting user)7799         public void setSharedUser(SharedUserSetting user) {
7800             mSharedUser = user;
7801         }
7802     }
7803 
7804     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)7805     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
7806         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
7807                 != PackageManager.PERMISSION_GRANTED) {
7808             pw.println("Permission Denial: can't dump ActivityManager from from pid="
7809                     + Binder.getCallingPid()
7810                     + ", uid=" + Binder.getCallingUid()
7811                     + " without permission "
7812                     + android.Manifest.permission.DUMP);
7813             return;
7814         }
7815 
7816         DumpState dumpState = new DumpState();
7817 
7818         String packageName = null;
7819 
7820         int opti = 0;
7821         while (opti < args.length) {
7822             String opt = args[opti];
7823             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7824                 break;
7825             }
7826             opti++;
7827             if ("-a".equals(opt)) {
7828                 // Right now we only know how to print all.
7829             } else if ("-h".equals(opt)) {
7830                 pw.println("Package manager dump options:");
7831                 pw.println("  [-h] [-f] [cmd] ...");
7832                 pw.println("    -f: print details of intent filters");
7833                 pw.println("    -h: print this help");
7834                 pw.println("  cmd may be one of:");
7835                 pw.println("    l[ibraries]: list known shared libraries");
7836                 pw.println("    f[ibraries]: list device features");
7837                 pw.println("    r[esolvers]: dump intent resolvers");
7838                 pw.println("    perm[issions]: dump permissions");
7839                 pw.println("    prov[iders]: dump content providers");
7840                 pw.println("    p[ackages]: dump installed packages");
7841                 pw.println("    s[hared-users]: dump shared user IDs");
7842                 pw.println("    m[essages]: print collected runtime messages");
7843                 pw.println("    v[erifiers]: print package verifier info");
7844                 pw.println("    <package.name>: info about given package");
7845                 return;
7846             } else if ("-f".equals(opt)) {
7847                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
7848             } else {
7849                 pw.println("Unknown argument: " + opt + "; use -h for help");
7850             }
7851         }
7852 
7853         // Is the caller requesting to dump a particular piece of data?
7854         if (opti < args.length) {
7855             String cmd = args[opti];
7856             opti++;
7857             // Is this a package name?
7858             if ("android".equals(cmd) || cmd.contains(".")) {
7859                 packageName = cmd;
7860             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
7861                 dumpState.setDump(DumpState.DUMP_LIBS);
7862             } else if ("f".equals(cmd) || "features".equals(cmd)) {
7863                 dumpState.setDump(DumpState.DUMP_FEATURES);
7864             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
7865                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
7866             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
7867                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
7868             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
7869                 dumpState.setDump(DumpState.DUMP_PACKAGES);
7870             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
7871                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
7872             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
7873                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
7874             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
7875                 dumpState.setDump(DumpState.DUMP_MESSAGES);
7876             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
7877                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
7878             }
7879         }
7880 
7881         // reader
7882         synchronized (mPackages) {
7883             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
7884                 if (dumpState.onTitlePrinted())
7885                     pw.println(" ");
7886                 pw.println("Verifiers:");
7887                 pw.print("  Required: ");
7888                 pw.print(mRequiredVerifierPackage);
7889                 pw.print(" (uid=");
7890                 pw.print(getPackageUid(mRequiredVerifierPackage));
7891                 pw.println(")");
7892             }
7893 
7894             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
7895                 if (dumpState.onTitlePrinted())
7896                     pw.println(" ");
7897                 pw.println("Libraries:");
7898                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
7899                 while (it.hasNext()) {
7900                     String name = it.next();
7901                     pw.print("  ");
7902                     pw.print(name);
7903                     pw.print(" -> ");
7904                     pw.println(mSharedLibraries.get(name));
7905                 }
7906             }
7907 
7908             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
7909                 if (dumpState.onTitlePrinted())
7910                     pw.println(" ");
7911                 pw.println("Features:");
7912                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
7913                 while (it.hasNext()) {
7914                     String name = it.next();
7915                     pw.print("  ");
7916                     pw.println(name);
7917                 }
7918             }
7919 
7920             if (dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
7921                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
7922                         : "Activity Resolver Table:", "  ", packageName,
7923                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
7924                     dumpState.setTitlePrinted(true);
7925                 }
7926                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
7927                         : "Receiver Resolver Table:", "  ", packageName,
7928                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
7929                     dumpState.setTitlePrinted(true);
7930                 }
7931                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
7932                         : "Service Resolver Table:", "  ", packageName,
7933                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
7934                     dumpState.setTitlePrinted(true);
7935                 }
7936                 if (mSettings.mPreferredActivities.dump(pw,
7937                         dumpState.getTitlePrinted() ? "\nPreferred Activities:"
7938                             : "Preferred Activities:", "  ",
7939                         packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
7940                     dumpState.setTitlePrinted(true);
7941                 }
7942             }
7943 
7944             if (dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
7945                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
7946             }
7947 
7948             if (dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
7949                 boolean printedSomething = false;
7950                 for (PackageParser.Provider p : mProviders.values()) {
7951                     if (packageName != null && !packageName.equals(p.info.packageName)) {
7952                         continue;
7953                     }
7954                     if (!printedSomething) {
7955                         if (dumpState.onTitlePrinted())
7956                             pw.println(" ");
7957                         pw.println("Registered ContentProviders:");
7958                         printedSomething = true;
7959                     }
7960                     pw.print("  ["); pw.print(p.info.authority); pw.print("]: ");
7961                             pw.println(p.toString());
7962                 }
7963             }
7964 
7965             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
7966                 mSettings.dumpPackagesLPr(pw, packageName, dumpState);
7967             }
7968 
7969             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
7970                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
7971             }
7972 
7973             if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
7974                 if (dumpState.onTitlePrinted())
7975                     pw.println(" ");
7976                 mSettings.dumpReadMessagesLPr(pw, dumpState);
7977 
7978                 pw.println(" ");
7979                 pw.println("Package warning messages:");
7980                 final File fname = getSettingsProblemFile();
7981                 FileInputStream in = null;
7982                 try {
7983                     in = new FileInputStream(fname);
7984                     final int avail = in.available();
7985                     final byte[] data = new byte[avail];
7986                     in.read(data);
7987                     pw.print(new String(data));
7988                 } catch (FileNotFoundException e) {
7989                 } catch (IOException e) {
7990                 } finally {
7991                     if (in != null) {
7992                         try {
7993                             in.close();
7994                         } catch (IOException e) {
7995                         }
7996                     }
7997                 }
7998             }
7999         }
8000     }
8001 
8002     // ------- apps on sdcard specific code -------
8003     static final boolean DEBUG_SD_INSTALL = false;
8004 
8005     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
8006 
8007     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
8008 
8009     private boolean mMediaMounted = false;
8010 
getEncryptKey()8011     private String getEncryptKey() {
8012         try {
8013             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
8014                     SD_ENCRYPTION_KEYSTORE_NAME);
8015             if (sdEncKey == null) {
8016                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
8017                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
8018                 if (sdEncKey == null) {
8019                     Slog.e(TAG, "Failed to create encryption keys");
8020                     return null;
8021                 }
8022             }
8023             return sdEncKey;
8024         } catch (NoSuchAlgorithmException nsae) {
8025             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
8026             return null;
8027         } catch (IOException ioe) {
8028             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
8029             return null;
8030         }
8031 
8032     }
8033 
getTempContainerId()8034     /* package */static String getTempContainerId() {
8035         int tmpIdx = 1;
8036         String list[] = PackageHelper.getSecureContainerList();
8037         if (list != null) {
8038             for (final String name : list) {
8039                 // Ignore null and non-temporary container entries
8040                 if (name == null || !name.startsWith(mTempContainerPrefix)) {
8041                     continue;
8042                 }
8043 
8044                 String subStr = name.substring(mTempContainerPrefix.length());
8045                 try {
8046                     int cid = Integer.parseInt(subStr);
8047                     if (cid >= tmpIdx) {
8048                         tmpIdx = cid + 1;
8049                     }
8050                 } catch (NumberFormatException e) {
8051                 }
8052             }
8053         }
8054         return mTempContainerPrefix + tmpIdx;
8055     }
8056 
8057     /*
8058      * Update media status on PackageManager.
8059      */
updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)8060     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
8061         int callingUid = Binder.getCallingUid();
8062         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8063             throw new SecurityException("Media status can only be updated by the system");
8064         }
8065         // reader; this apparently protects mMediaMounted, but should probably
8066         // be a different lock in that case.
8067         synchronized (mPackages) {
8068             Log.i(TAG, "Updating external media status from "
8069                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
8070                     + (mediaStatus ? "mounted" : "unmounted"));
8071             if (DEBUG_SD_INSTALL)
8072                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
8073                         + ", mMediaMounted=" + mMediaMounted);
8074             if (mediaStatus == mMediaMounted) {
8075                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
8076                         : 0, -1);
8077                 mHandler.sendMessage(msg);
8078                 return;
8079             }
8080             mMediaMounted = mediaStatus;
8081         }
8082         // Queue up an async operation since the package installation may take a
8083         // little while.
8084         mHandler.post(new Runnable() {
8085             public void run() {
8086                 // TODO fix this; this does nothing.
8087                 mHandler.removeCallbacks(this);
8088                 updateExternalMediaStatusInner(mediaStatus, reportStatus);
8089             }
8090         });
8091     }
8092 
8093     /*
8094      * Collect information of applications on external media, map them against
8095      * existing containers and update information based on current mount status.
8096      * Please note that we always have to report status if reportStatus has been
8097      * set to true especially when unloading packages.
8098      */
updateExternalMediaStatusInner(boolean mediaStatus, boolean reportStatus)8099     private void updateExternalMediaStatusInner(boolean mediaStatus, boolean reportStatus) {
8100         // Collection of uids
8101         int uidArr[] = null;
8102         // Collection of stale containers
8103         HashSet<String> removeCids = new HashSet<String>();
8104         // Collection of packages on external media with valid containers.
8105         HashMap<SdInstallArgs, String> processCids = new HashMap<SdInstallArgs, String>();
8106         // Get list of secure containers.
8107         final String list[] = PackageHelper.getSecureContainerList();
8108         if (list == null || list.length == 0) {
8109             Log.i(TAG, "No secure containers on sdcard");
8110         } else {
8111             // Process list of secure containers and categorize them
8112             // as active or stale based on their package internal state.
8113             int uidList[] = new int[list.length];
8114             int num = 0;
8115             // reader
8116             synchronized (mPackages) {
8117                 for (String cid : list) {
8118                     SdInstallArgs args = new SdInstallArgs(cid);
8119                     if (DEBUG_SD_INSTALL)
8120                         Log.i(TAG, "Processing container " + cid);
8121                     String pkgName = args.getPackageName();
8122                     if (pkgName == null) {
8123                         if (DEBUG_SD_INSTALL)
8124                             Log.i(TAG, "Container : " + cid + " stale");
8125                         removeCids.add(cid);
8126                         continue;
8127                     }
8128                     if (DEBUG_SD_INSTALL)
8129                         Log.i(TAG, "Looking for pkg : " + pkgName);
8130                     PackageSetting ps = mSettings.mPackages.get(pkgName);
8131                     // The package status is changed only if the code path
8132                     // matches between settings and the container id.
8133                     if (ps != null && ps.codePathString != null
8134                             && ps.codePathString.equals(args.getCodePath())) {
8135                         if (DEBUG_SD_INSTALL)
8136                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
8137                                     + " at code path: " + ps.codePathString);
8138                         // We do have a valid package installed on sdcard
8139                         processCids.put(args, ps.codePathString);
8140                         int uid = ps.userId;
8141                         if (uid != -1) {
8142                             uidList[num++] = uid;
8143                         }
8144                     } else {
8145                         // Stale container on sdcard. Just delete
8146                         if (DEBUG_SD_INSTALL)
8147                             Log.i(TAG, "Container : " + cid + " stale");
8148                         removeCids.add(cid);
8149                     }
8150                 }
8151             }
8152 
8153             if (num > 0) {
8154                 // Sort uid list
8155                 Arrays.sort(uidList, 0, num);
8156                 // Throw away duplicates
8157                 uidArr = new int[num];
8158                 uidArr[0] = uidList[0];
8159                 int di = 0;
8160                 for (int i = 1; i < num; i++) {
8161                     if (uidList[i - 1] != uidList[i]) {
8162                         uidArr[di++] = uidList[i];
8163                     }
8164                 }
8165             }
8166         }
8167         // Process packages with valid entries.
8168         if (mediaStatus) {
8169             if (DEBUG_SD_INSTALL)
8170                 Log.i(TAG, "Loading packages");
8171             loadMediaPackages(processCids, uidArr, removeCids);
8172             startCleaningPackages();
8173         } else {
8174             if (DEBUG_SD_INSTALL)
8175                 Log.i(TAG, "Unloading packages");
8176             unloadMediaPackages(processCids, uidArr, reportStatus);
8177         }
8178     }
8179 
sendResourcesChangedBroadcast(boolean mediaStatus, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)8180    private void sendResourcesChangedBroadcast(boolean mediaStatus, ArrayList<String> pkgList,
8181             int uidArr[], IIntentReceiver finishedReceiver) {
8182         int size = pkgList.size();
8183         if (size > 0) {
8184             // Send broadcasts here
8185             Bundle extras = new Bundle();
8186             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
8187                     .toArray(new String[size]));
8188             if (uidArr != null) {
8189                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
8190             }
8191             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
8192                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
8193             sendPackageBroadcast(action, null, extras, null, finishedReceiver);
8194         }
8195     }
8196 
8197    /*
8198      * Look at potentially valid container ids from processCids If package
8199      * information doesn't match the one on record or package scanning fails,
8200      * the cid is added to list of removeCids. We currently don't delete stale
8201      * containers.
8202      */
loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[], HashSet<String> removeCids)8203    private void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[],
8204             HashSet<String> removeCids) {
8205         ArrayList<String> pkgList = new ArrayList<String>();
8206         Set<SdInstallArgs> keys = processCids.keySet();
8207         boolean doGc = false;
8208         for (SdInstallArgs args : keys) {
8209             String codePath = processCids.get(args);
8210             if (DEBUG_SD_INSTALL)
8211                 Log.i(TAG, "Loading container : " + args.cid);
8212             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
8213             try {
8214                 // Make sure there are no container errors first.
8215                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
8216                     Slog.e(TAG, "Failed to mount cid : " + args.cid
8217                             + " when installing from sdcard");
8218                     continue;
8219                 }
8220                 // Check code path here.
8221                 if (codePath == null || !codePath.equals(args.getCodePath())) {
8222                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
8223                             + " does not match one in settings " + codePath);
8224                     continue;
8225                 }
8226                 // Parse package
8227                 int parseFlags = PackageParser.PARSE_ON_SDCARD | mDefParseFlags;
8228                 doGc = true;
8229                 synchronized (mInstallLock) {
8230                     final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags,
8231                             0, 0);
8232                     // Scan the package
8233                     if (pkg != null) {
8234                         /*
8235                          * TODO why is the lock being held? doPostInstall is
8236                          * called in other places without the lock. This needs
8237                          * to be straightened out.
8238                          */
8239                         // writer
8240                         synchronized (mPackages) {
8241                             retCode = PackageManager.INSTALL_SUCCEEDED;
8242                             pkgList.add(pkg.packageName);
8243                             // Post process args
8244                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED);
8245                         }
8246                     } else {
8247                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
8248                     }
8249                 }
8250 
8251             } finally {
8252                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
8253                     // Don't destroy container here. Wait till gc clears things
8254                     // up.
8255                     removeCids.add(args.cid);
8256                 }
8257             }
8258         }
8259         // writer
8260         synchronized (mPackages) {
8261             // If the platform SDK has changed since the last time we booted,
8262             // we need to re-grant app permission to catch any new ones that
8263             // appear. This is really a hack, and means that apps can in some
8264             // cases get permissions that the user didn't initially explicitly
8265             // allow... it would be nice to have some better way to handle
8266             // this situation.
8267             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
8268             if (regrantPermissions)
8269                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
8270                         + mSdkVersion + "; regranting permissions for external storage");
8271             mSettings.mExternalSdkPlatform = mSdkVersion;
8272 
8273             // Make sure group IDs have been assigned, and any permission
8274             // changes in other apps are accounted for
8275             updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions);
8276             // can downgrade to reader
8277             // Persist settings
8278             mSettings.writeLPr();
8279         }
8280         // Send a broadcast to let everyone know we are done processing
8281         if (pkgList.size() > 0) {
8282             sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
8283         }
8284         // Force gc to avoid any stale parser references that we might have.
8285         if (doGc) {
8286             Runtime.getRuntime().gc();
8287         }
8288         // List stale containers and destroy stale temporary containers.
8289         if (removeCids != null) {
8290             for (String cid : removeCids) {
8291                 if (cid.startsWith(mTempContainerPrefix)) {
8292                     Log.i(TAG, "Destroying stale temporary container " + cid);
8293                     PackageHelper.destroySdDir(cid);
8294                 } else {
8295                     Log.w(TAG, "Container " + cid + " is stale");
8296                }
8297            }
8298         }
8299     }
8300 
8301    /*
8302      * Utility method to unload a list of specified containers
8303      */
unloadAllContainers(Set<SdInstallArgs> cidArgs)8304     private void unloadAllContainers(Set<SdInstallArgs> cidArgs) {
8305         // Just unmount all valid containers.
8306         for (SdInstallArgs arg : cidArgs) {
8307             synchronized (mInstallLock) {
8308                 arg.doPostDeleteLI(false);
8309            }
8310        }
8311    }
8312 
8313     /*
8314      * Unload packages mounted on external media. This involves deleting package
8315      * data from internal structures, sending broadcasts about diabled packages,
8316      * gc'ing to free up references, unmounting all secure containers
8317      * corresponding to packages on external media, and posting a
8318      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
8319      * that we always have to post this message if status has been requested no
8320      * matter what.
8321      */
unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)8322     private void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[],
8323             final boolean reportStatus) {
8324         if (DEBUG_SD_INSTALL)
8325             Log.i(TAG, "unloading media packages");
8326         ArrayList<String> pkgList = new ArrayList<String>();
8327         ArrayList<SdInstallArgs> failedList = new ArrayList<SdInstallArgs>();
8328         final Set<SdInstallArgs> keys = processCids.keySet();
8329         for (SdInstallArgs args : keys) {
8330             String pkgName = args.getPackageName();
8331             if (DEBUG_SD_INSTALL)
8332                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
8333             // Delete package internally
8334             PackageRemovedInfo outInfo = new PackageRemovedInfo();
8335             synchronized (mInstallLock) {
8336                 boolean res = deletePackageLI(pkgName, false, PackageManager.DONT_DELETE_DATA,
8337                         outInfo, false);
8338                 if (res) {
8339                     pkgList.add(pkgName);
8340                 } else {
8341                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
8342                     failedList.add(args);
8343                 }
8344             }
8345         }
8346 
8347         // reader
8348         synchronized (mPackages) {
8349             // We didn't update the settings after removing each package;
8350             // write them now for all packages.
8351             mSettings.writeLPr();
8352         }
8353 
8354         // We have to absolutely send UPDATED_MEDIA_STATUS only
8355         // after confirming that all the receivers processed the ordered
8356         // broadcast when packages get disabled, force a gc to clean things up.
8357         // and unload all the containers.
8358         if (pkgList.size() > 0) {
8359             sendResourcesChangedBroadcast(false, pkgList, uidArr, new IIntentReceiver.Stub() {
8360                 public void performReceive(Intent intent, int resultCode, String data,
8361                         Bundle extras, boolean ordered, boolean sticky) throws RemoteException {
8362                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
8363                             reportStatus ? 1 : 0, 1, keys);
8364                     mHandler.sendMessage(msg);
8365                 }
8366             });
8367         } else {
8368             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
8369                     keys);
8370             mHandler.sendMessage(msg);
8371         }
8372     }
8373 
movePackage(final String packageName, final IPackageMoveObserver observer, final int flags)8374     public void movePackage(final String packageName, final IPackageMoveObserver observer,
8375             final int flags) {
8376         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
8377         int returnCode = PackageManager.MOVE_SUCCEEDED;
8378         int currFlags = 0;
8379         int newFlags = 0;
8380         // reader
8381         synchronized (mPackages) {
8382             PackageParser.Package pkg = mPackages.get(packageName);
8383             if (pkg == null) {
8384                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
8385             } else {
8386                 // Disable moving fwd locked apps and system packages
8387                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
8388                     Slog.w(TAG, "Cannot move system application");
8389                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
8390                 } else if (pkg.applicationInfo != null && isForwardLocked(pkg)) {
8391                     Slog.w(TAG, "Cannot move forward locked app.");
8392                     returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
8393                 } else if (pkg.mOperationPending) {
8394                     Slog.w(TAG, "Attempt to move package which has pending operations");
8395                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
8396                 } else {
8397                     // Find install location first
8398                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
8399                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
8400                         Slog.w(TAG, "Ambigous flags specified for move location.");
8401                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
8402                     } else {
8403                         newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL
8404                                 : PackageManager.INSTALL_INTERNAL;
8405                         currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
8406                                 : PackageManager.INSTALL_INTERNAL;
8407                         if (newFlags == currFlags) {
8408                             Slog.w(TAG, "No move required. Trying to move to same location");
8409                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
8410                         }
8411                     }
8412                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
8413                         pkg.mOperationPending = true;
8414                     }
8415                 }
8416             }
8417 
8418             /*
8419              * TODO this next block probably shouldn't be inside the lock. We
8420              * can't guarantee these won't change after this is fired off
8421              * anyway.
8422              */
8423             if (returnCode != PackageManager.MOVE_SUCCEEDED) {
8424                 processPendingMove(new MoveParams(null, observer, 0, packageName, null), returnCode);
8425             } else {
8426                 Message msg = mHandler.obtainMessage(INIT_COPY);
8427                 InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
8428                         pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
8429                 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
8430                         pkg.applicationInfo.dataDir);
8431                 msg.obj = mp;
8432                 mHandler.sendMessage(msg);
8433             }
8434         }
8435     }
8436 
processPendingMove(final MoveParams mp, final int currentStatus)8437     private void processPendingMove(final MoveParams mp, final int currentStatus) {
8438         // Queue up an async operation since the package deletion may take a
8439         // little while.
8440         mHandler.post(new Runnable() {
8441             public void run() {
8442                 // TODO fix this; this does nothing.
8443                 mHandler.removeCallbacks(this);
8444                 int returnCode = currentStatus;
8445                 if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
8446                     int uidArr[] = null;
8447                     ArrayList<String> pkgList = null;
8448                     synchronized (mPackages) {
8449                         PackageParser.Package pkg = mPackages.get(mp.packageName);
8450                         if (pkg == null) {
8451                             Slog.w(TAG, " Package " + mp.packageName
8452                                     + " doesn't exist. Aborting move");
8453                             returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
8454                         } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
8455                             Slog.w(TAG, "Package " + mp.packageName + " code path changed from "
8456                                     + mp.srcArgs.getCodePath() + " to "
8457                                     + pkg.applicationInfo.sourceDir
8458                                     + " Aborting move and returning error");
8459                             returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
8460                         } else {
8461                             uidArr = new int[] {
8462                                 pkg.applicationInfo.uid
8463                             };
8464                             pkgList = new ArrayList<String>();
8465                             pkgList.add(mp.packageName);
8466                         }
8467                     }
8468                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
8469                         // Send resources unavailable broadcast
8470                         sendResourcesChangedBroadcast(false, pkgList, uidArr, null);
8471                         // Update package code and resource paths
8472                         synchronized (mInstallLock) {
8473                             synchronized (mPackages) {
8474                                 PackageParser.Package pkg = mPackages.get(mp.packageName);
8475                                 // Recheck for package again.
8476                                 if (pkg == null) {
8477                                     Slog.w(TAG, " Package " + mp.packageName
8478                                             + " doesn't exist. Aborting move");
8479                                     returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
8480                                 } else if (!mp.srcArgs.getCodePath().equals(
8481                                         pkg.applicationInfo.sourceDir)) {
8482                                     Slog.w(TAG, "Package " + mp.packageName
8483                                             + " code path changed from " + mp.srcArgs.getCodePath()
8484                                             + " to " + pkg.applicationInfo.sourceDir
8485                                             + " Aborting move and returning error");
8486                                     returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
8487                                 } else {
8488                                     final String oldCodePath = pkg.mPath;
8489                                     final String newCodePath = mp.targetArgs.getCodePath();
8490                                     final String newResPath = mp.targetArgs.getResourcePath();
8491                                     final String newNativePath = mp.targetArgs
8492                                             .getNativeLibraryPath();
8493 
8494                                     if ((mp.flags & PackageManager.INSTALL_EXTERNAL) == 0) {
8495                                         if (mInstaller
8496                                                 .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
8497                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
8498                                         } else {
8499                                             NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File(
8500                                                     newCodePath), new File(newNativePath));
8501                                         }
8502                                     } else {
8503                                         if (mInstaller.linkNativeLibraryDirectory(
8504                                                 pkg.applicationInfo.dataDir, newNativePath) < 0) {
8505                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
8506                                         }
8507                                     }
8508 
8509                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
8510                                         pkg.mPath = newCodePath;
8511                                         // Move dex files around
8512                                         if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) {
8513                                             // Moving of dex files failed. Set
8514                                             // error code and abort move.
8515                                             pkg.mPath = pkg.mScanPath;
8516                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
8517                                         }
8518                                     }
8519 
8520                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
8521                                         pkg.mScanPath = newCodePath;
8522                                         pkg.applicationInfo.sourceDir = newCodePath;
8523                                         pkg.applicationInfo.publicSourceDir = newResPath;
8524                                         pkg.applicationInfo.nativeLibraryDir = newNativePath;
8525                                         PackageSetting ps = (PackageSetting) pkg.mExtras;
8526                                         ps.codePath = new File(pkg.applicationInfo.sourceDir);
8527                                         ps.codePathString = ps.codePath.getPath();
8528                                         ps.resourcePath = new File(
8529                                                 pkg.applicationInfo.publicSourceDir);
8530                                         ps.resourcePathString = ps.resourcePath.getPath();
8531                                         ps.nativeLibraryPathString = newNativePath;
8532                                         // Set the application info flag
8533                                         // correctly.
8534                                         if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
8535                                             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
8536                                         } else {
8537                                             pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
8538                                         }
8539                                         ps.setFlags(pkg.applicationInfo.flags);
8540                                         mAppDirs.remove(oldCodePath);
8541                                         mAppDirs.put(newCodePath, pkg);
8542                                         // Persist settings
8543                                         mSettings.writeLPr();
8544                                     }
8545                                 }
8546                             }
8547                         }
8548                         // Send resources available broadcast
8549                         sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
8550                     }
8551                 }
8552                 if (returnCode != PackageManager.MOVE_SUCCEEDED) {
8553                     // Clean up failed installation
8554                     if (mp.targetArgs != null) {
8555                         mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR);
8556                     }
8557                 } else {
8558                     // Force a gc to clear things up.
8559                     Runtime.getRuntime().gc();
8560                     // Delete older code
8561                     synchronized (mInstallLock) {
8562                         mp.srcArgs.doPostDeleteLI(true);
8563                     }
8564                 }
8565 
8566                 // Allow more operations on this file if we didn't fail because
8567                 // an operation was already pending for this package.
8568                 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) {
8569                     synchronized (mPackages) {
8570                         PackageParser.Package pkg = mPackages.get(mp.packageName);
8571                         if (pkg != null) {
8572                             pkg.mOperationPending = false;
8573                        }
8574                    }
8575                 }
8576 
8577                 IPackageMoveObserver observer = mp.observer;
8578                 if (observer != null) {
8579                     try {
8580                         observer.packageMoved(mp.packageName, returnCode);
8581                     } catch (RemoteException e) {
8582                         Log.i(TAG, "Observer no longer exists.");
8583                     }
8584                 }
8585             }
8586         });
8587     }
8588 
setInstallLocation(int loc)8589     public boolean setInstallLocation(int loc) {
8590         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
8591                 null);
8592         if (getInstallLocation() == loc) {
8593             return true;
8594         }
8595         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
8596                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
8597             android.provider.Settings.System.putInt(mContext.getContentResolver(),
8598                     android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION, loc);
8599             return true;
8600         }
8601         return false;
8602    }
8603 
getInstallLocation()8604     public int getInstallLocation() {
8605         return android.provider.Settings.System.getInt(mContext.getContentResolver(),
8606                 android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION,
8607                 PackageHelper.APP_INSTALL_AUTO);
8608     }
8609 
createUser(String name, int flags)8610     public UserInfo createUser(String name, int flags) {
8611         // TODO(kroot): Add a real permission for creating users
8612         enforceSystemOrRoot("Only the system can create users");
8613 
8614         // TODO(kroot): fix this API
8615         UserInfo userInfo = mUserManager.createUser(name, flags, new ArrayList<ApplicationInfo>());
8616         return userInfo;
8617     }
8618 
removeUser(int userId)8619     public boolean removeUser(int userId) {
8620         // TODO(kroot): Add a real permission for removing users
8621         enforceSystemOrRoot("Only the system can remove users");
8622 
8623         if (userId == 0) {
8624             return false;
8625         }
8626         mUserManager.removeUser(userId);
8627         return true;
8628     }
8629 
8630     @Override
getVerifierDeviceIdentity()8631     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
8632         mContext.enforceCallingOrSelfPermission(
8633                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
8634                 "Only package verification agents can read the verifier device identity");
8635 
8636         synchronized (mPackages) {
8637             return mSettings.getVerifierDeviceIdentityLPw();
8638         }
8639     }
8640 }
8641