Home | History | Annotate | Download | only in pm
      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 {
    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 
    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 
    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 
    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 
    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 
    467         PackageHandler(Looper looper) {
    468             super(looper);
    469         }
    470 
    471         public void handleMessage(Message msg) {
    472             try {
    473                 doHandleMessage(msg);
    474             } finally {
    475                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    476             }
    477         }
    478 
    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 
    808     void scheduleWriteSettingsLocked() {
    809         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
    810             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
    811         }
    812     }
    813 
    814     void scheduleWriteStoppedPackagesLocked() {
    815         if (!mHandler.hasMessages(WRITE_STOPPED_PACKAGES)) {
    816             mHandler.sendEmptyMessageDelayed(WRITE_STOPPED_PACKAGES, WRITE_SETTINGS_DELAY);
    817         }
    818     }
    819 
    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 
    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 
    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 
    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 
   1160     public boolean isFirstBoot() {
   1161         return !mRestoredSettings;
   1162     }
   1163 
   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
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1828     public boolean hasSystemFeature(String name) {
   1829         synchronized (mPackages) {
   1830             return mAvailableFeatures.containsKey(name);
   1831         }
   1832     }
   1833 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1966     public boolean addPermission(PermissionInfo info) {
   1967         synchronized (mPackages) {
   1968             return addPermissionLocked(info, false);
   1969         }
   1970     }
   1971 
   1972     public boolean addPermissionAsync(PermissionInfo info) {
   1973         synchronized (mPackages) {
   1974             return addPermissionLocked(info, true);
   1975         }
   1976     }
   1977 
   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 
   1994     public boolean isProtectedBroadcast(String actionName) {
   1995         synchronized (mPackages) {
   1996             return mProtectedBroadcasts.contains(actionName);
   1997         }
   1998     }
   1999 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   2161     ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
   2162             int flags, List<ResolveInfo> query, int priority) {
   2163         // writer
   2164         synchronized (mPackages) {
   2165             if (intent.getSelector() != null) {
   2166                 intent = intent.getSelector();
   2167             }
   2168             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
   2169             List<PreferredActivity> prefs =
   2170                     mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
   2171                             (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
   2172             if (prefs != null && prefs.size() > 0) {
   2173                 // First figure out how good the original match set is.
   2174                 // We will only allow preferred activities that came
   2175                 // from the same match quality.
   2176                 int match = 0;
   2177 
   2178                 if (DEBUG_PREFERRED) {
   2179                     Log.v(TAG, "Figuring out best match...");
   2180                 }
   2181 
   2182                 final int N = query.size();
   2183                 for (int j=0; j<N; j++) {
   2184                     final ResolveInfo ri = query.get(j);
   2185                     if (DEBUG_PREFERRED) {
   2186                         Log.v(TAG, "Match for " + ri.activityInfo + ": 0x"
   2187                                 + Integer.toHexString(match));
   2188                     }
   2189                     if (ri.match > match) {
   2190                         match = ri.match;
   2191                     }
   2192                 }
   2193 
   2194                 if (DEBUG_PREFERRED) {
   2195                     Log.v(TAG, "Best match: 0x" + Integer.toHexString(match));
   2196                 }
   2197 
   2198                 match &= IntentFilter.MATCH_CATEGORY_MASK;
   2199                 final int M = prefs.size();
   2200                 for (int i=0; i<M; i++) {
   2201                     final PreferredActivity pa = prefs.get(i);
   2202                     if (pa.mPref.mMatch != match) {
   2203                         continue;
   2204                     }
   2205                     final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags);
   2206                     if (DEBUG_PREFERRED) {
   2207                         Log.v(TAG, "Got preferred activity:");
   2208                         if (ai != null) {
   2209                             ai.dump(new LogPrinter(Log.VERBOSE, TAG), "  ");
   2210                         } else {
   2211                             Log.v(TAG, "  null");
   2212                         }
   2213                     }
   2214                     if (ai != null) {
   2215                         for (int j=0; j<N; j++) {
   2216                             final ResolveInfo ri = query.get(j);
   2217                             if (!ri.activityInfo.applicationInfo.packageName
   2218                                     .equals(ai.applicationInfo.packageName)) {
   2219                                 continue;
   2220                             }
   2221                             if (!ri.activityInfo.name.equals(ai.name)) {
   2222                                 continue;
   2223                             }
   2224 
   2225                             // Okay we found a previously set preferred app.
   2226                             // If the result set is different from when this
   2227                             // was created, we need to clear it and re-ask the
   2228                             // user their preference.
   2229                             if (!pa.mPref.sameSet(query, priority)) {
   2230                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
   2231                                         + intent + " type " + resolvedType);
   2232                                 mSettings.mPreferredActivities.removeFilter(pa);
   2233                                 return null;
   2234                             }
   2235 
   2236                             // Yay!
   2237                             return ri;
   2238                         }
   2239                     }
   2240                 }
   2241             }
   2242         }
   2243         return null;
   2244     }
   2245 
   2246     public List<ResolveInfo> queryIntentActivities(Intent intent,
   2247             String resolvedType, int flags) {
   2248         ComponentName comp = intent.getComponent();
   2249         if (comp == null) {
   2250             if (intent.getSelector() != null) {
   2251                 intent = intent.getSelector();
   2252                 comp = intent.getComponent();
   2253             }
   2254         }
   2255         if (comp != null) {
   2256             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2257             final ActivityInfo ai = getActivityInfo(comp, flags);
   2258             if (ai != null) {
   2259                 final ResolveInfo ri = new ResolveInfo();
   2260                 ri.activityInfo = ai;
   2261                 list.add(ri);
   2262             }
   2263             return list;
   2264         }
   2265 
   2266         // reader
   2267         synchronized (mPackages) {
   2268             final String pkgName = intent.getPackage();
   2269             if (pkgName == null) {
   2270                 return mActivities.queryIntent(intent, resolvedType, flags);
   2271             }
   2272             final PackageParser.Package pkg = mPackages.get(pkgName);
   2273             if (pkg != null) {
   2274                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
   2275                         pkg.activities);
   2276             }
   2277             return new ArrayList<ResolveInfo>();
   2278         }
   2279     }
   2280 
   2281     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
   2282             Intent[] specifics, String[] specificTypes, Intent intent,
   2283             String resolvedType, int flags) {
   2284         final String resultsAction = intent.getAction();
   2285 
   2286         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
   2287                 | PackageManager.GET_RESOLVED_FILTER);
   2288 
   2289         if (DEBUG_INTENT_MATCHING) {
   2290             Log.v(TAG, "Query " + intent + ": " + results);
   2291         }
   2292 
   2293         int specificsPos = 0;
   2294         int N;
   2295 
   2296         // todo: note that the algorithm used here is O(N^2).  This
   2297         // isn't a problem in our current environment, but if we start running
   2298         // into situations where we have more than 5 or 10 matches then this
   2299         // should probably be changed to something smarter...
   2300 
   2301         // First we go through and resolve each of the specific items
   2302         // that were supplied, taking care of removing any corresponding
   2303         // duplicate items in the generic resolve list.
   2304         if (specifics != null) {
   2305             for (int i=0; i<specifics.length; i++) {
   2306                 final Intent sintent = specifics[i];
   2307                 if (sintent == null) {
   2308                     continue;
   2309                 }
   2310 
   2311                 if (DEBUG_INTENT_MATCHING) {
   2312                     Log.v(TAG, "Specific #" + i + ": " + sintent);
   2313                 }
   2314 
   2315                 String action = sintent.getAction();
   2316                 if (resultsAction != null && resultsAction.equals(action)) {
   2317                     // If this action was explicitly requested, then don't
   2318                     // remove things that have it.
   2319                     action = null;
   2320                 }
   2321 
   2322                 ResolveInfo ri = null;
   2323                 ActivityInfo ai = null;
   2324 
   2325                 ComponentName comp = sintent.getComponent();
   2326                 if (comp == null) {
   2327                     ri = resolveIntent(
   2328                         sintent,
   2329                         specificTypes != null ? specificTypes[i] : null,
   2330                         flags);
   2331                     if (ri == null) {
   2332                         continue;
   2333                     }
   2334                     if (ri == mResolveInfo) {
   2335                         // ACK!  Must do something better with this.
   2336                     }
   2337                     ai = ri.activityInfo;
   2338                     comp = new ComponentName(ai.applicationInfo.packageName,
   2339                             ai.name);
   2340                 } else {
   2341                     ai = getActivityInfo(comp, flags);
   2342                     if (ai == null) {
   2343                         continue;
   2344                     }
   2345                 }
   2346 
   2347                 // Look for any generic query activities that are duplicates
   2348                 // of this specific one, and remove them from the results.
   2349                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
   2350                 N = results.size();
   2351                 int j;
   2352                 for (j=specificsPos; j<N; j++) {
   2353                     ResolveInfo sri = results.get(j);
   2354                     if ((sri.activityInfo.name.equals(comp.getClassName())
   2355                             && sri.activityInfo.applicationInfo.packageName.equals(
   2356                                     comp.getPackageName()))
   2357                         || (action != null && sri.filter.matchAction(action))) {
   2358                         results.remove(j);
   2359                         if (DEBUG_INTENT_MATCHING) Log.v(
   2360                             TAG, "Removing duplicate item from " + j
   2361                             + " due to specific " + specificsPos);
   2362                         if (ri == null) {
   2363                             ri = sri;
   2364                         }
   2365                         j--;
   2366                         N--;
   2367                     }
   2368                 }
   2369 
   2370                 // Add this specific item to its proper place.
   2371                 if (ri == null) {
   2372                     ri = new ResolveInfo();
   2373                     ri.activityInfo = ai;
   2374                 }
   2375                 results.add(specificsPos, ri);
   2376                 ri.specificIndex = i;
   2377                 specificsPos++;
   2378             }
   2379         }
   2380 
   2381         // Now we go through the remaining generic results and remove any
   2382         // duplicate actions that are found here.
   2383         N = results.size();
   2384         for (int i=specificsPos; i<N-1; i++) {
   2385             final ResolveInfo rii = results.get(i);
   2386             if (rii.filter == null) {
   2387                 continue;
   2388             }
   2389 
   2390             // Iterate over all of the actions of this result's intent
   2391             // filter...  typically this should be just one.
   2392             final Iterator<String> it = rii.filter.actionsIterator();
   2393             if (it == null) {
   2394                 continue;
   2395             }
   2396             while (it.hasNext()) {
   2397                 final String action = it.next();
   2398                 if (resultsAction != null && resultsAction.equals(action)) {
   2399                     // If this action was explicitly requested, then don't
   2400                     // remove things that have it.
   2401                     continue;
   2402                 }
   2403                 for (int j=i+1; j<N; j++) {
   2404                     final ResolveInfo rij = results.get(j);
   2405                     if (rij.filter != null && rij.filter.hasAction(action)) {
   2406                         results.remove(j);
   2407                         if (DEBUG_INTENT_MATCHING) Log.v(
   2408                             TAG, "Removing duplicate item from " + j
   2409                             + " due to action " + action + " at " + i);
   2410                         j--;
   2411                         N--;
   2412                     }
   2413                 }
   2414             }
   2415 
   2416             // If the caller didn't request filter information, drop it now
   2417             // so we don't have to marshall/unmarshall it.
   2418             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   2419                 rii.filter = null;
   2420             }
   2421         }
   2422 
   2423         // Filter out the caller activity if so requested.
   2424         if (caller != null) {
   2425             N = results.size();
   2426             for (int i=0; i<N; i++) {
   2427                 ActivityInfo ainfo = results.get(i).activityInfo;
   2428                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
   2429                         && caller.getClassName().equals(ainfo.name)) {
   2430                     results.remove(i);
   2431                     break;
   2432                 }
   2433             }
   2434         }
   2435 
   2436         // If the caller didn't request filter information,
   2437         // drop them now so we don't have to
   2438         // marshall/unmarshall it.
   2439         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   2440             N = results.size();
   2441             for (int i=0; i<N; i++) {
   2442                 results.get(i).filter = null;
   2443             }
   2444         }
   2445 
   2446         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
   2447         return results;
   2448     }
   2449 
   2450     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags) {
   2451         ComponentName comp = intent.getComponent();
   2452         if (comp == null) {
   2453             if (intent.getSelector() != null) {
   2454                 intent = intent.getSelector();
   2455                 comp = intent.getComponent();
   2456             }
   2457         }
   2458         if (comp != null) {
   2459             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2460             ActivityInfo ai = getReceiverInfo(comp, flags);
   2461             if (ai != null) {
   2462                 ResolveInfo ri = new ResolveInfo();
   2463                 ri.activityInfo = ai;
   2464                 list.add(ri);
   2465             }
   2466             return list;
   2467         }
   2468 
   2469         // reader
   2470         synchronized (mPackages) {
   2471             String pkgName = intent.getPackage();
   2472             if (pkgName == null) {
   2473                 return mReceivers.queryIntent(intent, resolvedType, flags);
   2474             }
   2475             final PackageParser.Package pkg = mPackages.get(pkgName);
   2476             if (pkg != null) {
   2477                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers);
   2478             }
   2479             return null;
   2480         }
   2481     }
   2482 
   2483     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags) {
   2484         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags);
   2485         if (query != null) {
   2486             if (query.size() >= 1) {
   2487                 // If there is more than one service with the same priority,
   2488                 // just arbitrarily pick the first one.
   2489                 return query.get(0);
   2490             }
   2491         }
   2492         return null;
   2493     }
   2494 
   2495     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags) {
   2496         ComponentName comp = intent.getComponent();
   2497         if (comp == null) {
   2498             if (intent.getSelector() != null) {
   2499                 intent = intent.getSelector();
   2500                 comp = intent.getComponent();
   2501             }
   2502         }
   2503         if (comp != null) {
   2504             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2505             final ServiceInfo si = getServiceInfo(comp, flags);
   2506             if (si != null) {
   2507                 final ResolveInfo ri = new ResolveInfo();
   2508                 ri.serviceInfo = si;
   2509                 list.add(ri);
   2510             }
   2511             return list;
   2512         }
   2513 
   2514         // reader
   2515         synchronized (mPackages) {
   2516             String pkgName = intent.getPackage();
   2517             if (pkgName == null) {
   2518                 return mServices.queryIntent(intent, resolvedType, flags);
   2519             }
   2520             final PackageParser.Package pkg = mPackages.get(pkgName);
   2521             if (pkg != null) {
   2522                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services);
   2523             }
   2524             return null;
   2525         }
   2526     }
   2527 
   2528     private static final int getContinuationPoint(final String[] keys, final String key) {
   2529         final int index;
   2530         if (key == null) {
   2531             index = 0;
   2532         } else {
   2533             final int insertPoint = Arrays.binarySearch(keys, key);
   2534             if (insertPoint < 0) {
   2535                 index = -insertPoint;
   2536             } else {
   2537                 index = insertPoint + 1;
   2538             }
   2539         }
   2540         return index;
   2541     }
   2542 
   2543     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead) {
   2544         final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
   2545         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   2546         final String[] keys;
   2547 
   2548         // writer
   2549         synchronized (mPackages) {
   2550             if (listUninstalled) {
   2551                 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
   2552             } else {
   2553                 keys = mPackages.keySet().toArray(new String[mPackages.size()]);
   2554             }
   2555 
   2556             Arrays.sort(keys);
   2557             int i = getContinuationPoint(keys, lastRead);
   2558             final int N = keys.length;
   2559 
   2560             while (i < N) {
   2561                 final String packageName = keys[i++];
   2562 
   2563                 PackageInfo pi = null;
   2564                 if (listUninstalled) {
   2565                     final PackageSetting ps = mSettings.mPackages.get(packageName);
   2566                     if (ps != null) {
   2567                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags);
   2568                     }
   2569                 } else {
   2570                     final PackageParser.Package p = mPackages.get(packageName);
   2571                     if (p != null) {
   2572                         pi = generatePackageInfo(p, flags);
   2573                     }
   2574                 }
   2575 
   2576                 if (pi != null && !list.append(pi)) {
   2577                     break;
   2578                 }
   2579             }
   2580 
   2581             if (i == N) {
   2582                 list.setLastSlice(true);
   2583             }
   2584         }
   2585 
   2586         return list;
   2587     }
   2588 
   2589     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
   2590             String lastRead) {
   2591         final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>();
   2592         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   2593         final String[] keys;
   2594 
   2595         // writer
   2596         synchronized (mPackages) {
   2597             if (listUninstalled) {
   2598                 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
   2599             } else {
   2600                 keys = mPackages.keySet().toArray(new String[mPackages.size()]);
   2601             }
   2602 
   2603             Arrays.sort(keys);
   2604             int i = getContinuationPoint(keys, lastRead);
   2605             final int N = keys.length;
   2606 
   2607             while (i < N) {
   2608                 final String packageName = keys[i++];
   2609 
   2610                 ApplicationInfo ai = null;
   2611                 if (listUninstalled) {
   2612                     final PackageSetting ps = mSettings.mPackages.get(packageName);
   2613                     if (ps != null) {
   2614                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags);
   2615                     }
   2616                 } else {
   2617                     final PackageParser.Package p = mPackages.get(packageName);
   2618                     if (p != null) {
   2619                         ai = PackageParser.generateApplicationInfo(p, flags);
   2620                     }
   2621                 }
   2622 
   2623                 if (ai != null && !list.append(ai)) {
   2624                     break;
   2625                 }
   2626             }
   2627 
   2628             if (i == N) {
   2629                 list.setLastSlice(true);
   2630             }
   2631         }
   2632 
   2633         return list;
   2634     }
   2635 
   2636     public List<ApplicationInfo> getPersistentApplications(int flags) {
   2637         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
   2638 
   2639         // reader
   2640         synchronized (mPackages) {
   2641             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
   2642             while (i.hasNext()) {
   2643                 final PackageParser.Package p = i.next();
   2644                 if (p.applicationInfo != null
   2645                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
   2646                         && (!mSafeMode || isSystemApp(p))) {
   2647                     finalList.add(PackageParser.generateApplicationInfo(p, flags));
   2648                 }
   2649             }
   2650         }
   2651 
   2652         return finalList;
   2653     }
   2654 
   2655     public ProviderInfo resolveContentProvider(String name, int flags) {
   2656         // reader
   2657         synchronized (mPackages) {
   2658             final PackageParser.Provider provider = mProviders.get(name);
   2659             return provider != null
   2660                     && mSettings.isEnabledLPr(provider.info, flags)
   2661                     && (!mSafeMode || (provider.info.applicationInfo.flags
   2662                             &ApplicationInfo.FLAG_SYSTEM) != 0)
   2663                     ? PackageParser.generateProviderInfo(provider, flags)
   2664                     : null;
   2665         }
   2666     }
   2667 
   2668     /**
   2669      * @deprecated
   2670      */
   2671     @Deprecated
   2672     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
   2673         // reader
   2674         synchronized (mPackages) {
   2675             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet()
   2676                     .iterator();
   2677 
   2678             while (i.hasNext()) {
   2679                 Map.Entry<String, PackageParser.Provider> entry = i.next();
   2680                 PackageParser.Provider p = entry.getValue();
   2681 
   2682                 if (p.syncable
   2683                         && (!mSafeMode || (p.info.applicationInfo.flags
   2684                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
   2685                     outNames.add(entry.getKey());
   2686                     outInfo.add(PackageParser.generateProviderInfo(p, 0));
   2687                 }
   2688             }
   2689         }
   2690     }
   2691 
   2692     public List<ProviderInfo> queryContentProviders(String processName,
   2693             int uid, int flags) {
   2694         ArrayList<ProviderInfo> finalList = null;
   2695 
   2696         // reader
   2697         synchronized (mPackages) {
   2698             final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
   2699             while (i.hasNext()) {
   2700                 final PackageParser.Provider p = i.next();
   2701                 if (p.info.authority != null
   2702                         && (processName == null
   2703                                 || (p.info.processName.equals(processName)
   2704                                         && p.info.applicationInfo.uid == uid))
   2705                         && mSettings.isEnabledLPr(p.info, flags)
   2706                         && (!mSafeMode
   2707                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
   2708                     if (finalList == null) {
   2709                         finalList = new ArrayList<ProviderInfo>(3);
   2710                     }
   2711                     finalList.add(PackageParser.generateProviderInfo(p, flags));
   2712                 }
   2713             }
   2714         }
   2715 
   2716         if (finalList != null) {
   2717             Collections.sort(finalList, mProviderInitOrderSorter);
   2718         }
   2719 
   2720         return finalList;
   2721     }
   2722 
   2723     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
   2724             int flags) {
   2725         // reader
   2726         synchronized (mPackages) {
   2727             final PackageParser.Instrumentation i = mInstrumentation.get(name);
   2728             return PackageParser.generateInstrumentationInfo(i, flags);
   2729         }
   2730     }
   2731 
   2732     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
   2733             int flags) {
   2734         ArrayList<InstrumentationInfo> finalList =
   2735             new ArrayList<InstrumentationInfo>();
   2736 
   2737         // reader
   2738         synchronized (mPackages) {
   2739             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
   2740             while (i.hasNext()) {
   2741                 final PackageParser.Instrumentation p = i.next();
   2742                 if (targetPackage == null
   2743                         || targetPackage.equals(p.info.targetPackage)) {
   2744                     finalList.add(PackageParser.generateInstrumentationInfo(p,
   2745                             flags));
   2746                 }
   2747             }
   2748         }
   2749 
   2750         return finalList;
   2751     }
   2752 
   2753     private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
   2754         String[] files = dir.list();
   2755         if (files == null) {
   2756             Log.d(TAG, "No files in app dir " + dir);
   2757             return;
   2758         }
   2759 
   2760         if (DEBUG_PACKAGE_SCANNING) {
   2761             Log.d(TAG, "Scanning app dir " + dir);
   2762         }
   2763 
   2764         int i;
   2765         for (i=0; i<files.length; i++) {
   2766             File file = new File(dir, files[i]);
   2767             if (!isPackageFilename(files[i])) {
   2768                 // Ignore entries which are not apk's
   2769                 continue;
   2770             }
   2771             PackageParser.Package pkg = scanPackageLI(file,
   2772                     flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);
   2773             // Don't mess around with apps in system partition.
   2774             if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
   2775                     mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
   2776                 // Delete the apk
   2777                 Slog.w(TAG, "Cleaning up failed install of " + file);
   2778                 file.delete();
   2779             }
   2780         }
   2781     }
   2782 
   2783     private static File getSettingsProblemFile() {
   2784         File dataDir = Environment.getDataDirectory();
   2785         File systemDir = new File(dataDir, "system");
   2786         File fname = new File(systemDir, "uiderrors.txt");
   2787         return fname;
   2788     }
   2789 
   2790     static void reportSettingsProblem(int priority, String msg) {
   2791         try {
   2792             File fname = getSettingsProblemFile();
   2793             FileOutputStream out = new FileOutputStream(fname, true);
   2794             PrintWriter pw = new PrintWriter(out);
   2795             SimpleDateFormat formatter = new SimpleDateFormat();
   2796             String dateString = formatter.format(new Date(System.currentTimeMillis()));
   2797             pw.println(dateString + ": " + msg);
   2798             pw.close();
   2799             FileUtils.setPermissions(
   2800                     fname.toString(),
   2801                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
   2802                     -1, -1);
   2803         } catch (java.io.IOException e) {
   2804         }
   2805         Slog.println(priority, TAG, msg);
   2806     }
   2807 
   2808     private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
   2809             PackageParser.Package pkg, File srcFile, int parseFlags) {
   2810         if (GET_CERTIFICATES) {
   2811             if (ps != null
   2812                     && ps.codePath.equals(srcFile)
   2813                     && ps.timeStamp == srcFile.lastModified()) {
   2814                 if (ps.signatures.mSignatures != null
   2815                         && ps.signatures.mSignatures.length != 0) {
   2816                     // Optimization: reuse the existing cached certificates
   2817                     // if the package appears to be unchanged.
   2818                     pkg.mSignatures = ps.signatures.mSignatures;
   2819                     return true;
   2820                 }
   2821 
   2822                 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures.  Collecting certs again to recover them.");
   2823             } else {
   2824                 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
   2825             }
   2826 
   2827             if (!pp.collectCertificates(pkg, parseFlags)) {
   2828                 mLastScanError = pp.getParseError();
   2829                 return false;
   2830             }
   2831         }
   2832         return true;
   2833     }
   2834 
   2835     /*
   2836      *  Scan a package and return the newly parsed package.
   2837      *  Returns null in case of errors and the error code is stored in mLastScanError
   2838      */
   2839     private PackageParser.Package scanPackageLI(File scanFile,
   2840             int parseFlags, int scanMode, long currentTime) {
   2841         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   2842         String scanPath = scanFile.getPath();
   2843         parseFlags |= mDefParseFlags;
   2844         PackageParser pp = new PackageParser(scanPath);
   2845         pp.setSeparateProcesses(mSeparateProcesses);
   2846         pp.setOnlyCoreApps(mOnlyCore);
   2847         final PackageParser.Package pkg = pp.parsePackage(scanFile,
   2848                 scanPath, mMetrics, parseFlags);
   2849         if (pkg == null) {
   2850             mLastScanError = pp.getParseError();
   2851             return null;
   2852         }
   2853         PackageSetting ps = null;
   2854         PackageSetting updatedPkg;
   2855         // reader
   2856         synchronized (mPackages) {
   2857             // Look to see if we already know about this package.
   2858             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
   2859             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
   2860                 // This package has been renamed to its original name.  Let's
   2861                 // use that.
   2862                 ps = mSettings.peekPackageLPr(oldName);
   2863             }
   2864             // If there was no original package, see one for the real package name.
   2865             if (ps == null) {
   2866                 ps = mSettings.peekPackageLPr(pkg.packageName);
   2867             }
   2868             // Check to see if this package could be hiding/updating a system
   2869             // package.  Must look for it either under the original or real
   2870             // package name depending on our state.
   2871             updatedPkg = mSettings.mDisabledSysPackages.get(
   2872                     ps != null ? ps.name : pkg.packageName);
   2873         }
   2874         // First check if this is a system package that may involve an update
   2875         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   2876             if (ps != null && !ps.codePath.equals(scanFile)) {
   2877                 // The path has changed from what was last scanned...  check the
   2878                 // version of the new path against what we have stored to determine
   2879                 // what to do.
   2880                 if (pkg.mVersionCode < ps.versionCode) {
   2881                     // The system package has been updated and the code path does not match
   2882                     // Ignore entry. Skip it.
   2883                     Log.i(TAG, "Package " + ps.name + " at " + scanFile
   2884                             + " ignored: updated version " + ps.versionCode
   2885                             + " better than this " + pkg.mVersionCode);
   2886                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   2887                     return null;
   2888                 } else {
   2889                     // The current app on the system partion is better than
   2890                     // what we have updated to on the data partition; switch
   2891                     // back to the system partition version.
   2892                     // At this point, its safely assumed that package installation for
   2893                     // apps in system partition will go through. If not there won't be a working
   2894                     // version of the app
   2895                     // writer
   2896                     synchronized (mPackages) {
   2897                         // Just remove the loaded entries from package lists.
   2898                         mPackages.remove(ps.name);
   2899                     }
   2900                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile
   2901                             + "reverting from " + ps.codePathString
   2902                             + ": new version " + pkg.mVersionCode
   2903                             + " better than installed " + ps.versionCode);
   2904                     InstallArgs args = new FileInstallArgs(ps.codePathString,
   2905                             ps.resourcePathString, ps.nativeLibraryPathString);
   2906                     args.cleanUpResourcesLI();
   2907                     mSettings.enableSystemPackageLPw(ps.name);
   2908                 }
   2909             }
   2910         }
   2911         if (updatedPkg != null) {
   2912             // An updated system app will not have the PARSE_IS_SYSTEM flag set initially
   2913             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
   2914         }
   2915         // Verify certificates against what was last scanned
   2916         if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
   2917             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
   2918             return null;
   2919         }
   2920         // The apk is forward locked (not public) if its code and resources
   2921         // are kept in different files.
   2922         // TODO grab this value from PackageSettings
   2923         if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
   2924             parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   2925         }
   2926 
   2927         String codePath = null;
   2928         String resPath = null;
   2929         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
   2930             if (ps != null && ps.resourcePathString != null) {
   2931                 resPath = ps.resourcePathString;
   2932             } else {
   2933                 // Should not happen at all. Just log an error.
   2934                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
   2935             }
   2936         } else {
   2937             resPath = pkg.mScanPath;
   2938         }
   2939         codePath = pkg.mScanPath;
   2940         // Set application objects path explicitly.
   2941         setApplicationInfoPaths(pkg, codePath, resPath);
   2942         // Note that we invoke the following method only if we are about to unpack an application
   2943         return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);
   2944     }
   2945 
   2946     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
   2947             String destResPath) {
   2948         pkg.mPath = pkg.mScanPath = destCodePath;
   2949         pkg.applicationInfo.sourceDir = destCodePath;
   2950         pkg.applicationInfo.publicSourceDir = destResPath;
   2951     }
   2952 
   2953     private static String fixProcessName(String defProcessName,
   2954             String processName, int uid) {
   2955         if (processName == null) {
   2956             return defProcessName;
   2957         }
   2958         return processName;
   2959     }
   2960 
   2961     private boolean verifySignaturesLP(PackageSetting pkgSetting,
   2962             PackageParser.Package pkg) {
   2963         if (pkgSetting.signatures.mSignatures != null) {
   2964             // Already existing package. Make sure signatures match
   2965             if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
   2966                 PackageManager.SIGNATURE_MATCH) {
   2967                     Slog.e(TAG, "Package " + pkg.packageName
   2968                             + " signatures do not match the previously installed version; ignoring!");
   2969                     mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
   2970                     return false;
   2971                 }
   2972         }
   2973         // Check for shared user signatures
   2974         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
   2975             if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   2976                     pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   2977                 Slog.e(TAG, "Package " + pkg.packageName
   2978                         + " has no signatures that match those in shared user "
   2979                         + pkgSetting.sharedUser.name + "; ignoring!");
   2980                 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
   2981                 return false;
   2982             }
   2983         }
   2984         return true;
   2985     }
   2986 
   2987     /**
   2988      * Enforces that only the system UID or root's UID can call a method exposed
   2989      * via Binder.
   2990      *
   2991      * @param message used as message if SecurityException is thrown
   2992      * @throws SecurityException if the caller is not system or root
   2993      */
   2994     private static final void enforceSystemOrRoot(String message) {
   2995         final int uid = Binder.getCallingUid();
   2996         if (uid != Process.SYSTEM_UID && uid != 0) {
   2997             throw new SecurityException(message);
   2998         }
   2999     }
   3000 
   3001     public void performBootDexOpt() {
   3002         ArrayList<PackageParser.Package> pkgs = null;
   3003         synchronized (mPackages) {
   3004             if (mDeferredDexOpt.size() > 0) {
   3005                 pkgs = new ArrayList<PackageParser.Package>(mDeferredDexOpt);
   3006                 mDeferredDexOpt.clear();
   3007             }
   3008         }
   3009         if (pkgs != null) {
   3010             for (int i=0; i<pkgs.size(); i++) {
   3011                 if (!isFirstBoot()) {
   3012                     try {
   3013                         ActivityManagerNative.getDefault().showBootMessage(
   3014                                 mContext.getResources().getString(
   3015                                         com.android.internal.R.string.android_upgrading_apk,
   3016                                         i+1, pkgs.size()), true);
   3017                     } catch (RemoteException e) {
   3018                     }
   3019                 }
   3020                 PackageParser.Package p = pkgs.get(i);
   3021                 synchronized (mInstallLock) {
   3022                     if (!p.mDidDexOpt) {
   3023                         performDexOptLI(p, false, false);
   3024                     }
   3025                 }
   3026             }
   3027         }
   3028     }
   3029 
   3030     public boolean performDexOpt(String packageName) {
   3031         enforceSystemOrRoot("Only the system can request dexopt be performed");
   3032 
   3033         if (!mNoDexOpt) {
   3034             return false;
   3035         }
   3036 
   3037         PackageParser.Package p;
   3038         synchronized (mPackages) {
   3039             p = mPackages.get(packageName);
   3040             if (p == null || p.mDidDexOpt) {
   3041                 return false;
   3042             }
   3043         }
   3044         synchronized (mInstallLock) {
   3045             return performDexOptLI(p, false, false) == DEX_OPT_PERFORMED;
   3046         }
   3047     }
   3048 
   3049     static final int DEX_OPT_SKIPPED = 0;
   3050     static final int DEX_OPT_PERFORMED = 1;
   3051     static final int DEX_OPT_DEFERRED = 2;
   3052     static final int DEX_OPT_FAILED = -1;
   3053 
   3054     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer) {
   3055         boolean performed = false;
   3056         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
   3057             String path = pkg.mScanPath;
   3058             int ret = 0;
   3059             try {
   3060                 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
   3061                     if (!forceDex && defer) {
   3062                         mDeferredDexOpt.add(pkg);
   3063                         return DEX_OPT_DEFERRED;
   3064                     } else {
   3065                         Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
   3066                         ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
   3067                                 !isForwardLocked(pkg));
   3068                         pkg.mDidDexOpt = true;
   3069                         performed = true;
   3070                     }
   3071                 }
   3072             } catch (FileNotFoundException e) {
   3073                 Slog.w(TAG, "Apk not found for dexopt: " + path);
   3074                 ret = -1;
   3075             } catch (IOException e) {
   3076                 Slog.w(TAG, "IOException reading apk: " + path, e);
   3077                 ret = -1;
   3078             } catch (dalvik.system.StaleDexCacheError e) {
   3079                 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
   3080                 ret = -1;
   3081             } catch (Exception e) {
   3082                 Slog.w(TAG, "Exception when doing dexopt : ", e);
   3083                 ret = -1;
   3084             }
   3085             if (ret < 0) {
   3086                 //error from installer
   3087                 return DEX_OPT_FAILED;
   3088             }
   3089         }
   3090 
   3091         return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
   3092     }
   3093 
   3094     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
   3095         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   3096             Slog.w(TAG, "Unable to update from " + oldPkg.name
   3097                     + " to " + newPkg.packageName
   3098                     + ": old package not in system partition");
   3099             return false;
   3100         } else if (mPackages.get(oldPkg.name) != null) {
   3101             Slog.w(TAG, "Unable to update from " + oldPkg.name
   3102                     + " to " + newPkg.packageName
   3103                     + ": old package still exists");
   3104             return false;
   3105         }
   3106         return true;
   3107     }
   3108 
   3109     File getDataPathForUser(int userId) {
   3110         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
   3111     }
   3112 
   3113     private File getDataPathForPackage(String packageName, int userId) {
   3114         /*
   3115          * Until we fully support multiple users, return the directory we
   3116          * previously would have. The PackageManagerTests will need to be
   3117          * revised when this is changed back..
   3118          */
   3119         if (userId == 0) {
   3120             return new File(mAppDataDir, packageName);
   3121         } else {
   3122             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
   3123                 + File.separator + packageName);
   3124         }
   3125     }
   3126 
   3127     private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
   3128             int parseFlags, int scanMode, long currentTime) {
   3129         File scanFile = new File(pkg.mScanPath);
   3130         if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
   3131                 pkg.applicationInfo.publicSourceDir == null) {
   3132             // Bail out. The resource and code paths haven't been set.
   3133             Slog.w(TAG, " Code and resource paths haven't been set correctly");
   3134             mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
   3135             return null;
   3136         }
   3137         mScanningPath = scanFile;
   3138 
   3139         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   3140             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
   3141         }
   3142 
   3143         if (pkg.packageName.equals("android")) {
   3144             synchronized (mPackages) {
   3145                 if (mAndroidApplication != null) {
   3146                     Slog.w(TAG, "*************************************************");
   3147                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
   3148                     Slog.w(TAG, " file=" + mScanningPath);
   3149                     Slog.w(TAG, "*************************************************");
   3150                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   3151                     return null;
   3152                 }
   3153 
   3154                 // Set up information for our fall-back user intent resolution
   3155                 // activity.
   3156                 mPlatformPackage = pkg;
   3157                 pkg.mVersionCode = mSdkVersion;
   3158                 mAndroidApplication = pkg.applicationInfo;
   3159                 mResolveActivity.applicationInfo = mAndroidApplication;
   3160                 mResolveActivity.name = ResolverActivity.class.getName();
   3161                 mResolveActivity.packageName = mAndroidApplication.packageName;
   3162                 mResolveActivity.processName = mAndroidApplication.processName;
   3163                 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   3164                 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
   3165                 mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
   3166                 mResolveActivity.exported = true;
   3167                 mResolveActivity.enabled = true;
   3168                 mResolveInfo.activityInfo = mResolveActivity;
   3169                 mResolveInfo.priority = 0;
   3170                 mResolveInfo.preferredOrder = 0;
   3171                 mResolveInfo.match = 0;
   3172                 mResolveComponentName = new ComponentName(
   3173                         mAndroidApplication.packageName, mResolveActivity.name);
   3174             }
   3175         }
   3176 
   3177         if (DEBUG_PACKAGE_SCANNING) {
   3178             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   3179                 Log.d(TAG, "Scanning package " + pkg.packageName);
   3180         }
   3181 
   3182         if (mPackages.containsKey(pkg.packageName)
   3183                 || mSharedLibraries.containsKey(pkg.packageName)) {
   3184             Slog.w(TAG, "Application package " + pkg.packageName
   3185                     + " already installed.  Skipping duplicate.");
   3186             mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   3187             return null;
   3188         }
   3189 
   3190         // Initialize package source and resource directories
   3191         File destCodeFile = new File(pkg.applicationInfo.sourceDir);
   3192         File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
   3193 
   3194         SharedUserSetting suid = null;
   3195         PackageSetting pkgSetting = null;
   3196 
   3197         if (!isSystemApp(pkg)) {
   3198             // Only system apps can use these features.
   3199             pkg.mOriginalPackages = null;
   3200             pkg.mRealPackage = null;
   3201             pkg.mAdoptPermissions = null;
   3202         }
   3203 
   3204         // writer
   3205         synchronized (mPackages) {
   3206             // Check all shared libraries and map to their actual file path.
   3207             if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
   3208                 if (mTmpSharedLibraries == null ||
   3209                         mTmpSharedLibraries.length < mSharedLibraries.size()) {
   3210                     mTmpSharedLibraries = new String[mSharedLibraries.size()];
   3211                 }
   3212                 int num = 0;
   3213                 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
   3214                 for (int i=0; i<N; i++) {
   3215                     final String file = mSharedLibraries.get(pkg.usesLibraries.get(i));
   3216                     if (file == null) {
   3217                         Slog.e(TAG, "Package " + pkg.packageName
   3218                                 + " requires unavailable shared library "
   3219                                 + pkg.usesLibraries.get(i) + "; failing!");
   3220                         mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
   3221                         return null;
   3222                     }
   3223                     mTmpSharedLibraries[num] = file;
   3224                     num++;
   3225                 }
   3226                 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
   3227                 for (int i=0; i<N; i++) {
   3228                     final String file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
   3229                     if (file == null) {
   3230                         Slog.w(TAG, "Package " + pkg.packageName
   3231                                 + " desires unavailable shared library "
   3232                                 + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
   3233                     } else {
   3234                         mTmpSharedLibraries[num] = file;
   3235                         num++;
   3236                     }
   3237                 }
   3238                 if (num > 0) {
   3239                     pkg.usesLibraryFiles = new String[num];
   3240                     System.arraycopy(mTmpSharedLibraries, 0,
   3241                             pkg.usesLibraryFiles, 0, num);
   3242                 }
   3243             }
   3244 
   3245             if (pkg.mSharedUserId != null) {
   3246                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId,
   3247                         pkg.applicationInfo.flags, true);
   3248                 if (suid == null) {
   3249                     Slog.w(TAG, "Creating application package " + pkg.packageName
   3250                             + " for shared user failed");
   3251                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3252                     return null;
   3253                 }
   3254                 if (DEBUG_PACKAGE_SCANNING) {
   3255                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   3256                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
   3257                                 + "): packages=" + suid.packages);
   3258                 }
   3259             }
   3260 
   3261             // Check if we are renaming from an original package name.
   3262             PackageSetting origPackage = null;
   3263             String realName = null;
   3264             if (pkg.mOriginalPackages != null) {
   3265                 // This package may need to be renamed to a previously
   3266                 // installed name.  Let's check on that...
   3267                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
   3268                 if (pkg.mOriginalPackages.contains(renamed)) {
   3269                     // This package had originally been installed as the
   3270                     // original name, and we have already taken care of
   3271                     // transitioning to the new one.  Just update the new
   3272                     // one to continue using the old name.
   3273                     realName = pkg.mRealPackage;
   3274                     if (!pkg.packageName.equals(renamed)) {
   3275                         // Callers into this function may have already taken
   3276                         // care of renaming the package; only do it here if
   3277                         // it is not already done.
   3278                         pkg.setPackageName(renamed);
   3279                     }
   3280 
   3281                 } else {
   3282                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
   3283                         if ((origPackage = mSettings.peekPackageLPr(
   3284                                 pkg.mOriginalPackages.get(i))) != null) {
   3285                             // We do have the package already installed under its
   3286                             // original name...  should we use it?
   3287                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
   3288                                 // New package is not compatible with original.
   3289                                 origPackage = null;
   3290                                 continue;
   3291                             } else if (origPackage.sharedUser != null) {
   3292                                 // Make sure uid is compatible between packages.
   3293                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
   3294                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
   3295                                             + " to " + pkg.packageName + ": old uid "
   3296                                             + origPackage.sharedUser.name
   3297                                             + " differs from " + pkg.mSharedUserId);
   3298                                     origPackage = null;
   3299                                     continue;
   3300                                 }
   3301                             } else {
   3302                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
   3303                                         + pkg.packageName + " to old name " + origPackage.name);
   3304                             }
   3305                             break;
   3306                         }
   3307                     }
   3308                 }
   3309             }
   3310 
   3311             if (mTransferedPackages.contains(pkg.packageName)) {
   3312                 Slog.w(TAG, "Package " + pkg.packageName
   3313                         + " was transferred to another, but its .apk remains");
   3314             }
   3315 
   3316             // Just create the setting, don't add it yet. For already existing packages
   3317             // the PkgSetting exists already and doesn't have to be created.
   3318             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
   3319                     destResourceFile, pkg.applicationInfo.nativeLibraryDir,
   3320                     pkg.applicationInfo.flags, true, false);
   3321             if (pkgSetting == null) {
   3322                 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
   3323                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3324                 return null;
   3325             }
   3326 
   3327             if (pkgSetting.origPackage != null) {
   3328                 // If we are first transitioning from an original package,
   3329                 // fix up the new package's name now.  We need to do this after
   3330                 // looking up the package under its new name, so getPackageLP
   3331                 // can take care of fiddling things correctly.
   3332                 pkg.setPackageName(origPackage.name);
   3333 
   3334                 // File a report about this.
   3335                 String msg = "New package " + pkgSetting.realName
   3336                         + " renamed to replace old package " + pkgSetting.name;
   3337                 reportSettingsProblem(Log.WARN, msg);
   3338 
   3339                 // Make a note of it.
   3340                 mTransferedPackages.add(origPackage.name);
   3341 
   3342                 // No longer need to retain this.
   3343                 pkgSetting.origPackage = null;
   3344             }
   3345 
   3346             if (realName != null) {
   3347                 // Make a note of it.
   3348                 mTransferedPackages.add(pkg.packageName);
   3349             }
   3350 
   3351             if (mSettings.mDisabledSysPackages.get(pkg.packageName) != null) {
   3352                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   3353             }
   3354 
   3355             pkg.applicationInfo.uid = pkgSetting.userId;
   3356             pkg.mExtras = pkgSetting;
   3357 
   3358             if (!verifySignaturesLP(pkgSetting, pkg)) {
   3359                 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   3360                     return null;
   3361                 }
   3362                 // The signature has changed, but this package is in the system
   3363                 // image...  let's recover!
   3364                 pkgSetting.signatures.mSignatures = pkg.mSignatures;
   3365                 // However...  if this package is part of a shared user, but it
   3366                 // doesn't match the signature of the shared user, let's fail.
   3367                 // What this means is that you can't change the signatures
   3368                 // associated with an overall shared user, which doesn't seem all
   3369                 // that unreasonable.
   3370                 if (pkgSetting.sharedUser != null) {
   3371                     if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   3372                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   3373                         Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
   3374                         mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
   3375                         return null;
   3376                     }
   3377                 }
   3378                 // File a report about this.
   3379                 String msg = "System package " + pkg.packageName
   3380                         + " signature changed; retaining data.";
   3381                 reportSettingsProblem(Log.WARN, msg);
   3382             }
   3383 
   3384             // Verify that this new package doesn't have any content providers
   3385             // that conflict with existing packages.  Only do this if the
   3386             // package isn't already installed, since we don't want to break
   3387             // things that are installed.
   3388             if ((scanMode&SCAN_NEW_INSTALL) != 0) {
   3389                 final int N = pkg.providers.size();
   3390                 int i;
   3391                 for (i=0; i<N; i++) {
   3392                     PackageParser.Provider p = pkg.providers.get(i);
   3393                     if (p.info.authority != null) {
   3394                         String names[] = p.info.authority.split(";");
   3395                         for (int j = 0; j < names.length; j++) {
   3396                             if (mProviders.containsKey(names[j])) {
   3397                                 PackageParser.Provider other = mProviders.get(names[j]);
   3398                                 Slog.w(TAG, "Can't install because provider name " + names[j] +
   3399                                         " (in package " + pkg.applicationInfo.packageName +
   3400                                         ") is already used by "
   3401                                         + ((other != null && other.getComponentName() != null)
   3402                                                 ? other.getComponentName().getPackageName() : "?"));
   3403                                 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
   3404                                 return null;
   3405                             }
   3406                         }
   3407                     }
   3408                 }
   3409             }
   3410 
   3411             if (pkg.mAdoptPermissions != null) {
   3412                 // This package wants to adopt ownership of permissions from
   3413                 // another package.
   3414                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
   3415                     final String origName = pkg.mAdoptPermissions.get(i);
   3416                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
   3417                     if (orig != null) {
   3418                         if (verifyPackageUpdateLPr(orig, pkg)) {
   3419                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
   3420                                     + pkg.packageName);
   3421                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
   3422                         }
   3423                     }
   3424                 }
   3425             }
   3426         }
   3427 
   3428         final String pkgName = pkg.packageName;
   3429 
   3430         final long scanFileTime = scanFile.lastModified();
   3431         final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
   3432         pkg.applicationInfo.processName = fixProcessName(
   3433                 pkg.applicationInfo.packageName,
   3434                 pkg.applicationInfo.processName,
   3435                 pkg.applicationInfo.uid);
   3436 
   3437         File dataPath;
   3438         if (mPlatformPackage == pkg) {
   3439             // The system package is special.
   3440             dataPath = new File (Environment.getDataDirectory(), "system");
   3441             pkg.applicationInfo.dataDir = dataPath.getPath();
   3442         } else {
   3443             // This is a normal package, need to make its data directory.
   3444             dataPath = getDataPathForPackage(pkg.packageName, 0);
   3445 
   3446             boolean uidError = false;
   3447 
   3448             if (dataPath.exists()) {
   3449                 mOutPermissions[1] = 0;
   3450                 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
   3451 
   3452                 // If we have mismatched owners for the data path, we have a problem.
   3453                 if (mOutPermissions[1] != pkg.applicationInfo.uid) {
   3454                     boolean recovered = false;
   3455                     if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   3456                         // If this is a system app, we can at least delete its
   3457                         // current data so the application will still work.
   3458                         int ret = mInstaller.remove(pkgName, 0);
   3459                         if (ret >= 0) {
   3460                             // TODO: Kill the processes first
   3461                             // Remove the data directories for all users
   3462                             mUserManager.removePackageForAllUsers(pkgName);
   3463                             // Old data gone!
   3464                             String msg = "System package " + pkg.packageName
   3465                                     + " has changed from uid: "
   3466                                     + mOutPermissions[1] + " to "
   3467                                     + pkg.applicationInfo.uid + "; old data erased";
   3468                             reportSettingsProblem(Log.WARN, msg);
   3469                             recovered = true;
   3470 
   3471                             // And now re-install the app.
   3472                             ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
   3473                                     pkg.applicationInfo.uid);
   3474                             if (ret == -1) {
   3475                                 // Ack should not happen!
   3476                                 msg = "System package " + pkg.packageName
   3477                                         + " could not have data directory re-created after delete.";
   3478                                 reportSettingsProblem(Log.WARN, msg);
   3479                                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3480                                 return null;
   3481                             }
   3482                             // Create data directories for all users
   3483                             mUserManager.installPackageForAllUsers(pkgName,
   3484                                     pkg.applicationInfo.uid);
   3485                         }
   3486                         if (!recovered) {
   3487                             mHasSystemUidErrors = true;
   3488                         }
   3489                     }
   3490                     if (!recovered) {
   3491                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
   3492                             + pkg.applicationInfo.uid + "/fs_"
   3493                             + mOutPermissions[1];
   3494                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
   3495                         String msg = "Package " + pkg.packageName
   3496                                 + " has mismatched uid: "
   3497                                 + mOutPermissions[1] + " on disk, "
   3498                                 + pkg.applicationInfo.uid + " in settings";
   3499                         // writer
   3500                         synchronized (mPackages) {
   3501                             mSettings.mReadMessages.append(msg);
   3502                             mSettings.mReadMessages.append('\n');
   3503                             uidError = true;
   3504                             if (!pkgSetting.uidError) {
   3505                                 reportSettingsProblem(Log.ERROR, msg);
   3506                             }
   3507                         }
   3508                     }
   3509                 }
   3510                 pkg.applicationInfo.dataDir = dataPath.getPath();
   3511             } else {
   3512                 if (DEBUG_PACKAGE_SCANNING) {
   3513                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   3514                         Log.v(TAG, "Want this data dir: " + dataPath);
   3515                 }
   3516                 //invoke installer to do the actual installation
   3517                 int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
   3518                         pkg.applicationInfo.uid);
   3519                 if (ret < 0) {
   3520                     // Error from installer
   3521                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3522                     return null;
   3523                 }
   3524                 // Create data directories for all users
   3525                 mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);
   3526 
   3527                 if (dataPath.exists()) {
   3528                     pkg.applicationInfo.dataDir = dataPath.getPath();
   3529                 } else {
   3530                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
   3531                     pkg.applicationInfo.dataDir = null;
   3532                 }
   3533             }
   3534 
   3535             /*
   3536              * Set the data dir to the default "/data/data/<package name>/lib"
   3537              * if we got here without anyone telling us different (e.g., apps
   3538              * stored on SD card have their native libraries stored in the ASEC
   3539              * container with the APK).
   3540              *
   3541              * This happens during an upgrade from a package settings file that
   3542              * doesn't have a native library path attribute at all.
   3543              */
   3544             if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
   3545                 if (pkgSetting.nativeLibraryPathString == null) {
   3546                     final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
   3547                     pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
   3548                     pkgSetting.nativeLibraryPathString = nativeLibraryPath;
   3549                 } else {
   3550                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
   3551                 }
   3552             }
   3553 
   3554             pkgSetting.uidError = uidError;
   3555         }
   3556 
   3557         String path = scanFile.getPath();
   3558         /* Note: We don't want to unpack the native binaries for
   3559          *        system applications, unless they have been updated
   3560          *        (the binaries are already under /system/lib).
   3561          *        Also, don't unpack libs for apps on the external card
   3562          *        since they should have their libraries in the ASEC
   3563          *        container already.
   3564          *
   3565          *        In other words, we're going to unpack the binaries
   3566          *        only for non-system apps and system app upgrades.
   3567          */
   3568         if (pkg.applicationInfo.nativeLibraryDir != null) {
   3569             try {
   3570                 final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
   3571                 final String dataPathString = dataPath.getCanonicalPath();
   3572 
   3573                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
   3574                     /*
   3575                      * Upgrading from a previous version of the OS sometimes
   3576                      * leaves native libraries in the /data/data/<app>/lib
   3577                      * directory for system apps even when they shouldn't be.
   3578                      * Recent changes in the JNI library search path
   3579                      * necessitates we remove those to match previous behavior.
   3580                      */
   3581                     if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
   3582                         Log.i(TAG, "removed obsolete native libraries for system package "
   3583                                 + path);
   3584                     }
   3585                 } else if (nativeLibraryDir.getParentFile().getCanonicalPath()
   3586                         .equals(dataPathString)) {
   3587                     /*
   3588                      * Make sure the native library dir isn't a symlink to
   3589                      * something. If it is, ask installd to remove it and create
   3590                      * a directory so we can copy to it afterwards.
   3591                      */
   3592                     boolean isSymLink;
   3593                     try {
   3594                         isSymLink = S_ISLNK(Libcore.os.lstat(nativeLibraryDir.getPath()).st_mode);
   3595                     } catch (ErrnoException e) {
   3596                         // This shouldn't happen, but we'll fail-safe.
   3597                         isSymLink = true;
   3598                     }
   3599                     if (isSymLink) {
   3600                         mInstaller.unlinkNativeLibraryDirectory(dataPathString);
   3601                     }
   3602 
   3603                     /*
   3604                      * If this is an internal application or our
   3605                      * nativeLibraryPath points to our data directory, unpack
   3606                      * the libraries if necessary.
   3607                      */
   3608                     NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
   3609                 } else {
   3610                     Slog.i(TAG, "Linking native library dir for " + path);
   3611                     mInstaller.linkNativeLibraryDirectory(dataPathString,
   3612                             pkg.applicationInfo.nativeLibraryDir);
   3613                 }
   3614             } catch (IOException ioe) {
   3615                 Log.e(TAG, "Unable to get canonical file " + ioe.toString());
   3616             }
   3617         }
   3618         pkg.mScanPath = path;
   3619 
   3620         if ((scanMode&SCAN_NO_DEX) == 0) {
   3621             if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0)
   3622                     == DEX_OPT_FAILED) {
   3623                 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
   3624                 return null;
   3625             }
   3626         }
   3627 
   3628         if (mFactoryTest && pkg.requestedPermissions.contains(
   3629                 android.Manifest.permission.FACTORY_TEST)) {
   3630             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
   3631         }
   3632 
   3633         // Request the ActivityManager to kill the process(only for existing packages)
   3634         // so that we do not end up in a confused state while the user is still using the older
   3635         // version of the application while the new one gets installed.
   3636         if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   3637             killApplication(pkg.applicationInfo.packageName,
   3638                         pkg.applicationInfo.uid);
   3639         }
   3640 
   3641         // writer
   3642         synchronized (mPackages) {
   3643             // We don't expect installation to fail beyond this point,
   3644             if ((scanMode&SCAN_MONITOR) != 0) {
   3645                 mAppDirs.put(pkg.mPath, pkg);
   3646             }
   3647             // Add the new setting to mSettings
   3648             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
   3649             // Add the new setting to mPackages
   3650             mPackages.put(pkg.applicationInfo.packageName, pkg);
   3651             // Make sure we don't accidentally delete its data.
   3652             mSettings.mPackagesToBeCleaned.remove(pkgName);
   3653 
   3654             // Take care of first install / last update times.
   3655             if (currentTime != 0) {
   3656                 if (pkgSetting.firstInstallTime == 0) {
   3657                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
   3658                 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
   3659                     pkgSetting.lastUpdateTime = currentTime;
   3660                 }
   3661             } else if (pkgSetting.firstInstallTime == 0) {
   3662                 // We need *something*.  Take time time stamp of the file.
   3663                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
   3664             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
   3665                 if (scanFileTime != pkgSetting.timeStamp) {
   3666                     // A package on the system image has changed; consider this
   3667                     // to be an update.
   3668                     pkgSetting.lastUpdateTime = scanFileTime;
   3669                 }
   3670             }
   3671 
   3672             int N = pkg.providers.size();
   3673             StringBuilder r = null;
   3674             int i;
   3675             for (i=0; i<N; i++) {
   3676                 PackageParser.Provider p = pkg.providers.get(i);
   3677                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
   3678                         p.info.processName, pkg.applicationInfo.uid);
   3679                 mProvidersByComponent.put(new ComponentName(p.info.packageName,
   3680                         p.info.name), p);
   3681                 p.syncable = p.info.isSyncable;
   3682                 if (p.info.authority != null) {
   3683                     String names[] = p.info.authority.split(";");
   3684                     p.info.authority = null;
   3685                     for (int j = 0; j < names.length; j++) {
   3686                         if (j == 1 && p.syncable) {
   3687                             // We only want the first authority for a provider to possibly be
   3688                             // syncable, so if we already added this provider using a different
   3689                             // authority clear the syncable flag. We copy the provider before
   3690                             // changing it because the mProviders object contains a reference
   3691                             // to a provider that we don't want to change.
   3692                             // Only do this for the second authority since the resulting provider
   3693                             // object can be the same for all future authorities for this provider.
   3694                             p = new PackageParser.Provider(p);
   3695                             p.syncable = false;
   3696                         }
   3697                         if (!mProviders.containsKey(names[j])) {
   3698                             mProviders.put(names[j], p);
   3699                             if (p.info.authority == null) {
   3700                                 p.info.authority = names[j];
   3701                             } else {
   3702                                 p.info.authority = p.info.authority + ";" + names[j];
   3703                             }
   3704                             if (DEBUG_PACKAGE_SCANNING) {
   3705                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   3706                                     Log.d(TAG, "Registered content provider: " + names[j]
   3707                                             + ", className = " + p.info.name + ", isSyncable = "
   3708                                             + p.info.isSyncable);
   3709                             }
   3710                         } else {
   3711                             PackageParser.Provider other = mProviders.get(names[j]);
   3712                             Slog.w(TAG, "Skipping provider name " + names[j] +
   3713                                     " (in package " + pkg.applicationInfo.packageName +
   3714                                     "): name already used by "
   3715                                     + ((other != null && other.getComponentName() != null)
   3716                                             ? other.getComponentName().getPackageName() : "?"));
   3717                         }
   3718                     }
   3719                 }
   3720                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3721                     if (r == null) {
   3722                         r = new StringBuilder(256);
   3723                     } else {
   3724                         r.append(' ');
   3725                     }
   3726                     r.append(p.info.name);
   3727                 }
   3728             }
   3729             if (r != null) {
   3730                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
   3731             }
   3732 
   3733             N = pkg.services.size();
   3734             r = null;
   3735             for (i=0; i<N; i++) {
   3736                 PackageParser.Service s = pkg.services.get(i);
   3737                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
   3738                         s.info.processName, pkg.applicationInfo.uid);
   3739                 mServices.addService(s);
   3740                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3741                     if (r == null) {
   3742                         r = new StringBuilder(256);
   3743                     } else {
   3744                         r.append(' ');
   3745                     }
   3746                     r.append(s.info.name);
   3747                 }
   3748             }
   3749             if (r != null) {
   3750                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
   3751             }
   3752 
   3753             N = pkg.receivers.size();
   3754             r = null;
   3755             for (i=0; i<N; i++) {
   3756                 PackageParser.Activity a = pkg.receivers.get(i);
   3757                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   3758                         a.info.processName, pkg.applicationInfo.uid);
   3759                 mReceivers.addActivity(a, "receiver");
   3760                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3761                     if (r == null) {
   3762                         r = new StringBuilder(256);
   3763                     } else {
   3764                         r.append(' ');
   3765                     }
   3766                     r.append(a.info.name);
   3767                 }
   3768             }
   3769             if (r != null) {
   3770                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
   3771             }
   3772 
   3773             N = pkg.activities.size();
   3774             r = null;
   3775             for (i=0; i<N; i++) {
   3776                 PackageParser.Activity a = pkg.activities.get(i);
   3777                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   3778                         a.info.processName, pkg.applicationInfo.uid);
   3779                 mActivities.addActivity(a, "activity");
   3780                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3781                     if (r == null) {
   3782                         r = new StringBuilder(256);
   3783                     } else {
   3784                         r.append(' ');
   3785                     }
   3786                     r.append(a.info.name);
   3787                 }
   3788             }
   3789             if (r != null) {
   3790                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
   3791             }
   3792 
   3793             N = pkg.permissionGroups.size();
   3794             r = null;
   3795             for (i=0; i<N; i++) {
   3796                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
   3797                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
   3798                 if (cur == null) {
   3799                     mPermissionGroups.put(pg.info.name, pg);
   3800                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3801                         if (r == null) {
   3802                             r = new StringBuilder(256);
   3803                         } else {
   3804                             r.append(' ');
   3805                         }
   3806                         r.append(pg.info.name);
   3807                     }
   3808                 } else {
   3809                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
   3810                             + pg.info.packageName + " ignored: original from "
   3811                             + cur.info.packageName);
   3812                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3813                         if (r == null) {
   3814                             r = new StringBuilder(256);
   3815                         } else {
   3816                             r.append(' ');
   3817                         }
   3818                         r.append("DUP:");
   3819                         r.append(pg.info.name);
   3820                     }
   3821                 }
   3822             }
   3823             if (r != null) {
   3824                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
   3825             }
   3826 
   3827             N = pkg.permissions.size();
   3828             r = null;
   3829             for (i=0; i<N; i++) {
   3830                 PackageParser.Permission p = pkg.permissions.get(i);
   3831                 HashMap<String, BasePermission> permissionMap =
   3832                         p.tree ? mSettings.mPermissionTrees
   3833                         : mSettings.mPermissions;
   3834                 p.group = mPermissionGroups.get(p.info.group);
   3835                 if (p.info.group == null || p.group != null) {
   3836                     BasePermission bp = permissionMap.get(p.info.name);
   3837                     if (bp == null) {
   3838                         bp = new BasePermission(p.info.name, p.info.packageName,
   3839                                 BasePermission.TYPE_NORMAL);
   3840                         permissionMap.put(p.info.name, bp);
   3841                     }
   3842                     if (bp.perm == null) {
   3843                         if (bp.sourcePackage == null
   3844                                 || bp.sourcePackage.equals(p.info.packageName)) {
   3845                             BasePermission tree = findPermissionTreeLP(p.info.name);
   3846                             if (tree == null
   3847                                     || tree.sourcePackage.equals(p.info.packageName)) {
   3848                                 bp.packageSetting = pkgSetting;
   3849                                 bp.perm = p;
   3850                                 bp.uid = pkg.applicationInfo.uid;
   3851                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3852                                     if (r == null) {
   3853                                         r = new StringBuilder(256);
   3854                                     } else {
   3855                                         r.append(' ');
   3856                                     }
   3857                                     r.append(p.info.name);
   3858                                 }
   3859                             } else {
   3860                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
   3861                                         + p.info.packageName + " ignored: base tree "
   3862                                         + tree.name + " is from package "
   3863                                         + tree.sourcePackage);
   3864                             }
   3865                         } else {
   3866                             Slog.w(TAG, "Permission " + p.info.name + " from package "
   3867                                     + p.info.packageName + " ignored: original from "
   3868                                     + bp.sourcePackage);
   3869                         }
   3870                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3871                         if (r == null) {
   3872                             r = new StringBuilder(256);
   3873                         } else {
   3874                             r.append(' ');
   3875                         }
   3876                         r.append("DUP:");
   3877                         r.append(p.info.name);
   3878                     }
   3879                     if (bp.perm == p) {
   3880                         bp.protectionLevel = p.info.protectionLevel;
   3881                     }
   3882                 } else {
   3883                     Slog.w(TAG, "Permission " + p.info.name + " from package "
   3884                             + p.info.packageName + " ignored: no group "
   3885                             + p.group);
   3886                 }
   3887             }
   3888             if (r != null) {
   3889                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
   3890             }
   3891 
   3892             N = pkg.instrumentation.size();
   3893             r = null;
   3894             for (i=0; i<N; i++) {
   3895                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   3896                 a.info.packageName = pkg.applicationInfo.packageName;
   3897                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
   3898                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
   3899                 a.info.dataDir = pkg.applicationInfo.dataDir;
   3900                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
   3901                 mInstrumentation.put(a.getComponentName(), a);
   3902                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3903                     if (r == null) {
   3904                         r = new StringBuilder(256);
   3905                     } else {
   3906                         r.append(' ');
   3907                     }
   3908                     r.append(a.info.name);
   3909                 }
   3910             }
   3911             if (r != null) {
   3912                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
   3913             }
   3914 
   3915             if (pkg.protectedBroadcasts != null) {
   3916                 N = pkg.protectedBroadcasts.size();
   3917                 for (i=0; i<N; i++) {
   3918                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
   3919                 }
   3920             }
   3921 
   3922             pkgSetting.setTimeStamp(scanFileTime);
   3923         }
   3924 
   3925         return pkg;
   3926     }
   3927 
   3928     private void killApplication(String pkgName, int uid) {
   3929         // Request the ActivityManager to kill the process(only for existing packages)
   3930         // so that we do not end up in a confused state while the user is still using the older
   3931         // version of the application while the new one gets installed.
   3932         IActivityManager am = ActivityManagerNative.getDefault();
   3933         if (am != null) {
   3934             try {
   3935                 am.killApplicationWithUid(pkgName, uid);
   3936             } catch (RemoteException e) {
   3937             }
   3938         }
   3939     }
   3940 
   3941     void removePackageLI(PackageParser.Package pkg, boolean chatty) {
   3942         if (DEBUG_INSTALL) {
   3943             if (chatty)
   3944                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
   3945         }
   3946 
   3947         // writer
   3948         synchronized (mPackages) {
   3949             clearPackagePreferredActivitiesLPw(pkg.packageName);
   3950 
   3951             mPackages.remove(pkg.applicationInfo.packageName);
   3952             if (pkg.mPath != null) {
   3953                 mAppDirs.remove(pkg.mPath);
   3954             }
   3955 
   3956             int N = pkg.providers.size();
   3957             StringBuilder r = null;
   3958             int i;
   3959             for (i=0; i<N; i++) {
   3960                 PackageParser.Provider p = pkg.providers.get(i);
   3961                 mProvidersByComponent.remove(new ComponentName(p.info.packageName,
   3962                         p.info.name));
   3963                 if (p.info.authority == null) {
   3964 
   3965                     /* The is another ContentProvider with this authority when
   3966                      * this app was installed so this authority is null,
   3967                      * Ignore it as we don't have to unregister the provider.
   3968                      */
   3969                     continue;
   3970                 }
   3971                 String names[] = p.info.authority.split(";");
   3972                 for (int j = 0; j < names.length; j++) {
   3973                     if (mProviders.get(names[j]) == p) {
   3974                         mProviders.remove(names[j]);
   3975                         if (DEBUG_REMOVE) {
   3976                             if (chatty)
   3977                                 Log.d(TAG, "Unregistered content provider: " + names[j]
   3978                                         + ", className = " + p.info.name + ", isSyncable = "
   3979                                         + p.info.isSyncable);
   3980                         }
   3981                     }
   3982                 }
   3983                 if (chatty) {
   3984                     if (r == null) {
   3985                         r = new StringBuilder(256);
   3986                     } else {
   3987                         r.append(' ');
   3988                     }
   3989                     r.append(p.info.name);
   3990                 }
   3991             }
   3992             if (r != null) {
   3993                 if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
   3994             }
   3995 
   3996             N = pkg.services.size();
   3997             r = null;
   3998             for (i=0; i<N; i++) {
   3999                 PackageParser.Service s = pkg.services.get(i);
   4000                 mServices.removeService(s);
   4001                 if (chatty) {
   4002                     if (r == null) {
   4003                         r = new StringBuilder(256);
   4004                     } else {
   4005                         r.append(' ');
   4006                     }
   4007                     r.append(s.info.name);
   4008                 }
   4009             }
   4010             if (r != null) {
   4011                 if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
   4012             }
   4013 
   4014             N = pkg.receivers.size();
   4015             r = null;
   4016             for (i=0; i<N; i++) {
   4017                 PackageParser.Activity a = pkg.receivers.get(i);
   4018                 mReceivers.removeActivity(a, "receiver");
   4019                 if (chatty) {
   4020                     if (r == null) {
   4021                         r = new StringBuilder(256);
   4022                     } else {
   4023                         r.append(' ');
   4024                     }
   4025                     r.append(a.info.name);
   4026                 }
   4027             }
   4028             if (r != null) {
   4029                 if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
   4030             }
   4031 
   4032             N = pkg.activities.size();
   4033             r = null;
   4034             for (i=0; i<N; i++) {
   4035                 PackageParser.Activity a = pkg.activities.get(i);
   4036                 mActivities.removeActivity(a, "activity");
   4037                 if (chatty) {
   4038                     if (r == null) {
   4039                         r = new StringBuilder(256);
   4040                     } else {
   4041                         r.append(' ');
   4042                     }
   4043                     r.append(a.info.name);
   4044                 }
   4045             }
   4046             if (r != null) {
   4047                 if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
   4048             }
   4049 
   4050             N = pkg.permissions.size();
   4051             r = null;
   4052             for (i=0; i<N; i++) {
   4053                 PackageParser.Permission p = pkg.permissions.get(i);
   4054                 BasePermission bp = mSettings.mPermissions.get(p.info.name);
   4055                 if (bp == null) {
   4056                     bp = mSettings.mPermissionTrees.get(p.info.name);
   4057                 }
   4058                 if (bp != null && bp.perm == p) {
   4059                     bp.perm = null;
   4060                     if (chatty) {
   4061                         if (r == null) {
   4062                             r = new StringBuilder(256);
   4063                         } else {
   4064                             r.append(' ');
   4065                         }
   4066                         r.append(p.info.name);
   4067                     }
   4068                 }
   4069             }
   4070             if (r != null) {
   4071                 if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   4072             }
   4073 
   4074             N = pkg.instrumentation.size();
   4075             r = null;
   4076             for (i=0; i<N; i++) {
   4077                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   4078                 mInstrumentation.remove(a.getComponentName());
   4079                 if (chatty) {
   4080                     if (r == null) {
   4081                         r = new StringBuilder(256);
   4082                     } else {
   4083                         r.append(' ');
   4084                     }
   4085                     r.append(a.info.name);
   4086                 }
   4087             }
   4088             if (r != null) {
   4089                 if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
   4090             }
   4091         }
   4092     }
   4093 
   4094     private static final boolean isPackageFilename(String name) {
   4095         return name != null && name.endsWith(".apk");
   4096     }
   4097 
   4098     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
   4099         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
   4100             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
   4101                 return true;
   4102             }
   4103         }
   4104         return false;
   4105     }
   4106 
   4107     private void updatePermissionsLPw(String changingPkg,
   4108             PackageParser.Package pkgInfo, boolean grantPermissions,
   4109             boolean replace, boolean replaceAll) {
   4110         // Make sure there are no dangling permission trees.
   4111         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
   4112         while (it.hasNext()) {
   4113             final BasePermission bp = it.next();
   4114             if (bp.packageSetting == null) {
   4115                 // We may not yet have parsed the package, so just see if
   4116                 // we still know about its settings.
   4117                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   4118             }
   4119             if (bp.packageSetting == null) {
   4120                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
   4121                         + " from package " + bp.sourcePackage);
   4122                 it.remove();
   4123             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   4124                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   4125                     Slog.i(TAG, "Removing old permission tree: " + bp.name
   4126                             + " from package " + bp.sourcePackage);
   4127                     grantPermissions = true;
   4128                     it.remove();
   4129                 }
   4130             }
   4131         }
   4132 
   4133         // Make sure all dynamic permissions have been assigned to a package,
   4134         // and make sure there are no dangling permissions.
   4135         it = mSettings.mPermissions.values().iterator();
   4136         while (it.hasNext()) {
   4137             final BasePermission bp = it.next();
   4138             if (bp.type == BasePermission.TYPE_DYNAMIC) {
   4139                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
   4140                         + bp.name + " pkg=" + bp.sourcePackage
   4141                         + " info=" + bp.pendingInfo);
   4142                 if (bp.packageSetting == null && bp.pendingInfo != null) {
   4143                     final BasePermission tree = findPermissionTreeLP(bp.name);
   4144                     if (tree != null && tree.perm != null) {
   4145                         bp.packageSetting = tree.packageSetting;
   4146                         bp.perm = new PackageParser.Permission(tree.perm.owner,
   4147                                 new PermissionInfo(bp.pendingInfo));
   4148                         bp.perm.info.packageName = tree.perm.info.packageName;
   4149                         bp.perm.info.name = bp.name;
   4150                         bp.uid = tree.uid;
   4151                     }
   4152                 }
   4153             }
   4154             if (bp.packageSetting == null) {
   4155                 // We may not yet have parsed the package, so just see if
   4156                 // we still know about its settings.
   4157                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   4158             }
   4159             if (bp.packageSetting == null) {
   4160                 Slog.w(TAG, "Removing dangling permission: " + bp.name
   4161                         + " from package " + bp.sourcePackage);
   4162                 it.remove();
   4163             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   4164                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   4165                     Slog.i(TAG, "Removing old permission: " + bp.name
   4166                             + " from package " + bp.sourcePackage);
   4167                     grantPermissions = true;
   4168                     it.remove();
   4169                 }
   4170             }
   4171         }
   4172 
   4173         // Now update the permissions for all packages, in particular
   4174         // replace the granted permissions of the system packages.
   4175         if (grantPermissions) {
   4176             for (PackageParser.Package pkg : mPackages.values()) {
   4177                 if (pkg != pkgInfo) {
   4178                     grantPermissionsLPw(pkg, replaceAll);
   4179                 }
   4180             }
   4181         }
   4182 
   4183         if (pkgInfo != null) {
   4184             grantPermissionsLPw(pkgInfo, replace);
   4185         }
   4186     }
   4187 
   4188     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
   4189         final PackageSetting ps = (PackageSetting) pkg.mExtras;
   4190         if (ps == null) {
   4191             return;
   4192         }
   4193         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   4194         boolean changedPermission = false;
   4195 
   4196         if (replace) {
   4197             ps.permissionsFixed = false;
   4198             if (gp == ps) {
   4199                 gp.grantedPermissions.clear();
   4200                 gp.gids = mGlobalGids;
   4201             }
   4202         }
   4203 
   4204         if (gp.gids == null) {
   4205             gp.gids = mGlobalGids;
   4206         }
   4207 
   4208         final int N = pkg.requestedPermissions.size();
   4209         for (int i=0; i<N; i++) {
   4210             final String name = pkg.requestedPermissions.get(i);
   4211             final BasePermission bp = mSettings.mPermissions.get(name);
   4212             if (DEBUG_INSTALL) {
   4213                 if (gp != ps) {
   4214                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
   4215                 }
   4216             }
   4217             if (bp != null && bp.packageSetting != null) {
   4218                 final String perm = bp.name;
   4219                 boolean allowed;
   4220                 boolean allowedSig = false;
   4221                 if (bp.protectionLevel == PermissionInfo.PROTECTION_NORMAL
   4222                         || bp.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
   4223                     allowed = true;
   4224                 } else if (bp.packageSetting == null) {
   4225                     // This permission is invalid; skip it.
   4226                     allowed = false;
   4227                 } else if (bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE
   4228                         || bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
   4229                     allowed = (compareSignatures(
   4230                             bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
   4231                                     == PackageManager.SIGNATURE_MATCH)
   4232                             || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
   4233                                     == PackageManager.SIGNATURE_MATCH);
   4234                     if (!allowed && bp.protectionLevel
   4235                             == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
   4236                         if (isSystemApp(pkg)) {
   4237                             // For updated system applications, the signatureOrSystem permission
   4238                             // is granted only if it had been defined by the original application.
   4239                             if (isUpdatedSystemApp(pkg)) {
   4240                                 final PackageSetting sysPs = mSettings
   4241                                         .getDisabledSystemPkgLPr(pkg.packageName);
   4242                                 final GrantedPermissions origGp = sysPs.sharedUser != null
   4243                                         ? sysPs.sharedUser : sysPs;
   4244                                 if (origGp.grantedPermissions.contains(perm)) {
   4245                                     allowed = true;
   4246                                 } else {
   4247                                     allowed = false;
   4248                                 }
   4249                             } else {
   4250                                 allowed = true;
   4251                             }
   4252                         }
   4253                     }
   4254                     if (allowed) {
   4255                         allowedSig = true;
   4256                     }
   4257                 } else {
   4258                     allowed = false;
   4259                 }
   4260                 if (DEBUG_INSTALL) {
   4261                     if (gp != ps) {
   4262                         Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
   4263                     }
   4264                 }
   4265                 if (allowed) {
   4266                     if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
   4267                             && ps.permissionsFixed) {
   4268                         // If this is an existing, non-system package, then
   4269                         // we can't add any new permissions to it.
   4270                         if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
   4271                             allowed = false;
   4272                             // Except...  if this is a permission that was added
   4273                             // to the platform (note: need to only do this when
   4274                             // updating the platform).
   4275                             final int NP = PackageParser.NEW_PERMISSIONS.length;
   4276                             for (int ip=0; ip<NP; ip++) {
   4277                                 final PackageParser.NewPermissionInfo npi
   4278                                         = PackageParser.NEW_PERMISSIONS[ip];
   4279                                 if (npi.name.equals(perm)
   4280                                         && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
   4281                                     allowed = true;
   4282                                     Log.i(TAG, "Auto-granting " + perm + " to old pkg "
   4283                                             + pkg.packageName);
   4284                                     break;
   4285                                 }
   4286                             }
   4287                         }
   4288                     }
   4289                     if (allowed) {
   4290                         if (!gp.grantedPermissions.contains(perm)) {
   4291                             changedPermission = true;
   4292                             gp.grantedPermissions.add(perm);
   4293                             gp.gids = appendInts(gp.gids, bp.gids);
   4294                         } else if (!ps.haveGids) {
   4295                             gp.gids = appendInts(gp.gids, bp.gids);
   4296                         }
   4297                     } else {
   4298                         Slog.w(TAG, "Not granting permission " + perm
   4299                                 + " to package " + pkg.packageName
   4300                                 + " because it was previously installed without");
   4301                     }
   4302                 } else {
   4303                     if (gp.grantedPermissions.remove(perm)) {
   4304                         changedPermission = true;
   4305                         gp.gids = removeInts(gp.gids, bp.gids);
   4306                         Slog.i(TAG, "Un-granting permission " + perm
   4307                                 + " from package " + pkg.packageName
   4308                                 + " (protectionLevel=" + bp.protectionLevel
   4309                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   4310                                 + ")");
   4311                     } else {
   4312                         Slog.w(TAG, "Not granting permission " + perm
   4313                                 + " to package " + pkg.packageName
   4314                                 + " (protectionLevel=" + bp.protectionLevel
   4315                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   4316                                 + ")");
   4317                     }
   4318                 }
   4319             } else {
   4320                 Slog.w(TAG, "Unknown permission " + name
   4321                         + " in package " + pkg.packageName);
   4322             }
   4323         }
   4324 
   4325         if ((changedPermission || replace) && !ps.permissionsFixed &&
   4326                 ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) ||
   4327                 ((ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)){
   4328             // This is the first that we have heard about this package, so the
   4329             // permissions we have now selected are fixed until explicitly
   4330             // changed.
   4331             ps.permissionsFixed = true;
   4332         }
   4333         ps.haveGids = true;
   4334     }
   4335 
   4336     private final class ActivityIntentResolver
   4337             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
   4338         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   4339                 boolean defaultOnly) {
   4340             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   4341             return super.queryIntent(intent, resolvedType, defaultOnly);
   4342         }
   4343 
   4344         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags) {
   4345             mFlags = flags;
   4346             return super.queryIntent(intent, resolvedType,
   4347                 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
   4348         }
   4349 
   4350         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   4351                 int flags, ArrayList<PackageParser.Activity> packageActivities) {
   4352             if (packageActivities == null) {
   4353                 return null;
   4354             }
   4355             mFlags = flags;
   4356             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   4357             final int N = packageActivities.size();
   4358             ArrayList<ArrayList<PackageParser.ActivityIntentInfo>> listCut =
   4359                 new ArrayList<ArrayList<PackageParser.ActivityIntentInfo>>(N);
   4360 
   4361             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
   4362             for (int i = 0; i < N; ++i) {
   4363                 intentFilters = packageActivities.get(i).intents;
   4364                 if (intentFilters != null && intentFilters.size() > 0) {
   4365                     listCut.add(intentFilters);
   4366                 }
   4367             }
   4368             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
   4369         }
   4370 
   4371         public final void addActivity(PackageParser.Activity a, String type) {
   4372             final boolean systemApp = isSystemApp(a.info.applicationInfo);
   4373             mActivities.put(a.getComponentName(), a);
   4374             if (DEBUG_SHOW_INFO)
   4375                 Log.v(
   4376                 TAG, "  " + type + " " +
   4377                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
   4378             if (DEBUG_SHOW_INFO)
   4379                 Log.v(TAG, "    Class=" + a.info.name);
   4380             final int NI = a.intents.size();
   4381             for (int j=0; j<NI; j++) {
   4382                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   4383                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
   4384                     intent.setPriority(0);
   4385                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
   4386                             + a.className + " with priority > 0, forcing to 0");
   4387                 }
   4388                 if (DEBUG_SHOW_INFO) {
   4389                     Log.v(TAG, "    IntentFilter:");
   4390                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   4391                 }
   4392                 if (!intent.debugCheck()) {
   4393                     Log.w(TAG, "==> For Activity " + a.info.name);
   4394                 }
   4395                 addFilter(intent);
   4396             }
   4397         }
   4398 
   4399         public final void removeActivity(PackageParser.Activity a, String type) {
   4400             mActivities.remove(a.getComponentName());
   4401             if (DEBUG_SHOW_INFO) {
   4402                 Log.v(TAG, "  " + type + " "
   4403                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
   4404                                 : a.info.name) + ":");
   4405                 Log.v(TAG, "    Class=" + a.info.name);
   4406             }
   4407             final int NI = a.intents.size();
   4408             for (int j=0; j<NI; j++) {
   4409                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   4410                 if (DEBUG_SHOW_INFO) {
   4411                     Log.v(TAG, "    IntentFilter:");
   4412                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   4413                 }
   4414                 removeFilter(intent);
   4415             }
   4416         }
   4417 
   4418         @Override
   4419         protected boolean allowFilterResult(
   4420                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
   4421             ActivityInfo filterAi = filter.activity.info;
   4422             for (int i=dest.size()-1; i>=0; i--) {
   4423                 ActivityInfo destAi = dest.get(i).activityInfo;
   4424                 if (destAi.name == filterAi.name
   4425                         && destAi.packageName == filterAi.packageName) {
   4426                     return false;
   4427                 }
   4428             }
   4429             return true;
   4430         }
   4431 
   4432         @Override
   4433         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter) {
   4434             PackageParser.Package p = filter.activity.owner;
   4435             if (p != null) {
   4436                 PackageSetting ps = (PackageSetting)p.mExtras;
   4437                 if (ps != null) {
   4438                     // System apps are never considered stopped for purposes of
   4439                     // filtering, because there may be no way for the user to
   4440                     // actually re-launch them.
   4441                     return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0;
   4442                 }
   4443             }
   4444             return false;
   4445         }
   4446 
   4447         @Override
   4448         protected String packageForFilter(PackageParser.ActivityIntentInfo info) {
   4449             return info.activity.owner.packageName;
   4450         }
   4451 
   4452         @Override
   4453         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
   4454                 int match) {
   4455             if (!mSettings.isEnabledLPr(info.activity.info, mFlags)) {
   4456                 return null;
   4457             }
   4458             final PackageParser.Activity activity = info.activity;
   4459             if (mSafeMode && (activity.info.applicationInfo.flags
   4460                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   4461                 return null;
   4462             }
   4463             final ResolveInfo res = new ResolveInfo();
   4464             res.activityInfo = PackageParser.generateActivityInfo(activity,
   4465                     mFlags);
   4466             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   4467                 res.filter = info;
   4468             }
   4469             res.priority = info.getPriority();
   4470             res.preferredOrder = activity.owner.mPreferredOrder;
   4471             //System.out.println("Result: " + res.activityInfo.className +
   4472             //                   " = " + res.priority);
   4473             res.match = match;
   4474             res.isDefault = info.hasDefault;
   4475             res.labelRes = info.labelRes;
   4476             res.nonLocalizedLabel = info.nonLocalizedLabel;
   4477             res.icon = info.icon;
   4478             res.system = isSystemApp(res.activityInfo.applicationInfo);
   4479             return res;
   4480         }
   4481 
   4482         @Override
   4483         protected void sortResults(List<ResolveInfo> results) {
   4484             Collections.sort(results, mResolvePrioritySorter);
   4485         }
   4486 
   4487         @Override
   4488         protected void dumpFilter(PrintWriter out, String prefix,
   4489                 PackageParser.ActivityIntentInfo filter) {
   4490             out.print(prefix); out.print(
   4491                     Integer.toHexString(System.identityHashCode(filter.activity)));
   4492                     out.print(' ');
   4493                     out.print(filter.activity.getComponentShortName());
   4494                     out.print(" filter ");
   4495                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   4496         }
   4497 
   4498 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   4499 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   4500 //            final List<ResolveInfo> retList = Lists.newArrayList();
   4501 //            while (i.hasNext()) {
   4502 //                final ResolveInfo resolveInfo = i.next();
   4503 //                if (isEnabledLP(resolveInfo.activityInfo)) {
   4504 //                    retList.add(resolveInfo);
   4505 //                }
   4506 //            }
   4507 //            return retList;
   4508 //        }
   4509 
   4510         // Keys are String (activity class name), values are Activity.
   4511         private final HashMap<ComponentName, PackageParser.Activity> mActivities
   4512                 = new HashMap<ComponentName, PackageParser.Activity>();
   4513         private int mFlags;
   4514     }
   4515 
   4516     private final class ServiceIntentResolver
   4517             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
   4518         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   4519                 boolean defaultOnly) {
   4520             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   4521             return super.queryIntent(intent, resolvedType, defaultOnly);
   4522         }
   4523 
   4524         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags) {
   4525             mFlags = flags;
   4526             return super.queryIntent(intent, resolvedType,
   4527                 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
   4528         }
   4529 
   4530         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   4531                 int flags, ArrayList<PackageParser.Service> packageServices) {
   4532             if (packageServices == null) {
   4533                 return null;
   4534             }
   4535             mFlags = flags;
   4536             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   4537             final int N = packageServices.size();
   4538             ArrayList<ArrayList<PackageParser.ServiceIntentInfo>> listCut =
   4539                 new ArrayList<ArrayList<PackageParser.ServiceIntentInfo>>(N);
   4540 
   4541             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
   4542             for (int i = 0; i < N; ++i) {
   4543                 intentFilters = packageServices.get(i).intents;
   4544                 if (intentFilters != null && intentFilters.size() > 0) {
   4545                     listCut.add(intentFilters);
   4546                 }
   4547             }
   4548             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
   4549         }
   4550 
   4551         public final void addService(PackageParser.Service s) {
   4552             mServices.put(s.getComponentName(), s);
   4553             if (DEBUG_SHOW_INFO) {
   4554                 Log.v(TAG, "  "
   4555                         + (s.info.nonLocalizedLabel != null
   4556                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   4557                 Log.v(TAG, "    Class=" + s.info.name);
   4558             }
   4559             final int NI = s.intents.size();
   4560             int j;
   4561             for (j=0; j<NI; j++) {
   4562                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   4563                 if (DEBUG_SHOW_INFO) {
   4564                     Log.v(TAG, "    IntentFilter:");
   4565                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   4566                 }
   4567                 if (!intent.debugCheck()) {
   4568                     Log.w(TAG, "==> For Service " + s.info.name);
   4569                 }
   4570                 addFilter(intent);
   4571             }
   4572         }
   4573 
   4574         public final void removeService(PackageParser.Service s) {
   4575             mServices.remove(s.getComponentName());
   4576             if (DEBUG_SHOW_INFO) {
   4577                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
   4578                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   4579                 Log.v(TAG, "    Class=" + s.info.name);
   4580             }
   4581             final int NI = s.intents.size();
   4582             int j;
   4583             for (j=0; j<NI; j++) {
   4584                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   4585                 if (DEBUG_SHOW_INFO) {
   4586                     Log.v(TAG, "    IntentFilter:");
   4587                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   4588                 }
   4589                 removeFilter(intent);
   4590             }
   4591         }
   4592 
   4593         @Override
   4594         protected boolean allowFilterResult(
   4595                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
   4596             ServiceInfo filterSi = filter.service.info;
   4597             for (int i=dest.size()-1; i>=0; i--) {
   4598                 ServiceInfo destAi = dest.get(i).serviceInfo;
   4599                 if (destAi.name == filterSi.name
   4600                         && destAi.packageName == filterSi.packageName) {
   4601                     return false;
   4602                 }
   4603             }
   4604             return true;
   4605         }
   4606 
   4607         @Override
   4608         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter) {
   4609             PackageParser.Package p = filter.service.owner;
   4610             if (p != null) {
   4611                 PackageSetting ps = (PackageSetting)p.mExtras;
   4612                 if (ps != null) {
   4613                     // System apps are never considered stopped for purposes of
   4614                     // filtering, because there may be no way for the user to
   4615                     // actually re-launch them.
   4616                     return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0;
   4617                 }
   4618             }
   4619             return false;
   4620         }
   4621 
   4622         @Override
   4623         protected String packageForFilter(PackageParser.ServiceIntentInfo info) {
   4624             return info.service.owner.packageName;
   4625         }
   4626 
   4627         @Override
   4628         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
   4629                 int match) {
   4630             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
   4631             if (!mSettings.isEnabledLPr(info.service.info, mFlags)) {
   4632                 return null;
   4633             }
   4634             final PackageParser.Service service = info.service;
   4635             if (mSafeMode && (service.info.applicationInfo.flags
   4636                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   4637                 return null;
   4638             }
   4639             final ResolveInfo res = new ResolveInfo();
   4640             res.serviceInfo = PackageParser.generateServiceInfo(service,
   4641                     mFlags);
   4642             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   4643                 res.filter = filter;
   4644             }
   4645             res.priority = info.getPriority();
   4646             res.preferredOrder = service.owner.mPreferredOrder;
   4647             //System.out.println("Result: " + res.activityInfo.className +
   4648             //                   " = " + res.priority);
   4649             res.match = match;
   4650             res.isDefault = info.hasDefault;
   4651             res.labelRes = info.labelRes;
   4652             res.nonLocalizedLabel = info.nonLocalizedLabel;
   4653             res.icon = info.icon;
   4654             res.system = isSystemApp(res.serviceInfo.applicationInfo);
   4655             return res;
   4656         }
   4657 
   4658         @Override
   4659         protected void sortResults(List<ResolveInfo> results) {
   4660             Collections.sort(results, mResolvePrioritySorter);
   4661         }
   4662 
   4663         @Override
   4664         protected void dumpFilter(PrintWriter out, String prefix,
   4665                 PackageParser.ServiceIntentInfo filter) {
   4666             out.print(prefix); out.print(
   4667                     Integer.toHexString(System.identityHashCode(filter.service)));
   4668                     out.print(' ');
   4669                     out.print(filter.service.getComponentShortName());
   4670                     out.print(" filter ");
   4671                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   4672         }
   4673 
   4674 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   4675 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   4676 //            final List<ResolveInfo> retList = Lists.newArrayList();
   4677 //            while (i.hasNext()) {
   4678 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
   4679 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
   4680 //                    retList.add(resolveInfo);
   4681 //                }
   4682 //            }
   4683 //            return retList;
   4684 //        }
   4685 
   4686         // Keys are String (activity class name), values are Activity.
   4687         private final HashMap<ComponentName, PackageParser.Service> mServices
   4688                 = new HashMap<ComponentName, PackageParser.Service>();
   4689         private int mFlags;
   4690     };
   4691 
   4692     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
   4693             new Comparator<ResolveInfo>() {
   4694         public int compare(ResolveInfo r1, ResolveInfo r2) {
   4695             int v1 = r1.priority;
   4696             int v2 = r2.priority;
   4697             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
   4698             if (v1 != v2) {
   4699                 return (v1 > v2) ? -1 : 1;
   4700             }
   4701             v1 = r1.preferredOrder;
   4702             v2 = r2.preferredOrder;
   4703             if (v1 != v2) {
   4704                 return (v1 > v2) ? -1 : 1;
   4705             }
   4706             if (r1.isDefault != r2.isDefault) {
   4707                 return r1.isDefault ? -1 : 1;
   4708             }
   4709             v1 = r1.match;
   4710             v2 = r2.match;
   4711             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
   4712             if (v1 != v2) {
   4713                 return (v1 > v2) ? -1 : 1;
   4714             }
   4715             if (r1.system != r2.system) {
   4716                 return r1.system ? -1 : 1;
   4717             }
   4718             return 0;
   4719         }
   4720     };
   4721 
   4722     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
   4723             new Comparator<ProviderInfo>() {
   4724         public int compare(ProviderInfo p1, ProviderInfo p2) {
   4725             final int v1 = p1.initOrder;
   4726             final int v2 = p2.initOrder;
   4727             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
   4728         }
   4729     };
   4730 
   4731     static final void sendPackageBroadcast(String action, String pkg,
   4732             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver) {
   4733         IActivityManager am = ActivityManagerNative.getDefault();
   4734         if (am != null) {
   4735             try {
   4736                 final Intent intent = new Intent(action,
   4737                         pkg != null ? Uri.fromParts("package", pkg, null) : null);
   4738                 if (extras != null) {
   4739                     intent.putExtras(extras);
   4740                 }
   4741                 if (targetPkg != null) {
   4742                     intent.setPackage(targetPkg);
   4743                 }
   4744                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
   4745                 am.broadcastIntent(null, intent, null, finishedReceiver,
   4746                         0, null, null, null, finishedReceiver != null, false);
   4747             } catch (RemoteException ex) {
   4748             }
   4749         }
   4750     }
   4751 
   4752     /**
   4753      * Check if the external storage media is available. This is true if there
   4754      * is a mounted external storage medium or if the external storage is
   4755      * emulated.
   4756      */
   4757     private boolean isExternalMediaAvailable() {
   4758         return mMediaMounted || Environment.isExternalStorageEmulated();
   4759     }
   4760 
   4761     public String nextPackageToClean(String lastPackage) {
   4762         // writer
   4763         synchronized (mPackages) {
   4764             if (!isExternalMediaAvailable()) {
   4765                 // If the external storage is no longer mounted at this point,
   4766                 // the caller may not have been able to delete all of this
   4767                 // packages files and can not delete any more.  Bail.
   4768                 return null;
   4769             }
   4770             if (lastPackage != null) {
   4771                 mSettings.mPackagesToBeCleaned.remove(lastPackage);
   4772             }
   4773             return mSettings.mPackagesToBeCleaned.size() > 0
   4774                     ? mSettings.mPackagesToBeCleaned.get(0) : null;
   4775         }
   4776     }
   4777 
   4778     void schedulePackageCleaning(String packageName) {
   4779         mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE, packageName));
   4780     }
   4781 
   4782     void startCleaningPackages() {
   4783         // reader
   4784         synchronized (mPackages) {
   4785             if (!isExternalMediaAvailable()) {
   4786                 return;
   4787             }
   4788             if (mSettings.mPackagesToBeCleaned.size() <= 0) {
   4789                 return;
   4790             }
   4791         }
   4792         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
   4793         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
   4794         IActivityManager am = ActivityManagerNative.getDefault();
   4795         if (am != null) {
   4796             try {
   4797                 am.startService(null, intent, null);
   4798             } catch (RemoteException e) {
   4799             }
   4800         }
   4801     }
   4802 
   4803     private final class AppDirObserver extends FileObserver {
   4804         public AppDirObserver(String path, int mask, boolean isrom) {
   4805             super(path, mask);
   4806             mRootDir = path;
   4807             mIsRom = isrom;
   4808         }
   4809 
   4810         public void onEvent(int event, String path) {
   4811             String removedPackage = null;
   4812             int removedUid = -1;
   4813             String addedPackage = null;
   4814             int addedUid = -1;
   4815 
   4816             // TODO post a message to the handler to obtain serial ordering
   4817             synchronized (mInstallLock) {
   4818                 String fullPathStr = null;
   4819                 File fullPath = null;
   4820                 if (path != null) {
   4821                     fullPath = new File(mRootDir, path);
   4822                     fullPathStr = fullPath.getPath();
   4823                 }
   4824 
   4825                 if (DEBUG_APP_DIR_OBSERVER)
   4826                     Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event));
   4827 
   4828                 if (!isPackageFilename(path)) {
   4829                     if (DEBUG_APP_DIR_OBSERVER)
   4830                         Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr);
   4831                     return;
   4832                 }
   4833 
   4834                 // Ignore packages that are being installed or
   4835                 // have just been installed.
   4836                 if (ignoreCodePath(fullPathStr)) {
   4837                     return;
   4838                 }
   4839                 PackageParser.Package p = null;
   4840                 // reader
   4841                 synchronized (mPackages) {
   4842                     p = mAppDirs.get(fullPathStr);
   4843                 }
   4844                 if ((event&REMOVE_EVENTS) != 0) {
   4845                     if (p != null) {
   4846                         removePackageLI(p, true);
   4847                         removedPackage = p.applicationInfo.packageName;
   4848                         removedUid = p.applicationInfo.uid;
   4849                     }
   4850                 }
   4851 
   4852                 if ((event&ADD_EVENTS) != 0) {
   4853                     if (p == null) {
   4854                         p = scanPackageLI(fullPath,
   4855                                 (mIsRom ? PackageParser.PARSE_IS_SYSTEM
   4856                                         | PackageParser.PARSE_IS_SYSTEM_DIR: 0) |
   4857                                 PackageParser.PARSE_CHATTY |
   4858                                 PackageParser.PARSE_MUST_BE_APK,
   4859                                 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
   4860                                 System.currentTimeMillis());
   4861                         if (p != null) {
   4862                             /*
   4863                              * TODO this seems dangerous as the package may have
   4864                              * changed since we last acquired the mPackages
   4865                              * lock.
   4866                              */
   4867                             // writer
   4868                             synchronized (mPackages) {
   4869                                 updatePermissionsLPw(p.packageName, p,
   4870                                         p.permissions.size() > 0, false, false);
   4871                             }
   4872                             addedPackage = p.applicationInfo.packageName;
   4873                             addedUid = p.applicationInfo.uid;
   4874                         }
   4875                     }
   4876                 }
   4877 
   4878                 // reader
   4879                 synchronized (mPackages) {
   4880                     mSettings.writeLPr();
   4881                 }
   4882             }
   4883 
   4884             if (removedPackage != null) {
   4885                 Bundle extras = new Bundle(1);
   4886                 extras.putInt(Intent.EXTRA_UID, removedUid);
   4887                 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
   4888                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
   4889                         extras, null, null);
   4890             }
   4891             if (addedPackage != null) {
   4892                 Bundle extras = new Bundle(1);
   4893                 extras.putInt(Intent.EXTRA_UID, addedUid);
   4894                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
   4895                         extras, null, null);
   4896             }
   4897         }
   4898 
   4899         private final String mRootDir;
   4900         private final boolean mIsRom;
   4901     }
   4902 
   4903     /* Called when a downloaded package installation has been confirmed by the user */
   4904     public void installPackage(
   4905             final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
   4906         installPackage(packageURI, observer, flags, null);
   4907     }
   4908 
   4909     /* Called when a downloaded package installation has been confirmed by the user */
   4910     public void installPackage(
   4911             final Uri packageURI, final IPackageInstallObserver observer, final int flags,
   4912             final String installerPackageName) {
   4913         installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
   4914                 null);
   4915     }
   4916 
   4917     @Override
   4918     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
   4919             int flags, String installerPackageName, Uri verificationURI,
   4920             ManifestDigest manifestDigest) {
   4921         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
   4922 
   4923         final int uid = Binder.getCallingUid();
   4924 
   4925         final int filteredFlags;
   4926 
   4927         if (uid == Process.SHELL_UID || uid == 0) {
   4928             if (DEBUG_INSTALL) {
   4929                 Slog.v(TAG, "Install from ADB");
   4930             }
   4931             filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
   4932         } else {
   4933             filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
   4934         }
   4935 
   4936         final Message msg = mHandler.obtainMessage(INIT_COPY);
   4937         msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
   4938                 verificationURI, manifestDigest);
   4939         mHandler.sendMessage(msg);
   4940     }
   4941 
   4942     @Override
   4943     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
   4944         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
   4945         final PackageVerificationResponse response = new PackageVerificationResponse(
   4946                 verificationCode, Binder.getCallingUid());
   4947         msg.arg1 = id;
   4948         msg.obj = response;
   4949         mHandler.sendMessage(msg);
   4950     }
   4951 
   4952     private ComponentName matchComponentForVerifier(String packageName,
   4953             List<ResolveInfo> receivers) {
   4954         ActivityInfo targetReceiver = null;
   4955 
   4956         final int NR = receivers.size();
   4957         for (int i = 0; i < NR; i++) {
   4958             final ResolveInfo info = receivers.get(i);
   4959             if (info.activityInfo == null) {
   4960                 continue;
   4961             }
   4962 
   4963             if (packageName.equals(info.activityInfo.packageName)) {
   4964                 targetReceiver = info.activityInfo;
   4965                 break;
   4966             }
   4967         }
   4968 
   4969         if (targetReceiver == null) {
   4970             return null;
   4971         }
   4972 
   4973         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
   4974     }
   4975 
   4976     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
   4977             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
   4978         if (pkgInfo.verifiers.length == 0) {
   4979             return null;
   4980         }
   4981 
   4982         final int N = pkgInfo.verifiers.length;
   4983         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
   4984         for (int i = 0; i < N; i++) {
   4985             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
   4986 
   4987             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
   4988                     receivers);
   4989             if (comp == null) {
   4990                 continue;
   4991             }
   4992 
   4993             final int verifierUid = getUidForVerifier(verifierInfo);
   4994             if (verifierUid == -1) {
   4995                 continue;
   4996             }
   4997 
   4998             if (DEBUG_VERIFY) {
   4999                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
   5000                         + " with the correct signature");
   5001             }
   5002             sufficientVerifiers.add(comp);
   5003             verificationState.addSufficientVerifier(verifierUid);
   5004         }
   5005 
   5006         return sufficientVerifiers;
   5007     }
   5008 
   5009     private int getUidForVerifier(VerifierInfo verifierInfo) {
   5010         synchronized (mPackages) {
   5011             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
   5012             if (pkg == null) {
   5013                 return -1;
   5014             } else if (pkg.mSignatures.length != 1) {
   5015                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
   5016                         + " has more than one signature; ignoring");
   5017                 return -1;
   5018             }
   5019 
   5020             /*
   5021              * If the public key of the package's signature does not match
   5022              * our expected public key, then this is a different package and
   5023              * we should skip.
   5024              */
   5025 
   5026             final byte[] expectedPublicKey;
   5027             try {
   5028                 final Signature verifierSig = pkg.mSignatures[0];
   5029                 final PublicKey publicKey = verifierSig.getPublicKey();
   5030                 expectedPublicKey = publicKey.getEncoded();
   5031             } catch (CertificateException e) {
   5032                 return -1;
   5033             }
   5034 
   5035             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
   5036 
   5037             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
   5038                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
   5039                         + " does not have the expected public key; ignoring");
   5040                 return -1;
   5041             }
   5042 
   5043             return pkg.applicationInfo.uid;
   5044         }
   5045     }
   5046 
   5047     public void finishPackageInstall(int token) {
   5048         enforceSystemOrRoot("Only the system is allowed to finish installs");
   5049 
   5050         if (DEBUG_INSTALL) {
   5051             Slog.v(TAG, "BM finishing package install for " + token);
   5052         }
   5053 
   5054         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   5055         mHandler.sendMessage(msg);
   5056     }
   5057 
   5058     /**
   5059      * Get the verification agent timeout.
   5060      *
   5061      * @return verification timeout in milliseconds
   5062      */
   5063     private long getVerificationTimeout() {
   5064         return android.provider.Settings.Secure.getLong(mContext.getContentResolver(),
   5065                 android.provider.Settings.Secure.PACKAGE_VERIFIER_TIMEOUT,
   5066                 DEFAULT_VERIFICATION_TIMEOUT);
   5067     }
   5068 
   5069     /**
   5070      * Check whether or not package verification has been enabled.
   5071      *
   5072      * @return true if verification should be performed
   5073      */
   5074     private boolean isVerificationEnabled() {
   5075         return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
   5076                 android.provider.Settings.Secure.PACKAGE_VERIFIER_ENABLE,
   5077                 DEFAULT_VERIFY_ENABLE ? 1 : 0) == 1 ? true : false;
   5078     }
   5079 
   5080     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
   5081         final int uid = Binder.getCallingUid();
   5082         // writer
   5083         synchronized (mPackages) {
   5084             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
   5085             if (targetPackageSetting == null) {
   5086                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
   5087             }
   5088 
   5089             PackageSetting installerPackageSetting;
   5090             if (installerPackageName != null) {
   5091                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
   5092                 if (installerPackageSetting == null) {
   5093                     throw new IllegalArgumentException("Unknown installer package: "
   5094                             + installerPackageName);
   5095                 }
   5096             } else {
   5097                 installerPackageSetting = null;
   5098             }
   5099 
   5100             Signature[] callerSignature;
   5101             Object obj = mSettings.getUserIdLPr(uid);
   5102             if (obj != null) {
   5103                 if (obj instanceof SharedUserSetting) {
   5104                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
   5105                 } else if (obj instanceof PackageSetting) {
   5106                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
   5107                 } else {
   5108                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
   5109                 }
   5110             } else {
   5111                 throw new SecurityException("Unknown calling uid " + uid);
   5112             }
   5113 
   5114             // Verify: can't set installerPackageName to a package that is
   5115             // not signed with the same cert as the caller.
   5116             if (installerPackageSetting != null) {
   5117                 if (compareSignatures(callerSignature,
   5118                         installerPackageSetting.signatures.mSignatures)
   5119                         != PackageManager.SIGNATURE_MATCH) {
   5120                     throw new SecurityException(
   5121                             "Caller does not have same cert as new installer package "
   5122                             + installerPackageName);
   5123                 }
   5124             }
   5125 
   5126             // Verify: if target already has an installer package, it must
   5127             // be signed with the same cert as the caller.
   5128             if (targetPackageSetting.installerPackageName != null) {
   5129                 PackageSetting setting = mSettings.mPackages.get(
   5130                         targetPackageSetting.installerPackageName);
   5131                 // If the currently set package isn't valid, then it's always
   5132                 // okay to change it.
   5133                 if (setting != null) {
   5134                     if (compareSignatures(callerSignature,
   5135                             setting.signatures.mSignatures)
   5136                             != PackageManager.SIGNATURE_MATCH) {
   5137                         throw new SecurityException(
   5138                                 "Caller does not have same cert as old installer package "
   5139                                 + targetPackageSetting.installerPackageName);
   5140                     }
   5141                 }
   5142             }
   5143 
   5144             // Okay!
   5145             targetPackageSetting.installerPackageName = installerPackageName;
   5146             scheduleWriteSettingsLocked();
   5147         }
   5148     }
   5149 
   5150     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
   5151         // Queue up an async operation since the package installation may take a little while.
   5152         mHandler.post(new Runnable() {
   5153             public void run() {
   5154                 mHandler.removeCallbacks(this);
   5155                  // Result object to be returned
   5156                 PackageInstalledInfo res = new PackageInstalledInfo();
   5157                 res.returnCode = currentStatus;
   5158                 res.uid = -1;
   5159                 res.pkg = null;
   5160                 res.removedInfo = new PackageRemovedInfo();
   5161                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   5162                     args.doPreInstall(res.returnCode);
   5163                     synchronized (mInstallLock) {
   5164                         installPackageLI(args, true, res);
   5165                     }
   5166                     args.doPostInstall(res.returnCode);
   5167                 }
   5168 
   5169                 // A restore should be performed at this point if (a) the install
   5170                 // succeeded, (b) the operation is not an update, and (c) the new
   5171                 // package has a backupAgent defined.
   5172                 final boolean update = res.removedInfo.removedPackage != null;
   5173                 boolean doRestore = (!update
   5174                         && res.pkg != null
   5175                         && res.pkg.applicationInfo.backupAgentName != null);
   5176 
   5177                 // Set up the post-install work request bookkeeping.  This will be used
   5178                 // and cleaned up by the post-install event handling regardless of whether
   5179                 // there's a restore pass performed.  Token values are >= 1.
   5180                 int token;
   5181                 if (mNextInstallToken < 0) mNextInstallToken = 1;
   5182                 token = mNextInstallToken++;
   5183 
   5184                 PostInstallData data = new PostInstallData(args, res);
   5185                 mRunningInstalls.put(token, data);
   5186                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
   5187 
   5188                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
   5189                     // Pass responsibility to the Backup Manager.  It will perform a
   5190                     // restore if appropriate, then pass responsibility back to the
   5191                     // Package Manager to run the post-install observer callbacks
   5192                     // and broadcasts.
   5193                     IBackupManager bm = IBackupManager.Stub.asInterface(
   5194                             ServiceManager.getService(Context.BACKUP_SERVICE));
   5195                     if (bm != null) {
   5196                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
   5197                                 + " to BM for possible restore");
   5198                         try {
   5199                             bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
   5200                         } catch (RemoteException e) {
   5201                             // can't happen; the backup manager is local
   5202                         } catch (Exception e) {
   5203                             Slog.e(TAG, "Exception trying to enqueue restore", e);
   5204                             doRestore = false;
   5205                         }
   5206                     } else {
   5207                         Slog.e(TAG, "Backup Manager not found!");
   5208                         doRestore = false;
   5209                     }
   5210                 }
   5211 
   5212                 if (!doRestore) {
   5213                     // No restore possible, or the Backup Manager was mysteriously not
   5214                     // available -- just fire the post-install work request directly.
   5215                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
   5216                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   5217                     mHandler.sendMessage(msg);
   5218                 }
   5219             }
   5220         });
   5221     }
   5222 
   5223     private abstract class HandlerParams {
   5224         private static final int MAX_RETRIES = 4;
   5225 
   5226         /**
   5227          * Number of times startCopy() has been attempted and had a non-fatal
   5228          * error.
   5229          */
   5230         private int mRetries = 0;
   5231 
   5232         final boolean startCopy() {
   5233             boolean res;
   5234             try {
   5235                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy");
   5236 
   5237                 if (++mRetries > MAX_RETRIES) {
   5238                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
   5239                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
   5240                     handleServiceError();
   5241                     return false;
   5242                 } else {
   5243                     handleStartCopy();
   5244                     res = true;
   5245                 }
   5246             } catch (RemoteException e) {
   5247                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
   5248                 mHandler.sendEmptyMessage(MCS_RECONNECT);
   5249                 res = false;
   5250             }
   5251             handleReturnCode();
   5252             return res;
   5253         }
   5254 
   5255         final void serviceError() {
   5256             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
   5257             handleServiceError();
   5258             handleReturnCode();
   5259         }
   5260 
   5261         abstract void handleStartCopy() throws RemoteException;
   5262         abstract void handleServiceError();
   5263         abstract void handleReturnCode();
   5264     }
   5265 
   5266     class MeasureParams extends HandlerParams {
   5267         private final PackageStats mStats;
   5268         private boolean mSuccess;
   5269 
   5270         private final IPackageStatsObserver mObserver;
   5271 
   5272         public MeasureParams(PackageStats stats, boolean success, IPackageStatsObserver observer) {
   5273             mObserver = observer;
   5274             mStats = stats;
   5275             mSuccess = success;
   5276         }
   5277 
   5278         @Override
   5279         void handleStartCopy() throws RemoteException {
   5280             final boolean mounted;
   5281 
   5282             if (Environment.isExternalStorageEmulated()) {
   5283                 mounted = true;
   5284             } else {
   5285                 final String status = Environment.getExternalStorageState();
   5286 
   5287                 mounted = status.equals(Environment.MEDIA_MOUNTED)
   5288                         || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
   5289             }
   5290 
   5291             if (mounted) {
   5292                 final File externalCacheDir = Environment
   5293                         .getExternalStorageAppCacheDirectory(mStats.packageName);
   5294                 final long externalCacheSize = mContainerService
   5295                         .calculateDirectorySize(externalCacheDir.getPath());
   5296                 mStats.externalCacheSize = externalCacheSize;
   5297 
   5298                 final File externalDataDir = Environment
   5299                         .getExternalStorageAppDataDirectory(mStats.packageName);
   5300                 long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
   5301                         .getPath());
   5302 
   5303                 if (externalCacheDir.getParentFile().equals(externalDataDir)) {
   5304                     externalDataSize -= externalCacheSize;
   5305                 }
   5306                 mStats.externalDataSize = externalDataSize;
   5307 
   5308                 final File externalMediaDir = Environment
   5309                         .getExternalStorageAppMediaDirectory(mStats.packageName);
   5310                 mStats.externalMediaSize = mContainerService
   5311                         .calculateDirectorySize(externalMediaDir.getPath());
   5312 
   5313                 final File externalObbDir = Environment
   5314                         .getExternalStorageAppObbDirectory(mStats.packageName);
   5315                 mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir
   5316                         .getPath());
   5317             }
   5318         }
   5319 
   5320         @Override
   5321         void handleReturnCode() {
   5322             if (mObserver != null) {
   5323                 try {
   5324                     mObserver.onGetStatsCompleted(mStats, mSuccess);
   5325                 } catch (RemoteException e) {
   5326                     Slog.i(TAG, "Observer no longer exists.");
   5327                 }
   5328             }
   5329         }
   5330 
   5331         @Override
   5332         void handleServiceError() {
   5333             Slog.e(TAG, "Could not measure application " + mStats.packageName
   5334                             + " external storage");
   5335         }
   5336     }
   5337 
   5338     class InstallParams extends HandlerParams {
   5339         final IPackageInstallObserver observer;
   5340         int flags;
   5341         final Uri packageURI;
   5342         final String installerPackageName;
   5343         final Uri verificationURI;
   5344         final ManifestDigest manifestDigest;
   5345         private InstallArgs mArgs;
   5346         private int mRet;
   5347 
   5348         InstallParams(Uri packageURI,
   5349                 IPackageInstallObserver observer, int flags,
   5350                 String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest) {
   5351             this.packageURI = packageURI;
   5352             this.flags = flags;
   5353             this.observer = observer;
   5354             this.installerPackageName = installerPackageName;
   5355             this.verificationURI = verificationURI;
   5356             this.manifestDigest = manifestDigest;
   5357         }
   5358 
   5359         private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
   5360             String packageName = pkgLite.packageName;
   5361             int installLocation = pkgLite.installLocation;
   5362             boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
   5363             // reader
   5364             synchronized (mPackages) {
   5365                 PackageParser.Package pkg = mPackages.get(packageName);
   5366                 if (pkg != null) {
   5367                     if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   5368                         // Check for updated system application.
   5369                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   5370                             if (onSd) {
   5371                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
   5372                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
   5373                             }
   5374                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   5375                         } else {
   5376                             if (onSd) {
   5377                                 // Install flag overrides everything.
   5378                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   5379                             }
   5380                             // If current upgrade specifies particular preference
   5381                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
   5382                                 // Application explicitly specified internal.
   5383                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   5384                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
   5385                                 // App explictly prefers external. Let policy decide
   5386                             } else {
   5387                                 // Prefer previous location
   5388                                 if (isExternal(pkg)) {
   5389                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   5390                                 }
   5391                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   5392                             }
   5393                         }
   5394                     } else {
   5395                         // Invalid install. Return error code
   5396                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
   5397                     }
   5398                 }
   5399             }
   5400             // All the special cases have been taken care of.
   5401             // Return result based on recommended install location.
   5402             if (onSd) {
   5403                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   5404             }
   5405             return pkgLite.recommendedInstallLocation;
   5406         }
   5407 
   5408         /*
   5409          * Invoke remote method to get package information and install
   5410          * location values. Override install location based on default
   5411          * policy if needed and then create install arguments based
   5412          * on the install location.
   5413          */
   5414         public void handleStartCopy() throws RemoteException {
   5415             int ret = PackageManager.INSTALL_SUCCEEDED;
   5416             final boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   5417             final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
   5418             final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
   5419             PackageInfoLite pkgLite = null;
   5420 
   5421             if (onInt && onSd) {
   5422                 // Check if both bits are set.
   5423                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
   5424                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   5425             } else if (fwdLocked && onSd) {
   5426                 // Check for forward locked apps
   5427                 Slog.w(TAG, "Cannot install fwd locked apps on sdcard");
   5428                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   5429             } else {
   5430                 final long lowThreshold;
   5431 
   5432                 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
   5433                         .getService(DeviceStorageMonitorService.SERVICE);
   5434                 if (dsm == null) {
   5435                     Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
   5436                     lowThreshold = 0L;
   5437                 } else {
   5438                     lowThreshold = dsm.getMemoryLowThreshold();
   5439                 }
   5440 
   5441                 // Remote call to find out default install location
   5442                 try {
   5443                     mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   5444                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5445                     pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags,
   5446                             lowThreshold);
   5447                 } finally {
   5448                     mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5449                 }
   5450 
   5451                 int loc = pkgLite.recommendedInstallLocation;
   5452                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
   5453                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   5454                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
   5455                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   5456                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
   5457                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5458                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
   5459                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
   5460                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
   5461                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
   5462                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
   5463                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
   5464                 } else {
   5465                     // Override with defaults if needed.
   5466                     loc = installLocationPolicy(pkgLite, flags);
   5467                     if (!onSd && !onInt) {
   5468                         // Override install location with flags
   5469                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
   5470                             // Set the flag to install on external media.
   5471                             flags |= PackageManager.INSTALL_EXTERNAL;
   5472                             flags &= ~PackageManager.INSTALL_INTERNAL;
   5473                         } else {
   5474                             // Make sure the flag for installing on external
   5475                             // media is unset
   5476                             flags |= PackageManager.INSTALL_INTERNAL;
   5477                             flags &= ~PackageManager.INSTALL_EXTERNAL;
   5478                         }
   5479                     }
   5480                 }
   5481             }
   5482 
   5483             final InstallArgs args = createInstallArgs(this);
   5484             mArgs = args;
   5485 
   5486             if (ret == PackageManager.INSTALL_SUCCEEDED) {
   5487                 /*
   5488                  * Determine if we have any installed package verifiers. If we
   5489                  * do, then we'll defer to them to verify the packages.
   5490                  */
   5491                 final int requiredUid = mRequiredVerifierPackage == null ? -1
   5492                         : getPackageUid(mRequiredVerifierPackage);
   5493                 if (requiredUid != -1 && isVerificationEnabled()) {
   5494                     final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
   5495                     verification.setDataAndType(packageURI, PACKAGE_MIME_TYPE);
   5496                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5497 
   5498                     final List<ResolveInfo> receivers = queryIntentReceivers(verification, null,
   5499                             PackageManager.GET_DISABLED_COMPONENTS);
   5500 
   5501                     if (DEBUG_VERIFY) {
   5502                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
   5503                                 + verification.toString() + " with " + pkgLite.verifiers.length
   5504                                 + " optional verifiers");
   5505                     }
   5506 
   5507                     final int verificationId = mPendingVerificationToken++;
   5508 
   5509                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
   5510 
   5511                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
   5512                             installerPackageName);
   5513 
   5514                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
   5515 
   5516                     if (verificationURI != null) {
   5517                         verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
   5518                                 verificationURI);
   5519                     }
   5520 
   5521                     final PackageVerificationState verificationState = new PackageVerificationState(
   5522                             requiredUid, args);
   5523 
   5524                     mPendingVerification.append(verificationId, verificationState);
   5525 
   5526                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
   5527                             receivers, verificationState);
   5528 
   5529                     /*
   5530                      * If any sufficient verifiers were listed in the package
   5531                      * manifest, attempt to ask them.
   5532                      */
   5533                     if (sufficientVerifiers != null) {
   5534                         final int N = sufficientVerifiers.size();
   5535                         if (N == 0) {
   5536                             Slog.i(TAG, "Additional verifiers required, but none installed.");
   5537                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   5538                         } else {
   5539                             for (int i = 0; i < N; i++) {
   5540                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
   5541 
   5542                                 final Intent sufficientIntent = new Intent(verification);
   5543                                 sufficientIntent.setComponent(verifierComponent);
   5544 
   5545                                 mContext.sendBroadcast(sufficientIntent);
   5546                             }
   5547                         }
   5548                     }
   5549 
   5550                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
   5551                             mRequiredVerifierPackage, receivers);
   5552                     if (ret == PackageManager.INSTALL_SUCCEEDED
   5553                             && mRequiredVerifierPackage != null) {
   5554                         /*
   5555                          * Send the intent to the required verification agent,
   5556                          * but only start the verification timeout after the
   5557                          * target BroadcastReceivers have run.
   5558                          */
   5559                         verification.setComponent(requiredVerifierComponent);
   5560                         mContext.sendOrderedBroadcast(verification,
   5561                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   5562                                 new BroadcastReceiver() {
   5563                                     @Override
   5564                                     public void onReceive(Context context, Intent intent) {
   5565                                         final Message msg = mHandler
   5566                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
   5567                                         msg.arg1 = verificationId;
   5568                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
   5569                                     }
   5570                                 }, null, 0, null, null);
   5571 
   5572                         /*
   5573                          * We don't want the copy to proceed until verification
   5574                          * succeeds, so null out this field.
   5575                          */
   5576                         mArgs = null;
   5577                     }
   5578                 } else {
   5579                     /*
   5580                      * No package verification is enabled, so immediately start
   5581                      * the remote call to initiate copy using temporary file.
   5582                      */
   5583                     ret = args.copyApk(mContainerService, true);
   5584                 }
   5585             }
   5586 
   5587             mRet = ret;
   5588         }
   5589 
   5590         @Override
   5591         void handleReturnCode() {
   5592             // If mArgs is null, then MCS couldn't be reached. When it
   5593             // reconnects, it will try again to install. At that point, this
   5594             // will succeed.
   5595             if (mArgs != null) {
   5596                 processPendingInstall(mArgs, mRet);
   5597             }
   5598         }
   5599 
   5600         @Override
   5601         void handleServiceError() {
   5602             mArgs = createInstallArgs(this);
   5603             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   5604         }
   5605     }
   5606 
   5607     /*
   5608      * Utility class used in movePackage api.
   5609      * srcArgs and targetArgs are not set for invalid flags and make
   5610      * sure to do null checks when invoking methods on them.
   5611      * We probably want to return ErrorPrams for both failed installs
   5612      * and moves.
   5613      */
   5614     class MoveParams extends HandlerParams {
   5615         final IPackageMoveObserver observer;
   5616         final int flags;
   5617         final String packageName;
   5618         final InstallArgs srcArgs;
   5619         final InstallArgs targetArgs;
   5620         int mRet;
   5621 
   5622         MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
   5623                 String packageName, String dataDir) {
   5624             this.srcArgs = srcArgs;
   5625             this.observer = observer;
   5626             this.flags = flags;
   5627             this.packageName = packageName;
   5628             if (srcArgs != null) {
   5629                 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
   5630                 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
   5631             } else {
   5632                 targetArgs = null;
   5633             }
   5634         }
   5635 
   5636         public void handleStartCopy() throws RemoteException {
   5637             mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5638             // Check for storage space on target medium
   5639             if (!targetArgs.checkFreeStorage(mContainerService)) {
   5640                 Log.w(TAG, "Insufficient storage to install");
   5641                 return;
   5642             }
   5643             // Create the file args now.
   5644             mRet = targetArgs.copyApk(mContainerService, false);
   5645             targetArgs.doPreInstall(mRet);
   5646             if (DEBUG_SD_INSTALL) {
   5647                 StringBuilder builder = new StringBuilder();
   5648                 if (srcArgs != null) {
   5649                     builder.append("src: ");
   5650                     builder.append(srcArgs.getCodePath());
   5651                 }
   5652                 if (targetArgs != null) {
   5653                     builder.append(" target : ");
   5654                     builder.append(targetArgs.getCodePath());
   5655                 }
   5656                 Log.i(TAG, builder.toString());
   5657             }
   5658         }
   5659 
   5660         @Override
   5661         void handleReturnCode() {
   5662             targetArgs.doPostInstall(mRet);
   5663             int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
   5664             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
   5665                 currentStatus = PackageManager.MOVE_SUCCEEDED;
   5666             } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
   5667                 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
   5668             }
   5669             processPendingMove(this, currentStatus);
   5670         }
   5671 
   5672         @Override
   5673         void handleServiceError() {
   5674             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   5675         }
   5676     }
   5677 
   5678     private InstallArgs createInstallArgs(InstallParams params) {
   5679         if (installOnSd(params.flags)) {
   5680             return new SdInstallArgs(params);
   5681         } else {
   5682             return new FileInstallArgs(params);
   5683         }
   5684     }
   5685 
   5686     private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
   5687             String nativeLibraryPath) {
   5688         if (installOnSd(flags)) {
   5689             return new SdInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
   5690         } else {
   5691             return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
   5692         }
   5693     }
   5694 
   5695     // Used by package mover
   5696     private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
   5697         if (installOnSd(flags)) {
   5698             String cid = getNextCodePath(null, pkgName, "/" + SdInstallArgs.RES_FILE_NAME);
   5699             return new SdInstallArgs(packageURI, cid);
   5700         } else {
   5701             return new FileInstallArgs(packageURI, pkgName, dataDir);
   5702         }
   5703     }
   5704 
   5705     static abstract class InstallArgs {
   5706         final IPackageInstallObserver observer;
   5707         // Always refers to PackageManager flags only
   5708         final int flags;
   5709         final Uri packageURI;
   5710         final String installerPackageName;
   5711         final ManifestDigest manifestDigest;
   5712 
   5713         InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags,
   5714                 String installerPackageName, ManifestDigest manifestDigest) {
   5715             this.packageURI = packageURI;
   5716             this.flags = flags;
   5717             this.observer = observer;
   5718             this.installerPackageName = installerPackageName;
   5719             this.manifestDigest = manifestDigest;
   5720         }
   5721 
   5722         abstract void createCopyFile();
   5723         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
   5724         abstract int doPreInstall(int status);
   5725         abstract boolean doRename(int status, String pkgName, String oldCodePath);
   5726         abstract int doPostInstall(int status);
   5727         abstract String getCodePath();
   5728         abstract String getResourcePath();
   5729         abstract String getNativeLibraryPath();
   5730         // Need installer lock especially for dex file removal.
   5731         abstract void cleanUpResourcesLI();
   5732         abstract boolean doPostDeleteLI(boolean delete);
   5733         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
   5734     }
   5735 
   5736     class FileInstallArgs extends InstallArgs {
   5737         File installDir;
   5738         String codeFileName;
   5739         String resourceFileName;
   5740         String libraryPath;
   5741         boolean created = false;
   5742 
   5743         FileInstallArgs(InstallParams params) {
   5744             super(params.packageURI, params.observer, params.flags, params.installerPackageName,
   5745                     params.manifestDigest);
   5746         }
   5747 
   5748         FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
   5749             super(null, null, 0, null, null);
   5750             File codeFile = new File(fullCodePath);
   5751             installDir = codeFile.getParentFile();
   5752             codeFileName = fullCodePath;
   5753             resourceFileName = fullResourcePath;
   5754             libraryPath = nativeLibraryPath;
   5755         }
   5756 
   5757         FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
   5758             super(packageURI, null, 0, null, null);
   5759             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
   5760             String apkName = getNextCodePath(null, pkgName, ".apk");
   5761             codeFileName = new File(installDir, apkName + ".apk").getPath();
   5762             resourceFileName = getResourcePathFromCodePath();
   5763             libraryPath = new File(dataDir, LIB_DIR_NAME).getPath();
   5764         }
   5765 
   5766         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
   5767             final long lowThreshold;
   5768 
   5769             final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager
   5770                     .getService(DeviceStorageMonitorService.SERVICE);
   5771             if (dsm == null) {
   5772                 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed");
   5773                 lowThreshold = 0L;
   5774             } else {
   5775                 if (dsm.isMemoryLow()) {
   5776                     Log.w(TAG, "Memory is reported as being too low; aborting package install");
   5777                     return false;
   5778                 }
   5779 
   5780                 lowThreshold = dsm.getMemoryLowThreshold();
   5781             }
   5782 
   5783             try {
   5784                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   5785                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5786                 return imcs.checkInternalFreeStorage(packageURI, lowThreshold);
   5787             } finally {
   5788                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5789             }
   5790         }
   5791 
   5792         String getCodePath() {
   5793             return codeFileName;
   5794         }
   5795 
   5796         void createCopyFile() {
   5797             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
   5798             codeFileName = createTempPackageFile(installDir).getPath();
   5799             resourceFileName = getResourcePathFromCodePath();
   5800             created = true;
   5801         }
   5802 
   5803         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   5804             if (temp) {
   5805                 // Generate temp file name
   5806                 createCopyFile();
   5807             }
   5808             // Get a ParcelFileDescriptor to write to the output file
   5809             File codeFile = new File(codeFileName);
   5810             if (!created) {
   5811                 try {
   5812                     codeFile.createNewFile();
   5813                     // Set permissions
   5814                     if (!setPermissions()) {
   5815                         // Failed setting permissions.
   5816                         return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5817                     }
   5818                 } catch (IOException e) {
   5819                    Slog.w(TAG, "Failed to create file " + codeFile);
   5820                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5821                 }
   5822             }
   5823             ParcelFileDescriptor out = null;
   5824             try {
   5825                 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE);
   5826             } catch (FileNotFoundException e) {
   5827                 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName);
   5828                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5829             }
   5830             // Copy the resource now
   5831             int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5832             try {
   5833                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   5834                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5835                 ret = imcs.copyResource(packageURI, out);
   5836             } finally {
   5837                 try { if (out != null) out.close(); } catch (IOException e) {}
   5838                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5839             }
   5840 
   5841             return ret;
   5842         }
   5843 
   5844         int doPreInstall(int status) {
   5845             if (status != PackageManager.INSTALL_SUCCEEDED) {
   5846                 cleanUp();
   5847             }
   5848             return status;
   5849         }
   5850 
   5851         boolean doRename(int status, final String pkgName, String oldCodePath) {
   5852             if (status != PackageManager.INSTALL_SUCCEEDED) {
   5853                 cleanUp();
   5854                 return false;
   5855             } else {
   5856                 // Rename based on packageName
   5857                 File codeFile = new File(getCodePath());
   5858                 String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
   5859                 File desFile = new File(installDir, apkName + ".apk");
   5860                 if (!codeFile.renameTo(desFile)) {
   5861                     return false;
   5862                 }
   5863                 // Reset paths since the file has been renamed.
   5864                 codeFileName = desFile.getPath();
   5865                 resourceFileName = getResourcePathFromCodePath();
   5866                 // Set permissions
   5867                 if (!setPermissions()) {
   5868                     // Failed setting permissions.
   5869                     return false;
   5870                 }
   5871                 return true;
   5872             }
   5873         }
   5874 
   5875         int doPostInstall(int status) {
   5876             if (status != PackageManager.INSTALL_SUCCEEDED) {
   5877                 cleanUp();
   5878             }
   5879             return status;
   5880         }
   5881 
   5882         String getResourcePath() {
   5883             return resourceFileName;
   5884         }
   5885 
   5886         String getResourcePathFromCodePath() {
   5887             String codePath = getCodePath();
   5888             if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
   5889                 String apkNameOnly = getApkName(codePath);
   5890                 return mAppInstallDir.getPath() + "/" + apkNameOnly + ".zip";
   5891             } else {
   5892                 return codePath;
   5893             }
   5894         }
   5895 
   5896         @Override
   5897         String getNativeLibraryPath() {
   5898             return libraryPath;
   5899         }
   5900 
   5901         private boolean cleanUp() {
   5902             boolean ret = true;
   5903             String sourceDir = getCodePath();
   5904             String publicSourceDir = getResourcePath();
   5905             if (sourceDir != null) {
   5906                 File sourceFile = new File(sourceDir);
   5907                 if (!sourceFile.exists()) {
   5908                     Slog.w(TAG, "Package source " + sourceDir + " does not exist.");
   5909                     ret = false;
   5910                 }
   5911                 // Delete application's code and resources
   5912                 sourceFile.delete();
   5913             }
   5914             if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) {
   5915                 final File publicSourceFile = new File(publicSourceDir);
   5916                 if (!publicSourceFile.exists()) {
   5917                     Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist.");
   5918                 }
   5919                 if (publicSourceFile.exists()) {
   5920                     publicSourceFile.delete();
   5921                 }
   5922             }
   5923             return ret;
   5924         }
   5925 
   5926         void cleanUpResourcesLI() {
   5927             String sourceDir = getCodePath();
   5928             if (cleanUp()) {
   5929                 int retCode = mInstaller.rmdex(sourceDir);
   5930                 if (retCode < 0) {
   5931                     Slog.w(TAG, "Couldn't remove dex file for package: "
   5932                             +  " at location "
   5933                             + sourceDir + ", retcode=" + retCode);
   5934                     // we don't consider this to be a failure of the core package deletion
   5935                 }
   5936             }
   5937         }
   5938 
   5939         private boolean setPermissions() {
   5940             // TODO Do this in a more elegant way later on. for now just a hack
   5941             if (!isFwdLocked()) {
   5942                 final int filePermissions =
   5943                     FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
   5944                     |FileUtils.S_IROTH;
   5945                 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1);
   5946                 if (retCode != 0) {
   5947                     Slog.e(TAG, "Couldn't set new package file permissions for " +
   5948                             getCodePath()
   5949                             + ". The return code was: " + retCode);
   5950                     // TODO Define new internal error
   5951                     return false;
   5952                 }
   5953                 return true;
   5954             }
   5955             return true;
   5956         }
   5957 
   5958         boolean doPostDeleteLI(boolean delete) {
   5959             // XXX err, shouldn't we respect the delete flag?
   5960             cleanUpResourcesLI();
   5961             return true;
   5962         }
   5963 
   5964         private boolean isFwdLocked() {
   5965             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   5966         }
   5967     }
   5968 
   5969     /**
   5970      * Extract the MountService "container ID" from the full code path of an
   5971      * .apk.
   5972      */
   5973     static String cidFromCodePath(String fullCodePath) {
   5974         int eidx = fullCodePath.lastIndexOf("/");
   5975         String subStr1 = fullCodePath.substring(0, eidx);
   5976         int sidx = subStr1.lastIndexOf("/");
   5977         return subStr1.substring(sidx+1, eidx);
   5978     }
   5979 
   5980     class SdInstallArgs extends InstallArgs {
   5981         static final String RES_FILE_NAME = "pkg.apk";
   5982 
   5983         String cid;
   5984         String packagePath;
   5985         String libraryPath;
   5986 
   5987         SdInstallArgs(InstallParams params) {
   5988             super(params.packageURI, params.observer, params.flags, params.installerPackageName,
   5989                     params.manifestDigest);
   5990         }
   5991 
   5992         SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
   5993             super(null, null, PackageManager.INSTALL_EXTERNAL, null, null);
   5994             // Extract cid from fullCodePath
   5995             int eidx = fullCodePath.lastIndexOf("/");
   5996             String subStr1 = fullCodePath.substring(0, eidx);
   5997             int sidx = subStr1.lastIndexOf("/");
   5998             cid = subStr1.substring(sidx+1, eidx);
   5999             setCachePath(subStr1);
   6000         }
   6001 
   6002         SdInstallArgs(String cid) {
   6003             super(null, null, PackageManager.INSTALL_EXTERNAL, null, null);
   6004             this.cid = cid;
   6005             setCachePath(PackageHelper.getSdDir(cid));
   6006         }
   6007 
   6008         SdInstallArgs(Uri packageURI, String cid) {
   6009             super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null, null);
   6010             this.cid = cid;
   6011         }
   6012 
   6013         void createCopyFile() {
   6014             cid = getTempContainerId();
   6015         }
   6016 
   6017         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
   6018             try {
   6019                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   6020                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
   6021                 return imcs.checkExternalFreeStorage(packageURI);
   6022             } finally {
   6023                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   6024             }
   6025         }
   6026 
   6027         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   6028             if (temp) {
   6029                 createCopyFile();
   6030             } else {
   6031                 /*
   6032                  * Pre-emptively destroy the container since it's destroyed if
   6033                  * copying fails due to it existing anyway.
   6034                  */
   6035                 PackageHelper.destroySdDir(cid);
   6036             }
   6037 
   6038             final String newCachePath;
   6039             try {
   6040                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   6041                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
   6042                 newCachePath = imcs.copyResourceToContainer(packageURI, cid,
   6043                         getEncryptKey(), RES_FILE_NAME);
   6044             } finally {
   6045                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   6046             }
   6047 
   6048             if (newCachePath != null) {
   6049                 setCachePath(newCachePath);
   6050                 return PackageManager.INSTALL_SUCCEEDED;
   6051             } else {
   6052                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   6053             }
   6054         }
   6055 
   6056         @Override
   6057         String getCodePath() {
   6058             return packagePath;
   6059         }
   6060 
   6061         @Override
   6062         String getResourcePath() {
   6063             return packagePath;
   6064         }
   6065 
   6066         @Override
   6067         String getNativeLibraryPath() {
   6068             return libraryPath;
   6069         }
   6070 
   6071         int doPreInstall(int status) {
   6072             if (status != PackageManager.INSTALL_SUCCEEDED) {
   6073                 // Destroy container
   6074                 PackageHelper.destroySdDir(cid);
   6075             } else {
   6076                 boolean mounted = PackageHelper.isContainerMounted(cid);
   6077                 if (!mounted) {
   6078                     String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
   6079                             Process.SYSTEM_UID);
   6080                     if (newCachePath != null) {
   6081                         setCachePath(newCachePath);
   6082                     } else {
   6083                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   6084                     }
   6085                 }
   6086             }
   6087             return status;
   6088         }
   6089 
   6090         boolean doRename(int status, final String pkgName,
   6091                 String oldCodePath) {
   6092             String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
   6093             String newCachePath = null;
   6094             if (PackageHelper.isContainerMounted(cid)) {
   6095                 // Unmount the container
   6096                 if (!PackageHelper.unMountSdDir(cid)) {
   6097                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
   6098                     return false;
   6099                 }
   6100             }
   6101             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   6102                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
   6103                         " which might be stale. Will try to clean up.");
   6104                 // Clean up the stale container and proceed to recreate.
   6105                 if (!PackageHelper.destroySdDir(newCacheId)) {
   6106                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
   6107                     return false;
   6108                 }
   6109                 // Successfully cleaned up stale container. Try to rename again.
   6110                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   6111                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
   6112                             + " inspite of cleaning it up.");
   6113                     return false;
   6114                 }
   6115             }
   6116             if (!PackageHelper.isContainerMounted(newCacheId)) {
   6117                 Slog.w(TAG, "Mounting container " + newCacheId);
   6118                 newCachePath = PackageHelper.mountSdDir(newCacheId,
   6119                         getEncryptKey(), Process.SYSTEM_UID);
   6120             } else {
   6121                 newCachePath = PackageHelper.getSdDir(newCacheId);
   6122             }
   6123             if (newCachePath == null) {
   6124                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
   6125                 return false;
   6126             }
   6127             Log.i(TAG, "Succesfully renamed " + cid +
   6128                     " to " + newCacheId +
   6129                     " at new path: " + newCachePath);
   6130             cid = newCacheId;
   6131             setCachePath(newCachePath);
   6132             return true;
   6133         }
   6134 
   6135         private void setCachePath(String newCachePath) {
   6136             File cachePath = new File(newCachePath);
   6137             libraryPath = new File(cachePath, LIB_DIR_NAME).getPath();
   6138             packagePath = new File(cachePath, RES_FILE_NAME).getPath();
   6139         }
   6140 
   6141         int doPostInstall(int status) {
   6142             if (status != PackageManager.INSTALL_SUCCEEDED) {
   6143                 cleanUp();
   6144             } else {
   6145                 boolean mounted = PackageHelper.isContainerMounted(cid);
   6146                 if (!mounted) {
   6147                     PackageHelper.mountSdDir(cid,
   6148                             getEncryptKey(), Process.myUid());
   6149                 }
   6150             }
   6151             return status;
   6152         }
   6153 
   6154         private void cleanUp() {
   6155             // Destroy secure container
   6156             PackageHelper.destroySdDir(cid);
   6157         }
   6158 
   6159         void cleanUpResourcesLI() {
   6160             String sourceFile = getCodePath();
   6161             // Remove dex file
   6162             int retCode = mInstaller.rmdex(sourceFile);
   6163             if (retCode < 0) {
   6164                 Slog.w(TAG, "Couldn't remove dex file for package: "
   6165                         + " at location "
   6166                         + sourceFile.toString() + ", retcode=" + retCode);
   6167                 // we don't consider this to be a failure of the core package deletion
   6168             }
   6169             cleanUp();
   6170         }
   6171 
   6172         boolean matchContainer(String app) {
   6173             if (cid.startsWith(app)) {
   6174                 return true;
   6175             }
   6176             return false;
   6177         }
   6178 
   6179         String getPackageName() {
   6180             int idx = cid.lastIndexOf("-");
   6181             if (idx == -1) {
   6182                 return cid;
   6183             }
   6184             return cid.substring(0, idx);
   6185         }
   6186 
   6187         boolean doPostDeleteLI(boolean delete) {
   6188             boolean ret = false;
   6189             boolean mounted = PackageHelper.isContainerMounted(cid);
   6190             if (mounted) {
   6191                 // Unmount first
   6192                 ret = PackageHelper.unMountSdDir(cid);
   6193             }
   6194             if (ret && delete) {
   6195                 cleanUpResourcesLI();
   6196             }
   6197             return ret;
   6198         }
   6199     };
   6200 
   6201     // Utility method used to create code paths based on package name and available index.
   6202     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
   6203         String idxStr = "";
   6204         int idx = 1;
   6205         // Fall back to default value of idx=1 if prefix is not
   6206         // part of oldCodePath
   6207         if (oldCodePath != null) {
   6208             String subStr = oldCodePath;
   6209             // Drop the suffix right away
   6210             if (subStr.endsWith(suffix)) {
   6211                 subStr = subStr.substring(0, subStr.length() - suffix.length());
   6212             }
   6213             // If oldCodePath already contains prefix find out the
   6214             // ending index to either increment or decrement.
   6215             int sidx = subStr.lastIndexOf(prefix);
   6216             if (sidx != -1) {
   6217                 subStr = subStr.substring(sidx + prefix.length());
   6218                 if (subStr != null) {
   6219                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
   6220                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
   6221                     }
   6222                     try {
   6223                         idx = Integer.parseInt(subStr);
   6224                         if (idx <= 1) {
   6225                             idx++;
   6226                         } else {
   6227                             idx--;
   6228                         }
   6229                     } catch(NumberFormatException e) {
   6230                     }
   6231                 }
   6232             }
   6233         }
   6234         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
   6235         return prefix + idxStr;
   6236     }
   6237 
   6238     // Utility method used to ignore ADD/REMOVE events
   6239     // by directory observer.
   6240     private static boolean ignoreCodePath(String fullPathStr) {
   6241         String apkName = getApkName(fullPathStr);
   6242         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
   6243         if (idx != -1 && ((idx+1) < apkName.length())) {
   6244             // Make sure the package ends with a numeral
   6245             String version = apkName.substring(idx+1);
   6246             try {
   6247                 Integer.parseInt(version);
   6248                 return true;
   6249             } catch (NumberFormatException e) {}
   6250         }
   6251         return false;
   6252     }
   6253 
   6254     // Utility method that returns the relative package path with respect
   6255     // to the installation directory. Like say for /data/data/com.test-1.apk
   6256     // string com.test-1 is returned.
   6257     static String getApkName(String codePath) {
   6258         if (codePath == null) {
   6259             return null;
   6260         }
   6261         int sidx = codePath.lastIndexOf("/");
   6262         int eidx = codePath.lastIndexOf(".");
   6263         if (eidx == -1) {
   6264             eidx = codePath.length();
   6265         } else if (eidx == 0) {
   6266             Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name");
   6267             return null;
   6268         }
   6269         return codePath.substring(sidx+1, eidx);
   6270     }
   6271 
   6272     class PackageInstalledInfo {
   6273         String name;
   6274         int uid;
   6275         PackageParser.Package pkg;
   6276         int returnCode;
   6277         PackageRemovedInfo removedInfo;
   6278     }
   6279 
   6280     /*
   6281      * Install a non-existing package.
   6282      */
   6283     private void installNewPackageLI(PackageParser.Package pkg,
   6284             int parseFlags,
   6285             int scanMode,
   6286             String installerPackageName, PackageInstalledInfo res) {
   6287         // Remember this for later, in case we need to rollback this install
   6288         String pkgName = pkg.packageName;
   6289 
   6290         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
   6291         res.name = pkgName;
   6292         synchronized(mPackages) {
   6293             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
   6294                 // A package with the same name is already installed, though
   6295                 // it has been renamed to an older name.  The package we
   6296                 // are trying to install should be installed as an update to
   6297                 // the existing one, but that has not been requested, so bail.
   6298                 Slog.w(TAG, "Attempt to re-install " + pkgName
   6299                         + " without first uninstalling package running as "
   6300                         + mSettings.mRenamedPackages.get(pkgName));
   6301                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   6302                 return;
   6303             }
   6304             if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) {
   6305                 // Don't allow installation over an existing package with the same name.
   6306                 Slog.w(TAG, "Attempt to re-install " + pkgName
   6307                         + " without first uninstalling.");
   6308                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   6309                 return;
   6310             }
   6311         }
   6312         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   6313         PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
   6314                 System.currentTimeMillis());
   6315         if (newPackage == null) {
   6316             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
   6317             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
   6318                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
   6319             }
   6320         } else {
   6321             updateSettingsLI(newPackage,
   6322                     installerPackageName,
   6323                     res);
   6324             // delete the partially installed application. the data directory will have to be
   6325             // restored if it was already existing
   6326             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   6327                 // remove package from internal structures.  Note that we want deletePackageX to
   6328                 // delete the package data and cache directories that it created in
   6329                 // scanPackageLocked, unless those directories existed before we even tried to
   6330                 // install.
   6331                 deletePackageLI(
   6332                         pkgName, false,
   6333                         dataDirExists ? PackageManager.DONT_DELETE_DATA : 0,
   6334                                 res.removedInfo, true);
   6335             }
   6336         }
   6337     }
   6338 
   6339     private void replacePackageLI(PackageParser.Package pkg,
   6340             int parseFlags,
   6341             int scanMode,
   6342             String installerPackageName, PackageInstalledInfo res) {
   6343 
   6344         PackageParser.Package oldPackage;
   6345         String pkgName = pkg.packageName;
   6346         // First find the old package info and check signatures
   6347         synchronized(mPackages) {
   6348             oldPackage = mPackages.get(pkgName);
   6349             if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
   6350                     != PackageManager.SIGNATURE_MATCH) {
   6351                 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
   6352                 return;
   6353             }
   6354         }
   6355         boolean sysPkg = (isSystemApp(oldPackage));
   6356         if (sysPkg) {
   6357             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res);
   6358         } else {
   6359             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res);
   6360         }
   6361     }
   6362 
   6363     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
   6364             PackageParser.Package pkg,
   6365             int parseFlags, int scanMode,
   6366             String installerPackageName, PackageInstalledInfo res) {
   6367         PackageParser.Package newPackage = null;
   6368         String pkgName = deletedPackage.packageName;
   6369         boolean deletedPkg = true;
   6370         boolean updatedSettings = false;
   6371 
   6372         long origUpdateTime;
   6373         if (pkg.mExtras != null) {
   6374             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
   6375         } else {
   6376             origUpdateTime = 0;
   6377         }
   6378 
   6379         // First delete the existing package while retaining the data directory
   6380         if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA,
   6381                 res.removedInfo, true)) {
   6382             // If the existing package wasn't successfully deleted
   6383             res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
   6384             deletedPkg = false;
   6385         } else {
   6386             // Successfully deleted the old package. Now proceed with re-installation
   6387             mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   6388             newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
   6389                     System.currentTimeMillis());
   6390             if (newPackage == null) {
   6391                 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
   6392                 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
   6393                     res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
   6394                 }
   6395             } else {
   6396                 updateSettingsLI(newPackage,
   6397                         installerPackageName,
   6398                         res);
   6399                 updatedSettings = true;
   6400             }
   6401         }
   6402 
   6403         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   6404             // remove package from internal structures.  Note that we want deletePackageX to
   6405             // delete the package data and cache directories that it created in
   6406             // scanPackageLocked, unless those directories existed before we even tried to
   6407             // install.
   6408             if(updatedSettings) {
   6409                 deletePackageLI(
   6410                         pkgName, true,
   6411                         PackageManager.DONT_DELETE_DATA,
   6412                                 res.removedInfo, true);
   6413             }
   6414             // Since we failed to install the new package we need to restore the old
   6415             // package that we deleted.
   6416             if(deletedPkg) {
   6417                 File restoreFile = new File(deletedPackage.mPath);
   6418                 if (restoreFile == null) {
   6419                     Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName);
   6420                     return;
   6421                 }
   6422                 // Parse old package
   6423                 boolean oldOnSd = isExternal(deletedPackage);
   6424                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
   6425                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
   6426                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
   6427                 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
   6428                         | SCAN_UPDATE_TIME;
   6429                 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
   6430                         origUpdateTime) == null) {
   6431                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
   6432                     return;
   6433                 }
   6434                 // Restore of old package succeeded. Update permissions.
   6435                 // writer
   6436                 synchronized (mPackages) {
   6437                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
   6438                             true, false, false);
   6439                     // can downgrade to reader
   6440                     mSettings.writeLPr();
   6441                 }
   6442                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
   6443             }
   6444         }
   6445     }
   6446 
   6447     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
   6448             PackageParser.Package pkg,
   6449             int parseFlags, int scanMode,
   6450             String installerPackageName, PackageInstalledInfo res) {
   6451         PackageParser.Package newPackage = null;
   6452         boolean updatedSettings = false;
   6453         parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
   6454                 PackageParser.PARSE_IS_SYSTEM;
   6455         String packageName = deletedPackage.packageName;
   6456         res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
   6457         if (packageName == null) {
   6458             Slog.w(TAG, "Attempt to delete null packageName.");
   6459             return;
   6460         }
   6461         PackageParser.Package oldPkg;
   6462         PackageSetting oldPkgSetting;
   6463         // reader
   6464         synchronized (mPackages) {
   6465             oldPkg = mPackages.get(packageName);
   6466             oldPkgSetting = mSettings.mPackages.get(packageName);
   6467             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
   6468                     (oldPkgSetting == null)) {
   6469                 Slog.w(TAG, "Couldn't find package:"+packageName+" information");
   6470                 return;
   6471             }
   6472         }
   6473 
   6474         killApplication(packageName, oldPkg.applicationInfo.uid);
   6475 
   6476         res.removedInfo.uid = oldPkg.applicationInfo.uid;
   6477         res.removedInfo.removedPackage = packageName;
   6478         // Remove existing system package
   6479         removePackageLI(oldPkg, true);
   6480         // writer
   6481         synchronized (mPackages) {
   6482             if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) {
   6483                 // We didn't need to disable the .apk as a current system package,
   6484                 // which means we are replacing another update that is already
   6485                 // installed.  We need to make sure to delete the older one's .apk.
   6486                 res.removedInfo.args = createInstallArgs(isExternal(pkg)
   6487                         ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL,
   6488                         deletedPackage.applicationInfo.sourceDir,
   6489                         deletedPackage.applicationInfo.publicSourceDir,
   6490                         deletedPackage.applicationInfo.nativeLibraryDir);
   6491             } else {
   6492                 res.removedInfo.args = null;
   6493             }
   6494         }
   6495 
   6496         // Successfully disabled the old package. Now proceed with re-installation
   6497         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   6498         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   6499         newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0);
   6500         if (newPackage == null) {
   6501             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
   6502             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
   6503                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
   6504             }
   6505         } else {
   6506             if (newPackage.mExtras != null) {
   6507                 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;
   6508                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
   6509                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
   6510             }
   6511             updateSettingsLI(newPackage, installerPackageName, res);
   6512             updatedSettings = true;
   6513         }
   6514 
   6515         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   6516             // Re installation failed. Restore old information
   6517             // Remove new pkg information
   6518             if (newPackage != null) {
   6519                 removePackageLI(newPackage, true);
   6520             }
   6521             // Add back the old system package
   6522             scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0);
   6523             // Restore the old system information in Settings
   6524             synchronized(mPackages) {
   6525                 if (updatedSettings) {
   6526                     mSettings.enableSystemPackageLPw(packageName);
   6527                     mSettings.setInstallerPackageName(packageName,
   6528                             oldPkgSetting.installerPackageName);
   6529                 }
   6530                 mSettings.writeLPr();
   6531             }
   6532         }
   6533     }
   6534 
   6535     // Utility method used to move dex files during install.
   6536     private int moveDexFilesLI(PackageParser.Package newPackage) {
   6537         int retCode;
   6538         if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
   6539             retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
   6540             if (retCode != 0) {
   6541                 if (mNoDexOpt) {
   6542                     /*
   6543                      * If we're in an engineering build, programs are lazily run
   6544                      * through dexopt. If the .dex file doesn't exist yet, it
   6545                      * will be created when the program is run next.
   6546                      */
   6547                     Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath);
   6548                 } else {
   6549                     Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath);
   6550                     return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   6551                 }
   6552             }
   6553         }
   6554         return PackageManager.INSTALL_SUCCEEDED;
   6555     }
   6556 
   6557     private void updateSettingsLI(PackageParser.Package newPackage,
   6558             String installerPackageName, PackageInstalledInfo res) {
   6559         String pkgName = newPackage.packageName;
   6560         synchronized (mPackages) {
   6561             //write settings. the installStatus will be incomplete at this stage.
   6562             //note that the new package setting would have already been
   6563             //added to mPackages. It hasn't been persisted yet.
   6564             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
   6565             mSettings.writeLPr();
   6566         }
   6567 
   6568         if ((res.returnCode = moveDexFilesLI(newPackage))
   6569                 != PackageManager.INSTALL_SUCCEEDED) {
   6570             // Discontinue if moving dex files failed.
   6571             return;
   6572         }
   6573         if((res.returnCode = setPermissionsLI(newPackage))
   6574                 != PackageManager.INSTALL_SUCCEEDED) {
   6575             mInstaller.rmdex(newPackage.mScanPath);
   6576             return;
   6577         } else {
   6578             Log.d(TAG, "New package installed in " + newPackage.mPath);
   6579         }
   6580         synchronized (mPackages) {
   6581             updatePermissionsLPw(newPackage.packageName, newPackage,
   6582                     newPackage.permissions.size() > 0, true, false);
   6583             res.name = pkgName;
   6584             res.uid = newPackage.applicationInfo.uid;
   6585             res.pkg = newPackage;
   6586             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
   6587             mSettings.setInstallerPackageName(pkgName, installerPackageName);
   6588             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   6589             //to update install status
   6590             mSettings.writeLPr();
   6591         }
   6592     }
   6593 
   6594     private void installPackageLI(InstallArgs args,
   6595             boolean newInstall, PackageInstalledInfo res) {
   6596         int pFlags = args.flags;
   6597         String installerPackageName = args.installerPackageName;
   6598         File tmpPackageFile = new File(args.getCodePath());
   6599         boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
   6600         boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
   6601         boolean replace = false;
   6602         int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
   6603                 | (newInstall ? SCAN_NEW_INSTALL : 0);
   6604         // Result object to be returned
   6605         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   6606 
   6607         // Retrieve PackageSettings and parse package
   6608         int parseFlags = PackageParser.PARSE_CHATTY |
   6609         (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) |
   6610         (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
   6611         parseFlags |= mDefParseFlags;
   6612         PackageParser pp = new PackageParser(tmpPackageFile.getPath());
   6613         pp.setSeparateProcesses(mSeparateProcesses);
   6614         final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
   6615                 null, mMetrics, parseFlags);
   6616         if (pkg == null) {
   6617             res.returnCode = pp.getParseError();
   6618             return;
   6619         }
   6620         String pkgName = res.name = pkg.packageName;
   6621         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
   6622             if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
   6623                 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
   6624                 return;
   6625             }
   6626         }
   6627         if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
   6628             res.returnCode = pp.getParseError();
   6629             return;
   6630         }
   6631 
   6632         /* If the installer passed in a manifest digest, compare it now. */
   6633         if (args.manifestDigest != null) {
   6634             if (DEBUG_INSTALL) {
   6635                 final String parsedManifest = pkg.manifestDigest == null ? "null"
   6636                         : pkg.manifestDigest.toString();
   6637                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
   6638                         + parsedManifest);
   6639             }
   6640 
   6641             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
   6642                 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
   6643                 return;
   6644             }
   6645         } else if (DEBUG_INSTALL) {
   6646             final String parsedManifest = pkg.manifestDigest == null
   6647                     ? "null" : pkg.manifestDigest.toString();
   6648             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
   6649         }
   6650 
   6651         // Get rid of all references to package scan path via parser.
   6652         pp = null;
   6653         String oldCodePath = null;
   6654         boolean systemApp = false;
   6655         synchronized (mPackages) {
   6656             // Check if installing already existing package
   6657             if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   6658                 String oldName = mSettings.mRenamedPackages.get(pkgName);
   6659                 if (pkg.mOriginalPackages != null
   6660                         && pkg.mOriginalPackages.contains(oldName)
   6661                         && mPackages.containsKey(oldName)) {
   6662                     // This package is derived from an original package,
   6663                     // and this device has been updating from that original
   6664                     // name.  We must continue using the original name, so
   6665                     // rename the new package here.
   6666                     pkg.setPackageName(oldName);
   6667                     pkgName = pkg.packageName;
   6668                     replace = true;
   6669                 } else if (mPackages.containsKey(pkgName)) {
   6670                     // This package, under its official name, already exists
   6671                     // on the device; we should replace it.
   6672                     replace = true;
   6673                 }
   6674             }
   6675             PackageSetting ps = mSettings.mPackages.get(pkgName);
   6676             if (ps != null) {
   6677                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
   6678                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
   6679                     systemApp = (ps.pkg.applicationInfo.flags &
   6680                             ApplicationInfo.FLAG_SYSTEM) != 0;
   6681                 }
   6682             }
   6683         }
   6684 
   6685         if (systemApp && onSd) {
   6686             // Disable updates to system apps on sdcard
   6687             Slog.w(TAG, "Cannot install updates to system apps on sdcard");
   6688             res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   6689             return;
   6690         }
   6691 
   6692         if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
   6693             res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   6694             return;
   6695         }
   6696         // Set application objects path explicitly after the rename
   6697         setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
   6698         pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
   6699         if (replace) {
   6700             replacePackageLI(pkg, parseFlags, scanMode,
   6701                     installerPackageName, res);
   6702         } else {
   6703             installNewPackageLI(pkg, parseFlags, scanMode,
   6704                     installerPackageName,res);
   6705         }
   6706     }
   6707 
   6708     private int setPermissionsLI(PackageParser.Package newPackage) {
   6709         int retCode = 0;
   6710         // TODO Gross hack but fix later. Ideally move this to be a post installation
   6711         // check after alloting uid.
   6712         if (isForwardLocked(newPackage)) {
   6713             File destResourceFile = new File(newPackage.applicationInfo.publicSourceDir);
   6714             try {
   6715                 extractPublicFiles(newPackage, destResourceFile);
   6716             } catch (IOException e) {
   6717                 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" +
   6718                            " forward-locked app.");
   6719                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   6720             } finally {
   6721                 //TODO clean up the extracted public files
   6722             }
   6723             retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath),
   6724                     newPackage.applicationInfo.uid);
   6725         } else {
   6726             // The permissions on the resource file was set when it was copied for
   6727             // non forward locked apps and apps on sdcard
   6728         }
   6729 
   6730         if (retCode != 0) {
   6731             Slog.e(TAG, "Couldn't set new package file permissions for " + newPackage.mPath
   6732                     + ". The return code was: " + retCode);
   6733             // TODO Define new internal error
   6734             return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   6735         }
   6736         return PackageManager.INSTALL_SUCCEEDED;
   6737     }
   6738 
   6739     private static boolean isForwardLocked(PackageParser.Package pkg) {
   6740         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
   6741     }
   6742 
   6743     private static boolean isExternal(PackageParser.Package pkg) {
   6744         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   6745     }
   6746 
   6747     private static boolean isSystemApp(PackageParser.Package pkg) {
   6748         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   6749     }
   6750 
   6751     private static boolean isSystemApp(ApplicationInfo info) {
   6752         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   6753     }
   6754 
   6755     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
   6756         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   6757     }
   6758 
   6759     private void extractPublicFiles(PackageParser.Package newPackage,
   6760                                     File publicZipFile) throws IOException {
   6761         final FileOutputStream fstr = new FileOutputStream(publicZipFile);
   6762         final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr);
   6763         final ZipFile privateZip = new ZipFile(newPackage.mPath);
   6764 
   6765         // Copy manifest, resources.arsc and res directory to public zip
   6766 
   6767         final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries();
   6768         while (privateZipEntries.hasMoreElements()) {
   6769             final ZipEntry zipEntry = privateZipEntries.nextElement();
   6770             final String zipEntryName = zipEntry.getName();
   6771             if ("AndroidManifest.xml".equals(zipEntryName)
   6772                 || "resources.arsc".equals(zipEntryName)
   6773                 || zipEntryName.startsWith("res/")) {
   6774                 try {
   6775                     copyZipEntry(zipEntry, privateZip, publicZipOutStream);
   6776                 } catch (IOException e) {
   6777                     try {
   6778                         publicZipOutStream.close();
   6779                         throw e;
   6780                     } finally {
   6781                         publicZipFile.delete();
   6782                     }
   6783                 }
   6784             }
   6785         }
   6786 
   6787         publicZipOutStream.finish();
   6788         publicZipOutStream.flush();
   6789         FileUtils.sync(fstr);
   6790         publicZipOutStream.close();
   6791         FileUtils.setPermissions(
   6792                 publicZipFile.getAbsolutePath(),
   6793                 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP|FileUtils.S_IROTH,
   6794                 -1, -1);
   6795     }
   6796 
   6797     private static void copyZipEntry(ZipEntry zipEntry,
   6798                                      ZipFile inZipFile,
   6799                                      ZipOutputStream outZipStream) throws IOException {
   6800         byte[] buffer = new byte[4096];
   6801         int num;
   6802 
   6803         ZipEntry newEntry;
   6804         if (zipEntry.getMethod() == ZipEntry.STORED) {
   6805             // Preserve the STORED method of the input entry.
   6806             newEntry = new ZipEntry(zipEntry);
   6807         } else {
   6808             // Create a new entry so that the compressed len is recomputed.
   6809             newEntry = new ZipEntry(zipEntry.getName());
   6810         }
   6811         outZipStream.putNextEntry(newEntry);
   6812 
   6813         InputStream data = inZipFile.getInputStream(zipEntry);
   6814         while ((num = data.read(buffer)) > 0) {
   6815             outZipStream.write(buffer, 0, num);
   6816         }
   6817         outZipStream.flush();
   6818     }
   6819 
   6820     private void deleteTempPackageFiles() {
   6821         FilenameFilter filter = new FilenameFilter() {
   6822             public boolean accept(File dir, String name) {
   6823                 return name.startsWith("vmdl") && name.endsWith(".tmp");
   6824             }
   6825         };
   6826         String tmpFilesList[] = mAppInstallDir.list(filter);
   6827         if(tmpFilesList == null) {
   6828             return;
   6829         }
   6830         for(int i = 0; i < tmpFilesList.length; i++) {
   6831             File tmpFile = new File(mAppInstallDir, tmpFilesList[i]);
   6832             tmpFile.delete();
   6833         }
   6834     }
   6835 
   6836     private File createTempPackageFile(File installDir) {
   6837         File tmpPackageFile;
   6838         try {
   6839             tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir);
   6840         } catch (IOException e) {
   6841             Slog.e(TAG, "Couldn't create temp file for downloaded package file.");
   6842             return null;
   6843         }
   6844         try {
   6845             FileUtils.setPermissions(
   6846                     tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR,
   6847                     -1, -1);
   6848         } catch (IOException e) {
   6849             Slog.e(TAG, "Trouble getting the canoncical path for a temp file.");
   6850             return null;
   6851         }
   6852         return tmpPackageFile;
   6853     }
   6854 
   6855     public void deletePackage(final String packageName,
   6856                               final IPackageDeleteObserver observer,
   6857                               final int flags) {
   6858         mContext.enforceCallingOrSelfPermission(
   6859                 android.Manifest.permission.DELETE_PACKAGES, null);
   6860         // Queue up an async operation since the package deletion may take a little while.
   6861         mHandler.post(new Runnable() {
   6862             public void run() {
   6863                 mHandler.removeCallbacks(this);
   6864                 final int returnCode = deletePackageX(packageName, true, true, flags);
   6865                 if (observer != null) {
   6866                     try {
   6867                         observer.packageDeleted(packageName, returnCode);
   6868                     } catch (RemoteException e) {
   6869                         Log.i(TAG, "Observer no longer exists.");
   6870                     } //end catch
   6871                 } //end if
   6872             } //end run
   6873         });
   6874     }
   6875 
   6876     /**
   6877      *  This method is an internal method that could be get invoked either
   6878      *  to delete an installed package or to clean up a failed installation.
   6879      *  After deleting an installed package, a broadcast is sent to notify any
   6880      *  listeners that the package has been installed. For cleaning up a failed
   6881      *  installation, the broadcast is not necessary since the package's
   6882      *  installation wouldn't have sent the initial broadcast either
   6883      *  The key steps in deleting a package are
   6884      *  deleting the package information in internal structures like mPackages,
   6885      *  deleting the packages base directories through installd
   6886      *  updating mSettings to reflect current status
   6887      *  persisting settings for later use
   6888      *  sending a broadcast if necessary
   6889      */
   6890     private int deletePackageX(String packageName, boolean sendBroadCast,
   6891                                    boolean deleteCodeAndResources, int flags) {
   6892         final PackageRemovedInfo info = new PackageRemovedInfo();
   6893         final boolean res;
   6894 
   6895         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
   6896                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
   6897         try {
   6898             if (dpm != null && dpm.packageHasActiveAdmins(packageName)) {
   6899                 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
   6900                 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
   6901             }
   6902         } catch (RemoteException e) {
   6903         }
   6904 
   6905         synchronized (mInstallLock) {
   6906             res = deletePackageLI(packageName, deleteCodeAndResources,
   6907                     flags | REMOVE_CHATTY, info, true);
   6908         }
   6909 
   6910         if (res && sendBroadCast) {
   6911             boolean systemUpdate = info.isRemovedPackageSystemUpdate;
   6912             info.sendBroadcast(deleteCodeAndResources, systemUpdate);
   6913 
   6914             // If the removed package was a system update, the old system packaged
   6915             // was re-enabled; we need to broadcast this information
   6916             if (systemUpdate) {
   6917                 Bundle extras = new Bundle(1);
   6918                 extras.putInt(Intent.EXTRA_UID, info.removedUid >= 0 ? info.removedUid : info.uid);
   6919                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   6920 
   6921                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
   6922                         extras, null, null);
   6923                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
   6924                         extras, null, null);
   6925                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
   6926                         null, packageName, null);
   6927             }
   6928         }
   6929         // Force a gc here.
   6930         Runtime.getRuntime().gc();
   6931         // Delete the resources here after sending the broadcast to let
   6932         // other processes clean up before deleting resources.
   6933         if (info.args != null) {
   6934             synchronized (mInstallLock) {
   6935                 info.args.doPostDeleteLI(deleteCodeAndResources);
   6936             }
   6937         }
   6938 
   6939         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
   6940     }
   6941 
   6942     static class PackageRemovedInfo {
   6943         String removedPackage;
   6944         int uid = -1;
   6945         int removedUid = -1;
   6946         boolean isRemovedPackageSystemUpdate = false;
   6947         // Clean up resources deleted packages.
   6948         InstallArgs args = null;
   6949 
   6950         void sendBroadcast(boolean fullRemove, boolean replacing) {
   6951             Bundle extras = new Bundle(1);
   6952             extras.putInt(Intent.EXTRA_UID, removedUid >= 0 ? removedUid : uid);
   6953             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
   6954             if (replacing) {
   6955                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   6956             }
   6957             if (removedPackage != null) {
   6958                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
   6959                         extras, null, null);
   6960                 if (fullRemove && !replacing) {
   6961                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
   6962                             extras, null, null);
   6963                 }
   6964             }
   6965             if (removedUid >= 0) {
   6966                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null);
   6967             }
   6968         }
   6969     }
   6970 
   6971     /*
   6972      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
   6973      * flag is not set, the data directory is removed as well.
   6974      * make sure this flag is set for partially installed apps. If not its meaningless to
   6975      * delete a partially installed application.
   6976      */
   6977     private void removePackageDataLI(PackageParser.Package p, PackageRemovedInfo outInfo,
   6978             int flags, boolean writeSettings) {
   6979         String packageName = p.packageName;
   6980         if (outInfo != null) {
   6981             outInfo.removedPackage = packageName;
   6982         }
   6983         removePackageLI(p, (flags&REMOVE_CHATTY) != 0);
   6984         // Retrieve object to delete permissions for shared user later on
   6985         final PackageSetting deletedPs;
   6986         // reader
   6987         synchronized (mPackages) {
   6988             deletedPs = mSettings.mPackages.get(packageName);
   6989         }
   6990         if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
   6991             int retCode = mInstaller.remove(packageName, 0);
   6992             if (retCode < 0) {
   6993                 Slog.w(TAG, "Couldn't remove app data or cache directory for package: "
   6994                            + packageName + ", retcode=" + retCode);
   6995                 // we don't consider this to be a failure of the core package deletion
   6996             } else {
   6997                 // TODO: Kill the processes first
   6998                 mUserManager.removePackageForAllUsers(packageName);
   6999             }
   7000             schedulePackageCleaning(packageName);
   7001         }
   7002         // writer
   7003         synchronized (mPackages) {
   7004             if (deletedPs != null) {
   7005                 if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
   7006                     if (outInfo != null) {
   7007                         outInfo.removedUid = mSettings.removePackageLPw(packageName);
   7008                     }
   7009                     if (deletedPs != null) {
   7010                         updatePermissionsLPw(deletedPs.name, null, false, false, false);
   7011                         if (deletedPs.sharedUser != null) {
   7012                             // remove permissions associated with package
   7013                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
   7014                         }
   7015                     }
   7016                 }
   7017                 // remove from preferred activities.
   7018                 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
   7019                 for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
   7020                     if (pa.mPref.mComponent.getPackageName().equals(deletedPs.name)) {
   7021                         removed.add(pa);
   7022                     }
   7023                 }
   7024                 for (PreferredActivity pa : removed) {
   7025                     mSettings.mPreferredActivities.removeFilter(pa);
   7026                 }
   7027             }
   7028             // can downgrade to reader
   7029             if (writeSettings) {
   7030                 // Save settings now
   7031                 mSettings.writeLPr();
   7032             }
   7033         }
   7034     }
   7035 
   7036     /*
   7037      * Tries to delete system package.
   7038      */
   7039     private boolean deleteSystemPackageLI(PackageParser.Package p,
   7040             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
   7041         ApplicationInfo applicationInfo = p.applicationInfo;
   7042         //applicable for non-partially installed applications only
   7043         if (applicationInfo == null) {
   7044             Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
   7045             return false;
   7046         }
   7047         PackageSetting ps = null;
   7048         // Confirm if the system package has been updated
   7049         // An updated system app can be deleted. This will also have to restore
   7050         // the system pkg from system partition
   7051         // reader
   7052         synchronized (mPackages) {
   7053             ps = mSettings.getDisabledSystemPkgLPr(p.packageName);
   7054         }
   7055         if (ps == null) {
   7056             Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName);
   7057             return false;
   7058         } else {
   7059             Log.i(TAG, "Deleting system pkg from data partition");
   7060         }
   7061         // Delete the updated package
   7062         outInfo.isRemovedPackageSystemUpdate = true;
   7063         if (ps.versionCode < p.mVersionCode) {
   7064             // Delete data for downgrades
   7065             flags &= ~PackageManager.DONT_DELETE_DATA;
   7066         } else {
   7067             // Preserve data by setting flag
   7068             flags |= PackageManager.DONT_DELETE_DATA;
   7069         }
   7070         boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo,
   7071                 writeSettings);
   7072         if (!ret) {
   7073             return false;
   7074         }
   7075         // writer
   7076         synchronized (mPackages) {
   7077             // Reinstate the old system package
   7078             mSettings.enableSystemPackageLPw(p.packageName);
   7079             // Remove any native libraries from the upgraded package.
   7080             NativeLibraryHelper.removeNativeBinariesLI(p.applicationInfo.nativeLibraryDir);
   7081         }
   7082         // Install the system package
   7083         PackageParser.Package newPkg = scanPackageLI(ps.codePath,
   7084                 PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM,
   7085                 SCAN_MONITOR | SCAN_NO_PATHS, 0);
   7086 
   7087         if (newPkg == null) {
   7088             Slog.w(TAG, "Failed to restore system package:"+p.packageName+" with error:" + mLastScanError);
   7089             return false;
   7090         }
   7091         // writer
   7092         synchronized (mPackages) {
   7093             updatePermissionsLPw(newPkg.packageName, newPkg, true, true, false);
   7094             // can downgrade to reader here
   7095             if (writeSettings) {
   7096                 mSettings.writeLPr();
   7097             }
   7098         }
   7099         return true;
   7100     }
   7101 
   7102     private boolean deleteInstalledPackageLI(PackageParser.Package p,
   7103             boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo,
   7104             boolean writeSettings) {
   7105         ApplicationInfo applicationInfo = p.applicationInfo;
   7106         if (applicationInfo == null) {
   7107             Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
   7108             return false;
   7109         }
   7110         if (outInfo != null) {
   7111             outInfo.uid = applicationInfo.uid;
   7112         }
   7113 
   7114         // Delete package data from internal structures and also remove data if flag is set
   7115         removePackageDataLI(p, outInfo, flags, writeSettings);
   7116 
   7117         // Delete application code and resources
   7118         if (deleteCodeAndResources) {
   7119             // TODO can pick up from PackageSettings as well
   7120             int installFlags = isExternal(p) ? PackageManager.INSTALL_EXTERNAL : 0;
   7121             installFlags |= isForwardLocked(p) ? PackageManager.INSTALL_FORWARD_LOCK : 0;
   7122             outInfo.args = createInstallArgs(installFlags, applicationInfo.sourceDir,
   7123                     applicationInfo.publicSourceDir, applicationInfo.nativeLibraryDir);
   7124         }
   7125         return true;
   7126     }
   7127 
   7128     /*
   7129      * This method handles package deletion in general
   7130      */
   7131     private boolean deletePackageLI(String packageName,
   7132             boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo,
   7133             boolean writeSettings) {
   7134         if (packageName == null) {
   7135             Slog.w(TAG, "Attempt to delete null packageName.");
   7136             return false;
   7137         }
   7138         PackageParser.Package p;
   7139         boolean dataOnly = false;
   7140         synchronized (mPackages) {
   7141             p = mPackages.get(packageName);
   7142             if (p == null) {
   7143                 //this retrieves partially installed apps
   7144                 dataOnly = true;
   7145                 PackageSetting ps = mSettings.mPackages.get(packageName);
   7146                 if (ps == null) {
   7147                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   7148                     return false;
   7149                 }
   7150                 p = ps.pkg;
   7151             }
   7152         }
   7153         if (p == null) {
   7154             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   7155             return false;
   7156         }
   7157 
   7158         if (dataOnly) {
   7159             // Delete application data first
   7160             removePackageDataLI(p, outInfo, flags, writeSettings);
   7161             return true;
   7162         }
   7163         // At this point the package should have ApplicationInfo associated with it
   7164         if (p.applicationInfo == null) {
   7165             Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
   7166             return false;
   7167         }
   7168         boolean ret = false;
   7169         if (isSystemApp(p)) {
   7170             Log.i(TAG, "Removing system package:"+p.packageName);
   7171             // When an updated system application is deleted we delete the existing resources as well and
   7172             // fall back to existing code in system partition
   7173             ret = deleteSystemPackageLI(p, flags, outInfo, writeSettings);
   7174         } else {
   7175             Log.i(TAG, "Removing non-system package:"+p.packageName);
   7176             // Kill application pre-emptively especially for apps on sd.
   7177             killApplication(packageName, p.applicationInfo.uid);
   7178             ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo,
   7179                     writeSettings);
   7180         }
   7181         return ret;
   7182     }
   7183 
   7184     public void clearApplicationUserData(final String packageName,
   7185             final IPackageDataObserver observer) {
   7186         mContext.enforceCallingOrSelfPermission(
   7187                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
   7188         // Queue up an async operation since the package deletion may take a little while.
   7189         mHandler.post(new Runnable() {
   7190             public void run() {
   7191                 mHandler.removeCallbacks(this);
   7192                 final boolean succeeded;
   7193                 synchronized (mInstallLock) {
   7194                     succeeded = clearApplicationUserDataLI(packageName);
   7195                 }
   7196                 if (succeeded) {
   7197                     // invoke DeviceStorageMonitor's update method to clear any notifications
   7198                     DeviceStorageMonitorService dsm = (DeviceStorageMonitorService)
   7199                             ServiceManager.getService(DeviceStorageMonitorService.SERVICE);
   7200                     if (dsm != null) {
   7201                         dsm.updateMemory();
   7202                     }
   7203                 }
   7204                 if(observer != null) {
   7205                     try {
   7206                         observer.onRemoveCompleted(packageName, succeeded);
   7207                     } catch (RemoteException e) {
   7208                         Log.i(TAG, "Observer no longer exists.");
   7209                     }
   7210                 } //end if observer
   7211             } //end run
   7212         });
   7213     }
   7214 
   7215     private boolean clearApplicationUserDataLI(String packageName) {
   7216         if (packageName == null) {
   7217             Slog.w(TAG, "Attempt to delete null packageName.");
   7218             return false;
   7219         }
   7220         PackageParser.Package p;
   7221         boolean dataOnly = false;
   7222         synchronized (mPackages) {
   7223             p = mPackages.get(packageName);
   7224             if(p == null) {
   7225                 dataOnly = true;
   7226                 PackageSetting ps = mSettings.mPackages.get(packageName);
   7227                 if((ps == null) || (ps.pkg == null)) {
   7228                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   7229                     return false;
   7230                 }
   7231                 p = ps.pkg;
   7232             }
   7233         }
   7234 
   7235         if (!dataOnly) {
   7236             //need to check this only for fully installed applications
   7237             if (p == null) {
   7238                 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   7239                 return false;
   7240             }
   7241             final ApplicationInfo applicationInfo = p.applicationInfo;
   7242             if (applicationInfo == null) {
   7243                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
   7244                 return false;
   7245             }
   7246         }
   7247         int retCode = mInstaller.clearUserData(packageName, 0); // TODO - correct userId
   7248         if (retCode < 0) {
   7249             Slog.w(TAG, "Couldn't remove cache files for package: "
   7250                     + packageName);
   7251             return false;
   7252         }
   7253         return true;
   7254     }
   7255 
   7256     public void deleteApplicationCacheFiles(final String packageName,
   7257             final IPackageDataObserver observer) {
   7258         mContext.enforceCallingOrSelfPermission(
   7259                 android.Manifest.permission.DELETE_CACHE_FILES, null);
   7260         // Queue up an async operation since the package deletion may take a little while.
   7261         mHandler.post(new Runnable() {
   7262             public void run() {
   7263                 mHandler.removeCallbacks(this);
   7264                 final boolean succeded;
   7265                 synchronized (mInstallLock) {
   7266                     succeded = deleteApplicationCacheFilesLI(packageName);
   7267                 }
   7268                 if(observer != null) {
   7269                     try {
   7270                         observer.onRemoveCompleted(packageName, succeded);
   7271                     } catch (RemoteException e) {
   7272                         Log.i(TAG, "Observer no longer exists.");
   7273                     }
   7274                 } //end if observer
   7275             } //end run
   7276         });
   7277     }
   7278 
   7279     private boolean deleteApplicationCacheFilesLI(String packageName) {
   7280         if (packageName == null) {
   7281             Slog.w(TAG, "Attempt to delete null packageName.");
   7282             return false;
   7283         }
   7284         PackageParser.Package p;
   7285         synchronized (mPackages) {
   7286             p = mPackages.get(packageName);
   7287         }
   7288         if (p == null) {
   7289             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   7290             return false;
   7291         }
   7292         final ApplicationInfo applicationInfo = p.applicationInfo;
   7293         if (applicationInfo == null) {
   7294             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
   7295             return false;
   7296         }
   7297         int retCode = mInstaller.deleteCacheFiles(packageName);
   7298         if (retCode < 0) {
   7299             Slog.w(TAG, "Couldn't remove cache files for package: "
   7300                        + packageName);
   7301             return false;
   7302         }
   7303         return true;
   7304     }
   7305 
   7306     public void getPackageSizeInfo(final String packageName,
   7307             final IPackageStatsObserver observer) {
   7308         mContext.enforceCallingOrSelfPermission(
   7309                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
   7310         // Queue up an async operation since the package deletion may take a little while.
   7311         mHandler.post(new Runnable() {
   7312             public void run() {
   7313                 mHandler.removeCallbacks(this);
   7314                 PackageStats stats = new PackageStats(packageName);
   7315 
   7316                 final boolean success;
   7317                 synchronized (mInstallLock) {
   7318                     success = getPackageSizeInfoLI(packageName, stats);
   7319                 }
   7320 
   7321                 Message msg = mHandler.obtainMessage(INIT_COPY);
   7322                 msg.obj = new MeasureParams(stats, success, observer);
   7323                 mHandler.sendMessage(msg);
   7324             } //end run
   7325         });
   7326     }
   7327 
   7328     private boolean getPackageSizeInfoLI(String packageName, PackageStats pStats) {
   7329         if (packageName == null) {
   7330             Slog.w(TAG, "Attempt to get size of null packageName.");
   7331             return false;
   7332         }
   7333         PackageParser.Package p;
   7334         boolean dataOnly = false;
   7335         String asecPath = null;
   7336         synchronized (mPackages) {
   7337             p = mPackages.get(packageName);
   7338             if(p == null) {
   7339                 dataOnly = true;
   7340                 PackageSetting ps = mSettings.mPackages.get(packageName);
   7341                 if((ps == null) || (ps.pkg == null)) {
   7342                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   7343                     return false;
   7344                 }
   7345                 p = ps.pkg;
   7346             }
   7347             if (p != null && isExternal(p)) {
   7348                 String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir);
   7349                 if (secureContainerId != null) {
   7350                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
   7351                 }
   7352             }
   7353         }
   7354         String publicSrcDir = null;
   7355         if(!dataOnly) {
   7356             final ApplicationInfo applicationInfo = p.applicationInfo;
   7357             if (applicationInfo == null) {
   7358                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
   7359                 return false;
   7360             }
   7361             if (isForwardLocked(p)) {
   7362                 publicSrcDir = applicationInfo.publicSourceDir;
   7363             }
   7364         }
   7365         int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir,
   7366                 asecPath, pStats);
   7367         if (res < 0) {
   7368             return false;
   7369         }
   7370         return true;
   7371     }
   7372 
   7373 
   7374     public void addPackageToPreferred(String packageName) {
   7375         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
   7376     }
   7377 
   7378     public void removePackageFromPreferred(String packageName) {
   7379         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
   7380     }
   7381 
   7382     public List<PackageInfo> getPreferredPackages(int flags) {
   7383         return new ArrayList<PackageInfo>();
   7384     }
   7385 
   7386     private int getUidTargetSdkVersionLockedLPr(int uid) {
   7387         Object obj = mSettings.getUserIdLPr(uid);
   7388         if (obj instanceof SharedUserSetting) {
   7389             final SharedUserSetting sus = (SharedUserSetting) obj;
   7390             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
   7391             final Iterator<PackageSetting> it = sus.packages.iterator();
   7392             while (it.hasNext()) {
   7393                 final PackageSetting ps = it.next();
   7394                 if (ps.pkg != null) {
   7395                     int v = ps.pkg.applicationInfo.targetSdkVersion;
   7396                     if (v < vers) vers = v;
   7397                 }
   7398             }
   7399             return vers;
   7400         } else if (obj instanceof PackageSetting) {
   7401             final PackageSetting ps = (PackageSetting) obj;
   7402             if (ps.pkg != null) {
   7403                 return ps.pkg.applicationInfo.targetSdkVersion;
   7404             }
   7405         }
   7406         return Build.VERSION_CODES.CUR_DEVELOPMENT;
   7407     }
   7408 
   7409     public void addPreferredActivity(IntentFilter filter, int match,
   7410             ComponentName[] set, ComponentName activity) {
   7411         // writer
   7412         synchronized (mPackages) {
   7413             if (mContext.checkCallingOrSelfPermission(
   7414                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   7415                     != PackageManager.PERMISSION_GRANTED) {
   7416                 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
   7417                         < Build.VERSION_CODES.FROYO) {
   7418                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
   7419                             + Binder.getCallingUid());
   7420                     return;
   7421                 }
   7422                 mContext.enforceCallingOrSelfPermission(
   7423                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   7424             }
   7425 
   7426             Slog.i(TAG, "Adding preferred activity " + activity + ":");
   7427             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   7428             mSettings.mPreferredActivities.addFilter(
   7429                     new PreferredActivity(filter, match, set, activity));
   7430             scheduleWriteSettingsLocked();
   7431         }
   7432     }
   7433 
   7434     public void replacePreferredActivity(IntentFilter filter, int match,
   7435             ComponentName[] set, ComponentName activity) {
   7436         if (filter.countActions() != 1) {
   7437             throw new IllegalArgumentException(
   7438                     "replacePreferredActivity expects filter to have only 1 action.");
   7439         }
   7440         if (filter.countCategories() != 1) {
   7441             throw new IllegalArgumentException(
   7442                     "replacePreferredActivity expects filter to have only 1 category.");
   7443         }
   7444         if (filter.countDataAuthorities() != 0
   7445                 || filter.countDataPaths() != 0
   7446                 || filter.countDataSchemes() != 0
   7447                 || filter.countDataTypes() != 0) {
   7448             throw new IllegalArgumentException(
   7449                     "replacePreferredActivity expects filter to have no data authorities, " +
   7450                     "paths, schemes or types.");
   7451         }
   7452         synchronized (mPackages) {
   7453             if (mContext.checkCallingOrSelfPermission(
   7454                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   7455                     != PackageManager.PERMISSION_GRANTED) {
   7456                 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
   7457                         < Build.VERSION_CODES.FROYO) {
   7458                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
   7459                             + Binder.getCallingUid());
   7460                     return;
   7461                 }
   7462                 mContext.enforceCallingOrSelfPermission(
   7463                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   7464             }
   7465 
   7466             Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
   7467             String action = filter.getAction(0);
   7468             String category = filter.getCategory(0);
   7469             while (it.hasNext()) {
   7470                 PreferredActivity pa = it.next();
   7471                 if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
   7472                     it.remove();
   7473                     Log.i(TAG, "Removed preferred activity " + pa.mPref.mComponent + ":");
   7474                     filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   7475                 }
   7476             }
   7477             addPreferredActivity(filter, match, set, activity);
   7478         }
   7479     }
   7480 
   7481     public void clearPackagePreferredActivities(String packageName) {
   7482         final int uid = Binder.getCallingUid();
   7483         // writer
   7484         synchronized (mPackages) {
   7485             PackageParser.Package pkg = mPackages.get(packageName);
   7486             if (pkg == null || pkg.applicationInfo.uid != uid) {
   7487                 if (mContext.checkCallingOrSelfPermission(
   7488                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   7489                         != PackageManager.PERMISSION_GRANTED) {
   7490                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
   7491                             < Build.VERSION_CODES.FROYO) {
   7492                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
   7493                                 + Binder.getCallingUid());
   7494                         return;
   7495                     }
   7496                     mContext.enforceCallingOrSelfPermission(
   7497                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   7498                 }
   7499             }
   7500 
   7501             if (clearPackagePreferredActivitiesLPw(packageName)) {
   7502                 scheduleWriteSettingsLocked();
   7503             }
   7504         }
   7505     }
   7506 
   7507     boolean clearPackagePreferredActivitiesLPw(String packageName) {
   7508         boolean changed = false;
   7509         Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
   7510         while (it.hasNext()) {
   7511             PreferredActivity pa = it.next();
   7512             if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
   7513                 it.remove();
   7514                 changed = true;
   7515             }
   7516         }
   7517         return changed;
   7518     }
   7519 
   7520     public int getPreferredActivities(List<IntentFilter> outFilters,
   7521             List<ComponentName> outActivities, String packageName) {
   7522 
   7523         int num = 0;
   7524         // reader
   7525         synchronized (mPackages) {
   7526             final Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
   7527             while (it.hasNext()) {
   7528                 final PreferredActivity pa = it.next();
   7529                 if (packageName == null
   7530                         || pa.mPref.mComponent.getPackageName().equals(packageName)) {
   7531                     if (outFilters != null) {
   7532                         outFilters.add(new IntentFilter(pa));
   7533                     }
   7534                     if (outActivities != null) {
   7535                         outActivities.add(pa.mPref.mComponent);
   7536                     }
   7537                 }
   7538             }
   7539         }
   7540 
   7541         return num;
   7542     }
   7543 
   7544     public void setApplicationEnabledSetting(String appPackageName,
   7545             int newState, int flags) {
   7546         setEnabledSetting(appPackageName, null, newState, flags);
   7547     }
   7548 
   7549     public void setComponentEnabledSetting(ComponentName componentName,
   7550             int newState, int flags) {
   7551         setEnabledSetting(componentName.getPackageName(),
   7552                 componentName.getClassName(), newState, flags);
   7553     }
   7554 
   7555     private void setEnabledSetting(
   7556             final String packageName, String className, int newState, final int flags) {
   7557         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
   7558               || newState == COMPONENT_ENABLED_STATE_ENABLED
   7559               || newState == COMPONENT_ENABLED_STATE_DISABLED
   7560               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER)) {
   7561             throw new IllegalArgumentException("Invalid new component state: "
   7562                     + newState);
   7563         }
   7564         PackageSetting pkgSetting;
   7565         final int uid = Binder.getCallingUid();
   7566         final int permission = mContext.checkCallingPermission(
   7567                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
   7568         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
   7569         boolean sendNow = false;
   7570         boolean isApp = (className == null);
   7571         String componentName = isApp ? packageName : className;
   7572         int packageUid = -1;
   7573         ArrayList<String> components;
   7574 
   7575         // writer
   7576         synchronized (mPackages) {
   7577             pkgSetting = mSettings.mPackages.get(packageName);
   7578             if (pkgSetting == null) {
   7579                 if (className == null) {
   7580                     throw new IllegalArgumentException(
   7581                             "Unknown package: " + packageName);
   7582                 }
   7583                 throw new IllegalArgumentException(
   7584                         "Unknown component: " + packageName
   7585                         + "/" + className);
   7586             }
   7587             if (!allowedByPermission && (uid != pkgSetting.userId)) {
   7588                 throw new SecurityException(
   7589                         "Permission Denial: attempt to change component state from pid="
   7590                         + Binder.getCallingPid()
   7591                         + ", uid=" + uid + ", package uid=" + pkgSetting.userId);
   7592             }
   7593             if (className == null) {
   7594                 // We're dealing with an application/package level state change
   7595                 if (pkgSetting.enabled == newState) {
   7596                     // Nothing to do
   7597                     return;
   7598                 }
   7599                 pkgSetting.enabled = newState;
   7600                 pkgSetting.pkg.mSetEnabled = newState;
   7601             } else {
   7602                 // We're dealing with a component level state change
   7603                 switch (newState) {
   7604                 case COMPONENT_ENABLED_STATE_ENABLED:
   7605                     if (!pkgSetting.enableComponentLPw(className)) {
   7606                         return;
   7607                     }
   7608                     break;
   7609                 case COMPONENT_ENABLED_STATE_DISABLED:
   7610                     if (!pkgSetting.disableComponentLPw(className)) {
   7611                         return;
   7612                     }
   7613                     break;
   7614                 case COMPONENT_ENABLED_STATE_DEFAULT:
   7615                     if (!pkgSetting.restoreComponentLPw(className)) {
   7616                         return;
   7617                     }
   7618                     break;
   7619                 default:
   7620                     Slog.e(TAG, "Invalid new component state: " + newState);
   7621                     return;
   7622                 }
   7623             }
   7624             mSettings.writeLPr();
   7625             packageUid = pkgSetting.userId;
   7626             components = mPendingBroadcasts.get(packageName);
   7627             final boolean newPackage = components == null;
   7628             if (newPackage) {
   7629                 components = new ArrayList<String>();
   7630             }
   7631             if (!components.contains(componentName)) {
   7632                 components.add(componentName);
   7633             }
   7634             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
   7635                 sendNow = true;
   7636                 // Purge entry from pending broadcast list if another one exists already
   7637                 // since we are sending one right away.
   7638                 mPendingBroadcasts.remove(packageName);
   7639             } else {
   7640                 if (newPackage) {
   7641                     mPendingBroadcasts.put(packageName, components);
   7642                 }
   7643                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
   7644                     // Schedule a message
   7645                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
   7646                 }
   7647             }
   7648         }
   7649 
   7650         long callingId = Binder.clearCallingIdentity();
   7651         try {
   7652             if (sendNow) {
   7653                 sendPackageChangedBroadcast(packageName,
   7654                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
   7655             }
   7656         } finally {
   7657             Binder.restoreCallingIdentity(callingId);
   7658         }
   7659     }
   7660 
   7661     private void sendPackageChangedBroadcast(String packageName,
   7662             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
   7663         if (DEBUG_INSTALL)
   7664             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
   7665                     + componentNames);
   7666         Bundle extras = new Bundle(4);
   7667         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
   7668         String nameList[] = new String[componentNames.size()];
   7669         componentNames.toArray(nameList);
   7670         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
   7671         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
   7672         extras.putInt(Intent.EXTRA_UID, packageUid);
   7673         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null);
   7674     }
   7675 
   7676     public void setPackageStoppedState(String packageName, boolean stopped) {
   7677         final int uid = Binder.getCallingUid();
   7678         final int permission = mContext.checkCallingOrSelfPermission(
   7679                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
   7680         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
   7681         // writer
   7682         synchronized (mPackages) {
   7683             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
   7684                     uid)) {
   7685                 scheduleWriteStoppedPackagesLocked();
   7686             }
   7687         }
   7688     }
   7689 
   7690     public String getInstallerPackageName(String packageName) {
   7691         // reader
   7692         synchronized (mPackages) {
   7693             return mSettings.getInstallerPackageNameLPr(packageName);
   7694         }
   7695     }
   7696 
   7697     public int getApplicationEnabledSetting(String packageName) {
   7698         // reader
   7699         synchronized (mPackages) {
   7700             return mSettings.getApplicationEnabledSettingLPr(packageName);
   7701         }
   7702     }
   7703 
   7704     public int getComponentEnabledSetting(ComponentName componentName) {
   7705         // reader
   7706         synchronized (mPackages) {
   7707             return mSettings.getComponentEnabledSettingLPr(componentName);
   7708         }
   7709     }
   7710 
   7711     public void enterSafeMode() {
   7712         enforceSystemOrRoot("Only the system can request entering safe mode");
   7713 
   7714         if (!mSystemReady) {
   7715             mSafeMode = true;
   7716         }
   7717     }
   7718 
   7719     public void systemReady() {
   7720         mSystemReady = true;
   7721 
   7722         // Read the compatibilty setting when the system is ready.
   7723         boolean compatibilityModeEnabled = android.provider.Settings.System.getInt(
   7724                 mContext.getContentResolver(),
   7725                 android.provider.Settings.System.COMPATIBILITY_MODE, 1) == 1;
   7726         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
   7727         if (DEBUG_SETTINGS) {
   7728             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
   7729         }
   7730     }
   7731 
   7732     public boolean isSafeMode() {
   7733         return mSafeMode;
   7734     }
   7735 
   7736     public boolean hasSystemUidErrors() {
   7737         return mHasSystemUidErrors;
   7738     }
   7739 
   7740     static String arrayToString(int[] array) {
   7741         StringBuffer buf = new StringBuffer(128);
   7742         buf.append('[');
   7743         if (array != null) {
   7744             for (int i=0; i<array.length; i++) {
   7745                 if (i > 0) buf.append(", ");
   7746                 buf.append(array[i]);
   7747             }
   7748         }
   7749         buf.append(']');
   7750         return buf.toString();
   7751     }
   7752 
   7753     static class DumpState {
   7754         public static final int DUMP_LIBS = 1 << 0;
   7755 
   7756         public static final int DUMP_FEATURES = 1 << 1;
   7757 
   7758         public static final int DUMP_RESOLVERS = 1 << 2;
   7759 
   7760         public static final int DUMP_PERMISSIONS = 1 << 3;
   7761 
   7762         public static final int DUMP_PACKAGES = 1 << 4;
   7763 
   7764         public static final int DUMP_SHARED_USERS = 1 << 5;
   7765 
   7766         public static final int DUMP_MESSAGES = 1 << 6;
   7767 
   7768         public static final int DUMP_PROVIDERS = 1 << 7;
   7769 
   7770         public static final int DUMP_VERIFIERS = 1 << 8;
   7771 
   7772         public static final int OPTION_SHOW_FILTERS = 1 << 0;
   7773 
   7774         private int mTypes;
   7775 
   7776         private int mOptions;
   7777 
   7778         private boolean mTitlePrinted;
   7779 
   7780         private SharedUserSetting mSharedUser;
   7781 
   7782         public boolean isDumping(int type) {
   7783             if (mTypes == 0) {
   7784                 return true;
   7785             }
   7786 
   7787             return (mTypes & type) != 0;
   7788         }
   7789 
   7790         public void setDump(int type) {
   7791             mTypes |= type;
   7792         }
   7793 
   7794         public boolean isOptionEnabled(int option) {
   7795             return (mOptions & option) != 0;
   7796         }
   7797 
   7798         public void setOptionEnabled(int option) {
   7799             mOptions |= option;
   7800         }
   7801 
   7802         public boolean onTitlePrinted() {
   7803             final boolean printed = mTitlePrinted;
   7804             mTitlePrinted = true;
   7805             return printed;
   7806         }
   7807 
   7808         public boolean getTitlePrinted() {
   7809             return mTitlePrinted;
   7810         }
   7811 
   7812         public void setTitlePrinted(boolean enabled) {
   7813             mTitlePrinted = enabled;
   7814         }
   7815 
   7816         public SharedUserSetting getSharedUser() {
   7817             return mSharedUser;
   7818         }
   7819 
   7820         public void setSharedUser(SharedUserSetting user) {
   7821             mSharedUser = user;
   7822         }
   7823     }
   7824 
   7825     @Override
   7826     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   7827         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
   7828                 != PackageManager.PERMISSION_GRANTED) {
   7829             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   7830                     + Binder.getCallingPid()
   7831                     + ", uid=" + Binder.getCallingUid()
   7832                     + " without permission "
   7833                     + android.Manifest.permission.DUMP);
   7834             return;
   7835         }
   7836 
   7837         DumpState dumpState = new DumpState();
   7838 
   7839         String packageName = null;
   7840 
   7841         int opti = 0;
   7842         while (opti < args.length) {
   7843             String opt = args[opti];
   7844             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   7845                 break;
   7846             }
   7847             opti++;
   7848             if ("-a".equals(opt)) {
   7849                 // Right now we only know how to print all.
   7850             } else if ("-h".equals(opt)) {
   7851                 pw.println("Package manager dump options:");
   7852                 pw.println("  [-h] [-f] [cmd] ...");
   7853                 pw.println("    -f: print details of intent filters");
   7854                 pw.println("    -h: print this help");
   7855                 pw.println("  cmd may be one of:");
   7856                 pw.println("    l[ibraries]: list known shared libraries");
   7857                 pw.println("    f[ibraries]: list device features");
   7858                 pw.println("    r[esolvers]: dump intent resolvers");
   7859                 pw.println("    perm[issions]: dump permissions");
   7860                 pw.println("    prov[iders]: dump content providers");
   7861                 pw.println("    p[ackages]: dump installed packages");
   7862                 pw.println("    s[hared-users]: dump shared user IDs");
   7863                 pw.println("    m[essages]: print collected runtime messages");
   7864                 pw.println("    v[erifiers]: print package verifier info");
   7865                 pw.println("    <package.name>: info about given package");
   7866                 return;
   7867             } else if ("-f".equals(opt)) {
   7868                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
   7869             } else {
   7870                 pw.println("Unknown argument: " + opt + "; use -h for help");
   7871             }
   7872         }
   7873 
   7874         // Is the caller requesting to dump a particular piece of data?
   7875         if (opti < args.length) {
   7876             String cmd = args[opti];
   7877             opti++;
   7878             // Is this a package name?
   7879             if ("android".equals(cmd) || cmd.contains(".")) {
   7880                 packageName = cmd;
   7881             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
   7882                 dumpState.setDump(DumpState.DUMP_LIBS);
   7883             } else if ("f".equals(cmd) || "features".equals(cmd)) {
   7884                 dumpState.setDump(DumpState.DUMP_FEATURES);
   7885             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
   7886                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
   7887             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
   7888                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
   7889             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
   7890                 dumpState.setDump(DumpState.DUMP_PACKAGES);
   7891             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
   7892                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
   7893             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
   7894                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
   7895             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
   7896                 dumpState.setDump(DumpState.DUMP_MESSAGES);
   7897             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
   7898                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
   7899             }
   7900         }
   7901 
   7902         // reader
   7903         synchronized (mPackages) {
   7904             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
   7905                 if (dumpState.onTitlePrinted())
   7906                     pw.println(" ");
   7907                 pw.println("Verifiers:");
   7908                 pw.print("  Required: ");
   7909                 pw.print(mRequiredVerifierPackage);
   7910                 pw.print(" (uid=");
   7911                 pw.print(getPackageUid(mRequiredVerifierPackage));
   7912                 pw.println(")");
   7913             }
   7914 
   7915             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
   7916                 if (dumpState.onTitlePrinted())
   7917                     pw.println(" ");
   7918                 pw.println("Libraries:");
   7919                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
   7920                 while (it.hasNext()) {
   7921                     String name = it.next();
   7922                     pw.print("  ");
   7923                     pw.print(name);
   7924                     pw.print(" -> ");
   7925                     pw.println(mSharedLibraries.get(name));
   7926                 }
   7927             }
   7928 
   7929             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
   7930                 if (dumpState.onTitlePrinted())
   7931                     pw.println(" ");
   7932                 pw.println("Features:");
   7933                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
   7934                 while (it.hasNext()) {
   7935                     String name = it.next();
   7936                     pw.print("  ");
   7937                     pw.println(name);
   7938                 }
   7939             }
   7940 
   7941             if (dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
   7942                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
   7943                         : "Activity Resolver Table:", "  ", packageName,
   7944                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
   7945                     dumpState.setTitlePrinted(true);
   7946                 }
   7947                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
   7948                         : "Receiver Resolver Table:", "  ", packageName,
   7949                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
   7950                     dumpState.setTitlePrinted(true);
   7951                 }
   7952                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
   7953                         : "Service Resolver Table:", "  ", packageName,
   7954                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
   7955                     dumpState.setTitlePrinted(true);
   7956                 }
   7957                 if (mSettings.mPreferredActivities.dump(pw,
   7958                         dumpState.getTitlePrinted() ? "\nPreferred Activities:"
   7959                             : "Preferred Activities:", "  ",
   7960                         packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
   7961                     dumpState.setTitlePrinted(true);
   7962                 }
   7963             }
   7964 
   7965             if (dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
   7966                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
   7967             }
   7968 
   7969             if (dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
   7970                 boolean printedSomething = false;
   7971                 for (PackageParser.Provider p : mProvidersByComponent.values()) {
   7972                     if (packageName != null && !packageName.equals(p.info.packageName)) {
   7973                         continue;
   7974                     }
   7975                     if (!printedSomething) {
   7976                         if (dumpState.onTitlePrinted())
   7977                             pw.println(" ");
   7978                         pw.println("Registered ContentProviders:");
   7979                         printedSomething = true;
   7980                     }
   7981                     pw.print("  "); pw.print(p.getComponentShortName()); pw.println(":");
   7982                     pw.print("    "); pw.println(p.toString());
   7983                 }
   7984                 printedSomething = false;
   7985                 for (Map.Entry<String, PackageParser.Provider> entry : mProviders.entrySet()) {
   7986                     PackageParser.Provider p = entry.getValue();
   7987                     if (packageName != null && !packageName.equals(p.info.packageName)) {
   7988                         continue;
   7989                     }
   7990                     if (!printedSomething) {
   7991                         if (dumpState.onTitlePrinted())
   7992                             pw.println(" ");
   7993                         pw.println("ContentProvider Authorities:");
   7994                         printedSomething = true;
   7995                     }
   7996                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
   7997                     pw.print("    "); pw.println(p.toString());
   7998                 }
   7999             }
   8000 
   8001             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
   8002                 mSettings.dumpPackagesLPr(pw, packageName, dumpState);
   8003             }
   8004 
   8005             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
   8006                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
   8007             }
   8008 
   8009             if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
   8010                 if (dumpState.onTitlePrinted())
   8011                     pw.println(" ");
   8012                 mSettings.dumpReadMessagesLPr(pw, dumpState);
   8013 
   8014                 pw.println(" ");
   8015                 pw.println("Package warning messages:");
   8016                 final File fname = getSettingsProblemFile();
   8017                 FileInputStream in = null;
   8018                 try {
   8019                     in = new FileInputStream(fname);
   8020                     final int avail = in.available();
   8021                     final byte[] data = new byte[avail];
   8022                     in.read(data);
   8023                     pw.print(new String(data));
   8024                 } catch (FileNotFoundException e) {
   8025                 } catch (IOException e) {
   8026                 } finally {
   8027                     if (in != null) {
   8028                         try {
   8029                             in.close();
   8030                         } catch (IOException e) {
   8031                         }
   8032                     }
   8033                 }
   8034             }
   8035         }
   8036     }
   8037 
   8038     // ------- apps on sdcard specific code -------
   8039     static final boolean DEBUG_SD_INSTALL = false;
   8040 
   8041     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
   8042 
   8043     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
   8044 
   8045     private boolean mMediaMounted = false;
   8046 
   8047     private String getEncryptKey() {
   8048         try {
   8049             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
   8050                     SD_ENCRYPTION_KEYSTORE_NAME);
   8051             if (sdEncKey == null) {
   8052                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
   8053                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
   8054                 if (sdEncKey == null) {
   8055                     Slog.e(TAG, "Failed to create encryption keys");
   8056                     return null;
   8057                 }
   8058             }
   8059             return sdEncKey;
   8060         } catch (NoSuchAlgorithmException nsae) {
   8061             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
   8062             return null;
   8063         } catch (IOException ioe) {
   8064             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
   8065             return null;
   8066         }
   8067 
   8068     }
   8069 
   8070     /* package */static String getTempContainerId() {
   8071         int tmpIdx = 1;
   8072         String list[] = PackageHelper.getSecureContainerList();
   8073         if (list != null) {
   8074             for (final String name : list) {
   8075                 // Ignore null and non-temporary container entries
   8076                 if (name == null || !name.startsWith(mTempContainerPrefix)) {
   8077                     continue;
   8078                 }
   8079 
   8080                 String subStr = name.substring(mTempContainerPrefix.length());
   8081                 try {
   8082                     int cid = Integer.parseInt(subStr);
   8083                     if (cid >= tmpIdx) {
   8084                         tmpIdx = cid + 1;
   8085                     }
   8086                 } catch (NumberFormatException e) {
   8087                 }
   8088             }
   8089         }
   8090         return mTempContainerPrefix + tmpIdx;
   8091     }
   8092 
   8093     /*
   8094      * Update media status on PackageManager.
   8095      */
   8096     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
   8097         int callingUid = Binder.getCallingUid();
   8098         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   8099             throw new SecurityException("Media status can only be updated by the system");
   8100         }
   8101         // reader; this apparently protects mMediaMounted, but should probably
   8102         // be a different lock in that case.
   8103         synchronized (mPackages) {
   8104             Log.i(TAG, "Updating external media status from "
   8105                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
   8106                     + (mediaStatus ? "mounted" : "unmounted"));
   8107             if (DEBUG_SD_INSTALL)
   8108                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
   8109                         + ", mMediaMounted=" + mMediaMounted);
   8110             if (mediaStatus == mMediaMounted) {
   8111                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
   8112                         : 0, -1);
   8113                 mHandler.sendMessage(msg);
   8114                 return;
   8115             }
   8116             mMediaMounted = mediaStatus;
   8117         }
   8118         // Queue up an async operation since the package installation may take a
   8119         // little while.
   8120         mHandler.post(new Runnable() {
   8121             public void run() {
   8122                 // TODO fix this; this does nothing.
   8123                 mHandler.removeCallbacks(this);
   8124                 updateExternalMediaStatusInner(mediaStatus, reportStatus);
   8125             }
   8126         });
   8127     }
   8128 
   8129     /*
   8130      * Collect information of applications on external media, map them against
   8131      * existing containers and update information based on current mount status.
   8132      * Please note that we always have to report status if reportStatus has been
   8133      * set to true especially when unloading packages.
   8134      */
   8135     private void updateExternalMediaStatusInner(boolean mediaStatus, boolean reportStatus) {
   8136         // Collection of uids
   8137         int uidArr[] = null;
   8138         // Collection of stale containers
   8139         HashSet<String> removeCids = new HashSet<String>();
   8140         // Collection of packages on external media with valid containers.
   8141         HashMap<SdInstallArgs, String> processCids = new HashMap<SdInstallArgs, String>();
   8142         // Get list of secure containers.
   8143         final String list[] = PackageHelper.getSecureContainerList();
   8144         if (list == null || list.length == 0) {
   8145             Log.i(TAG, "No secure containers on sdcard");
   8146         } else {
   8147             // Process list of secure containers and categorize them
   8148             // as active or stale based on their package internal state.
   8149             int uidList[] = new int[list.length];
   8150             int num = 0;
   8151             // reader
   8152             synchronized (mPackages) {
   8153                 for (String cid : list) {
   8154                     SdInstallArgs args = new SdInstallArgs(cid);
   8155                     if (DEBUG_SD_INSTALL)
   8156                         Log.i(TAG, "Processing container " + cid);
   8157                     String pkgName = args.getPackageName();
   8158                     if (pkgName == null) {
   8159                         if (DEBUG_SD_INSTALL)
   8160                             Log.i(TAG, "Container : " + cid + " stale");
   8161                         removeCids.add(cid);
   8162                         continue;
   8163                     }
   8164                     if (DEBUG_SD_INSTALL)
   8165                         Log.i(TAG, "Looking for pkg : " + pkgName);
   8166                     PackageSetting ps = mSettings.mPackages.get(pkgName);
   8167                     // The package status is changed only if the code path
   8168                     // matches between settings and the container id.
   8169                     if (ps != null && ps.codePathString != null
   8170                             && ps.codePathString.equals(args.getCodePath())) {
   8171                         if (DEBUG_SD_INSTALL)
   8172                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
   8173                                     + " at code path: " + ps.codePathString);
   8174                         // We do have a valid package installed on sdcard
   8175                         processCids.put(args, ps.codePathString);
   8176                         int uid = ps.userId;
   8177                         if (uid != -1) {
   8178                             uidList[num++] = uid;
   8179                         }
   8180                     } else {
   8181                         // Stale container on sdcard. Just delete
   8182                         if (DEBUG_SD_INSTALL)
   8183                             Log.i(TAG, "Container : " + cid + " stale");
   8184                         removeCids.add(cid);
   8185                     }
   8186                 }
   8187             }
   8188 
   8189             if (num > 0) {
   8190                 // Sort uid list
   8191                 Arrays.sort(uidList, 0, num);
   8192                 // Throw away duplicates
   8193                 uidArr = new int[num];
   8194                 uidArr[0] = uidList[0];
   8195                 int di = 0;
   8196                 for (int i = 1; i < num; i++) {
   8197                     if (uidList[i - 1] != uidList[i]) {
   8198                         uidArr[di++] = uidList[i];
   8199                     }
   8200                 }
   8201             }
   8202         }
   8203         // Process packages with valid entries.
   8204         if (mediaStatus) {
   8205             if (DEBUG_SD_INSTALL)
   8206                 Log.i(TAG, "Loading packages");
   8207             loadMediaPackages(processCids, uidArr, removeCids);
   8208             startCleaningPackages();
   8209         } else {
   8210             if (DEBUG_SD_INSTALL)
   8211                 Log.i(TAG, "Unloading packages");
   8212             unloadMediaPackages(processCids, uidArr, reportStatus);
   8213         }
   8214     }
   8215 
   8216    private void sendResourcesChangedBroadcast(boolean mediaStatus, ArrayList<String> pkgList,
   8217             int uidArr[], IIntentReceiver finishedReceiver) {
   8218         int size = pkgList.size();
   8219         if (size > 0) {
   8220             // Send broadcasts here
   8221             Bundle extras = new Bundle();
   8222             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
   8223                     .toArray(new String[size]));
   8224             if (uidArr != null) {
   8225                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
   8226             }
   8227             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
   8228                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
   8229             sendPackageBroadcast(action, null, extras, null, finishedReceiver);
   8230         }
   8231     }
   8232 
   8233    /*
   8234      * Look at potentially valid container ids from processCids If package
   8235      * information doesn't match the one on record or package scanning fails,
   8236      * the cid is added to list of removeCids. We currently don't delete stale
   8237      * containers.
   8238      */
   8239    private void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[],
   8240             HashSet<String> removeCids) {
   8241         ArrayList<String> pkgList = new ArrayList<String>();
   8242         Set<SdInstallArgs> keys = processCids.keySet();
   8243         boolean doGc = false;
   8244         for (SdInstallArgs args : keys) {
   8245             String codePath = processCids.get(args);
   8246             if (DEBUG_SD_INSTALL)
   8247                 Log.i(TAG, "Loading container : " + args.cid);
   8248             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   8249             try {
   8250                 // Make sure there are no container errors first.
   8251                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
   8252                     Slog.e(TAG, "Failed to mount cid : " + args.cid
   8253                             + " when installing from sdcard");
   8254                     continue;
   8255                 }
   8256                 // Check code path here.
   8257                 if (codePath == null || !codePath.equals(args.getCodePath())) {
   8258                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
   8259                             + " does not match one in settings " + codePath);
   8260                     continue;
   8261                 }
   8262                 // Parse package
   8263                 int parseFlags = PackageParser.PARSE_ON_SDCARD | mDefParseFlags;
   8264                 doGc = true;
   8265                 synchronized (mInstallLock) {
   8266                     final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags,
   8267                             0, 0);
   8268                     // Scan the package
   8269                     if (pkg != null) {
   8270                         /*
   8271                          * TODO why is the lock being held? doPostInstall is
   8272                          * called in other places without the lock. This needs
   8273                          * to be straightened out.
   8274                          */
   8275                         // writer
   8276                         synchronized (mPackages) {
   8277                             retCode = PackageManager.INSTALL_SUCCEEDED;
   8278                             pkgList.add(pkg.packageName);
   8279                             // Post process args
   8280                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED);
   8281                         }
   8282                     } else {
   8283                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
   8284                     }
   8285                 }
   8286 
   8287             } finally {
   8288                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
   8289                     // Don't destroy container here. Wait till gc clears things
   8290                     // up.
   8291                     removeCids.add(args.cid);
   8292                 }
   8293             }
   8294         }
   8295         // writer
   8296         synchronized (mPackages) {
   8297             // If the platform SDK has changed since the last time we booted,
   8298             // we need to re-grant app permission to catch any new ones that
   8299             // appear. This is really a hack, and means that apps can in some
   8300             // cases get permissions that the user didn't initially explicitly
   8301             // allow... it would be nice to have some better way to handle
   8302             // this situation.
   8303             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
   8304             if (regrantPermissions)
   8305                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
   8306                         + mSdkVersion + "; regranting permissions for external storage");
   8307             mSettings.mExternalSdkPlatform = mSdkVersion;
   8308 
   8309             // Make sure group IDs have been assigned, and any permission
   8310             // changes in other apps are accounted for
   8311             updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions);
   8312             // can downgrade to reader
   8313             // Persist settings
   8314             mSettings.writeLPr();
   8315         }
   8316         // Send a broadcast to let everyone know we are done processing
   8317         if (pkgList.size() > 0) {
   8318             sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
   8319         }
   8320         // Force gc to avoid any stale parser references that we might have.
   8321         if (doGc) {
   8322             Runtime.getRuntime().gc();
   8323         }
   8324         // List stale containers and destroy stale temporary containers.
   8325         if (removeCids != null) {
   8326             for (String cid : removeCids) {
   8327                 if (cid.startsWith(mTempContainerPrefix)) {
   8328                     Log.i(TAG, "Destroying stale temporary container " + cid);
   8329                     PackageHelper.destroySdDir(cid);
   8330                 } else {
   8331                     Log.w(TAG, "Container " + cid + " is stale");
   8332                }
   8333            }
   8334         }
   8335     }
   8336 
   8337    /*
   8338      * Utility method to unload a list of specified containers
   8339      */
   8340     private void unloadAllContainers(Set<SdInstallArgs> cidArgs) {
   8341         // Just unmount all valid containers.
   8342         for (SdInstallArgs arg : cidArgs) {
   8343             synchronized (mInstallLock) {
   8344                 arg.doPostDeleteLI(false);
   8345            }
   8346        }
   8347    }
   8348 
   8349     /*
   8350      * Unload packages mounted on external media. This involves deleting package
   8351      * data from internal structures, sending broadcasts about diabled packages,
   8352      * gc'ing to free up references, unmounting all secure containers
   8353      * corresponding to packages on external media, and posting a
   8354      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
   8355      * that we always have to post this message if status has been requested no
   8356      * matter what.
   8357      */
   8358     private void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[],
   8359             final boolean reportStatus) {
   8360         if (DEBUG_SD_INSTALL)
   8361             Log.i(TAG, "unloading media packages");
   8362         ArrayList<String> pkgList = new ArrayList<String>();
   8363         ArrayList<SdInstallArgs> failedList = new ArrayList<SdInstallArgs>();
   8364         final Set<SdInstallArgs> keys = processCids.keySet();
   8365         for (SdInstallArgs args : keys) {
   8366             String pkgName = args.getPackageName();
   8367             if (DEBUG_SD_INSTALL)
   8368                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
   8369             // Delete package internally
   8370             PackageRemovedInfo outInfo = new PackageRemovedInfo();
   8371             synchronized (mInstallLock) {
   8372                 boolean res = deletePackageLI(pkgName, false, PackageManager.DONT_DELETE_DATA,
   8373                         outInfo, false);
   8374                 if (res) {
   8375                     pkgList.add(pkgName);
   8376                 } else {
   8377                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
   8378                     failedList.add(args);
   8379                 }
   8380             }
   8381         }
   8382 
   8383         // reader
   8384         synchronized (mPackages) {
   8385             // We didn't update the settings after removing each package;
   8386             // write them now for all packages.
   8387             mSettings.writeLPr();
   8388         }
   8389 
   8390         // We have to absolutely send UPDATED_MEDIA_STATUS only
   8391         // after confirming that all the receivers processed the ordered
   8392         // broadcast when packages get disabled, force a gc to clean things up.
   8393         // and unload all the containers.
   8394         if (pkgList.size() > 0) {
   8395             sendResourcesChangedBroadcast(false, pkgList, uidArr, new IIntentReceiver.Stub() {
   8396                 public void performReceive(Intent intent, int resultCode, String data,
   8397                         Bundle extras, boolean ordered, boolean sticky) throws RemoteException {
   8398                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
   8399                             reportStatus ? 1 : 0, 1, keys);
   8400                     mHandler.sendMessage(msg);
   8401                 }
   8402             });
   8403         } else {
   8404             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
   8405                     keys);
   8406             mHandler.sendMessage(msg);
   8407         }
   8408     }
   8409 
   8410     public void movePackage(final String packageName, final IPackageMoveObserver observer,
   8411             final int flags) {
   8412         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
   8413         int returnCode = PackageManager.MOVE_SUCCEEDED;
   8414         int currFlags = 0;
   8415         int newFlags = 0;
   8416         // reader
   8417         synchronized (mPackages) {
   8418             PackageParser.Package pkg = mPackages.get(packageName);
   8419             if (pkg == null) {
   8420                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
   8421             } else {
   8422                 // Disable moving fwd locked apps and system packages
   8423                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
   8424                     Slog.w(TAG, "Cannot move system application");
   8425                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
   8426                 } else if (pkg.applicationInfo != null && isForwardLocked(pkg)) {
   8427                     Slog.w(TAG, "Cannot move forward locked app.");
   8428                     returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
   8429                 } else if (pkg.mOperationPending) {
   8430                     Slog.w(TAG, "Attempt to move package which has pending operations");
   8431                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
   8432                 } else {
   8433                     // Find install location first
   8434                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
   8435                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
   8436                         Slog.w(TAG, "Ambigous flags specified for move location.");
   8437                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
   8438                     } else {
   8439                         newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL
   8440                                 : PackageManager.INSTALL_INTERNAL;
   8441                         currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL
   8442                                 : PackageManager.INSTALL_INTERNAL;
   8443                         if (newFlags == currFlags) {
   8444                             Slog.w(TAG, "No move required. Trying to move to same location");
   8445                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
   8446                         }
   8447                     }
   8448                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
   8449                         pkg.mOperationPending = true;
   8450                     }
   8451                 }
   8452             }
   8453 
   8454             /*
   8455              * TODO this next block probably shouldn't be inside the lock. We
   8456              * can't guarantee these won't change after this is fired off
   8457              * anyway.
   8458              */
   8459             if (returnCode != PackageManager.MOVE_SUCCEEDED) {
   8460                 processPendingMove(new MoveParams(null, observer, 0, packageName, null), returnCode);
   8461             } else {
   8462                 Message msg = mHandler.obtainMessage(INIT_COPY);
   8463                 InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir,
   8464                         pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir);
   8465                 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName,
   8466                         pkg.applicationInfo.dataDir);
   8467                 msg.obj = mp;
   8468                 mHandler.sendMessage(msg);
   8469             }
   8470         }
   8471     }
   8472 
   8473     private void processPendingMove(final MoveParams mp, final int currentStatus) {
   8474         // Queue up an async operation since the package deletion may take a
   8475         // little while.
   8476         mHandler.post(new Runnable() {
   8477             public void run() {
   8478                 // TODO fix this; this does nothing.
   8479                 mHandler.removeCallbacks(this);
   8480                 int returnCode = currentStatus;
   8481                 if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
   8482                     int uidArr[] = null;
   8483                     ArrayList<String> pkgList = null;
   8484                     synchronized (mPackages) {
   8485                         PackageParser.Package pkg = mPackages.get(mp.packageName);
   8486                         if (pkg == null) {
   8487                             Slog.w(TAG, " Package " + mp.packageName
   8488                                     + " doesn't exist. Aborting move");
   8489                             returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
   8490                         } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
   8491                             Slog.w(TAG, "Package " + mp.packageName + " code path changed from "
   8492                                     + mp.srcArgs.getCodePath() + " to "
   8493                                     + pkg.applicationInfo.sourceDir
   8494                                     + " Aborting move and returning error");
   8495                             returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
   8496                         } else {
   8497                             uidArr = new int[] {
   8498                                 pkg.applicationInfo.uid
   8499                             };
   8500                             pkgList = new ArrayList<String>();
   8501                             pkgList.add(mp.packageName);
   8502                         }
   8503                     }
   8504                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
   8505                         // Send resources unavailable broadcast
   8506                         sendResourcesChangedBroadcast(false, pkgList, uidArr, null);
   8507                         // Update package code and resource paths
   8508                         synchronized (mInstallLock) {
   8509                             synchronized (mPackages) {
   8510                                 PackageParser.Package pkg = mPackages.get(mp.packageName);
   8511                                 // Recheck for package again.
   8512                                 if (pkg == null) {
   8513                                     Slog.w(TAG, " Package " + mp.packageName
   8514                                             + " doesn't exist. Aborting move");
   8515                                     returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
   8516                                 } else if (!mp.srcArgs.getCodePath().equals(
   8517                                         pkg.applicationInfo.sourceDir)) {
   8518                                     Slog.w(TAG, "Package " + mp.packageName
   8519                                             + " code path changed from " + mp.srcArgs.getCodePath()
   8520                                             + " to " + pkg.applicationInfo.sourceDir
   8521                                             + " Aborting move and returning error");
   8522                                     returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
   8523                                 } else {
   8524                                     final String oldCodePath = pkg.mPath;
   8525                                     final String newCodePath = mp.targetArgs.getCodePath();
   8526                                     final String newResPath = mp.targetArgs.getResourcePath();
   8527                                     final String newNativePath = mp.targetArgs
   8528                                             .getNativeLibraryPath();
   8529 
   8530                                     if ((mp.flags & PackageManager.INSTALL_EXTERNAL) == 0) {
   8531                                         if (mInstaller
   8532                                                 .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) {
   8533                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
   8534                                         } else {
   8535                                             NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File(
   8536                                                     newCodePath), new File(newNativePath));
   8537                                         }
   8538                                     } else {
   8539                                         if (mInstaller.linkNativeLibraryDirectory(
   8540                                                 pkg.applicationInfo.dataDir, newNativePath) < 0) {
   8541                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
   8542                                         }
   8543                                     }
   8544 
   8545                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
   8546                                         pkg.mPath = newCodePath;
   8547                                         // Move dex files around
   8548                                         if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) {
   8549                                             // Moving of dex files failed. Set
   8550                                             // error code and abort move.
   8551                                             pkg.mPath = pkg.mScanPath;
   8552                                             returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
   8553                                         }
   8554                                     }
   8555 
   8556                                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
   8557                                         pkg.mScanPath = newCodePath;
   8558                                         pkg.applicationInfo.sourceDir = newCodePath;
   8559                                         pkg.applicationInfo.publicSourceDir = newResPath;
   8560                                         pkg.applicationInfo.nativeLibraryDir = newNativePath;
   8561                                         PackageSetting ps = (PackageSetting) pkg.mExtras;
   8562                                         ps.codePath = new File(pkg.applicationInfo.sourceDir);
   8563                                         ps.codePathString = ps.codePath.getPath();
   8564                                         ps.resourcePath = new File(
   8565                                                 pkg.applicationInfo.publicSourceDir);
   8566                                         ps.resourcePathString = ps.resourcePath.getPath();
   8567                                         ps.nativeLibraryPathString = newNativePath;
   8568                                         // Set the application info flag
   8569                                         // correctly.
   8570                                         if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
   8571                                             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
   8572                                         } else {
   8573                                             pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
   8574                                         }
   8575                                         ps.setFlags(pkg.applicationInfo.flags);
   8576                                         mAppDirs.remove(oldCodePath);
   8577                                         mAppDirs.put(newCodePath, pkg);
   8578                                         // Persist settings
   8579                                         mSettings.writeLPr();
   8580                                     }
   8581                                 }
   8582                             }
   8583                         }
   8584                         // Send resources available broadcast
   8585                         sendResourcesChangedBroadcast(true, pkgList, uidArr, null);
   8586                     }
   8587                 }
   8588                 if (returnCode != PackageManager.MOVE_SUCCEEDED) {
   8589                     // Clean up failed installation
   8590                     if (mp.targetArgs != null) {
   8591                         mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR);
   8592                     }
   8593                 } else {
   8594                     // Force a gc to clear things up.
   8595                     Runtime.getRuntime().gc();
   8596                     // Delete older code
   8597                     synchronized (mInstallLock) {
   8598                         mp.srcArgs.doPostDeleteLI(true);
   8599                     }
   8600                 }
   8601 
   8602                 // Allow more operations on this file if we didn't fail because
   8603                 // an operation was already pending for this package.
   8604                 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) {
   8605                     synchronized (mPackages) {
   8606                         PackageParser.Package pkg = mPackages.get(mp.packageName);
   8607                         if (pkg != null) {
   8608                             pkg.mOperationPending = false;
   8609                        }
   8610                    }
   8611                 }
   8612 
   8613                 IPackageMoveObserver observer = mp.observer;
   8614                 if (observer != null) {
   8615                     try {
   8616                         observer.packageMoved(mp.packageName, returnCode);
   8617                     } catch (RemoteException e) {
   8618                         Log.i(TAG, "Observer no longer exists.");
   8619                     }
   8620                 }
   8621             }
   8622         });
   8623     }
   8624 
   8625     public boolean setInstallLocation(int loc) {
   8626         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
   8627                 null);
   8628         if (getInstallLocation() == loc) {
   8629             return true;
   8630         }
   8631         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
   8632                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
   8633             android.provider.Settings.System.putInt(mContext.getContentResolver(),
   8634                     android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION, loc);
   8635             return true;
   8636         }
   8637         return false;
   8638    }
   8639 
   8640     public int getInstallLocation() {
   8641         return android.provider.Settings.System.getInt(mContext.getContentResolver(),
   8642                 android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION,
   8643                 PackageHelper.APP_INSTALL_AUTO);
   8644     }
   8645 
   8646     public UserInfo createUser(String name, int flags) {
   8647         // TODO(kroot): Add a real permission for creating users
   8648         enforceSystemOrRoot("Only the system can create users");
   8649 
   8650         // TODO(kroot): fix this API
   8651         UserInfo userInfo = mUserManager.createUser(name, flags, new ArrayList<ApplicationInfo>());
   8652         return userInfo;
   8653     }
   8654 
   8655     public boolean removeUser(int userId) {
   8656         // TODO(kroot): Add a real permission for removing users
   8657         enforceSystemOrRoot("Only the system can remove users");
   8658 
   8659         if (userId == 0) {
   8660             return false;
   8661         }
   8662         mUserManager.removeUser(userId);
   8663         return true;
   8664     }
   8665 
   8666     @Override
   8667     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
   8668         mContext.enforceCallingOrSelfPermission(
   8669                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   8670                 "Only package verification agents can read the verifier device identity");
   8671 
   8672         synchronized (mPackages) {
   8673             return mSettings.getVerifierDeviceIdentityLPw();
   8674         }
   8675     }
   8676 }
   8677