Home | History | Annotate | Download | only in server
      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;
     18 
     19 import com.android.internal.app.IMediaContainerService;
     20 import com.android.internal.app.ResolverActivity;
     21 import com.android.internal.content.NativeLibraryHelper;
     22 import com.android.internal.content.PackageHelper;
     23 import com.android.internal.util.FastXmlSerializer;
     24 import com.android.internal.util.JournaledFile;
     25 import com.android.internal.util.XmlUtils;
     26 
     27 import org.xmlpull.v1.XmlPullParser;
     28 import org.xmlpull.v1.XmlPullParserException;
     29 import org.xmlpull.v1.XmlSerializer;
     30 
     31 import android.app.ActivityManagerNative;
     32 import android.app.IActivityManager;
     33 import android.app.admin.IDevicePolicyManager;
     34 import android.app.backup.IBackupManager;
     35 import android.content.Context;
     36 import android.content.ComponentName;
     37 import android.content.IIntentReceiver;
     38 import android.content.Intent;
     39 import android.content.IntentFilter;
     40 import android.content.IntentSender;
     41 import android.content.ServiceConnection;
     42 import android.content.IntentSender.SendIntentException;
     43 import android.content.pm.ActivityInfo;
     44 import android.content.pm.ApplicationInfo;
     45 import android.content.pm.ComponentInfo;
     46 import android.content.pm.FeatureInfo;
     47 import android.content.pm.IPackageDataObserver;
     48 import android.content.pm.IPackageDeleteObserver;
     49 import android.content.pm.IPackageInstallObserver;
     50 import android.content.pm.IPackageManager;
     51 import android.content.pm.IPackageMoveObserver;
     52 import android.content.pm.IPackageStatsObserver;
     53 import android.content.pm.InstrumentationInfo;
     54 import android.content.pm.PackageInfo;
     55 import android.content.pm.PackageInfoLite;
     56 import android.content.pm.PackageManager;
     57 import android.content.pm.PackageStats;
     58 import android.content.pm.ParceledListSlice;
     59 
     60 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
     61 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
     62 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
     63 import android.content.pm.PackageParser;
     64 import android.content.pm.PermissionInfo;
     65 import android.content.pm.PermissionGroupInfo;
     66 import android.content.pm.ProviderInfo;
     67 import android.content.pm.ResolveInfo;
     68 import android.content.pm.ServiceInfo;
     69 import android.content.pm.Signature;
     70 import android.net.Uri;
     71 import android.os.Binder;
     72 import android.os.Build;
     73 import android.os.Bundle;
     74 import android.os.Debug;
     75 import android.os.HandlerThread;
     76 import android.os.IBinder;
     77 import android.os.Looper;
     78 import android.os.Message;
     79 import android.os.Parcel;
     80 import android.os.Parcelable;
     81 import android.os.RemoteException;
     82 import android.os.Environment;
     83 import android.os.FileObserver;
     84 import android.os.FileUtils;
     85 import android.os.Handler;
     86 import android.os.ParcelFileDescriptor;
     87 import android.os.Process;
     88 import android.os.ServiceManager;
     89 import android.os.SystemClock;
     90 import android.os.SystemProperties;
     91 import android.provider.Settings;
     92 import android.security.SystemKeyStore;
     93 import android.util.*;
     94 import android.view.Display;
     95 import android.view.WindowManager;
     96 
     97 import java.io.BufferedOutputStream;
     98 import java.io.File;
     99 import java.io.FileDescriptor;
    100 import java.io.FileInputStream;
    101 import java.io.FileNotFoundException;
    102 import java.io.FileOutputStream;
    103 import java.io.FileReader;
    104 import java.io.FilenameFilter;
    105 import java.io.IOException;
    106 import java.io.InputStream;
    107 import java.io.PrintWriter;
    108 import java.security.NoSuchAlgorithmException;
    109 import java.text.SimpleDateFormat;
    110 import java.util.ArrayList;
    111 import java.util.Arrays;
    112 import java.util.Collection;
    113 import java.util.Collections;
    114 import java.util.Comparator;
    115 import java.util.Date;
    116 import java.util.Enumeration;
    117 import java.util.HashMap;
    118 import java.util.HashSet;
    119 import java.util.Iterator;
    120 import java.util.LinkedList;
    121 import java.util.List;
    122 import java.util.Map;
    123 import java.util.Set;
    124 import java.util.zip.ZipEntry;
    125 import java.util.zip.ZipException;
    126 import java.util.zip.ZipFile;
    127 import java.util.zip.ZipOutputStream;
    128 
    129 /**
    130  * Keep track of all those .apks everywhere.
    131  *
    132  * This is very central to the platform's security; please run the unit
    133  * tests whenever making modifications here:
    134  *
    135 mmm frameworks/base/tests/AndroidTests
    136 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
    137 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
    138  *
    139  */
    140 class PackageManagerService extends IPackageManager.Stub {
    141     private static final String TAG = "PackageManager";
    142     private static final boolean DEBUG_SETTINGS = false;
    143     private static final boolean DEBUG_PREFERRED = false;
    144     private static final boolean DEBUG_UPGRADE = false;
    145     private static final boolean DEBUG_INSTALL = false;
    146 
    147     private static final boolean MULTIPLE_APPLICATION_UIDS = true;
    148     private static final int RADIO_UID = Process.PHONE_UID;
    149     private static final int LOG_UID = Process.LOG_UID;
    150     private static final int NFC_UID = Process.NFC_UID;
    151     private static final int FIRST_APPLICATION_UID =
    152         Process.FIRST_APPLICATION_UID;
    153     private static final int MAX_APPLICATION_UIDS = 1000;
    154 
    155     private static final boolean SHOW_INFO = false;
    156 
    157     private static final boolean GET_CERTIFICATES = true;
    158 
    159     private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
    160 
    161     private static final int REMOVE_EVENTS =
    162         FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
    163     private static final int ADD_EVENTS =
    164         FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;
    165 
    166     private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;
    167     // Suffix used during package installation when copying/moving
    168     // package apks to install directory.
    169     private static final String INSTALL_PACKAGE_SUFFIX = "-";
    170 
    171     /**
    172      * Indicates the state of installation. Used by PackageManager to
    173      * figure out incomplete installations. Say a package is being installed
    174      * (the state is set to PKG_INSTALL_INCOMPLETE) and remains so till
    175      * the package installation is successful or unsuccesful lin which case
    176      * the PackageManager will no longer maintain state information associated
    177      * with the package. If some exception(like device freeze or battery being
    178      * pulled out) occurs during installation of a package, the PackageManager
    179      * needs this information to clean up the previously failed installation.
    180      */
    181     private static final int PKG_INSTALL_INCOMPLETE = 0;
    182     private static final int PKG_INSTALL_COMPLETE = 1;
    183 
    184     static final int SCAN_MONITOR = 1<<0;
    185     static final int SCAN_NO_DEX = 1<<1;
    186     static final int SCAN_FORCE_DEX = 1<<2;
    187     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
    188     static final int SCAN_NEW_INSTALL = 1<<4;
    189     static final int SCAN_NO_PATHS = 1<<5;
    190     static final int SCAN_UPDATE_TIME = 1<<6;
    191 
    192     static final int REMOVE_CHATTY = 1<<16;
    193 
    194     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
    195 
    196     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
    197             DEFAULT_CONTAINER_PACKAGE,
    198             "com.android.defcontainer.DefaultContainerService");
    199 
    200     private static final String LIB_DIR_NAME = "lib";
    201 
    202     static final String mTempContainerPrefix = "smdl2tmp";
    203 
    204     final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
    205             Process.THREAD_PRIORITY_BACKGROUND);
    206     final PackageHandler mHandler;
    207 
    208     final int mSdkVersion = Build.VERSION.SDK_INT;
    209     final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
    210             ? null : Build.VERSION.CODENAME;
    211 
    212     final Context mContext;
    213     final boolean mFactoryTest;
    214     final boolean mNoDexOpt;
    215     final DisplayMetrics mMetrics;
    216     final int mDefParseFlags;
    217     final String[] mSeparateProcesses;
    218 
    219     // This is where all application persistent data goes.
    220     final File mAppDataDir;
    221 
    222     // If Encrypted File System feature is enabled, all application persistent data
    223     // should go here instead.
    224     final File mSecureAppDataDir;
    225 
    226     // This is the object monitoring the framework dir.
    227     final FileObserver mFrameworkInstallObserver;
    228 
    229     // This is the object monitoring the system app dir.
    230     final FileObserver mSystemInstallObserver;
    231 
    232     // This is the object monitoring the system app dir.
    233     final FileObserver mVendorInstallObserver;
    234 
    235     // This is the object monitoring mAppInstallDir.
    236     final FileObserver mAppInstallObserver;
    237 
    238     // This is the object monitoring mDrmAppPrivateInstallDir.
    239     final FileObserver mDrmAppInstallObserver;
    240 
    241     // Used for priviledge escalation.  MUST NOT BE CALLED WITH mPackages
    242     // LOCK HELD.  Can be called with mInstallLock held.
    243     final Installer mInstaller;
    244 
    245     final File mFrameworkDir;
    246     final File mSystemAppDir;
    247     final File mVendorAppDir;
    248     final File mAppInstallDir;
    249     final File mDalvikCacheDir;
    250 
    251     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
    252     // apps.
    253     final File mDrmAppPrivateInstallDir;
    254 
    255     // ----------------------------------------------------------------
    256 
    257     // Lock for state used when installing and doing other long running
    258     // operations.  Methods that must be called with this lock held have
    259     // the prefix "LI".
    260     final Object mInstallLock = new Object();
    261 
    262     // These are the directories in the 3rd party applications installed dir
    263     // that we have currently loaded packages from.  Keys are the application's
    264     // installed zip file (absolute codePath), and values are Package.
    265     final HashMap<String, PackageParser.Package> mAppDirs =
    266             new HashMap<String, PackageParser.Package>();
    267 
    268     // Information for the parser to write more useful error messages.
    269     File mScanningPath;
    270     int mLastScanError;
    271 
    272     final int[] mOutPermissions = new int[3];
    273 
    274     // ----------------------------------------------------------------
    275 
    276     // Keys are String (package name), values are Package.  This also serves
    277     // as the lock for the global state.  Methods that must be called with
    278     // this lock held have the prefix "LP".
    279     final HashMap<String, PackageParser.Package> mPackages =
    280             new HashMap<String, PackageParser.Package>();
    281 
    282     final Settings mSettings;
    283     boolean mRestoredSettings;
    284 
    285     // Group-ids that are given to all packages as read from etc/permissions/*.xml.
    286     int[] mGlobalGids;
    287 
    288     // These are the built-in uid -> permission mappings that were read from the
    289     // etc/permissions.xml file.
    290     final SparseArray<HashSet<String>> mSystemPermissions =
    291             new SparseArray<HashSet<String>>();
    292 
    293     // These are the built-in shared libraries that were read from the
    294     // etc/permissions.xml file.
    295     final HashMap<String, String> mSharedLibraries = new HashMap<String, String>();
    296 
    297     // Temporary for building the final shared libraries for an .apk.
    298     String[] mTmpSharedLibraries = null;
    299 
    300     // These are the features this devices supports that were read from the
    301     // etc/permissions.xml file.
    302     final HashMap<String, FeatureInfo> mAvailableFeatures =
    303             new HashMap<String, FeatureInfo>();
    304 
    305     // All available activities, for your resolving pleasure.
    306     final ActivityIntentResolver mActivities =
    307             new ActivityIntentResolver();
    308 
    309     // All available receivers, for your resolving pleasure.
    310     final ActivityIntentResolver mReceivers =
    311             new ActivityIntentResolver();
    312 
    313     // All available services, for your resolving pleasure.
    314     final ServiceIntentResolver mServices = new ServiceIntentResolver();
    315 
    316     // Keys are String (provider class name), values are Provider.
    317     final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent =
    318             new HashMap<ComponentName, PackageParser.Provider>();
    319 
    320     // Mapping from provider base names (first directory in content URI codePath)
    321     // to the provider information.
    322     final HashMap<String, PackageParser.Provider> mProviders =
    323             new HashMap<String, PackageParser.Provider>();
    324 
    325     // Mapping from instrumentation class names to info about them.
    326     final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
    327             new HashMap<ComponentName, PackageParser.Instrumentation>();
    328 
    329     // Mapping from permission names to info about them.
    330     final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
    331             new HashMap<String, PackageParser.PermissionGroup>();
    332 
    333     // Packages whose data we have transfered into another package, thus
    334     // should no longer exist.
    335     final HashSet<String> mTransferedPackages = new HashSet<String>();
    336 
    337     // Broadcast actions that are only available to the system.
    338     final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
    339 
    340     boolean mSystemReady;
    341     boolean mSafeMode;
    342     boolean mHasSystemUidErrors;
    343 
    344     ApplicationInfo mAndroidApplication;
    345     final ActivityInfo mResolveActivity = new ActivityInfo();
    346     final ResolveInfo mResolveInfo = new ResolveInfo();
    347     ComponentName mResolveComponentName;
    348     PackageParser.Package mPlatformPackage;
    349 
    350     // Set of pending broadcasts for aggregating enable/disable of components.
    351     final HashMap<String, ArrayList<String>> mPendingBroadcasts
    352             = new HashMap<String, ArrayList<String>>();
    353     // Service Connection to remote media container service to copy
    354     // package uri's from external media onto secure containers
    355     // or internal storage.
    356     private IMediaContainerService mContainerService = null;
    357 
    358     static final int SEND_PENDING_BROADCAST = 1;
    359     static final int MCS_BOUND = 3;
    360     static final int END_COPY = 4;
    361     static final int INIT_COPY = 5;
    362     static final int MCS_UNBIND = 6;
    363     static final int START_CLEANING_PACKAGE = 7;
    364     static final int FIND_INSTALL_LOC = 8;
    365     static final int POST_INSTALL = 9;
    366     static final int MCS_RECONNECT = 10;
    367     static final int MCS_GIVE_UP = 11;
    368     static final int UPDATED_MEDIA_STATUS = 12;
    369     static final int WRITE_SETTINGS = 13;
    370 
    371     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
    372 
    373     // Delay time in millisecs
    374     static final int BROADCAST_DELAY = 10 * 1000;
    375     final private DefaultContainerConnection mDefContainerConn =
    376             new DefaultContainerConnection();
    377     class DefaultContainerConnection implements ServiceConnection {
    378         public void onServiceConnected(ComponentName name, IBinder service) {
    379             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
    380             IMediaContainerService imcs =
    381                 IMediaContainerService.Stub.asInterface(service);
    382             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
    383         }
    384 
    385         public void onServiceDisconnected(ComponentName name) {
    386             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
    387         }
    388     };
    389 
    390     // Recordkeeping of restore-after-install operations that are currently in flight
    391     // between the Package Manager and the Backup Manager
    392     class PostInstallData {
    393         public InstallArgs args;
    394         public PackageInstalledInfo res;
    395 
    396         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
    397             args = _a;
    398             res = _r;
    399         }
    400     };
    401     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
    402     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
    403 
    404     class PackageHandler extends Handler {
    405         private boolean mBound = false;
    406         final ArrayList<HandlerParams> mPendingInstalls =
    407             new ArrayList<HandlerParams>();
    408 
    409         private boolean connectToService() {
    410             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
    411                     " DefaultContainerService");
    412             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
    413             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    414             if (mContext.bindService(service, mDefContainerConn,
    415                     Context.BIND_AUTO_CREATE)) {
    416                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    417                 mBound = true;
    418                 return true;
    419             }
    420             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    421             return false;
    422         }
    423 
    424         private void disconnectService() {
    425             mContainerService = null;
    426             mBound = false;
    427             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    428             mContext.unbindService(mDefContainerConn);
    429             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    430         }
    431 
    432         PackageHandler(Looper looper) {
    433             super(looper);
    434         }
    435 
    436         public void handleMessage(Message msg) {
    437             try {
    438                 doHandleMessage(msg);
    439             } finally {
    440                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    441             }
    442         }
    443 
    444         void doHandleMessage(Message msg) {
    445             switch (msg.what) {
    446                 case INIT_COPY: {
    447                     if (DEBUG_SD_INSTALL) Log.i(TAG, "init_copy");
    448                     HandlerParams params = (HandlerParams) msg.obj;
    449                     int idx = mPendingInstalls.size();
    450                     if (DEBUG_SD_INSTALL) Log.i(TAG, "idx=" + idx);
    451                     // If a bind was already initiated we dont really
    452                     // need to do anything. The pending install
    453                     // will be processed later on.
    454                     if (!mBound) {
    455                         // If this is the only one pending we might
    456                         // have to bind to the service again.
    457                         if (!connectToService()) {
    458                             Slog.e(TAG, "Failed to bind to media container service");
    459                             params.serviceError();
    460                             return;
    461                         } else {
    462                             // Once we bind to the service, the first
    463                             // pending request will be processed.
    464                             mPendingInstalls.add(idx, params);
    465                         }
    466                     } else {
    467                         mPendingInstalls.add(idx, params);
    468                         // Already bound to the service. Just make
    469                         // sure we trigger off processing the first request.
    470                         if (idx == 0) {
    471                             mHandler.sendEmptyMessage(MCS_BOUND);
    472                         }
    473                     }
    474                     break;
    475                 }
    476                 case MCS_BOUND: {
    477                     if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_bound");
    478                     if (msg.obj != null) {
    479                         mContainerService = (IMediaContainerService) msg.obj;
    480                     }
    481                     if (mContainerService == null) {
    482                         // Something seriously wrong. Bail out
    483                         Slog.e(TAG, "Cannot bind to media container service");
    484                         for (HandlerParams params : mPendingInstalls) {
    485                             mPendingInstalls.remove(0);
    486                             // Indicate service bind error
    487                             params.serviceError();
    488                         }
    489                         mPendingInstalls.clear();
    490                     } else if (mPendingInstalls.size() > 0) {
    491                         HandlerParams params = mPendingInstalls.get(0);
    492                         if (params != null) {
    493                             params.startCopy();
    494                         }
    495                     } else {
    496                         // Should never happen ideally.
    497                         Slog.w(TAG, "Empty queue");
    498                     }
    499                     break;
    500                 }
    501                 case MCS_RECONNECT : {
    502                     if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_reconnect");
    503                     if (mPendingInstalls.size() > 0) {
    504                         if (mBound) {
    505                             disconnectService();
    506                         }
    507                         if (!connectToService()) {
    508                             Slog.e(TAG, "Failed to bind to media container service");
    509                             for (HandlerParams params : mPendingInstalls) {
    510                                 mPendingInstalls.remove(0);
    511                                 // Indicate service bind error
    512                                 params.serviceError();
    513                             }
    514                             mPendingInstalls.clear();
    515                         }
    516                     }
    517                     break;
    518                 }
    519                 case MCS_UNBIND : {
    520                     if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_unbind");
    521                     // Delete pending install
    522                     if (mPendingInstalls.size() > 0) {
    523                         mPendingInstalls.remove(0);
    524                     }
    525                     if (mPendingInstalls.size() == 0) {
    526                         if (mBound) {
    527                             disconnectService();
    528                         }
    529                     } else {
    530                         // There are more pending requests in queue.
    531                         // Just post MCS_BOUND message to trigger processing
    532                         // of next pending install.
    533                         mHandler.sendEmptyMessage(MCS_BOUND);
    534                     }
    535                     break;
    536                 }
    537                 case MCS_GIVE_UP: {
    538                     if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_giveup too many retries");
    539                     HandlerParams params = mPendingInstalls.remove(0);
    540                     break;
    541                 }
    542                 case SEND_PENDING_BROADCAST : {
    543                     String packages[];
    544                     ArrayList components[];
    545                     int size = 0;
    546                     int uids[];
    547                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    548                     synchronized (mPackages) {
    549                         if (mPendingBroadcasts == null) {
    550                             return;
    551                         }
    552                         size = mPendingBroadcasts.size();
    553                         if (size <= 0) {
    554                             // Nothing to be done. Just return
    555                             return;
    556                         }
    557                         packages = new String[size];
    558                         components = new ArrayList[size];
    559                         uids = new int[size];
    560                         Iterator<HashMap.Entry<String, ArrayList<String>>>
    561                                 it = mPendingBroadcasts.entrySet().iterator();
    562                         int i = 0;
    563                         while (it.hasNext() && i < size) {
    564                             HashMap.Entry<String, ArrayList<String>> ent = it.next();
    565                             packages[i] = ent.getKey();
    566                             components[i] = ent.getValue();
    567                             PackageSetting ps = mSettings.mPackages.get(ent.getKey());
    568                             uids[i] = (ps != null) ? ps.userId : -1;
    569                             i++;
    570                         }
    571                         size = i;
    572                         mPendingBroadcasts.clear();
    573                     }
    574                     // Send broadcasts
    575                     for (int i = 0; i < size; i++) {
    576                         sendPackageChangedBroadcast(packages[i], true,
    577                                 (ArrayList<String>)components[i], uids[i]);
    578                     }
    579                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    580                     break;
    581                 }
    582                 case START_CLEANING_PACKAGE: {
    583                     String packageName = (String)msg.obj;
    584                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    585                     synchronized (mPackages) {
    586                         if (!mSettings.mPackagesToBeCleaned.contains(packageName)) {
    587                             mSettings.mPackagesToBeCleaned.add(packageName);
    588                         }
    589                     }
    590                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    591                     startCleaningPackages();
    592                 } break;
    593                 case POST_INSTALL: {
    594                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
    595                     PostInstallData data = mRunningInstalls.get(msg.arg1);
    596                     mRunningInstalls.delete(msg.arg1);
    597                     boolean deleteOld = false;
    598 
    599                     if (data != null) {
    600                         InstallArgs args = data.args;
    601                         PackageInstalledInfo res = data.res;
    602 
    603                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
    604                             res.removedInfo.sendBroadcast(false, true);
    605                             Bundle extras = new Bundle(1);
    606                             extras.putInt(Intent.EXTRA_UID, res.uid);
    607                             final boolean update = res.removedInfo.removedPackage != null;
    608                             if (update) {
    609                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
    610                             }
    611                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
    612                                     res.pkg.applicationInfo.packageName,
    613                                     extras, null);
    614                             if (update) {
    615                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
    616                                         res.pkg.applicationInfo.packageName,
    617                                         extras, null);
    618                             }
    619                             if (res.removedInfo.args != null) {
    620                                 // Remove the replaced package's older resources safely now
    621                                 deleteOld = true;
    622                             }
    623                         }
    624                         // Force a gc to clear up things
    625                         Runtime.getRuntime().gc();
    626                         // We delete after a gc for applications  on sdcard.
    627                         if (deleteOld) {
    628                             synchronized (mInstallLock) {
    629                                 res.removedInfo.args.doPostDeleteLI(true);
    630                             }
    631                         }
    632                         if (args.observer != null) {
    633                             try {
    634                                 args.observer.packageInstalled(res.name, res.returnCode);
    635                             } catch (RemoteException e) {
    636                                 Slog.i(TAG, "Observer no longer exists.");
    637                             }
    638                         }
    639                     } else {
    640                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
    641                     }
    642                 } break;
    643                 case UPDATED_MEDIA_STATUS: {
    644                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
    645                     boolean reportStatus = msg.arg1 == 1;
    646                     boolean doGc = msg.arg2 == 1;
    647                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
    648                     if (doGc) {
    649                         // Force a gc to clear up stale containers.
    650                         Runtime.getRuntime().gc();
    651                     }
    652                     if (msg.obj != null) {
    653                         Set<SdInstallArgs> args = (Set<SdInstallArgs>) msg.obj;
    654                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
    655                         // Unload containers
    656                         unloadAllContainers(args);
    657                     }
    658                     if (reportStatus) {
    659                         try {
    660                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
    661                             PackageHelper.getMountService().finishMediaUpdate();
    662                         } catch (RemoteException e) {
    663                             Log.e(TAG, "MountService not running?");
    664                         }
    665                     }
    666                 } break;
    667                 case WRITE_SETTINGS: {
    668                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    669                     synchronized (mPackages) {
    670                         removeMessages(WRITE_SETTINGS);
    671                         mSettings.writeLP();
    672                     }
    673                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    674                 } break;
    675             }
    676         }
    677     }
    678 
    679     void scheduleWriteSettingsLocked() {
    680         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
    681             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
    682         }
    683     }
    684 
    685     static boolean installOnSd(int flags) {
    686         if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) ||
    687                 ((flags & PackageManager.INSTALL_INTERNAL) != 0)) {
    688             return false;
    689         }
    690         if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
    691             return true;
    692         }
    693         return false;
    694     }
    695 
    696     public static final IPackageManager main(Context context, boolean factoryTest) {
    697         PackageManagerService m = new PackageManagerService(context, factoryTest);
    698         ServiceManager.addService("package", m);
    699         return m;
    700     }
    701 
    702     static String[] splitString(String str, char sep) {
    703         int count = 1;
    704         int i = 0;
    705         while ((i=str.indexOf(sep, i)) >= 0) {
    706             count++;
    707             i++;
    708         }
    709 
    710         String[] res = new String[count];
    711         i=0;
    712         count = 0;
    713         int lastI=0;
    714         while ((i=str.indexOf(sep, i)) >= 0) {
    715             res[count] = str.substring(lastI, i);
    716             count++;
    717             i++;
    718             lastI = i;
    719         }
    720         res[count] = str.substring(lastI, str.length());
    721         return res;
    722     }
    723 
    724     public PackageManagerService(Context context, boolean factoryTest) {
    725         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
    726                 SystemClock.uptimeMillis());
    727 
    728         if (mSdkVersion <= 0) {
    729             Slog.w(TAG, "**** ro.build.version.sdk not set!");
    730         }
    731 
    732         mContext = context;
    733         mFactoryTest = factoryTest;
    734         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
    735         mMetrics = new DisplayMetrics();
    736         mSettings = new Settings();
    737         mSettings.addSharedUserLP("android.uid.system",
    738                 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
    739         mSettings.addSharedUserLP("android.uid.phone",
    740                 MULTIPLE_APPLICATION_UIDS
    741                         ? RADIO_UID : FIRST_APPLICATION_UID,
    742                 ApplicationInfo.FLAG_SYSTEM);
    743         mSettings.addSharedUserLP("android.uid.log",
    744                 MULTIPLE_APPLICATION_UIDS
    745                         ? LOG_UID : FIRST_APPLICATION_UID,
    746                 ApplicationInfo.FLAG_SYSTEM);
    747         mSettings.addSharedUserLP("android.uid.nfc",
    748                 MULTIPLE_APPLICATION_UIDS
    749                         ? NFC_UID : FIRST_APPLICATION_UID,
    750                 ApplicationInfo.FLAG_SYSTEM);
    751 
    752         String separateProcesses = SystemProperties.get("debug.separate_processes");
    753         if (separateProcesses != null && separateProcesses.length() > 0) {
    754             if ("*".equals(separateProcesses)) {
    755                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
    756                 mSeparateProcesses = null;
    757                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
    758             } else {
    759                 mDefParseFlags = 0;
    760                 mSeparateProcesses = separateProcesses.split(",");
    761                 Slog.w(TAG, "Running with debug.separate_processes: "
    762                         + separateProcesses);
    763             }
    764         } else {
    765             mDefParseFlags = 0;
    766             mSeparateProcesses = null;
    767         }
    768 
    769         Installer installer = new Installer();
    770         // Little hacky thing to check if installd is here, to determine
    771         // whether we are running on the simulator and thus need to take
    772         // care of building the /data file structure ourself.
    773         // (apparently the sim now has a working installer)
    774         if (installer.ping() && Process.supportsProcesses()) {
    775             mInstaller = installer;
    776         } else {
    777             mInstaller = null;
    778         }
    779 
    780         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    781         Display d = wm.getDefaultDisplay();
    782         d.getMetrics(mMetrics);
    783 
    784         synchronized (mInstallLock) {
    785         synchronized (mPackages) {
    786             mHandlerThread.start();
    787             mHandler = new PackageHandler(mHandlerThread.getLooper());
    788 
    789             File dataDir = Environment.getDataDirectory();
    790             mAppDataDir = new File(dataDir, "data");
    791             mSecureAppDataDir = new File(dataDir, "secure/data");
    792             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
    793 
    794             if (mInstaller == null) {
    795                 // Make sure these dirs exist, when we are running in
    796                 // the simulator.
    797                 // Make a wide-open directory for random misc stuff.
    798                 File miscDir = new File(dataDir, "misc");
    799                 miscDir.mkdirs();
    800                 mAppDataDir.mkdirs();
    801                 mSecureAppDataDir.mkdirs();
    802                 mDrmAppPrivateInstallDir.mkdirs();
    803             }
    804 
    805             readPermissions();
    806 
    807             mRestoredSettings = mSettings.readLP();
    808             long startTime = SystemClock.uptimeMillis();
    809 
    810             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
    811                     startTime);
    812 
    813             // Set flag to monitor and not change apk file paths when
    814             // scanning install directories.
    815             int scanMode = SCAN_MONITOR | SCAN_NO_PATHS;
    816             if (mNoDexOpt) {
    817                 Slog.w(TAG, "Running ENG build: no pre-dexopt!");
    818                 scanMode |= SCAN_NO_DEX;
    819             }
    820 
    821             final HashSet<String> libFiles = new HashSet<String>();
    822 
    823             mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
    824             mDalvikCacheDir = new File(dataDir, "dalvik-cache");
    825 
    826             if (mInstaller != null) {
    827                 boolean didDexOpt = false;
    828 
    829                 /**
    830                  * Out of paranoia, ensure that everything in the boot class
    831                  * path has been dexed.
    832                  */
    833                 String bootClassPath = System.getProperty("java.boot.class.path");
    834                 if (bootClassPath != null) {
    835                     String[] paths = splitString(bootClassPath, ':');
    836                     for (int i=0; i<paths.length; i++) {
    837                         try {
    838                             if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
    839                                 libFiles.add(paths[i]);
    840                                 mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
    841                                 didDexOpt = true;
    842                             }
    843                         } catch (FileNotFoundException e) {
    844                             Slog.w(TAG, "Boot class path not found: " + paths[i]);
    845                         } catch (IOException e) {
    846                             Slog.w(TAG, "Exception reading boot class path: " + paths[i], e);
    847                         }
    848                     }
    849                 } else {
    850                     Slog.w(TAG, "No BOOTCLASSPATH found!");
    851                 }
    852 
    853                 /**
    854                  * Also ensure all external libraries have had dexopt run on them.
    855                  */
    856                 if (mSharedLibraries.size() > 0) {
    857                     Iterator<String> libs = mSharedLibraries.values().iterator();
    858                     while (libs.hasNext()) {
    859                         String lib = libs.next();
    860                         try {
    861                             if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
    862                                 libFiles.add(lib);
    863                                 mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
    864                                 didDexOpt = true;
    865                             }
    866                         } catch (FileNotFoundException e) {
    867                             Slog.w(TAG, "Library not found: " + lib);
    868                         } catch (IOException e) {
    869                             Slog.w(TAG, "Exception reading library: " + lib, e);
    870                         }
    871                     }
    872                 }
    873 
    874                 // Gross hack for now: we know this file doesn't contain any
    875                 // code, so don't dexopt it to avoid the resulting log spew.
    876                 libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
    877 
    878                 /**
    879                  * And there are a number of commands implemented in Java, which
    880                  * we currently need to do the dexopt on so that they can be
    881                  * run from a non-root shell.
    882                  */
    883                 String[] frameworkFiles = mFrameworkDir.list();
    884                 if (frameworkFiles != null) {
    885                     for (int i=0; i<frameworkFiles.length; i++) {
    886                         File libPath = new File(mFrameworkDir, frameworkFiles[i]);
    887                         String path = libPath.getPath();
    888                         // Skip the file if we alrady did it.
    889                         if (libFiles.contains(path)) {
    890                             continue;
    891                         }
    892                         // Skip the file if it is not a type we want to dexopt.
    893                         if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
    894                             continue;
    895                         }
    896                         try {
    897                             if (dalvik.system.DexFile.isDexOptNeeded(path)) {
    898                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true);
    899                                 didDexOpt = true;
    900                             }
    901                         } catch (FileNotFoundException e) {
    902                             Slog.w(TAG, "Jar not found: " + path);
    903                         } catch (IOException e) {
    904                             Slog.w(TAG, "Exception reading jar: " + path, e);
    905                         }
    906                     }
    907                 }
    908 
    909                 if (didDexOpt) {
    910                     // If we had to do a dexopt of one of the previous
    911                     // things, then something on the system has changed.
    912                     // Consider this significant, and wipe away all other
    913                     // existing dexopt files to ensure we don't leave any
    914                     // dangling around.
    915                     String[] files = mDalvikCacheDir.list();
    916                     if (files != null) {
    917                         for (int i=0; i<files.length; i++) {
    918                             String fn = files[i];
    919                             if (fn.startsWith("data@app@")
    920                                     || fn.startsWith("data@app-private@")) {
    921                                 Slog.i(TAG, "Pruning dalvik file: " + fn);
    922                                 (new File(mDalvikCacheDir, fn)).delete();
    923                             }
    924                         }
    925                     }
    926                 }
    927             }
    928 
    929             // Find base frameworks (resource packages without code).
    930             mFrameworkInstallObserver = new AppDirObserver(
    931                 mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
    932             mFrameworkInstallObserver.startWatching();
    933             scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
    934                     | PackageParser.PARSE_IS_SYSTEM_DIR,
    935                     scanMode | SCAN_NO_DEX, 0);
    936 
    937             // Collect all system packages.
    938             mSystemAppDir = new File(Environment.getRootDirectory(), "app");
    939             mSystemInstallObserver = new AppDirObserver(
    940                 mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
    941             mSystemInstallObserver.startWatching();
    942             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
    943                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
    944 
    945             // Collect all vendor packages.
    946             mVendorAppDir = new File("/vendor/app");
    947             mVendorInstallObserver = new AppDirObserver(
    948                 mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
    949             mVendorInstallObserver.startWatching();
    950             scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
    951                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
    952 
    953             if (mInstaller != null) {
    954                 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
    955                 mInstaller.moveFiles();
    956             }
    957 
    958             // Prune any system packages that no longer exist.
    959             Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
    960             while (psit.hasNext()) {
    961                 PackageSetting ps = psit.next();
    962                 if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0
    963                         && !mPackages.containsKey(ps.name)
    964                         && !mSettings.mDisabledSysPackages.containsKey(ps.name)) {
    965                     psit.remove();
    966                     String msg = "System package " + ps.name
    967                             + " no longer exists; wiping its data";
    968                     reportSettingsProblem(Log.WARN, msg);
    969                     if (mInstaller != null) {
    970                         // XXX how to set useEncryptedFSDir for packages that
    971                         // are not encrypted?
    972                         mInstaller.remove(ps.name, true);
    973                     }
    974                 }
    975             }
    976 
    977             mAppInstallDir = new File(dataDir, "app");
    978             if (mInstaller == null) {
    979                 // Make sure these dirs exist, when we are running in
    980                 // the simulator.
    981                 mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists
    982             }
    983             //look for any incomplete package installations
    984             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackages();
    985             //clean up list
    986             for(int i = 0; i < deletePkgsList.size(); i++) {
    987                 //clean up here
    988                 cleanupInstallFailedPackage(deletePkgsList.get(i));
    989             }
    990             //delete tmp files
    991             deleteTempPackageFiles();
    992 
    993             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
    994                     SystemClock.uptimeMillis());
    995             mAppInstallObserver = new AppDirObserver(
    996                 mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
    997             mAppInstallObserver.startWatching();
    998             scanDirLI(mAppInstallDir, 0, scanMode, 0);
    999 
   1000             mDrmAppInstallObserver = new AppDirObserver(
   1001                 mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
   1002             mDrmAppInstallObserver.startWatching();
   1003             scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
   1004                     scanMode, 0);
   1005 
   1006             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
   1007                     SystemClock.uptimeMillis());
   1008             Slog.i(TAG, "Time to scan packages: "
   1009                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
   1010                     + " seconds");
   1011 
   1012             // If the platform SDK has changed since the last time we booted,
   1013             // we need to re-grant app permission to catch any new ones that
   1014             // appear.  This is really a hack, and means that apps can in some
   1015             // cases get permissions that the user didn't initially explicitly
   1016             // allow...  it would be nice to have some better way to handle
   1017             // this situation.
   1018             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
   1019                     != mSdkVersion;
   1020             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
   1021                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
   1022                     + "; regranting permissions for internal storage");
   1023             mSettings.mInternalSdkPlatform = mSdkVersion;
   1024 
   1025             updatePermissionsLP(null, null, true, regrantPermissions, regrantPermissions);
   1026 
   1027             mSettings.writeLP();
   1028 
   1029             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
   1030                     SystemClock.uptimeMillis());
   1031 
   1032             // Now after opening every single application zip, make sure they
   1033             // are all flushed.  Not really needed, but keeps things nice and
   1034             // tidy.
   1035             Runtime.getRuntime().gc();
   1036         } // synchronized (mPackages)
   1037         } // synchronized (mInstallLock)
   1038     }
   1039 
   1040     @Override
   1041     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1042             throws RemoteException {
   1043         try {
   1044             return super.onTransact(code, data, reply, flags);
   1045         } catch (RuntimeException e) {
   1046             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
   1047                 Slog.e(TAG, "Package Manager Crash", e);
   1048             }
   1049             throw e;
   1050         }
   1051     }
   1052 
   1053     void cleanupInstallFailedPackage(PackageSetting ps) {
   1054         Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
   1055         if (mInstaller != null) {
   1056             boolean useSecureFS = useEncryptedFilesystemForPackage(ps.pkg);
   1057             int retCode = mInstaller.remove(ps.name, useSecureFS);
   1058             if (retCode < 0) {
   1059                 Slog.w(TAG, "Couldn't remove app data directory for package: "
   1060                            + ps.name + ", retcode=" + retCode);
   1061             }
   1062         } else {
   1063             //for emulator
   1064             PackageParser.Package pkg = mPackages.get(ps.name);
   1065             File dataDir = new File(pkg.applicationInfo.dataDir);
   1066             dataDir.delete();
   1067         }
   1068         if (ps.codePath != null) {
   1069             if (!ps.codePath.delete()) {
   1070                 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
   1071             }
   1072         }
   1073         if (ps.resourcePath != null) {
   1074             if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
   1075                 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
   1076             }
   1077         }
   1078         mSettings.removePackageLP(ps.name);
   1079     }
   1080 
   1081     void readPermissions() {
   1082         // Read permissions from .../etc/permission directory.
   1083         File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
   1084         if (!libraryDir.exists() || !libraryDir.isDirectory()) {
   1085             Slog.w(TAG, "No directory " + libraryDir + ", skipping");
   1086             return;
   1087         }
   1088         if (!libraryDir.canRead()) {
   1089             Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
   1090             return;
   1091         }
   1092 
   1093         // Iterate over the files in the directory and scan .xml files
   1094         for (File f : libraryDir.listFiles()) {
   1095             // We'll read platform.xml last
   1096             if (f.getPath().endsWith("etc/permissions/platform.xml")) {
   1097                 continue;
   1098             }
   1099 
   1100             if (!f.getPath().endsWith(".xml")) {
   1101                 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
   1102                 continue;
   1103             }
   1104             if (!f.canRead()) {
   1105                 Slog.w(TAG, "Permissions library file " + f + " cannot be read");
   1106                 continue;
   1107             }
   1108 
   1109             readPermissionsFromXml(f);
   1110         }
   1111 
   1112         // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
   1113         final File permFile = new File(Environment.getRootDirectory(),
   1114                 "etc/permissions/platform.xml");
   1115         readPermissionsFromXml(permFile);
   1116     }
   1117 
   1118     private void readPermissionsFromXml(File permFile) {
   1119         FileReader permReader = null;
   1120         try {
   1121             permReader = new FileReader(permFile);
   1122         } catch (FileNotFoundException e) {
   1123             Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
   1124             return;
   1125         }
   1126 
   1127         try {
   1128             XmlPullParser parser = Xml.newPullParser();
   1129             parser.setInput(permReader);
   1130 
   1131             XmlUtils.beginDocument(parser, "permissions");
   1132 
   1133             while (true) {
   1134                 XmlUtils.nextElement(parser);
   1135                 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
   1136                     break;
   1137                 }
   1138 
   1139                 String name = parser.getName();
   1140                 if ("group".equals(name)) {
   1141                     String gidStr = parser.getAttributeValue(null, "gid");
   1142                     if (gidStr != null) {
   1143                         int gid = Integer.parseInt(gidStr);
   1144                         mGlobalGids = appendInt(mGlobalGids, gid);
   1145                     } else {
   1146                         Slog.w(TAG, "<group> without gid at "
   1147                                 + parser.getPositionDescription());
   1148                     }
   1149 
   1150                     XmlUtils.skipCurrentTag(parser);
   1151                     continue;
   1152                 } else if ("permission".equals(name)) {
   1153                     String perm = parser.getAttributeValue(null, "name");
   1154                     if (perm == null) {
   1155                         Slog.w(TAG, "<permission> without name at "
   1156                                 + parser.getPositionDescription());
   1157                         XmlUtils.skipCurrentTag(parser);
   1158                         continue;
   1159                     }
   1160                     perm = perm.intern();
   1161                     readPermission(parser, perm);
   1162 
   1163                 } else if ("assign-permission".equals(name)) {
   1164                     String perm = parser.getAttributeValue(null, "name");
   1165                     if (perm == null) {
   1166                         Slog.w(TAG, "<assign-permission> without name at "
   1167                                 + parser.getPositionDescription());
   1168                         XmlUtils.skipCurrentTag(parser);
   1169                         continue;
   1170                     }
   1171                     String uidStr = parser.getAttributeValue(null, "uid");
   1172                     if (uidStr == null) {
   1173                         Slog.w(TAG, "<assign-permission> without uid at "
   1174                                 + parser.getPositionDescription());
   1175                         XmlUtils.skipCurrentTag(parser);
   1176                         continue;
   1177                     }
   1178                     int uid = Process.getUidForName(uidStr);
   1179                     if (uid < 0) {
   1180                         Slog.w(TAG, "<assign-permission> with unknown uid \""
   1181                                 + uidStr + "\" at "
   1182                                 + parser.getPositionDescription());
   1183                         XmlUtils.skipCurrentTag(parser);
   1184                         continue;
   1185                     }
   1186                     perm = perm.intern();
   1187                     HashSet<String> perms = mSystemPermissions.get(uid);
   1188                     if (perms == null) {
   1189                         perms = new HashSet<String>();
   1190                         mSystemPermissions.put(uid, perms);
   1191                     }
   1192                     perms.add(perm);
   1193                     XmlUtils.skipCurrentTag(parser);
   1194 
   1195                 } else if ("library".equals(name)) {
   1196                     String lname = parser.getAttributeValue(null, "name");
   1197                     String lfile = parser.getAttributeValue(null, "file");
   1198                     if (lname == null) {
   1199                         Slog.w(TAG, "<library> without name at "
   1200                                 + parser.getPositionDescription());
   1201                     } else if (lfile == null) {
   1202                         Slog.w(TAG, "<library> without file at "
   1203                                 + parser.getPositionDescription());
   1204                     } else {
   1205                         //Log.i(TAG, "Got library " + lname + " in " + lfile);
   1206                         mSharedLibraries.put(lname, lfile);
   1207                     }
   1208                     XmlUtils.skipCurrentTag(parser);
   1209                     continue;
   1210 
   1211                 } else if ("feature".equals(name)) {
   1212                     String fname = parser.getAttributeValue(null, "name");
   1213                     if (fname == null) {
   1214                         Slog.w(TAG, "<feature> without name at "
   1215                                 + parser.getPositionDescription());
   1216                     } else {
   1217                         //Log.i(TAG, "Got feature " + fname);
   1218                         FeatureInfo fi = new FeatureInfo();
   1219                         fi.name = fname;
   1220                         mAvailableFeatures.put(fname, fi);
   1221                     }
   1222                     XmlUtils.skipCurrentTag(parser);
   1223                     continue;
   1224 
   1225                 } else {
   1226                     XmlUtils.skipCurrentTag(parser);
   1227                     continue;
   1228                 }
   1229 
   1230             }
   1231         } catch (XmlPullParserException e) {
   1232             Slog.w(TAG, "Got execption parsing permissions.", e);
   1233         } catch (IOException e) {
   1234             Slog.w(TAG, "Got execption parsing permissions.", e);
   1235         }
   1236     }
   1237 
   1238     void readPermission(XmlPullParser parser, String name)
   1239             throws IOException, XmlPullParserException {
   1240 
   1241         name = name.intern();
   1242 
   1243         BasePermission bp = mSettings.mPermissions.get(name);
   1244         if (bp == null) {
   1245             bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
   1246             mSettings.mPermissions.put(name, bp);
   1247         }
   1248         int outerDepth = parser.getDepth();
   1249         int type;
   1250         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
   1251                && (type != XmlPullParser.END_TAG
   1252                        || parser.getDepth() > outerDepth)) {
   1253             if (type == XmlPullParser.END_TAG
   1254                     || type == XmlPullParser.TEXT) {
   1255                 continue;
   1256             }
   1257 
   1258             String tagName = parser.getName();
   1259             if ("group".equals(tagName)) {
   1260                 String gidStr = parser.getAttributeValue(null, "gid");
   1261                 if (gidStr != null) {
   1262                     int gid = Process.getGidForName(gidStr);
   1263                     bp.gids = appendInt(bp.gids, gid);
   1264                 } else {
   1265                     Slog.w(TAG, "<group> without gid at "
   1266                             + parser.getPositionDescription());
   1267                 }
   1268             }
   1269             XmlUtils.skipCurrentTag(parser);
   1270         }
   1271     }
   1272 
   1273     static int[] appendInt(int[] cur, int val) {
   1274         if (cur == null) {
   1275             return new int[] { val };
   1276         }
   1277         final int N = cur.length;
   1278         for (int i=0; i<N; i++) {
   1279             if (cur[i] == val) {
   1280                 return cur;
   1281             }
   1282         }
   1283         int[] ret = new int[N+1];
   1284         System.arraycopy(cur, 0, ret, 0, N);
   1285         ret[N] = val;
   1286         return ret;
   1287     }
   1288 
   1289     static int[] appendInts(int[] cur, int[] add) {
   1290         if (add == null) return cur;
   1291         if (cur == null) return add;
   1292         final int N = add.length;
   1293         for (int i=0; i<N; i++) {
   1294             cur = appendInt(cur, add[i]);
   1295         }
   1296         return cur;
   1297     }
   1298 
   1299     static int[] removeInt(int[] cur, int val) {
   1300         if (cur == null) {
   1301             return null;
   1302         }
   1303         final int N = cur.length;
   1304         for (int i=0; i<N; i++) {
   1305             if (cur[i] == val) {
   1306                 int[] ret = new int[N-1];
   1307                 if (i > 0) {
   1308                     System.arraycopy(cur, 0, ret, 0, i);
   1309                 }
   1310                 if (i < (N-1)) {
   1311                     System.arraycopy(cur, i + 1, ret, i, N - i - 1);
   1312                 }
   1313                 return ret;
   1314             }
   1315         }
   1316         return cur;
   1317     }
   1318 
   1319     static int[] removeInts(int[] cur, int[] rem) {
   1320         if (rem == null) return cur;
   1321         if (cur == null) return cur;
   1322         final int N = rem.length;
   1323         for (int i=0; i<N; i++) {
   1324             cur = removeInt(cur, rem[i]);
   1325         }
   1326         return cur;
   1327     }
   1328 
   1329     PackageInfo generatePackageInfo(PackageParser.Package p, int flags) {
   1330         if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   1331             // The package has been uninstalled but has retained data and resources.
   1332             return PackageParser.generatePackageInfo(p, null, flags, 0, 0);
   1333         }
   1334         final PackageSetting ps = (PackageSetting)p.mExtras;
   1335         if (ps == null) {
   1336             return null;
   1337         }
   1338         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   1339         return PackageParser.generatePackageInfo(p, gp.gids, flags,
   1340                 ps.firstInstallTime, ps.lastUpdateTime);
   1341     }
   1342 
   1343     public PackageInfo getPackageInfo(String packageName, int flags) {
   1344         synchronized (mPackages) {
   1345             PackageParser.Package p = mPackages.get(packageName);
   1346             if (Config.LOGV) Log.v(
   1347                 TAG, "getPackageInfo " + packageName
   1348                 + ": " + p);
   1349             if (p != null) {
   1350                 return generatePackageInfo(p, flags);
   1351             }
   1352             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   1353                 return generatePackageInfoFromSettingsLP(packageName, flags);
   1354             }
   1355         }
   1356         return null;
   1357     }
   1358 
   1359     public String[] currentToCanonicalPackageNames(String[] names) {
   1360         String[] out = new String[names.length];
   1361         synchronized (mPackages) {
   1362             for (int i=names.length-1; i>=0; i--) {
   1363                 PackageSetting ps = mSettings.mPackages.get(names[i]);
   1364                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
   1365             }
   1366         }
   1367         return out;
   1368     }
   1369 
   1370     public String[] canonicalToCurrentPackageNames(String[] names) {
   1371         String[] out = new String[names.length];
   1372         synchronized (mPackages) {
   1373             for (int i=names.length-1; i>=0; i--) {
   1374                 String cur = mSettings.mRenamedPackages.get(names[i]);
   1375                 out[i] = cur != null ? cur : names[i];
   1376             }
   1377         }
   1378         return out;
   1379     }
   1380 
   1381     public int getPackageUid(String packageName) {
   1382         synchronized (mPackages) {
   1383             PackageParser.Package p = mPackages.get(packageName);
   1384             if(p != null) {
   1385                 return p.applicationInfo.uid;
   1386             }
   1387             PackageSetting ps = mSettings.mPackages.get(packageName);
   1388             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
   1389                 return -1;
   1390             }
   1391             p = ps.pkg;
   1392             return p != null ? p.applicationInfo.uid : -1;
   1393         }
   1394     }
   1395 
   1396     public int[] getPackageGids(String packageName) {
   1397         synchronized (mPackages) {
   1398             PackageParser.Package p = mPackages.get(packageName);
   1399             if (Config.LOGV) Log.v(
   1400                 TAG, "getPackageGids" + packageName
   1401                 + ": " + p);
   1402             if (p != null) {
   1403                 final PackageSetting ps = (PackageSetting)p.mExtras;
   1404                 final SharedUserSetting suid = ps.sharedUser;
   1405                 return suid != null ? suid.gids : ps.gids;
   1406             }
   1407         }
   1408         // stupid thing to indicate an error.
   1409         return new int[0];
   1410     }
   1411 
   1412     static final PermissionInfo generatePermissionInfo(
   1413             BasePermission bp, int flags) {
   1414         if (bp.perm != null) {
   1415             return PackageParser.generatePermissionInfo(bp.perm, flags);
   1416         }
   1417         PermissionInfo pi = new PermissionInfo();
   1418         pi.name = bp.name;
   1419         pi.packageName = bp.sourcePackage;
   1420         pi.nonLocalizedLabel = bp.name;
   1421         pi.protectionLevel = bp.protectionLevel;
   1422         return pi;
   1423     }
   1424 
   1425     public PermissionInfo getPermissionInfo(String name, int flags) {
   1426         synchronized (mPackages) {
   1427             final BasePermission p = mSettings.mPermissions.get(name);
   1428             if (p != null) {
   1429                 return generatePermissionInfo(p, flags);
   1430             }
   1431             return null;
   1432         }
   1433     }
   1434 
   1435     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
   1436         synchronized (mPackages) {
   1437             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
   1438             for (BasePermission p : mSettings.mPermissions.values()) {
   1439                 if (group == null) {
   1440                     if (p.perm == null || p.perm.info.group == null) {
   1441                         out.add(generatePermissionInfo(p, flags));
   1442                     }
   1443                 } else {
   1444                     if (p.perm != null && group.equals(p.perm.info.group)) {
   1445                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
   1446                     }
   1447                 }
   1448             }
   1449 
   1450             if (out.size() > 0) {
   1451                 return out;
   1452             }
   1453             return mPermissionGroups.containsKey(group) ? out : null;
   1454         }
   1455     }
   1456 
   1457     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
   1458         synchronized (mPackages) {
   1459             return PackageParser.generatePermissionGroupInfo(
   1460                     mPermissionGroups.get(name), flags);
   1461         }
   1462     }
   1463 
   1464     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
   1465         synchronized (mPackages) {
   1466             final int N = mPermissionGroups.size();
   1467             ArrayList<PermissionGroupInfo> out
   1468                     = new ArrayList<PermissionGroupInfo>(N);
   1469             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
   1470                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
   1471             }
   1472             return out;
   1473         }
   1474     }
   1475 
   1476     private ApplicationInfo generateApplicationInfoFromSettingsLP(String packageName, int flags) {
   1477         PackageSetting ps = mSettings.mPackages.get(packageName);
   1478         if(ps != null) {
   1479             if(ps.pkg == null) {
   1480                 PackageInfo pInfo = generatePackageInfoFromSettingsLP(packageName, flags);
   1481                 if(pInfo != null) {
   1482                     return pInfo.applicationInfo;
   1483                 }
   1484                 return null;
   1485             }
   1486             return PackageParser.generateApplicationInfo(ps.pkg, flags);
   1487         }
   1488         return null;
   1489     }
   1490 
   1491     private PackageInfo generatePackageInfoFromSettingsLP(String packageName, int flags) {
   1492         PackageSetting ps = mSettings.mPackages.get(packageName);
   1493         if(ps != null) {
   1494             if(ps.pkg == null) {
   1495                 ps.pkg = new PackageParser.Package(packageName);
   1496                 ps.pkg.applicationInfo.packageName = packageName;
   1497                 ps.pkg.applicationInfo.flags = ps.pkgFlags;
   1498                 ps.pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
   1499                 ps.pkg.applicationInfo.sourceDir = ps.codePathString;
   1500                 ps.pkg.applicationInfo.dataDir = getDataPathForPackage(ps.pkg).getPath();
   1501                 ps.pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
   1502                 ps.pkg.mSetEnabled = ps.enabled;
   1503             }
   1504             return generatePackageInfo(ps.pkg, flags);
   1505         }
   1506         return null;
   1507     }
   1508 
   1509     public ApplicationInfo getApplicationInfo(String packageName, int flags) {
   1510         synchronized (mPackages) {
   1511             PackageParser.Package p = mPackages.get(packageName);
   1512             if (Config.LOGV) Log.v(
   1513                     TAG, "getApplicationInfo " + packageName
   1514                     + ": " + p);
   1515             if (p != null) {
   1516                 // Note: isEnabledLP() does not apply here - always return info
   1517                 return PackageParser.generateApplicationInfo(p, flags);
   1518             }
   1519             if ("android".equals(packageName)||"system".equals(packageName)) {
   1520                 return mAndroidApplication;
   1521             }
   1522             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   1523                 return generateApplicationInfoFromSettingsLP(packageName, flags);
   1524             }
   1525         }
   1526         return null;
   1527     }
   1528 
   1529 
   1530     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
   1531         mContext.enforceCallingOrSelfPermission(
   1532                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   1533         // Queue up an async operation since clearing cache may take a little while.
   1534         mHandler.post(new Runnable() {
   1535             public void run() {
   1536                 mHandler.removeCallbacks(this);
   1537                 int retCode = -1;
   1538                 if (mInstaller != null) {
   1539                     retCode = mInstaller.freeCache(freeStorageSize);
   1540                     if (retCode < 0) {
   1541                         Slog.w(TAG, "Couldn't clear application caches");
   1542                     }
   1543                 } //end if mInstaller
   1544                 if (observer != null) {
   1545                     try {
   1546                         observer.onRemoveCompleted(null, (retCode >= 0));
   1547                     } catch (RemoteException e) {
   1548                         Slog.w(TAG, "RemoveException when invoking call back");
   1549                     }
   1550                 }
   1551             }
   1552         });
   1553     }
   1554 
   1555     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
   1556         mContext.enforceCallingOrSelfPermission(
   1557                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   1558         // Queue up an async operation since clearing cache may take a little while.
   1559         mHandler.post(new Runnable() {
   1560             public void run() {
   1561                 mHandler.removeCallbacks(this);
   1562                 int retCode = -1;
   1563                 if (mInstaller != null) {
   1564                     retCode = mInstaller.freeCache(freeStorageSize);
   1565                     if (retCode < 0) {
   1566                         Slog.w(TAG, "Couldn't clear application caches");
   1567                     }
   1568                 }
   1569                 if(pi != null) {
   1570                     try {
   1571                         // Callback via pending intent
   1572                         int code = (retCode >= 0) ? 1 : 0;
   1573                         pi.sendIntent(null, code, null,
   1574                                 null, null);
   1575                     } catch (SendIntentException e1) {
   1576                         Slog.i(TAG, "Failed to send pending intent");
   1577                     }
   1578                 }
   1579             }
   1580         });
   1581     }
   1582 
   1583     public ActivityInfo getActivityInfo(ComponentName component, int flags) {
   1584         synchronized (mPackages) {
   1585             PackageParser.Activity a = mActivities.mActivities.get(component);
   1586 
   1587             if (Config.LOGV) Log.v(TAG, "getActivityInfo " + component + ": " + a);
   1588             if (a != null && mSettings.isEnabledLP(a.info, flags)) {
   1589                 return PackageParser.generateActivityInfo(a, flags);
   1590             }
   1591             if (mResolveComponentName.equals(component)) {
   1592                 return mResolveActivity;
   1593             }
   1594         }
   1595         return null;
   1596     }
   1597 
   1598     public ActivityInfo getReceiverInfo(ComponentName component, int flags) {
   1599         synchronized (mPackages) {
   1600             PackageParser.Activity a = mReceivers.mActivities.get(component);
   1601             if (Config.LOGV) Log.v(
   1602                 TAG, "getReceiverInfo " + component + ": " + a);
   1603             if (a != null && mSettings.isEnabledLP(a.info, flags)) {
   1604                 return PackageParser.generateActivityInfo(a, flags);
   1605             }
   1606         }
   1607         return null;
   1608     }
   1609 
   1610     public ServiceInfo getServiceInfo(ComponentName component, int flags) {
   1611         synchronized (mPackages) {
   1612             PackageParser.Service s = mServices.mServices.get(component);
   1613             if (Config.LOGV) Log.v(
   1614                 TAG, "getServiceInfo " + component + ": " + s);
   1615             if (s != null && mSettings.isEnabledLP(s.info, flags)) {
   1616                 return PackageParser.generateServiceInfo(s, flags);
   1617             }
   1618         }
   1619         return null;
   1620     }
   1621 
   1622     public ProviderInfo getProviderInfo(ComponentName component, int flags) {
   1623         synchronized (mPackages) {
   1624             PackageParser.Provider p = mProvidersByComponent.get(component);
   1625             if (Config.LOGV) Log.v(
   1626                 TAG, "getProviderInfo " + component + ": " + p);
   1627             if (p != null && mSettings.isEnabledLP(p.info, flags)) {
   1628                 return PackageParser.generateProviderInfo(p, flags);
   1629             }
   1630         }
   1631         return null;
   1632     }
   1633 
   1634     public String[] getSystemSharedLibraryNames() {
   1635         Set<String> libSet;
   1636         synchronized (mPackages) {
   1637             libSet = mSharedLibraries.keySet();
   1638             int size = libSet.size();
   1639             if (size > 0) {
   1640                 String[] libs = new String[size];
   1641                 libSet.toArray(libs);
   1642                 return libs;
   1643             }
   1644         }
   1645         return null;
   1646     }
   1647 
   1648     public FeatureInfo[] getSystemAvailableFeatures() {
   1649         Collection<FeatureInfo> featSet;
   1650         synchronized (mPackages) {
   1651             featSet = mAvailableFeatures.values();
   1652             int size = featSet.size();
   1653             if (size > 0) {
   1654                 FeatureInfo[] features = new FeatureInfo[size+1];
   1655                 featSet.toArray(features);
   1656                 FeatureInfo fi = new FeatureInfo();
   1657                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
   1658                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
   1659                 features[size] = fi;
   1660                 return features;
   1661             }
   1662         }
   1663         return null;
   1664     }
   1665 
   1666     public boolean hasSystemFeature(String name) {
   1667         synchronized (mPackages) {
   1668             return mAvailableFeatures.containsKey(name);
   1669         }
   1670     }
   1671 
   1672     public int checkPermission(String permName, String pkgName) {
   1673         synchronized (mPackages) {
   1674             PackageParser.Package p = mPackages.get(pkgName);
   1675             if (p != null && p.mExtras != null) {
   1676                 PackageSetting ps = (PackageSetting)p.mExtras;
   1677                 if (ps.sharedUser != null) {
   1678                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
   1679                         return PackageManager.PERMISSION_GRANTED;
   1680                     }
   1681                 } else if (ps.grantedPermissions.contains(permName)) {
   1682                     return PackageManager.PERMISSION_GRANTED;
   1683                 }
   1684             }
   1685         }
   1686         return PackageManager.PERMISSION_DENIED;
   1687     }
   1688 
   1689     public int checkUidPermission(String permName, int uid) {
   1690         synchronized (mPackages) {
   1691             Object obj = mSettings.getUserIdLP(uid);
   1692             if (obj != null) {
   1693                 GrantedPermissions gp = (GrantedPermissions)obj;
   1694                 if (gp.grantedPermissions.contains(permName)) {
   1695                     return PackageManager.PERMISSION_GRANTED;
   1696                 }
   1697             } else {
   1698                 HashSet<String> perms = mSystemPermissions.get(uid);
   1699                 if (perms != null && perms.contains(permName)) {
   1700                     return PackageManager.PERMISSION_GRANTED;
   1701                 }
   1702             }
   1703         }
   1704         return PackageManager.PERMISSION_DENIED;
   1705     }
   1706 
   1707     private BasePermission findPermissionTreeLP(String permName) {
   1708         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
   1709             if (permName.startsWith(bp.name) &&
   1710                     permName.length() > bp.name.length() &&
   1711                     permName.charAt(bp.name.length()) == '.') {
   1712                 return bp;
   1713             }
   1714         }
   1715         return null;
   1716     }
   1717 
   1718     private BasePermission checkPermissionTreeLP(String permName) {
   1719         if (permName != null) {
   1720             BasePermission bp = findPermissionTreeLP(permName);
   1721             if (bp != null) {
   1722                 if (bp.uid == Binder.getCallingUid()) {
   1723                     return bp;
   1724                 }
   1725                 throw new SecurityException("Calling uid "
   1726                         + Binder.getCallingUid()
   1727                         + " is not allowed to add to permission tree "
   1728                         + bp.name + " owned by uid " + bp.uid);
   1729             }
   1730         }
   1731         throw new SecurityException("No permission tree found for " + permName);
   1732     }
   1733 
   1734     static boolean compareStrings(CharSequence s1, CharSequence s2) {
   1735         if (s1 == null) {
   1736             return s2 == null;
   1737         }
   1738         if (s2 == null) {
   1739             return false;
   1740         }
   1741         if (s1.getClass() != s2.getClass()) {
   1742             return false;
   1743         }
   1744         return s1.equals(s2);
   1745     }
   1746 
   1747     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
   1748         if (pi1.icon != pi2.icon) return false;
   1749         if (pi1.logo != pi2.logo) return false;
   1750         if (pi1.protectionLevel != pi2.protectionLevel) return false;
   1751         if (!compareStrings(pi1.name, pi2.name)) return false;
   1752         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
   1753         // We'll take care of setting this one.
   1754         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
   1755         // These are not currently stored in settings.
   1756         //if (!compareStrings(pi1.group, pi2.group)) return false;
   1757         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
   1758         //if (pi1.labelRes != pi2.labelRes) return false;
   1759         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
   1760         return true;
   1761     }
   1762 
   1763     boolean addPermissionLocked(PermissionInfo info, boolean async) {
   1764         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
   1765             throw new SecurityException("Label must be specified in permission");
   1766         }
   1767         BasePermission tree = checkPermissionTreeLP(info.name);
   1768         BasePermission bp = mSettings.mPermissions.get(info.name);
   1769         boolean added = bp == null;
   1770         boolean changed = true;
   1771         if (added) {
   1772             bp = new BasePermission(info.name, tree.sourcePackage,
   1773                     BasePermission.TYPE_DYNAMIC);
   1774         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
   1775             throw new SecurityException(
   1776                     "Not allowed to modify non-dynamic permission "
   1777                     + info.name);
   1778         } else {
   1779             if (bp.protectionLevel == info.protectionLevel
   1780                     && bp.perm.owner.equals(tree.perm.owner)
   1781                     && bp.uid == tree.uid
   1782                     && comparePermissionInfos(bp.perm.info, info)) {
   1783                 changed = false;
   1784             }
   1785         }
   1786         bp.protectionLevel = info.protectionLevel;
   1787         bp.perm = new PackageParser.Permission(tree.perm.owner,
   1788                 new PermissionInfo(info));
   1789         bp.perm.info.packageName = tree.perm.info.packageName;
   1790         bp.uid = tree.uid;
   1791         if (added) {
   1792             mSettings.mPermissions.put(info.name, bp);
   1793         }
   1794         if (changed) {
   1795             if (!async) {
   1796                 mSettings.writeLP();
   1797             } else {
   1798                 scheduleWriteSettingsLocked();
   1799             }
   1800         }
   1801         return added;
   1802     }
   1803 
   1804     public boolean addPermission(PermissionInfo info) {
   1805         synchronized (mPackages) {
   1806             return addPermissionLocked(info, false);
   1807         }
   1808     }
   1809 
   1810     public boolean addPermissionAsync(PermissionInfo info) {
   1811         synchronized (mPackages) {
   1812             return addPermissionLocked(info, true);
   1813         }
   1814     }
   1815 
   1816     public void removePermission(String name) {
   1817         synchronized (mPackages) {
   1818             checkPermissionTreeLP(name);
   1819             BasePermission bp = mSettings.mPermissions.get(name);
   1820             if (bp != null) {
   1821                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
   1822                     throw new SecurityException(
   1823                             "Not allowed to modify non-dynamic permission "
   1824                             + name);
   1825                 }
   1826                 mSettings.mPermissions.remove(name);
   1827                 mSettings.writeLP();
   1828             }
   1829         }
   1830     }
   1831 
   1832     public boolean isProtectedBroadcast(String actionName) {
   1833         synchronized (mPackages) {
   1834             return mProtectedBroadcasts.contains(actionName);
   1835         }
   1836     }
   1837 
   1838     public int checkSignatures(String pkg1, String pkg2) {
   1839         synchronized (mPackages) {
   1840             PackageParser.Package p1 = mPackages.get(pkg1);
   1841             PackageParser.Package p2 = mPackages.get(pkg2);
   1842             if (p1 == null || p1.mExtras == null
   1843                     || p2 == null || p2.mExtras == null) {
   1844                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   1845             }
   1846             return checkSignaturesLP(p1.mSignatures, p2.mSignatures);
   1847         }
   1848     }
   1849 
   1850     public int checkUidSignatures(int uid1, int uid2) {
   1851         synchronized (mPackages) {
   1852             Signature[] s1;
   1853             Signature[] s2;
   1854             Object obj = mSettings.getUserIdLP(uid1);
   1855             if (obj != null) {
   1856                 if (obj instanceof SharedUserSetting) {
   1857                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
   1858                 } else if (obj instanceof PackageSetting) {
   1859                     s1 = ((PackageSetting)obj).signatures.mSignatures;
   1860                 } else {
   1861                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   1862                 }
   1863             } else {
   1864                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   1865             }
   1866             obj = mSettings.getUserIdLP(uid2);
   1867             if (obj != null) {
   1868                 if (obj instanceof SharedUserSetting) {
   1869                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
   1870                 } else if (obj instanceof PackageSetting) {
   1871                     s2 = ((PackageSetting)obj).signatures.mSignatures;
   1872                 } else {
   1873                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   1874                 }
   1875             } else {
   1876                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   1877             }
   1878             return checkSignaturesLP(s1, s2);
   1879         }
   1880     }
   1881 
   1882     int checkSignaturesLP(Signature[] s1, Signature[] s2) {
   1883         if (s1 == null) {
   1884             return s2 == null
   1885                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
   1886                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
   1887         }
   1888         if (s2 == null) {
   1889             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
   1890         }
   1891         HashSet<Signature> set1 = new HashSet<Signature>();
   1892         for (Signature sig : s1) {
   1893             set1.add(sig);
   1894         }
   1895         HashSet<Signature> set2 = new HashSet<Signature>();
   1896         for (Signature sig : s2) {
   1897             set2.add(sig);
   1898         }
   1899         // Make sure s2 contains all signatures in s1.
   1900         if (set1.equals(set2)) {
   1901             return PackageManager.SIGNATURE_MATCH;
   1902         }
   1903         return PackageManager.SIGNATURE_NO_MATCH;
   1904     }
   1905 
   1906     public String[] getPackagesForUid(int uid) {
   1907         synchronized (mPackages) {
   1908             Object obj = mSettings.getUserIdLP(uid);
   1909             if (obj instanceof SharedUserSetting) {
   1910                 SharedUserSetting sus = (SharedUserSetting)obj;
   1911                 final int N = sus.packages.size();
   1912                 String[] res = new String[N];
   1913                 Iterator<PackageSetting> it = sus.packages.iterator();
   1914                 int i=0;
   1915                 while (it.hasNext()) {
   1916                     res[i++] = it.next().name;
   1917                 }
   1918                 return res;
   1919             } else if (obj instanceof PackageSetting) {
   1920                 PackageSetting ps = (PackageSetting)obj;
   1921                 return new String[] { ps.name };
   1922             }
   1923         }
   1924         return null;
   1925     }
   1926 
   1927     public String getNameForUid(int uid) {
   1928         synchronized (mPackages) {
   1929             Object obj = mSettings.getUserIdLP(uid);
   1930             if (obj instanceof SharedUserSetting) {
   1931                 SharedUserSetting sus = (SharedUserSetting)obj;
   1932                 return sus.name + ":" + sus.userId;
   1933             } else if (obj instanceof PackageSetting) {
   1934                 PackageSetting ps = (PackageSetting)obj;
   1935                 return ps.name;
   1936             }
   1937         }
   1938         return null;
   1939     }
   1940 
   1941     public int getUidForSharedUser(String sharedUserName) {
   1942         if(sharedUserName == null) {
   1943             return -1;
   1944         }
   1945         synchronized (mPackages) {
   1946             SharedUserSetting suid = mSettings.getSharedUserLP(sharedUserName, 0, false);
   1947             if(suid == null) {
   1948                 return -1;
   1949             }
   1950             return suid.userId;
   1951         }
   1952     }
   1953 
   1954     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
   1955             int flags) {
   1956         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags);
   1957         return chooseBestActivity(intent, resolvedType, flags, query);
   1958     }
   1959 
   1960     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
   1961                                            int flags, List<ResolveInfo> query) {
   1962         if (query != null) {
   1963             final int N = query.size();
   1964             if (N == 1) {
   1965                 return query.get(0);
   1966             } else if (N > 1) {
   1967                 // If there is more than one activity with the same priority,
   1968                 // then let the user decide between them.
   1969                 ResolveInfo r0 = query.get(0);
   1970                 ResolveInfo r1 = query.get(1);
   1971                 if (false) {
   1972                     System.out.println(r0.activityInfo.name +
   1973                                        "=" + r0.priority + " vs " +
   1974                                        r1.activityInfo.name +
   1975                                        "=" + r1.priority);
   1976                 }
   1977                 // If the first activity has a higher priority, or a different
   1978                 // default, then it is always desireable to pick it.
   1979                 if (r0.priority != r1.priority
   1980                         || r0.preferredOrder != r1.preferredOrder
   1981                         || r0.isDefault != r1.isDefault) {
   1982                     return query.get(0);
   1983                 }
   1984                 // If we have saved a preference for a preferred activity for
   1985                 // this Intent, use that.
   1986                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
   1987                         flags, query, r0.priority);
   1988                 if (ri != null) {
   1989                     return ri;
   1990                 }
   1991                 return mResolveInfo;
   1992             }
   1993         }
   1994         return null;
   1995     }
   1996 
   1997     ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
   1998             int flags, List<ResolveInfo> query, int priority) {
   1999         synchronized (mPackages) {
   2000             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
   2001             List<PreferredActivity> prefs =
   2002                     mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
   2003                             (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
   2004             if (prefs != null && prefs.size() > 0) {
   2005                 // First figure out how good the original match set is.
   2006                 // We will only allow preferred activities that came
   2007                 // from the same match quality.
   2008                 int match = 0;
   2009                 final int N = query.size();
   2010                 if (DEBUG_PREFERRED) Log.v(TAG, "Figuring out best match...");
   2011                 for (int j=0; j<N; j++) {
   2012                     ResolveInfo ri = query.get(j);
   2013                     if (DEBUG_PREFERRED) Log.v(TAG, "Match for " + ri.activityInfo
   2014                             + ": 0x" + Integer.toHexString(match));
   2015                     if (ri.match > match) match = ri.match;
   2016                 }
   2017                 if (DEBUG_PREFERRED) Log.v(TAG, "Best match: 0x"
   2018                         + Integer.toHexString(match));
   2019                 match &= IntentFilter.MATCH_CATEGORY_MASK;
   2020                 final int M = prefs.size();
   2021                 for (int i=0; i<M; i++) {
   2022                     PreferredActivity pa = prefs.get(i);
   2023                     if (pa.mMatch != match) {
   2024                         continue;
   2025                     }
   2026                     ActivityInfo ai = getActivityInfo(pa.mActivity, flags);
   2027                     if (DEBUG_PREFERRED) {
   2028                         Log.v(TAG, "Got preferred activity:");
   2029                         if (ai != null) {
   2030                             ai.dump(new LogPrinter(Log.VERBOSE, TAG), "  ");
   2031                         } else {
   2032                             Log.v(TAG, "  null");
   2033                         }
   2034                     }
   2035                     if (ai != null) {
   2036                         for (int j=0; j<N; j++) {
   2037                             ResolveInfo ri = query.get(j);
   2038                             if (!ri.activityInfo.applicationInfo.packageName
   2039                                     .equals(ai.applicationInfo.packageName)) {
   2040                                 continue;
   2041                             }
   2042                             if (!ri.activityInfo.name.equals(ai.name)) {
   2043                                 continue;
   2044                             }
   2045 
   2046                             // Okay we found a previously set preferred app.
   2047                             // If the result set is different from when this
   2048                             // was created, we need to clear it and re-ask the
   2049                             // user their preference.
   2050                             if (!pa.sameSet(query, priority)) {
   2051                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
   2052                                         + intent + " type " + resolvedType);
   2053                                 mSettings.mPreferredActivities.removeFilter(pa);
   2054                                 return null;
   2055                             }
   2056 
   2057                             // Yay!
   2058                             return ri;
   2059                         }
   2060                     }
   2061                 }
   2062             }
   2063         }
   2064         return null;
   2065     }
   2066 
   2067     public List<ResolveInfo> queryIntentActivities(Intent intent,
   2068             String resolvedType, int flags) {
   2069         ComponentName comp = intent.getComponent();
   2070         if (comp != null) {
   2071             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2072             ActivityInfo ai = getActivityInfo(comp, flags);
   2073             if (ai != null) {
   2074                 ResolveInfo ri = new ResolveInfo();
   2075                 ri.activityInfo = ai;
   2076                 list.add(ri);
   2077             }
   2078             return list;
   2079         }
   2080 
   2081         synchronized (mPackages) {
   2082             String pkgName = intent.getPackage();
   2083             if (pkgName == null) {
   2084                 return (List<ResolveInfo>)mActivities.queryIntent(intent,
   2085                         resolvedType, flags);
   2086             }
   2087             PackageParser.Package pkg = mPackages.get(pkgName);
   2088             if (pkg != null) {
   2089                 return (List<ResolveInfo>) mActivities.queryIntentForPackage(intent,
   2090                         resolvedType, flags, pkg.activities);
   2091             }
   2092             return null;
   2093         }
   2094     }
   2095 
   2096     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
   2097             Intent[] specifics, String[] specificTypes, Intent intent,
   2098             String resolvedType, int flags) {
   2099         final String resultsAction = intent.getAction();
   2100 
   2101         List<ResolveInfo> results = queryIntentActivities(
   2102             intent, resolvedType, flags|PackageManager.GET_RESOLVED_FILTER);
   2103         if (Config.LOGV) Log.v(TAG, "Query " + intent + ": " + results);
   2104 
   2105         int specificsPos = 0;
   2106         int N;
   2107 
   2108         // todo: note that the algorithm used here is O(N^2).  This
   2109         // isn't a problem in our current environment, but if we start running
   2110         // into situations where we have more than 5 or 10 matches then this
   2111         // should probably be changed to something smarter...
   2112 
   2113         // First we go through and resolve each of the specific items
   2114         // that were supplied, taking care of removing any corresponding
   2115         // duplicate items in the generic resolve list.
   2116         if (specifics != null) {
   2117             for (int i=0; i<specifics.length; i++) {
   2118                 final Intent sintent = specifics[i];
   2119                 if (sintent == null) {
   2120                     continue;
   2121                 }
   2122 
   2123                 if (Config.LOGV) Log.v(TAG, "Specific #" + i + ": " + sintent);
   2124                 String action = sintent.getAction();
   2125                 if (resultsAction != null && resultsAction.equals(action)) {
   2126                     // If this action was explicitly requested, then don't
   2127                     // remove things that have it.
   2128                     action = null;
   2129                 }
   2130                 ComponentName comp = sintent.getComponent();
   2131                 ResolveInfo ri = null;
   2132                 ActivityInfo ai = null;
   2133                 if (comp == null) {
   2134                     ri = resolveIntent(
   2135                         sintent,
   2136                         specificTypes != null ? specificTypes[i] : null,
   2137                         flags);
   2138                     if (ri == null) {
   2139                         continue;
   2140                     }
   2141                     if (ri == mResolveInfo) {
   2142                         // ACK!  Must do something better with this.
   2143                     }
   2144                     ai = ri.activityInfo;
   2145                     comp = new ComponentName(ai.applicationInfo.packageName,
   2146                             ai.name);
   2147                 } else {
   2148                     ai = getActivityInfo(comp, flags);
   2149                     if (ai == null) {
   2150                         continue;
   2151                     }
   2152                 }
   2153 
   2154                 // Look for any generic query activities that are duplicates
   2155                 // of this specific one, and remove them from the results.
   2156                 if (Config.LOGV) Log.v(TAG, "Specific #" + i + ": " + ai);
   2157                 N = results.size();
   2158                 int j;
   2159                 for (j=specificsPos; j<N; j++) {
   2160                     ResolveInfo sri = results.get(j);
   2161                     if ((sri.activityInfo.name.equals(comp.getClassName())
   2162                             && sri.activityInfo.applicationInfo.packageName.equals(
   2163                                     comp.getPackageName()))
   2164                         || (action != null && sri.filter.matchAction(action))) {
   2165                         results.remove(j);
   2166                         if (Config.LOGV) Log.v(
   2167                             TAG, "Removing duplicate item from " + j
   2168                             + " due to specific " + specificsPos);
   2169                         if (ri == null) {
   2170                             ri = sri;
   2171                         }
   2172                         j--;
   2173                         N--;
   2174                     }
   2175                 }
   2176 
   2177                 // Add this specific item to its proper place.
   2178                 if (ri == null) {
   2179                     ri = new ResolveInfo();
   2180                     ri.activityInfo = ai;
   2181                 }
   2182                 results.add(specificsPos, ri);
   2183                 ri.specificIndex = i;
   2184                 specificsPos++;
   2185             }
   2186         }
   2187 
   2188         // Now we go through the remaining generic results and remove any
   2189         // duplicate actions that are found here.
   2190         N = results.size();
   2191         for (int i=specificsPos; i<N-1; i++) {
   2192             final ResolveInfo rii = results.get(i);
   2193             if (rii.filter == null) {
   2194                 continue;
   2195             }
   2196 
   2197             // Iterate over all of the actions of this result's intent
   2198             // filter...  typically this should be just one.
   2199             final Iterator<String> it = rii.filter.actionsIterator();
   2200             if (it == null) {
   2201                 continue;
   2202             }
   2203             while (it.hasNext()) {
   2204                 final String action = it.next();
   2205                 if (resultsAction != null && resultsAction.equals(action)) {
   2206                     // If this action was explicitly requested, then don't
   2207                     // remove things that have it.
   2208                     continue;
   2209                 }
   2210                 for (int j=i+1; j<N; j++) {
   2211                     final ResolveInfo rij = results.get(j);
   2212                     if (rij.filter != null && rij.filter.hasAction(action)) {
   2213                         results.remove(j);
   2214                         if (Config.LOGV) Log.v(
   2215                             TAG, "Removing duplicate item from " + j
   2216                             + " due to action " + action + " at " + i);
   2217                         j--;
   2218                         N--;
   2219                     }
   2220                 }
   2221             }
   2222 
   2223             // If the caller didn't request filter information, drop it now
   2224             // so we don't have to marshall/unmarshall it.
   2225             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   2226                 rii.filter = null;
   2227             }
   2228         }
   2229 
   2230         // Filter out the caller activity if so requested.
   2231         if (caller != null) {
   2232             N = results.size();
   2233             for (int i=0; i<N; i++) {
   2234                 ActivityInfo ainfo = results.get(i).activityInfo;
   2235                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
   2236                         && caller.getClassName().equals(ainfo.name)) {
   2237                     results.remove(i);
   2238                     break;
   2239                 }
   2240             }
   2241         }
   2242 
   2243         // If the caller didn't request filter information,
   2244         // drop them now so we don't have to
   2245         // marshall/unmarshall it.
   2246         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   2247             N = results.size();
   2248             for (int i=0; i<N; i++) {
   2249                 results.get(i).filter = null;
   2250             }
   2251         }
   2252 
   2253         if (Config.LOGV) Log.v(TAG, "Result: " + results);
   2254         return results;
   2255     }
   2256 
   2257     public List<ResolveInfo> queryIntentReceivers(Intent intent,
   2258             String resolvedType, int flags) {
   2259         ComponentName comp = intent.getComponent();
   2260         if (comp != null) {
   2261             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2262             ActivityInfo ai = getReceiverInfo(comp, flags);
   2263             if (ai != null) {
   2264                 ResolveInfo ri = new ResolveInfo();
   2265                 ri.activityInfo = ai;
   2266                 list.add(ri);
   2267             }
   2268             return list;
   2269         }
   2270 
   2271         synchronized (mPackages) {
   2272             String pkgName = intent.getPackage();
   2273             if (pkgName == null) {
   2274                 return (List<ResolveInfo>)mReceivers.queryIntent(intent,
   2275                         resolvedType, flags);
   2276             }
   2277             PackageParser.Package pkg = mPackages.get(pkgName);
   2278             if (pkg != null) {
   2279                 return (List<ResolveInfo>) mReceivers.queryIntentForPackage(intent,
   2280                         resolvedType, flags, pkg.receivers);
   2281             }
   2282             return null;
   2283         }
   2284     }
   2285 
   2286     public ResolveInfo resolveService(Intent intent, String resolvedType,
   2287             int flags) {
   2288         List<ResolveInfo> query = queryIntentServices(intent, resolvedType,
   2289                 flags);
   2290         if (query != null) {
   2291             if (query.size() >= 1) {
   2292                 // If there is more than one service with the same priority,
   2293                 // just arbitrarily pick the first one.
   2294                 return query.get(0);
   2295             }
   2296         }
   2297         return null;
   2298     }
   2299 
   2300     public List<ResolveInfo> queryIntentServices(Intent intent,
   2301             String resolvedType, int flags) {
   2302         ComponentName comp = intent.getComponent();
   2303         if (comp != null) {
   2304             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2305             ServiceInfo si = getServiceInfo(comp, flags);
   2306             if (si != null) {
   2307                 ResolveInfo ri = new ResolveInfo();
   2308                 ri.serviceInfo = si;
   2309                 list.add(ri);
   2310             }
   2311             return list;
   2312         }
   2313 
   2314         synchronized (mPackages) {
   2315             String pkgName = intent.getPackage();
   2316             if (pkgName == null) {
   2317                 return (List<ResolveInfo>)mServices.queryIntent(intent,
   2318                         resolvedType, flags);
   2319             }
   2320             PackageParser.Package pkg = mPackages.get(pkgName);
   2321             if (pkg != null) {
   2322                 return (List<ResolveInfo>)mServices.queryIntentForPackage(intent,
   2323                         resolvedType, flags, pkg.services);
   2324             }
   2325             return null;
   2326         }
   2327     }
   2328 
   2329     private static final int getContinuationPoint(final String[] keys, final String key) {
   2330         final int index;
   2331         if (key == null) {
   2332             index = 0;
   2333         } else {
   2334             final int insertPoint = Arrays.binarySearch(keys, key);
   2335             if (insertPoint < 0) {
   2336                 index = -insertPoint;
   2337             } else {
   2338                 index = insertPoint + 1;
   2339             }
   2340         }
   2341         return index;
   2342     }
   2343 
   2344     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead) {
   2345         final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
   2346         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   2347         final String[] keys;
   2348 
   2349         synchronized (mPackages) {
   2350             if (listUninstalled) {
   2351                 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
   2352             } else {
   2353                 keys = mPackages.keySet().toArray(new String[mPackages.size()]);
   2354             }
   2355 
   2356             Arrays.sort(keys);
   2357             int i = getContinuationPoint(keys, lastRead);
   2358             final int N = keys.length;
   2359 
   2360             while (i < N) {
   2361                 final String packageName = keys[i++];
   2362 
   2363                 PackageInfo pi = null;
   2364                 if (listUninstalled) {
   2365                     final PackageSetting ps = mSettings.mPackages.get(packageName);
   2366                     if (ps != null) {
   2367                         pi = generatePackageInfoFromSettingsLP(ps.name, flags);
   2368                     }
   2369                 } else {
   2370                     final PackageParser.Package p = mPackages.get(packageName);
   2371                     if (p != null) {
   2372                         pi = generatePackageInfo(p, flags);
   2373                     }
   2374                 }
   2375 
   2376                 if (pi != null && !list.append(pi)) {
   2377                     break;
   2378                 }
   2379             }
   2380 
   2381             if (i == N) {
   2382                 list.setLastSlice(true);
   2383             }
   2384         }
   2385 
   2386         return list;
   2387     }
   2388 
   2389     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
   2390             String lastRead) {
   2391         final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>();
   2392         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   2393         final String[] keys;
   2394 
   2395         synchronized (mPackages) {
   2396             if (listUninstalled) {
   2397                 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
   2398             } else {
   2399                 keys = mPackages.keySet().toArray(new String[mPackages.size()]);
   2400             }
   2401 
   2402             Arrays.sort(keys);
   2403             int i = getContinuationPoint(keys, lastRead);
   2404             final int N = keys.length;
   2405 
   2406             while (i < N) {
   2407                 final String packageName = keys[i++];
   2408 
   2409                 ApplicationInfo ai = null;
   2410                 if (listUninstalled) {
   2411                     final PackageSetting ps = mSettings.mPackages.get(packageName);
   2412                     if (ps != null) {
   2413                         ai = generateApplicationInfoFromSettingsLP(ps.name, flags);
   2414                     }
   2415                 } else {
   2416                     final PackageParser.Package p = mPackages.get(packageName);
   2417                     if (p != null) {
   2418                         ai = PackageParser.generateApplicationInfo(p, flags);
   2419                     }
   2420                 }
   2421 
   2422                 if (ai != null && !list.append(ai)) {
   2423                     break;
   2424                 }
   2425             }
   2426 
   2427             if (i == N) {
   2428                 list.setLastSlice(true);
   2429             }
   2430         }
   2431 
   2432         return list;
   2433     }
   2434 
   2435     public List<ApplicationInfo> getPersistentApplications(int flags) {
   2436         ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
   2437 
   2438         synchronized (mPackages) {
   2439             Iterator<PackageParser.Package> i = mPackages.values().iterator();
   2440             while (i.hasNext()) {
   2441                 PackageParser.Package p = i.next();
   2442                 if (p.applicationInfo != null
   2443                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
   2444                         && (!mSafeMode || isSystemApp(p))) {
   2445                     finalList.add(PackageParser.generateApplicationInfo(p, flags));
   2446                 }
   2447             }
   2448         }
   2449 
   2450         return finalList;
   2451     }
   2452 
   2453     public ProviderInfo resolveContentProvider(String name, int flags) {
   2454         synchronized (mPackages) {
   2455             final PackageParser.Provider provider = mProviders.get(name);
   2456             return provider != null
   2457                     && mSettings.isEnabledLP(provider.info, flags)
   2458                     && (!mSafeMode || (provider.info.applicationInfo.flags
   2459                             &ApplicationInfo.FLAG_SYSTEM) != 0)
   2460                     ? PackageParser.generateProviderInfo(provider, flags)
   2461                     : null;
   2462         }
   2463     }
   2464 
   2465     /**
   2466      * @deprecated
   2467      */
   2468     public void querySyncProviders(List outNames, List outInfo) {
   2469         synchronized (mPackages) {
   2470             Iterator<Map.Entry<String, PackageParser.Provider>> i
   2471                 = mProviders.entrySet().iterator();
   2472 
   2473             while (i.hasNext()) {
   2474                 Map.Entry<String, PackageParser.Provider> entry = i.next();
   2475                 PackageParser.Provider p = entry.getValue();
   2476 
   2477                 if (p.syncable
   2478                         && (!mSafeMode || (p.info.applicationInfo.flags
   2479                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
   2480                     outNames.add(entry.getKey());
   2481                     outInfo.add(PackageParser.generateProviderInfo(p, 0));
   2482                 }
   2483             }
   2484         }
   2485     }
   2486 
   2487     public List<ProviderInfo> queryContentProviders(String processName,
   2488             int uid, int flags) {
   2489         ArrayList<ProviderInfo> finalList = null;
   2490 
   2491         synchronized (mPackages) {
   2492             Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
   2493             while (i.hasNext()) {
   2494                 PackageParser.Provider p = i.next();
   2495                 if (p.info.authority != null
   2496                     && (processName == null ||
   2497                             (p.info.processName.equals(processName)
   2498                                     && p.info.applicationInfo.uid == uid))
   2499                     && mSettings.isEnabledLP(p.info, flags)
   2500                     && (!mSafeMode || (p.info.applicationInfo.flags
   2501                             &ApplicationInfo.FLAG_SYSTEM) != 0)) {
   2502                     if (finalList == null) {
   2503                         finalList = new ArrayList<ProviderInfo>(3);
   2504                     }
   2505                     finalList.add(PackageParser.generateProviderInfo(p,
   2506                             flags));
   2507                 }
   2508             }
   2509         }
   2510 
   2511         if (finalList != null) {
   2512             Collections.sort(finalList, mProviderInitOrderSorter);
   2513         }
   2514 
   2515         return finalList;
   2516     }
   2517 
   2518     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
   2519             int flags) {
   2520         synchronized (mPackages) {
   2521             final PackageParser.Instrumentation i = mInstrumentation.get(name);
   2522             return PackageParser.generateInstrumentationInfo(i, flags);
   2523         }
   2524     }
   2525 
   2526     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
   2527             int flags) {
   2528         ArrayList<InstrumentationInfo> finalList =
   2529             new ArrayList<InstrumentationInfo>();
   2530 
   2531         synchronized (mPackages) {
   2532             Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
   2533             while (i.hasNext()) {
   2534                 PackageParser.Instrumentation p = i.next();
   2535                 if (targetPackage == null
   2536                         || targetPackage.equals(p.info.targetPackage)) {
   2537                     finalList.add(PackageParser.generateInstrumentationInfo(p,
   2538                             flags));
   2539                 }
   2540             }
   2541         }
   2542 
   2543         return finalList;
   2544     }
   2545 
   2546     private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
   2547         String[] files = dir.list();
   2548         if (files == null) {
   2549             Log.d(TAG, "No files in app dir " + dir);
   2550             return;
   2551         }
   2552 
   2553         if (false) {
   2554             Log.d(TAG, "Scanning app dir " + dir);
   2555         }
   2556 
   2557         int i;
   2558         for (i=0; i<files.length; i++) {
   2559             File file = new File(dir, files[i]);
   2560             if (!isPackageFilename(files[i])) {
   2561                 // Ignore entries which are not apk's
   2562                 continue;
   2563             }
   2564             PackageParser.Package pkg = scanPackageLI(file,
   2565                     flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);
   2566             // Don't mess around with apps in system partition.
   2567             if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
   2568                     mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
   2569                 // Delete the apk
   2570                 Slog.w(TAG, "Cleaning up failed install of " + file);
   2571                 file.delete();
   2572             }
   2573         }
   2574     }
   2575 
   2576     private static File getSettingsProblemFile() {
   2577         File dataDir = Environment.getDataDirectory();
   2578         File systemDir = new File(dataDir, "system");
   2579         File fname = new File(systemDir, "uiderrors.txt");
   2580         return fname;
   2581     }
   2582 
   2583     private static void reportSettingsProblem(int priority, String msg) {
   2584         try {
   2585             File fname = getSettingsProblemFile();
   2586             FileOutputStream out = new FileOutputStream(fname, true);
   2587             PrintWriter pw = new PrintWriter(out);
   2588             SimpleDateFormat formatter = new SimpleDateFormat();
   2589             String dateString = formatter.format(new Date(System.currentTimeMillis()));
   2590             pw.println(dateString + ": " + msg);
   2591             pw.close();
   2592             FileUtils.setPermissions(
   2593                     fname.toString(),
   2594                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
   2595                     -1, -1);
   2596         } catch (java.io.IOException e) {
   2597         }
   2598         Slog.println(priority, TAG, msg);
   2599     }
   2600 
   2601     private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
   2602             PackageParser.Package pkg, File srcFile, int parseFlags) {
   2603         if (GET_CERTIFICATES) {
   2604             if (ps != null
   2605                     && ps.codePath.equals(srcFile)
   2606                     && ps.timeStamp == srcFile.lastModified()) {
   2607                 if (ps.signatures.mSignatures != null
   2608                         && ps.signatures.mSignatures.length != 0) {
   2609                     // Optimization: reuse the existing cached certificates
   2610                     // if the package appears to be unchanged.
   2611                     pkg.mSignatures = ps.signatures.mSignatures;
   2612                     return true;
   2613                 }
   2614 
   2615                 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures.  Collecting certs again to recover them.");
   2616             } else {
   2617                 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
   2618             }
   2619 
   2620             if (!pp.collectCertificates(pkg, parseFlags)) {
   2621                 mLastScanError = pp.getParseError();
   2622                 return false;
   2623             }
   2624         }
   2625         return true;
   2626     }
   2627 
   2628     /*
   2629      *  Scan a package and return the newly parsed package.
   2630      *  Returns null in case of errors and the error code is stored in mLastScanError
   2631      */
   2632     private PackageParser.Package scanPackageLI(File scanFile,
   2633             int parseFlags, int scanMode, long currentTime) {
   2634         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   2635         String scanPath = scanFile.getPath();
   2636         parseFlags |= mDefParseFlags;
   2637         PackageParser pp = new PackageParser(scanPath);
   2638         pp.setSeparateProcesses(mSeparateProcesses);
   2639         final PackageParser.Package pkg = pp.parsePackage(scanFile,
   2640                 scanPath, mMetrics, parseFlags);
   2641         if (pkg == null) {
   2642             mLastScanError = pp.getParseError();
   2643             return null;
   2644         }
   2645         PackageSetting ps = null;
   2646         PackageSetting updatedPkg;
   2647         synchronized (mPackages) {
   2648             // Look to see if we already know about this package.
   2649             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
   2650             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
   2651                 // This package has been renamed to its original name.  Let's
   2652                 // use that.
   2653                 ps = mSettings.peekPackageLP(oldName);
   2654             }
   2655             // If there was no original package, see one for the real package name.
   2656             if (ps == null) {
   2657                 ps = mSettings.peekPackageLP(pkg.packageName);
   2658             }
   2659             // Check to see if this package could be hiding/updating a system
   2660             // package.  Must look for it either under the original or real
   2661             // package name depending on our state.
   2662             updatedPkg = mSettings.mDisabledSysPackages.get(
   2663                     ps != null ? ps.name : pkg.packageName);
   2664         }
   2665         // First check if this is a system package that may involve an update
   2666         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   2667             if (ps != null && !ps.codePath.equals(scanFile)) {
   2668                 // The path has changed from what was last scanned...  check the
   2669                 // version of the new path against what we have stored to determine
   2670                 // what to do.
   2671                 if (pkg.mVersionCode < ps.versionCode) {
   2672                     // The system package has been updated and the code path does not match
   2673                     // Ignore entry. Skip it.
   2674                     Log.i(TAG, "Package " + ps.name + " at " + scanFile
   2675                             + " ignored: updated version " + ps.versionCode
   2676                             + " better than this " + pkg.mVersionCode);
   2677                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   2678                     return null;
   2679                 } else {
   2680                     // The current app on the system partion is better than
   2681                     // what we have updated to on the data partition; switch
   2682                     // back to the system partition version.
   2683                     // At this point, its safely assumed that package installation for
   2684                     // apps in system partition will go through. If not there won't be a working
   2685                     // version of the app
   2686                     synchronized (mPackages) {
   2687                         // Just remove the loaded entries from package lists.
   2688                         mPackages.remove(ps.name);
   2689                     }
   2690                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile
   2691                             + "reverting from " + ps.codePathString
   2692                             + ": new version " + pkg.mVersionCode
   2693                             + " better than installed " + ps.versionCode);
   2694                     InstallArgs args = new FileInstallArgs(ps.codePathString,
   2695                             ps.resourcePathString, ps.nativeLibraryPathString);
   2696                     args.cleanUpResourcesLI();
   2697                     mSettings.enableSystemPackageLP(ps.name);
   2698                 }
   2699             }
   2700         }
   2701         if (updatedPkg != null) {
   2702             // An updated system app will not have the PARSE_IS_SYSTEM flag set initially
   2703             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
   2704         }
   2705         // Verify certificates against what was last scanned
   2706         if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
   2707             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
   2708             return null;
   2709         }
   2710         // The apk is forward locked (not public) if its code and resources
   2711         // are kept in different files.
   2712         // TODO grab this value from PackageSettings
   2713         if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
   2714             parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   2715         }
   2716 
   2717         String codePath = null;
   2718         String resPath = null;
   2719         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
   2720             if (ps != null && ps.resourcePathString != null) {
   2721                 resPath = ps.resourcePathString;
   2722             } else {
   2723                 // Should not happen at all. Just log an error.
   2724                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
   2725             }
   2726         } else {
   2727             resPath = pkg.mScanPath;
   2728         }
   2729         codePath = pkg.mScanPath;
   2730         // Set application objects path explicitly.
   2731         setApplicationInfoPaths(pkg, codePath, resPath);
   2732         // Note that we invoke the following method only if we are about to unpack an application
   2733         return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);
   2734     }
   2735 
   2736     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
   2737             String destResPath) {
   2738         pkg.mPath = pkg.mScanPath = destCodePath;
   2739         pkg.applicationInfo.sourceDir = destCodePath;
   2740         pkg.applicationInfo.publicSourceDir = destResPath;
   2741     }
   2742 
   2743     private static String fixProcessName(String defProcessName,
   2744             String processName, int uid) {
   2745         if (processName == null) {
   2746             return defProcessName;
   2747         }
   2748         return processName;
   2749     }
   2750 
   2751     private boolean verifySignaturesLP(PackageSetting pkgSetting,
   2752             PackageParser.Package pkg) {
   2753         if (pkgSetting.signatures.mSignatures != null) {
   2754             // Already existing package. Make sure signatures match
   2755             if (checkSignaturesLP(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
   2756                 PackageManager.SIGNATURE_MATCH) {
   2757                     Slog.e(TAG, "Package " + pkg.packageName
   2758                             + " signatures do not match the previously installed version; ignoring!");
   2759                     mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
   2760                     return false;
   2761                 }
   2762         }
   2763         // Check for shared user signatures
   2764         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
   2765             if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures,
   2766                     pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   2767                 Slog.e(TAG, "Package " + pkg.packageName
   2768                         + " has no signatures that match those in shared user "
   2769                         + pkgSetting.sharedUser.name + "; ignoring!");
   2770                 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
   2771                 return false;
   2772             }
   2773         }
   2774         return true;
   2775     }
   2776 
   2777     public boolean performDexOpt(String packageName) {
   2778         if (!mNoDexOpt) {
   2779             return false;
   2780         }
   2781 
   2782         PackageParser.Package p;
   2783         synchronized (mPackages) {
   2784             p = mPackages.get(packageName);
   2785             if (p == null || p.mDidDexOpt) {
   2786                 return false;
   2787             }
   2788         }
   2789         synchronized (mInstallLock) {
   2790             return performDexOptLI(p, false) == DEX_OPT_PERFORMED;
   2791         }
   2792     }
   2793 
   2794     static final int DEX_OPT_SKIPPED = 0;
   2795     static final int DEX_OPT_PERFORMED = 1;
   2796     static final int DEX_OPT_FAILED = -1;
   2797 
   2798     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex) {
   2799         boolean performed = false;
   2800         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0 && mInstaller != null) {
   2801             String path = pkg.mScanPath;
   2802             int ret = 0;
   2803             try {
   2804                 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
   2805                     ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
   2806                             !isForwardLocked(pkg));
   2807                     pkg.mDidDexOpt = true;
   2808                     performed = true;
   2809                 }
   2810             } catch (FileNotFoundException e) {
   2811                 Slog.w(TAG, "Apk not found for dexopt: " + path);
   2812                 ret = -1;
   2813             } catch (IOException e) {
   2814                 Slog.w(TAG, "IOException reading apk: " + path, e);
   2815                 ret = -1;
   2816             } catch (dalvik.system.StaleDexCacheError e) {
   2817                 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
   2818                 ret = -1;
   2819             } catch (Exception e) {
   2820                 Slog.w(TAG, "Exception when doing dexopt : ", e);
   2821                 ret = -1;
   2822             }
   2823             if (ret < 0) {
   2824                 //error from installer
   2825                 return DEX_OPT_FAILED;
   2826             }
   2827         }
   2828 
   2829         return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
   2830     }
   2831 
   2832     private static boolean useEncryptedFilesystemForPackage(PackageParser.Package pkg) {
   2833         return Environment.isEncryptedFilesystemEnabled() &&
   2834                 ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_NEVER_ENCRYPT) == 0);
   2835     }
   2836 
   2837     private boolean verifyPackageUpdate(PackageSetting oldPkg, PackageParser.Package newPkg) {
   2838         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   2839             Slog.w(TAG, "Unable to update from " + oldPkg.name
   2840                     + " to " + newPkg.packageName
   2841                     + ": old package not in system partition");
   2842             return false;
   2843         } else if (mPackages.get(oldPkg.name) != null) {
   2844             Slog.w(TAG, "Unable to update from " + oldPkg.name
   2845                     + " to " + newPkg.packageName
   2846                     + ": old package still exists");
   2847             return false;
   2848         }
   2849         return true;
   2850     }
   2851 
   2852     private File getDataPathForPackage(PackageParser.Package pkg) {
   2853         boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
   2854         File dataPath;
   2855         if (useEncryptedFSDir) {
   2856             dataPath = new File(mSecureAppDataDir, pkg.packageName);
   2857         } else {
   2858             dataPath = new File(mAppDataDir, pkg.packageName);
   2859         }
   2860         return dataPath;
   2861     }
   2862 
   2863     private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
   2864             int parseFlags, int scanMode, long currentTime) {
   2865         File scanFile = new File(pkg.mScanPath);
   2866         if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
   2867                 pkg.applicationInfo.publicSourceDir == null) {
   2868             // Bail out. The resource and code paths haven't been set.
   2869             Slog.w(TAG, " Code and resource paths haven't been set correctly");
   2870             mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
   2871             return null;
   2872         }
   2873         mScanningPath = scanFile;
   2874         if (pkg == null) {
   2875             mLastScanError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
   2876             return null;
   2877         }
   2878 
   2879         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   2880             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
   2881         }
   2882 
   2883         if (pkg.packageName.equals("android")) {
   2884             synchronized (mPackages) {
   2885                 if (mAndroidApplication != null) {
   2886                     Slog.w(TAG, "*************************************************");
   2887                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
   2888                     Slog.w(TAG, " file=" + mScanningPath);
   2889                     Slog.w(TAG, "*************************************************");
   2890                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   2891                     return null;
   2892                 }
   2893 
   2894                 // Set up information for our fall-back user intent resolution
   2895                 // activity.
   2896                 mPlatformPackage = pkg;
   2897                 pkg.mVersionCode = mSdkVersion;
   2898                 mAndroidApplication = pkg.applicationInfo;
   2899                 mResolveActivity.applicationInfo = mAndroidApplication;
   2900                 mResolveActivity.name = ResolverActivity.class.getName();
   2901                 mResolveActivity.packageName = mAndroidApplication.packageName;
   2902                 mResolveActivity.processName = mAndroidApplication.processName;
   2903                 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   2904                 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
   2905                 mResolveActivity.theme = com.android.internal.R.style.Theme_Dialog_Alert;
   2906                 mResolveActivity.exported = true;
   2907                 mResolveActivity.enabled = true;
   2908                 mResolveInfo.activityInfo = mResolveActivity;
   2909                 mResolveInfo.priority = 0;
   2910                 mResolveInfo.preferredOrder = 0;
   2911                 mResolveInfo.match = 0;
   2912                 mResolveComponentName = new ComponentName(
   2913                         mAndroidApplication.packageName, mResolveActivity.name);
   2914             }
   2915         }
   2916 
   2917         if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
   2918                 TAG, "Scanning package " + pkg.packageName);
   2919         if (mPackages.containsKey(pkg.packageName)
   2920                 || mSharedLibraries.containsKey(pkg.packageName)) {
   2921             Slog.w(TAG, "Application package " + pkg.packageName
   2922                     + " already installed.  Skipping duplicate.");
   2923             mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   2924             return null;
   2925         }
   2926 
   2927         // Initialize package source and resource directories
   2928         File destCodeFile = new File(pkg.applicationInfo.sourceDir);
   2929         File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
   2930 
   2931         SharedUserSetting suid = null;
   2932         PackageSetting pkgSetting = null;
   2933 
   2934         if (!isSystemApp(pkg)) {
   2935             // Only system apps can use these features.
   2936             pkg.mOriginalPackages = null;
   2937             pkg.mRealPackage = null;
   2938             pkg.mAdoptPermissions = null;
   2939         }
   2940 
   2941         synchronized (mPackages) {
   2942             // Check all shared libraries and map to their actual file path.
   2943             if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
   2944                 if (mTmpSharedLibraries == null ||
   2945                         mTmpSharedLibraries.length < mSharedLibraries.size()) {
   2946                     mTmpSharedLibraries = new String[mSharedLibraries.size()];
   2947                 }
   2948                 int num = 0;
   2949                 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
   2950                 for (int i=0; i<N; i++) {
   2951                     String file = mSharedLibraries.get(pkg.usesLibraries.get(i));
   2952                     if (file == null) {
   2953                         Slog.e(TAG, "Package " + pkg.packageName
   2954                                 + " requires unavailable shared library "
   2955                                 + pkg.usesLibraries.get(i) + "; failing!");
   2956                         mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
   2957                         return null;
   2958                     }
   2959                     mTmpSharedLibraries[num] = file;
   2960                     num++;
   2961                 }
   2962                 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
   2963                 for (int i=0; i<N; i++) {
   2964                     String file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
   2965                     if (file == null) {
   2966                         Slog.w(TAG, "Package " + pkg.packageName
   2967                                 + " desires unavailable shared library "
   2968                                 + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
   2969                     } else {
   2970                         mTmpSharedLibraries[num] = file;
   2971                         num++;
   2972                     }
   2973                 }
   2974                 if (num > 0) {
   2975                     pkg.usesLibraryFiles = new String[num];
   2976                     System.arraycopy(mTmpSharedLibraries, 0,
   2977                             pkg.usesLibraryFiles, 0, num);
   2978                 }
   2979             }
   2980 
   2981             if (pkg.mSharedUserId != null) {
   2982                 suid = mSettings.getSharedUserLP(pkg.mSharedUserId,
   2983                         pkg.applicationInfo.flags, true);
   2984                 if (suid == null) {
   2985                     Slog.w(TAG, "Creating application package " + pkg.packageName
   2986                             + " for shared user failed");
   2987                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   2988                     return null;
   2989                 }
   2990                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) {
   2991                     Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid="
   2992                             + suid.userId + "): packages=" + suid.packages);
   2993                 }
   2994             }
   2995 
   2996             if (false) {
   2997                 if (pkg.mOriginalPackages != null) {
   2998                     Log.w(TAG, "WAITING FOR DEBUGGER");
   2999                     Debug.waitForDebugger();
   3000                     Log.i(TAG, "Package " + pkg.packageName + " from original packages"
   3001                             + pkg.mOriginalPackages);
   3002                 }
   3003             }
   3004 
   3005             // Check if we are renaming from an original package name.
   3006             PackageSetting origPackage = null;
   3007             String realName = null;
   3008             if (pkg.mOriginalPackages != null) {
   3009                 // This package may need to be renamed to a previously
   3010                 // installed name.  Let's check on that...
   3011                 String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
   3012                 if (pkg.mOriginalPackages.contains(renamed)) {
   3013                     // This package had originally been installed as the
   3014                     // original name, and we have already taken care of
   3015                     // transitioning to the new one.  Just update the new
   3016                     // one to continue using the old name.
   3017                     realName = pkg.mRealPackage;
   3018                     if (!pkg.packageName.equals(renamed)) {
   3019                         // Callers into this function may have already taken
   3020                         // care of renaming the package; only do it here if
   3021                         // it is not already done.
   3022                         pkg.setPackageName(renamed);
   3023                     }
   3024 
   3025                 } else {
   3026                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
   3027                         if ((origPackage=mSettings.peekPackageLP(
   3028                                 pkg.mOriginalPackages.get(i))) != null) {
   3029                             // We do have the package already installed under its
   3030                             // original name...  should we use it?
   3031                             if (!verifyPackageUpdate(origPackage, pkg)) {
   3032                                 // New package is not compatible with original.
   3033                                 origPackage = null;
   3034                                 continue;
   3035                             } else if (origPackage.sharedUser != null) {
   3036                                 // Make sure uid is compatible between packages.
   3037                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
   3038                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
   3039                                             + " to " + pkg.packageName + ": old uid "
   3040                                             + origPackage.sharedUser.name
   3041                                             + " differs from " + pkg.mSharedUserId);
   3042                                     origPackage = null;
   3043                                     continue;
   3044                                 }
   3045                             } else {
   3046                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
   3047                                         + pkg.packageName + " to old name " + origPackage.name);
   3048                             }
   3049                             break;
   3050                         }
   3051                     }
   3052                 }
   3053             }
   3054 
   3055             if (mTransferedPackages.contains(pkg.packageName)) {
   3056                 Slog.w(TAG, "Package " + pkg.packageName
   3057                         + " was transferred to another, but its .apk remains");
   3058             }
   3059 
   3060             // Just create the setting, don't add it yet. For already existing packages
   3061             // the PkgSetting exists already and doesn't have to be created.
   3062             pkgSetting = mSettings.getPackageLP(pkg, origPackage, realName, suid, destCodeFile,
   3063                     destResourceFile, pkg.applicationInfo.nativeLibraryDir,
   3064                     pkg.applicationInfo.flags, true, false);
   3065             if (pkgSetting == null) {
   3066                 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
   3067                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3068                 return null;
   3069             }
   3070 
   3071             if (pkgSetting.origPackage != null) {
   3072                 // If we are first transitioning from an original package,
   3073                 // fix up the new package's name now.  We need to do this after
   3074                 // looking up the package under its new name, so getPackageLP
   3075                 // can take care of fiddling things correctly.
   3076                 pkg.setPackageName(origPackage.name);
   3077 
   3078                 // File a report about this.
   3079                 String msg = "New package " + pkgSetting.realName
   3080                         + " renamed to replace old package " + pkgSetting.name;
   3081                 reportSettingsProblem(Log.WARN, msg);
   3082 
   3083                 // Make a note of it.
   3084                 mTransferedPackages.add(origPackage.name);
   3085 
   3086                 // No longer need to retain this.
   3087                 pkgSetting.origPackage = null;
   3088             }
   3089 
   3090             if (realName != null) {
   3091                 // Make a note of it.
   3092                 mTransferedPackages.add(pkg.packageName);
   3093             }
   3094 
   3095             if (mSettings.mDisabledSysPackages.get(pkg.packageName) != null) {
   3096                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   3097             }
   3098 
   3099             pkg.applicationInfo.uid = pkgSetting.userId;
   3100             pkg.mExtras = pkgSetting;
   3101 
   3102             if (!verifySignaturesLP(pkgSetting, pkg)) {
   3103                 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   3104                     return null;
   3105                 }
   3106                 // The signature has changed, but this package is in the system
   3107                 // image...  let's recover!
   3108                 pkgSetting.signatures.mSignatures = pkg.mSignatures;
   3109                 // However...  if this package is part of a shared user, but it
   3110                 // doesn't match the signature of the shared user, let's fail.
   3111                 // What this means is that you can't change the signatures
   3112                 // associated with an overall shared user, which doesn't seem all
   3113                 // that unreasonable.
   3114                 if (pkgSetting.sharedUser != null) {
   3115                     if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures,
   3116                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   3117                         Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
   3118                         mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
   3119                         return null;
   3120                     }
   3121                 }
   3122                 // File a report about this.
   3123                 String msg = "System package " + pkg.packageName
   3124                         + " signature changed; retaining data.";
   3125                 reportSettingsProblem(Log.WARN, msg);
   3126             }
   3127 
   3128             // Verify that this new package doesn't have any content providers
   3129             // that conflict with existing packages.  Only do this if the
   3130             // package isn't already installed, since we don't want to break
   3131             // things that are installed.
   3132             if ((scanMode&SCAN_NEW_INSTALL) != 0) {
   3133                 int N = pkg.providers.size();
   3134                 int i;
   3135                 for (i=0; i<N; i++) {
   3136                     PackageParser.Provider p = pkg.providers.get(i);
   3137                     if (p.info.authority != null) {
   3138                         String names[] = p.info.authority.split(";");
   3139                         for (int j = 0; j < names.length; j++) {
   3140                             if (mProviders.containsKey(names[j])) {
   3141                                 PackageParser.Provider other = mProviders.get(names[j]);
   3142                                 Slog.w(TAG, "Can't install because provider name " + names[j] +
   3143                                         " (in package " + pkg.applicationInfo.packageName +
   3144                                         ") is already used by "
   3145                                         + ((other != null && other.getComponentName() != null)
   3146                                                 ? other.getComponentName().getPackageName() : "?"));
   3147                                 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
   3148                                 return null;
   3149                             }
   3150                         }
   3151                     }
   3152                 }
   3153             }
   3154         }
   3155 
   3156         final String pkgName = pkg.packageName;
   3157 
   3158         if (pkg.mAdoptPermissions != null) {
   3159             // This package wants to adopt ownership of permissions from
   3160             // another package.
   3161             for (int i=pkg.mAdoptPermissions.size()-1; i>=0; i--) {
   3162                 String origName = pkg.mAdoptPermissions.get(i);
   3163                 PackageSetting orig = mSettings.peekPackageLP(origName);
   3164                 if (orig != null) {
   3165                     if (verifyPackageUpdate(orig, pkg)) {
   3166                         Slog.i(TAG, "Adopting permissions from "
   3167                                 + origName + " to " + pkg.packageName);
   3168                         mSettings.transferPermissions(origName, pkg.packageName);
   3169                     }
   3170                 }
   3171             }
   3172         }
   3173 
   3174         final long scanFileTime = scanFile.lastModified();
   3175         final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
   3176         final boolean scanFileNewer = forceDex || scanFileTime != pkgSetting.timeStamp;
   3177         pkg.applicationInfo.processName = fixProcessName(
   3178                 pkg.applicationInfo.packageName,
   3179                 pkg.applicationInfo.processName,
   3180                 pkg.applicationInfo.uid);
   3181 
   3182         File dataPath;
   3183         if (mPlatformPackage == pkg) {
   3184             // The system package is special.
   3185             dataPath = new File (Environment.getDataDirectory(), "system");
   3186             pkg.applicationInfo.dataDir = dataPath.getPath();
   3187         } else {
   3188             // This is a normal package, need to make its data directory.
   3189             boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
   3190             dataPath = getDataPathForPackage(pkg);
   3191 
   3192             boolean uidError = false;
   3193 
   3194             if (dataPath.exists()) {
   3195                 mOutPermissions[1] = 0;
   3196                 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
   3197 
   3198                 // If we have mismatched owners for the data path, we have a
   3199                 // problem (unless we're running in the simulator.)
   3200                 if (mOutPermissions[1] != pkg.applicationInfo.uid && Process.supportsProcesses()) {
   3201                     boolean recovered = false;
   3202                     if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   3203                         // If this is a system app, we can at least delete its
   3204                         // current data so the application will still work.
   3205                         if (mInstaller != null) {
   3206                             int ret = mInstaller.remove(pkgName, useEncryptedFSDir);
   3207                             if (ret >= 0) {
   3208                                 // Old data gone!
   3209                                 String msg = "System package " + pkg.packageName
   3210                                         + " has changed from uid: "
   3211                                         + mOutPermissions[1] + " to "
   3212                                         + pkg.applicationInfo.uid + "; old data erased";
   3213                                 reportSettingsProblem(Log.WARN, msg);
   3214                                 recovered = true;
   3215 
   3216                                 // And now re-install the app.
   3217                                 ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
   3218                                         pkg.applicationInfo.uid);
   3219                                 if (ret == -1) {
   3220                                     // Ack should not happen!
   3221                                     msg = "System package " + pkg.packageName
   3222                                             + " could not have data directory re-created after delete.";
   3223                                     reportSettingsProblem(Log.WARN, msg);
   3224                                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3225                                     return null;
   3226                                 }
   3227                             }
   3228                         }
   3229                         if (!recovered) {
   3230                             mHasSystemUidErrors = true;
   3231                         }
   3232                     }
   3233                     if (!recovered) {
   3234                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
   3235                             + pkg.applicationInfo.uid + "/fs_"
   3236                             + mOutPermissions[1];
   3237                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
   3238                         String msg = "Package " + pkg.packageName
   3239                                 + " has mismatched uid: "
   3240                                 + mOutPermissions[1] + " on disk, "
   3241                                 + pkg.applicationInfo.uid + " in settings";
   3242                         synchronized (mPackages) {
   3243                             mSettings.mReadMessages.append(msg);
   3244                             mSettings.mReadMessages.append('\n');
   3245                             uidError = true;
   3246                             if (!pkgSetting.uidError) {
   3247                                 reportSettingsProblem(Log.ERROR, msg);
   3248                             }
   3249                         }
   3250                     }
   3251                 }
   3252                 pkg.applicationInfo.dataDir = dataPath.getPath();
   3253             } else {
   3254                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGV)
   3255                     Log.v(TAG, "Want this data dir: " + dataPath);
   3256                 //invoke installer to do the actual installation
   3257                 if (mInstaller != null) {
   3258                     int ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid,
   3259                             pkg.applicationInfo.uid);
   3260                     if(ret < 0) {
   3261                         // Error from installer
   3262                         mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3263                         return null;
   3264                     }
   3265                 } else {
   3266                     dataPath.mkdirs();
   3267                     if (dataPath.exists()) {
   3268                         FileUtils.setPermissions(
   3269                             dataPath.toString(),
   3270                             FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
   3271                             pkg.applicationInfo.uid, pkg.applicationInfo.uid);
   3272                     }
   3273                 }
   3274                 if (dataPath.exists()) {
   3275                     pkg.applicationInfo.dataDir = dataPath.getPath();
   3276                 } else {
   3277                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
   3278                     pkg.applicationInfo.dataDir = null;
   3279                 }
   3280             }
   3281 
   3282             /*
   3283              * Set the data dir to the default "/data/data/<package name>/lib"
   3284              * if we got here without anyone telling us different (e.g., apps
   3285              * stored on SD card have their native libraries stored in the ASEC
   3286              * container with the APK).
   3287              *
   3288              * This happens during an upgrade from a package settings file that
   3289              * doesn't have a native library path attribute at all.
   3290              */
   3291             if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
   3292                 if (pkgSetting.nativeLibraryPathString == null) {
   3293                     final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
   3294                     pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
   3295                     pkgSetting.nativeLibraryPathString = nativeLibraryPath;
   3296                 } else {
   3297                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
   3298                 }
   3299             }
   3300 
   3301             pkgSetting.uidError = uidError;
   3302         }
   3303 
   3304         // If we're running in the simulator, we don't need to unpack anything.
   3305         if (mInstaller != null) {
   3306             String path = scanFile.getPath();
   3307             /* Note: We don't want to unpack the native binaries for
   3308              *        system applications, unless they have been updated
   3309              *        (the binaries are already under /system/lib).
   3310              *        Also, don't unpack libs for apps on the external card
   3311              *        since they should have their libraries in the ASEC
   3312              *        container already.
   3313              *
   3314              *        In other words, we're going to unpack the binaries
   3315              *        only for non-system apps and system app upgrades.
   3316              */
   3317             if (pkg.applicationInfo.nativeLibraryDir != null) {
   3318                 final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
   3319                 final String dataPathString = dataPath.getPath();
   3320 
   3321                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
   3322                     /*
   3323                      * Upgrading from a previous version of the OS sometimes
   3324                      * leaves native libraries in the /data/data/<app>/lib
   3325                      * directory for system apps even when they shouldn't be.
   3326                      * Recent changes in the JNI library search path
   3327                      * necessitates we remove those to match previous behavior.
   3328                      */
   3329                     if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
   3330                         Log.i(TAG, "removed obsolete native libraries for system package " + path);
   3331                     }
   3332                 } else if (nativeLibraryDir.getParent().equals(dataPathString)) {
   3333                     /*
   3334                      * If this is an internal application or our
   3335                      * nativeLibraryPath points to our data directory, unpack
   3336                      * the libraries. The native library path pointing to the
   3337                      * data directory for an application in an ASEC container
   3338                      * can happen for older apps that existed before an OTA to
   3339                      * Gingerbread.
   3340                      */
   3341                     Slog.i(TAG, "Unpacking native libraries for " + path);
   3342                     mInstaller.unlinkNativeLibraryDirectory(dataPathString);
   3343                     NativeLibraryHelper.copyNativeBinariesLI(scanFile, nativeLibraryDir);
   3344                 } else {
   3345                     Slog.i(TAG, "Linking native library dir for " + path);
   3346                     mInstaller.linkNativeLibraryDirectory(dataPathString,
   3347                             pkg.applicationInfo.nativeLibraryDir);
   3348                 }
   3349             }
   3350             pkg.mScanPath = path;
   3351 
   3352             if ((scanMode&SCAN_NO_DEX) == 0) {
   3353                 if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) {
   3354                     mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
   3355                     return null;
   3356                 }
   3357             }
   3358         }
   3359 
   3360         if (mFactoryTest && pkg.requestedPermissions.contains(
   3361                 android.Manifest.permission.FACTORY_TEST)) {
   3362             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
   3363         }
   3364 
   3365         // Request the ActivityManager to kill the process(only for existing packages)
   3366         // so that we do not end up in a confused state while the user is still using the older
   3367         // version of the application while the new one gets installed.
   3368         if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   3369             killApplication(pkg.applicationInfo.packageName,
   3370                         pkg.applicationInfo.uid);
   3371         }
   3372 
   3373         synchronized (mPackages) {
   3374             // We don't expect installation to fail beyond this point,
   3375             if ((scanMode&SCAN_MONITOR) != 0) {
   3376                 mAppDirs.put(pkg.mPath, pkg);
   3377             }
   3378             // Add the new setting to mSettings
   3379             mSettings.insertPackageSettingLP(pkgSetting, pkg);
   3380             // Add the new setting to mPackages
   3381             mPackages.put(pkg.applicationInfo.packageName, pkg);
   3382             // Make sure we don't accidentally delete its data.
   3383             mSettings.mPackagesToBeCleaned.remove(pkgName);
   3384 
   3385             // Take care of first install / last update times.
   3386             if (currentTime != 0) {
   3387                 if (pkgSetting.firstInstallTime == 0) {
   3388                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
   3389                 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
   3390                     pkgSetting.lastUpdateTime = currentTime;
   3391                 }
   3392             } else if (pkgSetting.firstInstallTime == 0) {
   3393                 // We need *something*.  Take time time stamp of the file.
   3394                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
   3395             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
   3396                 if (scanFileTime != pkgSetting.timeStamp) {
   3397                     // A package on the system image has changed; consider this
   3398                     // to be an update.
   3399                     pkgSetting.lastUpdateTime = scanFileTime;
   3400                 }
   3401             }
   3402 
   3403             int N = pkg.providers.size();
   3404             StringBuilder r = null;
   3405             int i;
   3406             for (i=0; i<N; i++) {
   3407                 PackageParser.Provider p = pkg.providers.get(i);
   3408                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
   3409                         p.info.processName, pkg.applicationInfo.uid);
   3410                 mProvidersByComponent.put(new ComponentName(p.info.packageName,
   3411                         p.info.name), p);
   3412                 p.syncable = p.info.isSyncable;
   3413                 if (p.info.authority != null) {
   3414                     String names[] = p.info.authority.split(";");
   3415                     p.info.authority = null;
   3416                     for (int j = 0; j < names.length; j++) {
   3417                         if (j == 1 && p.syncable) {
   3418                             // We only want the first authority for a provider to possibly be
   3419                             // syncable, so if we already added this provider using a different
   3420                             // authority clear the syncable flag. We copy the provider before
   3421                             // changing it because the mProviders object contains a reference
   3422                             // to a provider that we don't want to change.
   3423                             // Only do this for the second authority since the resulting provider
   3424                             // object can be the same for all future authorities for this provider.
   3425                             p = new PackageParser.Provider(p);
   3426                             p.syncable = false;
   3427                         }
   3428                         if (!mProviders.containsKey(names[j])) {
   3429                             mProviders.put(names[j], p);
   3430                             if (p.info.authority == null) {
   3431                                 p.info.authority = names[j];
   3432                             } else {
   3433                                 p.info.authority = p.info.authority + ";" + names[j];
   3434                             }
   3435                             if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD)
   3436                                 Log.d(TAG, "Registered content provider: " + names[j] +
   3437                                         ", className = " + p.info.name +
   3438                                         ", isSyncable = " + p.info.isSyncable);
   3439                         } else {
   3440                             PackageParser.Provider other = mProviders.get(names[j]);
   3441                             Slog.w(TAG, "Skipping provider name " + names[j] +
   3442                                     " (in package " + pkg.applicationInfo.packageName +
   3443                                     "): name already used by "
   3444                                     + ((other != null && other.getComponentName() != null)
   3445                                             ? other.getComponentName().getPackageName() : "?"));
   3446                         }
   3447                     }
   3448                 }
   3449                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3450                     if (r == null) {
   3451                         r = new StringBuilder(256);
   3452                     } else {
   3453                         r.append(' ');
   3454                     }
   3455                     r.append(p.info.name);
   3456                 }
   3457             }
   3458             if (r != null) {
   3459                 if (Config.LOGD) Log.d(TAG, "  Providers: " + r);
   3460             }
   3461 
   3462             N = pkg.services.size();
   3463             r = null;
   3464             for (i=0; i<N; i++) {
   3465                 PackageParser.Service s = pkg.services.get(i);
   3466                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
   3467                         s.info.processName, pkg.applicationInfo.uid);
   3468                 mServices.addService(s);
   3469                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3470                     if (r == null) {
   3471                         r = new StringBuilder(256);
   3472                     } else {
   3473                         r.append(' ');
   3474                     }
   3475                     r.append(s.info.name);
   3476                 }
   3477             }
   3478             if (r != null) {
   3479                 if (Config.LOGD) Log.d(TAG, "  Services: " + r);
   3480             }
   3481 
   3482             N = pkg.receivers.size();
   3483             r = null;
   3484             for (i=0; i<N; i++) {
   3485                 PackageParser.Activity a = pkg.receivers.get(i);
   3486                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   3487                         a.info.processName, pkg.applicationInfo.uid);
   3488                 mReceivers.addActivity(a, "receiver");
   3489                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3490                     if (r == null) {
   3491                         r = new StringBuilder(256);
   3492                     } else {
   3493                         r.append(' ');
   3494                     }
   3495                     r.append(a.info.name);
   3496                 }
   3497             }
   3498             if (r != null) {
   3499                 if (Config.LOGD) Log.d(TAG, "  Receivers: " + r);
   3500             }
   3501 
   3502             N = pkg.activities.size();
   3503             r = null;
   3504             for (i=0; i<N; i++) {
   3505                 PackageParser.Activity a = pkg.activities.get(i);
   3506                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   3507                         a.info.processName, pkg.applicationInfo.uid);
   3508                 mActivities.addActivity(a, "activity");
   3509                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3510                     if (r == null) {
   3511                         r = new StringBuilder(256);
   3512                     } else {
   3513                         r.append(' ');
   3514                     }
   3515                     r.append(a.info.name);
   3516                 }
   3517             }
   3518             if (r != null) {
   3519                 if (Config.LOGD) Log.d(TAG, "  Activities: " + r);
   3520             }
   3521 
   3522             N = pkg.permissionGroups.size();
   3523             r = null;
   3524             for (i=0; i<N; i++) {
   3525                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
   3526                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
   3527                 if (cur == null) {
   3528                     mPermissionGroups.put(pg.info.name, pg);
   3529                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3530                         if (r == null) {
   3531                             r = new StringBuilder(256);
   3532                         } else {
   3533                             r.append(' ');
   3534                         }
   3535                         r.append(pg.info.name);
   3536                     }
   3537                 } else {
   3538                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
   3539                             + pg.info.packageName + " ignored: original from "
   3540                             + cur.info.packageName);
   3541                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3542                         if (r == null) {
   3543                             r = new StringBuilder(256);
   3544                         } else {
   3545                             r.append(' ');
   3546                         }
   3547                         r.append("DUP:");
   3548                         r.append(pg.info.name);
   3549                     }
   3550                 }
   3551             }
   3552             if (r != null) {
   3553                 if (Config.LOGD) Log.d(TAG, "  Permission Groups: " + r);
   3554             }
   3555 
   3556             N = pkg.permissions.size();
   3557             r = null;
   3558             for (i=0; i<N; i++) {
   3559                 PackageParser.Permission p = pkg.permissions.get(i);
   3560                 HashMap<String, BasePermission> permissionMap =
   3561                         p.tree ? mSettings.mPermissionTrees
   3562                         : mSettings.mPermissions;
   3563                 p.group = mPermissionGroups.get(p.info.group);
   3564                 if (p.info.group == null || p.group != null) {
   3565                     BasePermission bp = permissionMap.get(p.info.name);
   3566                     if (bp == null) {
   3567                         bp = new BasePermission(p.info.name, p.info.packageName,
   3568                                 BasePermission.TYPE_NORMAL);
   3569                         permissionMap.put(p.info.name, bp);
   3570                     }
   3571                     if (bp.perm == null) {
   3572                         if (bp.sourcePackage == null
   3573                                 || bp.sourcePackage.equals(p.info.packageName)) {
   3574                             BasePermission tree = findPermissionTreeLP(p.info.name);
   3575                             if (tree == null
   3576                                     || tree.sourcePackage.equals(p.info.packageName)) {
   3577                                 bp.packageSetting = pkgSetting;
   3578                                 bp.perm = p;
   3579                                 bp.uid = pkg.applicationInfo.uid;
   3580                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3581                                     if (r == null) {
   3582                                         r = new StringBuilder(256);
   3583                                     } else {
   3584                                         r.append(' ');
   3585                                     }
   3586                                     r.append(p.info.name);
   3587                                 }
   3588                             } else {
   3589                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
   3590                                         + p.info.packageName + " ignored: base tree "
   3591                                         + tree.name + " is from package "
   3592                                         + tree.sourcePackage);
   3593                             }
   3594                         } else {
   3595                             Slog.w(TAG, "Permission " + p.info.name + " from package "
   3596                                     + p.info.packageName + " ignored: original from "
   3597                                     + bp.sourcePackage);
   3598                         }
   3599                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3600                         if (r == null) {
   3601                             r = new StringBuilder(256);
   3602                         } else {
   3603                             r.append(' ');
   3604                         }
   3605                         r.append("DUP:");
   3606                         r.append(p.info.name);
   3607                     }
   3608                     if (bp.perm == p) {
   3609                         bp.protectionLevel = p.info.protectionLevel;
   3610                     }
   3611                 } else {
   3612                     Slog.w(TAG, "Permission " + p.info.name + " from package "
   3613                             + p.info.packageName + " ignored: no group "
   3614                             + p.group);
   3615                 }
   3616             }
   3617             if (r != null) {
   3618                 if (Config.LOGD) Log.d(TAG, "  Permissions: " + r);
   3619             }
   3620 
   3621             N = pkg.instrumentation.size();
   3622             r = null;
   3623             for (i=0; i<N; i++) {
   3624                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   3625                 a.info.packageName = pkg.applicationInfo.packageName;
   3626                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
   3627                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
   3628                 a.info.dataDir = pkg.applicationInfo.dataDir;
   3629                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
   3630                 mInstrumentation.put(a.getComponentName(), a);
   3631                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   3632                     if (r == null) {
   3633                         r = new StringBuilder(256);
   3634                     } else {
   3635                         r.append(' ');
   3636                     }
   3637                     r.append(a.info.name);
   3638                 }
   3639             }
   3640             if (r != null) {
   3641                 if (Config.LOGD) Log.d(TAG, "  Instrumentation: " + r);
   3642             }
   3643 
   3644             if (pkg.protectedBroadcasts != null) {
   3645                 N = pkg.protectedBroadcasts.size();
   3646                 for (i=0; i<N; i++) {
   3647                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
   3648                 }
   3649             }
   3650 
   3651             pkgSetting.setTimeStamp(scanFileTime);
   3652         }
   3653 
   3654         return pkg;
   3655     }
   3656 
   3657     private void killApplication(String pkgName, int uid) {
   3658         // Request the ActivityManager to kill the process(only for existing packages)
   3659         // so that we do not end up in a confused state while the user is still using the older
   3660         // version of the application while the new one gets installed.
   3661         IActivityManager am = ActivityManagerNative.getDefault();
   3662         if (am != null) {
   3663             try {
   3664                 am.killApplicationWithUid(pkgName, uid);
   3665             } catch (RemoteException e) {
   3666             }
   3667         }
   3668     }
   3669 
   3670     // Return the path of the directory that will contain the native binaries
   3671     // of a given installed package. This is relative to the data path.
   3672     //
   3673     private File getNativeBinaryDirForPackage(PackageParser.Package pkg) {
   3674         final String nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
   3675         if (nativeLibraryDir != null) {
   3676             return new File(nativeLibraryDir);
   3677         } else {
   3678             // Fall back for old packages
   3679             return new File(pkg.applicationInfo.dataDir, LIB_DIR_NAME);
   3680         }
   3681     }
   3682 
   3683     void removePackageLI(PackageParser.Package pkg, boolean chatty) {
   3684         if (chatty && Config.LOGD) Log.d(
   3685             TAG, "Removing package " + pkg.applicationInfo.packageName );
   3686 
   3687         synchronized (mPackages) {
   3688             clearPackagePreferredActivitiesLP(pkg.packageName);
   3689 
   3690             mPackages.remove(pkg.applicationInfo.packageName);
   3691             if (pkg.mPath != null) {
   3692                 mAppDirs.remove(pkg.mPath);
   3693             }
   3694 
   3695             int N = pkg.providers.size();
   3696             StringBuilder r = null;
   3697             int i;
   3698             for (i=0; i<N; i++) {
   3699                 PackageParser.Provider p = pkg.providers.get(i);
   3700                 mProvidersByComponent.remove(new ComponentName(p.info.packageName,
   3701                         p.info.name));
   3702                 if (p.info.authority == null) {
   3703 
   3704                     /* The is another ContentProvider with this authority when
   3705                      * this app was installed so this authority is null,
   3706                      * Ignore it as we don't have to unregister the provider.
   3707                      */
   3708                     continue;
   3709                 }
   3710                 String names[] = p.info.authority.split(";");
   3711                 for (int j = 0; j < names.length; j++) {
   3712                     if (mProviders.get(names[j]) == p) {
   3713                         mProviders.remove(names[j]);
   3714                         if (chatty && Config.LOGD) Log.d(
   3715                             TAG, "Unregistered content provider: " + names[j] +
   3716                             ", className = " + p.info.name +
   3717                             ", isSyncable = " + p.info.isSyncable);
   3718                     }
   3719                 }
   3720                 if (chatty) {
   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 (Config.LOGD) 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                 mServices.removeService(s);
   3738                 if (chatty) {
   3739                     if (r == null) {
   3740                         r = new StringBuilder(256);
   3741                     } else {
   3742                         r.append(' ');
   3743                     }
   3744                     r.append(s.info.name);
   3745                 }
   3746             }
   3747             if (r != null) {
   3748                 if (Config.LOGD) Log.d(TAG, "  Services: " + r);
   3749             }
   3750 
   3751             N = pkg.receivers.size();
   3752             r = null;
   3753             for (i=0; i<N; i++) {
   3754                 PackageParser.Activity a = pkg.receivers.get(i);
   3755                 mReceivers.removeActivity(a, "receiver");
   3756                 if (chatty) {
   3757                     if (r == null) {
   3758                         r = new StringBuilder(256);
   3759                     } else {
   3760                         r.append(' ');
   3761                     }
   3762                     r.append(a.info.name);
   3763                 }
   3764             }
   3765             if (r != null) {
   3766                 if (Config.LOGD) Log.d(TAG, "  Receivers: " + r);
   3767             }
   3768 
   3769             N = pkg.activities.size();
   3770             r = null;
   3771             for (i=0; i<N; i++) {
   3772                 PackageParser.Activity a = pkg.activities.get(i);
   3773                 mActivities.removeActivity(a, "activity");
   3774                 if (chatty) {
   3775                     if (r == null) {
   3776                         r = new StringBuilder(256);
   3777                     } else {
   3778                         r.append(' ');
   3779                     }
   3780                     r.append(a.info.name);
   3781                 }
   3782             }
   3783             if (r != null) {
   3784                 if (Config.LOGD) Log.d(TAG, "  Activities: " + r);
   3785             }
   3786 
   3787             N = pkg.permissions.size();
   3788             r = null;
   3789             for (i=0; i<N; i++) {
   3790                 PackageParser.Permission p = pkg.permissions.get(i);
   3791                 boolean tree = false;
   3792                 BasePermission bp = mSettings.mPermissions.get(p.info.name);
   3793                 if (bp == null) {
   3794                     tree = true;
   3795                     bp = mSettings.mPermissionTrees.get(p.info.name);
   3796                 }
   3797                 if (bp != null && bp.perm == p) {
   3798                     bp.perm = null;
   3799                     if (chatty) {
   3800                         if (r == null) {
   3801                             r = new StringBuilder(256);
   3802                         } else {
   3803                             r.append(' ');
   3804                         }
   3805                         r.append(p.info.name);
   3806                     }
   3807                 }
   3808             }
   3809             if (r != null) {
   3810                 if (Config.LOGD) Log.d(TAG, "  Permissions: " + r);
   3811             }
   3812 
   3813             N = pkg.instrumentation.size();
   3814             r = null;
   3815             for (i=0; i<N; i++) {
   3816                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   3817                 mInstrumentation.remove(a.getComponentName());
   3818                 if (chatty) {
   3819                     if (r == null) {
   3820                         r = new StringBuilder(256);
   3821                     } else {
   3822                         r.append(' ');
   3823                     }
   3824                     r.append(a.info.name);
   3825                 }
   3826             }
   3827             if (r != null) {
   3828                 if (Config.LOGD) Log.d(TAG, "  Instrumentation: " + r);
   3829             }
   3830         }
   3831     }
   3832 
   3833     private static final boolean isPackageFilename(String name) {
   3834         return name != null && name.endsWith(".apk");
   3835     }
   3836 
   3837     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
   3838         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
   3839             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
   3840                 return true;
   3841             }
   3842         }
   3843         return false;
   3844     }
   3845 
   3846     private void updatePermissionsLP(String changingPkg,
   3847             PackageParser.Package pkgInfo, boolean grantPermissions,
   3848             boolean replace, boolean replaceAll) {
   3849         // Make sure there are no dangling permission trees.
   3850         Iterator<BasePermission> it = mSettings.mPermissionTrees
   3851                 .values().iterator();
   3852         while (it.hasNext()) {
   3853             BasePermission bp = it.next();
   3854             if (bp.packageSetting == null) {
   3855                 // We may not yet have parsed the package, so just see if
   3856                 // we still know about its settings.
   3857                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   3858             }
   3859             if (bp.packageSetting == null) {
   3860                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
   3861                         + " from package " + bp.sourcePackage);
   3862                 it.remove();
   3863             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   3864                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   3865                     Slog.i(TAG, "Removing old permission tree: " + bp.name
   3866                             + " from package " + bp.sourcePackage);
   3867                     grantPermissions = true;
   3868                     it.remove();
   3869                 }
   3870             }
   3871         }
   3872 
   3873         // Make sure all dynamic permissions have been assigned to a package,
   3874         // and make sure there are no dangling permissions.
   3875         it = mSettings.mPermissions.values().iterator();
   3876         while (it.hasNext()) {
   3877             BasePermission bp = it.next();
   3878             if (bp.type == BasePermission.TYPE_DYNAMIC) {
   3879                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
   3880                         + bp.name + " pkg=" + bp.sourcePackage
   3881                         + " info=" + bp.pendingInfo);
   3882                 if (bp.packageSetting == null && bp.pendingInfo != null) {
   3883                     BasePermission tree = findPermissionTreeLP(bp.name);
   3884                     if (tree != null) {
   3885                         bp.packageSetting = tree.packageSetting;
   3886                         bp.perm = new PackageParser.Permission(tree.perm.owner,
   3887                                 new PermissionInfo(bp.pendingInfo));
   3888                         bp.perm.info.packageName = tree.perm.info.packageName;
   3889                         bp.perm.info.name = bp.name;
   3890                         bp.uid = tree.uid;
   3891                     }
   3892                 }
   3893             }
   3894             if (bp.packageSetting == null) {
   3895                 // We may not yet have parsed the package, so just see if
   3896                 // we still know about its settings.
   3897                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   3898             }
   3899             if (bp.packageSetting == null) {
   3900                 Slog.w(TAG, "Removing dangling permission: " + bp.name
   3901                         + " from package " + bp.sourcePackage);
   3902                 it.remove();
   3903             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   3904                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   3905                     Slog.i(TAG, "Removing old permission: " + bp.name
   3906                             + " from package " + bp.sourcePackage);
   3907                     grantPermissions = true;
   3908                     it.remove();
   3909                 }
   3910             }
   3911         }
   3912 
   3913         // Now update the permissions for all packages, in particular
   3914         // replace the granted permissions of the system packages.
   3915         if (grantPermissions) {
   3916             for (PackageParser.Package pkg : mPackages.values()) {
   3917                 if (pkg != pkgInfo) {
   3918                     grantPermissionsLP(pkg, replaceAll);
   3919                 }
   3920             }
   3921         }
   3922 
   3923         if (pkgInfo != null) {
   3924             grantPermissionsLP(pkgInfo, replace);
   3925         }
   3926     }
   3927 
   3928     private void grantPermissionsLP(PackageParser.Package pkg, boolean replace) {
   3929         final PackageSetting ps = (PackageSetting)pkg.mExtras;
   3930         if (ps == null) {
   3931             return;
   3932         }
   3933         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   3934         boolean changedPermission = false;
   3935 
   3936         if (replace) {
   3937             ps.permissionsFixed = false;
   3938             if (gp == ps) {
   3939                 gp.grantedPermissions.clear();
   3940                 gp.gids = mGlobalGids;
   3941             }
   3942         }
   3943 
   3944         if (gp.gids == null) {
   3945             gp.gids = mGlobalGids;
   3946         }
   3947 
   3948         final int N = pkg.requestedPermissions.size();
   3949         for (int i=0; i<N; i++) {
   3950             String name = pkg.requestedPermissions.get(i);
   3951             BasePermission bp = mSettings.mPermissions.get(name);
   3952             if (false) {
   3953                 if (gp != ps) {
   3954                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name
   3955                             + ": " + bp);
   3956                 }
   3957             }
   3958             if (bp != null && bp.packageSetting != null) {
   3959                 final String perm = bp.name;
   3960                 boolean allowed;
   3961                 boolean allowedSig = false;
   3962                 if (bp.protectionLevel == PermissionInfo.PROTECTION_NORMAL
   3963                         || bp.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
   3964                     allowed = true;
   3965                 } else if (bp.packageSetting == null) {
   3966                     // This permission is invalid; skip it.
   3967                     allowed = false;
   3968                 } else if (bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE
   3969                         || bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
   3970                     allowed = (checkSignaturesLP(
   3971                             bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
   3972                                     == PackageManager.SIGNATURE_MATCH)
   3973                             || (checkSignaturesLP(mPlatformPackage.mSignatures, pkg.mSignatures)
   3974                                     == PackageManager.SIGNATURE_MATCH);
   3975                     if (!allowed && bp.protectionLevel
   3976                             == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
   3977                         if (isSystemApp(pkg)) {
   3978                             // For updated system applications, the signatureOrSystem permission
   3979                             // is granted only if it had been defined by the original application.
   3980                             if (isUpdatedSystemApp(pkg)) {
   3981                                 PackageSetting sysPs = mSettings.getDisabledSystemPkg(
   3982                                         pkg.packageName);
   3983                                 final GrantedPermissions origGp = sysPs.sharedUser != null
   3984                                         ? sysPs.sharedUser : sysPs;
   3985                                 if (origGp.grantedPermissions.contains(perm)) {
   3986                                     allowed = true;
   3987                                 } else {
   3988                                     allowed = false;
   3989                                 }
   3990                             } else {
   3991                                 allowed = true;
   3992                             }
   3993                         }
   3994                     }
   3995                     if (allowed) {
   3996                         allowedSig = true;
   3997                     }
   3998                 } else {
   3999                     allowed = false;
   4000                 }
   4001                 if (false) {
   4002                     if (gp != ps) {
   4003                         Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
   4004                     }
   4005                 }
   4006                 if (allowed) {
   4007                     if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
   4008                             && ps.permissionsFixed) {
   4009                         // If this is an existing, non-system package, then
   4010                         // we can't add any new permissions to it.
   4011                         if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
   4012                             allowed = false;
   4013                             // Except...  if this is a permission that was added
   4014                             // to the platform (note: need to only do this when
   4015                             // updating the platform).
   4016                             final int NP = PackageParser.NEW_PERMISSIONS.length;
   4017                             for (int ip=0; ip<NP; ip++) {
   4018                                 final PackageParser.NewPermissionInfo npi
   4019                                         = PackageParser.NEW_PERMISSIONS[ip];
   4020                                 if (npi.name.equals(perm)
   4021                                         && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
   4022                                     allowed = true;
   4023                                     Log.i(TAG, "Auto-granting " + perm + " to old pkg "
   4024                                             + pkg.packageName);
   4025                                     break;
   4026                                 }
   4027                             }
   4028                         }
   4029                     }
   4030                     if (allowed) {
   4031                         if (!gp.grantedPermissions.contains(perm)) {
   4032                             changedPermission = true;
   4033                             gp.grantedPermissions.add(perm);
   4034                             gp.gids = appendInts(gp.gids, bp.gids);
   4035                         } else if (!ps.haveGids) {
   4036                             gp.gids = appendInts(gp.gids, bp.gids);
   4037                         }
   4038                     } else {
   4039                         Slog.w(TAG, "Not granting permission " + perm
   4040                                 + " to package " + pkg.packageName
   4041                                 + " because it was previously installed without");
   4042                     }
   4043                 } else {
   4044                     if (gp.grantedPermissions.remove(perm)) {
   4045                         changedPermission = true;
   4046                         gp.gids = removeInts(gp.gids, bp.gids);
   4047                         Slog.i(TAG, "Un-granting permission " + perm
   4048                                 + " from package " + pkg.packageName
   4049                                 + " (protectionLevel=" + bp.protectionLevel
   4050                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   4051                                 + ")");
   4052                     } else {
   4053                         Slog.w(TAG, "Not granting permission " + perm
   4054                                 + " to package " + pkg.packageName
   4055                                 + " (protectionLevel=" + bp.protectionLevel
   4056                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   4057                                 + ")");
   4058                     }
   4059                 }
   4060             } else {
   4061                 Slog.w(TAG, "Unknown permission " + name
   4062                         + " in package " + pkg.packageName);
   4063             }
   4064         }
   4065 
   4066         if ((changedPermission || replace) && !ps.permissionsFixed &&
   4067                 ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) ||
   4068                 ((ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)){
   4069             // This is the first that we have heard about this package, so the
   4070             // permissions we have now selected are fixed until explicitly
   4071             // changed.
   4072             ps.permissionsFixed = true;
   4073         }
   4074         ps.haveGids = true;
   4075     }
   4076 
   4077     private final class ActivityIntentResolver
   4078             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
   4079         public List queryIntent(Intent intent, String resolvedType, boolean defaultOnly) {
   4080             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   4081             return super.queryIntent(intent, resolvedType, defaultOnly);
   4082         }
   4083 
   4084         public List queryIntent(Intent intent, String resolvedType, int flags) {
   4085             mFlags = flags;
   4086             return super.queryIntent(intent, resolvedType,
   4087                 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
   4088         }
   4089 
   4090         public List queryIntentForPackage(Intent intent, String resolvedType, int flags,
   4091                                           ArrayList<PackageParser.Activity> packageActivities) {
   4092             if (packageActivities == null) {
   4093                 return null;
   4094             }
   4095             mFlags = flags;
   4096             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   4097             int N = packageActivities.size();
   4098             ArrayList<ArrayList<PackageParser.ActivityIntentInfo>> listCut =
   4099                 new ArrayList<ArrayList<PackageParser.ActivityIntentInfo>>(N);
   4100 
   4101             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
   4102             for (int i = 0; i < N; ++i) {
   4103                 intentFilters = packageActivities.get(i).intents;
   4104                 if (intentFilters != null && intentFilters.size() > 0) {
   4105                     listCut.add(intentFilters);
   4106                 }
   4107             }
   4108             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
   4109         }
   4110 
   4111         public final void addActivity(PackageParser.Activity a, String type) {
   4112             final boolean systemApp = isSystemApp(a.info.applicationInfo);
   4113             mActivities.put(a.getComponentName(), a);
   4114             if (SHOW_INFO || Config.LOGV) Log.v(
   4115                 TAG, "  " + type + " " +
   4116                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
   4117             if (SHOW_INFO || Config.LOGV) Log.v(TAG, "    Class=" + a.info.name);
   4118             int NI = a.intents.size();
   4119             for (int j=0; j<NI; j++) {
   4120                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   4121                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
   4122                     intent.setPriority(0);
   4123                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
   4124                             + a.className + " with priority > 0, forcing to 0");
   4125                 }
   4126                 if (SHOW_INFO || Config.LOGV) {
   4127                     Log.v(TAG, "    IntentFilter:");
   4128                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   4129                 }
   4130                 if (!intent.debugCheck()) {
   4131                     Log.w(TAG, "==> For Activity " + a.info.name);
   4132                 }
   4133                 addFilter(intent);
   4134             }
   4135         }
   4136 
   4137         public final void removeActivity(PackageParser.Activity a, String type) {
   4138             mActivities.remove(a.getComponentName());
   4139             if (SHOW_INFO || Config.LOGV) Log.v(
   4140                 TAG, "  " + type + " " +
   4141                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
   4142             if (SHOW_INFO || Config.LOGV) Log.v(TAG, "    Class=" + a.info.name);
   4143             int NI = a.intents.size();
   4144             for (int j=0; j<NI; j++) {
   4145                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   4146                 if (SHOW_INFO || Config.LOGV) {
   4147                     Log.v(TAG, "    IntentFilter:");
   4148                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   4149                 }
   4150                 removeFilter(intent);
   4151             }
   4152         }
   4153 
   4154         @Override
   4155         protected boolean allowFilterResult(
   4156                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
   4157             ActivityInfo filterAi = filter.activity.info;
   4158             for (int i=dest.size()-1; i>=0; i--) {
   4159                 ActivityInfo destAi = dest.get(i).activityInfo;
   4160                 if (destAi.name == filterAi.name
   4161                         && destAi.packageName == filterAi.packageName) {
   4162                     return false;
   4163                 }
   4164             }
   4165             return true;
   4166         }
   4167 
   4168         @Override
   4169         protected String packageForFilter(PackageParser.ActivityIntentInfo info) {
   4170             return info.activity.owner.packageName;
   4171         }
   4172 
   4173         @Override
   4174         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
   4175                 int match) {
   4176             if (!mSettings.isEnabledLP(info.activity.info, mFlags)) {
   4177                 return null;
   4178             }
   4179             final PackageParser.Activity activity = info.activity;
   4180             if (mSafeMode && (activity.info.applicationInfo.flags
   4181                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   4182                 return null;
   4183             }
   4184             final ResolveInfo res = new ResolveInfo();
   4185             res.activityInfo = PackageParser.generateActivityInfo(activity,
   4186                     mFlags);
   4187             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   4188                 res.filter = info;
   4189             }
   4190             res.priority = info.getPriority();
   4191             res.preferredOrder = activity.owner.mPreferredOrder;
   4192             //System.out.println("Result: " + res.activityInfo.className +
   4193             //                   " = " + res.priority);
   4194             res.match = match;
   4195             res.isDefault = info.hasDefault;
   4196             res.labelRes = info.labelRes;
   4197             res.nonLocalizedLabel = info.nonLocalizedLabel;
   4198             res.icon = info.icon;
   4199             return res;
   4200         }
   4201 
   4202         @Override
   4203         protected void sortResults(List<ResolveInfo> results) {
   4204             Collections.sort(results, mResolvePrioritySorter);
   4205         }
   4206 
   4207         @Override
   4208         protected void dumpFilter(PrintWriter out, String prefix,
   4209                 PackageParser.ActivityIntentInfo filter) {
   4210             out.print(prefix); out.print(
   4211                     Integer.toHexString(System.identityHashCode(filter.activity)));
   4212                     out.print(' ');
   4213                     out.print(filter.activity.getComponentShortName());
   4214                     out.print(" filter ");
   4215                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   4216         }
   4217 
   4218 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   4219 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   4220 //            final List<ResolveInfo> retList = Lists.newArrayList();
   4221 //            while (i.hasNext()) {
   4222 //                final ResolveInfo resolveInfo = i.next();
   4223 //                if (isEnabledLP(resolveInfo.activityInfo)) {
   4224 //                    retList.add(resolveInfo);
   4225 //                }
   4226 //            }
   4227 //            return retList;
   4228 //        }
   4229 
   4230         // Keys are String (activity class name), values are Activity.
   4231         private final HashMap<ComponentName, PackageParser.Activity> mActivities
   4232                 = new HashMap<ComponentName, PackageParser.Activity>();
   4233         private int mFlags;
   4234     }
   4235 
   4236     private final class ServiceIntentResolver
   4237             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
   4238         public List queryIntent(Intent intent, String resolvedType, boolean defaultOnly) {
   4239             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   4240             return super.queryIntent(intent, resolvedType, defaultOnly);
   4241         }
   4242 
   4243         public List queryIntent(Intent intent, String resolvedType, int flags) {
   4244             mFlags = flags;
   4245             return super.queryIntent(intent, resolvedType,
   4246                 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0);
   4247         }
   4248 
   4249         public List queryIntentForPackage(Intent intent, String resolvedType, int flags,
   4250                                           ArrayList<PackageParser.Service> packageServices) {
   4251             if (packageServices == null) {
   4252                 return null;
   4253             }
   4254             mFlags = flags;
   4255             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   4256             int N = packageServices.size();
   4257             ArrayList<ArrayList<PackageParser.ServiceIntentInfo>> listCut =
   4258                 new ArrayList<ArrayList<PackageParser.ServiceIntentInfo>>(N);
   4259 
   4260             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
   4261             for (int i = 0; i < N; ++i) {
   4262                 intentFilters = packageServices.get(i).intents;
   4263                 if (intentFilters != null && intentFilters.size() > 0) {
   4264                     listCut.add(intentFilters);
   4265                 }
   4266             }
   4267             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
   4268         }
   4269 
   4270         public final void addService(PackageParser.Service s) {
   4271             mServices.put(s.getComponentName(), s);
   4272             if (SHOW_INFO || Config.LOGV) Log.v(
   4273                 TAG, "  " + (s.info.nonLocalizedLabel != null
   4274                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   4275             if (SHOW_INFO || Config.LOGV) Log.v(
   4276                     TAG, "    Class=" + s.info.name);
   4277             int NI = s.intents.size();
   4278             int j;
   4279             for (j=0; j<NI; j++) {
   4280                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   4281                 if (SHOW_INFO || Config.LOGV) {
   4282                     Log.v(TAG, "    IntentFilter:");
   4283                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   4284                 }
   4285                 if (!intent.debugCheck()) {
   4286                     Log.w(TAG, "==> For Service " + s.info.name);
   4287                 }
   4288                 addFilter(intent);
   4289             }
   4290         }
   4291 
   4292         public final void removeService(PackageParser.Service s) {
   4293             mServices.remove(s.getComponentName());
   4294             if (SHOW_INFO || Config.LOGV) Log.v(
   4295                 TAG, "  " + (s.info.nonLocalizedLabel != null
   4296                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   4297             if (SHOW_INFO || Config.LOGV) Log.v(
   4298                     TAG, "    Class=" + s.info.name);
   4299             int NI = s.intents.size();
   4300             int j;
   4301             for (j=0; j<NI; j++) {
   4302                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   4303                 if (SHOW_INFO || Config.LOGV) {
   4304                     Log.v(TAG, "    IntentFilter:");
   4305                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   4306                 }
   4307                 removeFilter(intent);
   4308             }
   4309         }
   4310 
   4311         @Override
   4312         protected boolean allowFilterResult(
   4313                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
   4314             ServiceInfo filterSi = filter.service.info;
   4315             for (int i=dest.size()-1; i>=0; i--) {
   4316                 ServiceInfo destAi = dest.get(i).serviceInfo;
   4317                 if (destAi.name == filterSi.name
   4318                         && destAi.packageName == filterSi.packageName) {
   4319                     return false;
   4320                 }
   4321             }
   4322             return true;
   4323         }
   4324 
   4325         @Override
   4326         protected String packageForFilter(PackageParser.ServiceIntentInfo info) {
   4327             return info.service.owner.packageName;
   4328         }
   4329 
   4330         @Override
   4331         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
   4332                 int match) {
   4333             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
   4334             if (!mSettings.isEnabledLP(info.service.info, mFlags)) {
   4335                 return null;
   4336             }
   4337             final PackageParser.Service service = info.service;
   4338             if (mSafeMode && (service.info.applicationInfo.flags
   4339                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   4340                 return null;
   4341             }
   4342             final ResolveInfo res = new ResolveInfo();
   4343             res.serviceInfo = PackageParser.generateServiceInfo(service,
   4344                     mFlags);
   4345             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   4346                 res.filter = filter;
   4347             }
   4348             res.priority = info.getPriority();
   4349             res.preferredOrder = service.owner.mPreferredOrder;
   4350             //System.out.println("Result: " + res.activityInfo.className +
   4351             //                   " = " + res.priority);
   4352             res.match = match;
   4353             res.isDefault = info.hasDefault;
   4354             res.labelRes = info.labelRes;
   4355             res.nonLocalizedLabel = info.nonLocalizedLabel;
   4356             res.icon = info.icon;
   4357             return res;
   4358         }
   4359 
   4360         @Override
   4361         protected void sortResults(List<ResolveInfo> results) {
   4362             Collections.sort(results, mResolvePrioritySorter);
   4363         }
   4364 
   4365         @Override
   4366         protected void dumpFilter(PrintWriter out, String prefix,
   4367                 PackageParser.ServiceIntentInfo filter) {
   4368             out.print(prefix); out.print(
   4369                     Integer.toHexString(System.identityHashCode(filter.service)));
   4370                     out.print(' ');
   4371                     out.print(filter.service.getComponentShortName());
   4372                     out.print(" filter ");
   4373                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   4374         }
   4375 
   4376 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   4377 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   4378 //            final List<ResolveInfo> retList = Lists.newArrayList();
   4379 //            while (i.hasNext()) {
   4380 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
   4381 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
   4382 //                    retList.add(resolveInfo);
   4383 //                }
   4384 //            }
   4385 //            return retList;
   4386 //        }
   4387 
   4388         // Keys are String (activity class name), values are Activity.
   4389         private final HashMap<ComponentName, PackageParser.Service> mServices
   4390                 = new HashMap<ComponentName, PackageParser.Service>();
   4391         private int mFlags;
   4392     };
   4393 
   4394     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
   4395             new Comparator<ResolveInfo>() {
   4396         public int compare(ResolveInfo r1, ResolveInfo r2) {
   4397             int v1 = r1.priority;
   4398             int v2 = r2.priority;
   4399             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
   4400             if (v1 != v2) {
   4401                 return (v1 > v2) ? -1 : 1;
   4402             }
   4403             v1 = r1.preferredOrder;
   4404             v2 = r2.preferredOrder;
   4405             if (v1 != v2) {
   4406                 return (v1 > v2) ? -1 : 1;
   4407             }
   4408             if (r1.isDefault != r2.isDefault) {
   4409                 return r1.isDefault ? -1 : 1;
   4410             }
   4411             v1 = r1.match;
   4412             v2 = r2.match;
   4413             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
   4414             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
   4415         }
   4416     };
   4417 
   4418     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
   4419             new Comparator<ProviderInfo>() {
   4420         public int compare(ProviderInfo p1, ProviderInfo p2) {
   4421             final int v1 = p1.initOrder;
   4422             final int v2 = p2.initOrder;
   4423             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
   4424         }
   4425     };
   4426 
   4427     private static final void sendPackageBroadcast(String action, String pkg,
   4428             Bundle extras, IIntentReceiver finishedReceiver) {
   4429         IActivityManager am = ActivityManagerNative.getDefault();
   4430         if (am != null) {
   4431             try {
   4432                 final Intent intent = new Intent(action,
   4433                         pkg != null ? Uri.fromParts("package", pkg, null) : null);
   4434                 if (extras != null) {
   4435                     intent.putExtras(extras);
   4436                 }
   4437                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
   4438                 am.broadcastIntent(null, intent, null, finishedReceiver,
   4439                         0, null, null, null, finishedReceiver != null, false);
   4440             } catch (RemoteException ex) {
   4441             }
   4442         }
   4443     }
   4444 
   4445     public String nextPackageToClean(String lastPackage) {
   4446         synchronized (mPackages) {
   4447             if (!mMediaMounted) {
   4448                 // If the external storage is no longer mounted at this point,
   4449                 // the caller may not have been able to delete all of this
   4450                 // packages files and can not delete any more.  Bail.
   4451                 return null;
   4452             }
   4453             if (lastPackage != null) {
   4454                 mSettings.mPackagesToBeCleaned.remove(lastPackage);
   4455             }
   4456             return mSettings.mPackagesToBeCleaned.size() > 0
   4457                     ? mSettings.mPackagesToBeCleaned.get(0) : null;
   4458         }
   4459     }
   4460 
   4461     void schedulePackageCleaning(String packageName) {
   4462         mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE, packageName));
   4463     }
   4464 
   4465     void startCleaningPackages() {
   4466         synchronized (mPackages) {
   4467             if (!mMediaMounted) {
   4468                 return;
   4469             }
   4470             if (mSettings.mPackagesToBeCleaned.size() <= 0) {
   4471                 return;
   4472             }
   4473         }
   4474         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
   4475         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
   4476         IActivityManager am = ActivityManagerNative.getDefault();
   4477         if (am != null) {
   4478             try {
   4479                 am.startService(null, intent, null);
   4480             } catch (RemoteException e) {
   4481             }
   4482         }
   4483     }
   4484 
   4485     private final class AppDirObserver extends FileObserver {
   4486         public AppDirObserver(String path, int mask, boolean isrom) {
   4487             super(path, mask);
   4488             mRootDir = path;
   4489             mIsRom = isrom;
   4490         }
   4491 
   4492         public void onEvent(int event, String path) {
   4493             String removedPackage = null;
   4494             int removedUid = -1;
   4495             String addedPackage = null;
   4496             int addedUid = -1;
   4497 
   4498             synchronized (mInstallLock) {
   4499                 String fullPathStr = null;
   4500                 File fullPath = null;
   4501                 if (path != null) {
   4502                     fullPath = new File(mRootDir, path);
   4503                     fullPathStr = fullPath.getPath();
   4504                 }
   4505 
   4506                 if (Config.LOGV) Log.v(
   4507                     TAG, "File " + fullPathStr + " changed: "
   4508                     + Integer.toHexString(event));
   4509 
   4510                 if (!isPackageFilename(path)) {
   4511                     if (Config.LOGV) Log.v(
   4512                         TAG, "Ignoring change of non-package file: " + fullPathStr);
   4513                     return;
   4514                 }
   4515 
   4516                 // Ignore packages that are being installed or
   4517                 // have just been installed.
   4518                 if (ignoreCodePath(fullPathStr)) {
   4519                     return;
   4520                 }
   4521                 PackageParser.Package p = null;
   4522                 synchronized (mPackages) {
   4523                     p = mAppDirs.get(fullPathStr);
   4524                 }
   4525                 if ((event&REMOVE_EVENTS) != 0) {
   4526                     if (p != null) {
   4527                         removePackageLI(p, true);
   4528                         removedPackage = p.applicationInfo.packageName;
   4529                         removedUid = p.applicationInfo.uid;
   4530                     }
   4531                 }
   4532 
   4533                 if ((event&ADD_EVENTS) != 0) {
   4534                     if (p == null) {
   4535                         p = scanPackageLI(fullPath,
   4536                                 (mIsRom ? PackageParser.PARSE_IS_SYSTEM
   4537                                         | PackageParser.PARSE_IS_SYSTEM_DIR: 0) |
   4538                                 PackageParser.PARSE_CHATTY |
   4539                                 PackageParser.PARSE_MUST_BE_APK,
   4540                                 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME,
   4541                                 System.currentTimeMillis());
   4542                         if (p != null) {
   4543                             synchronized (mPackages) {
   4544                                 updatePermissionsLP(p.packageName, p,
   4545                                         p.permissions.size() > 0, false, false);
   4546                             }
   4547                             addedPackage = p.applicationInfo.packageName;
   4548                             addedUid = p.applicationInfo.uid;
   4549                         }
   4550                     }
   4551                 }
   4552 
   4553                 synchronized (mPackages) {
   4554                     mSettings.writeLP();
   4555                 }
   4556             }
   4557 
   4558             if (removedPackage != null) {
   4559                 Bundle extras = new Bundle(1);
   4560                 extras.putInt(Intent.EXTRA_UID, removedUid);
   4561                 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false);
   4562                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
   4563                         extras, null);
   4564             }
   4565             if (addedPackage != null) {
   4566                 Bundle extras = new Bundle(1);
   4567                 extras.putInt(Intent.EXTRA_UID, addedUid);
   4568                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage,
   4569                         extras, null);
   4570             }
   4571         }
   4572 
   4573         private final String mRootDir;
   4574         private final boolean mIsRom;
   4575     }
   4576 
   4577     /* Called when a downloaded package installation has been confirmed by the user */
   4578     public void installPackage(
   4579             final Uri packageURI, final IPackageInstallObserver observer, final int flags) {
   4580         installPackage(packageURI, observer, flags, null);
   4581     }
   4582 
   4583     /* Called when a downloaded package installation has been confirmed by the user */
   4584     public void installPackage(
   4585             final Uri packageURI, final IPackageInstallObserver observer, final int flags,
   4586             final String installerPackageName) {
   4587         mContext.enforceCallingOrSelfPermission(
   4588                 android.Manifest.permission.INSTALL_PACKAGES, null);
   4589 
   4590         Message msg = mHandler.obtainMessage(INIT_COPY);
   4591         msg.obj = new InstallParams(packageURI, observer, flags,
   4592                 installerPackageName);
   4593         mHandler.sendMessage(msg);
   4594     }
   4595 
   4596     public void finishPackageInstall(int token) {
   4597         if (DEBUG_INSTALL) Log.v(TAG, "BM finishing package install for " + token);
   4598         Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   4599         mHandler.sendMessage(msg);
   4600     }
   4601 
   4602     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
   4603         // Queue up an async operation since the package installation may take a little while.
   4604         mHandler.post(new Runnable() {
   4605             public void run() {
   4606                 mHandler.removeCallbacks(this);
   4607                  // Result object to be returned
   4608                 PackageInstalledInfo res = new PackageInstalledInfo();
   4609                 res.returnCode = currentStatus;
   4610                 res.uid = -1;
   4611                 res.pkg = null;
   4612                 res.removedInfo = new PackageRemovedInfo();
   4613                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   4614                     args.doPreInstall(res.returnCode);
   4615                     synchronized (mInstallLock) {
   4616                         installPackageLI(args, true, res);
   4617                     }
   4618                     args.doPostInstall(res.returnCode);
   4619                 }
   4620 
   4621                 // A restore should be performed at this point if (a) the install
   4622                 // succeeded, (b) the operation is not an update, and (c) the new
   4623                 // package has a backupAgent defined.
   4624                 final boolean update = res.removedInfo.removedPackage != null;
   4625                 boolean doRestore = (!update
   4626                         && res.pkg != null
   4627                         && res.pkg.applicationInfo.backupAgentName != null);
   4628 
   4629                 // Set up the post-install work request bookkeeping.  This will be used
   4630                 // and cleaned up by the post-install event handling regardless of whether
   4631                 // there's a restore pass performed.  Token values are >= 1.
   4632                 int token;
   4633                 if (mNextInstallToken < 0) mNextInstallToken = 1;
   4634                 token = mNextInstallToken++;
   4635 
   4636                 PostInstallData data = new PostInstallData(args, res);
   4637                 mRunningInstalls.put(token, data);
   4638                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
   4639 
   4640                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
   4641                     // Pass responsibility to the Backup Manager.  It will perform a
   4642                     // restore if appropriate, then pass responsibility back to the
   4643                     // Package Manager to run the post-install observer callbacks
   4644                     // and broadcasts.
   4645                     IBackupManager bm = IBackupManager.Stub.asInterface(
   4646                             ServiceManager.getService(Context.BACKUP_SERVICE));
   4647                     if (bm != null) {
   4648                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
   4649                                 + " to BM for possible restore");
   4650                         try {
   4651                             bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
   4652                         } catch (RemoteException e) {
   4653                             // can't happen; the backup manager is local
   4654                         } catch (Exception e) {
   4655                             Slog.e(TAG, "Exception trying to enqueue restore", e);
   4656                             doRestore = false;
   4657                         }
   4658                     } else {
   4659                         Slog.e(TAG, "Backup Manager not found!");
   4660                         doRestore = false;
   4661                     }
   4662                 }
   4663 
   4664                 if (!doRestore) {
   4665                     // No restore possible, or the Backup Manager was mysteriously not
   4666                     // available -- just fire the post-install work request directly.
   4667                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
   4668                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   4669                     mHandler.sendMessage(msg);
   4670                 }
   4671             }
   4672         });
   4673     }
   4674 
   4675     abstract class HandlerParams {
   4676         final static int MAX_RETRIES = 4;
   4677         int retry = 0;
   4678         final void startCopy() {
   4679             try {
   4680                 if (DEBUG_SD_INSTALL) Log.i(TAG, "startCopy");
   4681                 retry++;
   4682                 if (retry > MAX_RETRIES) {
   4683                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
   4684                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
   4685                     handleServiceError();
   4686                     return;
   4687                 } else {
   4688                     handleStartCopy();
   4689                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Posting install MCS_UNBIND");
   4690                     mHandler.sendEmptyMessage(MCS_UNBIND);
   4691                 }
   4692             } catch (RemoteException e) {
   4693                 if (DEBUG_SD_INSTALL) Log.i(TAG, "Posting install MCS_RECONNECT");
   4694                 mHandler.sendEmptyMessage(MCS_RECONNECT);
   4695             }
   4696             handleReturnCode();
   4697         }
   4698 
   4699         final void serviceError() {
   4700             if (DEBUG_SD_INSTALL) Log.i(TAG, "serviceError");
   4701             handleServiceError();
   4702             handleReturnCode();
   4703         }
   4704         abstract void handleStartCopy() throws RemoteException;
   4705         abstract void handleServiceError();
   4706         abstract void handleReturnCode();
   4707     }
   4708 
   4709     class InstallParams extends HandlerParams {
   4710         final IPackageInstallObserver observer;
   4711         int flags;
   4712         final Uri packageURI;
   4713         final String installerPackageName;
   4714         private InstallArgs mArgs;
   4715         private int mRet;
   4716         InstallParams(Uri packageURI,
   4717                 IPackageInstallObserver observer, int flags,
   4718                 String installerPackageName) {
   4719             this.packageURI = packageURI;
   4720             this.flags = flags;
   4721             this.observer = observer;
   4722             this.installerPackageName = installerPackageName;
   4723         }
   4724 
   4725         private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
   4726             String packageName = pkgLite.packageName;
   4727             int installLocation = pkgLite.installLocation;
   4728             boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
   4729             synchronized (mPackages) {
   4730                 PackageParser.Package pkg = mPackages.get(packageName);
   4731                 if (pkg != null) {
   4732                     if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   4733                         // Check for updated system application.
   4734                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   4735                             if (onSd) {
   4736                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
   4737                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
   4738                             }
   4739                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   4740                         } else {
   4741                             if (onSd) {
   4742                                 // Install flag overrides everything.
   4743                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   4744                             }
   4745                             // If current upgrade specifies particular preference
   4746                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
   4747                                 // Application explicitly specified internal.
   4748                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   4749                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
   4750                                 // App explictly prefers external. Let policy decide
   4751                             } else {
   4752                                 // Prefer previous location
   4753                                 if (isExternal(pkg)) {
   4754                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   4755                                 }
   4756                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   4757                             }
   4758                         }
   4759                     } else {
   4760                         // Invalid install. Return error code
   4761                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
   4762                     }
   4763                 }
   4764             }
   4765             // All the special cases have been taken care of.
   4766             // Return result based on recommended install location.
   4767             if (onSd) {
   4768                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   4769             }
   4770             return pkgLite.recommendedInstallLocation;
   4771         }
   4772 
   4773         /*
   4774          * Invoke remote method to get package information and install
   4775          * location values. Override install location based on default
   4776          * policy if needed and then create install arguments based
   4777          * on the install location.
   4778          */
   4779         public void handleStartCopy() throws RemoteException {
   4780             int ret = PackageManager.INSTALL_SUCCEEDED;
   4781             boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   4782             boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0;
   4783             boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0;
   4784             if (onInt && onSd) {
   4785                 // Check if both bits are set.
   4786                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
   4787                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   4788             } else if (fwdLocked && onSd) {
   4789                 // Check for forward locked apps
   4790                 Slog.w(TAG, "Cannot install fwd locked apps on sdcard");
   4791                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   4792             } else {
   4793                 // Remote call to find out default install location
   4794                 final PackageInfoLite pkgLite;
   4795                 try {
   4796                     mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   4797                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
   4798                     pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags);
   4799                 } finally {
   4800                     mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   4801                 }
   4802 
   4803                 int loc = pkgLite.recommendedInstallLocation;
   4804                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION){
   4805                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   4806                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS){
   4807                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   4808                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE){
   4809                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   4810                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
   4811                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
   4812                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
   4813                   ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
   4814                 } else {
   4815                     // Override with defaults if needed.
   4816                     loc = installLocationPolicy(pkgLite, flags);
   4817                     if (!onSd && !onInt) {
   4818                         // Override install location with flags
   4819                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
   4820                             // Set the flag to install on external media.
   4821                             flags |= PackageManager.INSTALL_EXTERNAL;
   4822                             flags &= ~PackageManager.INSTALL_INTERNAL;
   4823                         } else {
   4824                             // Make sure the flag for installing on external
   4825                             // media is unset
   4826                             flags |= PackageManager.INSTALL_INTERNAL;
   4827                             flags &= ~PackageManager.INSTALL_EXTERNAL;
   4828                         }
   4829                     }
   4830                 }
   4831             }
   4832             // Create the file args now.
   4833             mArgs = createInstallArgs(this);
   4834             if (ret == PackageManager.INSTALL_SUCCEEDED) {
   4835                 // Create copy only if we are not in an erroneous state.
   4836                 // Remote call to initiate copy using temporary file
   4837                 ret = mArgs.copyApk(mContainerService, true);
   4838             }
   4839             mRet = ret;
   4840         }
   4841 
   4842         @Override
   4843         void handleReturnCode() {
   4844             // If mArgs is null, then MCS couldn't be reached. When it
   4845             // reconnects, it will try again to install. At that point, this
   4846             // will succeed.
   4847             if (mArgs != null) {
   4848                 processPendingInstall(mArgs, mRet);
   4849             }
   4850         }
   4851 
   4852         @Override
   4853         void handleServiceError() {
   4854             mArgs = createInstallArgs(this);
   4855             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   4856         }
   4857     }
   4858 
   4859     /*
   4860      * Utility class used in movePackage api.
   4861      * srcArgs and targetArgs are not set for invalid flags and make
   4862      * sure to do null checks when invoking methods on them.
   4863      * We probably want to return ErrorPrams for both failed installs
   4864      * and moves.
   4865      */
   4866     class MoveParams extends HandlerParams {
   4867         final IPackageMoveObserver observer;
   4868         final int flags;
   4869         final String packageName;
   4870         final InstallArgs srcArgs;
   4871         final InstallArgs targetArgs;
   4872         int mRet;
   4873 
   4874         MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags,
   4875                 String packageName, String dataDir) {
   4876             this.srcArgs = srcArgs;
   4877             this.observer = observer;
   4878             this.flags = flags;
   4879             this.packageName = packageName;
   4880             if (srcArgs != null) {
   4881                 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath()));
   4882                 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir);
   4883             } else {
   4884                 targetArgs = null;
   4885             }
   4886         }
   4887 
   4888         public void handleStartCopy() throws RemoteException {
   4889             mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   4890             // Check for storage space on target medium
   4891             if (!targetArgs.checkFreeStorage(mContainerService)) {
   4892                 Log.w(TAG, "Insufficient storage to install");
   4893                 return;
   4894             }
   4895             // Create the file args now.
   4896             mRet = targetArgs.copyApk(mContainerService, false);
   4897             targetArgs.doPreInstall(mRet);
   4898             if (DEBUG_SD_INSTALL) {
   4899                 StringBuilder builder = new StringBuilder();
   4900                 if (srcArgs != null) {
   4901                     builder.append("src: ");
   4902                     builder.append(srcArgs.getCodePath());
   4903                 }
   4904                 if (targetArgs != null) {
   4905                     builder.append(" target : ");
   4906                     builder.append(targetArgs.getCodePath());
   4907                 }
   4908                 Log.i(TAG, builder.toString());
   4909             }
   4910         }
   4911 
   4912         @Override
   4913         void handleReturnCode() {
   4914             targetArgs.doPostInstall(mRet);
   4915             int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
   4916             if (mRet == PackageManager.INSTALL_SUCCEEDED) {
   4917                 currentStatus = PackageManager.MOVE_SUCCEEDED;
   4918             } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
   4919                 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
   4920             }
   4921             processPendingMove(this, currentStatus);
   4922         }
   4923 
   4924         @Override
   4925         void handleServiceError() {
   4926             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   4927         }
   4928     }
   4929 
   4930     private InstallArgs createInstallArgs(InstallParams params) {
   4931         if (installOnSd(params.flags)) {
   4932             return new SdInstallArgs(params);
   4933         } else {
   4934             return new FileInstallArgs(params);
   4935         }
   4936     }
   4937 
   4938     private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath,
   4939             String nativeLibraryPath) {
   4940         if (installOnSd(flags)) {
   4941             return new SdInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
   4942         } else {
   4943             return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath);
   4944         }
   4945     }
   4946 
   4947     // Used by package mover
   4948     private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) {
   4949         if (installOnSd(flags)) {
   4950             String cid = getNextCodePath(null, pkgName, "/" + SdInstallArgs.RES_FILE_NAME);
   4951             return new SdInstallArgs(packageURI, cid);
   4952         } else {
   4953             return new FileInstallArgs(packageURI, pkgName, dataDir);
   4954         }
   4955     }
   4956 
   4957     static abstract class InstallArgs {
   4958         final IPackageInstallObserver observer;
   4959         // Always refers to PackageManager flags only
   4960         final int flags;
   4961         final Uri packageURI;
   4962         final String installerPackageName;
   4963 
   4964         InstallArgs(Uri packageURI,
   4965                 IPackageInstallObserver observer, int flags,
   4966                 String installerPackageName) {
   4967             this.packageURI = packageURI;
   4968             this.flags = flags;
   4969             this.observer = observer;
   4970             this.installerPackageName = installerPackageName;
   4971         }
   4972 
   4973         abstract void createCopyFile();
   4974         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
   4975         abstract int doPreInstall(int status);
   4976         abstract boolean doRename(int status, String pkgName, String oldCodePath);
   4977         abstract int doPostInstall(int status);
   4978         abstract String getCodePath();
   4979         abstract String getResourcePath();
   4980         abstract String getNativeLibraryPath();
   4981         // Need installer lock especially for dex file removal.
   4982         abstract void cleanUpResourcesLI();
   4983         abstract boolean doPostDeleteLI(boolean delete);
   4984         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
   4985     }
   4986 
   4987     class FileInstallArgs extends InstallArgs {
   4988         File installDir;
   4989         String codeFileName;
   4990         String resourceFileName;
   4991         String libraryPath;
   4992         boolean created = false;
   4993 
   4994         FileInstallArgs(InstallParams params) {
   4995             super(params.packageURI, params.observer,
   4996                     params.flags, params.installerPackageName);
   4997         }
   4998 
   4999         FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
   5000             super(null, null, 0, null);
   5001             File codeFile = new File(fullCodePath);
   5002             installDir = codeFile.getParentFile();
   5003             codeFileName = fullCodePath;
   5004             resourceFileName = fullResourcePath;
   5005             libraryPath = nativeLibraryPath;
   5006         }
   5007 
   5008         FileInstallArgs(Uri packageURI, String pkgName, String dataDir) {
   5009             super(packageURI, null, 0, null);
   5010             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
   5011             String apkName = getNextCodePath(null, pkgName, ".apk");
   5012             codeFileName = new File(installDir, apkName + ".apk").getPath();
   5013             resourceFileName = getResourcePathFromCodePath();
   5014             libraryPath = new File(dataDir, LIB_DIR_NAME).getPath();
   5015         }
   5016 
   5017         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
   5018             try {
   5019                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   5020                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5021                 return imcs.checkFreeStorage(false, packageURI);
   5022             } finally {
   5023                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5024             }
   5025         }
   5026 
   5027         String getCodePath() {
   5028             return codeFileName;
   5029         }
   5030 
   5031         void createCopyFile() {
   5032             installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir;
   5033             codeFileName = createTempPackageFile(installDir).getPath();
   5034             resourceFileName = getResourcePathFromCodePath();
   5035             created = true;
   5036         }
   5037 
   5038         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   5039             if (temp) {
   5040                 // Generate temp file name
   5041                 createCopyFile();
   5042             }
   5043             // Get a ParcelFileDescriptor to write to the output file
   5044             File codeFile = new File(codeFileName);
   5045             if (!created) {
   5046                 try {
   5047                     codeFile.createNewFile();
   5048                     // Set permissions
   5049                     if (!setPermissions()) {
   5050                         // Failed setting permissions.
   5051                         return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5052                     }
   5053                 } catch (IOException e) {
   5054                    Slog.w(TAG, "Failed to create file " + codeFile);
   5055                    return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5056                 }
   5057             }
   5058             ParcelFileDescriptor out = null;
   5059             try {
   5060                 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE);
   5061             } catch (FileNotFoundException e) {
   5062                 Slog.e(TAG, "Failed to create file descritpor for : " + codeFileName);
   5063                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5064             }
   5065             // Copy the resource now
   5066             int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5067             try {
   5068                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   5069                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5070                 if (imcs.copyResource(packageURI, out)) {
   5071                     ret = PackageManager.INSTALL_SUCCEEDED;
   5072                 }
   5073             } finally {
   5074                 try { if (out != null) out.close(); } catch (IOException e) {}
   5075                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5076             }
   5077 
   5078             return ret;
   5079         }
   5080 
   5081         int doPreInstall(int status) {
   5082             if (status != PackageManager.INSTALL_SUCCEEDED) {
   5083                 cleanUp();
   5084             }
   5085             return status;
   5086         }
   5087 
   5088         boolean doRename(int status, final String pkgName, String oldCodePath) {
   5089             if (status != PackageManager.INSTALL_SUCCEEDED) {
   5090                 cleanUp();
   5091                 return false;
   5092             } else {
   5093                 // Rename based on packageName
   5094                 File codeFile = new File(getCodePath());
   5095                 String apkName = getNextCodePath(oldCodePath, pkgName, ".apk");
   5096                 File desFile = new File(installDir, apkName + ".apk");
   5097                 if (!codeFile.renameTo(desFile)) {
   5098                     return false;
   5099                 }
   5100                 // Reset paths since the file has been renamed.
   5101                 codeFileName = desFile.getPath();
   5102                 resourceFileName = getResourcePathFromCodePath();
   5103                 // Set permissions
   5104                 if (!setPermissions()) {
   5105                     // Failed setting permissions.
   5106                     return false;
   5107                 }
   5108                 return true;
   5109             }
   5110         }
   5111 
   5112         int doPostInstall(int status) {
   5113             if (status != PackageManager.INSTALL_SUCCEEDED) {
   5114                 cleanUp();
   5115             }
   5116             return status;
   5117         }
   5118 
   5119         String getResourcePath() {
   5120             return resourceFileName;
   5121         }
   5122 
   5123         String getResourcePathFromCodePath() {
   5124             String codePath = getCodePath();
   5125             if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) {
   5126                 String apkNameOnly = getApkName(codePath);
   5127                 return mAppInstallDir.getPath() + "/" + apkNameOnly + ".zip";
   5128             } else {
   5129                 return codePath;
   5130             }
   5131         }
   5132 
   5133         @Override
   5134         String getNativeLibraryPath() {
   5135             return libraryPath;
   5136         }
   5137 
   5138         private boolean cleanUp() {
   5139             boolean ret = true;
   5140             String sourceDir = getCodePath();
   5141             String publicSourceDir = getResourcePath();
   5142             if (sourceDir != null) {
   5143                 File sourceFile = new File(sourceDir);
   5144                 if (!sourceFile.exists()) {
   5145                     Slog.w(TAG, "Package source " + sourceDir + " does not exist.");
   5146                     ret = false;
   5147                 }
   5148                 // Delete application's code and resources
   5149                 sourceFile.delete();
   5150             }
   5151             if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) {
   5152                 final File publicSourceFile = new File(publicSourceDir);
   5153                 if (!publicSourceFile.exists()) {
   5154                     Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist.");
   5155                 }
   5156                 if (publicSourceFile.exists()) {
   5157                     publicSourceFile.delete();
   5158                 }
   5159             }
   5160             return ret;
   5161         }
   5162 
   5163         void cleanUpResourcesLI() {
   5164             String sourceDir = getCodePath();
   5165             if (cleanUp() && mInstaller != null) {
   5166                 int retCode = mInstaller.rmdex(sourceDir);
   5167                 if (retCode < 0) {
   5168                     Slog.w(TAG, "Couldn't remove dex file for package: "
   5169                             +  " at location "
   5170                             + sourceDir + ", retcode=" + retCode);
   5171                     // we don't consider this to be a failure of the core package deletion
   5172                 }
   5173             }
   5174         }
   5175 
   5176         private boolean setPermissions() {
   5177             // TODO Do this in a more elegant way later on. for now just a hack
   5178             if (!isFwdLocked()) {
   5179                 final int filePermissions =
   5180                     FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP
   5181                     |FileUtils.S_IROTH;
   5182                 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1);
   5183                 if (retCode != 0) {
   5184                     Slog.e(TAG, "Couldn't set new package file permissions for " +
   5185                             getCodePath()
   5186                             + ". The return code was: " + retCode);
   5187                     // TODO Define new internal error
   5188                     return false;
   5189                 }
   5190                 return true;
   5191             }
   5192             return true;
   5193         }
   5194 
   5195         boolean doPostDeleteLI(boolean delete) {
   5196             // XXX err, shouldn't we respect the delete flag?
   5197             cleanUpResourcesLI();
   5198             return true;
   5199         }
   5200 
   5201         private boolean isFwdLocked() {
   5202             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   5203         }
   5204     }
   5205 
   5206     class SdInstallArgs extends InstallArgs {
   5207         static final String RES_FILE_NAME = "pkg.apk";
   5208 
   5209         String cid;
   5210         String packagePath;
   5211         String libraryPath;
   5212 
   5213         SdInstallArgs(InstallParams params) {
   5214             super(params.packageURI, params.observer,
   5215                     params.flags, params.installerPackageName);
   5216         }
   5217 
   5218         SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
   5219             super(null, null, PackageManager.INSTALL_EXTERNAL, null);
   5220             // Extract cid from fullCodePath
   5221             int eidx = fullCodePath.lastIndexOf("/");
   5222             String subStr1 = fullCodePath.substring(0, eidx);
   5223             int sidx = subStr1.lastIndexOf("/");
   5224             cid = subStr1.substring(sidx+1, eidx);
   5225             setCachePath(subStr1);
   5226         }
   5227 
   5228         SdInstallArgs(String cid) {
   5229             super(null, null, PackageManager.INSTALL_EXTERNAL, null);
   5230             this.cid = cid;
   5231             setCachePath(PackageHelper.getSdDir(cid));
   5232         }
   5233 
   5234         SdInstallArgs(Uri packageURI, String cid) {
   5235             super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null);
   5236             this.cid = cid;
   5237         }
   5238 
   5239         void createCopyFile() {
   5240             cid = getTempContainerId();
   5241         }
   5242 
   5243         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
   5244             try {
   5245                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   5246                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5247                 return imcs.checkFreeStorage(true, packageURI);
   5248             } finally {
   5249                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5250             }
   5251         }
   5252 
   5253         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   5254             if (temp) {
   5255                 createCopyFile();
   5256             }
   5257 
   5258             final String newCachePath;
   5259             try {
   5260                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
   5261                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5262                 newCachePath = imcs.copyResourceToContainer(packageURI, cid,
   5263                         getEncryptKey(), RES_FILE_NAME);
   5264             } finally {
   5265                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
   5266             }
   5267 
   5268             if (newCachePath != null) {
   5269                 setCachePath(newCachePath);
   5270                 return PackageManager.INSTALL_SUCCEEDED;
   5271             } else {
   5272                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   5273             }
   5274         }
   5275 
   5276         @Override
   5277         String getCodePath() {
   5278             return packagePath;
   5279         }
   5280 
   5281         @Override
   5282         String getResourcePath() {
   5283             return packagePath;
   5284         }
   5285 
   5286         @Override
   5287         String getNativeLibraryPath() {
   5288             return libraryPath;
   5289         }
   5290 
   5291         int doPreInstall(int status) {
   5292             if (status != PackageManager.INSTALL_SUCCEEDED) {
   5293                 // Destroy container
   5294                 PackageHelper.destroySdDir(cid);
   5295             } else {
   5296                 boolean mounted = PackageHelper.isContainerMounted(cid);
   5297                 if (!mounted) {
   5298                     String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(),
   5299                             Process.SYSTEM_UID);
   5300                     if (newCachePath != null) {
   5301                         setCachePath(newCachePath);
   5302                     } else {
   5303                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   5304                     }
   5305                 }
   5306             }
   5307             return status;
   5308         }
   5309 
   5310         boolean doRename(int status, final String pkgName,
   5311                 String oldCodePath) {
   5312             String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
   5313             String newCachePath = null;
   5314             if (PackageHelper.isContainerMounted(cid)) {
   5315                 // Unmount the container
   5316                 if (!PackageHelper.unMountSdDir(cid)) {
   5317                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
   5318                     return false;
   5319                 }
   5320             }
   5321             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   5322                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
   5323                         " which might be stale. Will try to clean up.");
   5324                 // Clean up the stale container and proceed to recreate.
   5325                 if (!PackageHelper.destroySdDir(newCacheId)) {
   5326                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
   5327                     return false;
   5328                 }
   5329                 // Successfully cleaned up stale container. Try to rename again.
   5330                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   5331                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
   5332                             + " inspite of cleaning it up.");
   5333                     return false;
   5334                 }
   5335             }
   5336             if (!PackageHelper.isContainerMounted(newCacheId)) {
   5337                 Slog.w(TAG, "Mounting container " + newCacheId);
   5338                 newCachePath = PackageHelper.mountSdDir(newCacheId,
   5339                         getEncryptKey(), Process.SYSTEM_UID);
   5340             } else {
   5341                 newCachePath = PackageHelper.getSdDir(newCacheId);
   5342             }
   5343             if (newCachePath == null) {
   5344                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
   5345                 return false;
   5346             }
   5347             Log.i(TAG, "Succesfully renamed " + cid +
   5348                     " to " + newCacheId +
   5349                     " at new path: " + newCachePath);
   5350             cid = newCacheId;
   5351             setCachePath(newCachePath);
   5352             return true;
   5353         }
   5354 
   5355         private void setCachePath(String newCachePath) {
   5356             File cachePath = new File(newCachePath);
   5357             libraryPath = new File(cachePath, LIB_DIR_NAME).getPath();
   5358             packagePath = new File(cachePath, RES_FILE_NAME).getPath();
   5359         }
   5360 
   5361         int doPostInstall(int status) {
   5362             if (status != PackageManager.INSTALL_SUCCEEDED) {
   5363                 cleanUp();
   5364             } else {
   5365                 boolean mounted = PackageHelper.isContainerMounted(cid);
   5366                 if (!mounted) {
   5367                     PackageHelper.mountSdDir(cid,
   5368                             getEncryptKey(), Process.myUid());
   5369                 }
   5370             }
   5371             return status;
   5372         }
   5373 
   5374         private void cleanUp() {
   5375             // Destroy secure container
   5376             PackageHelper.destroySdDir(cid);
   5377         }
   5378 
   5379         void cleanUpResourcesLI() {
   5380             String sourceFile = getCodePath();
   5381             // Remove dex file
   5382             if (mInstaller != null) {
   5383                 int retCode = mInstaller.rmdex(sourceFile);
   5384                 if (retCode < 0) {
   5385                     Slog.w(TAG, "Couldn't remove dex file for package: "
   5386                             + " at location "
   5387                             + sourceFile.toString() + ", retcode=" + retCode);
   5388                     // we don't consider this to be a failure of the core package deletion
   5389                 }
   5390             }
   5391             cleanUp();
   5392         }
   5393 
   5394         boolean matchContainer(String app) {
   5395             if (cid.startsWith(app)) {
   5396                 return true;
   5397             }
   5398             return false;
   5399         }
   5400 
   5401         String getPackageName() {
   5402             int idx = cid.lastIndexOf("-");
   5403             if (idx == -1) {
   5404                 return cid;
   5405             }
   5406             return cid.substring(0, idx);
   5407         }
   5408 
   5409         boolean doPostDeleteLI(boolean delete) {
   5410             boolean ret = false;
   5411             boolean mounted = PackageHelper.isContainerMounted(cid);
   5412             if (mounted) {
   5413                 // Unmount first
   5414                 ret = PackageHelper.unMountSdDir(cid);
   5415             }
   5416             if (ret && delete) {
   5417                 cleanUpResourcesLI();
   5418             }
   5419             return ret;
   5420         }
   5421     };
   5422 
   5423     // Utility method used to create code paths based on package name and available index.
   5424     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
   5425         String idxStr = "";
   5426         int idx = 1;
   5427         // Fall back to default value of idx=1 if prefix is not
   5428         // part of oldCodePath
   5429         if (oldCodePath != null) {
   5430             String subStr = oldCodePath;
   5431             // Drop the suffix right away
   5432             if (subStr.endsWith(suffix)) {
   5433                 subStr = subStr.substring(0, subStr.length() - suffix.length());
   5434             }
   5435             // If oldCodePath already contains prefix find out the
   5436             // ending index to either increment or decrement.
   5437             int sidx = subStr.lastIndexOf(prefix);
   5438             if (sidx != -1) {
   5439                 subStr = subStr.substring(sidx + prefix.length());
   5440                 if (subStr != null) {
   5441                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
   5442                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
   5443                     }
   5444                     try {
   5445                         idx = Integer.parseInt(subStr);
   5446                         if (idx <= 1) {
   5447                             idx++;
   5448                         } else {
   5449                             idx--;
   5450                         }
   5451                     } catch(NumberFormatException e) {
   5452                     }
   5453                 }
   5454             }
   5455         }
   5456         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
   5457         return prefix + idxStr;
   5458     }
   5459 
   5460     // Utility method used to ignore ADD/REMOVE events
   5461     // by directory observer.
   5462     private static boolean ignoreCodePath(String fullPathStr) {
   5463         String apkName = getApkName(fullPathStr);
   5464         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
   5465         if (idx != -1 && ((idx+1) < apkName.length())) {
   5466             // Make sure the package ends with a numeral
   5467             String version = apkName.substring(idx+1);
   5468             try {
   5469                 Integer.parseInt(version);
   5470                 return true;
   5471             } catch (NumberFormatException e) {}
   5472         }
   5473         return false;
   5474     }
   5475 
   5476     // Utility method that returns the relative package path with respect
   5477     // to the installation directory. Like say for /data/data/com.test-1.apk
   5478     // string com.test-1 is returned.
   5479     static String getApkName(String codePath) {
   5480         if (codePath == null) {
   5481             return null;
   5482         }
   5483         int sidx = codePath.lastIndexOf("/");
   5484         int eidx = codePath.lastIndexOf(".");
   5485         if (eidx == -1) {
   5486             eidx = codePath.length();
   5487         } else if (eidx == 0) {
   5488             Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name");
   5489             return null;
   5490         }
   5491         return codePath.substring(sidx+1, eidx);
   5492     }
   5493 
   5494     class PackageInstalledInfo {
   5495         String name;
   5496         int uid;
   5497         PackageParser.Package pkg;
   5498         int returnCode;
   5499         PackageRemovedInfo removedInfo;
   5500     }
   5501 
   5502     /*
   5503      * Install a non-existing package.
   5504      */
   5505     private void installNewPackageLI(PackageParser.Package pkg,
   5506             int parseFlags,
   5507             int scanMode,
   5508             String installerPackageName, PackageInstalledInfo res) {
   5509         // Remember this for later, in case we need to rollback this install
   5510         String pkgName = pkg.packageName;
   5511 
   5512         boolean dataDirExists = getDataPathForPackage(pkg).exists();
   5513         res.name = pkgName;
   5514         synchronized(mPackages) {
   5515             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
   5516                 // A package with the same name is already installed, though
   5517                 // it has been renamed to an older name.  The package we
   5518                 // are trying to install should be installed as an update to
   5519                 // the existing one, but that has not been requested, so bail.
   5520                 Slog.w(TAG, "Attempt to re-install " + pkgName
   5521                         + " without first uninstalling package running as "
   5522                         + mSettings.mRenamedPackages.get(pkgName));
   5523                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   5524                 return;
   5525             }
   5526             if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) {
   5527                 // Don't allow installation over an existing package with the same name.
   5528                 Slog.w(TAG, "Attempt to re-install " + pkgName
   5529                         + " without first uninstalling.");
   5530                 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   5531                 return;
   5532             }
   5533         }
   5534         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   5535         PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
   5536                 System.currentTimeMillis());
   5537         if (newPackage == null) {
   5538             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
   5539             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
   5540                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
   5541             }
   5542         } else {
   5543             updateSettingsLI(newPackage,
   5544                     installerPackageName,
   5545                     res);
   5546             // delete the partially installed application. the data directory will have to be
   5547             // restored if it was already existing
   5548             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   5549                 // remove package from internal structures.  Note that we want deletePackageX to
   5550                 // delete the package data and cache directories that it created in
   5551                 // scanPackageLocked, unless those directories existed before we even tried to
   5552                 // install.
   5553                 deletePackageLI(
   5554                         pkgName, false,
   5555                         dataDirExists ? PackageManager.DONT_DELETE_DATA : 0,
   5556                                 res.removedInfo, true);
   5557             }
   5558         }
   5559     }
   5560 
   5561     private void replacePackageLI(PackageParser.Package pkg,
   5562             int parseFlags,
   5563             int scanMode,
   5564             String installerPackageName, PackageInstalledInfo res) {
   5565 
   5566         PackageParser.Package oldPackage;
   5567         String pkgName = pkg.packageName;
   5568         // First find the old package info and check signatures
   5569         synchronized(mPackages) {
   5570             oldPackage = mPackages.get(pkgName);
   5571             if (checkSignaturesLP(oldPackage.mSignatures, pkg.mSignatures)
   5572                     != PackageManager.SIGNATURE_MATCH) {
   5573                 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
   5574                 return;
   5575             }
   5576         }
   5577         boolean sysPkg = (isSystemApp(oldPackage));
   5578         if (sysPkg) {
   5579             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res);
   5580         } else {
   5581             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res);
   5582         }
   5583     }
   5584 
   5585     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
   5586             PackageParser.Package pkg,
   5587             int parseFlags, int scanMode,
   5588             String installerPackageName, PackageInstalledInfo res) {
   5589         PackageParser.Package newPackage = null;
   5590         String pkgName = deletedPackage.packageName;
   5591         boolean deletedPkg = true;
   5592         boolean updatedSettings = false;
   5593 
   5594         String oldInstallerPackageName = null;
   5595         synchronized (mPackages) {
   5596             oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName);
   5597         }
   5598 
   5599         long origUpdateTime;
   5600         if (pkg.mExtras != null) {
   5601             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
   5602         } else {
   5603             origUpdateTime = 0;
   5604         }
   5605 
   5606         // First delete the existing package while retaining the data directory
   5607         if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA,
   5608                 res.removedInfo, true)) {
   5609             // If the existing package wasn't successfully deleted
   5610             res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
   5611             deletedPkg = false;
   5612         } else {
   5613             // Successfully deleted the old package. Now proceed with re-installation
   5614             mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   5615             newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME,
   5616                     System.currentTimeMillis());
   5617             if (newPackage == null) {
   5618                 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
   5619                 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
   5620                     res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
   5621                 }
   5622             } else {
   5623                 updateSettingsLI(newPackage,
   5624                         installerPackageName,
   5625                         res);
   5626                 updatedSettings = true;
   5627             }
   5628         }
   5629 
   5630         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   5631             // remove package from internal structures.  Note that we want deletePackageX to
   5632             // delete the package data and cache directories that it created in
   5633             // scanPackageLocked, unless those directories existed before we even tried to
   5634             // install.
   5635             if(updatedSettings) {
   5636                 deletePackageLI(
   5637                         pkgName, true,
   5638                         PackageManager.DONT_DELETE_DATA,
   5639                                 res.removedInfo, true);
   5640             }
   5641             // Since we failed to install the new package we need to restore the old
   5642             // package that we deleted.
   5643             if(deletedPkg) {
   5644                 File restoreFile = new File(deletedPackage.mPath);
   5645                 if (restoreFile == null) {
   5646                     Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName);
   5647                     return;
   5648                 }
   5649                 // Parse old package
   5650                 boolean oldOnSd = isExternal(deletedPackage);
   5651                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
   5652                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
   5653                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
   5654                 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
   5655                         | SCAN_UPDATE_TIME;
   5656                 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode,
   5657                         origUpdateTime) == null) {
   5658                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
   5659                     return;
   5660                 }
   5661                 // Restore of old package succeeded. Update permissions.
   5662                 synchronized (mPackages) {
   5663                     updatePermissionsLP(deletedPackage.packageName, deletedPackage,
   5664                             true, false, false);
   5665                     mSettings.writeLP();
   5666                 }
   5667                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
   5668             }
   5669         }
   5670     }
   5671 
   5672     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
   5673             PackageParser.Package pkg,
   5674             int parseFlags, int scanMode,
   5675             String installerPackageName, PackageInstalledInfo res) {
   5676         PackageParser.Package newPackage = null;
   5677         boolean updatedSettings = false;
   5678         parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING |
   5679                 PackageParser.PARSE_IS_SYSTEM;
   5680         String packageName = deletedPackage.packageName;
   5681         res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
   5682         if (packageName == null) {
   5683             Slog.w(TAG, "Attempt to delete null packageName.");
   5684             return;
   5685         }
   5686         PackageParser.Package oldPkg;
   5687         PackageSetting oldPkgSetting;
   5688         synchronized (mPackages) {
   5689             oldPkg = mPackages.get(packageName);
   5690             oldPkgSetting = mSettings.mPackages.get(packageName);
   5691             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
   5692                     (oldPkgSetting == null)) {
   5693                 Slog.w(TAG, "Couldn't find package:"+packageName+" information");
   5694                 return;
   5695             }
   5696         }
   5697 
   5698         killApplication(packageName, oldPkg.applicationInfo.uid);
   5699 
   5700         res.removedInfo.uid = oldPkg.applicationInfo.uid;
   5701         res.removedInfo.removedPackage = packageName;
   5702         // Remove existing system package
   5703         removePackageLI(oldPkg, true);
   5704         synchronized (mPackages) {
   5705             if (!mSettings.disableSystemPackageLP(packageName) && deletedPackage != null) {
   5706                 // We didn't need to disable the .apk as a current system package,
   5707                 // which means we are replacing another update that is already
   5708                 // installed.  We need to make sure to delete the older one's .apk.
   5709                 res.removedInfo.args = createInstallArgs(isExternal(pkg)
   5710                         ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL,
   5711                         deletedPackage.applicationInfo.sourceDir,
   5712                         deletedPackage.applicationInfo.publicSourceDir,
   5713                         deletedPackage.applicationInfo.nativeLibraryDir);
   5714             } else {
   5715                 res.removedInfo.args = null;
   5716             }
   5717         }
   5718 
   5719         // Successfully disabled the old package. Now proceed with re-installation
   5720         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   5721         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   5722         newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0);
   5723         if (newPackage == null) {
   5724             Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath);
   5725             if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) {
   5726                 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK;
   5727             }
   5728         } else {
   5729             if (newPackage.mExtras != null) {
   5730                 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras;
   5731                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
   5732                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
   5733             }
   5734             updateSettingsLI(newPackage, installerPackageName, res);
   5735             updatedSettings = true;
   5736         }
   5737 
   5738         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   5739             // Re installation failed. Restore old information
   5740             // Remove new pkg information
   5741             if (newPackage != null) {
   5742                 removePackageLI(newPackage, true);
   5743             }
   5744             // Add back the old system package
   5745             scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0);
   5746             // Restore the old system information in Settings
   5747             synchronized(mPackages) {
   5748                 if (updatedSettings) {
   5749                     mSettings.enableSystemPackageLP(packageName);
   5750                     mSettings.setInstallerPackageName(packageName,
   5751                             oldPkgSetting.installerPackageName);
   5752                 }
   5753                 mSettings.writeLP();
   5754             }
   5755         }
   5756     }
   5757 
   5758     // Utility method used to move dex files during install.
   5759     private int moveDexFilesLI(PackageParser.Package newPackage) {
   5760         int retCode;
   5761         if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
   5762             retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
   5763             if (retCode != 0) {
   5764                 if (mNoDexOpt) {
   5765                     /*
   5766                      * If we're in an engineering build, programs are lazily run
   5767                      * through dexopt. If the .dex file doesn't exist yet, it
   5768                      * will be created when the program is run next.
   5769                      */
   5770                     Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath);
   5771                 } else {
   5772                     Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath);
   5773                     return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5774                 }
   5775             }
   5776         }
   5777         return PackageManager.INSTALL_SUCCEEDED;
   5778     }
   5779 
   5780     private void updateSettingsLI(PackageParser.Package newPackage,
   5781             String installerPackageName, PackageInstalledInfo res) {
   5782         String pkgName = newPackage.packageName;
   5783         synchronized (mPackages) {
   5784             //write settings. the installStatus will be incomplete at this stage.
   5785             //note that the new package setting would have already been
   5786             //added to mPackages. It hasn't been persisted yet.
   5787             mSettings.setInstallStatus(pkgName, PKG_INSTALL_INCOMPLETE);
   5788             mSettings.writeLP();
   5789         }
   5790 
   5791         if ((res.returnCode = moveDexFilesLI(newPackage))
   5792                 != PackageManager.INSTALL_SUCCEEDED) {
   5793             // Discontinue if moving dex files failed.
   5794             return;
   5795         }
   5796         if((res.returnCode = setPermissionsLI(newPackage))
   5797                 != PackageManager.INSTALL_SUCCEEDED) {
   5798             if (mInstaller != null) {
   5799                 mInstaller.rmdex(newPackage.mScanPath);
   5800             }
   5801             return;
   5802         } else {
   5803             Log.d(TAG, "New package installed in " + newPackage.mPath);
   5804         }
   5805         synchronized (mPackages) {
   5806             updatePermissionsLP(newPackage.packageName, newPackage,
   5807                     newPackage.permissions.size() > 0, true, false);
   5808             res.name = pkgName;
   5809             res.uid = newPackage.applicationInfo.uid;
   5810             res.pkg = newPackage;
   5811             mSettings.setInstallStatus(pkgName, PKG_INSTALL_COMPLETE);
   5812             mSettings.setInstallerPackageName(pkgName, installerPackageName);
   5813             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   5814             //to update install status
   5815             mSettings.writeLP();
   5816         }
   5817     }
   5818 
   5819     private void installPackageLI(InstallArgs args,
   5820             boolean newInstall, PackageInstalledInfo res) {
   5821         int pFlags = args.flags;
   5822         String installerPackageName = args.installerPackageName;
   5823         File tmpPackageFile = new File(args.getCodePath());
   5824         boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
   5825         boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
   5826         boolean replace = false;
   5827         int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
   5828                 | (newInstall ? SCAN_NEW_INSTALL : 0);
   5829         // Result object to be returned
   5830         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   5831 
   5832         // Retrieve PackageSettings and parse package
   5833         int parseFlags = PackageParser.PARSE_CHATTY |
   5834         (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) |
   5835         (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
   5836         parseFlags |= mDefParseFlags;
   5837         PackageParser pp = new PackageParser(tmpPackageFile.getPath());
   5838         pp.setSeparateProcesses(mSeparateProcesses);
   5839         final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
   5840                 null, mMetrics, parseFlags);
   5841         if (pkg == null) {
   5842             res.returnCode = pp.getParseError();
   5843             return;
   5844         }
   5845         String pkgName = res.name = pkg.packageName;
   5846         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
   5847             if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
   5848                 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY;
   5849                 return;
   5850             }
   5851         }
   5852         if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) {
   5853             res.returnCode = pp.getParseError();
   5854             return;
   5855         }
   5856         // Get rid of all references to package scan path via parser.
   5857         pp = null;
   5858         String oldCodePath = null;
   5859         boolean systemApp = false;
   5860         synchronized (mPackages) {
   5861             // Check if installing already existing package
   5862             if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   5863                 String oldName = mSettings.mRenamedPackages.get(pkgName);
   5864                 if (pkg.mOriginalPackages != null
   5865                         && pkg.mOriginalPackages.contains(oldName)
   5866                         && mPackages.containsKey(oldName)) {
   5867                     // This package is derived from an original package,
   5868                     // and this device has been updating from that original
   5869                     // name.  We must continue using the original name, so
   5870                     // rename the new package here.
   5871                     pkg.setPackageName(oldName);
   5872                     pkgName = pkg.packageName;
   5873                     replace = true;
   5874                 } else if (mPackages.containsKey(pkgName)) {
   5875                     // This package, under its official name, already exists
   5876                     // on the device; we should replace it.
   5877                     replace = true;
   5878                 }
   5879             }
   5880             PackageSetting ps = mSettings.mPackages.get(pkgName);
   5881             if (ps != null) {
   5882                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
   5883                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
   5884                     systemApp = (ps.pkg.applicationInfo.flags &
   5885                             ApplicationInfo.FLAG_SYSTEM) != 0;
   5886                 }
   5887             }
   5888         }
   5889 
   5890         if (systemApp && onSd) {
   5891             // Disable updates to system apps on sdcard
   5892             Slog.w(TAG, "Cannot install updates to system apps on sdcard");
   5893             res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   5894             return;
   5895         }
   5896 
   5897         if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
   5898             res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5899             return;
   5900         }
   5901         // Set application objects path explicitly after the rename
   5902         setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath());
   5903         pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath();
   5904         if (replace) {
   5905             replacePackageLI(pkg, parseFlags, scanMode,
   5906                     installerPackageName, res);
   5907         } else {
   5908             installNewPackageLI(pkg, parseFlags, scanMode,
   5909                     installerPackageName,res);
   5910         }
   5911     }
   5912 
   5913     private int setPermissionsLI(PackageParser.Package newPackage) {
   5914         String pkgName = newPackage.packageName;
   5915         int retCode = 0;
   5916         // TODO Gross hack but fix later. Ideally move this to be a post installation
   5917         // check after alloting uid.
   5918         if (isForwardLocked(newPackage)) {
   5919             File destResourceFile = new File(newPackage.applicationInfo.publicSourceDir);
   5920             try {
   5921                 extractPublicFiles(newPackage, destResourceFile);
   5922             } catch (IOException e) {
   5923                 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" +
   5924                            " forward-locked app.");
   5925                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5926             } finally {
   5927                 //TODO clean up the extracted public files
   5928             }
   5929             if (mInstaller != null) {
   5930                 retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath),
   5931                         newPackage.applicationInfo.uid);
   5932             } else {
   5933                 final int filePermissions =
   5934                         FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP;
   5935                 retCode = FileUtils.setPermissions(newPackage.mPath, filePermissions, -1,
   5936                                                    newPackage.applicationInfo.uid);
   5937             }
   5938         } else {
   5939             // The permissions on the resource file was set when it was copied for
   5940             // non forward locked apps and apps on sdcard
   5941         }
   5942 
   5943         if (retCode != 0) {
   5944             Slog.e(TAG, "Couldn't set new package file permissions for " +
   5945                     newPackage.mPath
   5946                        + ". The return code was: " + retCode);
   5947             // TODO Define new internal error
   5948             return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   5949         }
   5950         return PackageManager.INSTALL_SUCCEEDED;
   5951     }
   5952 
   5953     private static boolean isForwardLocked(PackageParser.Package pkg) {
   5954         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
   5955     }
   5956 
   5957     private static boolean isExternal(PackageParser.Package pkg) {
   5958         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   5959     }
   5960 
   5961     private static boolean isSystemApp(PackageParser.Package pkg) {
   5962         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   5963     }
   5964 
   5965     private static boolean isSystemApp(ApplicationInfo info) {
   5966         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   5967     }
   5968 
   5969     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
   5970         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   5971     }
   5972 
   5973     private void extractPublicFiles(PackageParser.Package newPackage,
   5974                                     File publicZipFile) throws IOException {
   5975         final FileOutputStream fstr = new FileOutputStream(publicZipFile);
   5976         final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr);
   5977         final ZipFile privateZip = new ZipFile(newPackage.mPath);
   5978 
   5979         // Copy manifest, resources.arsc and res directory to public zip
   5980 
   5981         final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries();
   5982         while (privateZipEntries.hasMoreElements()) {
   5983             final ZipEntry zipEntry = privateZipEntries.nextElement();
   5984             final String zipEntryName = zipEntry.getName();
   5985             if ("AndroidManifest.xml".equals(zipEntryName)
   5986                 || "resources.arsc".equals(zipEntryName)
   5987                 || zipEntryName.startsWith("res/")) {
   5988                 try {
   5989                     copyZipEntry(zipEntry, privateZip, publicZipOutStream);
   5990                 } catch (IOException e) {
   5991                     try {
   5992                         publicZipOutStream.close();
   5993                         throw e;
   5994                     } finally {
   5995                         publicZipFile.delete();
   5996                     }
   5997                 }
   5998             }
   5999         }
   6000 
   6001         publicZipOutStream.finish();
   6002         publicZipOutStream.flush();
   6003         FileUtils.sync(fstr);
   6004         publicZipOutStream.close();
   6005         FileUtils.setPermissions(
   6006                 publicZipFile.getAbsolutePath(),
   6007                 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP|FileUtils.S_IROTH,
   6008                 -1, -1);
   6009     }
   6010 
   6011     private static void copyZipEntry(ZipEntry zipEntry,
   6012                                      ZipFile inZip