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