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     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<9;
    221 
    222     static final int REMOVE_CHATTY = 1<<16;
    223 
    224     /**
    225      * Timeout (in milliseconds) after which the watchdog should declare that
    226      * our handler thread is wedged.  The usual default for such things is one
    227      * minute but we sometimes do very lengthy I/O operations on this thread,
    228      * such as installing multi-gigabyte applications, so ours needs to be longer.
    229      */
    230     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
    231 
    232     /**
    233      * Whether verification is enabled by default.
    234      */
    235     private static final boolean DEFAULT_VERIFY_ENABLE = true;
    236 
    237     /**
    238      * The default maximum time to wait for the verification agent to return in
    239      * milliseconds.
    240      */
    241     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
    242 
    243     /**
    244      * The default response for package verification timeout.
    245      *
    246      * This can be either PackageManager.VERIFICATION_ALLOW or
    247      * PackageManager.VERIFICATION_REJECT.
    248      */
    249     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
    250 
    251     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
    252 
    253     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
    254             DEFAULT_CONTAINER_PACKAGE,
    255             "com.android.defcontainer.DefaultContainerService");
    256 
    257     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
    258 
    259     private static final String LIB_DIR_NAME = "lib";
    260 
    261     static final String mTempContainerPrefix = "smdl2tmp";
    262 
    263     final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
    264             Process.THREAD_PRIORITY_BACKGROUND);
    265     final PackageHandler mHandler;
    266 
    267     final int mSdkVersion = Build.VERSION.SDK_INT;
    268     final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
    269             ? null : Build.VERSION.CODENAME;
    270 
    271     final Context mContext;
    272     final boolean mFactoryTest;
    273     final boolean mOnlyCore;
    274     final boolean mNoDexOpt;
    275     final DisplayMetrics mMetrics;
    276     final int mDefParseFlags;
    277     final String[] mSeparateProcesses;
    278 
    279     // This is where all application persistent data goes.
    280     final File mAppDataDir;
    281 
    282     // This is where all application persistent data goes for secondary users.
    283     final File mUserAppDataDir;
    284 
    285     /** The location for ASEC container files on internal storage. */
    286     final String mAsecInternalPath;
    287 
    288     // This is the object monitoring the framework dir.
    289     final FileObserver mFrameworkInstallObserver;
    290 
    291     // This is the object monitoring the system app dir.
    292     final FileObserver mSystemInstallObserver;
    293 
    294     // This is the object monitoring the privileged system app dir.
    295     final FileObserver mPrivilegedInstallObserver;
    296 
    297     // This is the object monitoring the system app dir.
    298     final FileObserver mVendorInstallObserver;
    299 
    300     // This is the object monitoring mAppInstallDir.
    301     final FileObserver mAppInstallObserver;
    302 
    303     // This is the object monitoring mDrmAppPrivateInstallDir.
    304     final FileObserver mDrmAppInstallObserver;
    305 
    306     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
    307     // LOCK HELD.  Can be called with mInstallLock held.
    308     final Installer mInstaller;
    309 
    310     final File mAppInstallDir;
    311 
    312     /**
    313      * Directory to which applications installed internally have native
    314      * libraries copied.
    315      */
    316     private File mAppLibInstallDir;
    317 
    318     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
    319     // apps.
    320     final File mDrmAppPrivateInstallDir;
    321 
    322     // ----------------------------------------------------------------
    323 
    324     // Lock for state used when installing and doing other long running
    325     // operations.  Methods that must be called with this lock held have
    326     // the prefix "LI".
    327     final Object mInstallLock = new Object();
    328 
    329     // These are the directories in the 3rd party applications installed dir
    330     // that we have currently loaded packages from.  Keys are the application's
    331     // installed zip file (absolute codePath), and values are Package.
    332     final HashMap<String, PackageParser.Package> mAppDirs =
    333             new HashMap<String, PackageParser.Package>();
    334 
    335     // Information for the parser to write more useful error messages.
    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, true,
    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             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
   3662             // flag set initially
   3663             if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
   3664                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   3665             }
   3666         }
   3667         // Verify certificates against what was last scanned
   3668         if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
   3669             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
   3670             return null;
   3671         }
   3672 
   3673         /*
   3674          * A new system app appeared, but we already had a non-system one of the
   3675          * same name installed earlier.
   3676          */
   3677         boolean shouldHideSystemApp = false;
   3678         if (updatedPkg == null && ps != null
   3679                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
   3680             /*
   3681              * Check to make sure the signatures match first. If they don't,
   3682              * wipe the installed application and its data.
   3683              */
   3684             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
   3685                     != PackageManager.SIGNATURE_MATCH) {
   3686                 if (DEBUG_INSTALL) Slog.d(TAG, "Signature mismatch!");
   3687                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
   3688                 ps = null;
   3689             } else {
   3690                 /*
   3691                  * If the newly-added system app is an older version than the
   3692                  * already installed version, hide it. It will be scanned later
   3693                  * and re-added like an update.
   3694                  */
   3695                 if (pkg.mVersionCode < ps.versionCode) {
   3696                     shouldHideSystemApp = true;
   3697                 } else {
   3698                     /*
   3699                      * The newly found system app is a newer version that the
   3700                      * one previously installed. Simply remove the
   3701                      * already-installed application and replace it with our own
   3702                      * while keeping the application data.
   3703                      */
   3704                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
   3705                             + ps.codePathString + ": new version " + pkg.mVersionCode
   3706                             + " better than installed " + ps.versionCode);
   3707                     InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
   3708                             ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
   3709                     synchronized (mInstallLock) {
   3710                         args.cleanUpResourcesLI();
   3711                     }
   3712                 }
   3713             }
   3714         }
   3715 
   3716         // The apk is forward locked (not public) if its code and resources
   3717         // are kept in different files. (except for app in either system or
   3718         // vendor path).
   3719         // TODO grab this value from PackageSettings
   3720         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   3721             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
   3722                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   3723             }
   3724         }
   3725 
   3726         String codePath = null;
   3727         String resPath = null;
   3728         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
   3729             if (ps != null && ps.resourcePathString != null) {
   3730                 resPath = ps.resourcePathString;
   3731             } else {
   3732                 // Should not happen at all. Just log an error.
   3733                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
   3734             }
   3735         } else {
   3736             resPath = pkg.mScanPath;
   3737         }
   3738 
   3739         codePath = pkg.mScanPath;
   3740         // Set application objects path explicitly.
   3741         setApplicationInfoPaths(pkg, codePath, resPath);
   3742         // Note that we invoke the following method only if we are about to unpack an application
   3743         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
   3744                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
   3745 
   3746         /*
   3747          * If the system app should be overridden by a previously installed
   3748          * data, hide the system app now and let the /data/app scan pick it up
   3749          * again.
   3750          */
   3751         if (shouldHideSystemApp) {
   3752             synchronized (mPackages) {
   3753                 /*
   3754                  * We have to grant systems permissions before we hide, because
   3755                  * grantPermissions will assume the package update is trying to
   3756                  * expand its permissions.
   3757                  */
   3758                 grantPermissionsLPw(pkg, true);
   3759                 mSettings.disableSystemPackageLPw(pkg.packageName);
   3760             }
   3761         }
   3762 
   3763         return scannedPkg;
   3764     }
   3765 
   3766     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
   3767             String destResPath) {
   3768         pkg.mPath = pkg.mScanPath = destCodePath;
   3769         pkg.applicationInfo.sourceDir = destCodePath;
   3770         pkg.applicationInfo.publicSourceDir = destResPath;
   3771     }
   3772 
   3773     private static String fixProcessName(String defProcessName,
   3774             String processName, int uid) {
   3775         if (processName == null) {
   3776             return defProcessName;
   3777         }
   3778         return processName;
   3779     }
   3780 
   3781     private boolean verifySignaturesLP(PackageSetting pkgSetting,
   3782             PackageParser.Package pkg) {
   3783         if (pkgSetting.signatures.mSignatures != null) {
   3784             // Already existing package. Make sure signatures match
   3785             if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
   3786                 PackageManager.SIGNATURE_MATCH) {
   3787                     Slog.e(TAG, "Package " + pkg.packageName
   3788                             + " signatures do not match the previously installed version; ignoring!");
   3789                     mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
   3790                     return false;
   3791                 }
   3792         }
   3793         // Check for shared user signatures
   3794         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
   3795             if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   3796                     pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   3797                 Slog.e(TAG, "Package " + pkg.packageName
   3798                         + " has no signatures that match those in shared user "
   3799                         + pkgSetting.sharedUser.name + "; ignoring!");
   3800                 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
   3801                 return false;
   3802             }
   3803         }
   3804         return true;
   3805     }
   3806 
   3807     /**
   3808      * Enforces that only the system UID or root's UID can call a method exposed
   3809      * via Binder.
   3810      *
   3811      * @param message used as message if SecurityException is thrown
   3812      * @throws SecurityException if the caller is not system or root
   3813      */
   3814     private static final void enforceSystemOrRoot(String message) {
   3815         final int uid = Binder.getCallingUid();
   3816         if (uid != Process.SYSTEM_UID && uid != 0) {
   3817             throw new SecurityException(message);
   3818         }
   3819     }
   3820 
   3821     public void performBootDexOpt() {
   3822         HashSet<PackageParser.Package> pkgs = null;
   3823         synchronized (mPackages) {
   3824             pkgs = mDeferredDexOpt;
   3825             mDeferredDexOpt = null;
   3826         }
   3827         if (pkgs != null) {
   3828             int i = 0;
   3829             for (PackageParser.Package pkg : pkgs) {
   3830                 if (!isFirstBoot()) {
   3831                     i++;
   3832                     try {
   3833                         ActivityManagerNative.getDefault().showBootMessage(
   3834                                 mContext.getResources().getString(
   3835                                         com.android.internal.R.string.android_upgrading_apk,
   3836                                         i, pkgs.size()), true);
   3837                     } catch (RemoteException e) {
   3838                     }
   3839                 }
   3840                 PackageParser.Package p = pkg;
   3841                 synchronized (mInstallLock) {
   3842                     if (!p.mDidDexOpt) {
   3843                         performDexOptLI(p, false, false, true);
   3844                     }
   3845                 }
   3846             }
   3847         }
   3848     }
   3849 
   3850     public boolean performDexOpt(String packageName) {
   3851         enforceSystemOrRoot("Only the system can request dexopt be performed");
   3852 
   3853         if (!mNoDexOpt) {
   3854             return false;
   3855         }
   3856 
   3857         PackageParser.Package p;
   3858         synchronized (mPackages) {
   3859             p = mPackages.get(packageName);
   3860             if (p == null || p.mDidDexOpt) {
   3861                 return false;
   3862             }
   3863         }
   3864         synchronized (mInstallLock) {
   3865             return performDexOptLI(p, false, false, true) == DEX_OPT_PERFORMED;
   3866         }
   3867     }
   3868 
   3869     private void performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer,
   3870             HashSet<String> done) {
   3871         for (int i=0; i<libs.size(); i++) {
   3872             PackageParser.Package libPkg;
   3873             String libName;
   3874             synchronized (mPackages) {
   3875                 libName = libs.get(i);
   3876                 SharedLibraryEntry lib = mSharedLibraries.get(libName);
   3877                 if (lib != null && lib.apk != null) {
   3878                     libPkg = mPackages.get(lib.apk);
   3879                 } else {
   3880                     libPkg = null;
   3881                 }
   3882             }
   3883             if (libPkg != null && !done.contains(libName)) {
   3884                 performDexOptLI(libPkg, forceDex, defer, done);
   3885             }
   3886         }
   3887     }
   3888 
   3889     static final int DEX_OPT_SKIPPED = 0;
   3890     static final int DEX_OPT_PERFORMED = 1;
   3891     static final int DEX_OPT_DEFERRED = 2;
   3892     static final int DEX_OPT_FAILED = -1;
   3893 
   3894     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
   3895             HashSet<String> done) {
   3896         boolean performed = false;
   3897         if (done != null) {
   3898             done.add(pkg.packageName);
   3899             if (pkg.usesLibraries != null) {
   3900                 performDexOptLibsLI(pkg.usesLibraries, forceDex, defer, done);
   3901             }
   3902             if (pkg.usesOptionalLibraries != null) {
   3903                 performDexOptLibsLI(pkg.usesOptionalLibraries, forceDex, defer, done);
   3904             }
   3905         }
   3906         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
   3907             String path = pkg.mScanPath;
   3908             int ret = 0;
   3909             try {
   3910                 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
   3911                     if (!forceDex && defer) {
   3912                         if (mDeferredDexOpt == null) {
   3913                             mDeferredDexOpt = new HashSet<PackageParser.Package>();
   3914                         }
   3915                         mDeferredDexOpt.add(pkg);
   3916                         return DEX_OPT_DEFERRED;
   3917                     } else {
   3918                         Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
   3919                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   3920                         ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg));
   3921                         pkg.mDidDexOpt = true;
   3922                         performed = true;
   3923                     }
   3924                 }
   3925             } catch (FileNotFoundException e) {
   3926                 Slog.w(TAG, "Apk not found for dexopt: " + path);
   3927                 ret = -1;
   3928             } catch (IOException e) {
   3929                 Slog.w(TAG, "IOException reading apk: " + path, e);
   3930                 ret = -1;
   3931             } catch (dalvik.system.StaleDexCacheError e) {
   3932                 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
   3933                 ret = -1;
   3934             } catch (Exception e) {
   3935                 Slog.w(TAG, "Exception when doing dexopt : ", e);
   3936                 ret = -1;
   3937             }
   3938             if (ret < 0) {
   3939                 //error from installer
   3940                 return DEX_OPT_FAILED;
   3941             }
   3942         }
   3943 
   3944         return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
   3945     }
   3946 
   3947     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer,
   3948             boolean inclDependencies) {
   3949         HashSet<String> done;
   3950         boolean performed = false;
   3951         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
   3952             done = new HashSet<String>();
   3953             done.add(pkg.packageName);
   3954         } else {
   3955             done = null;
   3956         }
   3957         return performDexOptLI(pkg, forceDex, defer, done);
   3958     }
   3959 
   3960     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
   3961         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   3962             Slog.w(TAG, "Unable to update from " + oldPkg.name
   3963                     + " to " + newPkg.packageName
   3964                     + ": old package not in system partition");
   3965             return false;
   3966         } else if (mPackages.get(oldPkg.name) != null) {
   3967             Slog.w(TAG, "Unable to update from " + oldPkg.name
   3968                     + " to " + newPkg.packageName
   3969                     + ": old package still exists");
   3970             return false;
   3971         }
   3972         return true;
   3973     }
   3974 
   3975     File getDataPathForUser(int userId) {
   3976         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
   3977     }
   3978 
   3979     private File getDataPathForPackage(String packageName, int userId) {
   3980         /*
   3981          * Until we fully support multiple users, return the directory we
   3982          * previously would have. The PackageManagerTests will need to be
   3983          * revised when this is changed back..
   3984          */
   3985         if (userId == 0) {
   3986             return new File(mAppDataDir, packageName);
   3987         } else {
   3988             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
   3989                 + File.separator + packageName);
   3990         }
   3991     }
   3992 
   3993     private int createDataDirsLI(String packageName, int uid, String seinfo) {
   3994         int[] users = sUserManager.getUserIds();
   3995         int res = mInstaller.install(packageName, uid, uid, seinfo);
   3996         if (res < 0) {
   3997             return res;
   3998         }
   3999         for (int user : users) {
   4000             if (user != 0) {
   4001                 res = mInstaller.createUserData(packageName,
   4002                         UserHandle.getUid(user, uid), user);
   4003                 if (res < 0) {
   4004                     return res;
   4005                 }
   4006             }
   4007         }
   4008         return res;
   4009     }
   4010 
   4011     private int removeDataDirsLI(String packageName) {
   4012         int[] users = sUserManager.getUserIds();
   4013         int res = 0;
   4014         for (int user : users) {
   4015             int resInner = mInstaller.remove(packageName, user);
   4016             if (resInner < 0) {
   4017                 res = resInner;
   4018             }
   4019         }
   4020 
   4021         final File nativeLibraryFile = new File(mAppLibInstallDir, packageName);
   4022         NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile);
   4023         if (!nativeLibraryFile.delete()) {
   4024             Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath());
   4025         }
   4026 
   4027         return res;
   4028     }
   4029 
   4030     private int addSharedLibraryLPw(final SharedLibraryEntry file, int num,
   4031             PackageParser.Package changingLib) {
   4032         if (file.path != null) {
   4033             mTmpSharedLibraries[num] = file.path;
   4034             return num+1;
   4035         }
   4036         PackageParser.Package p = mPackages.get(file.apk);
   4037         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
   4038             // If we are doing this while in the middle of updating a library apk,
   4039             // then we need to make sure to use that new apk for determining the
   4040             // dependencies here.  (We haven't yet finished committing the new apk
   4041             // to the package manager state.)
   4042             if (p == null || p.packageName.equals(changingLib.packageName)) {
   4043                 p = changingLib;
   4044             }
   4045         }
   4046         if (p != null) {
   4047             String path = p.mPath;
   4048             for (int i=0; i<num; i++) {
   4049                 if (mTmpSharedLibraries[i].equals(path)) {
   4050                     return num;
   4051                 }
   4052             }
   4053             mTmpSharedLibraries[num] = p.mPath;
   4054             return num+1;
   4055         }
   4056         return num;
   4057     }
   4058 
   4059     private boolean updateSharedLibrariesLPw(PackageParser.Package pkg,
   4060             PackageParser.Package changingLib) {
   4061         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
   4062             if (mTmpSharedLibraries == null ||
   4063                     mTmpSharedLibraries.length < mSharedLibraries.size()) {
   4064                 mTmpSharedLibraries = new String[mSharedLibraries.size()];
   4065             }
   4066             int num = 0;
   4067             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
   4068             for (int i=0; i<N; i++) {
   4069                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
   4070                 if (file == null) {
   4071                     Slog.e(TAG, "Package " + pkg.packageName
   4072                             + " requires unavailable shared library "
   4073                             + pkg.usesLibraries.get(i) + "; failing!");
   4074                     mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
   4075                     return false;
   4076                 }
   4077                 num = addSharedLibraryLPw(file, num, changingLib);
   4078             }
   4079             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
   4080             for (int i=0; i<N; i++) {
   4081                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
   4082                 if (file == null) {
   4083                     Slog.w(TAG, "Package " + pkg.packageName
   4084                             + " desires unavailable shared library "
   4085                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
   4086                 } else {
   4087                     num = addSharedLibraryLPw(file, num, changingLib);
   4088                 }
   4089             }
   4090             if (num > 0) {
   4091                 pkg.usesLibraryFiles = new String[num];
   4092                 System.arraycopy(mTmpSharedLibraries, 0,
   4093                         pkg.usesLibraryFiles, 0, num);
   4094             } else {
   4095                 pkg.usesLibraryFiles = null;
   4096             }
   4097         }
   4098         return true;
   4099     }
   4100 
   4101     private static boolean hasString(List<String> list, List<String> which) {
   4102         if (list == null) {
   4103             return false;
   4104         }
   4105         for (int i=list.size()-1; i>=0; i--) {
   4106             for (int j=which.size()-1; j>=0; j--) {
   4107                 if (which.get(j).equals(list.get(i))) {
   4108                     return true;
   4109                 }
   4110             }
   4111         }
   4112         return false;
   4113     }
   4114 
   4115     private void updateAllSharedLibrariesLPw() {
   4116         for (PackageParser.Package pkg : mPackages.values()) {
   4117             updateSharedLibrariesLPw(pkg, null);
   4118         }
   4119     }
   4120 
   4121     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
   4122             PackageParser.Package changingPkg) {
   4123         ArrayList<PackageParser.Package> res = null;
   4124         for (PackageParser.Package pkg : mPackages.values()) {
   4125             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
   4126                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
   4127                 if (res == null) {
   4128                     res = new ArrayList<PackageParser.Package>();
   4129                 }
   4130                 res.add(pkg);
   4131                 updateSharedLibrariesLPw(pkg, changingPkg);
   4132             }
   4133         }
   4134         return res;
   4135     }
   4136 
   4137     private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
   4138             int parseFlags, int scanMode, long currentTime, UserHandle user) {
   4139         File scanFile = new File(pkg.mScanPath);
   4140         if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
   4141                 pkg.applicationInfo.publicSourceDir == null) {
   4142             // Bail out. The resource and code paths haven't been set.
   4143             Slog.w(TAG, " Code and resource paths haven't been set correctly");
   4144             mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
   4145             return null;
   4146         }
   4147 
   4148         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   4149             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
   4150         }
   4151 
   4152         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
   4153             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
   4154         }
   4155 
   4156         if (mCustomResolverComponentName != null &&
   4157                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
   4158             setUpCustomResolverActivity(pkg);
   4159         }
   4160 
   4161         if (pkg.packageName.equals("android")) {
   4162             synchronized (mPackages) {
   4163                 if (mAndroidApplication != null) {
   4164                     Slog.w(TAG, "*************************************************");
   4165                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
   4166                     Slog.w(TAG, " file=" + scanFile);
   4167                     Slog.w(TAG, "*************************************************");
   4168                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   4169                     return null;
   4170                 }
   4171 
   4172                 // Set up information for our fall-back user intent resolution activity.
   4173                 mPlatformPackage = pkg;
   4174                 pkg.mVersionCode = mSdkVersion;
   4175                 mAndroidApplication = pkg.applicationInfo;
   4176 
   4177                 if (!mResolverReplaced) {
   4178                     mResolveActivity.applicationInfo = mAndroidApplication;
   4179                     mResolveActivity.name = ResolverActivity.class.getName();
   4180                     mResolveActivity.packageName = mAndroidApplication.packageName;
   4181                     mResolveActivity.processName = "system:ui";
   4182                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   4183                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
   4184                     mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
   4185                     mResolveActivity.exported = true;
   4186                     mResolveActivity.enabled = true;
   4187                     mResolveInfo.activityInfo = mResolveActivity;
   4188                     mResolveInfo.priority = 0;
   4189                     mResolveInfo.preferredOrder = 0;
   4190                     mResolveInfo.match = 0;
   4191                     mResolveComponentName = new ComponentName(
   4192                             mAndroidApplication.packageName, mResolveActivity.name);
   4193                 }
   4194             }
   4195         }
   4196 
   4197         if (DEBUG_PACKAGE_SCANNING) {
   4198             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   4199                 Log.d(TAG, "Scanning package " + pkg.packageName);
   4200         }
   4201 
   4202         if (mPackages.containsKey(pkg.packageName)
   4203                 || mSharedLibraries.containsKey(pkg.packageName)) {
   4204             Slog.w(TAG, "Application package " + pkg.packageName
   4205                     + " already installed.  Skipping duplicate.");
   4206             mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   4207             return null;
   4208         }
   4209 
   4210         // Initialize package source and resource directories
   4211         File destCodeFile = new File(pkg.applicationInfo.sourceDir);
   4212         File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
   4213 
   4214         SharedUserSetting suid = null;
   4215         PackageSetting pkgSetting = null;
   4216 
   4217         if (!isSystemApp(pkg)) {
   4218             // Only system apps can use these features.
   4219             pkg.mOriginalPackages = null;
   4220             pkg.mRealPackage = null;
   4221             pkg.mAdoptPermissions = null;
   4222         }
   4223 
   4224         // writer
   4225         synchronized (mPackages) {
   4226             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   4227                 // Check all shared libraries and map to their actual file path.
   4228                 // We only do this here for apps not on a system dir, because those
   4229                 // are the only ones that can fail an install due to this.  We
   4230                 // will take care of the system apps by updating all of their
   4231                 // library paths after the scan is done.
   4232                 if (!updateSharedLibrariesLPw(pkg, null)) {
   4233                     return null;
   4234                 }
   4235             }
   4236 
   4237             if (pkg.mSharedUserId != null) {
   4238                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
   4239                 if (suid == null) {
   4240                     Slog.w(TAG, "Creating application package " + pkg.packageName
   4241                             + " for shared user failed");
   4242                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   4243                     return null;
   4244                 }
   4245                 if (DEBUG_PACKAGE_SCANNING) {
   4246                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   4247                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
   4248                                 + "): packages=" + suid.packages);
   4249                 }
   4250             }
   4251 
   4252             // Check if we are renaming from an original package name.
   4253             PackageSetting origPackage = null;
   4254             String realName = null;
   4255             if (pkg.mOriginalPackages != null) {
   4256                 // This package may need to be renamed to a previously
   4257                 // installed name.  Let's check on that...
   4258                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
   4259                 if (pkg.mOriginalPackages.contains(renamed)) {
   4260                     // This package had originally been installed as the
   4261                     // original name, and we have already taken care of
   4262                     // transitioning to the new one.  Just update the new
   4263                     // one to continue using the old name.
   4264                     realName = pkg.mRealPackage;
   4265                     if (!pkg.packageName.equals(renamed)) {
   4266                         // Callers into this function may have already taken
   4267                         // care of renaming the package; only do it here if
   4268                         // it is not already done.
   4269                         pkg.setPackageName(renamed);
   4270                     }
   4271 
   4272                 } else {
   4273                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
   4274                         if ((origPackage = mSettings.peekPackageLPr(
   4275                                 pkg.mOriginalPackages.get(i))) != null) {
   4276                             // We do have the package already installed under its
   4277                             // original name...  should we use it?
   4278                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
   4279                                 // New package is not compatible with original.
   4280                                 origPackage = null;
   4281                                 continue;
   4282                             } else if (origPackage.sharedUser != null) {
   4283                                 // Make sure uid is compatible between packages.
   4284                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
   4285                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
   4286                                             + " to " + pkg.packageName + ": old uid "
   4287                                             + origPackage.sharedUser.name
   4288                                             + " differs from " + pkg.mSharedUserId);
   4289                                     origPackage = null;
   4290                                     continue;
   4291                                 }
   4292                             } else {
   4293                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
   4294                                         + pkg.packageName + " to old name " + origPackage.name);
   4295                             }
   4296                             break;
   4297                         }
   4298                     }
   4299                 }
   4300             }
   4301 
   4302             if (mTransferedPackages.contains(pkg.packageName)) {
   4303                 Slog.w(TAG, "Package " + pkg.packageName
   4304                         + " was transferred to another, but its .apk remains");
   4305             }
   4306 
   4307             // Just create the setting, don't add it yet. For already existing packages
   4308             // the PkgSetting exists already and doesn't have to be created.
   4309             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
   4310                     destResourceFile, pkg.applicationInfo.nativeLibraryDir,
   4311                     pkg.applicationInfo.flags, user, false);
   4312             if (pkgSetting == null) {
   4313                 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
   4314                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   4315                 return null;
   4316             }
   4317 
   4318             if (pkgSetting.origPackage != null) {
   4319                 // If we are first transitioning from an original package,
   4320                 // fix up the new package's name now.  We need to do this after
   4321                 // looking up the package under its new name, so getPackageLP
   4322                 // can take care of fiddling things correctly.
   4323                 pkg.setPackageName(origPackage.name);
   4324 
   4325                 // File a report about this.
   4326                 String msg = "New package " + pkgSetting.realName
   4327                         + " renamed to replace old package " + pkgSetting.name;
   4328                 reportSettingsProblem(Log.WARN, msg);
   4329 
   4330                 // Make a note of it.
   4331                 mTransferedPackages.add(origPackage.name);
   4332 
   4333                 // No longer need to retain this.
   4334                 pkgSetting.origPackage = null;
   4335             }
   4336 
   4337             if (realName != null) {
   4338                 // Make a note of it.
   4339                 mTransferedPackages.add(pkg.packageName);
   4340             }
   4341 
   4342             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
   4343                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   4344             }
   4345 
   4346             if (mFoundPolicyFile) {
   4347                 SELinuxMMAC.assignSeinfoValue(pkg);
   4348             }
   4349 
   4350             pkg.applicationInfo.uid = pkgSetting.appId;
   4351             pkg.mExtras = pkgSetting;
   4352 
   4353             if (!verifySignaturesLP(pkgSetting, pkg)) {
   4354                 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   4355                     return null;
   4356                 }
   4357                 // The signature has changed, but this package is in the system
   4358                 // image...  let's recover!
   4359                 pkgSetting.signatures.mSignatures = pkg.mSignatures;
   4360                 // However...  if this package is part of a shared user, but it
   4361                 // doesn't match the signature of the shared user, let's fail.
   4362                 // What this means is that you can't change the signatures
   4363                 // associated with an overall shared user, which doesn't seem all
   4364                 // that unreasonable.
   4365                 if (pkgSetting.sharedUser != null) {
   4366                     if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   4367                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   4368                         Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
   4369                         mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
   4370                         return null;
   4371                     }
   4372                 }
   4373                 // File a report about this.
   4374                 String msg = "System package " + pkg.packageName
   4375                         + " signature changed; retaining data.";
   4376                 reportSettingsProblem(Log.WARN, msg);
   4377             }
   4378 
   4379             // Verify that this new package doesn't have any content providers
   4380             // that conflict with existing packages.  Only do this if the
   4381             // package isn't already installed, since we don't want to break
   4382             // things that are installed.
   4383             if ((scanMode&SCAN_NEW_INSTALL) != 0) {
   4384                 final int N = pkg.providers.size();
   4385                 int i;
   4386                 for (i=0; i<N; i++) {
   4387                     PackageParser.Provider p = pkg.providers.get(i);
   4388                     if (p.info.authority != null) {
   4389                         String names[] = p.info.authority.split(";");
   4390                         for (int j = 0; j < names.length; j++) {
   4391                             if (mProvidersByAuthority.containsKey(names[j])) {
   4392                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
   4393                                 Slog.w(TAG, "Can't install because provider name " + names[j] +
   4394                                         " (in package " + pkg.applicationInfo.packageName +
   4395                                         ") is already used by "
   4396                                         + ((other != null && other.getComponentName() != null)
   4397                                                 ? other.getComponentName().getPackageName() : "?"));
   4398                                 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
   4399                                 return null;
   4400                             }
   4401                         }
   4402                     }
   4403                 }
   4404             }
   4405 
   4406             if (pkg.mAdoptPermissions != null) {
   4407                 // This package wants to adopt ownership of permissions from
   4408                 // another package.
   4409                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
   4410                     final String origName = pkg.mAdoptPermissions.get(i);
   4411                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
   4412                     if (orig != null) {
   4413                         if (verifyPackageUpdateLPr(orig, pkg)) {
   4414                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
   4415                                     + pkg.packageName);
   4416                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
   4417                         }
   4418                     }
   4419                 }
   4420             }
   4421         }
   4422 
   4423         final String pkgName = pkg.packageName;
   4424 
   4425         final long scanFileTime = scanFile.lastModified();
   4426         final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
   4427         pkg.applicationInfo.processName = fixProcessName(
   4428                 pkg.applicationInfo.packageName,
   4429                 pkg.applicationInfo.processName,
   4430                 pkg.applicationInfo.uid);
   4431 
   4432         File dataPath;
   4433         if (mPlatformPackage == pkg) {
   4434             // The system package is special.
   4435             dataPath = new File (Environment.getDataDirectory(), "system");
   4436             pkg.applicationInfo.dataDir = dataPath.getPath();
   4437         } else {
   4438             // This is a normal package, need to make its data directory.
   4439             dataPath = getDataPathForPackage(pkg.packageName, 0);
   4440 
   4441             boolean uidError = false;
   4442 
   4443             if (dataPath.exists()) {
   4444                 int currentUid = 0;
   4445                 try {
   4446                     StructStat stat = Libcore.os.stat(dataPath.getPath());
   4447                     currentUid = stat.st_uid;
   4448                 } catch (ErrnoException e) {
   4449                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
   4450                 }
   4451 
   4452                 // If we have mismatched owners for the data path, we have a problem.
   4453                 if (currentUid != pkg.applicationInfo.uid) {
   4454                     boolean recovered = false;
   4455                     if (currentUid == 0) {
   4456                         // The directory somehow became owned by root.  Wow.
   4457                         // This is probably because the system was stopped while
   4458                         // installd was in the middle of messing with its libs
   4459                         // directory.  Ask installd to fix that.
   4460                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
   4461                                 pkg.applicationInfo.uid);
   4462                         if (ret >= 0) {
   4463                             recovered = true;
   4464                             String msg = "Package " + pkg.packageName
   4465                                     + " unexpectedly changed to uid 0; recovered to " +
   4466                                     + pkg.applicationInfo.uid;
   4467                             reportSettingsProblem(Log.WARN, msg);
   4468                         }
   4469                     }
   4470                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
   4471                             || (scanMode&SCAN_BOOTING) != 0)) {
   4472                         // If this is a system app, we can at least delete its
   4473                         // current data so the application will still work.
   4474                         int ret = removeDataDirsLI(pkgName);
   4475                         if (ret >= 0) {
   4476                             // TODO: Kill the processes first
   4477                             // Old data gone!
   4478                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
   4479                                     ? "System package " : "Third party package ";
   4480                             String msg = prefix + pkg.packageName
   4481                                     + " has changed from uid: "
   4482                                     + currentUid + " to "
   4483                                     + pkg.applicationInfo.uid + "; old data erased";
   4484                             reportSettingsProblem(Log.WARN, msg);
   4485                             recovered = true;
   4486 
   4487                             // And now re-install the app.
   4488                             ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
   4489                                                    pkg.applicationInfo.seinfo);
   4490                             if (ret == -1) {
   4491                                 // Ack should not happen!
   4492                                 msg = prefix + pkg.packageName
   4493                                         + " could not have data directory re-created after delete.";
   4494                                 reportSettingsProblem(Log.WARN, msg);
   4495                                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   4496                                 return null;
   4497                             }
   4498                         }
   4499                         if (!recovered) {
   4500                             mHasSystemUidErrors = true;
   4501                         }
   4502                     } else if (!recovered) {
   4503                         // If we allow this install to proceed, we will be broken.
   4504                         // Abort, abort!
   4505                         mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
   4506                         return null;
   4507                     }
   4508                     if (!recovered) {
   4509                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
   4510                             + pkg.applicationInfo.uid + "/fs_"
   4511                             + currentUid;
   4512                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
   4513                         String msg = "Package " + pkg.packageName
   4514                                 + " has mismatched uid: "
   4515                                 + currentUid + " on disk, "
   4516                                 + pkg.applicationInfo.uid + " in settings";
   4517                         // writer
   4518                         synchronized (mPackages) {
   4519                             mSettings.mReadMessages.append(msg);
   4520                             mSettings.mReadMessages.append('\n');
   4521                             uidError = true;
   4522                             if (!pkgSetting.uidError) {
   4523                                 reportSettingsProblem(Log.ERROR, msg);
   4524                             }
   4525                         }
   4526                     }
   4527                 }
   4528                 pkg.applicationInfo.dataDir = dataPath.getPath();
   4529             } else {
   4530                 if (DEBUG_PACKAGE_SCANNING) {
   4531                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   4532                         Log.v(TAG, "Want this data dir: " + dataPath);
   4533                 }
   4534                 //invoke installer to do the actual installation
   4535                 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
   4536                                            pkg.applicationInfo.seinfo);
   4537                 if (ret < 0) {
   4538                     // Error from installer
   4539                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   4540                     return null;
   4541                 }
   4542 
   4543                 if (dataPath.exists()) {
   4544                     pkg.applicationInfo.dataDir = dataPath.getPath();
   4545                 } else {
   4546                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
   4547                     pkg.applicationInfo.dataDir = null;
   4548                 }
   4549             }
   4550 
   4551             /*
   4552              * Set the data dir to the default "/data/data/<package name>/lib"
   4553              * if we got here without anyone telling us different (e.g., apps
   4554              * stored on SD card have their native libraries stored in the ASEC
   4555              * container with the APK).
   4556              *
   4557              * This happens during an upgrade from a package settings file that
   4558              * doesn't have a native library path attribute at all.
   4559              */
   4560             if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
   4561                 if (pkgSetting.nativeLibraryPathString == null) {
   4562                     setInternalAppNativeLibraryPath(pkg, pkgSetting);
   4563                 } else {
   4564                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
   4565                 }
   4566             }
   4567 
   4568             pkgSetting.uidError = uidError;
   4569         }
   4570 
   4571         String path = scanFile.getPath();
   4572         /* Note: We don't want to unpack the native binaries for
   4573          *        system applications, unless they have been updated
   4574          *        (the binaries are already under /system/lib).
   4575          *        Also, don't unpack libs for apps on the external card
   4576          *        since they should have their libraries in the ASEC
   4577          *        container already.
   4578          *
   4579          *        In other words, we're going to unpack the binaries
   4580          *        only for non-system apps and system app upgrades.
   4581          */
   4582         if (pkg.applicationInfo.nativeLibraryDir != null) {
   4583             try {
   4584                 File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
   4585                 final String dataPathString = dataPath.getCanonicalPath();
   4586 
   4587                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
   4588                     /*
   4589                      * Upgrading from a previous version of the OS sometimes
   4590                      * leaves native libraries in the /data/data/<app>/lib
   4591                      * directory for system apps even when they shouldn't be.
   4592                      * Recent changes in the JNI library search path
   4593                      * necessitates we remove those to match previous behavior.
   4594                      */
   4595                     if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
   4596                         Log.i(TAG, "removed obsolete native libraries for system package "
   4597                                 + path);
   4598                     }
   4599                 } else {
   4600                     if (!isForwardLocked(pkg) && !isExternal(pkg)) {
   4601                         /*
   4602                          * Update native library dir if it starts with
   4603                          * /data/data
   4604                          */
   4605                         if (nativeLibraryDir.getPath().startsWith(dataPathString)) {
   4606                             setInternalAppNativeLibraryPath(pkg, pkgSetting);
   4607                             nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
   4608                         }
   4609 
   4610                         try {
   4611                             if (copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir) != PackageManager.INSTALL_SUCCEEDED) {
   4612                                 Slog.e(TAG, "Unable to copy native libraries");
   4613                                 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   4614                                 return null;
   4615                             }
   4616                         } catch (IOException e) {
   4617                             Slog.e(TAG, "Unable to copy native libraries", e);
   4618                             mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   4619                             return null;
   4620                         }
   4621                     }
   4622 
   4623                     if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
   4624                     final int[] userIds = sUserManager.getUserIds();
   4625                     synchronized (mInstallLock) {
   4626                         for (int userId : userIds) {
   4627                             if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
   4628                                     pkg.applicationInfo.nativeLibraryDir, userId) < 0) {
   4629                                 Slog.w(TAG, "Failed linking native library dir (user=" + userId
   4630                                         + ")");
   4631                                 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   4632                                 return null;
   4633                             }
   4634                         }
   4635                     }
   4636                 }
   4637             } catch (IOException ioe) {
   4638                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
   4639             }
   4640         }
   4641         pkg.mScanPath = path;
   4642 
   4643         if ((scanMode&SCAN_NO_DEX) == 0) {
   4644             if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
   4645                     == DEX_OPT_FAILED) {
   4646                 if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
   4647                     removeDataDirsLI(pkg.packageName);
   4648                 }
   4649 
   4650                 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
   4651                 return null;
   4652             }
   4653         }
   4654 
   4655         if (mFactoryTest && pkg.requestedPermissions.contains(
   4656                 android.Manifest.permission.FACTORY_TEST)) {
   4657             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
   4658         }
   4659 
   4660         ArrayList<PackageParser.Package> clientLibPkgs = null;
   4661 
   4662         // writer
   4663         synchronized (mPackages) {
   4664             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   4665                 // Only system apps can add new shared libraries.
   4666                 if (pkg.libraryNames != null) {
   4667                     for (int i=0; i<pkg.libraryNames.size(); i++) {
   4668                         String name = pkg.libraryNames.get(i);
   4669                         boolean allowed = false;
   4670                         if (isUpdatedSystemApp(pkg)) {
   4671                             // New library entries can only be added through the
   4672                             // system image.  This is important to get rid of a lot
   4673                             // of nasty edge cases: for example if we allowed a non-
   4674                             // system update of the app to add a library, then uninstalling
   4675                             // the update would make the library go away, and assumptions
   4676                             // we made such as through app install filtering would now
   4677                             // have allowed apps on the device which aren't compatible
   4678                             // with it.  Better to just have the restriction here, be
   4679                             // conservative, and create many fewer cases that can negatively
   4680                             // impact the user experience.
   4681                             final PackageSetting sysPs = mSettings
   4682                                     .getDisabledSystemPkgLPr(pkg.packageName);
   4683                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
   4684                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
   4685                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
   4686                                         allowed = true;
   4687                                         allowed = true;
   4688                                         break;
   4689                                     }
   4690                                 }
   4691                             }
   4692                         } else {
   4693                             allowed = true;
   4694                         }
   4695                         if (allowed) {
   4696                             if (!mSharedLibraries.containsKey(name)) {
   4697                                 mSharedLibraries.put(name, new SharedLibraryEntry(null,
   4698                                         pkg.packageName));
   4699                             } else if (!name.equals(pkg.packageName)) {
   4700                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
   4701                                         + name + " already exists; skipping");
   4702                             }
   4703                         } else {
   4704                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
   4705                                     + name + " that is not declared on system image; skipping");
   4706                         }
   4707                     }
   4708                     if ((scanMode&SCAN_BOOTING) == 0) {
   4709                         // If we are not booting, we need to update any applications
   4710                         // that are clients of our shared library.  If we are booting,
   4711                         // this will all be done once the scan is complete.
   4712                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
   4713                     }
   4714                 }
   4715             }
   4716         }
   4717 
   4718         // We also need to dexopt any apps that are dependent on this library.  Note that
   4719         // if these fail, we should abort the install since installing the library will
   4720         // result in some apps being broken.
   4721         if (clientLibPkgs != null) {
   4722             if ((scanMode&SCAN_NO_DEX) == 0) {
   4723                 for (int i=0; i<clientLibPkgs.size(); i++) {
   4724                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
   4725                     if (performDexOptLI(clientPkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
   4726                             == DEX_OPT_FAILED) {
   4727                         if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
   4728                             removeDataDirsLI(pkg.packageName);
   4729                         }
   4730 
   4731                         mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
   4732                         return null;
   4733                     }
   4734                 }
   4735             }
   4736         }
   4737 
   4738         // Request the ActivityManager to kill the process(only for existing packages)
   4739         // so that we do not end up in a confused state while the user is still using the older
   4740         // version of the application while the new one gets installed.
   4741         if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   4742             // If the package lives in an asec, tell everyone that the container is going
   4743             // away so they can clean up any references to its resources (which would prevent
   4744             // vold from being able to unmount the asec)
   4745             if (isForwardLocked(pkg) || isExternal(pkg)) {
   4746                 if (DEBUG_INSTALL) {
   4747                     Slog.i(TAG, "upgrading pkg " + pkg + " is ASEC-hosted -> UNAVAILABLE");
   4748                 }
   4749                 final int[] uidArray = new int[] { pkg.applicationInfo.uid };
   4750                 final ArrayList<String> pkgList = new ArrayList<String>(1);
   4751                 pkgList.add(pkg.applicationInfo.packageName);
   4752                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
   4753             }
   4754 
   4755             // Post the request that it be killed now that the going-away broadcast is en route
   4756             killApplication(pkg.applicationInfo.packageName,
   4757                         pkg.applicationInfo.uid, "update pkg");
   4758         }
   4759 
   4760         // Also need to kill any apps that are dependent on the library.
   4761         if (clientLibPkgs != null) {
   4762             for (int i=0; i<clientLibPkgs.size(); i++) {
   4763                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
   4764                 killApplication(clientPkg.applicationInfo.packageName,
   4765                         clientPkg.applicationInfo.uid, "update lib");
   4766             }
   4767         }
   4768 
   4769         // writer
   4770         synchronized (mPackages) {
   4771             // We don't expect installation to fail beyond this point,
   4772             if ((scanMode&SCAN_MONITOR) != 0) {
   4773                 mAppDirs.put(pkg.mPath, pkg);
   4774             }
   4775             // Add the new setting to mSettings
   4776             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
   4777             // Add the new setting to mPackages
   4778             mPackages.put(pkg.applicationInfo.packageName, pkg);
   4779             // Make sure we don't accidentally delete its data.
   4780             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
   4781             while (iter.hasNext()) {
   4782                 PackageCleanItem item = iter.next();
   4783                 if (pkgName.equals(item.packageName)) {
   4784                     iter.remove();
   4785                 }
   4786             }
   4787 
   4788             // Take care of first install / last update times.
   4789             if (currentTime != 0) {
   4790                 if (pkgSetting.firstInstallTime == 0) {
   4791                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
   4792                 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
   4793                     pkgSetting.lastUpdateTime = currentTime;
   4794                 }
   4795             } else if (pkgSetting.firstInstallTime == 0) {
   4796                 // We need *something*.  Take time time stamp of the file.
   4797                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
   4798             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
   4799                 if (scanFileTime != pkgSetting.timeStamp) {
   4800                     // A package on the system image has changed; consider this
   4801                     // to be an update.
   4802                     pkgSetting.lastUpdateTime = scanFileTime;
   4803                 }
   4804             }
   4805 
   4806             // Add the package's KeySets to the global KeySetManager
   4807             KeySetManager ksm = mSettings.mKeySetManager;
   4808             try {
   4809                 ksm.addSigningKeySetToPackage(pkg.packageName, pkg.mSigningKeys);
   4810                 if (pkg.mKeySetMapping != null) {
   4811                     for (Map.Entry<String, Set<PublicKey>> entry : pkg.mKeySetMapping.entrySet()) {
   4812                         if (entry.getValue() != null) {
   4813                             ksm.addDefinedKeySetToPackage(pkg.packageName,
   4814                                 entry.getValue(), entry.getKey());
   4815                         }
   4816                     }
   4817                 }
   4818             } catch (NullPointerException e) {
   4819                 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
   4820             } catch (IllegalArgumentException e) {
   4821                 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
   4822             }
   4823 
   4824             int N = pkg.providers.size();
   4825             StringBuilder r = null;
   4826             int i;
   4827             for (i=0; i<N; i++) {
   4828                 PackageParser.Provider p = pkg.providers.get(i);
   4829                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
   4830                         p.info.processName, pkg.applicationInfo.uid);
   4831                 mProviders.addProvider(p);
   4832                 p.syncable = p.info.isSyncable;
   4833                 if (p.info.authority != null) {
   4834                     String names[] = p.info.authority.split(";");
   4835                     p.info.authority = null;
   4836                     for (int j = 0; j < names.length; j++) {
   4837                         if (j == 1 && p.syncable) {
   4838                             // We only want the first authority for a provider to possibly be
   4839                             // syncable, so if we already added this provider using a different
   4840                             // authority clear the syncable flag. We copy the provider before
   4841                             // changing it because the mProviders object contains a reference
   4842                             // to a provider that we don't want to change.
   4843                             // Only do this for the second authority since the resulting provider
   4844                             // object can be the same for all future authorities for this provider.
   4845                             p = new PackageParser.Provider(p);
   4846                             p.syncable = false;
   4847                         }
   4848                         if (!mProvidersByAuthority.containsKey(names[j])) {
   4849                             mProvidersByAuthority.put(names[j], p);
   4850                             if (p.info.authority == null) {
   4851                                 p.info.authority = names[j];
   4852                             } else {
   4853                                 p.info.authority = p.info.authority + ";" + names[j];
   4854                             }
   4855                             if (DEBUG_PACKAGE_SCANNING) {
   4856                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   4857                                     Log.d(TAG, "Registered content provider: " + names[j]
   4858                                             + ", className = " + p.info.name + ", isSyncable = "
   4859                                             + p.info.isSyncable);
   4860                             }
   4861                         } else {
   4862                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
   4863                             Slog.w(TAG, "Skipping provider name " + names[j] +
   4864                                     " (in package " + pkg.applicationInfo.packageName +
   4865                                     "): name already used by "
   4866                                     + ((other != null && other.getComponentName() != null)
   4867                                             ? other.getComponentName().getPackageName() : "?"));
   4868                         }
   4869                     }
   4870                 }
   4871                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4872                     if (r == null) {
   4873                         r = new StringBuilder(256);
   4874                     } else {
   4875                         r.append(' ');
   4876                     }
   4877                     r.append(p.info.name);
   4878                 }
   4879             }
   4880             if (r != null) {
   4881                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
   4882             }
   4883 
   4884             N = pkg.services.size();
   4885             r = null;
   4886             for (i=0; i<N; i++) {
   4887                 PackageParser.Service s = pkg.services.get(i);
   4888                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
   4889                         s.info.processName, pkg.applicationInfo.uid);
   4890                 mServices.addService(s);
   4891                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4892                     if (r == null) {
   4893                         r = new StringBuilder(256);
   4894                     } else {
   4895                         r.append(' ');
   4896                     }
   4897                     r.append(s.info.name);
   4898                 }
   4899             }
   4900             if (r != null) {
   4901                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
   4902             }
   4903 
   4904             N = pkg.receivers.size();
   4905             r = null;
   4906             for (i=0; i<N; i++) {
   4907                 PackageParser.Activity a = pkg.receivers.get(i);
   4908                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   4909                         a.info.processName, pkg.applicationInfo.uid);
   4910                 mReceivers.addActivity(a, "receiver");
   4911                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4912                     if (r == null) {
   4913                         r = new StringBuilder(256);
   4914                     } else {
   4915                         r.append(' ');
   4916                     }
   4917                     r.append(a.info.name);
   4918                 }
   4919             }
   4920             if (r != null) {
   4921                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
   4922             }
   4923 
   4924             N = pkg.activities.size();
   4925             r = null;
   4926             for (i=0; i<N; i++) {
   4927                 PackageParser.Activity a = pkg.activities.get(i);
   4928                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   4929                         a.info.processName, pkg.applicationInfo.uid);
   4930                 mActivities.addActivity(a, "activity");
   4931                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4932                     if (r == null) {
   4933                         r = new StringBuilder(256);
   4934                     } else {
   4935                         r.append(' ');
   4936                     }
   4937                     r.append(a.info.name);
   4938                 }
   4939             }
   4940             if (r != null) {
   4941                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
   4942             }
   4943 
   4944             N = pkg.permissionGroups.size();
   4945             r = null;
   4946             for (i=0; i<N; i++) {
   4947                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
   4948                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
   4949                 if (cur == null) {
   4950                     mPermissionGroups.put(pg.info.name, pg);
   4951                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4952                         if (r == null) {
   4953                             r = new StringBuilder(256);
   4954                         } else {
   4955                             r.append(' ');
   4956                         }
   4957                         r.append(pg.info.name);
   4958                     }
   4959                 } else {
   4960                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
   4961                             + pg.info.packageName + " ignored: original from "
   4962                             + cur.info.packageName);
   4963                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4964                         if (r == null) {
   4965                             r = new StringBuilder(256);
   4966                         } else {
   4967                             r.append(' ');
   4968                         }
   4969                         r.append("DUP:");
   4970                         r.append(pg.info.name);
   4971                     }
   4972                 }
   4973             }
   4974             if (r != null) {
   4975                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
   4976             }
   4977 
   4978             N = pkg.permissions.size();
   4979             r = null;
   4980             for (i=0; i<N; i++) {
   4981                 PackageParser.Permission p = pkg.permissions.get(i);
   4982                 HashMap<String, BasePermission> permissionMap =
   4983                         p.tree ? mSettings.mPermissionTrees
   4984                         : mSettings.mPermissions;
   4985                 p.group = mPermissionGroups.get(p.info.group);
   4986                 if (p.info.group == null || p.group != null) {
   4987                     BasePermission bp = permissionMap.get(p.info.name);
   4988                     if (bp == null) {
   4989                         bp = new BasePermission(p.info.name, p.info.packageName,
   4990                                 BasePermission.TYPE_NORMAL);
   4991                         permissionMap.put(p.info.name, bp);
   4992                     }
   4993                     if (bp.perm == null) {
   4994                         if (bp.sourcePackage != null
   4995                                 && !bp.sourcePackage.equals(p.info.packageName)) {
   4996                             // If this is a permission that was formerly defined by a non-system
   4997                             // app, but is now defined by a system app (following an upgrade),
   4998                             // discard the previous declaration and consider the system's to be
   4999                             // canonical.
   5000                             if (isSystemApp(p.owner)) {
   5001                                 Slog.i(TAG, "New decl " + p.owner + " of permission  "
   5002                                         + p.info.name + " is system");
   5003                                 bp.sourcePackage = null;
   5004                             }
   5005                         }
   5006                         if (bp.sourcePackage == null
   5007                                 || bp.sourcePackage.equals(p.info.packageName)) {
   5008                             BasePermission tree = findPermissionTreeLP(p.info.name);
   5009                             if (tree == null
   5010                                     || tree.sourcePackage.equals(p.info.packageName)) {
   5011                                 bp.packageSetting = pkgSetting;
   5012                                 bp.perm = p;
   5013                                 bp.uid = pkg.applicationInfo.uid;
   5014                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   5015                                     if (r == null) {
   5016                                         r = new StringBuilder(256);
   5017                                     } else {
   5018                                         r.append(' ');
   5019                                     }
   5020                                     r.append(p.info.name);
   5021                                 }
   5022                             } else {
   5023                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
   5024                                         + p.info.packageName + " ignored: base tree "
   5025                                         + tree.name + " is from package "
   5026                                         + tree.sourcePackage);
   5027                             }
   5028                         } else {
   5029                             Slog.w(TAG, "Permission " + p.info.name + " from package "
   5030                                     + p.info.packageName + " ignored: original from "
   5031                                     + bp.sourcePackage);
   5032                         }
   5033                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   5034                         if (r == null) {
   5035                             r = new StringBuilder(256);
   5036                         } else {
   5037                             r.append(' ');
   5038                         }
   5039                         r.append("DUP:");
   5040                         r.append(p.info.name);
   5041                     }
   5042                     if (bp.perm == p) {
   5043                         bp.protectionLevel = p.info.protectionLevel;
   5044                     }
   5045                 } else {
   5046                     Slog.w(TAG, "Permission " + p.info.name + " from package "
   5047                             + p.info.packageName + " ignored: no group "
   5048                             + p.group);
   5049                 }
   5050             }
   5051             if (r != null) {
   5052                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
   5053             }
   5054 
   5055             N = pkg.instrumentation.size();
   5056             r = null;
   5057             for (i=0; i<N; i++) {
   5058                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   5059                 a.info.packageName = pkg.applicationInfo.packageName;
   5060                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
   5061                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
   5062                 a.info.dataDir = pkg.applicationInfo.dataDir;
   5063                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
   5064                 mInstrumentation.put(a.getComponentName(), a);
   5065                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   5066                     if (r == null) {
   5067                         r = new StringBuilder(256);
   5068                     } else {
   5069                         r.append(' ');
   5070                     }
   5071                     r.append(a.info.name);
   5072                 }
   5073             }
   5074             if (r != null) {
   5075                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
   5076             }
   5077 
   5078             if (pkg.protectedBroadcasts != null) {
   5079                 N = pkg.protectedBroadcasts.size();
   5080                 for (i=0; i<N; i++) {
   5081                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
   5082                 }
   5083             }
   5084 
   5085             pkgSetting.setTimeStamp(scanFileTime);
   5086         }
   5087 
   5088         return pkg;
   5089     }
   5090 
   5091     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
   5092         synchronized (mPackages) {
   5093             mResolverReplaced = true;
   5094             // Set up information for custom user intent resolution activity.
   5095             mResolveActivity.applicationInfo = pkg.applicationInfo;
   5096             mResolveActivity.name = mCustomResolverComponentName.getClassName();
   5097             mResolveActivity.packageName = pkg.applicationInfo.packageName;
   5098             mResolveActivity.processName = null;
   5099             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   5100             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
   5101                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
   5102             mResolveActivity.theme = 0;
   5103             mResolveActivity.exported = true;
   5104             mResolveActivity.enabled = true;
   5105             mResolveInfo.activityInfo = mResolveActivity;
   5106             mResolveInfo.priority = 0;
   5107             mResolveInfo.preferredOrder = 0;
   5108             mResolveInfo.match = 0;
   5109             mResolveComponentName = mCustomResolverComponentName;
   5110             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
   5111                     mResolveComponentName);
   5112         }
   5113     }
   5114 
   5115     private void setInternalAppNativeLibraryPath(PackageParser.Package pkg,
   5116             PackageSetting pkgSetting) {
   5117         final String apkLibPath = getApkName(pkgSetting.codePathString);
   5118         final String nativeLibraryPath = new File(mAppLibInstallDir, apkLibPath).getPath();
   5119         pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
   5120         pkgSetting.nativeLibraryPathString = nativeLibraryPath;
   5121     }
   5122 
   5123     private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir)
   5124             throws IOException {
   5125         if (!nativeLibraryDir.isDirectory()) {
   5126             nativeLibraryDir.delete();
   5127 
   5128             if (!nativeLibraryDir.mkdir()) {
   5129                 throw new IOException("Cannot create " + nativeLibraryDir.getPath());
   5130             }
   5131 
   5132             try {
   5133                 Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH
   5134                         | S_IXOTH);
   5135             } catch (ErrnoException e) {
   5136                 throw new IOException("Cannot chmod native library directory "
   5137                         + nativeLibraryDir.getPath(), e);
   5138             }
   5139         } else if (!SELinux.restorecon(nativeLibraryDir)) {
   5140             throw new IOException("Cannot set SELinux context for " + nativeLibraryDir.getPath());
   5141         }
   5142 
   5143         /*
   5144          * If this is an internal application or our nativeLibraryPath points to
   5145          * the app-lib directory, unpack the libraries if necessary.
   5146          */
   5147         return NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
   5148     }
   5149 
   5150     private void killApplication(String pkgName, int appId, String reason) {
   5151         // Request the ActivityManager to kill the process(only for existing packages)
   5152         // so that we do not end up in a confused state while the user is still using the older
   5153         // version of the application while the new one gets installed.
   5154         IActivityManager am = ActivityManagerNative.getDefault();
   5155         if (am != null) {
   5156             try {
   5157                 am.killApplicationWithAppId(pkgName, appId, reason);
   5158             } catch (RemoteException e) {
   5159             }
   5160         }
   5161     }
   5162 
   5163     void removePackageLI(PackageSetting ps, boolean chatty) {
   5164         if (DEBUG_INSTALL) {
   5165             if (chatty)
   5166                 Log.d(TAG, "Removing package " + ps.name);
   5167         }
   5168 
   5169         // writer
   5170         synchronized (mPackages) {
   5171             mPackages.remove(ps.name);
   5172             if (ps.codePathString != null) {
   5173                 mAppDirs.remove(ps.codePathString);
   5174             }
   5175 
   5176             final PackageParser.Package pkg = ps.pkg;
   5177             if (pkg != null) {
   5178                 cleanPackageDataStructuresLILPw(pkg, chatty);
   5179             }
   5180         }
   5181     }
   5182 
   5183     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
   5184         if (DEBUG_INSTALL) {
   5185             if (chatty)
   5186                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
   5187         }
   5188 
   5189         // writer
   5190         synchronized (mPackages) {
   5191             mPackages.remove(pkg.applicationInfo.packageName);
   5192             if (pkg.mPath != null) {
   5193                 mAppDirs.remove(pkg.mPath);
   5194             }
   5195             cleanPackageDataStructuresLILPw(pkg, chatty);
   5196         }
   5197     }
   5198 
   5199     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
   5200         int N = pkg.providers.size();
   5201         StringBuilder r = null;
   5202         int i;
   5203         for (i=0; i<N; i++) {
   5204             PackageParser.Provider p = pkg.providers.get(i);
   5205             mProviders.removeProvider(p);
   5206             if (p.info.authority == null) {
   5207 
   5208                 /* There was another ContentProvider with this authority when
   5209                  * this app was installed so this authority is null,
   5210                  * Ignore it as we don't have to unregister the provider.
   5211                  */
   5212                 continue;
   5213             }
   5214             String names[] = p.info.authority.split(";");
   5215             for (int j = 0; j < names.length; j++) {
   5216                 if (mProvidersByAuthority.get(names[j]) == p) {
   5217                     mProvidersByAuthority.remove(names[j]);
   5218                     if (DEBUG_REMOVE) {
   5219                         if (chatty)
   5220                             Log.d(TAG, "Unregistered content provider: " + names[j]
   5221                                     + ", className = " + p.info.name + ", isSyncable = "
   5222                                     + p.info.isSyncable);
   5223                     }
   5224                 }
   5225             }
   5226             if (DEBUG_REMOVE && chatty) {
   5227                 if (r == null) {
   5228                     r = new StringBuilder(256);
   5229                 } else {
   5230                     r.append(' ');
   5231                 }
   5232                 r.append(p.info.name);
   5233             }
   5234         }
   5235         if (r != null) {
   5236             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
   5237         }
   5238 
   5239         N = pkg.services.size();
   5240         r = null;
   5241         for (i=0; i<N; i++) {
   5242             PackageParser.Service s = pkg.services.get(i);
   5243             mServices.removeService(s);
   5244             if (chatty) {
   5245                 if (r == null) {
   5246                     r = new StringBuilder(256);
   5247                 } else {
   5248                     r.append(' ');
   5249                 }
   5250                 r.append(s.info.name);
   5251             }
   5252         }
   5253         if (r != null) {
   5254             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
   5255         }
   5256 
   5257         N = pkg.receivers.size();
   5258         r = null;
   5259         for (i=0; i<N; i++) {
   5260             PackageParser.Activity a = pkg.receivers.get(i);
   5261             mReceivers.removeActivity(a, "receiver");
   5262             if (DEBUG_REMOVE && chatty) {
   5263                 if (r == null) {
   5264                     r = new StringBuilder(256);
   5265                 } else {
   5266                     r.append(' ');
   5267                 }
   5268                 r.append(a.info.name);
   5269             }
   5270         }
   5271         if (r != null) {
   5272             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
   5273         }
   5274 
   5275         N = pkg.activities.size();
   5276         r = null;
   5277         for (i=0; i<N; i++) {
   5278             PackageParser.Activity a = pkg.activities.get(i);
   5279             mActivities.removeActivity(a, "activity");
   5280             if (DEBUG_REMOVE && chatty) {
   5281                 if (r == null) {
   5282                     r = new StringBuilder(256);
   5283                 } else {
   5284                     r.append(' ');
   5285                 }
   5286                 r.append(a.info.name);
   5287             }
   5288         }
   5289         if (r != null) {
   5290             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
   5291         }
   5292 
   5293         N = pkg.permissions.size();
   5294         r = null;
   5295         for (i=0; i<N; i++) {
   5296             PackageParser.Permission p = pkg.permissions.get(i);
   5297             BasePermission bp = mSettings.mPermissions.get(p.info.name);
   5298             if (bp == null) {
   5299                 bp = mSettings.mPermissionTrees.get(p.info.name);
   5300             }
   5301             if (bp != null && bp.perm == p) {
   5302                 bp.perm = null;
   5303                 if (DEBUG_REMOVE && chatty) {
   5304                     if (r == null) {
   5305                         r = new StringBuilder(256);
   5306                     } else {
   5307                         r.append(' ');
   5308                     }
   5309                     r.append(p.info.name);
   5310                 }
   5311             }
   5312         }
   5313         if (r != null) {
   5314             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   5315         }
   5316 
   5317         N = pkg.instrumentation.size();
   5318         r = null;
   5319         for (i=0; i<N; i++) {
   5320             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   5321             mInstrumentation.remove(a.getComponentName());
   5322             if (DEBUG_REMOVE && chatty) {
   5323                 if (r == null) {
   5324                     r = new StringBuilder(256);
   5325                 } else {
   5326                     r.append(' ');
   5327                 }
   5328                 r.append(a.info.name);
   5329             }
   5330         }
   5331         if (r != null) {
   5332             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
   5333         }
   5334 
   5335         r = null;
   5336         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   5337             // Only system apps can hold shared libraries.
   5338             if (pkg.libraryNames != null) {
   5339                 for (i=0; i<pkg.libraryNames.size(); i++) {
   5340                     String name = pkg.libraryNames.get(i);
   5341                     SharedLibraryEntry cur = mSharedLibraries.get(name);
   5342                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
   5343                         mSharedLibraries.remove(name);
   5344                         if (DEBUG_REMOVE && chatty) {
   5345                             if (r == null) {
   5346                                 r = new StringBuilder(256);
   5347                             } else {
   5348                                 r.append(' ');
   5349                             }
   5350                             r.append(name);
   5351                         }
   5352                     }
   5353                 }
   5354             }
   5355         }
   5356         if (r != null) {
   5357             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
   5358         }
   5359     }
   5360 
   5361     private static final boolean isPackageFilename(String name) {
   5362         return name != null && name.endsWith(".apk");
   5363     }
   5364 
   5365     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
   5366         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
   5367             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
   5368                 return true;
   5369             }
   5370         }
   5371         return false;
   5372     }
   5373 
   5374     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
   5375     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
   5376     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
   5377 
   5378     private void updatePermissionsLPw(String changingPkg,
   5379             PackageParser.Package pkgInfo, int flags) {
   5380         // Make sure there are no dangling permission trees.
   5381         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
   5382         while (it.hasNext()) {
   5383             final BasePermission bp = it.next();
   5384             if (bp.packageSetting == null) {
   5385                 // We may not yet have parsed the package, so just see if
   5386                 // we still know about its settings.
   5387                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   5388             }
   5389             if (bp.packageSetting == null) {
   5390                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
   5391                         + " from package " + bp.sourcePackage);
   5392                 it.remove();
   5393             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   5394                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   5395                     Slog.i(TAG, "Removing old permission tree: " + bp.name
   5396                             + " from package " + bp.sourcePackage);
   5397                     flags |= UPDATE_PERMISSIONS_ALL;
   5398                     it.remove();
   5399                 }
   5400             }
   5401         }
   5402 
   5403         // Make sure all dynamic permissions have been assigned to a package,
   5404         // and make sure there are no dangling permissions.
   5405         it = mSettings.mPermissions.values().iterator();
   5406         while (it.hasNext()) {
   5407             final BasePermission bp = it.next();
   5408             if (bp.type == BasePermission.TYPE_DYNAMIC) {
   5409                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
   5410                         + bp.name + " pkg=" + bp.sourcePackage
   5411                         + " info=" + bp.pendingInfo);
   5412                 if (bp.packageSetting == null && bp.pendingInfo != null) {
   5413                     final BasePermission tree = findPermissionTreeLP(bp.name);
   5414                     if (tree != null && tree.perm != null) {
   5415                         bp.packageSetting = tree.packageSetting;
   5416                         bp.perm = new PackageParser.Permission(tree.perm.owner,
   5417                                 new PermissionInfo(bp.pendingInfo));
   5418                         bp.perm.info.packageName = tree.perm.info.packageName;
   5419                         bp.perm.info.name = bp.name;
   5420                         bp.uid = tree.uid;
   5421                     }
   5422                 }
   5423             }
   5424             if (bp.packageSetting == null) {
   5425                 // We may not yet have parsed the package, so just see if
   5426                 // we still know about its settings.
   5427                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   5428             }
   5429             if (bp.packageSetting == null) {
   5430                 Slog.w(TAG, "Removing dangling permission: " + bp.name
   5431                         + " from package " + bp.sourcePackage);
   5432                 it.remove();
   5433             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   5434                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   5435                     Slog.i(TAG, "Removing old permission: " + bp.name
   5436                             + " from package " + bp.sourcePackage);
   5437                     flags |= UPDATE_PERMISSIONS_ALL;
   5438                     it.remove();
   5439                 }
   5440             }
   5441         }
   5442 
   5443         // Now update the permissions for all packages, in particular
   5444         // replace the granted permissions of the system packages.
   5445         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
   5446             for (PackageParser.Package pkg : mPackages.values()) {
   5447                 if (pkg != pkgInfo) {
   5448                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
   5449                 }
   5450             }
   5451         }
   5452 
   5453         if (pkgInfo != null) {
   5454             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
   5455         }
   5456     }
   5457 
   5458     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
   5459         final PackageSetting ps = (PackageSetting) pkg.mExtras;
   5460         if (ps == null) {
   5461             return;
   5462         }
   5463         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   5464         HashSet<String> origPermissions = gp.grantedPermissions;
   5465         boolean changedPermission = false;
   5466 
   5467         if (replace) {
   5468             ps.permissionsFixed = false;
   5469             if (gp == ps) {
   5470                 origPermissions = new HashSet<String>(gp.grantedPermissions);
   5471                 gp.grantedPermissions.clear();
   5472                 gp.gids = mGlobalGids;
   5473             }
   5474         }
   5475 
   5476         if (gp.gids == null) {
   5477             gp.gids = mGlobalGids;
   5478         }
   5479 
   5480         final int N = pkg.requestedPermissions.size();
   5481         for (int i=0; i<N; i++) {
   5482             final String name = pkg.requestedPermissions.get(i);
   5483             final boolean required = pkg.requestedPermissionsRequired.get(i);
   5484             final BasePermission bp = mSettings.mPermissions.get(name);
   5485             if (DEBUG_INSTALL) {
   5486                 if (gp != ps) {
   5487                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
   5488                 }
   5489             }
   5490 
   5491             if (bp == null || bp.packageSetting == null) {
   5492                 Slog.w(TAG, "Unknown permission " + name
   5493                         + " in package " + pkg.packageName);
   5494                 continue;
   5495             }
   5496 
   5497             final String perm = bp.name;
   5498             boolean allowed;
   5499             boolean allowedSig = false;
   5500             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
   5501             if (level == PermissionInfo.PROTECTION_NORMAL
   5502                     || level == PermissionInfo.PROTECTION_DANGEROUS) {
   5503                 // We grant a normal or dangerous permission if any of the following
   5504                 // are true:
   5505                 // 1) The permission is required
   5506                 // 2) The permission is optional, but was granted in the past
   5507                 // 3) The permission is optional, but was requested by an
   5508                 //    app in /system (not /data)
   5509                 //
   5510                 // Otherwise, reject the permission.
   5511                 allowed = (required || origPermissions.contains(perm)
   5512                         || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
   5513             } else if (bp.packageSetting == null) {
   5514                 // This permission is invalid; skip it.
   5515                 allowed = false;
   5516             } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
   5517                 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
   5518                 if (allowed) {
   5519                     allowedSig = true;
   5520                 }
   5521             } else {
   5522                 allowed = false;
   5523             }
   5524             if (DEBUG_INSTALL) {
   5525                 if (gp != ps) {
   5526                     Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
   5527                 }
   5528             }
   5529             if (allowed) {
   5530                 if (!isSystemApp(ps) && ps.permissionsFixed) {
   5531                     // If this is an existing, non-system package, then
   5532                     // we can't add any new permissions to it.
   5533                     if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
   5534                         // Except...  if this is a permission that was added
   5535                         // to the platform (note: need to only do this when
   5536                         // updating the platform).
   5537                         allowed = isNewPlatformPermissionForPackage(perm, pkg);
   5538                     }
   5539                 }
   5540                 if (allowed) {
   5541                     if (!gp.grantedPermissions.contains(perm)) {
   5542                         changedPermission = true;
   5543                         gp.grantedPermissions.add(perm);
   5544                         gp.gids = appendInts(gp.gids, bp.gids);
   5545                     } else if (!ps.haveGids) {
   5546                         gp.gids = appendInts(gp.gids, bp.gids);
   5547                     }
   5548                 } else {
   5549                     Slog.w(TAG, "Not granting permission " + perm
   5550                             + " to package " + pkg.packageName
   5551                             + " because it was previously installed without");
   5552                 }
   5553             } else {
   5554                 if (gp.grantedPermissions.remove(perm)) {
   5555                     changedPermission = true;
   5556                     gp.gids = removeInts(gp.gids, bp.gids);
   5557                     Slog.i(TAG, "Un-granting permission " + perm
   5558                             + " from package " + pkg.packageName
   5559                             + " (protectionLevel=" + bp.protectionLevel
   5560                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   5561                             + ")");
   5562                 } else {
   5563                     Slog.w(TAG, "Not granting permission " + perm
   5564                             + " to package " + pkg.packageName
   5565                             + " (protectionLevel=" + bp.protectionLevel
   5566                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   5567                             + ")");
   5568                 }
   5569             }
   5570         }
   5571 
   5572         if ((changedPermission || replace) && !ps.permissionsFixed &&
   5573                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
   5574             // This is the first that we have heard about this package, so the
   5575             // permissions we have now selected are fixed until explicitly
   5576             // changed.
   5577             ps.permissionsFixed = true;
   5578         }
   5579         ps.haveGids = true;
   5580     }
   5581 
   5582     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
   5583         boolean allowed = false;
   5584         final int NP = PackageParser.NEW_PERMISSIONS.length;
   5585         for (int ip=0; ip<NP; ip++) {
   5586             final PackageParser.NewPermissionInfo npi
   5587                     = PackageParser.NEW_PERMISSIONS[ip];
   5588             if (npi.name.equals(perm)
   5589                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
   5590                 allowed = true;
   5591                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
   5592                         + pkg.packageName);
   5593                 break;
   5594             }
   5595         }
   5596         return allowed;
   5597     }
   5598 
   5599     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
   5600                                           BasePermission bp, HashSet<String> origPermissions) {
   5601         boolean allowed;
   5602         allowed = (compareSignatures(
   5603                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
   5604                         == PackageManager.SIGNATURE_MATCH)
   5605                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
   5606                         == PackageManager.SIGNATURE_MATCH);
   5607         if (!allowed && (bp.protectionLevel
   5608                 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
   5609             if (isSystemApp(pkg)) {
   5610                 // For updated system applications, a system permission
   5611                 // is granted only if it had been defined by the original application.
   5612                 if (isUpdatedSystemApp(pkg)) {
   5613                     final PackageSetting sysPs = mSettings
   5614                             .getDisabledSystemPkgLPr(pkg.packageName);
   5615                     final GrantedPermissions origGp = sysPs.sharedUser != null
   5616                             ? sysPs.sharedUser : sysPs;
   5617 
   5618                     if (origGp.grantedPermissions.contains(perm)) {
   5619                         // If the original was granted this permission, we take
   5620                         // that grant decision as read and propagate it to the
   5621                         // update.
   5622                         allowed = true;
   5623                     } else {
   5624                         // The system apk may have been updated with an older
   5625                         // version of the one on the data partition, but which
   5626                         // granted a new system permission that it didn't have
   5627                         // before.  In this case we do want to allow the app to
   5628                         // now get the new permission if the ancestral apk is
   5629                         // privileged to get it.
   5630                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
   5631                             for (int j=0;
   5632                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
   5633                                 if (perm.equals(
   5634                                         sysPs.pkg.requestedPermissions.get(j))) {
   5635                                     allowed = true;
   5636                                     break;
   5637                                 }
   5638                             }
   5639                         }
   5640                     }
   5641                 } else {
   5642                     allowed = isPrivilegedApp(pkg);
   5643                 }
   5644             }
   5645         }
   5646         if (!allowed && (bp.protectionLevel
   5647                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
   5648             // For development permissions, a development permission
   5649             // is granted only if it was already granted.
   5650             allowed = origPermissions.contains(perm);
   5651         }
   5652         return allowed;
   5653     }
   5654 
   5655     final class ActivityIntentResolver
   5656             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
   5657         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   5658                 boolean defaultOnly, int userId) {
   5659             if (!sUserManager.exists(userId)) return null;
   5660             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   5661             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   5662         }
   5663 
   5664         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   5665                 int userId) {
   5666             if (!sUserManager.exists(userId)) return null;
   5667             mFlags = flags;
   5668             return super.queryIntent(intent, resolvedType,
   5669                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   5670         }
   5671 
   5672         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   5673                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
   5674             if (!sUserManager.exists(userId)) return null;
   5675             if (packageActivities == null) {
   5676                 return null;
   5677             }
   5678             mFlags = flags;
   5679             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   5680             final int N = packageActivities.size();
   5681             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
   5682                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
   5683 
   5684             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
   5685             for (int i = 0; i < N; ++i) {
   5686                 intentFilters = packageActivities.get(i).intents;
   5687                 if (intentFilters != null && intentFilters.size() > 0) {
   5688                     PackageParser.ActivityIntentInfo[] array =
   5689                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
   5690                     intentFilters.toArray(array);
   5691                     listCut.add(array);
   5692                 }
   5693             }
   5694             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   5695         }
   5696 
   5697         public final void addActivity(PackageParser.Activity a, String type) {
   5698             final boolean systemApp = isSystemApp(a.info.applicationInfo);
   5699             mActivities.put(a.getComponentName(), a);
   5700             if (DEBUG_SHOW_INFO)
   5701                 Log.v(
   5702                 TAG, "  " + type + " " +
   5703                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
   5704             if (DEBUG_SHOW_INFO)
   5705                 Log.v(TAG, "    Class=" + a.info.name);
   5706             final int NI = a.intents.size();
   5707             for (int j=0; j<NI; j++) {
   5708                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   5709                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
   5710                     intent.setPriority(0);
   5711                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
   5712                             + a.className + " with priority > 0, forcing to 0");
   5713                 }
   5714                 if (DEBUG_SHOW_INFO) {
   5715                     Log.v(TAG, "    IntentFilter:");
   5716                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   5717                 }
   5718                 if (!intent.debugCheck()) {
   5719                     Log.w(TAG, "==> For Activity " + a.info.name);
   5720                 }
   5721                 addFilter(intent);
   5722             }
   5723         }
   5724 
   5725         public final void removeActivity(PackageParser.Activity a, String type) {
   5726             mActivities.remove(a.getComponentName());
   5727             if (DEBUG_SHOW_INFO) {
   5728                 Log.v(TAG, "  " + type + " "
   5729                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
   5730                                 : a.info.name) + ":");
   5731                 Log.v(TAG, "    Class=" + a.info.name);
   5732             }
   5733             final int NI = a.intents.size();
   5734             for (int j=0; j<NI; j++) {
   5735                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   5736                 if (DEBUG_SHOW_INFO) {
   5737                     Log.v(TAG, "    IntentFilter:");
   5738                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   5739                 }
   5740                 removeFilter(intent);
   5741             }
   5742         }
   5743 
   5744         @Override
   5745         protected boolean allowFilterResult(
   5746                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
   5747             ActivityInfo filterAi = filter.activity.info;
   5748             for (int i=dest.size()-1; i>=0; i--) {
   5749                 ActivityInfo destAi = dest.get(i).activityInfo;
   5750                 if (destAi.name == filterAi.name
   5751                         && destAi.packageName == filterAi.packageName) {
   5752                     return false;
   5753                 }
   5754             }
   5755             return true;
   5756         }
   5757 
   5758         @Override
   5759         protected ActivityIntentInfo[] newArray(int size) {
   5760             return new ActivityIntentInfo[size];
   5761         }
   5762 
   5763         @Override
   5764         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
   5765             if (!sUserManager.exists(userId)) return true;
   5766             PackageParser.Package p = filter.activity.owner;
   5767             if (p != null) {
   5768                 PackageSetting ps = (PackageSetting)p.mExtras;
   5769                 if (ps != null) {
   5770                     // System apps are never considered stopped for purposes of
   5771                     // filtering, because there may be no way for the user to
   5772                     // actually re-launch them.
   5773                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
   5774                             && ps.getStopped(userId);
   5775                 }
   5776             }
   5777             return false;
   5778         }
   5779 
   5780         @Override
   5781         protected boolean isPackageForFilter(String packageName,
   5782                 PackageParser.ActivityIntentInfo info) {
   5783             return packageName.equals(info.activity.owner.packageName);
   5784         }
   5785 
   5786         @Override
   5787         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
   5788                 int match, int userId) {
   5789             if (!sUserManager.exists(userId)) return null;
   5790             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
   5791                 return null;
   5792             }
   5793             final PackageParser.Activity activity = info.activity;
   5794             if (mSafeMode && (activity.info.applicationInfo.flags
   5795                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   5796                 return null;
   5797             }
   5798             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
   5799             if (ps == null) {
   5800                 return null;
   5801             }
   5802             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
   5803                     ps.readUserState(userId), userId);
   5804             if (ai == null) {
   5805                 return null;
   5806             }
   5807             final ResolveInfo res = new ResolveInfo();
   5808             res.activityInfo = ai;
   5809             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   5810                 res.filter = info;
   5811             }
   5812             res.priority = info.getPriority();
   5813             res.preferredOrder = activity.owner.mPreferredOrder;
   5814             //System.out.println("Result: " + res.activityInfo.className +
   5815             //                   " = " + res.priority);
   5816             res.match = match;
   5817             res.isDefault = info.hasDefault;
   5818             res.labelRes = info.labelRes;
   5819             res.nonLocalizedLabel = info.nonLocalizedLabel;
   5820             res.icon = info.icon;
   5821             res.system = isSystemApp(res.activityInfo.applicationInfo);
   5822             return res;
   5823         }
   5824 
   5825         @Override
   5826         protected void sortResults(List<ResolveInfo> results) {
   5827             Collections.sort(results, mResolvePrioritySorter);
   5828         }
   5829 
   5830         @Override
   5831         protected void dumpFilter(PrintWriter out, String prefix,
   5832                 PackageParser.ActivityIntentInfo filter) {
   5833             out.print(prefix); out.print(
   5834                     Integer.toHexString(System.identityHashCode(filter.activity)));
   5835                     out.print(' ');
   5836                     filter.activity.printComponentShortName(out);
   5837                     out.print(" filter ");
   5838                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   5839         }
   5840 
   5841 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   5842 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   5843 //            final List<ResolveInfo> retList = Lists.newArrayList();
   5844 //            while (i.hasNext()) {
   5845 //                final ResolveInfo resolveInfo = i.next();
   5846 //                if (isEnabledLP(resolveInfo.activityInfo)) {
   5847 //                    retList.add(resolveInfo);
   5848 //                }
   5849 //            }
   5850 //            return retList;
   5851 //        }
   5852 
   5853         // Keys are String (activity class name), values are Activity.
   5854         private final HashMap<ComponentName, PackageParser.Activity> mActivities
   5855                 = new HashMap<ComponentName, PackageParser.Activity>();
   5856         private int mFlags;
   5857     }
   5858 
   5859     private final class ServiceIntentResolver
   5860             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
   5861         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   5862                 boolean defaultOnly, int userId) {
   5863             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   5864             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   5865         }
   5866 
   5867         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   5868                 int userId) {
   5869             if (!sUserManager.exists(userId)) return null;
   5870             mFlags = flags;
   5871             return super.queryIntent(intent, resolvedType,
   5872                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   5873         }
   5874 
   5875         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   5876                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
   5877             if (!sUserManager.exists(userId)) return null;
   5878             if (packageServices == null) {
   5879                 return null;
   5880             }
   5881             mFlags = flags;
   5882             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   5883             final int N = packageServices.size();
   5884             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
   5885                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
   5886 
   5887             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
   5888             for (int i = 0; i < N; ++i) {
   5889                 intentFilters = packageServices.get(i).intents;
   5890                 if (intentFilters != null && intentFilters.size() > 0) {
   5891                     PackageParser.ServiceIntentInfo[] array =
   5892                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
   5893                     intentFilters.toArray(array);
   5894                     listCut.add(array);
   5895                 }
   5896             }
   5897             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   5898         }
   5899 
   5900         public final void addService(PackageParser.Service s) {
   5901             mServices.put(s.getComponentName(), s);
   5902             if (DEBUG_SHOW_INFO) {
   5903                 Log.v(TAG, "  "
   5904                         + (s.info.nonLocalizedLabel != null
   5905                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   5906                 Log.v(TAG, "    Class=" + s.info.name);
   5907             }
   5908             final int NI = s.intents.size();
   5909             int j;
   5910             for (j=0; j<NI; j++) {
   5911                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   5912                 if (DEBUG_SHOW_INFO) {
   5913                     Log.v(TAG, "    IntentFilter:");
   5914                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   5915                 }
   5916                 if (!intent.debugCheck()) {
   5917                     Log.w(TAG, "==> For Service " + s.info.name);
   5918                 }
   5919                 addFilter(intent);
   5920             }
   5921         }
   5922 
   5923         public final void removeService(PackageParser.Service s) {
   5924             mServices.remove(s.getComponentName());
   5925             if (DEBUG_SHOW_INFO) {
   5926                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
   5927                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   5928                 Log.v(TAG, "    Class=" + s.info.name);
   5929             }
   5930             final int NI = s.intents.size();
   5931             int j;
   5932             for (j=0; j<NI; j++) {
   5933                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   5934                 if (DEBUG_SHOW_INFO) {
   5935                     Log.v(TAG, "    IntentFilter:");
   5936                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   5937                 }
   5938                 removeFilter(intent);
   5939             }
   5940         }
   5941 
   5942         @Override
   5943         protected boolean allowFilterResult(
   5944                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
   5945             ServiceInfo filterSi = filter.service.info;
   5946             for (int i=dest.size()-1; i>=0; i--) {
   5947                 ServiceInfo destAi = dest.get(i).serviceInfo;
   5948                 if (destAi.name == filterSi.name
   5949                         && destAi.packageName == filterSi.packageName) {
   5950                     return false;
   5951                 }
   5952             }
   5953             return true;
   5954         }
   5955 
   5956         @Override
   5957         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
   5958             return new PackageParser.ServiceIntentInfo[size];
   5959         }
   5960 
   5961         @Override
   5962         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
   5963             if (!sUserManager.exists(userId)) return true;
   5964             PackageParser.Package p = filter.service.owner;
   5965             if (p != null) {
   5966                 PackageSetting ps = (PackageSetting)p.mExtras;
   5967                 if (ps != null) {
   5968                     // System apps are never considered stopped for purposes of
   5969                     // filtering, because there may be no way for the user to
   5970                     // actually re-launch them.
   5971                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
   5972                             && ps.getStopped(userId);
   5973                 }
   5974             }
   5975             return false;
   5976         }
   5977 
   5978         @Override
   5979         protected boolean isPackageForFilter(String packageName,
   5980                 PackageParser.ServiceIntentInfo info) {
   5981             return packageName.equals(info.service.owner.packageName);
   5982         }
   5983 
   5984         @Override
   5985         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
   5986                 int match, int userId) {
   5987             if (!sUserManager.exists(userId)) return null;
   5988             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
   5989             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
   5990                 return null;
   5991             }
   5992             final PackageParser.Service service = info.service;
   5993             if (mSafeMode && (service.info.applicationInfo.flags
   5994                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   5995                 return null;
   5996             }
   5997             PackageSetting ps = (PackageSetting) service.owner.mExtras;
   5998             if (ps == null) {
   5999                 return null;
   6000             }
   6001             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
   6002                     ps.readUserState(userId), userId);
   6003             if (si == null) {
   6004                 return null;
   6005             }
   6006             final ResolveInfo res = new ResolveInfo();
   6007             res.serviceInfo = si;
   6008             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   6009                 res.filter = filter;
   6010             }
   6011             res.priority = info.getPriority();
   6012             res.preferredOrder = service.owner.mPreferredOrder;
   6013             //System.out.println("Result: " + res.activityInfo.className +
   6014             //                   " = " + res.priority);
   6015             res.match = match;
   6016             res.isDefault = info.hasDefault;
   6017             res.labelRes = info.labelRes;
   6018             res.nonLocalizedLabel = info.nonLocalizedLabel;
   6019             res.icon = info.icon;
   6020             res.system = isSystemApp(res.serviceInfo.applicationInfo);
   6021             return res;
   6022         }
   6023 
   6024         @Override
   6025         protected void sortResults(List<ResolveInfo> results) {
   6026             Collections.sort(results, mResolvePrioritySorter);
   6027         }
   6028 
   6029         @Override
   6030         protected void dumpFilter(PrintWriter out, String prefix,
   6031                 PackageParser.ServiceIntentInfo filter) {
   6032             out.print(prefix); out.print(
   6033                     Integer.toHexString(System.identityHashCode(filter.service)));
   6034                     out.print(' ');
   6035                     filter.service.printComponentShortName(out);
   6036                     out.print(" filter ");
   6037                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   6038         }
   6039 
   6040 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   6041 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   6042 //            final List<ResolveInfo> retList = Lists.newArrayList();
   6043 //            while (i.hasNext()) {
   6044 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
   6045 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
   6046 //                    retList.add(resolveInfo);
   6047 //                }
   6048 //            }
   6049 //            return retList;
   6050 //        }
   6051 
   6052         // Keys are String (activity class name), values are Activity.
   6053         private final HashMap<ComponentName, PackageParser.Service> mServices
   6054                 = new HashMap<ComponentName, PackageParser.Service>();
   6055         private int mFlags;
   6056     };
   6057 
   6058     private final class ProviderIntentResolver
   6059             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
   6060         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   6061                 boolean defaultOnly, int userId) {
   6062             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   6063             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   6064         }
   6065 
   6066         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   6067                 int userId) {
   6068             if (!sUserManager.exists(userId))
   6069                 return null;
   6070             mFlags = flags;
   6071             return super.queryIntent(intent, resolvedType,
   6072                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   6073         }
   6074 
   6075         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   6076                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
   6077             if (!sUserManager.exists(userId))
   6078                 return null;
   6079             if (packageProviders == null) {
   6080                 return null;
   6081             }
   6082             mFlags = flags;
   6083             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
   6084             final int N = packageProviders.size();
   6085             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
   6086                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
   6087 
   6088             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
   6089             for (int i = 0; i < N; ++i) {
   6090                 intentFilters = packageProviders.get(i).intents;
   6091                 if (intentFilters != null && intentFilters.size() > 0) {
   6092                     PackageParser.ProviderIntentInfo[] array =
   6093                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
   6094                     intentFilters.toArray(array);
   6095                     listCut.add(array);
   6096                 }
   6097             }
   6098             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   6099         }
   6100 
   6101         public final void addProvider(PackageParser.Provider p) {
   6102             mProviders.put(p.getComponentName(), p);
   6103             if (DEBUG_SHOW_INFO) {
   6104                 Log.v(TAG, "  "
   6105                         + (p.info.nonLocalizedLabel != null
   6106                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
   6107                 Log.v(TAG, "    Class=" + p.info.name);
   6108             }
   6109             final int NI = p.intents.size();
   6110             int j;
   6111             for (j = 0; j < NI; j++) {
   6112                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
   6113                 if (DEBUG_SHOW_INFO) {
   6114                     Log.v(TAG, "    IntentFilter:");
   6115                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   6116                 }
   6117                 if (!intent.debugCheck()) {
   6118                     Log.w(TAG, "==> For Provider " + p.info.name);
   6119                 }
   6120                 addFilter(intent);
   6121             }
   6122         }
   6123 
   6124         public final void removeProvider(PackageParser.Provider p) {
   6125             mProviders.remove(p.getComponentName());
   6126             if (DEBUG_SHOW_INFO) {
   6127                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
   6128                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
   6129                 Log.v(TAG, "    Class=" + p.info.name);
   6130             }
   6131             final int NI = p.intents.size();
   6132             int j;
   6133             for (j = 0; j < NI; j++) {
   6134                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
   6135                 if (DEBUG_SHOW_INFO) {
   6136                     Log.v(TAG, "    IntentFilter:");
   6137                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   6138                 }
   6139                 removeFilter(intent);
   6140             }
   6141         }
   6142 
   6143         @Override
   6144         protected boolean allowFilterResult(
   6145                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
   6146             ProviderInfo filterPi = filter.provider.info;
   6147             for (int i = dest.size() - 1; i >= 0; i--) {
   6148                 ProviderInfo destPi = dest.get(i).providerInfo;
   6149                 if (destPi.name == filterPi.name
   6150                         && destPi.packageName == filterPi.packageName) {
   6151                     return false;
   6152                 }
   6153             }
   6154             return true;
   6155         }
   6156 
   6157         @Override
   6158         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
   6159             return new PackageParser.ProviderIntentInfo[size];
   6160         }
   6161 
   6162         @Override
   6163         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
   6164             if (!sUserManager.exists(userId))
   6165                 return true;
   6166             PackageParser.Package p = filter.provider.owner;
   6167             if (p != null) {
   6168                 PackageSetting ps = (PackageSetting) p.mExtras;
   6169                 if (ps != null) {
   6170                     // System apps are never considered stopped for purposes of
   6171                     // filtering, because there may be no way for the user to
   6172                     // actually re-launch them.
   6173                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
   6174                             && ps.getStopped(userId);
   6175                 }
   6176             }
   6177             return false;
   6178         }
   6179 
   6180         @Override
   6181         protected boolean isPackageForFilter(String packageName,
   6182                 PackageParser.ProviderIntentInfo info) {
   6183             return packageName.equals(info.provider.owner.packageName);
   6184         }
   6185 
   6186         @Override
   6187         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
   6188                 int match, int userId) {
   6189             if (!sUserManager.exists(userId))
   6190                 return null;
   6191             final PackageParser.ProviderIntentInfo info = filter;
   6192             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
   6193                 return null;
   6194             }
   6195             final PackageParser.Provider provider = info.provider;
   6196             if (mSafeMode && (provider.info.applicationInfo.flags
   6197                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
   6198                 return null;
   6199             }
   6200             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
   6201             if (ps == null) {
   6202                 return null;
   6203             }
   6204             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
   6205                     ps.readUserState(userId), userId);
   6206             if (pi == null) {
   6207                 return null;
   6208             }
   6209             final ResolveInfo res = new ResolveInfo();
   6210             res.providerInfo = pi;
   6211             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
   6212                 res.filter = filter;
   6213             }
   6214             res.priority = info.getPriority();
   6215             res.preferredOrder = provider.owner.mPreferredOrder;
   6216             res.match = match;
   6217             res.isDefault = info.hasDefault;
   6218             res.labelRes = info.labelRes;
   6219             res.nonLocalizedLabel = info.nonLocalizedLabel;
   6220             res.icon = info.icon;
   6221             res.system = isSystemApp(res.providerInfo.applicationInfo);
   6222             return res;
   6223         }
   6224 
   6225         @Override
   6226         protected void sortResults(List<ResolveInfo> results) {
   6227             Collections.sort(results, mResolvePrioritySorter);
   6228         }
   6229 
   6230         @Override
   6231         protected void dumpFilter(PrintWriter out, String prefix,
   6232                 PackageParser.ProviderIntentInfo filter) {
   6233             out.print(prefix);
   6234             out.print(
   6235                     Integer.toHexString(System.identityHashCode(filter.provider)));
   6236             out.print(' ');
   6237             filter.provider.printComponentShortName(out);
   6238             out.print(" filter ");
   6239             out.println(Integer.toHexString(System.identityHashCode(filter)));
   6240         }
   6241 
   6242         private final HashMap<ComponentName, PackageParser.Provider>