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