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