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