Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.pm;
     18 
     19 import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS;
     20 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
     21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
     22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
     23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
     24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
     25 import static com.android.internal.util.ArrayUtils.appendInt;
     26 import static com.android.internal.util.ArrayUtils.removeInt;
     27 import static libcore.io.OsConstants.S_ISLNK;
     28 
     29 import com.android.internal.app.IMediaContainerService;
     30 import com.android.internal.app.ResolverActivity;
     31 import com.android.internal.content.NativeLibraryHelper;
     32 import com.android.internal.content.PackageHelper;
     33 import com.android.internal.util.FastXmlSerializer;
     34 import com.android.internal.util.XmlUtils;
     35 import com.android.server.DeviceStorageMonitorService;
     36 import com.android.server.EventLogTags;
     37 import com.android.server.IntentResolver;
     38 
     39 import org.xmlpull.v1.XmlPullParser;
     40 import org.xmlpull.v1.XmlPullParserException;
     41 import org.xmlpull.v1.XmlSerializer;
     42 
     43 import android.app.ActivityManagerNative;
     44 import android.app.IActivityManager;
     45 import android.app.admin.IDevicePolicyManager;
     46 import android.app.backup.IBackupManager;
     47 import android.content.BroadcastReceiver;
     48 import android.content.ComponentName;
     49 import android.content.Context;
     50 import android.content.IIntentReceiver;
     51 import android.content.Intent;
     52 import android.content.IntentFilter;
     53 import android.content.IntentSender;
     54 import android.content.ServiceConnection;
     55 import android.content.IntentSender.SendIntentException;
     56 import android.content.pm.ActivityInfo;
     57 import android.content.pm.ApplicationInfo;
     58 import android.content.pm.ContainerEncryptionParams;
     59 import android.content.pm.FeatureInfo;
     60 import android.content.pm.IPackageDataObserver;
     61 import android.content.pm.IPackageDeleteObserver;
     62 import android.content.pm.IPackageInstallObserver;
     63 import android.content.pm.IPackageManager;
     64 import android.content.pm.IPackageMoveObserver;
     65 import android.content.pm.IPackageStatsObserver;
     66 import android.content.pm.InstrumentationInfo;
     67 import android.content.pm.PackageInfo;
     68 import android.content.pm.PackageInfoLite;
     69 import android.content.pm.PackageManager;
     70 import android.content.pm.PackageParser;
     71 import android.content.pm.PackageStats;
     72 import android.content.pm.ParceledListSlice;
     73 import android.content.pm.PermissionGroupInfo;
     74 import android.content.pm.PermissionInfo;
     75 import android.content.pm.ProviderInfo;
     76 import android.content.pm.ResolveInfo;
     77 import android.content.pm.ServiceInfo;
     78 import android.content.pm.Signature;
     79 import android.content.pm.UserInfo;
     80 import android.content.pm.ManifestDigest;
     81 import android.content.pm.VerifierDeviceIdentity;
     82 import android.content.pm.VerifierInfo;
     83 import android.net.Uri;
     84 import android.os.Binder;
     85 import android.os.Build;
     86 import android.os.Bundle;
     87 import android.os.Environment;
     88 import android.os.FileObserver;
     89 import android.os.FileUtils;
     90 import android.os.Handler;
     91 import android.os.HandlerThread;
     92 import android.os.IBinder;
     93 import android.os.Looper;
     94 import android.os.Message;
     95 import android.os.Parcel;
     96 import android.os.ParcelFileDescriptor;
     97 import android.os.Process;
     98 import android.os.RemoteException;
     99 import android.os.ServiceManager;
    100 import android.os.SystemClock;
    101 import android.os.SystemProperties;
    102 import android.os.UserId;
    103 import android.provider.Settings.Secure;
    104 import android.security.SystemKeyStore;
    105 import android.util.DisplayMetrics;
    106 import android.util.EventLog;
    107 import android.util.Log;
    108 import android.util.LogPrinter;
    109 import android.util.Slog;
    110 import android.util.SparseArray;
    111 import android.util.Xml;
    112 import android.view.Display;
    113 import android.view.WindowManager;
    114 
    115 import java.io.BufferedOutputStream;
    116 import java.io.File;
    117 import java.io.FileDescriptor;
    118 import java.io.FileInputStream;
    119 import java.io.FileNotFoundException;
    120 import java.io.FileOutputStream;
    121 import java.io.FileReader;
    122 import java.io.FilenameFilter;
    123 import java.io.IOException;
    124 import java.io.PrintWriter;
    125 import java.security.NoSuchAlgorithmException;
    126 import java.security.PublicKey;
    127 import java.security.cert.CertificateException;
    128 import java.text.SimpleDateFormat;
    129 import java.util.ArrayList;
    130 import java.util.Arrays;
    131 import java.util.Collection;
    132 import java.util.Collections;
    133 import java.util.Comparator;
    134 import java.util.Date;
    135 import java.util.HashMap;
    136 import java.util.HashSet;
    137 import java.util.Iterator;
    138 import java.util.List;
    139 import java.util.Map;
    140 import java.util.Map.Entry;
    141 import java.util.Set;
    142 
    143 import libcore.io.ErrnoException;
    144 import libcore.io.IoUtils;
    145 import libcore.io.Libcore;
    146 
    147 /**
    148  * Keep track of all those .apks everywhere.
    149  *
    150  * This is very central to the platform's security; please run the unit
    151  * tests whenever making modifications here:
    152  *
    153 mmm frameworks/base/tests/AndroidTests
    154 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
    155 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
    156  *
    157  * {@hide}
    158  */
    159 public class PackageManagerService extends IPackageManager.Stub {
    160     static final String TAG = "PackageManager";
    161     static final boolean DEBUG_SETTINGS = false;
    162     private static final boolean DEBUG_PREFERRED = false;
    163     static final boolean DEBUG_UPGRADE = false;
    164     private static final boolean DEBUG_INSTALL = false;
    165     private static final boolean DEBUG_REMOVE = false;
    166     private static final boolean DEBUG_SHOW_INFO = false;
    167     private static final boolean DEBUG_PACKAGE_INFO = false;
    168     private static final boolean DEBUG_INTENT_MATCHING = false;
    169     private static final boolean DEBUG_PACKAGE_SCANNING = false;
    170     private static final boolean DEBUG_APP_DIR_OBSERVER = false;
    171     private static final boolean DEBUG_VERIFY = false;
    172 
    173     private static final int RADIO_UID = Process.PHONE_UID;
    174     private static final int LOG_UID = Process.LOG_UID;
    175     private static final int NFC_UID = Process.NFC_UID;
    176 
    177     private static final boolean GET_CERTIFICATES = true;
    178 
    179     private static final int REMOVE_EVENTS =
    180         FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
    181     private static final int ADD_EVENTS =
    182         FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO;
    183 
    184     private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS;
    185     // Suffix used during package installation when copying/moving
    186     // package apks to install directory.
    187     private static final String INSTALL_PACKAGE_SUFFIX = "-";
    188 
    189     static final int SCAN_MONITOR = 1<<0;
    190     static final int SCAN_NO_DEX = 1<<1;
    191     static final int SCAN_FORCE_DEX = 1<<2;
    192     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
    193     static final int SCAN_NEW_INSTALL = 1<<4;
    194     static final int SCAN_NO_PATHS = 1<<5;
    195     static final int SCAN_UPDATE_TIME = 1<<6;
    196     static final int SCAN_DEFER_DEX = 1<<7;
    197     static final int SCAN_BOOTING = 1<<8;
    198 
    199     static final int REMOVE_CHATTY = 1<<16;
    200 
    201     /**
    202      * Whether verification is enabled by default.
    203      */
    204     // STOPSHIP: change this to true
    205     private static final boolean DEFAULT_VERIFY_ENABLE = false;
    206 
    207     /**
    208      * The default maximum time to wait for the verification agent to return in
    209      * milliseconds.
    210      */
    211     private static final long DEFAULT_VERIFICATION_TIMEOUT = 60 * 1000;
    212 
    213     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
    214 
    215     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
    216             DEFAULT_CONTAINER_PACKAGE,
    217             "com.android.defcontainer.DefaultContainerService");
    218 
    219     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
    220 
    221     private static final String LIB_DIR_NAME = "lib";
    222 
    223     static final String mTempContainerPrefix = "smdl2tmp";
    224 
    225     final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
    226             Process.THREAD_PRIORITY_BACKGROUND);
    227     final PackageHandler mHandler;
    228 
    229     final int mSdkVersion = Build.VERSION.SDK_INT;
    230     final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
    231             ? null : Build.VERSION.CODENAME;
    232 
    233     final Context mContext;
    234     final boolean mFactoryTest;
    235     final boolean mOnlyCore;
    236     final boolean mNoDexOpt;
    237     final DisplayMetrics mMetrics;
    238     final int mDefParseFlags;
    239     final String[] mSeparateProcesses;
    240 
    241     // This is where all application persistent data goes.
    242     final File mAppDataDir;
    243 
    244     // This is where all application persistent data goes for secondary users.
    245     final File mUserAppDataDir;
    246 
    247     /** The location for ASEC container files on internal storage. */
    248     final String mAsecInternalPath;
    249 
    250     // This is the object monitoring the framework dir.
    251     final FileObserver mFrameworkInstallObserver;
    252 
    253     // This is the object monitoring the system app dir.
    254     final FileObserver mSystemInstallObserver;
    255 
    256     // This is the object monitoring the system app dir.
    257     final FileObserver mVendorInstallObserver;
    258 
    259     // This is the object monitoring mAppInstallDir.
    260     final FileObserver mAppInstallObserver;
    261 
    262     // This is the object monitoring mDrmAppPrivateInstallDir.
    263     final FileObserver mDrmAppInstallObserver;
    264 
    265     // Used for priviledge escalation.  MUST NOT BE CALLED WITH mPackages
    266     // LOCK HELD.  Can be called with mInstallLock held.
    267     final Installer mInstaller;
    268 
    269     final File mFrameworkDir;
    270     final File mSystemAppDir;
    271     final File mVendorAppDir;
    272     final File mAppInstallDir;
    273     final File mDalvikCacheDir;
    274 
    275     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
    276     // apps.
    277     final File mDrmAppPrivateInstallDir;
    278 
    279     // ----------------------------------------------------------------
    280 
    281     // Lock for state used when installing and doing other long running
    282     // operations.  Methods that must be called with this lock held have
    283     // the prefix "LI".
    284     final Object mInstallLock = new Object();
    285 
    286     // These are the directories in the 3rd party applications installed dir
    287     // that we have currently loaded packages from.  Keys are the application's
    288     // installed zip file (absolute codePath), and values are Package.
    289     final HashMap<String, PackageParser.Package> mAppDirs =
    290             new HashMap<String, PackageParser.Package>();
    291 
    292     // Information for the parser to write more useful error messages.
    293     File mScanningPath;
    294     int mLastScanError;
    295 
    296     final int[] mOutPermissions = new int[3];
    297 
    298     // ----------------------------------------------------------------
    299 
    300     // Keys are String (package name), values are Package.  This also serves
    301     // as the lock for the global state.  Methods that must be called with
    302     // this lock held have the prefix "LP".
    303     final HashMap<String, PackageParser.Package> mPackages =
    304             new HashMap<String, PackageParser.Package>();
    305 
    306     final Settings mSettings;
    307     boolean mRestoredSettings;
    308 
    309     // Group-ids that are given to all packages as read from etc/permissions/*.xml.
    310     int[] mGlobalGids;
    311 
    312     // These are the built-in uid -> permission mappings that were read from the
    313     // etc/permissions.xml file.
    314     final SparseArray<HashSet<String>> mSystemPermissions =
    315             new SparseArray<HashSet<String>>();
    316 
    317     // These are the built-in shared libraries that were read from the
    318     // etc/permissions.xml file.
    319     final HashMap<String, String> mSharedLibraries = new HashMap<String, String>();
    320 
    321     // Temporary for building the final shared libraries for an .apk.
    322     String[] mTmpSharedLibraries = null;
    323 
    324     // These are the features this devices supports that were read from the
    325     // etc/permissions.xml file.
    326     final HashMap<String, FeatureInfo> mAvailableFeatures =
    327             new HashMap<String, FeatureInfo>();
    328 
    329     // All available activities, for your resolving pleasure.
    330     final ActivityIntentResolver mActivities =
    331             new ActivityIntentResolver();
    332 
    333     // All available receivers, for your resolving pleasure.
    334     final ActivityIntentResolver mReceivers =
    335             new ActivityIntentResolver();
    336 
    337     // All available services, for your resolving pleasure.
    338     final ServiceIntentResolver mServices = new ServiceIntentResolver();
    339 
    340     // Keys are String (provider class name), values are Provider.
    341     final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent =
    342             new HashMap<ComponentName, PackageParser.Provider>();
    343 
    344     // Mapping from provider base names (first directory in content URI codePath)
    345     // to the provider information.
    346     final HashMap<String, PackageParser.Provider> mProviders =
    347             new HashMap<String, PackageParser.Provider>();
    348 
    349     // Mapping from instrumentation class names to info about them.
    350     final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
    351             new HashMap<ComponentName, PackageParser.Instrumentation>();
    352 
    353     // Mapping from permission names to info about them.
    354     final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
    355             new HashMap<String, PackageParser.PermissionGroup>();
    356 
    357     // Packages whose data we have transfered into another package, thus
    358     // should no longer exist.
    359     final HashSet<String> mTransferedPackages = new HashSet<String>();
    360 
    361     // Broadcast actions that are only available to the system.
    362     final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
    363 
    364     /** List of packages waiting for verification. */
    365     final SparseArray<PackageVerificationState> mPendingVerification
    366             = new SparseArray<PackageVerificationState>();
    367 
    368     final ArrayList<PackageParser.Package> mDeferredDexOpt =
    369             new ArrayList<PackageParser.Package>();
    370 
    371     /** Token for keys in mPendingVerification. */
    372     private int mPendingVerificationToken = 0;
    373 
    374     boolean mSystemReady;
    375     boolean mSafeMode;
    376     boolean mHasSystemUidErrors;
    377 
    378     ApplicationInfo mAndroidApplication;
    379     final ActivityInfo mResolveActivity = new ActivityInfo();
    380     final ResolveInfo mResolveInfo = new ResolveInfo();
    381     ComponentName mResolveComponentName;
    382     PackageParser.Package mPlatformPackage;
    383 
    384     // Set of pending broadcasts for aggregating enable/disable of components.
    385     final HashMap<String, ArrayList<String>> mPendingBroadcasts
    386             = new HashMap<String, ArrayList<String>>();
    387     // Service Connection to remote media container service to copy
    388     // package uri's from external media onto secure containers
    389     // or internal storage.
    390     private IMediaContainerService mContainerService = null;
    391 
    392     static final int SEND_PENDING_BROADCAST = 1;
    393     static final int MCS_BOUND = 3;
    394     static final int END_COPY = 4;
    395     static final int INIT_COPY = 5;
    396     static final int MCS_UNBIND = 6;
    397     static final int START_CLEANING_PACKAGE = 7;
    398     static final int FIND_INSTALL_LOC = 8;
    399     static final int POST_INSTALL = 9;
    400     static final int MCS_RECONNECT = 10;
    401     static final int MCS_GIVE_UP = 11;
    402     static final int UPDATED_MEDIA_STATUS = 12;
    403     static final int WRITE_SETTINGS = 13;
    404     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
    405     static final int PACKAGE_VERIFIED = 15;
    406     static final int CHECK_PENDING_VERIFICATION = 16;
    407 
    408     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
    409 
    410     // Delay time in millisecs
    411     static final int BROADCAST_DELAY = 10 * 1000;
    412 
    413     static UserManager sUserManager;
    414 
    415     // Stores a list of users whose package restrictions file needs to be updated
    416     private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
    417 
    418     final private DefaultContainerConnection mDefContainerConn =
    419             new DefaultContainerConnection();
    420     class DefaultContainerConnection implements ServiceConnection {
    421         public void onServiceConnected(ComponentName name, IBinder service) {
    422             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
    423             IMediaContainerService imcs =
    424                 IMediaContainerService.Stub.asInterface(service);
    425             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
    426         }
    427 
    428         public void onServiceDisconnected(ComponentName name) {
    429             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
    430         }
    431     };
    432 
    433     // Recordkeeping of restore-after-install operations that are currently in flight
    434     // between the Package Manager and the Backup Manager
    435     class PostInstallData {
    436         public InstallArgs args;
    437         public PackageInstalledInfo res;
    438 
    439         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
    440             args = _a;
    441             res = _r;
    442         }
    443     };
    444     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
    445     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
    446 
    447     private final String mRequiredVerifierPackage;
    448 
    449     class PackageHandler extends Handler {
    450         private boolean mBound = false;
    451         final ArrayList<HandlerParams> mPendingInstalls =
    452             new ArrayList<HandlerParams>();
    453 
    454         private boolean connectToService() {
    455             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
    456                     " DefaultContainerService");
    457             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
    458             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    459             if (mContext.bindService(service, mDefContainerConn,
    460                     Context.BIND_AUTO_CREATE)) {
    461                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    462                 mBound = true;
    463                 return true;
    464             }
    465             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    466             return false;
    467         }
    468 
    469         private void disconnectService() {
    470             mContainerService = null;
    471             mBound = false;
    472             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    473             mContext.unbindService(mDefContainerConn);
    474             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    475         }
    476 
    477         PackageHandler(Looper looper) {
    478             super(looper);
    479         }
    480 
    481         public void handleMessage(Message msg) {
    482             try {
    483                 doHandleMessage(msg);
    484             } finally {
    485                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    486             }
    487         }
    488 
    489         void doHandleMessage(Message msg) {
    490             switch (msg.what) {
    491                 case INIT_COPY: {
    492                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy");
    493                     HandlerParams params = (HandlerParams) msg.obj;
    494                     int idx = mPendingInstalls.size();
    495                     if (DEBUG_INSTALL) Slog.i(TAG, "idx=" + idx);
    496                     // If a bind was already initiated we dont really
    497                     // need to do anything. The pending install
    498                     // will be processed later on.
    499                     if (!mBound) {
    500                         // If this is the only one pending we might
    501                         // have to bind to the service again.
    502                         if (!connectToService()) {
    503                             Slog.e(TAG, "Failed to bind to media container service");
    504                             params.serviceError();
    505                             return;
    506                         } else {
    507                             // Once we bind to the service, the first
    508                             // pending request will be processed.
    509                             mPendingInstalls.add(idx, params);
    510                         }
    511                     } else {
    512                         mPendingInstalls.add(idx, params);
    513                         // Already bound to the service. Just make
    514                         // sure we trigger off processing the first request.
    515                         if (idx == 0) {
    516                             mHandler.sendEmptyMessage(MCS_BOUND);
    517                         }
    518                     }
    519                     break;
    520                 }
    521                 case MCS_BOUND: {
    522                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
    523                     if (msg.obj != null) {
    524                         mContainerService = (IMediaContainerService) msg.obj;
    525                     }
    526                     if (mContainerService == null) {
    527                         // Something seriously wrong. Bail out
    528                         Slog.e(TAG, "Cannot bind to media container service");
    529                         for (HandlerParams params : mPendingInstalls) {
    530                             // Indicate service bind error
    531                             params.serviceError();
    532                         }
    533                         mPendingInstalls.clear();
    534                     } else if (mPendingInstalls.size() > 0) {
    535                         HandlerParams params = mPendingInstalls.get(0);
    536                         if (params != null) {
    537                             if (params.startCopy()) {
    538                                 // We are done...  look for more work or to
    539                                 // go idle.
    540                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
    541                                         "Checking for more work or unbind...");
    542                                 // Delete pending install
    543                                 if (mPendingInstalls.size() > 0) {
    544                                     mPendingInstalls.remove(0);
    545                                 }
    546                                 if (mPendingInstalls.size() == 0) {
    547                                     if (mBound) {
    548                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
    549                                                 "Posting delayed MCS_UNBIND");
    550                                         removeMessages(MCS_UNBIND);
    551                                         Message ubmsg = obtainMessage(MCS_UNBIND);
    552                                         // Unbind after a little delay, to avoid
    553                                         // continual thrashing.
    554                                         sendMessageDelayed(ubmsg, 10000);
    555                                     }
    556                                 } else {
    557                                     // There are more pending requests in queue.
    558                                     // Just post MCS_BOUND message to trigger processing
    559                                     // of next pending install.
    560                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
    561                                             "Posting MCS_BOUND for next woek");
    562                                     mHandler.sendEmptyMessage(MCS_BOUND);
    563                                 }
    564                             }
    565                         }
    566                     } else {
    567                         // Should never happen ideally.
    568                         Slog.w(TAG, "Empty queue");
    569                     }
    570                     break;
    571                 }
    572                 case MCS_RECONNECT: {
    573                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
    574                     if (mPendingInstalls.size() > 0) {
    575                         if (mBound) {
    576                             disconnectService();
    577                         }
    578                         if (!connectToService()) {
    579                             Slog.e(TAG, "Failed to bind to media container service");
    580                             for (HandlerParams params : mPendingInstalls) {
    581                                 // Indicate service bind error
    582                                 params.serviceError();
    583                             }
    584                             mPendingInstalls.clear();
    585                         }
    586                     }
    587                     break;
    588                 }
    589                 case MCS_UNBIND: {
    590                     // If there is no actual work left, then time to unbind.
    591                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
    592 
    593                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
    594                         if (mBound) {
    595                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
    596 
    597                             disconnectService();
    598                         }
    599                     } else if (mPendingInstalls.size() > 0) {
    600                         // There are more pending requests in queue.
    601                         // Just post MCS_BOUND message to trigger processing
    602                         // of next pending install.
    603                         mHandler.sendEmptyMessage(MCS_BOUND);
    604                     }
    605 
    606                     break;
    607                 }
    608                 case MCS_GIVE_UP: {
    609                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
    610                     mPendingInstalls.remove(0);
    611                     break;
    612                 }
    613                 case SEND_PENDING_BROADCAST: {
    614                     String packages[];
    615                     ArrayList<String> components[];
    616                     int size = 0;
    617                     int uids[];
    618                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    619                     synchronized (mPackages) {
    620                         if (mPendingBroadcasts == null) {
    621                             return;
    622                         }
    623                         size = mPendingBroadcasts.size();
    624                         if (size <= 0) {
    625                             // Nothing to be done. Just return
    626                             return;
    627                         }
    628                         packages = new String[size];
    629                         components = new ArrayList[size];
    630                         uids = new int[size];
    631                         Iterator<Map.Entry<String, ArrayList<String>>>
    632                                 it = mPendingBroadcasts.entrySet().iterator();
    633                         int i = 0;
    634                         while (it.hasNext() && i < size) {
    635                             Map.Entry<String, ArrayList<String>> ent = it.next();
    636                             packages[i] = ent.getKey();
    637                             components[i] = ent.getValue();
    638                             PackageSetting ps = mSettings.mPackages.get(ent.getKey());
    639                             uids[i] = (ps != null) ? ps.appId : -1;
    640                             i++;
    641                         }
    642                         size = i;
    643                         mPendingBroadcasts.clear();
    644                     }
    645                     // Send broadcasts
    646                     for (int i = 0; i < size; i++) {
    647                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
    648                     }
    649                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    650                     break;
    651                 }
    652                 case START_CLEANING_PACKAGE: {
    653                     String packageName = (String)msg.obj;
    654                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    655                     synchronized (mPackages) {
    656                         if (!mSettings.mPackagesToBeCleaned.contains(packageName)) {
    657                             mSettings.mPackagesToBeCleaned.add(packageName);
    658                         }
    659                     }
    660                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    661                     startCleaningPackages();
    662                 } break;
    663                 case POST_INSTALL: {
    664                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
    665                     PostInstallData data = mRunningInstalls.get(msg.arg1);
    666                     mRunningInstalls.delete(msg.arg1);
    667                     boolean deleteOld = false;
    668 
    669                     if (data != null) {
    670                         InstallArgs args = data.args;
    671                         PackageInstalledInfo res = data.res;
    672 
    673                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
    674                             res.removedInfo.sendBroadcast(false, true);
    675                             Bundle extras = new Bundle(1);
    676                             extras.putInt(Intent.EXTRA_UID, res.uid);
    677                             final boolean update = res.removedInfo.removedPackage != null;
    678                             if (update) {
    679                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
    680                             }
    681                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
    682                                     res.pkg.applicationInfo.packageName,
    683                                     extras, null, null, UserId.USER_ALL);
    684                             if (update) {
    685                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
    686                                         res.pkg.applicationInfo.packageName,
    687                                         extras, null, null, UserId.USER_ALL);
    688                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
    689                                         null, null,
    690                                         res.pkg.applicationInfo.packageName, null,
    691                                         UserId.USER_ALL);
    692                             }
    693                             if (res.removedInfo.args != null) {
    694                                 // Remove the replaced package's older resources safely now
    695                                 deleteOld = true;
    696                             }
    697                         }
    698                         // Force a gc to clear up things
    699                         Runtime.getRuntime().gc();
    700                         // We delete after a gc for applications  on sdcard.
    701                         if (deleteOld) {
    702                             synchronized (mInstallLock) {
    703                                 res.removedInfo.args.doPostDeleteLI(true);
    704                             }
    705                         }
    706                         if (args.observer != null) {
    707                             try {
    708                                 args.observer.packageInstalled(res.name, res.returnCode);
    709                             } catch (RemoteException e) {
    710                                 Slog.i(TAG, "Observer no longer exists.");
    711                             }
    712                         }
    713                     } else {
    714                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
    715                     }
    716                 } break;
    717                 case UPDATED_MEDIA_STATUS: {
    718                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
    719                     boolean reportStatus = msg.arg1 == 1;
    720                     boolean doGc = msg.arg2 == 1;
    721                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
    722                     if (doGc) {
    723                         // Force a gc to clear up stale containers.
    724                         Runtime.getRuntime().gc();
    725                     }
    726                     if (msg.obj != null) {
    727                         @SuppressWarnings("unchecked")
    728                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
    729                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
    730                         // Unload containers
    731                         unloadAllContainers(args);
    732                     }
    733                     if (reportStatus) {
    734                         try {
    735                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
    736                             PackageHelper.getMountService().finishMediaUpdate();
    737                         } catch (RemoteException e) {
    738                             Log.e(TAG, "MountService not running?");
    739                         }
    740                     }
    741                 } break;
    742                 case WRITE_SETTINGS: {
    743                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    744                     synchronized (mPackages) {
    745                         removeMessages(WRITE_SETTINGS);
    746                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
    747                         mSettings.writeLPr();
    748                         mDirtyUsers.clear();
    749                     }
    750                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    751                 } break;
    752                 case WRITE_PACKAGE_RESTRICTIONS: {
    753                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    754                     synchronized (mPackages) {
    755                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
    756                         for (int userId : mDirtyUsers) {
    757                             mSettings.writePackageRestrictionsLPr(userId);
    758                         }
    759                         mDirtyUsers.clear();
    760                     }
    761                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    762                 } break;
    763                 case CHECK_PENDING_VERIFICATION: {
    764                     final int verificationId = msg.arg1;
    765                     final PackageVerificationState state = mPendingVerification.get(verificationId);
    766 
    767                     if (state != null) {
    768                         final InstallArgs args = state.getInstallArgs();
    769                         Slog.i(TAG, "Verification timed out for " + args.packageURI.toString());
    770                         mPendingVerification.remove(verificationId);
    771 
    772                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_TIMEOUT;
    773                         processPendingInstall(args, ret);
    774 
    775                         mHandler.sendEmptyMessage(MCS_UNBIND);
    776                     }
    777 
    778                     break;
    779                 }
    780                 case PACKAGE_VERIFIED: {
    781                     final int verificationId = msg.arg1;
    782 
    783                     final PackageVerificationState state = mPendingVerification.get(verificationId);
    784                     if (state == null) {
    785                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
    786                         break;
    787                     }
    788 
    789                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
    790 
    791                     state.setVerifierResponse(response.callerUid, response.code);
    792 
    793                     if (state.isVerificationComplete()) {
    794                         mPendingVerification.remove(verificationId);
    795 
    796                         final InstallArgs args = state.getInstallArgs();
    797 
    798                         int ret;
    799                         if (state.isInstallAllowed()) {
    800                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
    801                             try {
    802                                 ret = args.copyApk(mContainerService, true);
    803                             } catch (RemoteException e) {
    804                                 Slog.e(TAG, "Could not contact the ContainerService");
    805                             }
    806                         } else {
    807                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
    808                         }
    809 
    810                         processPendingInstall(args, ret);
    811 
    812                         mHandler.sendEmptyMessage(MCS_UNBIND);
    813                     }
    814 
    815                     break;
    816                 }
    817             }
    818         }
    819     }
    820 
    821     void scheduleWriteSettingsLocked() {
    822         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
    823             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
    824         }
    825     }
    826 
    827     void scheduleWritePackageRestrictionsLocked(int userId) {
    828         if (!sUserManager.exists(userId)) return;
    829         mDirtyUsers.add(userId);
    830         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
    831             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
    832         }
    833     }
    834 
    835     public static final IPackageManager main(Context context, boolean factoryTest,
    836             boolean onlyCore) {
    837         PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore);
    838         ServiceManager.addService("package", m);
    839         return m;
    840     }
    841 
    842     static String[] splitString(String str, char sep) {
    843         int count = 1;
    844         int i = 0;
    845         while ((i=str.indexOf(sep, i)) >= 0) {
    846             count++;
    847             i++;
    848         }
    849 
    850         String[] res = new String[count];
    851         i=0;
    852         count = 0;
    853         int lastI=0;
    854         while ((i=str.indexOf(sep, i)) >= 0) {
    855             res[count] = str.substring(lastI, i);
    856             count++;
    857             i++;
    858             lastI = i;
    859         }
    860         res[count] = str.substring(lastI, str.length());
    861         return res;
    862     }
    863 
    864     public PackageManagerService(Context context, boolean factoryTest, boolean onlyCore) {
    865         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
    866                 SystemClock.uptimeMillis());
    867 
    868         if (mSdkVersion <= 0) {
    869             Slog.w(TAG, "**** ro.build.version.sdk not set!");
    870         }
    871 
    872         mContext = context;
    873         mFactoryTest = factoryTest;
    874         mOnlyCore = onlyCore;
    875         mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
    876         mMetrics = new DisplayMetrics();
    877         mSettings = new Settings();
    878         mSettings.addSharedUserLPw("android.uid.system",
    879                 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM);
    880         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, ApplicationInfo.FLAG_SYSTEM);
    881         mSettings.addSharedUserLPw("android.uid.log", LOG_UID, ApplicationInfo.FLAG_SYSTEM);
    882         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, ApplicationInfo.FLAG_SYSTEM);
    883 
    884         String separateProcesses = SystemProperties.get("debug.separate_processes");
    885         if (separateProcesses != null && separateProcesses.length() > 0) {
    886             if ("*".equals(separateProcesses)) {
    887                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
    888                 mSeparateProcesses = null;
    889                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
    890             } else {
    891                 mDefParseFlags = 0;
    892                 mSeparateProcesses = separateProcesses.split(",");
    893                 Slog.w(TAG, "Running with debug.separate_processes: "
    894                         + separateProcesses);
    895             }
    896         } else {
    897             mDefParseFlags = 0;
    898             mSeparateProcesses = null;
    899         }
    900 
    901         mInstaller = new Installer();
    902 
    903         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    904         Display d = wm.getDefaultDisplay();
    905         d.getMetrics(mMetrics);
    906 
    907         synchronized (mInstallLock) {
    908         // writer
    909         synchronized (mPackages) {
    910             mHandlerThread.start();
    911             mHandler = new PackageHandler(mHandlerThread.getLooper());
    912 
    913             File dataDir = Environment.getDataDirectory();
    914             mAppDataDir = new File(dataDir, "data");
    915             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
    916             mUserAppDataDir = new File(dataDir, "user");
    917             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
    918 
    919             sUserManager = new UserManager(mInstaller, mUserAppDataDir);
    920 
    921             readPermissions();
    922 
    923             mRestoredSettings = mSettings.readLPw(getUsers());
    924             long startTime = SystemClock.uptimeMillis();
    925 
    926             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
    927                     startTime);
    928 
    929             // Set flag to monitor and not change apk file paths when
    930             // scanning install directories.
    931             int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
    932             if (mNoDexOpt) {
    933                 Slog.w(TAG, "Running ENG build: no pre-dexopt!");
    934                 scanMode |= SCAN_NO_DEX;
    935             }
    936 
    937             final HashSet<String> libFiles = new HashSet<String>();
    938 
    939             mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
    940             mDalvikCacheDir = new File(dataDir, "dalvik-cache");
    941 
    942             boolean didDexOpt = false;
    943 
    944             /**
    945              * Out of paranoia, ensure that everything in the boot class
    946              * path has been dexed.
    947              */
    948             String bootClassPath = System.getProperty("java.boot.class.path");
    949             if (bootClassPath != null) {
    950                 String[] paths = splitString(bootClassPath, ':');
    951                 for (int i=0; i<paths.length; i++) {
    952                     try {
    953                         if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
    954                             libFiles.add(paths[i]);
    955                             mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
    956                             didDexOpt = true;
    957                         }
    958                     } catch (FileNotFoundException e) {
    959                         Slog.w(TAG, "Boot class path not found: " + paths[i]);
    960                     } catch (IOException e) {
    961                         Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
    962                                 + e.getMessage());
    963                     }
    964                 }
    965             } else {
    966                 Slog.w(TAG, "No BOOTCLASSPATH found!");
    967             }
    968 
    969             /**
    970              * Also ensure all external libraries have had dexopt run on them.
    971              */
    972             if (mSharedLibraries.size() > 0) {
    973                 Iterator<String> libs = mSharedLibraries.values().iterator();
    974                 while (libs.hasNext()) {
    975                     String lib = libs.next();
    976                     try {
    977                         if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
    978                             libFiles.add(lib);
    979                             mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
    980                             didDexOpt = true;
    981                         }
    982                     } catch (FileNotFoundException e) {
    983                         Slog.w(TAG, "Library not found: " + lib);
    984                     } catch (IOException e) {
    985                         Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
    986                                 + e.getMessage());
    987                     }
    988                 }
    989             }
    990 
    991             // Gross hack for now: we know this file doesn't contain any
    992             // code, so don't dexopt it to avoid the resulting log spew.
    993             libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
    994 
    995             /**
    996              * And there are a number of commands implemented in Java, which
    997              * we currently need to do the dexopt on so that they can be
    998              * run from a non-root shell.
    999              */
   1000             String[] frameworkFiles = mFrameworkDir.list();
   1001             if (frameworkFiles != null) {
   1002                 for (int i=0; i<frameworkFiles.length; i++) {
   1003                     File libPath = new File(mFrameworkDir, frameworkFiles[i]);
   1004                     String path = libPath.getPath();
   1005                     // Skip the file if we alrady did it.
   1006                     if (libFiles.contains(path)) {
   1007                         continue;
   1008                     }
   1009                     // Skip the file if it is not a type we want to dexopt.
   1010                     if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
   1011                         continue;
   1012                     }
   1013                     try {
   1014                         if (dalvik.system.DexFile.isDexOptNeeded(path)) {
   1015                             mInstaller.dexopt(path, Process.SYSTEM_UID, true);
   1016                             didDexOpt = true;
   1017                         }
   1018                     } catch (FileNotFoundException e) {
   1019                         Slog.w(TAG, "Jar not found: " + path);
   1020                     } catch (IOException e) {
   1021                         Slog.w(TAG, "Exception reading jar: " + path, e);
   1022                     }
   1023                 }
   1024             }
   1025 
   1026             if (didDexOpt) {
   1027                 // If we had to do a dexopt of one of the previous
   1028                 // things, then something on the system has changed.
   1029                 // Consider this significant, and wipe away all other
   1030                 // existing dexopt files to ensure we don't leave any
   1031                 // dangling around.
   1032                 String[] files = mDalvikCacheDir.list();
   1033                 if (files != null) {
   1034                     for (int i=0; i<files.length; i++) {
   1035                         String fn = files[i];
   1036                         if (fn.startsWith("data@app@")
   1037                                 || fn.startsWith("data@app-private@")) {
   1038                             Slog.i(TAG, "Pruning dalvik file: " + fn);
   1039                             (new File(mDalvikCacheDir, fn)).delete();
   1040                         }
   1041                     }
   1042                 }
   1043             }
   1044 
   1045             // Find base frameworks (resource packages without code).
   1046             mFrameworkInstallObserver = new AppDirObserver(
   1047                 mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
   1048             mFrameworkInstallObserver.startWatching();
   1049             scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
   1050                     | PackageParser.PARSE_IS_SYSTEM_DIR,
   1051                     scanMode | SCAN_NO_DEX, 0);
   1052 
   1053             // Collect all system packages.
   1054             mSystemAppDir = new File(Environment.getRootDirectory(), "app");
   1055             mSystemInstallObserver = new AppDirObserver(
   1056                 mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
   1057             mSystemInstallObserver.startWatching();
   1058             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
   1059                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
   1060 
   1061             // Collect all vendor packages.
   1062             mVendorAppDir = new File("/vendor/app");
   1063             mVendorInstallObserver = new AppDirObserver(
   1064                 mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
   1065             mVendorInstallObserver.startWatching();
   1066             scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM
   1067                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
   1068 
   1069             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
   1070             mInstaller.moveFiles();
   1071 
   1072             // Prune any system packages that no longer exist.
   1073             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
   1074             if (!mOnlyCore) {
   1075                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
   1076                 while (psit.hasNext()) {
   1077                     PackageSetting ps = psit.next();
   1078 
   1079                     /*
   1080                      * If this is not a system app, it can't be a
   1081                      * disable system app.
   1082                      */
   1083                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   1084                         continue;
   1085                     }
   1086 
   1087                     /*
   1088                      * If the package is scanned, it's not erased.
   1089                      */
   1090                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
   1091                     if (scannedPkg != null) {
   1092                         /*
   1093                          * If the system app is both scanned and in the
   1094                          * disabled packages list, then it must have been
   1095                          * added via OTA. Remove it from the currently
   1096                          * scanned package so the previously user-installed
   1097                          * application can be scanned.
   1098                          */
   1099                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
   1100                             Slog.i(TAG, "Expecting better updatd system app for " + ps.name
   1101                                     + "; removing system app");
   1102                             removePackageLI(scannedPkg, true);
   1103                         }
   1104 
   1105                         continue;
   1106                     }
   1107 
   1108                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
   1109                         psit.remove();
   1110                         String msg = "System package " + ps.name
   1111                                 + " no longer exists; wiping its data";
   1112                         reportSettingsProblem(Log.WARN, msg);
   1113                         mInstaller.remove(ps.name, 0);
   1114                         sUserManager.removePackageForAllUsers(ps.name);
   1115                     } else {
   1116                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
   1117                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
   1118                             possiblyDeletedUpdatedSystemApps.add(ps.name);
   1119                         }
   1120                     }
   1121                 }
   1122             }
   1123 
   1124             mAppInstallDir = new File(dataDir, "app");
   1125             //look for any incomplete package installations
   1126             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
   1127             //clean up list
   1128             for(int i = 0; i < deletePkgsList.size(); i++) {
   1129                 //clean up here
   1130                 cleanupInstallFailedPackage(deletePkgsList.get(i));
   1131             }
   1132             //delete tmp files
   1133             deleteTempPackageFiles();
   1134 
   1135             if (!mOnlyCore) {
   1136                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
   1137                         SystemClock.uptimeMillis());
   1138                 mAppInstallObserver = new AppDirObserver(
   1139                     mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
   1140                 mAppInstallObserver.startWatching();
   1141                 scanDirLI(mAppInstallDir, 0, scanMode, 0);
   1142 
   1143                 mDrmAppInstallObserver = new AppDirObserver(
   1144                     mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
   1145                 mDrmAppInstallObserver.startWatching();
   1146                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
   1147                         scanMode, 0);
   1148 
   1149                 /**
   1150                  * Remove disable package settings for any updated system
   1151                  * apps that were removed via an OTA. If they're not a
   1152                  * previously-updated app, remove them completely.
   1153                  * Otherwise, just revoke their system-level permissions.
   1154                  */
   1155                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
   1156                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
   1157                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
   1158 
   1159                     String msg;
   1160                     if (deletedPkg == null) {
   1161                         msg = "Updated system package " + deletedAppName
   1162                                 + " no longer exists; wiping its data";
   1163 
   1164                         mInstaller.remove(deletedAppName, 0);
   1165                         sUserManager.removePackageForAllUsers(deletedAppName);
   1166                     } else {
   1167                         msg = "Updated system app + " + deletedAppName
   1168                                 + " no longer present; removing system privileges for "
   1169                                 + deletedAppName;
   1170 
   1171                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
   1172 
   1173                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
   1174                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
   1175                     }
   1176                     reportSettingsProblem(Log.WARN, msg);
   1177                 }
   1178             } else {
   1179                 mAppInstallObserver = null;
   1180                 mDrmAppInstallObserver = null;
   1181             }
   1182 
   1183             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
   1184                     SystemClock.uptimeMillis());
   1185             Slog.i(TAG, "Time to scan packages: "
   1186                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
   1187                     + " seconds");
   1188 
   1189             // If the platform SDK has changed since the last time we booted,
   1190             // we need to re-grant app permission to catch any new ones that
   1191             // appear.  This is really a hack, and means that apps can in some
   1192             // cases get permissions that the user didn't initially explicitly
   1193             // allow...  it would be nice to have some better way to handle
   1194             // this situation.
   1195             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
   1196                     != mSdkVersion;
   1197             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
   1198                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
   1199                     + "; regranting permissions for internal storage");
   1200             mSettings.mInternalSdkPlatform = mSdkVersion;
   1201 
   1202             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
   1203                     | (regrantPermissions
   1204                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
   1205                             : 0));
   1206 
   1207             // Verify that all of the preferred activity components actually
   1208             // exist.  It is possible for applications to be updated and at
   1209             // that point remove a previously declared activity component that
   1210             // had been set as a preferred activity.  We try to clean this up
   1211             // the next time we encounter that preferred activity, but it is
   1212             // possible for the user flow to never be able to return to that
   1213             // situation so here we do a sanity check to make sure we haven't
   1214             // left any junk around.
   1215             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
   1216             for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
   1217                 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
   1218                     removed.add(pa);
   1219                 }
   1220             }
   1221             for (int i=0; i<removed.size(); i++) {
   1222                 PreferredActivity pa = removed.get(i);
   1223                 Slog.w(TAG, "Removing dangling preferred activity: "
   1224                         + pa.mPref.mComponent);
   1225                 mSettings.mPreferredActivities.removeFilter(pa);
   1226             }
   1227 
   1228             // can downgrade to reader
   1229             mSettings.writeLPr();
   1230 
   1231             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
   1232                     SystemClock.uptimeMillis());
   1233 
   1234             // Now after opening every single application zip, make sure they
   1235             // are all flushed.  Not really needed, but keeps things nice and
   1236             // tidy.
   1237             Runtime.getRuntime().gc();
   1238 
   1239             mRequiredVerifierPackage = getRequiredVerifierLPr();
   1240         } // synchronized (mPackages)
   1241         } // synchronized (mInstallLock)
   1242     }
   1243 
   1244     public boolean isFirstBoot() {
   1245         return !mRestoredSettings;
   1246     }
   1247 
   1248     private String getRequiredVerifierLPr() {
   1249         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
   1250         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
   1251                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
   1252 
   1253         String requiredVerifier = null;
   1254 
   1255         final int N = receivers.size();
   1256         for (int i = 0; i < N; i++) {
   1257             final ResolveInfo info = receivers.get(i);
   1258 
   1259             if (info.activityInfo == null) {
   1260                 continue;
   1261             }
   1262 
   1263             final String packageName = info.activityInfo.packageName;
   1264 
   1265             final PackageSetting ps = mSettings.mPackages.get(packageName);
   1266             if (ps == null) {
   1267                 continue;
   1268             }
   1269 
   1270             if (!ps.grantedPermissions
   1271                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
   1272                 continue;
   1273             }
   1274 
   1275             if (requiredVerifier != null) {
   1276                 throw new RuntimeException("There can be only one required verifier");
   1277             }
   1278 
   1279             requiredVerifier = packageName;
   1280         }
   1281 
   1282         return requiredVerifier;
   1283     }
   1284 
   1285     @Override
   1286     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1287             throws RemoteException {
   1288         try {
   1289             return super.onTransact(code, data, reply, flags);
   1290         } catch (RuntimeException e) {
   1291             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
   1292                 Slog.e(TAG, "Package Manager Crash", e);
   1293             }
   1294             throw e;
   1295         }
   1296     }
   1297 
   1298     void cleanupInstallFailedPackage(PackageSetting ps) {
   1299         Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
   1300         int retCode = mInstaller.remove(ps.name, 0);
   1301         if (retCode < 0) {
   1302             Slog.w(TAG, "Couldn't remove app data directory for package: "
   1303                        + ps.name + ", retcode=" + retCode);
   1304         } else {
   1305             sUserManager.removePackageForAllUsers(ps.name);
   1306         }
   1307         if (ps.codePath != null) {
   1308             if (!ps.codePath.delete()) {
   1309                 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath);
   1310             }
   1311         }
   1312         if (ps.resourcePath != null) {
   1313             if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) {
   1314                 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath);
   1315             }
   1316         }
   1317         mSettings.removePackageLPw(ps.name);
   1318     }
   1319 
   1320     void readPermissions() {
   1321         // Read permissions from .../etc/permission directory.
   1322         File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
   1323         if (!libraryDir.exists() || !libraryDir.isDirectory()) {
   1324             Slog.w(TAG, "No directory " + libraryDir + ", skipping");
   1325             return;
   1326         }
   1327         if (!libraryDir.canRead()) {
   1328             Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
   1329             return;
   1330         }
   1331 
   1332         // Iterate over the files in the directory and scan .xml files
   1333         for (File f : libraryDir.listFiles()) {
   1334             // We'll read platform.xml last
   1335             if (f.getPath().endsWith("etc/permissions/platform.xml")) {
   1336                 continue;
   1337             }
   1338 
   1339             if (!f.getPath().endsWith(".xml")) {
   1340                 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
   1341                 continue;
   1342             }
   1343             if (!f.canRead()) {
   1344                 Slog.w(TAG, "Permissions library file " + f + " cannot be read");
   1345                 continue;
   1346             }
   1347 
   1348             readPermissionsFromXml(f);
   1349         }
   1350 
   1351         // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
   1352         final File permFile = new File(Environment.getRootDirectory(),
   1353                 "etc/permissions/platform.xml");
   1354         readPermissionsFromXml(permFile);
   1355     }
   1356 
   1357     private void readPermissionsFromXml(File permFile) {
   1358         FileReader permReader = null;
   1359         try {
   1360             permReader = new FileReader(permFile);
   1361         } catch (FileNotFoundException e) {
   1362             Slog.w(TAG, "Couldn't find or open permissions file " + permFile);
   1363             return;
   1364         }
   1365 
   1366         try {
   1367             XmlPullParser parser = Xml.newPullParser();
   1368             parser.setInput(permReader);
   1369 
   1370             XmlUtils.beginDocument(parser, "permissions");
   1371 
   1372             while (true) {
   1373                 XmlUtils.nextElement(parser);
   1374                 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) {
   1375                     break;
   1376                 }
   1377 
   1378                 String name = parser.getName();
   1379                 if ("group".equals(name)) {
   1380                     String gidStr = parser.getAttributeValue(null, "gid");
   1381                     if (gidStr != null) {
   1382                         int gid = Integer.parseInt(gidStr);
   1383                         mGlobalGids = appendInt(mGlobalGids, gid);
   1384                     } else {
   1385                         Slog.w(TAG, "<group> without gid at "
   1386                                 + parser.getPositionDescription());
   1387                     }
   1388 
   1389                     XmlUtils.skipCurrentTag(parser);
   1390                     continue;
   1391                 } else if ("permission".equals(name)) {
   1392                     String perm = parser.getAttributeValue(null, "name");
   1393                     if (perm == null) {
   1394                         Slog.w(TAG, "<permission> without name at "
   1395                                 + parser.getPositionDescription());
   1396                         XmlUtils.skipCurrentTag(parser);
   1397                         continue;
   1398                     }
   1399                     perm = perm.intern();
   1400                     readPermission(parser, perm);
   1401 
   1402                 } else if ("assign-permission".equals(name)) {
   1403                     String perm = parser.getAttributeValue(null, "name");
   1404                     if (perm == null) {
   1405                         Slog.w(TAG, "<assign-permission> without name at "
   1406                                 + parser.getPositionDescription());
   1407                         XmlUtils.skipCurrentTag(parser);
   1408                         continue;
   1409                     }
   1410                     String uidStr = parser.getAttributeValue(null, "uid");
   1411                     if (uidStr == null) {
   1412                         Slog.w(TAG, "<assign-permission> without uid at "
   1413                                 + parser.getPositionDescription());
   1414                         XmlUtils.skipCurrentTag(parser);
   1415                         continue;
   1416                     }
   1417                     int uid = Process.getUidForName(uidStr);
   1418                     if (uid < 0) {
   1419                         Slog.w(TAG, "<assign-permission> with unknown uid \""
   1420                                 + uidStr + "\" at "
   1421                                 + parser.getPositionDescription());
   1422                         XmlUtils.skipCurrentTag(parser);
   1423                         continue;
   1424                     }
   1425                     perm = perm.intern();
   1426                     HashSet<String> perms = mSystemPermissions.get(uid);
   1427                     if (perms == null) {
   1428                         perms = new HashSet<String>();
   1429                         mSystemPermissions.put(uid, perms);
   1430                     }
   1431                     perms.add(perm);
   1432                     XmlUtils.skipCurrentTag(parser);
   1433 
   1434                 } else if ("library".equals(name)) {
   1435                     String lname = parser.getAttributeValue(null, "name");
   1436                     String lfile = parser.getAttributeValue(null, "file");
   1437                     if (lname == null) {
   1438                         Slog.w(TAG, "<library> without name at "
   1439                                 + parser.getPositionDescription());
   1440                     } else if (lfile == null) {
   1441                         Slog.w(TAG, "<library> without file at "
   1442                                 + parser.getPositionDescription());
   1443                     } else {
   1444                         //Log.i(TAG, "Got library " + lname + " in " + lfile);
   1445                         mSharedLibraries.put(lname, lfile);
   1446                     }
   1447                     XmlUtils.skipCurrentTag(parser);
   1448                     continue;
   1449 
   1450                 } else if ("feature".equals(name)) {
   1451                     String fname = parser.getAttributeValue(null, "name");
   1452                     if (fname == null) {
   1453                         Slog.w(TAG, "<feature> without name at "
   1454                                 + parser.getPositionDescription());
   1455                     } else {
   1456                         //Log.i(TAG, "Got feature " + fname);
   1457                         FeatureInfo fi = new FeatureInfo();
   1458                         fi.name = fname;
   1459                         mAvailableFeatures.put(fname, fi);
   1460                     }
   1461                     XmlUtils.skipCurrentTag(parser);
   1462                     continue;
   1463 
   1464                 } else {
   1465                     XmlUtils.skipCurrentTag(parser);
   1466                     continue;
   1467                 }
   1468 
   1469             }
   1470             permReader.close();
   1471         } catch (XmlPullParserException e) {
   1472             Slog.w(TAG, "Got execption parsing permissions.", e);
   1473         } catch (IOException e) {
   1474             Slog.w(TAG, "Got execption parsing permissions.", e);
   1475         }
   1476     }
   1477 
   1478     void readPermission(XmlPullParser parser, String name)
   1479             throws IOException, XmlPullParserException {
   1480 
   1481         name = name.intern();
   1482 
   1483         BasePermission bp = mSettings.mPermissions.get(name);
   1484         if (bp == null) {
   1485             bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN);
   1486             mSettings.mPermissions.put(name, bp);
   1487         }
   1488         int outerDepth = parser.getDepth();
   1489         int type;
   1490         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
   1491                && (type != XmlPullParser.END_TAG
   1492                        || parser.getDepth() > outerDepth)) {
   1493             if (type == XmlPullParser.END_TAG
   1494                     || type == XmlPullParser.TEXT) {
   1495                 continue;
   1496             }
   1497 
   1498             String tagName = parser.getName();
   1499             if ("group".equals(tagName)) {
   1500                 String gidStr = parser.getAttributeValue(null, "gid");
   1501                 if (gidStr != null) {
   1502                     int gid = Process.getGidForName(gidStr);
   1503                     bp.gids = appendInt(bp.gids, gid);
   1504                 } else {
   1505                     Slog.w(TAG, "<group> without gid at "
   1506                             + parser.getPositionDescription());
   1507                 }
   1508             }
   1509             XmlUtils.skipCurrentTag(parser);
   1510         }
   1511     }
   1512 
   1513     static int[] appendInts(int[] cur, int[] add) {
   1514         if (add == null) return cur;
   1515         if (cur == null) return add;
   1516         final int N = add.length;
   1517         for (int i=0; i<N; i++) {
   1518             cur = appendInt(cur, add[i]);
   1519         }
   1520         return cur;
   1521     }
   1522 
   1523     static int[] removeInts(int[] cur, int[] rem) {
   1524         if (rem == null) return cur;
   1525         if (cur == null) return cur;
   1526         final int N = rem.length;
   1527         for (int i=0; i<N; i++) {
   1528             cur = removeInt(cur, rem[i]);
   1529         }
   1530         return cur;
   1531     }
   1532 
   1533     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
   1534         if (!sUserManager.exists(userId)) return null;
   1535         PackageInfo pi;
   1536         if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   1537             // The package has been uninstalled but has retained data and resources.
   1538             pi = PackageParser.generatePackageInfo(p, null, flags, 0, 0, null, false, 0, userId);
   1539         } else {
   1540             final PackageSetting ps = (PackageSetting) p.mExtras;
   1541             if (ps == null) {
   1542                 return null;
   1543             }
   1544             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   1545             pi = PackageParser.generatePackageInfo(p, gp.gids, flags,
   1546                     ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
   1547                     ps.getStopped(userId), ps.getEnabled(userId), userId);
   1548             pi.applicationInfo.enabledSetting = ps.getEnabled(userId);
   1549             pi.applicationInfo.enabled =
   1550                     pi.applicationInfo.enabledSetting == COMPONENT_ENABLED_STATE_DEFAULT
   1551                     || pi.applicationInfo.enabledSetting == COMPONENT_ENABLED_STATE_ENABLED;
   1552         }
   1553         return pi;
   1554     }
   1555 
   1556     @Override
   1557     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
   1558         if (!sUserManager.exists(userId)) return null;
   1559         // reader
   1560         synchronized (mPackages) {
   1561             PackageParser.Package p = mPackages.get(packageName);
   1562             if (DEBUG_PACKAGE_INFO)
   1563                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
   1564             if (p != null) {
   1565                 return generatePackageInfo(p, flags, userId);
   1566             }
   1567             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   1568                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
   1569             }
   1570         }
   1571         return null;
   1572     }
   1573 
   1574     public String[] currentToCanonicalPackageNames(String[] names) {
   1575         String[] out = new String[names.length];
   1576         // reader
   1577         synchronized (mPackages) {
   1578             for (int i=names.length-1; i>=0; i--) {
   1579                 PackageSetting ps = mSettings.mPackages.get(names[i]);
   1580                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
   1581             }
   1582         }
   1583         return out;
   1584     }
   1585 
   1586     public String[] canonicalToCurrentPackageNames(String[] names) {
   1587         String[] out = new String[names.length];
   1588         // reader
   1589         synchronized (mPackages) {
   1590             for (int i=names.length-1; i>=0; i--) {
   1591                 String cur = mSettings.mRenamedPackages.get(names[i]);
   1592                 out[i] = cur != null ? cur : names[i];
   1593             }
   1594         }
   1595         return out;
   1596     }
   1597 
   1598     @Override
   1599     public int getPackageUid(String packageName, int userId) {
   1600         if (!sUserManager.exists(userId)) return -1;
   1601         // reader
   1602         synchronized (mPackages) {
   1603             PackageParser.Package p = mPackages.get(packageName);
   1604             if(p != null) {
   1605                 return UserId.getUid(userId, p.applicationInfo.uid);
   1606             }
   1607             PackageSetting ps = mSettings.mPackages.get(packageName);
   1608             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
   1609                 return -1;
   1610             }
   1611             p = ps.pkg;
   1612             return p != null ? UserId.getUid(userId, p.applicationInfo.uid) : -1;
   1613         }
   1614     }
   1615 
   1616     public int[] getPackageGids(String packageName) {
   1617         // reader
   1618         synchronized (mPackages) {
   1619             PackageParser.Package p = mPackages.get(packageName);
   1620             if (DEBUG_PACKAGE_INFO)
   1621                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
   1622             if (p != null) {
   1623                 final PackageSetting ps = (PackageSetting)p.mExtras;
   1624                 final SharedUserSetting suid = ps.sharedUser;
   1625                 int[] gids = suid != null ? suid.gids : ps.gids;
   1626 
   1627                 // include GIDs for any unenforced permissions
   1628                 if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE)) {
   1629                     final BasePermission basePerm = mSettings.mPermissions.get(
   1630                             READ_EXTERNAL_STORAGE);
   1631                     gids = appendInts(gids, basePerm.gids);
   1632                 }
   1633 
   1634                 return gids;
   1635             }
   1636         }
   1637         // stupid thing to indicate an error.
   1638         return new int[0];
   1639     }
   1640 
   1641     static final PermissionInfo generatePermissionInfo(
   1642             BasePermission bp, int flags) {
   1643         if (bp.perm != null) {
   1644             return PackageParser.generatePermissionInfo(bp.perm, flags);
   1645         }
   1646         PermissionInfo pi = new PermissionInfo();
   1647         pi.name = bp.name;
   1648         pi.packageName = bp.sourcePackage;
   1649         pi.nonLocalizedLabel = bp.name;
   1650         pi.protectionLevel = bp.protectionLevel;
   1651         return pi;
   1652     }
   1653 
   1654     public PermissionInfo getPermissionInfo(String name, int flags) {
   1655         // reader
   1656         synchronized (mPackages) {
   1657             final BasePermission p = mSettings.mPermissions.get(name);
   1658             if (p != null) {
   1659                 return generatePermissionInfo(p, flags);
   1660             }
   1661             return null;
   1662         }
   1663     }
   1664 
   1665     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
   1666         // reader
   1667         synchronized (mPackages) {
   1668             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
   1669             for (BasePermission p : mSettings.mPermissions.values()) {
   1670                 if (group == null) {
   1671                     if (p.perm == null || p.perm.info.group == null) {
   1672                         out.add(generatePermissionInfo(p, flags));
   1673                     }
   1674                 } else {
   1675                     if (p.perm != null && group.equals(p.perm.info.group)) {
   1676                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
   1677                     }
   1678                 }
   1679             }
   1680 
   1681             if (out.size() > 0) {
   1682                 return out;
   1683             }
   1684             return mPermissionGroups.containsKey(group) ? out : null;
   1685         }
   1686     }
   1687 
   1688     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
   1689         // reader
   1690         synchronized (mPackages) {
   1691             return PackageParser.generatePermissionGroupInfo(
   1692                     mPermissionGroups.get(name), flags);
   1693         }
   1694     }
   1695 
   1696     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
   1697         // reader
   1698         synchronized (mPackages) {
   1699             final int N = mPermissionGroups.size();
   1700             ArrayList<PermissionGroupInfo> out
   1701                     = new ArrayList<PermissionGroupInfo>(N);
   1702             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
   1703                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
   1704             }
   1705             return out;
   1706         }
   1707     }
   1708 
   1709     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
   1710             int userId) {
   1711         if (!sUserManager.exists(userId)) return null;
   1712         PackageSetting ps = mSettings.mPackages.get(packageName);
   1713         if (ps != null) {
   1714             if (ps.pkg == null) {
   1715                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, flags, userId);
   1716                 if (pInfo != null) {
   1717                     return pInfo.applicationInfo;
   1718                 }
   1719                 return null;
   1720             }
   1721             return PackageParser.generateApplicationInfo(ps.pkg, flags, ps.getStopped(userId),
   1722                     ps.getEnabled(userId), userId);
   1723         }
   1724         return null;
   1725     }
   1726 
   1727     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
   1728             int userId) {
   1729         if (!sUserManager.exists(userId)) return null;
   1730         PackageSetting ps = mSettings.mPackages.get(packageName);
   1731         if (ps != null) {
   1732             PackageParser.Package pkg = new PackageParser.Package(packageName);
   1733             if (ps.pkg == null) {
   1734                 ps.pkg = new PackageParser.Package(packageName);
   1735                 ps.pkg.applicationInfo.packageName = packageName;
   1736                 ps.pkg.applicationInfo.flags = ps.pkgFlags;
   1737                 ps.pkg.applicationInfo.publicSourceDir = ps.resourcePathString;
   1738                 ps.pkg.applicationInfo.sourceDir = ps.codePathString;
   1739                 ps.pkg.applicationInfo.dataDir =
   1740                         getDataPathForPackage(ps.pkg.packageName, 0).getPath();
   1741                 ps.pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
   1742             }
   1743             // ps.pkg.mSetEnabled = ps.getEnabled(userId);
   1744             // ps.pkg.mSetStopped = ps.getStopped(userId);
   1745             return generatePackageInfo(ps.pkg, flags, userId);
   1746         }
   1747         return null;
   1748     }
   1749 
   1750     @Override
   1751     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
   1752         if (!sUserManager.exists(userId)) return null;
   1753         // writer
   1754         synchronized (mPackages) {
   1755             PackageParser.Package p = mPackages.get(packageName);
   1756             if (DEBUG_PACKAGE_INFO) Log.v(
   1757                     TAG, "getApplicationInfo " + packageName
   1758                     + ": " + p);
   1759             if (p != null) {
   1760                 PackageSetting ps = mSettings.mPackages.get(packageName);
   1761                 if (ps == null) return null;
   1762                 // Note: isEnabledLP() does not apply here - always return info
   1763                 return PackageParser.generateApplicationInfo(p, flags, ps.getStopped(userId),
   1764                         ps.getEnabled(userId));
   1765             }
   1766             if ("android".equals(packageName)||"system".equals(packageName)) {
   1767                 return mAndroidApplication;
   1768             }
   1769             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   1770                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
   1771             }
   1772         }
   1773         return null;
   1774     }
   1775 
   1776 
   1777     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
   1778         mContext.enforceCallingOrSelfPermission(
   1779                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   1780         // Queue up an async operation since clearing cache may take a little while.
   1781         mHandler.post(new Runnable() {
   1782             public void run() {
   1783                 mHandler.removeCallbacks(this);
   1784                 int retCode = -1;
   1785                 retCode = mInstaller.freeCache(freeStorageSize);
   1786                 if (retCode < 0) {
   1787                     Slog.w(TAG, "Couldn't clear application caches");
   1788                 }
   1789                 if (observer != null) {
   1790                     try {
   1791                         observer.onRemoveCompleted(null, (retCode >= 0));
   1792                     } catch (RemoteException e) {
   1793                         Slog.w(TAG, "RemoveException when invoking call back");
   1794                     }
   1795                 }
   1796             }
   1797         });
   1798     }
   1799 
   1800     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
   1801         mContext.enforceCallingOrSelfPermission(
   1802                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   1803         // Queue up an async operation since clearing cache may take a little while.
   1804         mHandler.post(new Runnable() {
   1805             public void run() {
   1806                 mHandler.removeCallbacks(this);
   1807                 int retCode = -1;
   1808                 retCode = mInstaller.freeCache(freeStorageSize);
   1809                 if (retCode < 0) {
   1810                     Slog.w(TAG, "Couldn't clear application caches");
   1811                 }
   1812                 if(pi != null) {
   1813                     try {
   1814                         // Callback via pending intent
   1815                         int code = (retCode >= 0) ? 1 : 0;
   1816                         pi.sendIntent(null, code, null,
   1817                                 null, null);
   1818                     } catch (SendIntentException e1) {
   1819                         Slog.i(TAG, "Failed to send pending intent");
   1820                     }
   1821                 }
   1822             }
   1823         });
   1824     }
   1825 
   1826     @Override
   1827     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
   1828         if (!sUserManager.exists(userId)) return null;
   1829         synchronized (mPackages) {
   1830             PackageParser.Activity a = mActivities.mActivities.get(component);
   1831 
   1832             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
   1833             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
   1834                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   1835                 if (ps == null) return null;
   1836                 return PackageParser.generateActivityInfo(a, flags, ps.getStopped(userId),
   1837                         ps.getEnabled(userId), userId);
   1838             }
   1839             if (mResolveComponentName.equals(component)) {
   1840                 return mResolveActivity;
   1841             }
   1842         }
   1843         return null;
   1844     }
   1845 
   1846     @Override
   1847     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
   1848         if (!sUserManager.exists(userId)) return null;
   1849         synchronized (mPackages) {
   1850             PackageParser.Activity a = mReceivers.mActivities.get(component);
   1851             if (DEBUG_PACKAGE_INFO) Log.v(
   1852                 TAG, "getReceiverInfo " + component + ": " + a);
   1853             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
   1854                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   1855                 if (ps == null) return null;
   1856                 return PackageParser.generateActivityInfo(a, flags, ps.getStopped(userId),
   1857                         ps.getEnabled(userId), userId);
   1858             }
   1859         }
   1860         return null;
   1861     }
   1862 
   1863     @Override
   1864     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
   1865         if (!sUserManager.exists(userId)) return null;
   1866         synchronized (mPackages) {
   1867             PackageParser.Service s = mServices.mServices.get(component);
   1868             if (DEBUG_PACKAGE_INFO) Log.v(
   1869                 TAG, "getServiceInfo " + component + ": " + s);
   1870             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
   1871                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   1872                 if (ps == null) return null;
   1873                 return PackageParser.generateServiceInfo(s, flags, ps.getStopped(userId),
   1874                         ps.getEnabled(userId), userId);
   1875             }
   1876         }
   1877         return null;
   1878     }
   1879 
   1880     @Override
   1881     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
   1882         if (!sUserManager.exists(userId)) return null;
   1883         synchronized (mPackages) {
   1884             PackageParser.Provider p = mProvidersByComponent.get(component);
   1885             if (DEBUG_PACKAGE_INFO) Log.v(
   1886                 TAG, "getProviderInfo " + component + ": " + p);
   1887             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
   1888                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   1889                 if (ps == null) return null;
   1890                 return PackageParser.generateProviderInfo(p, flags, ps.getStopped(userId),
   1891                         ps.getEnabled(userId), userId);
   1892             }
   1893         }
   1894         return null;
   1895     }
   1896 
   1897     public String[] getSystemSharedLibraryNames() {
   1898         Set<String> libSet;
   1899         synchronized (mPackages) {
   1900             libSet = mSharedLibraries.keySet();
   1901             int size = libSet.size();
   1902             if (size > 0) {
   1903                 String[] libs = new String[size];
   1904                 libSet.toArray(libs);
   1905                 return libs;
   1906             }
   1907         }
   1908         return null;
   1909     }
   1910 
   1911     public FeatureInfo[] getSystemAvailableFeatures() {
   1912         Collection<FeatureInfo> featSet;
   1913         synchronized (mPackages) {
   1914             featSet = mAvailableFeatures.values();
   1915             int size = featSet.size();
   1916             if (size > 0) {
   1917                 FeatureInfo[] features = new FeatureInfo[size+1];
   1918                 featSet.toArray(features);
   1919                 FeatureInfo fi = new FeatureInfo();
   1920                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
   1921                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
   1922                 features[size] = fi;
   1923                 return features;
   1924             }
   1925         }
   1926         return null;
   1927     }
   1928 
   1929     public boolean hasSystemFeature(String name) {
   1930         synchronized (mPackages) {
   1931             return mAvailableFeatures.containsKey(name);
   1932         }
   1933     }
   1934 
   1935     private void checkValidCaller(int uid, int userId) {
   1936         if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
   1937             return;
   1938 
   1939         throw new SecurityException("Caller uid=" + uid
   1940                 + " is not privileged to communicate with user=" + userId);
   1941     }
   1942 
   1943     public int checkPermission(String permName, String pkgName) {
   1944         synchronized (mPackages) {
   1945             PackageParser.Package p = mPackages.get(pkgName);
   1946             if (p != null && p.mExtras != null) {
   1947                 PackageSetting ps = (PackageSetting)p.mExtras;
   1948                 if (ps.sharedUser != null) {
   1949                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
   1950                         return PackageManager.PERMISSION_GRANTED;
   1951                     }
   1952                 } else if (ps.grantedPermissions.contains(permName)) {
   1953                     return PackageManager.PERMISSION_GRANTED;
   1954                 }
   1955             }
   1956             if (!isPermissionEnforcedLocked(permName)) {
   1957                 return PackageManager.PERMISSION_GRANTED;
   1958             }
   1959         }
   1960         return PackageManager.PERMISSION_DENIED;
   1961     }
   1962 
   1963     public int checkUidPermission(String permName, int uid) {
   1964         synchronized (mPackages) {
   1965             Object obj = mSettings.getUserIdLPr(UserId.getAppId(uid));
   1966             if (obj != null) {
   1967                 GrantedPermissions gp = (GrantedPermissions)obj;
   1968                 if (gp.grantedPermissions.contains(permName)) {
   1969                     return PackageManager.PERMISSION_GRANTED;
   1970                 }
   1971             } else {
   1972                 HashSet<String> perms = mSystemPermissions.get(uid);
   1973                 if (perms != null && perms.contains(permName)) {
   1974                     return PackageManager.PERMISSION_GRANTED;
   1975                 }
   1976             }
   1977             if (!isPermissionEnforcedLocked(permName)) {
   1978                 return PackageManager.PERMISSION_GRANTED;
   1979             }
   1980         }
   1981         return PackageManager.PERMISSION_DENIED;
   1982     }
   1983 
   1984     private BasePermission findPermissionTreeLP(String permName) {
   1985         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
   1986             if (permName.startsWith(bp.name) &&
   1987                     permName.length() > bp.name.length() &&
   1988                     permName.charAt(bp.name.length()) == '.') {
   1989                 return bp;
   1990             }
   1991         }
   1992         return null;
   1993     }
   1994 
   1995     private BasePermission checkPermissionTreeLP(String permName) {
   1996         if (permName != null) {
   1997             BasePermission bp = findPermissionTreeLP(permName);
   1998             if (bp != null) {
   1999                 if (bp.uid == UserId.getAppId(Binder.getCallingUid())) {
   2000                     return bp;
   2001                 }
   2002                 throw new SecurityException("Calling uid "
   2003                         + Binder.getCallingUid()
   2004                         + " is not allowed to add to permission tree "
   2005                         + bp.name + " owned by uid " + bp.uid);
   2006             }
   2007         }
   2008         throw new SecurityException("No permission tree found for " + permName);
   2009     }
   2010 
   2011     static boolean compareStrings(CharSequence s1, CharSequence s2) {
   2012         if (s1 == null) {
   2013             return s2 == null;
   2014         }
   2015         if (s2 == null) {
   2016             return false;
   2017         }
   2018         if (s1.getClass() != s2.getClass()) {
   2019             return false;
   2020         }
   2021         return s1.equals(s2);
   2022     }
   2023 
   2024     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
   2025         if (pi1.icon != pi2.icon) return false;
   2026         if (pi1.logo != pi2.logo) return false;
   2027         if (pi1.protectionLevel != pi2.protectionLevel) return false;
   2028         if (!compareStrings(pi1.name, pi2.name)) return false;
   2029         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
   2030         // We'll take care of setting this one.
   2031         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
   2032         // These are not currently stored in settings.
   2033         //if (!compareStrings(pi1.group, pi2.group)) return false;
   2034         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
   2035         //if (pi1.labelRes != pi2.labelRes) return false;
   2036         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
   2037         return true;
   2038     }
   2039 
   2040     boolean addPermissionLocked(PermissionInfo info, boolean async) {
   2041         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
   2042             throw new SecurityException("Label must be specified in permission");
   2043         }
   2044         BasePermission tree = checkPermissionTreeLP(info.name);
   2045         BasePermission bp = mSettings.mPermissions.get(info.name);
   2046         boolean added = bp == null;
   2047         boolean changed = true;
   2048         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
   2049         if (added) {
   2050             bp = new BasePermission(info.name, tree.sourcePackage,
   2051                     BasePermission.TYPE_DYNAMIC);
   2052         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
   2053             throw new SecurityException(
   2054                     "Not allowed to modify non-dynamic permission "
   2055                     + info.name);
   2056         } else {
   2057             if (bp.protectionLevel == fixedLevel
   2058                     && bp.perm.owner.equals(tree.perm.owner)
   2059                     && bp.uid == tree.uid
   2060                     && comparePermissionInfos(bp.perm.info, info)) {
   2061                 changed = false;
   2062             }
   2063         }
   2064         bp.protectionLevel = fixedLevel;
   2065         info = new PermissionInfo(info);
   2066         info.protectionLevel = fixedLevel;
   2067         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
   2068         bp.perm.info.packageName = tree.perm.info.packageName;
   2069         bp.uid = tree.uid;
   2070         if (added) {
   2071             mSettings.mPermissions.put(info.name, bp);
   2072         }
   2073         if (changed) {
   2074             if (!async) {
   2075                 mSettings.writeLPr();
   2076             } else {
   2077                 scheduleWriteSettingsLocked();
   2078             }
   2079         }
   2080         return added;
   2081     }
   2082 
   2083     public boolean addPermission(PermissionInfo info) {
   2084         synchronized (mPackages) {
   2085             return addPermissionLocked(info, false);
   2086         }
   2087     }
   2088 
   2089     public boolean addPermissionAsync(PermissionInfo info) {
   2090         synchronized (mPackages) {
   2091             return addPermissionLocked(info, true);
   2092         }
   2093     }
   2094 
   2095     public void removePermission(String name) {
   2096         synchronized (mPackages) {
   2097             checkPermissionTreeLP(name);
   2098             BasePermission bp = mSettings.mPermissions.get(name);
   2099             if (bp != null) {
   2100                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
   2101                     throw new SecurityException(
   2102                             "Not allowed to modify non-dynamic permission "
   2103                             + name);
   2104                 }
   2105                 mSettings.mPermissions.remove(name);
   2106                 mSettings.writeLPr();
   2107             }
   2108         }
   2109     }
   2110 
   2111     public void grantPermission(String packageName, String permissionName) {
   2112         mContext.enforceCallingOrSelfPermission(
   2113                 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
   2114         synchronized (mPackages) {
   2115             final PackageParser.Package pkg = mPackages.get(packageName);
   2116             if (pkg == null) {
   2117                 throw new IllegalArgumentException("Unknown package: " + packageName);
   2118             }
   2119             final BasePermission bp = mSettings.mPermissions.get(permissionName);
   2120             if (bp == null) {
   2121                 throw new IllegalArgumentException("Unknown permission: " + packageName);
   2122             }
   2123             if (!pkg.requestedPermissions.contains(permissionName)) {
   2124                 throw new SecurityException("Package " + packageName
   2125                         + " has not requested permission " + permissionName);
   2126             }
   2127             if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
   2128                 throw new SecurityException("Permission " + permissionName
   2129                         + " is not a development permission");
   2130             }
   2131             final PackageSetting ps = (PackageSetting) pkg.mExtras;
   2132             if (ps == null) {
   2133                 return;
   2134             }
   2135             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   2136             if (gp.grantedPermissions.add(permissionName)) {
   2137                 if (ps.haveGids) {
   2138                     gp.gids = appendInts(gp.gids, bp.gids);
   2139                 }
   2140                 mSettings.writeLPr();
   2141             }
   2142         }
   2143     }
   2144 
   2145     public void revokePermission(String packageName, String permissionName) {
   2146         synchronized (mPackages) {
   2147             final PackageParser.Package pkg = mPackages.get(packageName);
   2148             if (pkg == null) {
   2149                 throw new IllegalArgumentException("Unknown package: " + packageName);
   2150             }
   2151             if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
   2152                 mContext.enforceCallingOrSelfPermission(
   2153                         android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
   2154             }
   2155             final BasePermission bp = mSettings.mPermissions.get(permissionName);
   2156             if (bp == null) {
   2157                 throw new IllegalArgumentException("Unknown permission: " + packageName);
   2158             }
   2159             if (!pkg.requestedPermissions.contains(permissionName)) {
   2160                 throw new SecurityException("Package " + packageName
   2161                         + " has not requested permission " + permissionName);
   2162             }
   2163             if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) == 0) {
   2164                 throw new SecurityException("Permission " + permissionName
   2165                         + " is not a development permission");
   2166             }
   2167             final PackageSetting ps = (PackageSetting) pkg.mExtras;
   2168             if (ps == null) {
   2169                 return;
   2170             }
   2171             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   2172             if (gp.grantedPermissions.remove(permissionName)) {
   2173                 gp.grantedPermissions.remove(permissionName);
   2174                 if (ps.haveGids) {
   2175                     gp.gids = removeInts(gp.gids, bp.gids);
   2176                 }
   2177                 mSettings.writeLPr();
   2178             }
   2179         }
   2180     }
   2181 
   2182     public boolean isProtectedBroadcast(String actionName) {
   2183         synchronized (mPackages) {
   2184             return mProtectedBroadcasts.contains(actionName);
   2185         }
   2186     }
   2187 
   2188     public int checkSignatures(String pkg1, String pkg2) {
   2189         synchronized (mPackages) {
   2190             final PackageParser.Package p1 = mPackages.get(pkg1);
   2191             final PackageParser.Package p2 = mPackages.get(pkg2);
   2192             if (p1 == null || p1.mExtras == null
   2193                     || p2 == null || p2.mExtras == null) {
   2194                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2195             }
   2196             return compareSignatures(p1.mSignatures, p2.mSignatures);
   2197         }
   2198     }
   2199 
   2200     public int checkUidSignatures(int uid1, int uid2) {
   2201         // Map to base uids.
   2202         uid1 = UserId.getAppId(uid1);
   2203         uid2 = UserId.getAppId(uid2);
   2204         // reader
   2205         synchronized (mPackages) {
   2206             Signature[] s1;
   2207             Signature[] s2;
   2208             Object obj = mSettings.getUserIdLPr(uid1);
   2209             if (obj != null) {
   2210                 if (obj instanceof SharedUserSetting) {
   2211                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
   2212                 } else if (obj instanceof PackageSetting) {
   2213                     s1 = ((PackageSetting)obj).signatures.mSignatures;
   2214                 } else {
   2215                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2216                 }
   2217             } else {
   2218                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2219             }
   2220             obj = mSettings.getUserIdLPr(uid2);
   2221             if (obj != null) {
   2222                 if (obj instanceof SharedUserSetting) {
   2223                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
   2224                 } else if (obj instanceof PackageSetting) {
   2225                     s2 = ((PackageSetting)obj).signatures.mSignatures;
   2226                 } else {
   2227                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2228                 }
   2229             } else {
   2230                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2231             }
   2232             return compareSignatures(s1, s2);
   2233         }
   2234     }
   2235 
   2236     static int compareSignatures(Signature[] s1, Signature[] s2) {
   2237         if (s1 == null) {
   2238             return s2 == null
   2239                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
   2240                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
   2241         }
   2242         if (s2 == null) {
   2243             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
   2244         }
   2245         HashSet<Signature> set1 = new HashSet<Signature>();
   2246         for (Signature sig : s1) {
   2247             set1.add(sig);
   2248         }
   2249         HashSet<Signature> set2 = new HashSet<Signature>();
   2250         for (Signature sig : s2) {
   2251             set2.add(sig);
   2252         }
   2253         // Make sure s2 contains all signatures in s1.
   2254         if (set1.equals(set2)) {
   2255             return PackageManager.SIGNATURE_MATCH;
   2256         }
   2257         return PackageManager.SIGNATURE_NO_MATCH;
   2258     }
   2259 
   2260     public String[] getPackagesForUid(int uid) {
   2261         uid = UserId.getAppId(uid);
   2262         // reader
   2263         synchronized (mPackages) {
   2264             Object obj = mSettings.getUserIdLPr(uid);
   2265             if (obj instanceof SharedUserSetting) {
   2266                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2267                 final int N = sus.packages.size();
   2268                 final String[] res = new String[N];
   2269                 final Iterator<PackageSetting> it = sus.packages.iterator();
   2270                 int i = 0;
   2271                 while (it.hasNext()) {
   2272                     res[i++] = it.next().name;
   2273                 }
   2274                 return res;
   2275             } else if (obj instanceof PackageSetting) {
   2276                 final PackageSetting ps = (PackageSetting) obj;
   2277                 return new String[] { ps.name };
   2278             }
   2279         }
   2280         return null;
   2281     }
   2282 
   2283     public String getNameForUid(int uid) {
   2284         // reader
   2285         synchronized (mPackages) {
   2286             Object obj = mSettings.getUserIdLPr(UserId.getAppId(uid));
   2287             if (obj instanceof SharedUserSetting) {
   2288                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2289                 return sus.name + ":" + sus.userId;
   2290             } else if (obj instanceof PackageSetting) {
   2291                 final PackageSetting ps = (PackageSetting) obj;
   2292                 return ps.name;
   2293             }
   2294         }
   2295         return null;
   2296     }
   2297 
   2298     public int getUidForSharedUser(String sharedUserName) {
   2299         if(sharedUserName == null) {
   2300             return -1;
   2301         }
   2302         // reader
   2303         synchronized (mPackages) {
   2304             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
   2305             if (suid == null) {
   2306                 return -1;
   2307             }
   2308             return suid.userId;
   2309         }
   2310     }
   2311 
   2312     @Override
   2313     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
   2314             int flags, int userId) {
   2315         if (!sUserManager.exists(userId)) return null;
   2316         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
   2317         return chooseBestActivity(intent, resolvedType, flags, query, userId);
   2318     }
   2319 
   2320     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
   2321             int flags, List<ResolveInfo> query, int userId) {
   2322         if (query != null) {
   2323             final int N = query.size();
   2324             if (N == 1) {
   2325                 return query.get(0);
   2326             } else if (N > 1) {
   2327                 // If there is more than one activity with the same priority,
   2328                 // then let the user decide between them.
   2329                 ResolveInfo r0 = query.get(0);
   2330                 ResolveInfo r1 = query.get(1);
   2331                 if (DEBUG_INTENT_MATCHING) {
   2332                     Log.d(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
   2333                             + r1.activityInfo.name + "=" + r1.priority);
   2334                 }
   2335                 // If the first activity has a higher priority, or a different
   2336                 // default, then it is always desireable to pick it.
   2337                 if (r0.priority != r1.priority
   2338                         || r0.preferredOrder != r1.preferredOrder
   2339                         || r0.isDefault != r1.isDefault) {
   2340                     return query.get(0);
   2341                 }
   2342                 // If we have saved a preference for a preferred activity for
   2343                 // this Intent, use that.
   2344                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
   2345                         flags, query, r0.priority, userId);
   2346                 if (ri != null) {
   2347                     return ri;
   2348                 }
   2349                 return mResolveInfo;
   2350             }
   2351         }
   2352         return null;
   2353     }
   2354 
   2355     ResolveInfo findPreferredActivity(Intent intent, String resolvedType,
   2356             int flags, List<ResolveInfo> query, int priority, int userId) {
   2357         if (!sUserManager.exists(userId)) return null;
   2358         // writer
   2359         synchronized (mPackages) {
   2360             if (intent.getSelector() != null) {
   2361                 intent = intent.getSelector();
   2362             }
   2363             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
   2364             List<PreferredActivity> prefs =
   2365                     mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
   2366                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   2367             if (prefs != null && prefs.size() > 0) {
   2368                 // First figure out how good the original match set is.
   2369                 // We will only allow preferred activities that came
   2370                 // from the same match quality.
   2371                 int match = 0;
   2372 
   2373                 if (DEBUG_PREFERRED) {
   2374                     Log.v(TAG, "Figuring out best match...");
   2375                 }
   2376 
   2377                 final int N = query.size();
   2378                 for (int j=0; j<N; j++) {
   2379                     final ResolveInfo ri = query.get(j);
   2380                     if (DEBUG_PREFERRED) {
   2381                         Log.v(TAG, "Match for " + ri.activityInfo + ": 0x"
   2382                                 + Integer.toHexString(match));
   2383                     }
   2384                     if (ri.match > match) {
   2385                         match = ri.match;
   2386                     }
   2387                 }
   2388 
   2389                 if (DEBUG_PREFERRED) {
   2390                     Log.v(TAG, "Best match: 0x" + Integer.toHexString(match));
   2391                 }
   2392 
   2393                 match &= IntentFilter.MATCH_CATEGORY_MASK;
   2394                 final int M = prefs.size();
   2395                 for (int i=0; i<M; i++) {
   2396                     final PreferredActivity pa = prefs.get(i);
   2397                     if (pa.mPref.mMatch != match) {
   2398                         continue;
   2399                     }
   2400                     final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags, userId);
   2401                     if (DEBUG_PREFERRED) {
   2402                         Log.v(TAG, "Got preferred activity:");
   2403                         if (ai != null) {
   2404                             ai.dump(new LogPrinter(Log.VERBOSE, TAG), "  ");
   2405                         } else {
   2406                             Log.v(TAG, "  null");
   2407                         }
   2408                     }
   2409                     if (ai == null) {
   2410                         // This previously registered preferred activity
   2411                         // component is no longer known.  Most likely an update
   2412                         // to the app was installed and in the new version this
   2413                         // component no longer exists.  Clean it up by removing
   2414                         // it from the preferred activities list, and skip it.
   2415                         Slog.w(TAG, "Removing dangling preferred activity: "
   2416                                 + pa.mPref.mComponent);
   2417                         mSettings.mPreferredActivities.removeFilter(pa);
   2418                         continue;
   2419                     }
   2420                     for (int j=0; j<N; j++) {
   2421                         final ResolveInfo ri = query.get(j);
   2422                         if (!ri.activityInfo.applicationInfo.packageName
   2423                                 .equals(ai.applicationInfo.packageName)) {
   2424                             continue;
   2425                         }
   2426                         if (!ri.activityInfo.name.equals(ai.name)) {
   2427                             continue;
   2428                         }
   2429 
   2430                         // Okay we found a previously set preferred app.
   2431                         // If the result set is different from when this
   2432                         // was created, we need to clear it and re-ask the
   2433                         // user their preference.
   2434                         if (!pa.mPref.sameSet(query, priority)) {
   2435                             Slog.i(TAG, "Result set changed, dropping preferred activity for "
   2436                                     + intent + " type " + resolvedType);
   2437                             mSettings.mPreferredActivities.removeFilter(pa);
   2438                             return null;
   2439                         }
   2440 
   2441                         // Yay!
   2442                         return ri;
   2443                     }
   2444                 }
   2445             }
   2446         }
   2447         return null;
   2448     }
   2449 
   2450     @Override
   2451     public List<ResolveInfo> queryIntentActivities(Intent intent,
   2452             String resolvedType, int flags, int userId) {
   2453         if (!sUserManager.exists(userId)) return null;
   2454         ComponentName comp = intent.getComponent();
   2455         if (comp == null) {
   2456             if (intent.getSelector() != null) {
   2457                 intent = intent.getSelector();
   2458                 comp = intent.getComponent();
   2459             }
   2460         }
   2461 
   2462         if (comp != null) {
   2463             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2464             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
   2465             if (ai != null) {
   2466                 final ResolveInfo ri = new ResolveInfo();
   2467                 ri.activityInfo = ai;
   2468                 list.add(ri);
   2469             }
   2470             return list;
   2471         }
   2472 
   2473         // reader
   2474         synchronized (mPackages) {
   2475             final String pkgName = intent.getPackage();
   2476             if (pkgName == null) {
   2477                 return mActivities.queryIntent(intent, resolvedType, flags, userId);
   2478             }
   2479             final PackageParser.Package pkg = mPackages.get(pkgName);
   2480             if (pkg != null) {
   2481                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
   2482                         pkg.activities, userId);
   2483             }
   2484             return new ArrayList<ResolveInfo>();
   2485         }
   2486     }
   2487 
   2488     @Override
   2489     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
   2490             Intent[] specifics, String[] specificTypes, Intent intent,
   2491             String resolvedType, int flags, int userId) {
   2492         if (!sUserManager.exists(userId)) return null;
   2493         final String resultsAction = intent.getAction();
   2494 
   2495         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
   2496                 | PackageManager.GET_RESOLVED_FILTER, userId);
   2497 
   2498         if (DEBUG_INTENT_MATCHING) {
   2499             Log.v(TAG, "Query " + intent + ": " + results);
   2500         }
   2501 
   2502         int specificsPos = 0;
   2503         int N;
   2504 
   2505         // todo: note that the algorithm used here is O(N^2).  This
   2506         // isn't a problem in our current environment, but if we start running
   2507         // into situations where we have more than 5 or 10 matches then this
   2508         // should probably be changed to something smarter...
   2509 
   2510         // First we go through and resolve each of the specific items
   2511         // that were supplied, taking care of removing any corresponding
   2512         // duplicate items in the generic resolve list.
   2513         if (specifics != null) {
   2514             for (int i=0; i<specifics.length; i++) {
   2515                 final Intent sintent = specifics[i];
   2516                 if (sintent == null) {
   2517                     continue;
   2518                 }
   2519 
   2520                 if (DEBUG_INTENT_MATCHING) {
   2521                     Log.v(TAG, "Specific #" + i + ": " + sintent);
   2522                 }
   2523 
   2524                 String action = sintent.getAction();
   2525                 if (resultsAction != null && resultsAction.equals(action)) {
   2526                     // If this action was explicitly requested, then don't
   2527                     // remove things that have it.
   2528                     action = null;
   2529                 }
   2530 
   2531                 ResolveInfo ri = null;
   2532                 ActivityInfo ai = null;
   2533 
   2534                 ComponentName comp = sintent.getComponent();
   2535                 if (comp == null) {
   2536                     ri = resolveIntent(
   2537                         sintent,
   2538                         specificTypes != null ? specificTypes[i] : null,
   2539                             flags, userId);
   2540                     if (ri == null) {
   2541                         continue;
   2542                     }
   2543                     if (ri == mResolveInfo) {
   2544                         // ACK!  Must do something better with this.
   2545                     }
   2546                     ai = ri.activityInfo;
   2547                     comp = new ComponentName(ai.applicationInfo.packageName,
   2548                             ai.name);
   2549                 } else {
   2550                     ai = getActivityInfo(comp, flags, userId);
   2551                     if (ai == null) {
   2552                         continue;
   2553                     }
   2554                 }
   2555 
   2556                 // Look for any generic query activities that are duplicates
   2557                 // of this specific one, and remove them from the results.
   2558                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
   2559                 N = results.size();
   2560                 int j;
   2561                 for (j=specificsPos; j<N; j++) {
   2562                     ResolveInfo sri = results.get(j);
   2563                     if ((sri.activityInfo.name.equals(comp.getClassName())
   2564                             && sri.activityInfo.applicationInfo.packageName.equals(
   2565                                     comp.getPackageName()))
   2566                         || (action != null && sri.filter.matchAction(action))) {
   2567                         results.remove(j);
   2568                         if (DEBUG_INTENT_MATCHING) Log.v(
   2569                             TAG, "Removing duplicate item from " + j
   2570                             + " due to specific " + specificsPos);
   2571                         if (ri == null) {
   2572                             ri = sri;
   2573                         }
   2574                         j--;
   2575                         N--;
   2576                     }
   2577                 }
   2578 
   2579                 // Add this specific item to its proper place.
   2580                 if (ri == null) {
   2581                     ri = new ResolveInfo();
   2582                     ri.activityInfo = ai;
   2583                 }
   2584                 results.add(specificsPos, ri);
   2585                 ri.specificIndex = i;
   2586                 specificsPos++;
   2587             }
   2588         }
   2589 
   2590         // Now we go through the remaining generic results and remove any
   2591         // duplicate actions that are found here.
   2592         N = results.size();
   2593         for (int i=specificsPos; i<N-1; i++) {
   2594             final ResolveInfo rii = results.get(i);
   2595             if (rii.filter == null) {
   2596                 continue;
   2597             }
   2598 
   2599             // Iterate over all of the actions of this result's intent
   2600             // filter...  typically this should be just one.
   2601             final Iterator<String> it = rii.filter.actionsIterator();
   2602             if (it == null) {
   2603                 continue;
   2604             }
   2605             while (it.hasNext()) {
   2606                 final String action = it.next();
   2607                 if (resultsAction != null && resultsAction.equals(action)) {
   2608                     // If this action was explicitly requested, then don't
   2609                     // remove things that have it.
   2610                     continue;
   2611                 }
   2612                 for (int j=i+1; j<N; j++) {
   2613                     final ResolveInfo rij = results.get(j);
   2614                     if (rij.filter != null && rij.filter.hasAction(action)) {
   2615                         results.remove(j);
   2616                         if (DEBUG_INTENT_MATCHING) Log.v(
   2617                             TAG, "Removing duplicate item from " + j
   2618                             + " due to action " + action + " at " + i);
   2619                         j--;
   2620                         N--;
   2621                     }
   2622                 }
   2623             }
   2624 
   2625             // If the caller didn't request filter information, drop it now
   2626             // so we don't have to marshall/unmarshall it.
   2627             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   2628                 rii.filter = null;
   2629             }
   2630         }
   2631 
   2632         // Filter out the caller activity if so requested.
   2633         if (caller != null) {
   2634             N = results.size();
   2635             for (int i=0; i<N; i++) {
   2636                 ActivityInfo ainfo = results.get(i).activityInfo;
   2637                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
   2638                         && caller.getClassName().equals(ainfo.name)) {
   2639                     results.remove(i);
   2640                     break;
   2641                 }
   2642             }
   2643         }
   2644 
   2645         // If the caller didn't request filter information,
   2646         // drop them now so we don't have to
   2647         // marshall/unmarshall it.
   2648         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   2649             N = results.size();
   2650             for (int i=0; i<N; i++) {
   2651                 results.get(i).filter = null;
   2652             }
   2653         }
   2654 
   2655         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
   2656         return results;
   2657     }
   2658 
   2659     @Override
   2660     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
   2661             int userId) {
   2662         if (!sUserManager.exists(userId)) return null;
   2663         ComponentName comp = intent.getComponent();
   2664         if (comp == null) {
   2665             if (intent.getSelector() != null) {
   2666                 intent = intent.getSelector();
   2667                 comp = intent.getComponent();
   2668             }
   2669         }
   2670         if (comp != null) {
   2671             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2672             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
   2673             if (ai != null) {
   2674                 ResolveInfo ri = new ResolveInfo();
   2675                 ri.activityInfo = ai;
   2676                 list.add(ri);
   2677             }
   2678             return list;
   2679         }
   2680 
   2681         // reader
   2682         synchronized (mPackages) {
   2683             String pkgName = intent.getPackage();
   2684             if (pkgName == null) {
   2685                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
   2686             }
   2687             final PackageParser.Package pkg = mPackages.get(pkgName);
   2688             if (pkg != null) {
   2689                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
   2690                         userId);
   2691             }
   2692             return null;
   2693         }
   2694     }
   2695 
   2696     @Override
   2697     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
   2698         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
   2699         if (!sUserManager.exists(userId)) return null;
   2700         if (query != null) {
   2701             if (query.size() >= 1) {
   2702                 // If there is more than one service with the same priority,
   2703                 // just arbitrarily pick the first one.
   2704                 return query.get(0);
   2705             }
   2706         }
   2707         return null;
   2708     }
   2709 
   2710     @Override
   2711     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
   2712             int userId) {
   2713         if (!sUserManager.exists(userId)) return null;
   2714         ComponentName comp = intent.getComponent();
   2715         if (comp == null) {
   2716             if (intent.getSelector() != null) {
   2717                 intent = intent.getSelector();
   2718                 comp = intent.getComponent();
   2719             }
   2720         }
   2721         if (comp != null) {
   2722             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   2723             final ServiceInfo si = getServiceInfo(comp, flags, userId);
   2724             if (si != null) {
   2725                 final ResolveInfo ri = new ResolveInfo();
   2726                 ri.serviceInfo = si;
   2727                 list.add(ri);
   2728             }
   2729             return list;
   2730         }
   2731 
   2732         // reader
   2733         synchronized (mPackages) {
   2734             String pkgName = intent.getPackage();
   2735             if (pkgName == null) {
   2736                 return mServices.queryIntent(intent, resolvedType, flags, userId);
   2737             }
   2738             final PackageParser.Package pkg = mPackages.get(pkgName);
   2739             if (pkg != null) {
   2740                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
   2741                         userId);
   2742             }
   2743             return null;
   2744         }
   2745     }
   2746 
   2747     private static final int getContinuationPoint(final String[] keys, final String key) {
   2748         final int index;
   2749         if (key == null) {
   2750             index = 0;
   2751         } else {
   2752             final int insertPoint = Arrays.binarySearch(keys, key);
   2753             if (insertPoint < 0) {
   2754                 index = -insertPoint;
   2755             } else {
   2756                 index = insertPoint + 1;
   2757             }
   2758         }
   2759         return index;
   2760     }
   2761 
   2762     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead) {
   2763         final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>();
   2764         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   2765         final String[] keys;
   2766         int userId = UserId.getCallingUserId();
   2767 
   2768         // writer
   2769         synchronized (mPackages) {
   2770             if (listUninstalled) {
   2771                 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
   2772             } else {
   2773                 keys = mPackages.keySet().toArray(new String[mPackages.size()]);
   2774             }
   2775 
   2776             Arrays.sort(keys);
   2777             int i = getContinuationPoint(keys, lastRead);
   2778             final int N = keys.length;
   2779 
   2780             while (i < N) {
   2781                 final String packageName = keys[i++];
   2782 
   2783                 PackageInfo pi = null;
   2784                 if (listUninstalled) {
   2785                     final PackageSetting ps = mSettings.mPackages.get(packageName);
   2786                     if (ps != null) {
   2787                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
   2788                     }
   2789                 } else {
   2790                     final PackageParser.Package p = mPackages.get(packageName);
   2791                     if (p != null) {
   2792                         pi = generatePackageInfo(p, flags, userId);
   2793                     }
   2794                 }
   2795 
   2796                 if (pi != null && list.append(pi)) {
   2797                     break;
   2798                 }
   2799             }
   2800 
   2801             if (i == N) {
   2802                 list.setLastSlice(true);
   2803             }
   2804         }
   2805 
   2806         return list;
   2807     }
   2808 
   2809     @Override
   2810     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags,
   2811             String lastRead, int userId) {
   2812         if (!sUserManager.exists(userId)) return null;
   2813         final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>();
   2814         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   2815         final String[] keys;
   2816 
   2817         // writer
   2818         synchronized (mPackages) {
   2819             if (listUninstalled) {
   2820                 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]);
   2821             } else {
   2822                 keys = mPackages.keySet().toArray(new String[mPackages.size()]);
   2823             }
   2824 
   2825             Arrays.sort(keys);
   2826             int i = getContinuationPoint(keys, lastRead);
   2827             final int N = keys.length;
   2828 
   2829             while (i < N) {
   2830                 final String packageName = keys[i++];
   2831 
   2832                 ApplicationInfo ai = null;
   2833                 final PackageSetting ps = mSettings.mPackages.get(packageName);
   2834                 if (listUninstalled) {
   2835                     if (ps != null) {
   2836                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
   2837                     }
   2838                 } else {
   2839                     final PackageParser.Package p = mPackages.get(packageName);
   2840                     if (p != null && ps != null) {
   2841                         ai = PackageParser.generateApplicationInfo(p, flags, ps.getStopped(userId),
   2842                                 ps.getEnabled(userId), userId);
   2843                     }
   2844                 }
   2845 
   2846                 if (ai != null && list.append(ai)) {
   2847                     break;
   2848                 }
   2849             }
   2850 
   2851             if (i == N) {
   2852                 list.setLastSlice(true);
   2853             }
   2854         }
   2855 
   2856         return list;
   2857     }
   2858 
   2859     public List<ApplicationInfo> getPersistentApplications(int flags) {
   2860         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
   2861 
   2862         // reader
   2863         synchronized (mPackages) {
   2864             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
   2865             final int userId = UserId.getCallingUserId();
   2866             while (i.hasNext()) {
   2867                 final PackageParser.Package p = i.next();
   2868                 if (p.applicationInfo != null
   2869                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
   2870                         && (!mSafeMode || isSystemApp(p))) {
   2871                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
   2872                     finalList.add(PackageParser.generateApplicationInfo(p, flags,
   2873                             ps != null ? ps.getStopped(userId) : false,
   2874                             ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
   2875                             userId));
   2876                 }
   2877             }
   2878         }
   2879 
   2880         return finalList;
   2881     }
   2882 
   2883     @Override
   2884     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
   2885         if (!sUserManager.exists(userId)) return null;
   2886         // reader
   2887         synchronized (mPackages) {
   2888             final PackageParser.Provider provider = mProviders.get(name);
   2889             PackageSetting ps = provider != null
   2890                     ? mSettings.mPackages.get(provider.owner.packageName)
   2891                     : null;
   2892             return provider != null
   2893                     && mSettings.isEnabledLPr(provider.info, flags, userId)
   2894                     && (!mSafeMode || (provider.info.applicationInfo.flags
   2895                             &ApplicationInfo.FLAG_SYSTEM) != 0)
   2896                     ? PackageParser.generateProviderInfo(provider, flags,
   2897                             ps != null ? ps.getStopped(userId) : false,
   2898                             ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
   2899                             userId)
   2900                     : null;
   2901         }
   2902     }
   2903 
   2904     /**
   2905      * @deprecated
   2906      */
   2907     @Deprecated
   2908     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
   2909         // reader
   2910         synchronized (mPackages) {
   2911             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet()
   2912                     .iterator();
   2913             final int userId = UserId.getCallingUserId();
   2914             while (i.hasNext()) {
   2915                 Map.Entry<String, PackageParser.Provider> entry = i.next();
   2916                 PackageParser.Provider p = entry.getValue();
   2917                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
   2918 
   2919                 if (p.syncable
   2920                         && (!mSafeMode || (p.info.applicationInfo.flags
   2921                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
   2922                     outNames.add(entry.getKey());
   2923                     outInfo.add(PackageParser.generateProviderInfo(p, 0,
   2924                             ps != null ? ps.getStopped(userId) : false,
   2925                             ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
   2926                             userId));
   2927                 }
   2928             }
   2929         }
   2930     }
   2931 
   2932     public List<ProviderInfo> queryContentProviders(String processName,
   2933             int uid, int flags) {
   2934         ArrayList<ProviderInfo> finalList = null;
   2935 
   2936         // reader
   2937         synchronized (mPackages) {
   2938             final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
   2939             final int userId = processName != null ?
   2940                     UserId.getUserId(uid) : UserId.getCallingUserId();
   2941             while (i.hasNext()) {
   2942                 final PackageParser.Provider p = i.next();
   2943                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
   2944                 if (p.info.authority != null
   2945                         && (processName == null
   2946                                 || (p.info.processName.equals(processName)
   2947                                         && UserId.isSameApp(p.info.applicationInfo.uid, uid)))
   2948                         && mSettings.isEnabledLPr(p.info, flags, userId)
   2949                         && (!mSafeMode
   2950                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
   2951                     if (finalList == null) {
   2952                         finalList = new ArrayList<ProviderInfo>(3);
   2953                     }
   2954                     finalList.add(PackageParser.generateProviderInfo(p, flags,
   2955                             ps != null ? ps.getStopped(userId) : false,
   2956                             ps != null ? ps.getEnabled(userId) : COMPONENT_ENABLED_STATE_DEFAULT,
   2957                             userId));
   2958                 }
   2959             }
   2960         }
   2961 
   2962         if (finalList != null) {
   2963             Collections.sort(finalList, mProviderInitOrderSorter);
   2964         }
   2965 
   2966         return finalList;
   2967     }
   2968 
   2969     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
   2970             int flags) {
   2971         // reader
   2972         synchronized (mPackages) {
   2973             final PackageParser.Instrumentation i = mInstrumentation.get(name);
   2974             return PackageParser.generateInstrumentationInfo(i, flags);
   2975         }
   2976     }
   2977 
   2978     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
   2979             int flags) {
   2980         ArrayList<InstrumentationInfo> finalList =
   2981             new ArrayList<InstrumentationInfo>();
   2982 
   2983         // reader
   2984         synchronized (mPackages) {
   2985             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
   2986             while (i.hasNext()) {
   2987                 final PackageParser.Instrumentation p = i.next();
   2988                 if (targetPackage == null
   2989                         || targetPackage.equals(p.info.targetPackage)) {
   2990                     finalList.add(PackageParser.generateInstrumentationInfo(p,
   2991                             flags));
   2992                 }
   2993             }
   2994         }
   2995 
   2996         return finalList;
   2997     }
   2998 
   2999     private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
   3000         String[] files = dir.list();
   3001         if (files == null) {
   3002             Log.d(TAG, "No files in app dir " + dir);
   3003             return;
   3004         }
   3005 
   3006         if (DEBUG_PACKAGE_SCANNING) {
   3007             Log.d(TAG, "Scanning app dir " + dir);
   3008         }
   3009 
   3010         int i;
   3011         for (i=0; i<files.length; i++) {
   3012             File file = new File(dir, files[i]);
   3013             if (!isPackageFilename(files[i])) {
   3014                 // Ignore entries which are not apk's
   3015                 continue;
   3016             }
   3017             PackageParser.Package pkg = scanPackageLI(file,
   3018                     flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime);
   3019             // Don't mess around with apps in system partition.
   3020             if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
   3021                     mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
   3022                 // Delete the apk
   3023                 Slog.w(TAG, "Cleaning up failed install of " + file);
   3024                 file.delete();
   3025             }
   3026         }
   3027     }
   3028 
   3029     private static File getSettingsProblemFile() {
   3030         File dataDir = Environment.getDataDirectory();
   3031         File systemDir = new File(dataDir, "system");
   3032         File fname = new File(systemDir, "uiderrors.txt");
   3033         return fname;
   3034     }
   3035 
   3036     static void reportSettingsProblem(int priority, String msg) {
   3037         try {
   3038             File fname = getSettingsProblemFile();
   3039             FileOutputStream out = new FileOutputStream(fname, true);
   3040             PrintWriter pw = new PrintWriter(out);
   3041             SimpleDateFormat formatter = new SimpleDateFormat();
   3042             String dateString = formatter.format(new Date(System.currentTimeMillis()));
   3043             pw.println(dateString + ": " + msg);
   3044             pw.close();
   3045             FileUtils.setPermissions(
   3046                     fname.toString(),
   3047                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
   3048                     -1, -1);
   3049         } catch (java.io.IOException e) {
   3050         }
   3051         Slog.println(priority, TAG, msg);
   3052     }
   3053 
   3054     private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps,
   3055             PackageParser.Package pkg, File srcFile, int parseFlags) {
   3056         if (GET_CERTIFICATES) {
   3057             if (ps != null
   3058                     && ps.codePath.equals(srcFile)
   3059                     && ps.timeStamp == srcFile.lastModified()) {
   3060                 if (ps.signatures.mSignatures != null
   3061                         && ps.signatures.mSignatures.length != 0) {
   3062                     // Optimization: reuse the existing cached certificates
   3063                     // if the package appears to be unchanged.
   3064                     pkg.mSignatures = ps.signatures.mSignatures;
   3065                     return true;
   3066                 }
   3067 
   3068                 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures.  Collecting certs again to recover them.");
   3069             } else {
   3070                 Log.i(TAG, srcFile.toString() + " changed; collecting certs");
   3071             }
   3072 
   3073             if (!pp.collectCertificates(pkg, parseFlags)) {
   3074                 mLastScanError = pp.getParseError();
   3075                 return false;
   3076             }
   3077         }
   3078         return true;
   3079     }
   3080 
   3081     /*
   3082      *  Scan a package and return the newly parsed package.
   3083      *  Returns null in case of errors and the error code is stored in mLastScanError
   3084      */
   3085     private PackageParser.Package scanPackageLI(File scanFile,
   3086             int parseFlags, int scanMode, long currentTime) {
   3087         mLastScanError = PackageManager.INSTALL_SUCCEEDED;
   3088         String scanPath = scanFile.getPath();
   3089         parseFlags |= mDefParseFlags;
   3090         PackageParser pp = new PackageParser(scanPath);
   3091         pp.setSeparateProcesses(mSeparateProcesses);
   3092         pp.setOnlyCoreApps(mOnlyCore);
   3093         final PackageParser.Package pkg = pp.parsePackage(scanFile,
   3094                 scanPath, mMetrics, parseFlags);
   3095         if (pkg == null) {
   3096             mLastScanError = pp.getParseError();
   3097             return null;
   3098         }
   3099         PackageSetting ps = null;
   3100         PackageSetting updatedPkg;
   3101         // reader
   3102         synchronized (mPackages) {
   3103             // Look to see if we already know about this package.
   3104             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
   3105             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
   3106                 // This package has been renamed to its original name.  Let's
   3107                 // use that.
   3108                 ps = mSettings.peekPackageLPr(oldName);
   3109             }
   3110             // If there was no original package, see one for the real package name.
   3111             if (ps == null) {
   3112                 ps = mSettings.peekPackageLPr(pkg.packageName);
   3113             }
   3114             // Check to see if this package could be hiding/updating a system
   3115             // package.  Must look for it either under the original or real
   3116             // package name depending on our state.
   3117             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
   3118         }
   3119         // First check if this is a system package that may involve an update
   3120         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   3121             if (ps != null && !ps.codePath.equals(scanFile)) {
   3122                 // The path has changed from what was last scanned...  check the
   3123                 // version of the new path against what we have stored to determine
   3124                 // what to do.
   3125                 if (pkg.mVersionCode < ps.versionCode) {
   3126                     // The system package has been updated and the code path does not match
   3127                     // Ignore entry. Skip it.
   3128                     Log.i(TAG, "Package " + ps.name + " at " + scanFile
   3129                             + " ignored: updated version " + ps.versionCode
   3130                             + " better than this " + pkg.mVersionCode);
   3131                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   3132                     return null;
   3133                 } else {
   3134                     // The current app on the system partion is better than
   3135                     // what we have updated to on the data partition; switch
   3136                     // back to the system partition version.
   3137                     // At this point, its safely assumed that package installation for
   3138                     // apps in system partition will go through. If not there won't be a working
   3139                     // version of the app
   3140                     // writer
   3141                     synchronized (mPackages) {
   3142                         // Just remove the loaded entries from package lists.
   3143                         mPackages.remove(ps.name);
   3144                     }
   3145                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile
   3146                             + "reverting from " + ps.codePathString
   3147                             + ": new version " + pkg.mVersionCode
   3148                             + " better than installed " + ps.versionCode);
   3149 
   3150                     InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
   3151                             ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
   3152                     synchronized (mInstaller) {
   3153                         args.cleanUpResourcesLI();
   3154                     }
   3155                     synchronized (mPackages) {
   3156                         mSettings.enableSystemPackageLPw(ps.name);
   3157                     }
   3158                 }
   3159             }
   3160         }
   3161 
   3162         if (updatedPkg != null) {
   3163             // An updated system app will not have the PARSE_IS_SYSTEM flag set
   3164             // initially
   3165             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
   3166         }
   3167         // Verify certificates against what was last scanned
   3168         if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
   3169             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
   3170             return null;
   3171         }
   3172 
   3173         /*
   3174          * A new system app appeared, but we already had a non-system one of the
   3175          * same name installed earlier.
   3176          */
   3177         boolean shouldHideSystemApp = false;
   3178         if (updatedPkg == null && ps != null
   3179                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
   3180             /*
   3181              * Check to make sure the signatures match first. If they don't,
   3182              * wipe the installed application and its data.
   3183              */
   3184             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
   3185                     != PackageManager.SIGNATURE_MATCH) {
   3186                 deletePackageLI(pkg.packageName, true, 0, null, false);
   3187                 ps = null;
   3188             } else {
   3189                 /*
   3190                  * If the newly-added system app is an older version than the
   3191                  * already installed version, hide it. It will be scanned later
   3192                  * and re-added like an update.
   3193                  */
   3194                 if (pkg.mVersionCode < ps.versionCode) {
   3195                     shouldHideSystemApp = true;
   3196                 } else {
   3197                     /*
   3198                      * The newly found system app is a newer version that the
   3199                      * one previously installed. Simply remove the
   3200                      * already-installed application and replace it with our own
   3201                      * while keeping the application data.
   3202                      */
   3203                     Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
   3204                             + ps.codePathString + ": new version " + pkg.mVersionCode
   3205                             + " better than installed " + ps.versionCode);
   3206                     InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
   3207                             ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
   3208                     synchronized (mInstaller) {
   3209                         args.cleanUpResourcesLI();
   3210                     }
   3211                 }
   3212             }
   3213         }
   3214 
   3215         // The apk is forward locked (not public) if its code and resources
   3216         // are kept in different files.
   3217         // TODO grab this value from PackageSettings
   3218         if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
   3219             parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   3220         }
   3221 
   3222         String codePath = null;
   3223         String resPath = null;
   3224         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) {
   3225             if (ps != null && ps.resourcePathString != null) {
   3226                 resPath = ps.resourcePathString;
   3227             } else {
   3228                 // Should not happen at all. Just log an error.
   3229                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
   3230             }
   3231         } else {
   3232             resPath = pkg.mScanPath;
   3233         }
   3234         codePath = pkg.mScanPath;
   3235         // Set application objects path explicitly.
   3236         setApplicationInfoPaths(pkg, codePath, resPath);
   3237         // Note that we invoke the following method only if we are about to unpack an application
   3238         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
   3239                 | SCAN_UPDATE_SIGNATURE, currentTime);
   3240 
   3241         /*
   3242          * If the system app should be overridden by a previously installed
   3243          * data, hide the system app now and let the /data/app scan pick it up
   3244          * again.
   3245          */
   3246         if (shouldHideSystemApp) {
   3247             synchronized (mPackages) {
   3248                 /*
   3249                  * We have to grant systems permissions before we hide, because
   3250                  * grantPermissions will assume the package update is trying to
   3251                  * expand its permissions.
   3252                  */
   3253                 grantPermissionsLPw(pkg, true);
   3254                 mSettings.disableSystemPackageLPw(pkg.packageName);
   3255             }
   3256         }
   3257 
   3258         return scannedPkg;
   3259     }
   3260 
   3261     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
   3262             String destResPath) {
   3263         pkg.mPath = pkg.mScanPath = destCodePath;
   3264         pkg.applicationInfo.sourceDir = destCodePath;
   3265         pkg.applicationInfo.publicSourceDir = destResPath;
   3266     }
   3267 
   3268     private static String fixProcessName(String defProcessName,
   3269             String processName, int uid) {
   3270         if (processName == null) {
   3271             return defProcessName;
   3272         }
   3273         return processName;
   3274     }
   3275 
   3276     private boolean verifySignaturesLP(PackageSetting pkgSetting,
   3277             PackageParser.Package pkg) {
   3278         if (pkgSetting.signatures.mSignatures != null) {
   3279             // Already existing package. Make sure signatures match
   3280             if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
   3281                 PackageManager.SIGNATURE_MATCH) {
   3282                     Slog.e(TAG, "Package " + pkg.packageName
   3283                             + " signatures do not match the previously installed version; ignoring!");
   3284                     mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
   3285                     return false;
   3286                 }
   3287         }
   3288         // Check for shared user signatures
   3289         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
   3290             if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   3291                     pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   3292                 Slog.e(TAG, "Package " + pkg.packageName
   3293                         + " has no signatures that match those in shared user "
   3294                         + pkgSetting.sharedUser.name + "; ignoring!");
   3295                 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
   3296                 return false;
   3297             }
   3298         }
   3299         return true;
   3300     }
   3301 
   3302     /**
   3303      * Enforces that only the system UID or root's UID can call a method exposed
   3304      * via Binder.
   3305      *
   3306      * @param message used as message if SecurityException is thrown
   3307      * @throws SecurityException if the caller is not system or root
   3308      */
   3309     private static final void enforceSystemOrRoot(String message) {
   3310         final int uid = Binder.getCallingUid();
   3311         if (uid != Process.SYSTEM_UID && uid != 0) {
   3312             throw new SecurityException(message);
   3313         }
   3314     }
   3315 
   3316     public void performBootDexOpt() {
   3317         ArrayList<PackageParser.Package> pkgs = null;
   3318         synchronized (mPackages) {
   3319             if (mDeferredDexOpt.size() > 0) {
   3320                 pkgs = new ArrayList<PackageParser.Package>(mDeferredDexOpt);
   3321                 mDeferredDexOpt.clear();
   3322             }
   3323         }
   3324         if (pkgs != null) {
   3325             for (int i=0; i<pkgs.size(); i++) {
   3326                 if (!isFirstBoot()) {
   3327                     try {
   3328                         ActivityManagerNative.getDefault().showBootMessage(
   3329                                 mContext.getResources().getString(
   3330                                         com.android.internal.R.string.android_upgrading_apk,
   3331                                         i+1, pkgs.size()), true);
   3332                     } catch (RemoteException e) {
   3333                     }
   3334                 }
   3335                 PackageParser.Package p = pkgs.get(i);
   3336                 synchronized (mInstallLock) {
   3337                     if (!p.mDidDexOpt) {
   3338                         performDexOptLI(p, false, false);
   3339                     }
   3340                 }
   3341             }
   3342         }
   3343     }
   3344 
   3345     public boolean performDexOpt(String packageName) {
   3346         enforceSystemOrRoot("Only the system can request dexopt be performed");
   3347 
   3348         if (!mNoDexOpt) {
   3349             return false;
   3350         }
   3351 
   3352         PackageParser.Package p;
   3353         synchronized (mPackages) {
   3354             p = mPackages.get(packageName);
   3355             if (p == null || p.mDidDexOpt) {
   3356                 return false;
   3357             }
   3358         }
   3359         synchronized (mInstallLock) {
   3360             return performDexOptLI(p, false, false) == DEX_OPT_PERFORMED;
   3361         }
   3362     }
   3363 
   3364     static final int DEX_OPT_SKIPPED = 0;
   3365     static final int DEX_OPT_PERFORMED = 1;
   3366     static final int DEX_OPT_DEFERRED = 2;
   3367     static final int DEX_OPT_FAILED = -1;
   3368 
   3369     private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer) {
   3370         boolean performed = false;
   3371         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
   3372             String path = pkg.mScanPath;
   3373             int ret = 0;
   3374             try {
   3375                 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) {
   3376                     if (!forceDex && defer) {
   3377                         mDeferredDexOpt.add(pkg);
   3378                         return DEX_OPT_DEFERRED;
   3379                     } else {
   3380                         Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
   3381                         ret = mInstaller.dexopt(path, pkg.applicationInfo.uid,
   3382                                 !isForwardLocked(pkg));
   3383                         pkg.mDidDexOpt = true;
   3384                         performed = true;
   3385                     }
   3386                 }
   3387             } catch (FileNotFoundException e) {
   3388                 Slog.w(TAG, "Apk not found for dexopt: " + path);
   3389                 ret = -1;
   3390             } catch (IOException e) {
   3391                 Slog.w(TAG, "IOException reading apk: " + path, e);
   3392                 ret = -1;
   3393             } catch (dalvik.system.StaleDexCacheError e) {
   3394                 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
   3395                 ret = -1;
   3396             } catch (Exception e) {
   3397                 Slog.w(TAG, "Exception when doing dexopt : ", e);
   3398                 ret = -1;
   3399             }
   3400             if (ret < 0) {
   3401                 //error from installer
   3402                 return DEX_OPT_FAILED;
   3403             }
   3404         }
   3405 
   3406         return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
   3407     }
   3408 
   3409     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
   3410         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   3411             Slog.w(TAG, "Unable to update from " + oldPkg.name
   3412                     + " to " + newPkg.packageName
   3413                     + ": old package not in system partition");
   3414             return false;
   3415         } else if (mPackages.get(oldPkg.name) != null) {
   3416             Slog.w(TAG, "Unable to update from " + oldPkg.name
   3417                     + " to " + newPkg.packageName
   3418                     + ": old package still exists");
   3419             return false;
   3420         }
   3421         return true;
   3422     }
   3423 
   3424     File getDataPathForUser(int userId) {
   3425         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
   3426     }
   3427 
   3428     private File getDataPathForPackage(String packageName, int userId) {
   3429         /*
   3430          * Until we fully support multiple users, return the directory we
   3431          * previously would have. The PackageManagerTests will need to be
   3432          * revised when this is changed back..
   3433          */
   3434         if (userId == 0) {
   3435             return new File(mAppDataDir, packageName);
   3436         } else {
   3437             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
   3438                 + File.separator + packageName);
   3439         }
   3440     }
   3441 
   3442     private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
   3443             int parseFlags, int scanMode, long currentTime) {
   3444         File scanFile = new File(pkg.mScanPath);
   3445         if (scanFile == null || pkg.applicationInfo.sourceDir == null ||
   3446                 pkg.applicationInfo.publicSourceDir == null) {
   3447             // Bail out. The resource and code paths haven't been set.
   3448             Slog.w(TAG, " Code and resource paths haven't been set correctly");
   3449             mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK;
   3450             return null;
   3451         }
   3452         mScanningPath = scanFile;
   3453 
   3454         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   3455             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
   3456         }
   3457 
   3458         if (pkg.packageName.equals("android")) {
   3459             synchronized (mPackages) {
   3460                 if (mAndroidApplication != null) {
   3461                     Slog.w(TAG, "*************************************************");
   3462                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
   3463                     Slog.w(TAG, " file=" + mScanningPath);
   3464                     Slog.w(TAG, "*************************************************");
   3465                     mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   3466                     return null;
   3467                 }
   3468 
   3469                 // Set up information for our fall-back user intent resolution
   3470                 // activity.
   3471                 mPlatformPackage = pkg;
   3472                 pkg.mVersionCode = mSdkVersion;
   3473                 mAndroidApplication = pkg.applicationInfo;
   3474                 mResolveActivity.applicationInfo = mAndroidApplication;
   3475                 mResolveActivity.name = ResolverActivity.class.getName();
   3476                 mResolveActivity.packageName = mAndroidApplication.packageName;
   3477                 mResolveActivity.processName = mAndroidApplication.processName;
   3478                 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   3479                 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
   3480                 mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
   3481                 mResolveActivity.exported = true;
   3482                 mResolveActivity.enabled = true;
   3483                 mResolveInfo.activityInfo = mResolveActivity;
   3484                 mResolveInfo.priority = 0;
   3485                 mResolveInfo.preferredOrder = 0;
   3486                 mResolveInfo.match = 0;
   3487                 mResolveComponentName = new ComponentName(
   3488                         mAndroidApplication.packageName, mResolveActivity.name);
   3489             }
   3490         }
   3491 
   3492         if (DEBUG_PACKAGE_SCANNING) {
   3493             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   3494                 Log.d(TAG, "Scanning package " + pkg.packageName);
   3495         }
   3496 
   3497         if (mPackages.containsKey(pkg.packageName)
   3498                 || mSharedLibraries.containsKey(pkg.packageName)) {
   3499             Slog.w(TAG, "Application package " + pkg.packageName
   3500                     + " already installed.  Skipping duplicate.");
   3501             mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
   3502             return null;
   3503         }
   3504 
   3505         // Initialize package source and resource directories
   3506         File destCodeFile = new File(pkg.applicationInfo.sourceDir);
   3507         File destResourceFile = new File(pkg.applicationInfo.publicSourceDir);
   3508 
   3509         SharedUserSetting suid = null;
   3510         PackageSetting pkgSetting = null;
   3511 
   3512         if (!isSystemApp(pkg)) {
   3513             // Only system apps can use these features.
   3514             pkg.mOriginalPackages = null;
   3515             pkg.mRealPackage = null;
   3516             pkg.mAdoptPermissions = null;
   3517         }
   3518 
   3519         // writer
   3520         synchronized (mPackages) {
   3521             // Check all shared libraries and map to their actual file path.
   3522             if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
   3523                 if (mTmpSharedLibraries == null ||
   3524                         mTmpSharedLibraries.length < mSharedLibraries.size()) {
   3525                     mTmpSharedLibraries = new String[mSharedLibraries.size()];
   3526                 }
   3527                 int num = 0;
   3528                 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
   3529                 for (int i=0; i<N; i++) {
   3530                     final String file = mSharedLibraries.get(pkg.usesLibraries.get(i));
   3531                     if (file == null) {
   3532                         Slog.e(TAG, "Package " + pkg.packageName
   3533                                 + " requires unavailable shared library "
   3534                                 + pkg.usesLibraries.get(i) + "; failing!");
   3535                         mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
   3536                         return null;
   3537                     }
   3538                     mTmpSharedLibraries[num] = file;
   3539                     num++;
   3540                 }
   3541                 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
   3542                 for (int i=0; i<N; i++) {
   3543                     final String file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
   3544                     if (file == null) {
   3545                         Slog.w(TAG, "Package " + pkg.packageName
   3546                                 + " desires unavailable shared library "
   3547                                 + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
   3548                     } else {
   3549                         mTmpSharedLibraries[num] = file;
   3550                         num++;
   3551                     }
   3552                 }
   3553                 if (num > 0) {
   3554                     pkg.usesLibraryFiles = new String[num];
   3555                     System.arraycopy(mTmpSharedLibraries, 0,
   3556                             pkg.usesLibraryFiles, 0, num);
   3557                 }
   3558             }
   3559 
   3560             if (pkg.mSharedUserId != null) {
   3561                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId,
   3562                         pkg.applicationInfo.flags, true);
   3563                 if (suid == null) {
   3564                     Slog.w(TAG, "Creating application package " + pkg.packageName
   3565                             + " for shared user failed");
   3566                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3567                     return null;
   3568                 }
   3569                 if (DEBUG_PACKAGE_SCANNING) {
   3570                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   3571                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
   3572                                 + "): packages=" + suid.packages);
   3573                 }
   3574             }
   3575 
   3576             // Check if we are renaming from an original package name.
   3577             PackageSetting origPackage = null;
   3578             String realName = null;
   3579             if (pkg.mOriginalPackages != null) {
   3580                 // This package may need to be renamed to a previously
   3581                 // installed name.  Let's check on that...
   3582                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
   3583                 if (pkg.mOriginalPackages.contains(renamed)) {
   3584                     // This package had originally been installed as the
   3585                     // original name, and we have already taken care of
   3586                     // transitioning to the new one.  Just update the new
   3587                     // one to continue using the old name.
   3588                     realName = pkg.mRealPackage;
   3589                     if (!pkg.packageName.equals(renamed)) {
   3590                         // Callers into this function may have already taken
   3591                         // care of renaming the package; only do it here if
   3592                         // it is not already done.
   3593                         pkg.setPackageName(renamed);
   3594                     }
   3595 
   3596                 } else {
   3597                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
   3598                         if ((origPackage = mSettings.peekPackageLPr(
   3599                                 pkg.mOriginalPackages.get(i))) != null) {
   3600                             // We do have the package already installed under its
   3601                             // original name...  should we use it?
   3602                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
   3603                                 // New package is not compatible with original.
   3604                                 origPackage = null;
   3605                                 continue;
   3606                             } else if (origPackage.sharedUser != null) {
   3607                                 // Make sure uid is compatible between packages.
   3608                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
   3609                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
   3610                                             + " to " + pkg.packageName + ": old uid "
   3611                                             + origPackage.sharedUser.name
   3612                                             + " differs from " + pkg.mSharedUserId);
   3613                                     origPackage = null;
   3614                                     continue;
   3615                                 }
   3616                             } else {
   3617                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
   3618                                         + pkg.packageName + " to old name " + origPackage.name);
   3619                             }
   3620                             break;
   3621                         }
   3622                     }
   3623                 }
   3624             }
   3625 
   3626             if (mTransferedPackages.contains(pkg.packageName)) {
   3627                 Slog.w(TAG, "Package " + pkg.packageName
   3628                         + " was transferred to another, but its .apk remains");
   3629             }
   3630 
   3631             // Just create the setting, don't add it yet. For already existing packages
   3632             // the PkgSetting exists already and doesn't have to be created.
   3633             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
   3634                     destResourceFile, pkg.applicationInfo.nativeLibraryDir,
   3635                     pkg.applicationInfo.flags, true, false);
   3636             if (pkgSetting == null) {
   3637                 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
   3638                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3639                 return null;
   3640             }
   3641 
   3642             if (pkgSetting.origPackage != null) {
   3643                 // If we are first transitioning from an original package,
   3644                 // fix up the new package's name now.  We need to do this after
   3645                 // looking up the package under its new name, so getPackageLP
   3646                 // can take care of fiddling things correctly.
   3647                 pkg.setPackageName(origPackage.name);
   3648 
   3649                 // File a report about this.
   3650                 String msg = "New package " + pkgSetting.realName
   3651                         + " renamed to replace old package " + pkgSetting.name;
   3652                 reportSettingsProblem(Log.WARN, msg);
   3653 
   3654                 // Make a note of it.
   3655                 mTransferedPackages.add(origPackage.name);
   3656 
   3657                 // No longer need to retain this.
   3658                 pkgSetting.origPackage = null;
   3659             }
   3660 
   3661             if (realName != null) {
   3662                 // Make a note of it.
   3663                 mTransferedPackages.add(pkg.packageName);
   3664             }
   3665 
   3666             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
   3667                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   3668             }
   3669 
   3670             pkg.applicationInfo.uid = pkgSetting.appId;
   3671             pkg.mExtras = pkgSetting;
   3672 
   3673             if (!verifySignaturesLP(pkgSetting, pkg)) {
   3674                 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   3675                     return null;
   3676                 }
   3677                 // The signature has changed, but this package is in the system
   3678                 // image...  let's recover!
   3679                 pkgSetting.signatures.mSignatures = pkg.mSignatures;
   3680                 // However...  if this package is part of a shared user, but it
   3681                 // doesn't match the signature of the shared user, let's fail.
   3682                 // What this means is that you can't change the signatures
   3683                 // associated with an overall shared user, which doesn't seem all
   3684                 // that unreasonable.
   3685                 if (pkgSetting.sharedUser != null) {
   3686                     if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   3687                             pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   3688                         Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
   3689                         mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
   3690                         return null;
   3691                     }
   3692                 }
   3693                 // File a report about this.
   3694                 String msg = "System package " + pkg.packageName
   3695                         + " signature changed; retaining data.";
   3696                 reportSettingsProblem(Log.WARN, msg);
   3697             }
   3698 
   3699             // Verify that this new package doesn't have any content providers
   3700             // that conflict with existing packages.  Only do this if the
   3701             // package isn't already installed, since we don't want to break
   3702             // things that are installed.
   3703             if ((scanMode&SCAN_NEW_INSTALL) != 0) {
   3704                 final int N = pkg.providers.size();
   3705                 int i;
   3706                 for (i=0; i<N; i++) {
   3707                     PackageParser.Provider p = pkg.providers.get(i);
   3708                     if (p.info.authority != null) {
   3709                         String names[] = p.info.authority.split(";");
   3710                         for (int j = 0; j < names.length; j++) {
   3711                             if (mProviders.containsKey(names[j])) {
   3712                                 PackageParser.Provider other = mProviders.get(names[j]);
   3713                                 Slog.w(TAG, "Can't install because provider name " + names[j] +
   3714                                         " (in package " + pkg.applicationInfo.packageName +
   3715                                         ") is already used by "
   3716                                         + ((other != null && other.getComponentName() != null)
   3717                                                 ? other.getComponentName().getPackageName() : "?"));
   3718                                 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
   3719                                 return null;
   3720                             }
   3721                         }
   3722                     }
   3723                 }
   3724             }
   3725 
   3726             if (pkg.mAdoptPermissions != null) {
   3727                 // This package wants to adopt ownership of permissions from
   3728                 // another package.
   3729                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
   3730                     final String origName = pkg.mAdoptPermissions.get(i);
   3731                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
   3732                     if (orig != null) {
   3733                         if (verifyPackageUpdateLPr(orig, pkg)) {
   3734                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
   3735                                     + pkg.packageName);
   3736                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
   3737                         }
   3738                     }
   3739                 }
   3740             }
   3741         }
   3742 
   3743         final String pkgName = pkg.packageName;
   3744 
   3745         final long scanFileTime = scanFile.lastModified();
   3746         final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0;
   3747         pkg.applicationInfo.processName = fixProcessName(
   3748                 pkg.applicationInfo.packageName,
   3749                 pkg.applicationInfo.processName,
   3750                 pkg.applicationInfo.uid);
   3751 
   3752         File dataPath;
   3753         if (mPlatformPackage == pkg) {
   3754             // The system package is special.
   3755             dataPath = new File (Environment.getDataDirectory(), "system");
   3756             pkg.applicationInfo.dataDir = dataPath.getPath();
   3757         } else {
   3758             // This is a normal package, need to make its data directory.
   3759             dataPath = getDataPathForPackage(pkg.packageName, 0);
   3760 
   3761             boolean uidError = false;
   3762 
   3763             if (dataPath.exists()) {
   3764                 // XXX should really do this check for each user.
   3765                 mOutPermissions[1] = 0;
   3766                 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions);
   3767 
   3768                 // If we have mismatched owners for the data path, we have a problem.
   3769                 if (mOutPermissions[1] != pkg.applicationInfo.uid) {
   3770                     boolean recovered = false;
   3771                     if (mOutPermissions[1] == 0) {
   3772                         // The directory somehow became owned by root.  Wow.
   3773                         // This is probably because the system was stopped while
   3774                         // installd was in the middle of messing with its libs
   3775                         // directory.  Ask installd to fix that.
   3776                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
   3777                                 pkg.applicationInfo.uid);
   3778                         if (ret >= 0) {
   3779                             recovered = true;
   3780                             String msg = "Package " + pkg.packageName
   3781                                     + " unexpectedly changed to uid 0; recovered to " +
   3782                                     + pkg.applicationInfo.uid;
   3783                             reportSettingsProblem(Log.WARN, msg);
   3784                         }
   3785                     }
   3786                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
   3787                             || (scanMode&SCAN_BOOTING) != 0)) {
   3788                         // If this is a system app, we can at least delete its
   3789                         // current data so the application will still work.
   3790                         int ret = mInstaller.remove(pkgName, 0);
   3791                         if (ret >= 0) {
   3792                             // TODO: Kill the processes first
   3793                             // Remove the data directories for all users
   3794                             sUserManager.removePackageForAllUsers(pkgName);
   3795                             // Old data gone!
   3796                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
   3797                                     ? "System package " : "Third party package ";
   3798                             String msg = prefix + pkg.packageName
   3799                                     + " has changed from uid: "
   3800                                     + mOutPermissions[1] + " to "
   3801                                     + pkg.applicationInfo.uid + "; old data erased";
   3802                             reportSettingsProblem(Log.WARN, msg);
   3803                             recovered = true;
   3804 
   3805                             // And now re-install the app.
   3806                             ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
   3807                                     pkg.applicationInfo.uid);
   3808                             if (ret == -1) {
   3809                                 // Ack should not happen!
   3810                                 msg = prefix + pkg.packageName
   3811                                         + " could not have data directory re-created after delete.";
   3812                                 reportSettingsProblem(Log.WARN, msg);
   3813                                 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3814                                 return null;
   3815                             }
   3816                             // Create data directories for all users
   3817                             sUserManager.installPackageForAllUsers(pkgName,
   3818                                     pkg.applicationInfo.uid);
   3819                         }
   3820                         if (!recovered) {
   3821                             mHasSystemUidErrors = true;
   3822                         }
   3823                     } else if (!recovered) {
   3824                         // If we allow this install to proceed, we will be broken.
   3825                         // Abort, abort!
   3826                         mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
   3827                         return null;
   3828                     }
   3829                     if (!recovered) {
   3830                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
   3831                             + pkg.applicationInfo.uid + "/fs_"
   3832                             + mOutPermissions[1];
   3833                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
   3834                         String msg = "Package " + pkg.packageName
   3835                                 + " has mismatched uid: "
   3836                                 + mOutPermissions[1] + " on disk, "
   3837                                 + pkg.applicationInfo.uid + " in settings";
   3838                         // writer
   3839                         synchronized (mPackages) {
   3840                             mSettings.mReadMessages.append(msg);
   3841                             mSettings.mReadMessages.append('\n');
   3842                             uidError = true;
   3843                             if (!pkgSetting.uidError) {
   3844                                 reportSettingsProblem(Log.ERROR, msg);
   3845                             }
   3846                         }
   3847                     }
   3848                 }
   3849                 pkg.applicationInfo.dataDir = dataPath.getPath();
   3850             } else {
   3851                 if (DEBUG_PACKAGE_SCANNING) {
   3852                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   3853                         Log.v(TAG, "Want this data dir: " + dataPath);
   3854                 }
   3855                 //invoke installer to do the actual installation
   3856                 int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid,
   3857                         pkg.applicationInfo.uid);
   3858                 if (ret < 0) {
   3859                     // Error from installer
   3860                     mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   3861                     return null;
   3862                 }
   3863                 // Create data directories for all users
   3864                 sUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid);
   3865 
   3866                 if (dataPath.exists()) {
   3867                     pkg.applicationInfo.dataDir = dataPath.getPath();
   3868                 } else {
   3869                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
   3870                     pkg.applicationInfo.dataDir = null;
   3871                 }
   3872             }
   3873 
   3874             /*
   3875              * Set the data dir to the default "/data/data/<package name>/lib"
   3876              * if we got here without anyone telling us different (e.g., apps
   3877              * stored on SD card have their native libraries stored in the ASEC
   3878              * container with the APK).
   3879              *
   3880              * This happens during an upgrade from a package settings file that
   3881              * doesn't have a native library path attribute at all.
   3882              */
   3883             if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) {
   3884                 if (pkgSetting.nativeLibraryPathString == null) {
   3885                     final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath();
   3886                     pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
   3887                     pkgSetting.nativeLibraryPathString = nativeLibraryPath;
   3888                 } else {
   3889                     pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString;
   3890                 }
   3891             }
   3892 
   3893             pkgSetting.uidError = uidError;
   3894         }
   3895 
   3896         String path = scanFile.getPath();
   3897         /* Note: We don't want to unpack the native binaries for
   3898          *        system applications, unless they have been updated
   3899          *        (the binaries are already under /system/lib).
   3900          *        Also, don't unpack libs for apps on the external card
   3901          *        since they should have their libraries in the ASEC
   3902          *        container already.
   3903          *
   3904          *        In other words, we're going to unpack the binaries
   3905          *        only for non-system apps and system app upgrades.
   3906          */
   3907         if (pkg.applicationInfo.nativeLibraryDir != null) {
   3908             try {
   3909                 final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
   3910                 final String dataPathString = dataPath.getCanonicalPath();
   3911 
   3912                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
   3913                     /*
   3914                      * Upgrading from a previous version of the OS sometimes
   3915                      * leaves native libraries in the /data/data/<app>/lib
   3916                      * directory for system apps even when they shouldn't be.
   3917                      * Recent changes in the JNI library search path
   3918                      * necessitates we remove those to match previous behavior.
   3919                      */
   3920                     if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
   3921                         Log.i(TAG, "removed obsolete native libraries for system package "
   3922                                 + path);
   3923                     }
   3924                 } else if (nativeLibraryDir.getParentFile().getCanonicalPath()
   3925                         .equals(dataPathString)) {
   3926                     /*
   3927                      * Make sure the native library dir isn't a symlink to
   3928                      * something. If it is, ask installd to remove it and create
   3929                      * a directory so we can copy to it afterwards.
   3930                      */
   3931                     boolean isSymLink;
   3932                     try {
   3933                         isSymLink = S_ISLNK(Libcore.os.lstat(nativeLibraryDir.getPath()).st_mode);
   3934                     } catch (ErrnoException e) {
   3935                         // This shouldn't happen, but we'll fail-safe.
   3936                         isSymLink = true;
   3937                     }
   3938                     if (isSymLink) {
   3939                         mInstaller.unlinkNativeLibraryDirectory(dataPathString);
   3940                     }
   3941 
   3942                     /*
   3943                      * If this is an internal application or our
   3944                      * nativeLibraryPath points to our data directory, unpack
   3945                      * the libraries if necessary.
   3946                      */
   3947                     NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir);
   3948                 } else {
   3949                     Slog.i(TAG, "Linking native library dir for " + path);
   3950                     mInstaller.linkNativeLibraryDirectory(dataPathString,
   3951                             pkg.applicationInfo.nativeLibraryDir);
   3952                 }
   3953             } catch (IOException ioe) {
   3954                 Log.e(TAG, "Unable to get canonical file " + ioe.toString());
   3955             }
   3956         }
   3957         pkg.mScanPath = path;
   3958 
   3959         if ((scanMode&SCAN_NO_DEX) == 0) {
   3960             if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0)
   3961                     == DEX_OPT_FAILED) {
   3962                 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT;
   3963                 return null;
   3964             }
   3965         }
   3966 
   3967         if (mFactoryTest && pkg.requestedPermissions.contains(
   3968                 android.Manifest.permission.FACTORY_TEST)) {
   3969             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
   3970         }
   3971 
   3972         // Request the ActivityManager to kill the process(only for existing packages)
   3973         // so that we do not end up in a confused state while the user is still using the older
   3974         // version of the application while the new one gets installed.
   3975         if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   3976             killApplication(pkg.applicationInfo.packageName,
   3977                         pkg.applicationInfo.uid);
   3978         }
   3979 
   3980         // writer
   3981         synchronized (mPackages) {
   3982             // We don't expect installation to fail beyond this point,
   3983             if ((scanMode&SCAN_MONITOR) != 0) {
   3984                 mAppDirs.put(pkg.mPath, pkg);
   3985             }
   3986             // Add the new setting to mSettings
   3987             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
   3988             // Add the new setting to mPackages
   3989             mPackages.put(pkg.applicationInfo.packageName, pkg);
   3990             // Make sure we don't accidentally delete its data.
   3991             mSettings.mPackagesToBeCleaned.remove(pkgName);
   3992 
   3993             // Take care of first install / last update times.
   3994             if (currentTime != 0) {
   3995                 if (pkgSetting.firstInstallTime == 0) {
   3996                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
   3997                 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) {
   3998                     pkgSetting.lastUpdateTime = currentTime;
   3999                 }
   4000             } else if (pkgSetting.firstInstallTime == 0) {
   4001                 // We need *something*.  Take time time stamp of the file.
   4002                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
   4003             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
   4004                 if (scanFileTime != pkgSetting.timeStamp) {
   4005                     // A package on the system image has changed; consider this
   4006                     // to be an update.
   4007                     pkgSetting.lastUpdateTime = scanFileTime;
   4008                 }
   4009             }
   4010 
   4011             int N = pkg.providers.size();
   4012             StringBuilder r = null;
   4013             int i;
   4014             for (i=0; i<N; i++) {
   4015                 PackageParser.Provider p = pkg.providers.get(i);
   4016                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
   4017                         p.info.processName, pkg.applicationInfo.uid);
   4018                 mProvidersByComponent.put(new ComponentName(p.info.packageName,
   4019                         p.info.name), p);
   4020                 p.syncable = p.info.isSyncable;
   4021                 if (p.info.authority != null) {
   4022                     String names[] = p.info.authority.split(";");
   4023                     p.info.authority = null;
   4024                     for (int j = 0; j < names.length; j++) {
   4025                         if (j == 1 && p.syncable) {
   4026                             // We only want the first authority for a provider to possibly be
   4027                             // syncable, so if we already added this provider using a different
   4028                             // authority clear the syncable flag. We copy the provider before
   4029                             // changing it because the mProviders object contains a reference
   4030                             // to a provider that we don't want to change.
   4031                             // Only do this for the second authority since the resulting provider
   4032                             // object can be the same for all future authorities for this provider.
   4033                             p = new PackageParser.Provider(p);
   4034                             p.syncable = false;
   4035                         }
   4036                         if (!mProviders.containsKey(names[j])) {
   4037                             mProviders.put(names[j], p);
   4038                             if (p.info.authority == null) {
   4039                                 p.info.authority = names[j];
   4040                             } else {
   4041                                 p.info.authority = p.info.authority + ";" + names[j];
   4042                             }
   4043                             if (DEBUG_PACKAGE_SCANNING) {
   4044                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   4045                                     Log.d(TAG, "Registered content provider: " + names[j]
   4046                                             + ", className = " + p.info.name + ", isSyncable = "
   4047                                             + p.info.isSyncable);
   4048                             }
   4049                         } else {
   4050                             PackageParser.Provider other = mProviders.get(names[j]);
   4051                             Slog.w(TAG, "Skipping provider name " + names[j] +
   4052                                     " (in package " + pkg.applicationInfo.packageName +
   4053                                     "): name already used by "
   4054                                     + ((other != null && other.getComponentName() != null)
   4055                                             ? other.getComponentName().getPackageName() : "?"));
   4056                         }
   4057                     }
   4058                 }
   4059                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4060                     if (r == null) {
   4061                         r = new StringBuilder(256);
   4062                     } else {
   4063                         r.append(' ');
   4064                     }
   4065                     r.append(p.info.name);
   4066                 }
   4067             }
   4068             if (r != null) {
   4069                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
   4070             }
   4071 
   4072             N = pkg.services.size();
   4073             r = null;
   4074             for (i=0; i<N; i++) {
   4075                 PackageParser.Service s = pkg.services.get(i);
   4076                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
   4077                         s.info.processName, pkg.applicationInfo.uid);
   4078                 mServices.addService(s);
   4079                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4080                     if (r == null) {
   4081                         r = new StringBuilder(256);
   4082                     } else {
   4083                         r.append(' ');
   4084                     }
   4085                     r.append(s.info.name);
   4086                 }
   4087             }
   4088             if (r != null) {
   4089                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
   4090             }
   4091 
   4092             N = pkg.receivers.size();
   4093             r = null;
   4094             for (i=0; i<N; i++) {
   4095                 PackageParser.Activity a = pkg.receivers.get(i);
   4096                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   4097                         a.info.processName, pkg.applicationInfo.uid);
   4098                 mReceivers.addActivity(a, "receiver");
   4099                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4100                     if (r == null) {
   4101                         r = new StringBuilder(256);
   4102                     } else {
   4103                         r.append(' ');
   4104                     }
   4105                     r.append(a.info.name);
   4106                 }
   4107             }
   4108             if (r != null) {
   4109                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
   4110             }
   4111 
   4112             N = pkg.activities.size();
   4113             r = null;
   4114             for (i=0; i<N; i++) {
   4115                 PackageParser.Activity a = pkg.activities.get(i);
   4116                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   4117                         a.info.processName, pkg.applicationInfo.uid);
   4118                 mActivities.addActivity(a, "activity");
   4119                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4120                     if (r == null) {
   4121                         r = new StringBuilder(256);
   4122                     } else {
   4123                         r.append(' ');
   4124                     }
   4125                     r.append(a.info.name);
   4126                 }
   4127             }
   4128             if (r != null) {
   4129                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
   4130             }
   4131 
   4132             N = pkg.permissionGroups.size();
   4133             r = null;
   4134             for (i=0; i<N; i++) {
   4135                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
   4136                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
   4137                 if (cur == null) {
   4138                     mPermissionGroups.put(pg.info.name, pg);
   4139                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4140                         if (r == null) {
   4141                             r = new StringBuilder(256);
   4142                         } else {
   4143                             r.append(' ');
   4144                         }
   4145                         r.append(pg.info.name);
   4146                     }
   4147                 } else {
   4148                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
   4149                             + pg.info.packageName + " ignored: original from "
   4150                             + cur.info.packageName);
   4151                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4152                         if (r == null) {
   4153                             r = new StringBuilder(256);
   4154                         } else {
   4155                             r.append(' ');
   4156                         }
   4157                         r.append("DUP:");
   4158                         r.append(pg.info.name);
   4159                     }
   4160                 }
   4161             }
   4162             if (r != null) {
   4163                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
   4164             }
   4165 
   4166             N = pkg.permissions.size();
   4167             r = null;
   4168             for (i=0; i<N; i++) {
   4169                 PackageParser.Permission p = pkg.permissions.get(i);
   4170                 HashMap<String, BasePermission> permissionMap =
   4171                         p.tree ? mSettings.mPermissionTrees
   4172                         : mSettings.mPermissions;
   4173                 p.group = mPermissionGroups.get(p.info.group);
   4174                 if (p.info.group == null || p.group != null) {
   4175                     BasePermission bp = permissionMap.get(p.info.name);
   4176                     if (bp == null) {
   4177                         bp = new BasePermission(p.info.name, p.info.packageName,
   4178                                 BasePermission.TYPE_NORMAL);
   4179                         permissionMap.put(p.info.name, bp);
   4180                     }
   4181                     if (bp.perm == null) {
   4182                         if (bp.sourcePackage == null
   4183                                 || bp.sourcePackage.equals(p.info.packageName)) {
   4184                             BasePermission tree = findPermissionTreeLP(p.info.name);
   4185                             if (tree == null
   4186                                     || tree.sourcePackage.equals(p.info.packageName)) {
   4187                                 bp.packageSetting = pkgSetting;
   4188                                 bp.perm = p;
   4189                                 bp.uid = pkg.applicationInfo.uid;
   4190                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4191                                     if (r == null) {
   4192                                         r = new StringBuilder(256);
   4193                                     } else {
   4194                                         r.append(' ');
   4195                                     }
   4196                                     r.append(p.info.name);
   4197                                 }
   4198                             } else {
   4199                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
   4200                                         + p.info.packageName + " ignored: base tree "
   4201                                         + tree.name + " is from package "
   4202                                         + tree.sourcePackage);
   4203                             }
   4204                         } else {
   4205                             Slog.w(TAG, "Permission " + p.info.name + " from package "
   4206                                     + p.info.packageName + " ignored: original from "
   4207                                     + bp.sourcePackage);
   4208                         }
   4209                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4210                         if (r == null) {
   4211                             r = new StringBuilder(256);
   4212                         } else {
   4213                             r.append(' ');
   4214                         }
   4215                         r.append("DUP:");
   4216                         r.append(p.info.name);
   4217                     }
   4218                     if (bp.perm == p) {
   4219                         bp.protectionLevel = p.info.protectionLevel;
   4220                     }
   4221                 } else {
   4222                     Slog.w(TAG, "Permission " + p.info.name + " from package "
   4223                             + p.info.packageName + " ignored: no group "
   4224                             + p.group);
   4225                 }
   4226             }
   4227             if (r != null) {
   4228                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
   4229             }
   4230 
   4231             N = pkg.instrumentation.size();
   4232             r = null;
   4233             for (i=0; i<N; i++) {
   4234                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   4235                 a.info.packageName = pkg.applicationInfo.packageName;
   4236                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
   4237                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
   4238                 a.info.dataDir = pkg.applicationInfo.dataDir;
   4239                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
   4240                 mInstrumentation.put(a.getComponentName(), a);
   4241                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   4242                     if (r == null) {
   4243                         r = new StringBuilder(256);
   4244                     } else {
   4245                         r.append(' ');
   4246                     }
   4247                     r.append(a.info.name);
   4248                 }
   4249             }
   4250             if (r != null) {
   4251                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
   4252             }
   4253 
   4254             if (pkg.protectedBroadcasts != null) {
   4255                 N = pkg.protectedBroadcasts.size();
   4256                 for (i=0; i<N; i++) {
   4257                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
   4258                 }
   4259             }
   4260 
   4261             pkgSetting.setTimeStamp(scanFileTime);
   4262         }
   4263 
   4264         return pkg;
   4265     }
   4266 
   4267     private void killApplication(String pkgName, int uid) {
   4268         // Request the ActivityManager to kill the process(only for existing packages)
   4269         // so that we do not end up in a confused state while the user is still using the older
   4270         // version of the application while the new one gets installed.
   4271         IActivityManager am = ActivityManagerNative.getDefault();
   4272         if (am != null) {
   4273             try {
   4274                 am.killApplicationWithUid(pkgName, uid);
   4275             } catch (RemoteException e) {
   4276             }
   4277         }
   4278     }
   4279 
   4280     void removePackageLI(PackageParser.Package pkg, boolean chatty) {
   4281         if (DEBUG_INSTALL) {
   4282             if (chatty)
   4283                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
   4284         }
   4285 
   4286         // writer
   4287         synchronized (mPackages) {
   4288             mPackages.remove(pkg.applicationInfo.packageName);
   4289             if (pkg.mPath != null) {
   4290                 mAppDirs.remove(pkg.mPath);
   4291             }
   4292 
   4293             int N = pkg.providers.size();
   4294             StringBuilder r = null;
   4295             int i;
   4296             for (i=0; i<N; i++) {
   4297                 PackageParser.Provider p = pkg.providers.get(i);
   4298                 mProvidersByComponent.remove(new ComponentName(p.info.packageName,
   4299                         p.info.name));
   4300                 if (p.info.authority == null) {
   4301 
   4302                     /* The is another ContentProvider with this authority when
   4303                      * this app was installed so this authority is null,
   4304                      * Ignore it as we don't have to unregister the provider.
   4305                      */
   4306                     continue;
   4307                 }
   4308                 String names[] = p.info.authority.split(";");
   4309                 for (int j = 0; j < names.length; j++) {
   4310                     if (mProviders.get(names[j]) == p) {
   4311                         mProviders.remove(names[j]);
   4312                         if (DEBUG_REMOVE) {
   4313                             if (chatty)
   4314                                 Log.d(TAG, "Unregistered content provider: " + names[j]
   4315                                         + ", className = " + p.info.name + ", isSyncable = "
   4316                                         + p.info.isSyncable);
   4317                         }
   4318                     }
   4319                 }
   4320                 if (chatty) {
   4321                     if (r == null) {
   4322                         r = new StringBuilder(256);
   4323                     } else {
   4324                         r.append(' ');
   4325                     }
   4326                     r.append(p.info.name);
   4327                 }
   4328             }
   4329             if (r != null) {
   4330                 if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
   4331             }
   4332 
   4333             N = pkg.services.size();
   4334             r = null;
   4335             for (i=0; i<N; i++) {
   4336                 PackageParser.Service s = pkg.services.get(i);
   4337                 mServices.removeService(s);
   4338                 if (chatty) {
   4339                     if (r == null) {
   4340                         r = new StringBuilder(256);
   4341                     } else {
   4342                         r.append(' ');
   4343                     }
   4344                     r.append(s.info.name);
   4345                 }
   4346             }
   4347             if (r != null) {
   4348                 if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
   4349             }
   4350 
   4351             N = pkg.receivers.size();
   4352             r = null;
   4353             for (i=0; i<N; i++) {
   4354                 PackageParser.Activity a = pkg.receivers.get(i);
   4355                 mReceivers.removeActivity(a, "receiver");
   4356                 if (chatty) {
   4357                     if (r == null) {
   4358                         r = new StringBuilder(256);
   4359                     } else {
   4360                         r.append(' ');
   4361                     }
   4362                     r.append(a.info.name);
   4363                 }
   4364             }
   4365             if (r != null) {
   4366                 if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
   4367             }
   4368 
   4369             N = pkg.activities.size();
   4370             r = null;
   4371             for (i=0; i<N; i++) {
   4372                 PackageParser.Activity a = pkg.activities.get(i);
   4373                 mActivities.removeActivity(a, "activity");
   4374                 if (chatty) {
   4375                     if (r == null) {
   4376                         r = new StringBuilder(256);
   4377                     } else {
   4378                         r.append(' ');
   4379                     }
   4380                     r.append(a.info.name);
   4381                 }
   4382             }
   4383             if (r != null) {
   4384                 if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
   4385             }
   4386 
   4387             N = pkg.permissions.size();
   4388             r = null;
   4389             for (i=0; i<N; i++) {
   4390                 PackageParser.Permission p = pkg.permissions.get(i);
   4391                 BasePermission bp = mSettings.mPermissions.get(p.info.name);
   4392                 if (bp == null) {
   4393                     bp = mSettings.mPermissionTrees.get(p.info.name);
   4394                 }
   4395                 if (bp != null && bp.perm == p) {
   4396                     bp.perm = null;
   4397                     if (chatty) {
   4398                         if (r == null) {
   4399                             r = new StringBuilder(256);
   4400                         } else {
   4401                             r.append(' ');
   4402                         }
   4403                         r.append(p.info.name);
   4404                     }
   4405                 }
   4406             }
   4407             if (r != null) {
   4408                 if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   4409             }
   4410 
   4411             N = pkg.instrumentation.size();
   4412             r = null;
   4413             for (i=0; i<N; i++) {
   4414                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   4415                 mInstrumentation.remove(a.getComponentName());
   4416                 if (chatty) {
   4417                     if (r == null) {
   4418                         r = new StringBuilder(256);
   4419                     } else {
   4420                         r.append(' ');
   4421                     }
   4422                     r.append(a.info.name);
   4423                 }
   4424             }
   4425             if (r != null) {
   4426                 if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
   4427             }
   4428         }
   4429     }
   4430 
   4431     private static final boolean isPackageFilename(String name) {
   4432         return name != null && name.endsWith(".apk");
   4433     }
   4434 
   4435     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
   4436         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
   4437             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
   4438                 return true;
   4439             }
   4440         }
   4441         return false;
   4442     }
   4443 
   4444     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
   4445     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
   4446     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
   4447 
   4448     private void updatePermissionsLPw(String changingPkg,
   4449             PackageParser.Package pkgInfo, int flags) {
   4450         // Make sure there are no dangling permission trees.
   4451         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
   4452         while (it.hasNext()) {
   4453             final BasePermission bp = it.next();
   4454             if (bp.packageSetting == null) {
   4455                 // We may not yet have parsed the package, so just see if
   4456                 // we still know about its settings.
   4457                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   4458             }
   4459             if (bp.packageSetting == null) {
   4460                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
   4461                         + " from package " + bp.sourcePackage);
   4462                 it.remove();
   4463             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   4464                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   4465                     Slog.i(TAG, "Removing old permission tree: " + bp.name
   4466                             + " from package " + bp.sourcePackage);
   4467                     flags |= UPDATE_PERMISSIONS_ALL;
   4468                     it.remove();
   4469                 }
   4470             }
   4471         }
   4472 
   4473         // Make sure all dynamic permissions have been assigned to a package,
   4474         // and make sure there are no dangling permissions.
   4475         it = mSettings.mPermissions.values().iterator();
   4476         while (it.hasNext()) {
   4477             final BasePermission bp = it.next();
   4478             if (bp.type == BasePermission.TYPE_DYNAMIC) {
   4479                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
   4480                         + bp.name + " pkg=" + bp.sourcePackage
   4481                         + " info=" + bp.pendingInfo);
   4482                 if (bp.packageSetting == null && bp.pendingInfo != null) {
   4483                     final BasePermission tree = findPermissionTreeLP(bp.name);
   4484                     if (tree != null && tree.perm != null) {
   4485                         bp.packageSetting = tree.packageSetting;
   4486                         bp.perm = new PackageParser.Permission(tree.perm.owner,
   4487                                 new PermissionInfo(bp.pendingInfo));
   4488                         bp.perm.info.packageName = tree.perm.info.packageName;
   4489                         bp.perm.info.name = bp.name;
   4490                         bp.uid = tree.uid;
   4491                     }
   4492                 }
   4493             }
   4494             if (bp.packageSetting == null) {
   4495                 // We may not yet have parsed the package, so just see if
   4496                 // we still know about its settings.
   4497                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   4498             }
   4499             if (bp.packageSetting == null) {
   4500                 Slog.w(TAG, "Removing dangling permission: " + bp.name
   4501                         + " from package " + bp.sourcePackage);
   4502                 it.remove();
   4503             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   4504                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   4505                     Slog.i(TAG, "Removing old permission: " + bp.name
   4506                             + " from package " + bp.sourcePackage);
   4507                     flags |= UPDATE_PERMISSIONS_ALL;
   4508                     it.remove();
   4509                 }
   4510             }
   4511         }
   4512 
   4513         // Now update the permissions for all packages, in particular
   4514         // replace the granted permissions of the system packages.
   4515         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
   4516             for (PackageParser.Package pkg : mPackages.values()) {
   4517                 if (pkg != pkgInfo) {
   4518                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
   4519                 }
   4520             }
   4521         }
   4522 
   4523         if (pkgInfo != null) {
   4524             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0);
   4525         }
   4526     }
   4527 
   4528     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) {
   4529         final PackageSetting ps = (PackageSetting) pkg.mExtras;
   4530         if (ps == null) {
   4531             return;
   4532         }
   4533         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   4534         HashSet<String> origPermissions = gp.grantedPermissions;
   4535         boolean changedPermission = false;
   4536 
   4537         if (replace) {
   4538             ps.permissionsFixed = false;
   4539             if (gp == ps) {
   4540                 origPermissions = new HashSet<String>(gp.grantedPermissions);
   4541                 gp.grantedPermissions.clear();
   4542                 gp.gids = mGlobalGids;
   4543             }
   4544         }
   4545 
   4546         if (gp.gids == null) {
   4547             gp.gids = mGlobalGids;
   4548         }
   4549 
   4550         final int N = pkg.requestedPermissions.size();
   4551         for (int i=0; i<N; i++) {
   4552             final String name = pkg.requestedPermissions.get(i);
   4553             //final boolean required = pkg.requestedPermssionsRequired.get(i);
   4554             final BasePermission bp = mSettings.mPermissions.get(name);
   4555             if (DEBUG_INSTALL) {
   4556                 if (gp != ps) {
   4557                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
   4558                 }
   4559             }
   4560             if (bp != null && bp.packageSetting != null) {
   4561                 final String perm = bp.name;
   4562                 boolean allowed;
   4563                 boolean allowedSig = false;
   4564                 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
   4565                 if (level == PermissionInfo.PROTECTION_NORMAL
   4566                         || level == PermissionInfo.PROTECTION_DANGEROUS) {
   4567                     allowed = true;
   4568                 } else if (bp.packageSetting == null) {
   4569                     // This permission is invalid; skip it.
   4570                     allowed = false;
   4571                 } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
   4572                     allowed = (compareSignatures(
   4573                             bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
   4574                                     == PackageManager.SIGNATURE_MATCH)
   4575                             || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
   4576                                     == PackageManager.SIGNATURE_MATCH);
   4577                     if (!allowed && (bp.protectionLevel
   4578                             & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
   4579                         if (isSystemApp(pkg)) {
   4580                             // For updated system applications, a system permission
   4581                             // is granted only if it had been defined by the original application.
   4582                             if (isUpdatedSystemApp(pkg)) {
   4583                                 final PackageSetting sysPs = mSettings
   4584                                         .