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