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