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 android.content.pm.PackageManager.INSTALL_EXTERNAL;
     27 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
     28 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
     29 import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
     30 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
     31 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
     32 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
     33 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
     34 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
     35 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
     36 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
     37 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
     38 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
     39 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
     40 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
     41 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
     42 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
     43 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
     44 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
     45 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
     46 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
     47 import static android.content.pm.PackageParser.isApkFile;
     48 import static android.os.Process.PACKAGE_INFO_GID;
     49 import static android.os.Process.SYSTEM_UID;
     50 import static android.system.OsConstants.O_CREAT;
     51 import static android.system.OsConstants.O_RDWR;
     52 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
     53 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
     54 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
     55 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
     56 import static com.android.internal.util.ArrayUtils.appendInt;
     57 import static com.android.internal.util.ArrayUtils.removeInt;
     58 
     59 import android.util.ArrayMap;
     60 
     61 import com.android.internal.R;
     62 import com.android.internal.app.IMediaContainerService;
     63 import com.android.internal.app.ResolverActivity;
     64 import com.android.internal.content.NativeLibraryHelper;
     65 import com.android.internal.content.PackageHelper;
     66 import com.android.internal.os.IParcelFileDescriptorFactory;
     67 import com.android.internal.util.ArrayUtils;
     68 import com.android.internal.util.FastPrintWriter;
     69 import com.android.internal.util.FastXmlSerializer;
     70 import com.android.internal.util.IndentingPrintWriter;
     71 import com.android.server.EventLogTags;
     72 import com.android.server.IntentResolver;
     73 import com.android.server.LocalServices;
     74 import com.android.server.ServiceThread;
     75 import com.android.server.SystemConfig;
     76 import com.android.server.Watchdog;
     77 import com.android.server.pm.Settings.DatabaseVersion;
     78 import com.android.server.storage.DeviceStorageMonitorInternal;
     79 
     80 import org.xmlpull.v1.XmlSerializer;
     81 
     82 import android.app.ActivityManager;
     83 import android.app.ActivityManagerNative;
     84 import android.app.AppGlobals;
     85 import android.app.IActivityManager;
     86 import android.app.admin.IDevicePolicyManager;
     87 import android.app.backup.IBackupManager;
     88 import android.app.usage.UsageStats;
     89 import android.app.usage.UsageStatsManager;
     90 import android.content.BroadcastReceiver;
     91 import android.content.ComponentName;
     92 import android.content.Context;
     93 import android.content.IIntentReceiver;
     94 import android.content.Intent;
     95 import android.content.IntentFilter;
     96 import android.content.IntentSender;
     97 import android.content.IntentSender.SendIntentException;
     98 import android.content.ServiceConnection;
     99 import android.content.pm.ActivityInfo;
    100 import android.content.pm.ApplicationInfo;
    101 import android.content.pm.FeatureInfo;
    102 import android.content.pm.IPackageDataObserver;
    103 import android.content.pm.IPackageDeleteObserver;
    104 import android.content.pm.IPackageDeleteObserver2;
    105 import android.content.pm.IPackageInstallObserver2;
    106 import android.content.pm.IPackageInstaller;
    107 import android.content.pm.IPackageManager;
    108 import android.content.pm.IPackageMoveObserver;
    109 import android.content.pm.IPackageStatsObserver;
    110 import android.content.pm.InstrumentationInfo;
    111 import android.content.pm.KeySet;
    112 import android.content.pm.ManifestDigest;
    113 import android.content.pm.PackageCleanItem;
    114 import android.content.pm.PackageInfo;
    115 import android.content.pm.PackageInfoLite;
    116 import android.content.pm.PackageInstaller;
    117 import android.content.pm.PackageManager;
    118 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
    119 import android.content.pm.PackageParser.ActivityIntentInfo;
    120 import android.content.pm.PackageParser.PackageLite;
    121 import android.content.pm.PackageParser.PackageParserException;
    122 import android.content.pm.PackageParser;
    123 import android.content.pm.PackageStats;
    124 import android.content.pm.PackageUserState;
    125 import android.content.pm.ParceledListSlice;
    126 import android.content.pm.PermissionGroupInfo;
    127 import android.content.pm.PermissionInfo;
    128 import android.content.pm.ProviderInfo;
    129 import android.content.pm.ResolveInfo;
    130 import android.content.pm.ServiceInfo;
    131 import android.content.pm.Signature;
    132 import android.content.pm.UserInfo;
    133 import android.content.pm.VerificationParams;
    134 import android.content.pm.VerifierDeviceIdentity;
    135 import android.content.pm.VerifierInfo;
    136 import android.content.res.Resources;
    137 import android.hardware.display.DisplayManager;
    138 import android.net.Uri;
    139 import android.os.Binder;
    140 import android.os.Build;
    141 import android.os.Bundle;
    142 import android.os.Environment;
    143 import android.os.Environment.UserEnvironment;
    144 import android.os.storage.IMountService;
    145 import android.os.storage.StorageManager;
    146 import android.os.Debug;
    147 import android.os.FileUtils;
    148 import android.os.Handler;
    149 import android.os.IBinder;
    150 import android.os.Looper;
    151 import android.os.Message;
    152 import android.os.Parcel;
    153 import android.os.ParcelFileDescriptor;
    154 import android.os.Process;
    155 import android.os.RemoteException;
    156 import android.os.SELinux;
    157 import android.os.ServiceManager;
    158 import android.os.SystemClock;
    159 import android.os.SystemProperties;
    160 import android.os.UserHandle;
    161 import android.os.UserManager;
    162 import android.security.KeyStore;
    163 import android.security.SystemKeyStore;
    164 import android.system.ErrnoException;
    165 import android.system.Os;
    166 import android.system.StructStat;
    167 import android.text.TextUtils;
    168 import android.text.format.DateUtils;
    169 import android.util.ArraySet;
    170 import android.util.AtomicFile;
    171 import android.util.DisplayMetrics;
    172 import android.util.EventLog;
    173 import android.util.ExceptionUtils;
    174 import android.util.Log;
    175 import android.util.LogPrinter;
    176 import android.util.PrintStreamPrinter;
    177 import android.util.Slog;
    178 import android.util.SparseArray;
    179 import android.util.SparseBooleanArray;
    180 import android.view.Display;
    181 
    182 import java.io.BufferedInputStream;
    183 import java.io.BufferedOutputStream;
    184 import java.io.BufferedReader;
    185 import java.io.File;
    186 import java.io.FileDescriptor;
    187 import java.io.FileInputStream;
    188 import java.io.FileNotFoundException;
    189 import java.io.FileOutputStream;
    190 import java.io.FileReader;
    191 import java.io.FilenameFilter;
    192 import java.io.IOException;
    193 import java.io.InputStream;
    194 import java.io.PrintWriter;
    195 import java.nio.charset.StandardCharsets;
    196 import java.security.NoSuchAlgorithmException;
    197 import java.security.PublicKey;
    198 import java.security.cert.CertificateEncodingException;
    199 import java.security.cert.CertificateException;
    200 import java.text.SimpleDateFormat;
    201 import java.util.ArrayList;
    202 import java.util.Arrays;
    203 import java.util.Collection;
    204 import java.util.Collections;
    205 import java.util.Comparator;
    206 import java.util.Date;
    207 import java.util.Iterator;
    208 import java.util.List;
    209 import java.util.Map;
    210 import java.util.Objects;
    211 import java.util.Set;
    212 import java.util.concurrent.atomic.AtomicBoolean;
    213 import java.util.concurrent.atomic.AtomicLong;
    214 
    215 import dalvik.system.DexFile;
    216 import dalvik.system.StaleDexCacheError;
    217 import dalvik.system.VMRuntime;
    218 
    219 import libcore.io.IoUtils;
    220 import libcore.util.EmptyArray;
    221 
    222 /**
    223  * Keep track of all those .apks everywhere.
    224  *
    225  * This is very central to the platform's security; please run the unit
    226  * tests whenever making modifications here:
    227  *
    228 mmm frameworks/base/tests/AndroidTests
    229 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
    230 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
    231  *
    232  * {@hide}
    233  */
    234 public class PackageManagerService extends IPackageManager.Stub {
    235     static final String TAG = "PackageManager";
    236     static final boolean DEBUG_SETTINGS = false;
    237     static final boolean DEBUG_PREFERRED = false;
    238     static final boolean DEBUG_UPGRADE = false;
    239     private static final boolean DEBUG_INSTALL = false;
    240     private static final boolean DEBUG_REMOVE = false;
    241     private static final boolean DEBUG_BROADCASTS = false;
    242     private static final boolean DEBUG_SHOW_INFO = false;
    243     private static final boolean DEBUG_PACKAGE_INFO = false;
    244     private static final boolean DEBUG_INTENT_MATCHING = false;
    245     private static final boolean DEBUG_PACKAGE_SCANNING = false;
    246     private static final boolean DEBUG_VERIFY = false;
    247     private static final boolean DEBUG_DEXOPT = false;
    248     private static final boolean DEBUG_ABI_SELECTION = false;
    249 
    250     private static final int RADIO_UID = Process.PHONE_UID;
    251     private static final int LOG_UID = Process.LOG_UID;
    252     private static final int NFC_UID = Process.NFC_UID;
    253     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
    254     private static final int SHELL_UID = Process.SHELL_UID;
    255 
    256     // Cap the size of permission trees that 3rd party apps can define
    257     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
    258 
    259     // Suffix used during package installation when copying/moving
    260     // package apks to install directory.
    261     private static final String INSTALL_PACKAGE_SUFFIX = "-";
    262 
    263     static final int SCAN_NO_DEX = 1<<1;
    264     static final int SCAN_FORCE_DEX = 1<<2;
    265     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
    266     static final int SCAN_NEW_INSTALL = 1<<4;
    267     static final int SCAN_NO_PATHS = 1<<5;
    268     static final int SCAN_UPDATE_TIME = 1<<6;
    269     static final int SCAN_DEFER_DEX = 1<<7;
    270     static final int SCAN_BOOTING = 1<<8;
    271     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
    272     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
    273     static final int SCAN_REPLACING = 1<<11;
    274     static final int SCAN_REQUIRE_KNOWN = 1<<12;
    275 
    276     static final int REMOVE_CHATTY = 1<<16;
    277 
    278     /**
    279      * Timeout (in milliseconds) after which the watchdog should declare that
    280      * our handler thread is wedged.  The usual default for such things is one
    281      * minute but we sometimes do very lengthy I/O operations on this thread,
    282      * such as installing multi-gigabyte applications, so ours needs to be longer.
    283      */
    284     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
    285 
    286     /**
    287      * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
    288      * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
    289      * settings entry if available, otherwise we use the hardcoded default.  If it's been
    290      * more than this long since the last fstrim, we force one during the boot sequence.
    291      *
    292      * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
    293      * one gets run at the next available charging+idle time.  This final mandatory
    294      * no-fstrim check kicks in only of the other scheduling criteria is never met.
    295      */
    296     private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
    297 
    298     /**
    299      * Whether verification is enabled by default.
    300      */
    301     private static final boolean DEFAULT_VERIFY_ENABLE = true;
    302 
    303     /**
    304      * The default maximum time to wait for the verification agent to return in
    305      * milliseconds.
    306      */
    307     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
    308 
    309     /**
    310      * The default response for package verification timeout.
    311      *
    312      * This can be either PackageManager.VERIFICATION_ALLOW or
    313      * PackageManager.VERIFICATION_REJECT.
    314      */
    315     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
    316 
    317     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
    318 
    319     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
    320             DEFAULT_CONTAINER_PACKAGE,
    321             "com.android.defcontainer.DefaultContainerService");
    322 
    323     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
    324 
    325     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
    326 
    327     private static String sPreferredInstructionSet;
    328 
    329     final ServiceThread mHandlerThread;
    330 
    331     private static final String IDMAP_PREFIX = "/data/resource-cache/";
    332     private static final String IDMAP_SUFFIX = "@idmap";
    333 
    334     final PackageHandler mHandler;
    335 
    336     /**
    337      * Messages for {@link #mHandler} that need to wait for system ready before
    338      * being dispatched.
    339      */
    340     private ArrayList<Message> mPostSystemReadyMessages;
    341 
    342     final int mSdkVersion = Build.VERSION.SDK_INT;
    343 
    344     final Context mContext;
    345     final boolean mFactoryTest;
    346     final boolean mOnlyCore;
    347     final boolean mLazyDexOpt;
    348     final long mDexOptLRUThresholdInMills;
    349     final DisplayMetrics mMetrics;
    350     final int mDefParseFlags;
    351     final String[] mSeparateProcesses;
    352     final boolean mIsUpgrade;
    353 
    354     // This is where all application persistent data goes.
    355     final File mAppDataDir;
    356 
    357     // This is where all application persistent data goes for secondary users.
    358     final File mUserAppDataDir;
    359 
    360     /** The location for ASEC container files on internal storage. */
    361     final String mAsecInternalPath;
    362 
    363     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
    364     // LOCK HELD.  Can be called with mInstallLock held.
    365     final Installer mInstaller;
    366 
    367     /** Directory where installed third-party apps stored */
    368     final File mAppInstallDir;
    369 
    370     /**
    371      * Directory to which applications installed internally have their
    372      * 32 bit native libraries copied.
    373      */
    374     private File mAppLib32InstallDir;
    375 
    376     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
    377     // apps.
    378     final File mDrmAppPrivateInstallDir;
    379 
    380     // ----------------------------------------------------------------
    381 
    382     // Lock for state used when installing and doing other long running
    383     // operations.  Methods that must be called with this lock held have
    384     // the suffix "LI".
    385     final Object mInstallLock = new Object();
    386 
    387     // ----------------------------------------------------------------
    388 
    389     // Keys are String (package name), values are Package.  This also serves
    390     // as the lock for the global state.  Methods that must be called with
    391     // this lock held have the prefix "LP".
    392     final ArrayMap<String, PackageParser.Package> mPackages =
    393             new ArrayMap<String, PackageParser.Package>();
    394 
    395     // Tracks available target package names -> overlay package paths.
    396     final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays =
    397         new ArrayMap<String, ArrayMap<String, PackageParser.Package>>();
    398 
    399     final Settings mSettings;
    400     boolean mRestoredSettings;
    401 
    402     // System configuration read by SystemConfig.
    403     final int[] mGlobalGids;
    404     final SparseArray<ArraySet<String>> mSystemPermissions;
    405     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
    406 
    407     // If mac_permissions.xml was found for seinfo labeling.
    408     boolean mFoundPolicyFile;
    409 
    410     // If a recursive restorecon of /data/data/<pkg> is needed.
    411     private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
    412 
    413     public static final class SharedLibraryEntry {
    414         public final String path;
    415         public final String apk;
    416 
    417         SharedLibraryEntry(String _path, String _apk) {
    418             path = _path;
    419             apk = _apk;
    420         }
    421     }
    422 
    423     // Currently known shared libraries.
    424     final ArrayMap<String, SharedLibraryEntry> mSharedLibraries =
    425             new ArrayMap<String, SharedLibraryEntry>();
    426 
    427     // All available activities, for your resolving pleasure.
    428     final ActivityIntentResolver mActivities =
    429             new ActivityIntentResolver();
    430 
    431     // All available receivers, for your resolving pleasure.
    432     final ActivityIntentResolver mReceivers =
    433             new ActivityIntentResolver();
    434 
    435     // All available services, for your resolving pleasure.
    436     final ServiceIntentResolver mServices = new ServiceIntentResolver();
    437 
    438     // All available providers, for your resolving pleasure.
    439     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
    440 
    441     // Mapping from provider base names (first directory in content URI codePath)
    442     // to the provider information.
    443     final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
    444             new ArrayMap<String, PackageParser.Provider>();
    445 
    446     // Mapping from instrumentation class names to info about them.
    447     final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
    448             new ArrayMap<ComponentName, PackageParser.Instrumentation>();
    449 
    450     // Mapping from permission names to info about them.
    451     final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
    452             new ArrayMap<String, PackageParser.PermissionGroup>();
    453 
    454     // Packages whose data we have transfered into another package, thus
    455     // should no longer exist.
    456     final ArraySet<String> mTransferedPackages = new ArraySet<String>();
    457 
    458     // Broadcast actions that are only available to the system.
    459     final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
    460 
    461     /** List of packages waiting for verification. */
    462     final SparseArray<PackageVerificationState> mPendingVerification
    463             = new SparseArray<PackageVerificationState>();
    464 
    465     /** Set of packages associated with each app op permission. */
    466     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
    467 
    468     final PackageInstallerService mInstallerService;
    469 
    470     ArraySet<PackageParser.Package> mDeferredDexOpt = null;
    471 
    472     // Cache of users who need badging.
    473     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
    474 
    475     /** Token for keys in mPendingVerification. */
    476     private int mPendingVerificationToken = 0;
    477 
    478     volatile boolean mSystemReady;
    479     volatile boolean mSafeMode;
    480     volatile boolean mHasSystemUidErrors;
    481 
    482     ApplicationInfo mAndroidApplication;
    483     final ActivityInfo mResolveActivity = new ActivityInfo();
    484     final ResolveInfo mResolveInfo = new ResolveInfo();
    485     ComponentName mResolveComponentName;
    486     PackageParser.Package mPlatformPackage;
    487     ComponentName mCustomResolverComponentName;
    488 
    489     boolean mResolverReplaced = false;
    490 
    491     // Set of pending broadcasts for aggregating enable/disable of components.
    492     static class PendingPackageBroadcasts {
    493         // for each user id, a map of <package name -> components within that package>
    494         final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
    495 
    496         public PendingPackageBroadcasts() {
    497             mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
    498         }
    499 
    500         public ArrayList<String> get(int userId, String packageName) {
    501             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
    502             return packages.get(packageName);
    503         }
    504 
    505         public void put(int userId, String packageName, ArrayList<String> components) {
    506             ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
    507             packages.put(packageName, components);
    508         }
    509 
    510         public void remove(int userId, String packageName) {
    511             ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
    512             if (packages != null) {
    513                 packages.remove(packageName);
    514             }
    515         }
    516 
    517         public void remove(int userId) {
    518             mUidMap.remove(userId);
    519         }
    520 
    521         public int userIdCount() {
    522             return mUidMap.size();
    523         }
    524 
    525         public int userIdAt(int n) {
    526             return mUidMap.keyAt(n);
    527         }
    528 
    529         public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
    530             return mUidMap.get(userId);
    531         }
    532 
    533         public int size() {
    534             // total number of pending broadcast entries across all userIds
    535             int num = 0;
    536             for (int i = 0; i< mUidMap.size(); i++) {
    537                 num += mUidMap.valueAt(i).size();
    538             }
    539             return num;
    540         }
    541 
    542         public void clear() {
    543             mUidMap.clear();
    544         }
    545 
    546         private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
    547             ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
    548             if (map == null) {
    549                 map = new ArrayMap<String, ArrayList<String>>();
    550                 mUidMap.put(userId, map);
    551             }
    552             return map;
    553         }
    554     }
    555     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
    556 
    557     // Service Connection to remote media container service to copy
    558     // package uri's from external media onto secure containers
    559     // or internal storage.
    560     private IMediaContainerService mContainerService = null;
    561 
    562     static final int SEND_PENDING_BROADCAST = 1;
    563     static final int MCS_BOUND = 3;
    564     static final int END_COPY = 4;
    565     static final int INIT_COPY = 5;
    566     static final int MCS_UNBIND = 6;
    567     static final int START_CLEANING_PACKAGE = 7;
    568     static final int FIND_INSTALL_LOC = 8;
    569     static final int POST_INSTALL = 9;
    570     static final int MCS_RECONNECT = 10;
    571     static final int MCS_GIVE_UP = 11;
    572     static final int UPDATED_MEDIA_STATUS = 12;
    573     static final int WRITE_SETTINGS = 13;
    574     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
    575     static final int PACKAGE_VERIFIED = 15;
    576     static final int CHECK_PENDING_VERIFICATION = 16;
    577 
    578     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
    579 
    580     // Delay time in millisecs
    581     static final int BROADCAST_DELAY = 10 * 1000;
    582 
    583     static UserManagerService sUserManager;
    584 
    585     // Stores a list of users whose package restrictions file needs to be updated
    586     private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
    587 
    588     final private DefaultContainerConnection mDefContainerConn =
    589             new DefaultContainerConnection();
    590     class DefaultContainerConnection implements ServiceConnection {
    591         public void onServiceConnected(ComponentName name, IBinder service) {
    592             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
    593             IMediaContainerService imcs =
    594                 IMediaContainerService.Stub.asInterface(service);
    595             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
    596         }
    597 
    598         public void onServiceDisconnected(ComponentName name) {
    599             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
    600         }
    601     };
    602 
    603     // Recordkeeping of restore-after-install operations that are currently in flight
    604     // between the Package Manager and the Backup Manager
    605     class PostInstallData {
    606         public InstallArgs args;
    607         public PackageInstalledInfo res;
    608 
    609         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
    610             args = _a;
    611             res = _r;
    612         }
    613     };
    614     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
    615     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
    616 
    617     private final String mRequiredVerifierPackage;
    618 
    619     private final PackageUsage mPackageUsage = new PackageUsage();
    620 
    621     private class PackageUsage {
    622         private static final int WRITE_INTERVAL
    623             = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
    624 
    625         private final Object mFileLock = new Object();
    626         private final AtomicLong mLastWritten = new AtomicLong(0);
    627         private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
    628 
    629         private boolean mIsHistoricalPackageUsageAvailable = true;
    630 
    631         boolean isHistoricalPackageUsageAvailable() {
    632             return mIsHistoricalPackageUsageAvailable;
    633         }
    634 
    635         void write(boolean force) {
    636             if (force) {
    637                 writeInternal();
    638                 return;
    639             }
    640             if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
    641                 && !DEBUG_DEXOPT) {
    642                 return;
    643             }
    644             if (mBackgroundWriteRunning.compareAndSet(false, true)) {
    645                 new Thread("PackageUsage_DiskWriter") {
    646                     @Override
    647                     public void run() {
    648                         try {
    649                             writeInternal();
    650                         } finally {
    651                             mBackgroundWriteRunning.set(false);
    652                         }
    653                     }
    654                 }.start();
    655             }
    656         }
    657 
    658         private void writeInternal() {
    659             synchronized (mPackages) {
    660                 synchronized (mFileLock) {
    661                     AtomicFile file = getFile();
    662                     FileOutputStream f = null;
    663                     try {
    664                         f = file.startWrite();
    665                         BufferedOutputStream out = new BufferedOutputStream(f);
    666                         FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID);
    667                         StringBuilder sb = new StringBuilder();
    668                         for (PackageParser.Package pkg : mPackages.values()) {
    669                             if (pkg.mLastPackageUsageTimeInMills == 0) {
    670                                 continue;
    671                             }
    672                             sb.setLength(0);
    673                             sb.append(pkg.packageName);
    674                             sb.append(' ');
    675                             sb.append((long)pkg.mLastPackageUsageTimeInMills);
    676                             sb.append('\n');
    677                             out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
    678                         }
    679                         out.flush();
    680                         file.finishWrite(f);
    681                     } catch (IOException e) {
    682                         if (f != null) {
    683                             file.failWrite(f);
    684                         }
    685                         Log.e(TAG, "Failed to write package usage times", e);
    686                     }
    687                 }
    688             }
    689             mLastWritten.set(SystemClock.elapsedRealtime());
    690         }
    691 
    692         void readLP() {
    693             synchronized (mFileLock) {
    694                 AtomicFile file = getFile();
    695                 BufferedInputStream in = null;
    696                 try {
    697                     in = new BufferedInputStream(file.openRead());
    698                     StringBuffer sb = new StringBuffer();
    699                     while (true) {
    700                         String packageName = readToken(in, sb, ' ');
    701                         if (packageName == null) {
    702                             break;
    703                         }
    704                         String timeInMillisString = readToken(in, sb, '\n');
    705                         if (timeInMillisString == null) {
    706                             throw new IOException("Failed to find last usage time for package "
    707                                                   + packageName);
    708                         }
    709                         PackageParser.Package pkg = mPackages.get(packageName);
    710                         if (pkg == null) {
    711                             continue;
    712                         }
    713                         long timeInMillis;
    714                         try {
    715                             timeInMillis = Long.parseLong(timeInMillisString.toString());
    716                         } catch (NumberFormatException e) {
    717                             throw new IOException("Failed to parse " + timeInMillisString
    718                                                   + " as a long.", e);
    719                         }
    720                         pkg.mLastPackageUsageTimeInMills = timeInMillis;
    721                     }
    722                 } catch (FileNotFoundException expected) {
    723                     mIsHistoricalPackageUsageAvailable = false;
    724                 } catch (IOException e) {
    725                     Log.w(TAG, "Failed to read package usage times", e);
    726                 } finally {
    727                     IoUtils.closeQuietly(in);
    728                 }
    729             }
    730             mLastWritten.set(SystemClock.elapsedRealtime());
    731         }
    732 
    733         private String readToken(InputStream in, StringBuffer sb, char endOfToken)
    734                 throws IOException {
    735             sb.setLength(0);
    736             while (true) {
    737                 int ch = in.read();
    738                 if (ch == -1) {
    739                     if (sb.length() == 0) {
    740                         return null;
    741                     }
    742                     throw new IOException("Unexpected EOF");
    743                 }
    744                 if (ch == endOfToken) {
    745                     return sb.toString();
    746                 }
    747                 sb.append((char)ch);
    748             }
    749         }
    750 
    751         private AtomicFile getFile() {
    752             File dataDir = Environment.getDataDirectory();
    753             File systemDir = new File(dataDir, "system");
    754             File fname = new File(systemDir, "package-usage.list");
    755             return new AtomicFile(fname);
    756         }
    757     }
    758 
    759     class PackageHandler extends Handler {
    760         private boolean mBound = false;
    761         final ArrayList<HandlerParams> mPendingInstalls =
    762             new ArrayList<HandlerParams>();
    763 
    764         private boolean connectToService() {
    765             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
    766                     " DefaultContainerService");
    767             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
    768             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    769             if (mContext.bindServiceAsUser(service, mDefContainerConn,
    770                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
    771                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    772                 mBound = true;
    773                 return true;
    774             }
    775             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    776             return false;
    777         }
    778 
    779         private void disconnectService() {
    780             mContainerService = null;
    781             mBound = false;
    782             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    783             mContext.unbindService(mDefContainerConn);
    784             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    785         }
    786 
    787         PackageHandler(Looper looper) {
    788             super(looper);
    789         }
    790 
    791         public void handleMessage(Message msg) {
    792             try {
    793                 doHandleMessage(msg);
    794             } finally {
    795                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    796             }
    797         }
    798 
    799         void doHandleMessage(Message msg) {
    800             switch (msg.what) {
    801                 case INIT_COPY: {
    802                     HandlerParams params = (HandlerParams) msg.obj;
    803                     int idx = mPendingInstalls.size();
    804                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
    805                     // If a bind was already initiated we dont really
    806                     // need to do anything. The pending install
    807                     // will be processed later on.
    808                     if (!mBound) {
    809                         // If this is the only one pending we might
    810                         // have to bind to the service again.
    811                         if (!connectToService()) {
    812                             Slog.e(TAG, "Failed to bind to media container service");
    813                             params.serviceError();
    814                             return;
    815                         } else {
    816                             // Once we bind to the service, the first
    817                             // pending request will be processed.
    818                             mPendingInstalls.add(idx, params);
    819                         }
    820                     } else {
    821                         mPendingInstalls.add(idx, params);
    822                         // Already bound to the service. Just make
    823                         // sure we trigger off processing the first request.
    824                         if (idx == 0) {
    825                             mHandler.sendEmptyMessage(MCS_BOUND);
    826                         }
    827                     }
    828                     break;
    829                 }
    830                 case MCS_BOUND: {
    831                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
    832                     if (msg.obj != null) {
    833                         mContainerService = (IMediaContainerService) msg.obj;
    834                     }
    835                     if (mContainerService == null) {
    836                         // Something seriously wrong. Bail out
    837                         Slog.e(TAG, "Cannot bind to media container service");
    838                         for (HandlerParams params : mPendingInstalls) {
    839                             // Indicate service bind error
    840                             params.serviceError();
    841                         }
    842                         mPendingInstalls.clear();
    843                     } else if (mPendingInstalls.size() > 0) {
    844                         HandlerParams params = mPendingInstalls.get(0);
    845                         if (params != null) {
    846                             if (params.startCopy()) {
    847                                 // We are done...  look for more work or to
    848                                 // go idle.
    849                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
    850                                         "Checking for more work or unbind...");
    851                                 // Delete pending install
    852                                 if (mPendingInstalls.size() > 0) {
    853                                     mPendingInstalls.remove(0);
    854                                 }
    855                                 if (mPendingInstalls.size() == 0) {
    856                                     if (mBound) {
    857                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
    858                                                 "Posting delayed MCS_UNBIND");
    859                                         removeMessages(MCS_UNBIND);
    860                                         Message ubmsg = obtainMessage(MCS_UNBIND);
    861                                         // Unbind after a little delay, to avoid
    862                                         // continual thrashing.
    863                                         sendMessageDelayed(ubmsg, 10000);
    864                                     }
    865                                 } else {
    866                                     // There are more pending requests in queue.
    867                                     // Just post MCS_BOUND message to trigger processing
    868                                     // of next pending install.
    869                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
    870                                             "Posting MCS_BOUND for next work");
    871                                     mHandler.sendEmptyMessage(MCS_BOUND);
    872                                 }
    873                             }
    874                         }
    875                     } else {
    876                         // Should never happen ideally.
    877                         Slog.w(TAG, "Empty queue");
    878                     }
    879                     break;
    880                 }
    881                 case MCS_RECONNECT: {
    882                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
    883                     if (mPendingInstalls.size() > 0) {
    884                         if (mBound) {
    885                             disconnectService();
    886                         }
    887                         if (!connectToService()) {
    888                             Slog.e(TAG, "Failed to bind to media container service");
    889                             for (HandlerParams params : mPendingInstalls) {
    890                                 // Indicate service bind error
    891                                 params.serviceError();
    892                             }
    893                             mPendingInstalls.clear();
    894                         }
    895                     }
    896                     break;
    897                 }
    898                 case MCS_UNBIND: {
    899                     // If there is no actual work left, then time to unbind.
    900                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
    901 
    902                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
    903                         if (mBound) {
    904                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
    905 
    906                             disconnectService();
    907                         }
    908                     } else if (mPendingInstalls.size() > 0) {
    909                         // There are more pending requests in queue.
    910                         // Just post MCS_BOUND message to trigger processing
    911                         // of next pending install.
    912                         mHandler.sendEmptyMessage(MCS_BOUND);
    913                     }
    914 
    915                     break;
    916                 }
    917                 case MCS_GIVE_UP: {
    918                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
    919                     mPendingInstalls.remove(0);
    920                     break;
    921                 }
    922                 case SEND_PENDING_BROADCAST: {
    923                     String packages[];
    924                     ArrayList<String> components[];
    925                     int size = 0;
    926                     int uids[];
    927                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    928                     synchronized (mPackages) {
    929                         if (mPendingBroadcasts == null) {
    930                             return;
    931                         }
    932                         size = mPendingBroadcasts.size();
    933                         if (size <= 0) {
    934                             // Nothing to be done. Just return
    935                             return;
    936                         }
    937                         packages = new String[size];
    938                         components = new ArrayList[size];
    939                         uids = new int[size];
    940                         int i = 0;  // filling out the above arrays
    941 
    942                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
    943                             int packageUserId = mPendingBroadcasts.userIdAt(n);
    944                             Iterator<Map.Entry<String, ArrayList<String>>> it
    945                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
    946                                             .entrySet().iterator();
    947                             while (it.hasNext() && i < size) {
    948                                 Map.Entry<String, ArrayList<String>> ent = it.next();
    949                                 packages[i] = ent.getKey();
    950                                 components[i] = ent.getValue();
    951                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
    952                                 uids[i] = (ps != null)
    953                                         ? UserHandle.getUid(packageUserId, ps.appId)
    954                                         : -1;
    955                                 i++;
    956                             }
    957                         }
    958                         size = i;
    959                         mPendingBroadcasts.clear();
    960                     }
    961                     // Send broadcasts
    962                     for (int i = 0; i < size; i++) {
    963                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
    964                     }
    965                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    966                     break;
    967                 }
    968                 case START_CLEANING_PACKAGE: {
    969                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    970                     final String packageName = (String)msg.obj;
    971                     final int userId = msg.arg1;
    972                     final boolean andCode = msg.arg2 != 0;
    973                     synchronized (mPackages) {
    974                         if (userId == UserHandle.USER_ALL) {
    975                             int[] users = sUserManager.getUserIds();
    976                             for (int user : users) {
    977                                 mSettings.addPackageToCleanLPw(
    978                                         new PackageCleanItem(user, packageName, andCode));
    979                             }
    980                         } else {
    981                             mSettings.addPackageToCleanLPw(
    982                                     new PackageCleanItem(userId, packageName, andCode));
    983                         }
    984                     }
    985                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    986                     startCleaningPackages();
    987                 } break;
    988                 case POST_INSTALL: {
    989                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
    990                     PostInstallData data = mRunningInstalls.get(msg.arg1);
    991                     mRunningInstalls.delete(msg.arg1);
    992                     boolean deleteOld = false;
    993 
    994                     if (data != null) {
    995                         InstallArgs args = data.args;
    996                         PackageInstalledInfo res = data.res;
    997 
    998                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
    999                             res.removedInfo.sendBroadcast(false, true, false);
   1000                             Bundle extras = new Bundle(1);
   1001                             extras.putInt(Intent.EXTRA_UID, res.uid);
   1002                             // Determine the set of users who are adding this
   1003                             // package for the first time vs. those who are seeing
   1004                             // an update.
   1005                             int[] firstUsers;
   1006                             int[] updateUsers = new int[0];
   1007                             if (res.origUsers == null || res.origUsers.length == 0) {
   1008                                 firstUsers = res.newUsers;
   1009                             } else {
   1010                                 firstUsers = new int[0];
   1011                                 for (int i=0; i<res.newUsers.length; i++) {
   1012                                     int user = res.newUsers[i];
   1013                                     boolean isNew = true;
   1014                                     for (int j=0; j<res.origUsers.length; j++) {
   1015                                         if (res.origUsers[j] == user) {
   1016                                             isNew = false;
   1017                                             break;
   1018                                         }
   1019                                     }
   1020                                     if (isNew) {
   1021                                         int[] newFirst = new int[firstUsers.length+1];
   1022                                         System.arraycopy(firstUsers, 0, newFirst, 0,
   1023                                                 firstUsers.length);
   1024                                         newFirst[firstUsers.length] = user;
   1025                                         firstUsers = newFirst;
   1026                                     } else {
   1027                                         int[] newUpdate = new int[updateUsers.length+1];
   1028                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
   1029                                                 updateUsers.length);
   1030                                         newUpdate[updateUsers.length] = user;
   1031                                         updateUsers = newUpdate;
   1032                                     }
   1033                                 }
   1034                             }
   1035                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
   1036                                     res.pkg.applicationInfo.packageName,
   1037                                     extras, null, null, firstUsers);
   1038                             final boolean update = res.removedInfo.removedPackage != null;
   1039                             if (update) {
   1040                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   1041                             }
   1042                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
   1043                                     res.pkg.applicationInfo.packageName,
   1044                                     extras, null, null, updateUsers);
   1045                             if (update) {
   1046                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
   1047                                         res.pkg.applicationInfo.packageName,
   1048                                         extras, null, null, updateUsers);
   1049                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
   1050                                         null, null,
   1051                                         res.pkg.applicationInfo.packageName, null, updateUsers);
   1052 
   1053                                 // treat asec-hosted packages like removable media on upgrade
   1054                                 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
   1055                                     if (DEBUG_INSTALL) {
   1056                                         Slog.i(TAG, "upgrading pkg " + res.pkg
   1057                                                 + " is ASEC-hosted -> AVAILABLE");
   1058                                     }
   1059                                     int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
   1060                                     ArrayList<String> pkgList = new ArrayList<String>(1);
   1061                                     pkgList.add(res.pkg.applicationInfo.packageName);
   1062                                     sendResourcesChangedBroadcast(true, true,
   1063                                             pkgList,uidArray, null);
   1064                                 }
   1065                             }
   1066                             if (res.removedInfo.args != null) {
   1067                                 // Remove the replaced package's older resources safely now
   1068                                 deleteOld = true;
   1069                             }
   1070 
   1071                             // Log current value of "unknown sources" setting
   1072                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
   1073                                 getUnknownSourcesSettings());
   1074                         }
   1075                         // Force a gc to clear up things
   1076                         Runtime.getRuntime().gc();
   1077                         // We delete after a gc for applications  on sdcard.
   1078                         if (deleteOld) {
   1079                             synchronized (mInstallLock) {
   1080                                 res.removedInfo.args.doPostDeleteLI(true);
   1081                             }
   1082                         }
   1083                         if (args.observer != null) {
   1084                             try {
   1085                                 Bundle extras = extrasForInstallResult(res);
   1086                                 args.observer.onPackageInstalled(res.name, res.returnCode,
   1087                                         res.returnMsg, extras);
   1088                             } catch (RemoteException e) {
   1089                                 Slog.i(TAG, "Observer no longer exists.");
   1090                             }
   1091                         }
   1092                     } else {
   1093                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
   1094                     }
   1095                 } break;
   1096                 case UPDATED_MEDIA_STATUS: {
   1097                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
   1098                     boolean reportStatus = msg.arg1 == 1;
   1099                     boolean doGc = msg.arg2 == 1;
   1100                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
   1101                     if (doGc) {
   1102                         // Force a gc to clear up stale containers.
   1103                         Runtime.getRuntime().gc();
   1104                     }
   1105                     if (msg.obj != null) {
   1106                         @SuppressWarnings("unchecked")
   1107                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
   1108                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
   1109                         // Unload containers
   1110                         unloadAllContainers(args);
   1111                     }
   1112                     if (reportStatus) {
   1113                         try {
   1114                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
   1115                             PackageHelper.getMountService().finishMediaUpdate();
   1116                         } catch (RemoteException e) {
   1117                             Log.e(TAG, "MountService not running?");
   1118                         }
   1119                     }
   1120                 } break;
   1121                 case WRITE_SETTINGS: {
   1122                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1123                     synchronized (mPackages) {
   1124                         removeMessages(WRITE_SETTINGS);
   1125                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
   1126                         mSettings.writeLPr();
   1127                         mDirtyUsers.clear();
   1128                     }
   1129                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1130                 } break;
   1131                 case WRITE_PACKAGE_RESTRICTIONS: {
   1132                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1133                     synchronized (mPackages) {
   1134                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
   1135                         for (int userId : mDirtyUsers) {
   1136                             mSettings.writePackageRestrictionsLPr(userId);
   1137                         }
   1138                         mDirtyUsers.clear();
   1139                     }
   1140                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1141                 } break;
   1142                 case CHECK_PENDING_VERIFICATION: {
   1143                     final int verificationId = msg.arg1;
   1144                     final PackageVerificationState state = mPendingVerification.get(verificationId);
   1145 
   1146                     if ((state != null) && !state.timeoutExtended()) {
   1147                         final InstallArgs args = state.getInstallArgs();
   1148                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
   1149 
   1150                         Slog.i(TAG, "Verification timed out for " + originUri);
   1151                         mPendingVerification.remove(verificationId);
   1152 
   1153                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   1154 
   1155                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
   1156                             Slog.i(TAG, "Continuing with installation of " + originUri);
   1157                             state.setVerifierResponse(Binder.getCallingUid(),
   1158                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
   1159                             broadcastPackageVerified(verificationId, originUri,
   1160                                     PackageManager.VERIFICATION_ALLOW,
   1161                                     state.getInstallArgs().getUser());
   1162                             try {
   1163                                 ret = args.copyApk(mContainerService, true);
   1164                             } catch (RemoteException e) {
   1165                                 Slog.e(TAG, "Could not contact the ContainerService");
   1166                             }
   1167                         } else {
   1168                             broadcastPackageVerified(verificationId, originUri,
   1169                                     PackageManager.VERIFICATION_REJECT,
   1170                                     state.getInstallArgs().getUser());
   1171                         }
   1172 
   1173                         processPendingInstall(args, ret);
   1174                         mHandler.sendEmptyMessage(MCS_UNBIND);
   1175                     }
   1176                     break;
   1177                 }
   1178                 case PACKAGE_VERIFIED: {
   1179                     final int verificationId = msg.arg1;
   1180 
   1181                     final PackageVerificationState state = mPendingVerification.get(verificationId);
   1182                     if (state == null) {
   1183                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
   1184                         break;
   1185                     }
   1186 
   1187                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
   1188 
   1189                     state.setVerifierResponse(response.callerUid, response.code);
   1190 
   1191                     if (state.isVerificationComplete()) {
   1192                         mPendingVerification.remove(verificationId);
   1193 
   1194                         final InstallArgs args = state.getInstallArgs();
   1195                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
   1196 
   1197                         int ret;
   1198                         if (state.isInstallAllowed()) {
   1199                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   1200                             broadcastPackageVerified(verificationId, originUri,
   1201                                     response.code, state.getInstallArgs().getUser());
   1202                             try {
   1203                                 ret = args.copyApk(mContainerService, true);
   1204                             } catch (RemoteException e) {
   1205                                 Slog.e(TAG, "Could not contact the ContainerService");
   1206                             }
   1207                         } else {
   1208                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   1209                         }
   1210 
   1211                         processPendingInstall(args, ret);
   1212 
   1213                         mHandler.sendEmptyMessage(MCS_UNBIND);
   1214                     }
   1215 
   1216                     break;
   1217                 }
   1218             }
   1219         }
   1220     }
   1221 
   1222     Bundle extrasForInstallResult(PackageInstalledInfo res) {
   1223         Bundle extras = null;
   1224         switch (res.returnCode) {
   1225             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
   1226                 extras = new Bundle();
   1227                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
   1228                         res.origPermission);
   1229                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
   1230                         res.origPackage);
   1231                 break;
   1232             }
   1233         }
   1234         return extras;
   1235     }
   1236 
   1237     void scheduleWriteSettingsLocked() {
   1238         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
   1239             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
   1240         }
   1241     }
   1242 
   1243     void scheduleWritePackageRestrictionsLocked(int userId) {
   1244         if (!sUserManager.exists(userId)) return;
   1245         mDirtyUsers.add(userId);
   1246         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
   1247             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
   1248         }
   1249     }
   1250 
   1251     public static final PackageManagerService main(Context context, Installer installer,
   1252             boolean factoryTest, boolean onlyCore) {
   1253         PackageManagerService m = new PackageManagerService(context, installer,
   1254                 factoryTest, onlyCore);
   1255         ServiceManager.addService("package", m);
   1256         return m;
   1257     }
   1258 
   1259     static String[] splitString(String str, char sep) {
   1260         int count = 1;
   1261         int i = 0;
   1262         while ((i=str.indexOf(sep, i)) >= 0) {
   1263             count++;
   1264             i++;
   1265         }
   1266 
   1267         String[] res = new String[count];
   1268         i=0;
   1269         count = 0;
   1270         int lastI=0;
   1271         while ((i=str.indexOf(sep, i)) >= 0) {
   1272             res[count] = str.substring(lastI, i);
   1273             count++;
   1274             i++;
   1275             lastI = i;
   1276         }
   1277         res[count] = str.substring(lastI, str.length());
   1278         return res;
   1279     }
   1280 
   1281     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
   1282         DisplayManager displayManager = (DisplayManager) context.getSystemService(
   1283                 Context.DISPLAY_SERVICE);
   1284         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
   1285     }
   1286 
   1287     public PackageManagerService(Context context, Installer installer,
   1288             boolean factoryTest, boolean onlyCore) {
   1289         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
   1290                 SystemClock.uptimeMillis());
   1291 
   1292         if (mSdkVersion <= 0) {
   1293             Slog.w(TAG, "**** ro.build.version.sdk not set!");
   1294         }
   1295 
   1296         mContext = context;
   1297         mFactoryTest = factoryTest;
   1298         mOnlyCore = onlyCore;
   1299         mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
   1300         mMetrics = new DisplayMetrics();
   1301         mSettings = new Settings(context);
   1302         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
   1303                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1304         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
   1305                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1306         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
   1307                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1308         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
   1309                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1310         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
   1311                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1312         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
   1313                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1314 
   1315         // TODO: add a property to control this?
   1316         long dexOptLRUThresholdInMinutes;
   1317         if (mLazyDexOpt) {
   1318             dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
   1319         } else {
   1320             dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
   1321         }
   1322         mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
   1323 
   1324         String separateProcesses = SystemProperties.get("debug.separate_processes");
   1325         if (separateProcesses != null && separateProcesses.length() > 0) {
   1326             if ("*".equals(separateProcesses)) {
   1327                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
   1328                 mSeparateProcesses = null;
   1329                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
   1330             } else {
   1331                 mDefParseFlags = 0;
   1332                 mSeparateProcesses = separateProcesses.split(",");
   1333                 Slog.w(TAG, "Running with debug.separate_processes: "
   1334                         + separateProcesses);
   1335             }
   1336         } else {
   1337             mDefParseFlags = 0;
   1338             mSeparateProcesses = null;
   1339         }
   1340 
   1341         mInstaller = installer;
   1342 
   1343         getDefaultDisplayMetrics(context, mMetrics);
   1344 
   1345         SystemConfig systemConfig = SystemConfig.getInstance();
   1346         mGlobalGids = systemConfig.getGlobalGids();
   1347         mSystemPermissions = systemConfig.getSystemPermissions();
   1348         mAvailableFeatures = systemConfig.getAvailableFeatures();
   1349 
   1350         synchronized (mInstallLock) {
   1351         // writer
   1352         synchronized (mPackages) {
   1353             mHandlerThread = new ServiceThread(TAG,
   1354                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
   1355             mHandlerThread.start();
   1356             mHandler = new PackageHandler(mHandlerThread.getLooper());
   1357             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
   1358 
   1359             File dataDir = Environment.getDataDirectory();
   1360             mAppDataDir = new File(dataDir, "data");
   1361             mAppInstallDir = new File(dataDir, "app");
   1362             mAppLib32InstallDir = new File(dataDir, "app-lib");
   1363             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
   1364             mUserAppDataDir = new File(dataDir, "user");
   1365             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
   1366 
   1367             sUserManager = new UserManagerService(context, this,
   1368                     mInstallLock, mPackages);
   1369 
   1370             // Propagate permission configuration in to package manager.
   1371             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
   1372                     = systemConfig.getPermissions();
   1373             for (int i=0; i<permConfig.size(); i++) {
   1374                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
   1375                 BasePermission bp = mSettings.mPermissions.get(perm.name);
   1376                 if (bp == null) {
   1377                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
   1378                     mSettings.mPermissions.put(perm.name, bp);
   1379                 }
   1380                 if (perm.gids != null) {
   1381                     bp.gids = appendInts(bp.gids, perm.gids);
   1382                 }
   1383             }
   1384 
   1385             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
   1386             for (int i=0; i<libConfig.size(); i++) {
   1387                 mSharedLibraries.put(libConfig.keyAt(i),
   1388                         new SharedLibraryEntry(libConfig.valueAt(i), null));
   1389             }
   1390 
   1391             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
   1392 
   1393             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
   1394                     mSdkVersion, mOnlyCore);
   1395 
   1396             String customResolverActivity = Resources.getSystem().getString(
   1397                     R.string.config_customResolverActivity);
   1398             if (TextUtils.isEmpty(customResolverActivity)) {
   1399                 customResolverActivity = null;
   1400             } else {
   1401                 mCustomResolverComponentName = ComponentName.unflattenFromString(
   1402                         customResolverActivity);
   1403             }
   1404 
   1405             long startTime = SystemClock.uptimeMillis();
   1406 
   1407             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
   1408                     startTime);
   1409 
   1410             // Set flag to monitor and not change apk file paths when
   1411             // scanning install directories.
   1412             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
   1413 
   1414             final ArraySet<String> alreadyDexOpted = new ArraySet<String>();
   1415 
   1416             /**
   1417              * Add everything in the in the boot class path to the
   1418              * list of process files because dexopt will have been run
   1419              * if necessary during zygote startup.
   1420              */
   1421             final String bootClassPath = System.getenv("BOOTCLASSPATH");
   1422             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
   1423 
   1424             if (bootClassPath != null) {
   1425                 String[] bootClassPathElements = splitString(bootClassPath, ':');
   1426                 for (String element : bootClassPathElements) {
   1427                     alreadyDexOpted.add(element);
   1428                 }
   1429             } else {
   1430                 Slog.w(TAG, "No BOOTCLASSPATH found!");
   1431             }
   1432 
   1433             if (systemServerClassPath != null) {
   1434                 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
   1435                 for (String element : systemServerClassPathElements) {
   1436                     alreadyDexOpted.add(element);
   1437                 }
   1438             } else {
   1439                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
   1440             }
   1441 
   1442             final List<String> allInstructionSets = getAllInstructionSets();
   1443             final String[] dexCodeInstructionSets =
   1444                 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
   1445 
   1446             /**
   1447              * Ensure all external libraries have had dexopt run on them.
   1448              */
   1449             if (mSharedLibraries.size() > 0) {
   1450                 // NOTE: For now, we're compiling these system "shared libraries"
   1451                 // (and framework jars) into all available architectures. It's possible
   1452                 // to compile them only when we come across an app that uses them (there's
   1453                 // already logic for that in scanPackageLI) but that adds some complexity.
   1454                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   1455                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
   1456                         final String lib = libEntry.path;
   1457                         if (lib == null) {
   1458                             continue;
   1459                         }
   1460 
   1461                         try {
   1462                             byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
   1463                                                                                  dexCodeInstructionSet,
   1464                                                                                  false);
   1465                             if (dexoptRequired != DexFile.UP_TO_DATE) {
   1466                                 alreadyDexOpted.add(lib);
   1467 
   1468                                 // The list of "shared libraries" we have at this point is
   1469                                 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
   1470                                     mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
   1471                                 } else {
   1472                                     mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
   1473                                 }
   1474                             }
   1475                         } catch (FileNotFoundException e) {
   1476                             Slog.w(TAG, "Library not found: " + lib);
   1477                         } catch (IOException e) {
   1478                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
   1479                                     + e.getMessage());
   1480                         }
   1481                     }
   1482                 }
   1483             }
   1484 
   1485             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
   1486 
   1487             // Gross hack for now: we know this file doesn't contain any
   1488             // code, so don't dexopt it to avoid the resulting log spew.
   1489             alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
   1490 
   1491             // Gross hack for now: we know this file is only part of
   1492             // the boot class path for art, so don't dexopt it to
   1493             // avoid the resulting log spew.
   1494             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
   1495 
   1496             /**
   1497              * And there are a number of commands implemented in Java, which
   1498              * we currently need to do the dexopt on so that they can be
   1499              * run from a non-root shell.
   1500              */
   1501             String[] frameworkFiles = frameworkDir.list();
   1502             if (frameworkFiles != null) {
   1503                 // TODO: We could compile these only for the most preferred ABI. We should
   1504                 // first double check that the dex files for these commands are not referenced
   1505                 // by other system apps.
   1506                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   1507                     for (int i=0; i<frameworkFiles.length; i++) {
   1508                         File libPath = new File(frameworkDir, frameworkFiles[i]);
   1509                         String path = libPath.getPath();
   1510                         // Skip the file if we already did it.
   1511                         if (alreadyDexOpted.contains(path)) {
   1512                             continue;
   1513                         }
   1514                         // Skip the file if it is not a type we want to dexopt.
   1515                         if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
   1516                             continue;
   1517                         }
   1518                         try {
   1519                             byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
   1520                                                                                  dexCodeInstructionSet,
   1521                                                                                  false);
   1522                             if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
   1523                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
   1524                             } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
   1525                                 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
   1526                             }
   1527                         } catch (FileNotFoundException e) {
   1528                             Slog.w(TAG, "Jar not found: " + path);
   1529                         } catch (IOException e) {
   1530                             Slog.w(TAG, "Exception reading jar: " + path, e);
   1531                         }
   1532                     }
   1533                 }
   1534             }
   1535 
   1536             // Collect vendor overlay packages.
   1537             // (Do this before scanning any apps.)
   1538             // For security and version matching reason, only consider
   1539             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
   1540             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
   1541             scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
   1542                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
   1543 
   1544             // Find base frameworks (resource packages without code).
   1545             scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
   1546                     | PackageParser.PARSE_IS_SYSTEM_DIR
   1547                     | PackageParser.PARSE_IS_PRIVILEGED,
   1548                     scanFlags | SCAN_NO_DEX, 0);
   1549 
   1550             // Collected privileged system packages.
   1551             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
   1552             scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
   1553                     | PackageParser.PARSE_IS_SYSTEM_DIR
   1554                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
   1555 
   1556             // Collect ordinary system packages.
   1557             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
   1558             scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
   1559                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   1560 
   1561             // Collect all vendor packages.
   1562             File vendorAppDir = new File("/vendor/app");
   1563             try {
   1564                 vendorAppDir = vendorAppDir.getCanonicalFile();
   1565             } catch (IOException e) {
   1566                 // failed to look up canonical path, continue with original one
   1567             }
   1568             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
   1569                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   1570 
   1571             // Collect all OEM packages.
   1572             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
   1573             scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
   1574                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   1575 
   1576             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
   1577             mInstaller.moveFiles();
   1578 
   1579             // Prune any system packages that no longer exist.
   1580             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
   1581             final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
   1582             if (!mOnlyCore) {
   1583                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
   1584                 while (psit.hasNext()) {
   1585                     PackageSetting ps = psit.next();
   1586 
   1587                     /*
   1588                      * If this is not a system app, it can't be a
   1589                      * disable system app.
   1590                      */
   1591                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   1592                         continue;
   1593                     }
   1594 
   1595                     /*
   1596                      * If the package is scanned, it's not erased.
   1597                      */
   1598                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
   1599                     if (scannedPkg != null) {
   1600                         /*
   1601                          * If the system app is both scanned and in the
   1602                          * disabled packages list, then it must have been
   1603                          * added via OTA. Remove it from the currently
   1604                          * scanned package so the previously user-installed
   1605                          * application can be scanned.
   1606                          */
   1607                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
   1608                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
   1609                                     + ps.name + "; removing system app.  Last known codePath="
   1610                                     + ps.codePathString + ", installStatus=" + ps.installStatus
   1611                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
   1612                                     + scannedPkg.mVersionCode);
   1613                             removePackageLI(ps, true);
   1614                             expectingBetter.put(ps.name, ps.codePath);
   1615                         }
   1616 
   1617                         continue;
   1618                     }
   1619 
   1620                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
   1621                         psit.remove();
   1622                         logCriticalInfo(Log.WARN, "System package " + ps.name
   1623                                 + " no longer exists; wiping its data");
   1624                         removeDataDirsLI(ps.name);
   1625                     } else {
   1626                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
   1627                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
   1628                             possiblyDeletedUpdatedSystemApps.add(ps.name);
   1629                         }
   1630                     }
   1631                 }
   1632             }
   1633 
   1634             //look for any incomplete package installations
   1635             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
   1636             //clean up list
   1637             for(int i = 0; i < deletePkgsList.size(); i++) {
   1638                 //clean up here
   1639                 cleanupInstallFailedPackage(deletePkgsList.get(i));
   1640             }
   1641             //delete tmp files
   1642             deleteTempPackageFiles();
   1643 
   1644             // Remove any shared userIDs that have no associated packages
   1645             mSettings.pruneSharedUsersLPw();
   1646 
   1647             if (!mOnlyCore) {
   1648                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
   1649                         SystemClock.uptimeMillis());
   1650                 scanDirLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
   1651 
   1652                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
   1653                         scanFlags | SCAN_REQUIRE_KNOWN, 0);
   1654 
   1655                 /**
   1656                  * Remove disable package settings for any updated system
   1657                  * apps that were removed via an OTA. If they're not a
   1658                  * previously-updated app, remove them completely.
   1659                  * Otherwise, just revoke their system-level permissions.
   1660                  */
   1661                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
   1662                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
   1663                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
   1664 
   1665                     String msg;
   1666                     if (deletedPkg == null) {
   1667                         msg = "Updated system package " + deletedAppName
   1668                                 + " no longer exists; wiping its data";
   1669                         removeDataDirsLI(deletedAppName);
   1670                     } else {
   1671                         msg = "Updated system app + " + deletedAppName
   1672                                 + " no longer present; removing system privileges for "
   1673                                 + deletedAppName;
   1674 
   1675                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
   1676 
   1677                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
   1678                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
   1679                     }
   1680                     logCriticalInfo(Log.WARN, msg);
   1681                 }
   1682 
   1683                 /**
   1684                  * Make sure all system apps that we expected to appear on
   1685                  * the userdata partition actually showed up. If they never
   1686                  * appeared, crawl back and revive the system version.
   1687                  */
   1688                 for (int i = 0; i < expectingBetter.size(); i++) {
   1689                     final String packageName = expectingBetter.keyAt(i);
   1690                     if (!mPackages.containsKey(packageName)) {
   1691                         final File scanFile = expectingBetter.valueAt(i);
   1692 
   1693                         logCriticalInfo(Log.WARN, "Expected better " + packageName
   1694                                 + " but never showed up; reverting to system");
   1695 
   1696                         final int reparseFlags;
   1697                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
   1698                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   1699                                     | PackageParser.PARSE_IS_SYSTEM_DIR
   1700                                     | PackageParser.PARSE_IS_PRIVILEGED;
   1701                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
   1702                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   1703                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   1704                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
   1705                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   1706                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   1707                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
   1708                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   1709                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   1710                         } else {
   1711                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
   1712                             continue;
   1713                         }
   1714 
   1715                         mSettings.enableSystemPackageLPw(packageName);
   1716 
   1717                         try {
   1718                             scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
   1719                         } catch (PackageManagerException e) {
   1720                             Slog.e(TAG, "Failed to parse original system package: "
   1721                                     + e.getMessage());
   1722                         }
   1723                     }
   1724                 }
   1725             }
   1726 
   1727             // Now that we know all of the shared libraries, update all clients to have
   1728             // the correct library paths.
   1729             updateAllSharedLibrariesLPw();
   1730 
   1731             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
   1732                 // NOTE: We ignore potential failures here during a system scan (like
   1733                 // the rest of the commands above) because there's precious little we
   1734                 // can do about it. A settings error is reported, though.
   1735                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
   1736                         false /* force dexopt */, false /* defer dexopt */);
   1737             }
   1738 
   1739             // Now that we know all the packages we are keeping,
   1740             // read and update their last usage times.
   1741             mPackageUsage.readLP();
   1742 
   1743             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
   1744                     SystemClock.uptimeMillis());
   1745             Slog.i(TAG, "Time to scan packages: "
   1746                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
   1747                     + " seconds");
   1748 
   1749             // If the platform SDK has changed since the last time we booted,
   1750             // we need to re-grant app permission to catch any new ones that
   1751             // appear.  This is really a hack, and means that apps can in some
   1752             // cases get permissions that the user didn't initially explicitly
   1753             // allow...  it would be nice to have some better way to handle
   1754             // this situation.
   1755             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
   1756                     != mSdkVersion;
   1757             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
   1758                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
   1759                     + "; regranting permissions for internal storage");
   1760             mSettings.mInternalSdkPlatform = mSdkVersion;
   1761 
   1762             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
   1763                     | (regrantPermissions
   1764                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
   1765                             : 0));
   1766 
   1767             // If this is the first boot, and it is a normal boot, then
   1768             // we need to initialize the default preferred apps.
   1769             if (!mRestoredSettings && !onlyCore) {
   1770                 mSettings.readDefaultPreferredAppsLPw(this, 0);
   1771             }
   1772 
   1773             // If this is first boot after an OTA, and a normal boot, then
   1774             // we need to clear code cache directories.
   1775             mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint);
   1776             if (mIsUpgrade && !onlyCore) {
   1777                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
   1778                 for (String pkgName : mSettings.mPackages.keySet()) {
   1779                     deleteCodeCacheDirsLI(pkgName);
   1780                 }
   1781                 mSettings.mFingerprint = Build.FINGERPRINT;
   1782             }
   1783 
   1784             // All the changes are done during package scanning.
   1785             mSettings.updateInternalDatabaseVersion();
   1786 
   1787             // can downgrade to reader
   1788             mSettings.writeLPr();
   1789 
   1790             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
   1791                     SystemClock.uptimeMillis());
   1792 
   1793 
   1794             mRequiredVerifierPackage = getRequiredVerifierLPr();
   1795         } // synchronized (mPackages)
   1796         } // synchronized (mInstallLock)
   1797 
   1798         mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);
   1799 
   1800         // Now after opening every single application zip, make sure they
   1801         // are all flushed.  Not really needed, but keeps things nice and
   1802         // tidy.
   1803         Runtime.getRuntime().gc();
   1804     }
   1805 
   1806     @Override
   1807     public boolean isFirstBoot() {
   1808         return !mRestoredSettings;
   1809     }
   1810 
   1811     @Override
   1812     public boolean isOnlyCoreApps() {
   1813         return mOnlyCore;
   1814     }
   1815 
   1816     @Override
   1817     public boolean isUpgrade() {
   1818         return mIsUpgrade;
   1819     }
   1820 
   1821     private String getRequiredVerifierLPr() {
   1822         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
   1823         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
   1824                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
   1825 
   1826         String requiredVerifier = null;
   1827 
   1828         final int N = receivers.size();
   1829         for (int i = 0; i < N; i++) {
   1830             final ResolveInfo info = receivers.get(i);
   1831 
   1832             if (info.activityInfo == null) {
   1833                 continue;
   1834             }
   1835 
   1836             final String packageName = info.activityInfo.packageName;
   1837 
   1838             final PackageSetting ps = mSettings.mPackages.get(packageName);
   1839             if (ps == null) {
   1840                 continue;
   1841             }
   1842 
   1843             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   1844             if (!gp.grantedPermissions
   1845                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
   1846                 continue;
   1847             }
   1848 
   1849             if (requiredVerifier != null) {
   1850                 throw new RuntimeException("There can be only one required verifier");
   1851             }
   1852 
   1853             requiredVerifier = packageName;
   1854         }
   1855 
   1856         return requiredVerifier;
   1857     }
   1858 
   1859     @Override
   1860     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1861             throws RemoteException {
   1862         try {
   1863             return super.onTransact(code, data, reply, flags);
   1864         } catch (RuntimeException e) {
   1865             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
   1866                 Slog.wtf(TAG, "Package Manager Crash", e);
   1867             }
   1868             throw e;
   1869         }
   1870     }
   1871 
   1872     void cleanupInstallFailedPackage(PackageSetting ps) {
   1873         logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
   1874 
   1875         removeDataDirsLI(ps.name);
   1876         if (ps.codePath != null) {
   1877             if (ps.codePath.isDirectory()) {
   1878                 FileUtils.deleteContents(ps.codePath);
   1879             }
   1880             ps.codePath.delete();
   1881         }
   1882         if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
   1883             if (ps.resourcePath.isDirectory()) {
   1884                 FileUtils.deleteContents(ps.resourcePath);
   1885             }
   1886             ps.resourcePath.delete();
   1887         }
   1888         mSettings.removePackageLPw(ps.name);
   1889     }
   1890 
   1891     static int[] appendInts(int[] cur, int[] add) {
   1892         if (add == null) return cur;
   1893         if (cur == null) return add;
   1894         final int N = add.length;
   1895         for (int i=0; i<N; i++) {
   1896             cur = appendInt(cur, add[i]);
   1897         }
   1898         return cur;
   1899     }
   1900 
   1901     static int[] removeInts(int[] cur, int[] rem) {
   1902         if (rem == null) return cur;
   1903         if (cur == null) return cur;
   1904         final int N = rem.length;
   1905         for (int i=0; i<N; i++) {
   1906             cur = removeInt(cur, rem[i]);
   1907         }
   1908         return cur;
   1909     }
   1910 
   1911     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
   1912         if (!sUserManager.exists(userId)) return null;
   1913         final PackageSetting ps = (PackageSetting) p.mExtras;
   1914         if (ps == null) {
   1915             return null;
   1916         }
   1917         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   1918         final PackageUserState state = ps.readUserState(userId);
   1919         return PackageParser.generatePackageInfo(p, gp.gids, flags,
   1920                 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
   1921                 state, userId);
   1922     }
   1923 
   1924     @Override
   1925     public boolean isPackageAvailable(String packageName, int userId) {
   1926         if (!sUserManager.exists(userId)) return false;
   1927         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
   1928         synchronized (mPackages) {
   1929             PackageParser.Package p = mPackages.get(packageName);
   1930             if (p != null) {
   1931                 final PackageSetting ps = (PackageSetting) p.mExtras;
   1932                 if (ps != null) {
   1933                     final PackageUserState state = ps.readUserState(userId);
   1934                     if (state != null) {
   1935                         return PackageParser.isAvailable(state);
   1936                     }
   1937                 }
   1938             }
   1939         }
   1940         return false;
   1941     }
   1942 
   1943     @Override
   1944     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
   1945         if (!sUserManager.exists(userId)) return null;
   1946         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
   1947         // reader
   1948         synchronized (mPackages) {
   1949             PackageParser.Package p = mPackages.get(packageName);
   1950             if (DEBUG_PACKAGE_INFO)
   1951                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
   1952             if (p != null) {
   1953                 return generatePackageInfo(p, flags, userId);
   1954             }
   1955             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   1956                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
   1957             }
   1958         }
   1959         return null;
   1960     }
   1961 
   1962     @Override
   1963     public String[] currentToCanonicalPackageNames(String[] names) {
   1964         String[] out = new String[names.length];
   1965         // reader
   1966         synchronized (mPackages) {
   1967             for (int i=names.length-1; i>=0; i--) {
   1968                 PackageSetting ps = mSettings.mPackages.get(names[i]);
   1969                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
   1970             }
   1971         }
   1972         return out;
   1973     }
   1974 
   1975     @Override
   1976     public String[] canonicalToCurrentPackageNames(String[] names) {
   1977         String[] out = new String[names.length];
   1978         // reader
   1979         synchronized (mPackages) {
   1980             for (int i=names.length-1; i>=0; i--) {
   1981                 String cur = mSettings.mRenamedPackages.get(names[i]);
   1982                 out[i] = cur != null ? cur : names[i];
   1983             }
   1984         }
   1985         return out;
   1986     }
   1987 
   1988     @Override
   1989     public int getPackageUid(String packageName, int userId) {
   1990         if (!sUserManager.exists(userId)) return -1;
   1991         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
   1992         // reader
   1993         synchronized (mPackages) {
   1994             PackageParser.Package p = mPackages.get(packageName);
   1995             if(p != null) {
   1996                 return UserHandle.getUid(userId, p.applicationInfo.uid);
   1997             }
   1998             PackageSetting ps = mSettings.mPackages.get(packageName);
   1999             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
   2000                 return -1;
   2001             }
   2002             p = ps.pkg;
   2003             return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
   2004         }
   2005     }
   2006 
   2007     @Override
   2008     public int[] getPackageGids(String packageName) {
   2009         // reader
   2010         synchronized (mPackages) {
   2011             PackageParser.Package p = mPackages.get(packageName);
   2012             if (DEBUG_PACKAGE_INFO)
   2013                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
   2014             if (p != null) {
   2015                 final PackageSetting ps = (PackageSetting)p.mExtras;
   2016                 return ps.getGids();
   2017             }
   2018         }
   2019         // stupid thing to indicate an error.
   2020         return new int[0];
   2021     }
   2022 
   2023     static final PermissionInfo generatePermissionInfo(
   2024             BasePermission bp, int flags) {
   2025         if (bp.perm != null) {
   2026             return PackageParser.generatePermissionInfo(bp.perm, flags);
   2027         }
   2028         PermissionInfo pi = new PermissionInfo();
   2029         pi.name = bp.name;
   2030         pi.packageName = bp.sourcePackage;
   2031         pi.nonLocalizedLabel = bp.name;
   2032         pi.protectionLevel = bp.protectionLevel;
   2033         return pi;
   2034     }
   2035 
   2036     @Override
   2037     public PermissionInfo getPermissionInfo(String name, int flags) {
   2038         // reader
   2039         synchronized (mPackages) {
   2040             final BasePermission p = mSettings.mPermissions.get(name);
   2041             if (p != null) {
   2042                 return generatePermissionInfo(p, flags);
   2043             }
   2044             return null;
   2045         }
   2046     }
   2047 
   2048     @Override
   2049     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
   2050         // reader
   2051         synchronized (mPackages) {
   2052             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
   2053             for (BasePermission p : mSettings.mPermissions.values()) {
   2054                 if (group == null) {
   2055                     if (p.perm == null || p.perm.info.group == null) {
   2056                         out.add(generatePermissionInfo(p, flags));
   2057                     }
   2058                 } else {
   2059                     if (p.perm != null && group.equals(p.perm.info.group)) {
   2060                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
   2061                     }
   2062                 }
   2063             }
   2064 
   2065             if (out.size() > 0) {
   2066                 return out;
   2067             }
   2068             return mPermissionGroups.containsKey(group) ? out : null;
   2069         }
   2070     }
   2071 
   2072     @Override
   2073     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
   2074         // reader
   2075         synchronized (mPackages) {
   2076             return PackageParser.generatePermissionGroupInfo(
   2077                     mPermissionGroups.get(name), flags);
   2078         }
   2079     }
   2080 
   2081     @Override
   2082     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
   2083         // reader
   2084         synchronized (mPackages) {
   2085             final int N = mPermissionGroups.size();
   2086             ArrayList<PermissionGroupInfo> out
   2087                     = new ArrayList<PermissionGroupInfo>(N);
   2088             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
   2089                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
   2090             }
   2091             return out;
   2092         }
   2093     }
   2094 
   2095     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
   2096             int userId) {
   2097         if (!sUserManager.exists(userId)) return null;
   2098         PackageSetting ps = mSettings.mPackages.get(packageName);
   2099         if (ps != null) {
   2100             if (ps.pkg == null) {
   2101                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
   2102                         flags, userId);
   2103                 if (pInfo != null) {
   2104                     return pInfo.applicationInfo;
   2105                 }
   2106                 return null;
   2107             }
   2108             return PackageParser.generateApplicationInfo(ps.pkg, flags,
   2109                     ps.readUserState(userId), userId);
   2110         }
   2111         return null;
   2112     }
   2113 
   2114     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
   2115             int userId) {
   2116         if (!sUserManager.exists(userId)) return null;
   2117         PackageSetting ps = mSettings.mPackages.get(packageName);
   2118         if (ps != null) {
   2119             PackageParser.Package pkg = ps.pkg;
   2120             if (pkg == null) {
   2121                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
   2122                     return null;
   2123                 }
   2124                 // Only data remains, so we aren't worried about code paths
   2125                 pkg = new PackageParser.Package(packageName);
   2126                 pkg.applicationInfo.packageName = packageName;
   2127                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
   2128                 pkg.applicationInfo.dataDir =
   2129                         getDataPathForPackage(packageName, 0).getPath();
   2130                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
   2131                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
   2132             }
   2133             return generatePackageInfo(pkg, flags, userId);
   2134         }
   2135         return null;
   2136     }
   2137 
   2138     @Override
   2139     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
   2140         if (!sUserManager.exists(userId)) return null;
   2141         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
   2142         // writer
   2143         synchronized (mPackages) {
   2144             PackageParser.Package p = mPackages.get(packageName);
   2145             if (DEBUG_PACKAGE_INFO) Log.v(
   2146                     TAG, "getApplicationInfo " + packageName
   2147                     + ": " + p);
   2148             if (p != null) {
   2149                 PackageSetting ps = mSettings.mPackages.get(packageName);
   2150                 if (ps == null) return null;
   2151                 // Note: isEnabledLP() does not apply here - always return info
   2152                 return PackageParser.generateApplicationInfo(
   2153                         p, flags, ps.readUserState(userId), userId);
   2154             }
   2155             if ("android".equals(packageName)||"system".equals(packageName)) {
   2156                 return mAndroidApplication;
   2157             }
   2158             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   2159                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
   2160             }
   2161         }
   2162         return null;
   2163     }
   2164 
   2165 
   2166     @Override
   2167     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
   2168         mContext.enforceCallingOrSelfPermission(
   2169                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   2170         // Queue up an async operation since clearing cache may take a little while.
   2171         mHandler.post(new Runnable() {
   2172             public void run() {
   2173                 mHandler.removeCallbacks(this);
   2174                 int retCode = -1;
   2175                 synchronized (mInstallLock) {
   2176                     retCode = mInstaller.freeCache(freeStorageSize);
   2177                     if (retCode < 0) {
   2178                         Slog.w(TAG, "Couldn't clear application caches");
   2179                     }
   2180                 }
   2181                 if (observer != null) {
   2182                     try {
   2183                         observer.onRemoveCompleted(null, (retCode >= 0));
   2184                     } catch (RemoteException e) {
   2185                         Slog.w(TAG, "RemoveException when invoking call back");
   2186                     }
   2187                 }
   2188             }
   2189         });
   2190     }
   2191 
   2192     @Override
   2193     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
   2194         mContext.enforceCallingOrSelfPermission(
   2195                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   2196         // Queue up an async operation since clearing cache may take a little while.
   2197         mHandler.post(new Runnable() {
   2198             public void run() {
   2199                 mHandler.removeCallbacks(this);
   2200                 int retCode = -1;
   2201                 synchronized (mInstallLock) {
   2202                     retCode = mInstaller.freeCache(freeStorageSize);
   2203                     if (retCode < 0) {
   2204                         Slog.w(TAG, "Couldn't clear application caches");
   2205                     }
   2206                 }
   2207                 if(pi != null) {
   2208                     try {
   2209                         // Callback via pending intent
   2210                         int code = (retCode >= 0) ? 1 : 0;
   2211                         pi.sendIntent(null, code, null,
   2212                                 null, null);
   2213                     } catch (SendIntentException e1) {
   2214                         Slog.i(TAG, "Failed to send pending intent");
   2215                     }
   2216                 }
   2217             }
   2218         });
   2219     }
   2220 
   2221     void freeStorage(long freeStorageSize) throws IOException {
   2222         synchronized (mInstallLock) {
   2223             if (mInstaller.freeCache(freeStorageSize) < 0) {
   2224                 throw new IOException("Failed to free enough space");
   2225             }
   2226         }
   2227     }
   2228 
   2229     @Override
   2230     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
   2231         if (!sUserManager.exists(userId)) return null;
   2232         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
   2233         synchronized (mPackages) {
   2234             PackageParser.Activity a = mActivities.mActivities.get(component);
   2235 
   2236             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
   2237             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
   2238                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   2239                 if (ps == null) return null;
   2240                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
   2241                         userId);
   2242             }
   2243             if (mResolveComponentName.equals(component)) {
   2244                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
   2245                         new PackageUserState(), userId);
   2246             }
   2247         }
   2248         return null;
   2249     }
   2250 
   2251     @Override
   2252     public boolean activitySupportsIntent(ComponentName component, Intent intent,
   2253             String resolvedType) {
   2254         synchronized (mPackages) {
   2255             PackageParser.Activity a = mActivities.mActivities.get(component);
   2256             if (a == null) {
   2257                 return false;
   2258             }
   2259             for (int i=0; i<a.intents.size(); i++) {
   2260                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
   2261                         intent.getData(), intent.getCategories(), TAG) >= 0) {
   2262                     return true;
   2263                 }
   2264             }
   2265             return false;
   2266         }
   2267     }
   2268 
   2269     @Override
   2270     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
   2271         if (!sUserManager.exists(userId)) return null;
   2272         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
   2273         synchronized (mPackages) {
   2274             PackageParser.Activity a = mReceivers.mActivities.get(component);
   2275             if (DEBUG_PACKAGE_INFO) Log.v(
   2276                 TAG, "getReceiverInfo " + component + ": " + a);
   2277             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
   2278                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   2279                 if (ps == null) return null;
   2280                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
   2281                         userId);
   2282             }
   2283         }
   2284         return null;
   2285     }
   2286 
   2287     @Override
   2288     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
   2289         if (!sUserManager.exists(userId)) return null;
   2290         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
   2291         synchronized (mPackages) {
   2292             PackageParser.Service s = mServices.mServices.get(component);
   2293             if (DEBUG_PACKAGE_INFO) Log.v(
   2294                 TAG, "getServiceInfo " + component + ": " + s);
   2295             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
   2296                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   2297                 if (ps == null) return null;
   2298                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
   2299                         userId);
   2300             }
   2301         }
   2302         return null;
   2303     }
   2304 
   2305     @Override
   2306     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
   2307         if (!sUserManager.exists(userId)) return null;
   2308         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
   2309         synchronized (mPackages) {
   2310             PackageParser.Provider p = mProviders.mProviders.get(component);
   2311             if (DEBUG_PACKAGE_INFO) Log.v(
   2312                 TAG, "getProviderInfo " + component + ": " + p);
   2313             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
   2314                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   2315                 if (ps == null) return null;
   2316                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
   2317                         userId);
   2318             }
   2319         }
   2320         return null;
   2321     }
   2322 
   2323     @Override
   2324     public String[] getSystemSharedLibraryNames() {
   2325         Set<String> libSet;
   2326         synchronized (mPackages) {
   2327             libSet = mSharedLibraries.keySet();
   2328             int size = libSet.size();
   2329             if (size > 0) {
   2330                 String[] libs = new String[size];
   2331                 libSet.toArray(libs);
   2332                 return libs;
   2333             }
   2334         }
   2335         return null;
   2336     }
   2337 
   2338     @Override
   2339     public FeatureInfo[] getSystemAvailableFeatures() {
   2340         Collection<FeatureInfo> featSet;
   2341         synchronized (mPackages) {
   2342             featSet = mAvailableFeatures.values();
   2343             int size = featSet.size();
   2344             if (size > 0) {
   2345                 FeatureInfo[] features = new FeatureInfo[size+1];
   2346                 featSet.toArray(features);
   2347                 FeatureInfo fi = new FeatureInfo();
   2348                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
   2349                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
   2350                 features[size] = fi;
   2351                 return features;
   2352             }
   2353         }
   2354         return null;
   2355     }
   2356 
   2357     @Override
   2358     public boolean hasSystemFeature(String name) {
   2359         synchronized (mPackages) {
   2360             return mAvailableFeatures.containsKey(name);
   2361         }
   2362     }
   2363 
   2364     private void checkValidCaller(int uid, int userId) {
   2365         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
   2366             return;
   2367 
   2368         throw new SecurityException("Caller uid=" + uid
   2369                 + " is not privileged to communicate with user=" + userId);
   2370     }
   2371 
   2372     @Override
   2373     public int checkPermission(String permName, String pkgName) {
   2374         synchronized (mPackages) {
   2375             PackageParser.Package p = mPackages.get(pkgName);
   2376             if (p != null && p.mExtras != null) {
   2377                 PackageSetting ps = (PackageSetting)p.mExtras;
   2378                 if (ps.sharedUser != null) {
   2379                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
   2380                         return PackageManager.PERMISSION_GRANTED;
   2381                     }
   2382                 } else if (ps.grantedPermissions.contains(permName)) {
   2383                     return PackageManager.PERMISSION_GRANTED;
   2384                 }
   2385             }
   2386         }
   2387         return PackageManager.PERMISSION_DENIED;
   2388     }
   2389 
   2390     @Override
   2391     public int checkUidPermission(String permName, int uid) {
   2392         synchronized (mPackages) {
   2393             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   2394             if (obj != null) {
   2395                 GrantedPermissions gp = (GrantedPermissions)obj;
   2396                 if (gp.grantedPermissions.contains(permName)) {
   2397                     return PackageManager.PERMISSION_GRANTED;
   2398                 }
   2399             } else {
   2400                 ArraySet<String> perms = mSystemPermissions.get(uid);
   2401                 if (perms != null && perms.contains(permName)) {
   2402                     return PackageManager.PERMISSION_GRANTED;
   2403                 }
   2404             }
   2405         }
   2406         return PackageManager.PERMISSION_DENIED;
   2407     }
   2408 
   2409     /**
   2410      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
   2411      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
   2412      * @param checkShell TODO(yamasani):
   2413      * @param message the message to log on security exception
   2414      */
   2415     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
   2416             boolean checkShell, String message) {
   2417         if (userId < 0) {
   2418             throw new IllegalArgumentException("Invalid userId " + userId);
   2419         }
   2420         if (checkShell) {
   2421             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
   2422         }
   2423         if (userId == UserHandle.getUserId(callingUid)) return;
   2424         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
   2425             if (requireFullPermission) {
   2426                 mContext.enforceCallingOrSelfPermission(
   2427                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
   2428             } else {
   2429                 try {
   2430                     mContext.enforceCallingOrSelfPermission(
   2431                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
   2432                 } catch (SecurityException se) {
   2433                     mContext.enforceCallingOrSelfPermission(
   2434                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
   2435                 }
   2436             }
   2437         }
   2438     }
   2439 
   2440     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
   2441         if (callingUid == Process.SHELL_UID) {
   2442             if (userHandle >= 0
   2443                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
   2444                 throw new SecurityException("Shell does not have permission to access user "
   2445                         + userHandle);
   2446             } else if (userHandle < 0) {
   2447                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
   2448                         + Debug.getCallers(3));
   2449             }
   2450         }
   2451     }
   2452 
   2453     private BasePermission findPermissionTreeLP(String permName) {
   2454         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
   2455             if (permName.startsWith(bp.name) &&
   2456                     permName.length() > bp.name.length() &&
   2457                     permName.charAt(bp.name.length()) == '.') {
   2458                 return bp;
   2459             }
   2460         }
   2461         return null;
   2462     }
   2463 
   2464     private BasePermission checkPermissionTreeLP(String permName) {
   2465         if (permName != null) {
   2466             BasePermission bp = findPermissionTreeLP(permName);
   2467             if (bp != null) {
   2468                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
   2469                     return bp;
   2470                 }
   2471                 throw new SecurityException("Calling uid "
   2472                         + Binder.getCallingUid()
   2473                         + " is not allowed to add to permission tree "
   2474                         + bp.name + " owned by uid " + bp.uid);
   2475             }
   2476         }
   2477         throw new SecurityException("No permission tree found for " + permName);
   2478     }
   2479 
   2480     static boolean compareStrings(CharSequence s1, CharSequence s2) {
   2481         if (s1 == null) {
   2482             return s2 == null;
   2483         }
   2484         if (s2 == null) {
   2485             return false;
   2486         }
   2487         if (s1.getClass() != s2.getClass()) {
   2488             return false;
   2489         }
   2490         return s1.equals(s2);
   2491     }
   2492 
   2493     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
   2494         if (pi1.icon != pi2.icon) return false;
   2495         if (pi1.logo != pi2.logo) return false;
   2496         if (pi1.protectionLevel != pi2.protectionLevel) return false;
   2497         if (!compareStrings(pi1.name, pi2.name)) return false;
   2498         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
   2499         // We'll take care of setting this one.
   2500         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
   2501         // These are not currently stored in settings.
   2502         //if (!compareStrings(pi1.group, pi2.group)) return false;
   2503         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
   2504         //if (pi1.labelRes != pi2.labelRes) return false;
   2505         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
   2506         return true;
   2507     }
   2508 
   2509     int permissionInfoFootprint(PermissionInfo info) {
   2510         int size = info.name.length();
   2511         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
   2512         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
   2513         return size;
   2514     }
   2515 
   2516     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
   2517         int size = 0;
   2518         for (BasePermission perm : mSettings.mPermissions.values()) {
   2519             if (perm.uid == tree.uid) {
   2520                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
   2521             }
   2522         }
   2523         return size;
   2524     }
   2525 
   2526     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
   2527         // We calculate the max size of permissions defined by this uid and throw
   2528         // if that plus the size of 'info' would exceed our stated maximum.
   2529         if (tree.uid != Process.SYSTEM_UID) {
   2530             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
   2531             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
   2532                 throw new SecurityException("Permission tree size cap exceeded");
   2533             }
   2534         }
   2535     }
   2536 
   2537     boolean addPermissionLocked(PermissionInfo info, boolean async) {
   2538         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
   2539             throw new SecurityException("Label must be specified in permission");
   2540         }
   2541         BasePermission tree = checkPermissionTreeLP(info.name);
   2542         BasePermission bp = mSettings.mPermissions.get(info.name);
   2543         boolean added = bp == null;
   2544         boolean changed = true;
   2545         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
   2546         if (added) {
   2547             enforcePermissionCapLocked(info, tree);
   2548             bp = new BasePermission(info.name, tree.sourcePackage,
   2549                     BasePermission.TYPE_DYNAMIC);
   2550         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
   2551             throw new SecurityException(
   2552                     "Not allowed to modify non-dynamic permission "
   2553                     + info.name);
   2554         } else {
   2555             if (bp.protectionLevel == fixedLevel
   2556                     && bp.perm.owner.equals(tree.perm.owner)
   2557                     && bp.uid == tree.uid
   2558                     && comparePermissionInfos(bp.perm.info, info)) {
   2559                 changed = false;
   2560             }
   2561         }
   2562         bp.protectionLevel = fixedLevel;
   2563         info = new PermissionInfo(info);
   2564         info.protectionLevel = fixedLevel;
   2565         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
   2566         bp.perm.info.packageName = tree.perm.info.packageName;
   2567         bp.uid = tree.uid;
   2568         if (added) {
   2569             mSettings.mPermissions.put(info.name, bp);
   2570         }
   2571         if (changed) {
   2572             if (!async) {
   2573                 mSettings.writeLPr();
   2574             } else {
   2575                 scheduleWriteSettingsLocked();
   2576             }
   2577         }
   2578         return added;
   2579     }
   2580 
   2581     @Override
   2582     public boolean addPermission(PermissionInfo info) {
   2583         synchronized (mPackages) {
   2584             return addPermissionLocked(info, false);
   2585         }
   2586     }
   2587 
   2588     @Override
   2589     public boolean addPermissionAsync(PermissionInfo info) {
   2590         synchronized (mPackages) {
   2591             return addPermissionLocked(info, true);
   2592         }
   2593     }
   2594 
   2595     @Override
   2596     public void removePermission(String name) {
   2597         synchronized (mPackages) {
   2598             checkPermissionTreeLP(name);
   2599             BasePermission bp = mSettings.mPermissions.get(name);
   2600             if (bp != null) {
   2601                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
   2602                     throw new SecurityException(
   2603                             "Not allowed to modify non-dynamic permission "
   2604                             + name);
   2605                 }
   2606                 mSettings.mPermissions.remove(name);
   2607                 mSettings.writeLPr();
   2608             }
   2609         }
   2610     }
   2611 
   2612     private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
   2613         int index = pkg.requestedPermissions.indexOf(bp.name);
   2614         if (index == -1) {
   2615             throw new SecurityException("Package " + pkg.packageName
   2616                     + " has not requested permission " + bp.name);
   2617         }
   2618         boolean isNormal =
   2619                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
   2620                         == PermissionInfo.PROTECTION_NORMAL);
   2621         boolean isDangerous =
   2622                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
   2623                         == PermissionInfo.PROTECTION_DANGEROUS);
   2624         boolean isDevelopment =
   2625                 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
   2626 
   2627         if (!isNormal && !isDangerous && !isDevelopment) {
   2628             throw new SecurityException("Permission " + bp.name
   2629                     + " is not a changeable permission type");
   2630         }
   2631 
   2632         if (isNormal || isDangerous) {
   2633             if (pkg.requestedPermissionsRequired.get(index)) {
   2634                 throw new SecurityException("Can't change " + bp.name
   2635                         + ". It is required by the application");
   2636             }
   2637         }
   2638     }
   2639 
   2640     @Override
   2641     public void grantPermission(String packageName, String permissionName) {
   2642         mContext.enforceCallingOrSelfPermission(
   2643                 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
   2644         synchronized (mPackages) {
   2645             final PackageParser.Package pkg = mPackages.get(packageName);
   2646             if (pkg == null) {
   2647                 throw new IllegalArgumentException("Unknown package: " + packageName);
   2648             }
   2649             final BasePermission bp = mSettings.mPermissions.get(permissionName);
   2650             if (bp == null) {
   2651                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
   2652             }
   2653 
   2654             checkGrantRevokePermissions(pkg, bp);
   2655 
   2656             final PackageSetting ps = (PackageSetting) pkg.mExtras;
   2657             if (ps == null) {
   2658                 return;
   2659             }
   2660             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
   2661             if (gp.grantedPermissions.add(permissionName)) {
   2662                 if (ps.haveGids) {
   2663                     gp.gids = appendInts(gp.gids, bp.gids);
   2664                 }
   2665                 mSettings.writeLPr();
   2666             }
   2667         }
   2668     }
   2669 
   2670     @Override
   2671     public void revokePermission(String packageName, String permissionName) {
   2672         int changedAppId = -1;
   2673 
   2674         synchronized (mPackages) {
   2675             final PackageParser.Package pkg = mPackages.get(packageName);
   2676             if (pkg == null) {
   2677                 throw new IllegalArgumentException("Unknown package: " + packageName);
   2678             }
   2679             if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
   2680                 mContext.enforceCallingOrSelfPermission(
   2681                         android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
   2682             }
   2683             final BasePermission bp = mSettings.mPermissions.get(permissionName);
   2684             if (bp == null) {
   2685                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
   2686             }
   2687 
   2688             checkGrantRevokePermissions(pkg, bp);
   2689 
   2690             final PackageSetting ps = (PackageSetting) pkg.mExtras;
   2691             if (ps == null) {
   2692                 return;
   2693             }
   2694             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
   2695             if (gp.grantedPermissions.remove(permissionName)) {
   2696                 gp.grantedPermissions.remove(permissionName);
   2697                 if (ps.haveGids) {
   2698                     gp.gids = removeInts(gp.gids, bp.gids);
   2699                 }
   2700                 mSettings.writeLPr();
   2701                 changedAppId = ps.appId;
   2702             }
   2703         }
   2704 
   2705         if (changedAppId >= 0) {
   2706             // We changed the perm on someone, kill its processes.
   2707             IActivityManager am = ActivityManagerNative.getDefault();
   2708             if (am != null) {
   2709                 final int callingUserId = UserHandle.getCallingUserId();
   2710                 final long ident = Binder.clearCallingIdentity();
   2711                 try {
   2712                     //XXX we should only revoke for the calling user's app permissions,
   2713                     // but for now we impact all users.
   2714                     //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
   2715                     //        "revoke " + permissionName);
   2716                     int[] users = sUserManager.getUserIds();
   2717                     for (int user : users) {
   2718                         am.killUid(UserHandle.getUid(user, changedAppId),
   2719                                 "revoke " + permissionName);
   2720                     }
   2721                 } catch (RemoteException e) {
   2722                 } finally {
   2723                     Binder.restoreCallingIdentity(ident);
   2724                 }
   2725             }
   2726         }
   2727     }
   2728 
   2729     @Override
   2730     public boolean isProtectedBroadcast(String actionName) {
   2731         synchronized (mPackages) {
   2732             return mProtectedBroadcasts.contains(actionName);
   2733         }
   2734     }
   2735 
   2736     @Override
   2737     public int checkSignatures(String pkg1, String pkg2) {
   2738         synchronized (mPackages) {
   2739             final PackageParser.Package p1 = mPackages.get(pkg1);
   2740             final PackageParser.Package p2 = mPackages.get(pkg2);
   2741             if (p1 == null || p1.mExtras == null
   2742                     || p2 == null || p2.mExtras == null) {
   2743                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2744             }
   2745             return compareSignatures(p1.mSignatures, p2.mSignatures);
   2746         }
   2747     }
   2748 
   2749     @Override
   2750     public int checkUidSignatures(int uid1, int uid2) {
   2751         // Map to base uids.
   2752         uid1 = UserHandle.getAppId(uid1);
   2753         uid2 = UserHandle.getAppId(uid2);
   2754         // reader
   2755         synchronized (mPackages) {
   2756             Signature[] s1;
   2757             Signature[] s2;
   2758             Object obj = mSettings.getUserIdLPr(uid1);
   2759             if (obj != null) {
   2760                 if (obj instanceof SharedUserSetting) {
   2761                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
   2762                 } else if (obj instanceof PackageSetting) {
   2763                     s1 = ((PackageSetting)obj).signatures.mSignatures;
   2764                 } else {
   2765                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2766                 }
   2767             } else {
   2768                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2769             }
   2770             obj = mSettings.getUserIdLPr(uid2);
   2771             if (obj != null) {
   2772                 if (obj instanceof SharedUserSetting) {
   2773                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
   2774                 } else if (obj instanceof PackageSetting) {
   2775                     s2 = ((PackageSetting)obj).signatures.mSignatures;
   2776                 } else {
   2777                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2778                 }
   2779             } else {
   2780                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2781             }
   2782             return compareSignatures(s1, s2);
   2783         }
   2784     }
   2785 
   2786     /**
   2787      * Compares two sets of signatures. Returns:
   2788      * <br />
   2789      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
   2790      * <br />
   2791      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
   2792      * <br />
   2793      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
   2794      * <br />
   2795      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
   2796      * <br />
   2797      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
   2798      */
   2799     static int compareSignatures(Signature[] s1, Signature[] s2) {
   2800         if (s1 == null) {
   2801             return s2 == null
   2802                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
   2803                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
   2804         }
   2805 
   2806         if (s2 == null) {
   2807             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
   2808         }
   2809 
   2810         if (s1.length != s2.length) {
   2811             return PackageManager.SIGNATURE_NO_MATCH;
   2812         }
   2813 
   2814         // Since both signature sets are of size 1, we can compare without HashSets.
   2815         if (s1.length == 1) {
   2816             return s1[0].equals(s2[0]) ?
   2817                     PackageManager.SIGNATURE_MATCH :
   2818                     PackageManager.SIGNATURE_NO_MATCH;
   2819         }
   2820 
   2821         ArraySet<Signature> set1 = new ArraySet<Signature>();
   2822         for (Signature sig : s1) {
   2823             set1.add(sig);
   2824         }
   2825         ArraySet<Signature> set2 = new ArraySet<Signature>();
   2826         for (Signature sig : s2) {
   2827             set2.add(sig);
   2828         }
   2829         // Make sure s2 contains all signatures in s1.
   2830         if (set1.equals(set2)) {
   2831             return PackageManager.SIGNATURE_MATCH;
   2832         }
   2833         return PackageManager.SIGNATURE_NO_MATCH;
   2834     }
   2835 
   2836     /**
   2837      * If the database version for this type of package (internal storage or
   2838      * external storage) is less than the version where package signatures
   2839      * were updated, return true.
   2840      */
   2841     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
   2842         return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
   2843                 DatabaseVersion.SIGNATURE_END_ENTITY))
   2844                 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
   2845                         DatabaseVersion.SIGNATURE_END_ENTITY));
   2846     }
   2847 
   2848     /**
   2849      * Used for backward compatibility to make sure any packages with
   2850      * certificate chains get upgraded to the new style. {@code existingSigs}
   2851      * will be in the old format (since they were stored on disk from before the
   2852      * system upgrade) and {@code scannedSigs} will be in the newer format.
   2853      */
   2854     private int compareSignaturesCompat(PackageSignatures existingSigs,
   2855             PackageParser.Package scannedPkg) {
   2856         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
   2857             return PackageManager.SIGNATURE_NO_MATCH;
   2858         }
   2859 
   2860         ArraySet<Signature> existingSet = new ArraySet<Signature>();
   2861         for (Signature sig : existingSigs.mSignatures) {
   2862             existingSet.add(sig);
   2863         }
   2864         ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
   2865         for (Signature sig : scannedPkg.mSignatures) {
   2866             try {
   2867                 Signature[] chainSignatures = sig.getChainSignatures();
   2868                 for (Signature chainSig : chainSignatures) {
   2869                     scannedCompatSet.add(chainSig);
   2870                 }
   2871             } catch (CertificateEncodingException e) {
   2872                 scannedCompatSet.add(sig);
   2873             }
   2874         }
   2875         /*
   2876          * Make sure the expanded scanned set contains all signatures in the
   2877          * existing one.
   2878          */
   2879         if (scannedCompatSet.equals(existingSet)) {
   2880             // Migrate the old signatures to the new scheme.
   2881             existingSigs.assignSignatures(scannedPkg.mSignatures);
   2882             // The new KeySets will be re-added later in the scanning process.
   2883             synchronized (mPackages) {
   2884                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
   2885             }
   2886             return PackageManager.SIGNATURE_MATCH;
   2887         }
   2888         return PackageManager.SIGNATURE_NO_MATCH;
   2889     }
   2890 
   2891     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
   2892         if (isExternal(scannedPkg)) {
   2893             return mSettings.isExternalDatabaseVersionOlderThan(
   2894                     DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
   2895         } else {
   2896             return mSettings.isInternalDatabaseVersionOlderThan(
   2897                     DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
   2898         }
   2899     }
   2900 
   2901     private int compareSignaturesRecover(PackageSignatures existingSigs,
   2902             PackageParser.Package scannedPkg) {
   2903         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
   2904             return PackageManager.SIGNATURE_NO_MATCH;
   2905         }
   2906 
   2907         String msg = null;
   2908         try {
   2909             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
   2910                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
   2911                         + scannedPkg.packageName);
   2912                 return PackageManager.SIGNATURE_MATCH;
   2913             }
   2914         } catch (CertificateException e) {
   2915             msg = e.getMessage();
   2916         }
   2917 
   2918         logCriticalInfo(Log.INFO,
   2919                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
   2920         return PackageManager.SIGNATURE_NO_MATCH;
   2921     }
   2922 
   2923     @Override
   2924     public String[] getPackagesForUid(int uid) {
   2925         uid = UserHandle.getAppId(uid);
   2926         // reader
   2927         synchronized (mPackages) {
   2928             Object obj = mSettings.getUserIdLPr(uid);
   2929             if (obj instanceof SharedUserSetting) {
   2930                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2931                 final int N = sus.packages.size();
   2932                 final String[] res = new String[N];
   2933                 final Iterator<PackageSetting> it = sus.packages.iterator();
   2934                 int i = 0;
   2935                 while (it.hasNext()) {
   2936                     res[i++] = it.next().name;
   2937                 }
   2938                 return res;
   2939             } else if (obj instanceof PackageSetting) {
   2940                 final PackageSetting ps = (PackageSetting) obj;
   2941                 return new String[] { ps.name };
   2942             }
   2943         }
   2944         return null;
   2945     }
   2946 
   2947     @Override
   2948     public String getNameForUid(int uid) {
   2949         // reader
   2950         synchronized (mPackages) {
   2951             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   2952             if (obj instanceof SharedUserSetting) {
   2953                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2954                 return sus.name + ":" + sus.userId;
   2955             } else if (obj instanceof PackageSetting) {
   2956                 final PackageSetting ps = (PackageSetting) obj;
   2957                 return ps.name;
   2958             }
   2959         }
   2960         return null;
   2961     }
   2962 
   2963     @Override
   2964     public int getUidForSharedUser(String sharedUserName) {
   2965         if(sharedUserName == null) {
   2966             return -1;
   2967         }
   2968         // reader
   2969         synchronized (mPackages) {
   2970             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
   2971             if (suid == null) {
   2972                 return -1;
   2973             }
   2974             return suid.userId;
   2975         }
   2976     }
   2977 
   2978     @Override
   2979     public int getFlagsForUid(int uid) {
   2980         synchronized (mPackages) {
   2981             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   2982             if (obj instanceof SharedUserSetting) {
   2983                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2984                 return sus.pkgFlags;
   2985             } else if (obj instanceof PackageSetting) {
   2986                 final PackageSetting ps = (PackageSetting) obj;
   2987                 return ps.pkgFlags;
   2988             }
   2989         }
   2990         return 0;
   2991     }
   2992 
   2993     @Override
   2994     public boolean isUidPrivileged(int uid) {
   2995         uid = UserHandle.getAppId(uid);
   2996         // reader
   2997         synchronized (mPackages) {
   2998             Object obj = mSettings.getUserIdLPr(uid);
   2999             if (obj instanceof SharedUserSetting) {
   3000                 final SharedUserSetting sus = (SharedUserSetting) obj;
   3001                 final Iterator<PackageSetting> it = sus.packages.iterator();
   3002                 while (it.hasNext()) {
   3003                     if (it.next().isPrivileged()) {
   3004                         return true;
   3005                     }
   3006                 }
   3007             } else if (obj instanceof PackageSetting) {
   3008                 final PackageSetting ps = (PackageSetting) obj;
   3009                 return ps.isPrivileged();
   3010             }
   3011         }
   3012         return false;
   3013     }
   3014 
   3015     @Override
   3016     public String[] getAppOpPermissionPackages(String permissionName) {
   3017         synchronized (mPackages) {
   3018             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
   3019             if (pkgs == null) {
   3020                 return null;
   3021             }
   3022             return pkgs.toArray(new String[pkgs.size()]);
   3023         }
   3024     }
   3025 
   3026     @Override
   3027     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
   3028             int flags, int userId) {
   3029         if (!sUserManager.exists(userId)) return null;
   3030         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
   3031         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
   3032         return chooseBestActivity(intent, resolvedType, flags, query, userId);
   3033     }
   3034 
   3035     @Override
   3036     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
   3037             IntentFilter filter, int match, ComponentName activity) {
   3038         final int userId = UserHandle.getCallingUserId();
   3039         if (DEBUG_PREFERRED) {
   3040             Log.v(TAG, "setLastChosenActivity intent=" + intent
   3041                 + " resolvedType=" + resolvedType
   3042                 + " flags=" + flags
   3043                 + " filter=" + filter
   3044                 + " match=" + match
   3045                 + " activity=" + activity);
   3046             filter.dump(new PrintStreamPrinter(System.out), "    ");
   3047         }
   3048         intent.setComponent(null);
   3049         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
   3050         // Find any earlier preferred or last chosen entries and nuke them
   3051         findPreferredActivity(intent, resolvedType,
   3052                 flags, query, 0, false, true, false, userId);
   3053         // Add the new activity as the last chosen for this filter
   3054         addPreferredActivityInternal(filter, match, null, activity, false, userId,
   3055                 "Setting last chosen");
   3056     }
   3057 
   3058     @Override
   3059     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
   3060         final int userId = UserHandle.getCallingUserId();
   3061         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
   3062         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
   3063         return findPreferredActivity(intent, resolvedType, flags, query, 0,
   3064                 false, false, false, userId);
   3065     }
   3066 
   3067     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
   3068             int flags, List<ResolveInfo> query, int userId) {
   3069         if (query != null) {
   3070             final int N = query.size();
   3071             if (N == 1) {
   3072                 return query.get(0);
   3073             } else if (N > 1) {
   3074                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   3075                 // If there is more than one activity with the same priority,
   3076                 // then let the user decide between them.
   3077                 ResolveInfo r0 = query.get(0);
   3078                 ResolveInfo r1 = query.get(1);
   3079                 if (DEBUG_INTENT_MATCHING || debug) {
   3080                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
   3081                             + r1.activityInfo.name + "=" + r1.priority);
   3082                 }
   3083                 // If the first activity has a higher priority, or a different
   3084                 // default, then it is always desireable to pick it.
   3085                 if (r0.priority != r1.priority
   3086                         || r0.preferredOrder != r1.preferredOrder
   3087                         || r0.isDefault != r1.isDefault) {
   3088                     return query.get(0);
   3089                 }
   3090                 // If we have saved a preference for a preferred activity for
   3091                 // this Intent, use that.
   3092                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
   3093                         flags, query, r0.priority, true, false, debug, userId);
   3094                 if (ri != null) {
   3095                     return ri;
   3096                 }
   3097                 if (userId != 0) {
   3098                     ri = new ResolveInfo(mResolveInfo);
   3099                     ri.activityInfo = new ActivityInfo(ri.activityInfo);
   3100                     ri.activityInfo.applicationInfo = new ApplicationInfo(
   3101                             ri.activityInfo.applicationInfo);
   3102                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
   3103                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
   3104                     return ri;
   3105                 }
   3106                 return mResolveInfo;
   3107             }
   3108         }
   3109         return null;
   3110     }
   3111 
   3112     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
   3113             int flags, List<ResolveInfo> query, boolean debug, int userId) {
   3114         final int N = query.size();
   3115         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
   3116                 .get(userId);
   3117         // Get the list of persistent preferred activities that handle the intent
   3118         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
   3119         List<PersistentPreferredActivity> pprefs = ppir != null
   3120                 ? ppir.queryIntent(intent, resolvedType,
   3121                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
   3122                 : null;
   3123         if (pprefs != null && pprefs.size() > 0) {
   3124             final int M = pprefs.size();
   3125             for (int i=0; i<M; i++) {
   3126                 final PersistentPreferredActivity ppa = pprefs.get(i);
   3127                 if (DEBUG_PREFERRED || debug) {
   3128                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
   3129                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
   3130                             + "\n  component=" + ppa.mComponent);
   3131                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   3132                 }
   3133                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
   3134                         flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
   3135                 if (DEBUG_PREFERRED || debug) {
   3136                     Slog.v(TAG, "Found persistent preferred activity:");
   3137                     if (ai != null) {
   3138                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   3139                     } else {
   3140                         Slog.v(TAG, "  null");
   3141                     }
   3142                 }
   3143                 if (ai == null) {
   3144                     // This previously registered persistent preferred activity
   3145                     // component is no longer known. Ignore it and do NOT remove it.
   3146                     continue;
   3147                 }
   3148                 for (int j=0; j<N; j++) {
   3149                     final ResolveInfo ri = query.get(j);
   3150                     if (!ri.activityInfo.applicationInfo.packageName
   3151                             .equals(ai.applicationInfo.packageName)) {
   3152                         continue;
   3153                     }
   3154                     if (!ri.activityInfo.name.equals(ai.name)) {
   3155                         continue;
   3156                     }
   3157                     //  Found a persistent preference that can handle the intent.
   3158                     if (DEBUG_PREFERRED || debug) {
   3159                         Slog.v(TAG, "Returning persistent preferred activity: " +
   3160                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
   3161                     }
   3162                     return ri;
   3163                 }
   3164             }
   3165         }
   3166         return null;
   3167     }
   3168 
   3169     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
   3170             List<ResolveInfo> query, int priority, boolean always,
   3171             boolean removeMatches, boolean debug, int userId) {
   3172         if (!sUserManager.exists(userId)) return null;
   3173         // writer
   3174         synchronized (mPackages) {
   3175             if (intent.getSelector() != null) {
   3176                 intent = intent.getSelector();
   3177             }
   3178             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
   3179 
   3180             // Try to find a matching persistent preferred activity.
   3181             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
   3182                     debug, userId);
   3183 
   3184             // If a persistent preferred activity matched, use it.
   3185             if (pri != null) {
   3186                 return pri;
   3187             }
   3188 
   3189             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   3190             // Get the list of preferred activities that handle the intent
   3191             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
   3192             List<PreferredActivity> prefs = pir != null
   3193                     ? pir.queryIntent(intent, resolvedType,
   3194                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
   3195                     : null;
   3196             if (prefs != null && prefs.size() > 0) {
   3197                 boolean changed = false;
   3198                 try {
   3199                     // First figure out how good the original match set is.
   3200                     // We will only allow preferred activities that came
   3201                     // from the same match quality.
   3202                     int match = 0;
   3203 
   3204                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
   3205 
   3206                     final int N = query.size();
   3207                     for (int j=0; j<N; j++) {
   3208                         final ResolveInfo ri = query.get(j);
   3209                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
   3210                                 + ": 0x" + Integer.toHexString(match));
   3211                         if (ri.match > match) {
   3212                             match = ri.match;
   3213                         }
   3214                     }
   3215 
   3216                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
   3217                             + Integer.toHexString(match));
   3218 
   3219                     match &= IntentFilter.MATCH_CATEGORY_MASK;
   3220                     final int M = prefs.size();
   3221                     for (int i=0; i<M; i++) {
   3222                         final PreferredActivity pa = prefs.get(i);
   3223                         if (DEBUG_PREFERRED || debug) {
   3224                             Slog.v(TAG, "Checking PreferredActivity ds="
   3225                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
   3226                                     + "\n  component=" + pa.mPref.mComponent);
   3227                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   3228                         }
   3229                         if (pa.mPref.mMatch != match) {
   3230                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
   3231                                     + Integer.toHexString(pa.mPref.mMatch));
   3232                             continue;
   3233                         }
   3234                         // If it's not an "always" type preferred activity and that's what we're
   3235                         // looking for, skip it.
   3236                         if (always && !pa.mPref.mAlways) {
   3237                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
   3238                             continue;
   3239                         }
   3240                         final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
   3241                                 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
   3242                         if (DEBUG_PREFERRED || debug) {
   3243                             Slog.v(TAG, "Found preferred activity:");
   3244                             if (ai != null) {
   3245                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   3246                             } else {
   3247                                 Slog.v(TAG, "  null");
   3248                             }
   3249                         }
   3250                         if (ai == null) {
   3251                             // This previously registered preferred activity
   3252                             // component is no longer known.  Most likely an update
   3253                             // to the app was installed and in the new version this
   3254                             // component no longer exists.  Clean it up by removing
   3255                             // it from the preferred activities list, and skip it.
   3256                             Slog.w(TAG, "Removing dangling preferred activity: "
   3257                                     + pa.mPref.mComponent);
   3258                             pir.removeFilter(pa);
   3259                             changed = true;
   3260                             continue;
   3261                         }
   3262                         for (int j=0; j<N; j++) {
   3263                             final ResolveInfo ri = query.get(j);
   3264                             if (!ri.activityInfo.applicationInfo.packageName
   3265                                     .equals(ai.applicationInfo.packageName)) {
   3266                                 continue;
   3267                             }
   3268                             if (!ri.activityInfo.name.equals(ai.name)) {
   3269                                 continue;
   3270                             }
   3271 
   3272                             if (removeMatches) {
   3273                                 pir.removeFilter(pa);
   3274                                 changed = true;
   3275                                 if (DEBUG_PREFERRED) {
   3276                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
   3277                                 }
   3278                                 break;
   3279                             }
   3280 
   3281                             // Okay we found a previously set preferred or last chosen app.
   3282                             // If the result set is different from when this
   3283                             // was created, we need to clear it and re-ask the
   3284                             // user their preference, if we're looking for an "always" type entry.
   3285                             if (always && !pa.mPref.sameSet(query)) {
   3286                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
   3287                                         + intent + " type " + resolvedType);
   3288                                 if (DEBUG_PREFERRED) {
   3289                                     Slog.v(TAG, "Removing preferred activity since set changed "
   3290                                             + pa.mPref.mComponent);
   3291                                 }
   3292                                 pir.removeFilter(pa);
   3293                                 // Re-add the filter as a "last chosen" entry (!always)
   3294                                 PreferredActivity lastChosen = new PreferredActivity(
   3295                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
   3296                                 pir.addFilter(lastChosen);
   3297                                 changed = true;
   3298                                 return null;
   3299                             }
   3300 
   3301                             // Yay! Either the set matched or we're looking for the last chosen
   3302                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
   3303                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
   3304                             return ri;
   3305                         }
   3306                     }
   3307                 } finally {
   3308                     if (changed) {
   3309                         if (DEBUG_PREFERRED) {
   3310                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
   3311                         }
   3312                         scheduleWritePackageRestrictionsLocked(userId);
   3313                     }
   3314                 }
   3315             }
   3316         }
   3317         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
   3318         return null;
   3319     }
   3320 
   3321     /*
   3322      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
   3323      */
   3324     @Override
   3325     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
   3326             int targetUserId) {
   3327         mContext.enforceCallingOrSelfPermission(
   3328                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   3329         List<CrossProfileIntentFilter> matches =
   3330                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
   3331         if (matches != null) {
   3332             int size = matches.size();
   3333             for (int i = 0; i < size; i++) {
   3334                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
   3335             }
   3336         }
   3337         return false;
   3338     }
   3339 
   3340     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
   3341             String resolvedType, int userId) {
   3342         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
   3343         if (resolver != null) {
   3344             return resolver.queryIntent(intent, resolvedType, false, userId);
   3345         }
   3346         return null;
   3347     }
   3348 
   3349     @Override
   3350     public List<ResolveInfo> queryIntentActivities(Intent intent,
   3351             String resolvedType, int flags, int userId) {
   3352         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3353         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
   3354         ComponentName comp = intent.getComponent();
   3355         if (comp == null) {
   3356             if (intent.getSelector() != null) {
   3357                 intent = intent.getSelector();
   3358                 comp = intent.getComponent();
   3359             }
   3360         }
   3361 
   3362         if (comp != null) {
   3363             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   3364             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
   3365             if (ai != null) {
   3366                 final ResolveInfo ri = new ResolveInfo();
   3367                 ri.activityInfo = ai;
   3368                 list.add(ri);
   3369             }
   3370             return list;
   3371         }
   3372 
   3373         // reader
   3374         synchronized (mPackages) {
   3375             final String pkgName = intent.getPackage();
   3376             if (pkgName == null) {
   3377                 List<CrossProfileIntentFilter> matchingFilters =
   3378                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
   3379                 // Check for results that need to skip the current profile.
   3380                 ResolveInfo resolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
   3381                         resolvedType, flags, userId);
   3382                 if (resolveInfo != null) {
   3383                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
   3384                     result.add(resolveInfo);
   3385                     return result;
   3386                 }
   3387                 // Check for cross profile results.
   3388                 resolveInfo = queryCrossProfileIntents(
   3389                         matchingFilters, intent, resolvedType, flags, userId);
   3390 
   3391                 // Check for results in the current profile.
   3392                 List<ResolveInfo> result = mActivities.queryIntent(
   3393                         intent, resolvedType, flags, userId);
   3394                 if (resolveInfo != null) {
   3395                     result.add(resolveInfo);
   3396                     Collections.sort(result, mResolvePrioritySorter);
   3397                 }
   3398                 return result;
   3399             }
   3400             final PackageParser.Package pkg = mPackages.get(pkgName);
   3401             if (pkg != null) {
   3402                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
   3403                         pkg.activities, userId);
   3404             }
   3405             return new ArrayList<ResolveInfo>();
   3406         }
   3407     }
   3408 
   3409     private ResolveInfo querySkipCurrentProfileIntents(
   3410             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
   3411             int flags, int sourceUserId) {
   3412         if (matchingFilters != null) {
   3413             int size = matchingFilters.size();
   3414             for (int i = 0; i < size; i ++) {
   3415                 CrossProfileIntentFilter filter = matchingFilters.get(i);
   3416                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
   3417                     // Checking if there are activities in the target user that can handle the
   3418                     // intent.
   3419                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
   3420                             flags, sourceUserId);
   3421                     if (resolveInfo != null) {
   3422                         return resolveInfo;
   3423                     }
   3424                 }
   3425             }
   3426         }
   3427         return null;
   3428     }
   3429 
   3430     // Return matching ResolveInfo if any for skip current profile intent filters.
   3431     private ResolveInfo queryCrossProfileIntents(
   3432             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
   3433             int flags, int sourceUserId) {
   3434         if (matchingFilters != null) {
   3435             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
   3436             // match the same intent. For performance reasons, it is better not to
   3437             // run queryIntent twice for the same userId
   3438             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
   3439             int size = matchingFilters.size();
   3440             for (int i = 0; i < size; i++) {
   3441                 CrossProfileIntentFilter filter = matchingFilters.get(i);
   3442                 int targetUserId = filter.getTargetUserId();
   3443                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
   3444                         && !alreadyTriedUserIds.get(targetUserId)) {
   3445                     // Checking if there are activities in the target user that can handle the
   3446                     // intent.
   3447                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
   3448                             flags, sourceUserId);
   3449                     if (resolveInfo != null) return resolveInfo;
   3450                     alreadyTriedUserIds.put(targetUserId, true);
   3451                 }
   3452             }
   3453         }
   3454         return null;
   3455     }
   3456 
   3457     private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
   3458             String resolvedType, int flags, int sourceUserId) {
   3459         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
   3460                 resolvedType, flags, filter.getTargetUserId());
   3461         if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
   3462             return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
   3463         }
   3464         return null;
   3465     }
   3466 
   3467     private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
   3468             int sourceUserId, int targetUserId) {
   3469         ResolveInfo forwardingResolveInfo = new ResolveInfo();
   3470         String className;
   3471         if (targetUserId == UserHandle.USER_OWNER) {
   3472             className = FORWARD_INTENT_TO_USER_OWNER;
   3473         } else {
   3474             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
   3475         }
   3476         ComponentName forwardingActivityComponentName = new ComponentName(
   3477                 mAndroidApplication.packageName, className);
   3478         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
   3479                 sourceUserId);
   3480         if (targetUserId == UserHandle.USER_OWNER) {
   3481             forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
   3482             forwardingResolveInfo.noResourceId = true;
   3483         }
   3484         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
   3485         forwardingResolveInfo.priority = 0;
   3486         forwardingResolveInfo.preferredOrder = 0;
   3487         forwardingResolveInfo.match = 0;
   3488         forwardingResolveInfo.isDefault = true;
   3489         forwardingResolveInfo.filter = filter;
   3490         forwardingResolveInfo.targetUserId = targetUserId;
   3491         return forwardingResolveInfo;
   3492     }
   3493 
   3494     @Override
   3495     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
   3496             Intent[] specifics, String[] specificTypes, Intent intent,
   3497             String resolvedType, int flags, int userId) {
   3498         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3499         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
   3500                 false, "query intent activity options");
   3501         final String resultsAction = intent.getAction();
   3502 
   3503         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
   3504                 | PackageManager.GET_RESOLVED_FILTER, userId);
   3505 
   3506         if (DEBUG_INTENT_MATCHING) {
   3507             Log.v(TAG, "Query " + intent + ": " + results);
   3508         }
   3509 
   3510         int specificsPos = 0;
   3511         int N;
   3512 
   3513         // todo: note that the algorithm used here is O(N^2).  This
   3514         // isn't a problem in our current environment, but if we start running
   3515         // into situations where we have more than 5 or 10 matches then this
   3516         // should probably be changed to something smarter...
   3517 
   3518         // First we go through and resolve each of the specific items
   3519         // that were supplied, taking care of removing any corresponding
   3520         // duplicate items in the generic resolve list.
   3521         if (specifics != null) {
   3522             for (int i=0; i<specifics.length; i++) {
   3523                 final Intent sintent = specifics[i];
   3524                 if (sintent == null) {
   3525                     continue;
   3526                 }
   3527 
   3528                 if (DEBUG_INTENT_MATCHING) {
   3529                     Log.v(TAG, "Specific #" + i + ": " + sintent);
   3530                 }
   3531 
   3532                 String action = sintent.getAction();
   3533                 if (resultsAction != null && resultsAction.equals(action)) {
   3534                     // If this action was explicitly requested, then don't
   3535                     // remove things that have it.
   3536                     action = null;
   3537                 }
   3538 
   3539                 ResolveInfo ri = null;
   3540                 ActivityInfo ai = null;
   3541 
   3542                 ComponentName comp = sintent.getComponent();
   3543                 if (comp == null) {
   3544                     ri = resolveIntent(
   3545                         sintent,
   3546                         specificTypes != null ? specificTypes[i] : null,
   3547                             flags, userId);
   3548                     if (ri == null) {
   3549                         continue;
   3550                     }
   3551                     if (ri == mResolveInfo) {
   3552                         // ACK!  Must do something better with this.
   3553                     }
   3554                     ai = ri.activityInfo;
   3555                     comp = new ComponentName(ai.applicationInfo.packageName,
   3556                             ai.name);
   3557                 } else {
   3558                     ai = getActivityInfo(comp, flags, userId);
   3559                     if (ai == null) {
   3560                         continue;
   3561                     }
   3562                 }
   3563 
   3564                 // Look for any generic query activities that are duplicates
   3565                 // of this specific one, and remove them from the results.
   3566                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
   3567                 N = results.size();
   3568                 int j;
   3569                 for (j=specificsPos; j<N; j++) {
   3570                     ResolveInfo sri = results.get(j);
   3571                     if ((sri.activityInfo.name.equals(comp.getClassName())
   3572                             && sri.activityInfo.applicationInfo.packageName.equals(
   3573                                     comp.getPackageName()))
   3574                         || (action != null && sri.filter.matchAction(action))) {
   3575                         results.remove(j);
   3576                         if (DEBUG_INTENT_MATCHING) Log.v(
   3577                             TAG, "Removing duplicate item from " + j
   3578                             + " due to specific " + specificsPos);
   3579                         if (ri == null) {
   3580                             ri = sri;
   3581                         }
   3582                         j--;
   3583                         N--;
   3584                     }
   3585                 }
   3586 
   3587                 // Add this specific item to its proper place.
   3588                 if (ri == null) {
   3589                     ri = new ResolveInfo();
   3590                     ri.activityInfo = ai;
   3591                 }
   3592                 results.add(specificsPos, ri);
   3593                 ri.specificIndex = i;
   3594                 specificsPos++;
   3595             }
   3596         }
   3597 
   3598         // Now we go through the remaining generic results and remove any
   3599         // duplicate actions that are found here.
   3600         N = results.size();
   3601         for (int i=specificsPos; i<N-1; i++) {
   3602             final ResolveInfo rii = results.get(i);
   3603             if (rii.filter == null) {
   3604                 continue;
   3605             }
   3606 
   3607             // Iterate over all of the actions of this result's intent
   3608             // filter...  typically this should be just one.
   3609             final Iterator<String> it = rii.filter.actionsIterator();
   3610             if (it == null) {
   3611                 continue;
   3612             }
   3613             while (it.hasNext()) {
   3614                 final String action = it.next();
   3615                 if (resultsAction != null && resultsAction.equals(action)) {
   3616                     // If this action was explicitly requested, then don't
   3617                     // remove things that have it.
   3618                     continue;
   3619                 }
   3620                 for (int j=i+1; j<N; j++) {
   3621                     final ResolveInfo rij = results.get(j);
   3622                     if (rij.filter != null && rij.filter.hasAction(action)) {
   3623                         results.remove(j);
   3624                         if (DEBUG_INTENT_MATCHING) Log.v(
   3625                             TAG, "Removing duplicate item from " + j
   3626                             + " due to action " + action + " at " + i);
   3627                         j--;
   3628                         N--;
   3629                     }
   3630                 }
   3631             }
   3632 
   3633             // If the caller didn't request filter information, drop it now
   3634             // so we don't have to marshall/unmarshall it.
   3635             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   3636                 rii.filter = null;
   3637             }
   3638         }
   3639 
   3640         // Filter out the caller activity if so requested.
   3641         if (caller != null) {
   3642             N = results.size();
   3643             for (int i=0; i<N; i++) {
   3644                 ActivityInfo ainfo = results.get(i).activityInfo;
   3645                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
   3646                         && caller.getClassName().equals(ainfo.name)) {
   3647                     results.remove(i);
   3648                     break;
   3649                 }
   3650             }
   3651         }
   3652 
   3653         // If the caller didn't request filter information,
   3654         // drop them now so we don't have to
   3655         // marshall/unmarshall it.
   3656         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   3657             N = results.size();
   3658             for (int i=0; i<N; i++) {
   3659                 results.get(i).filter = null;
   3660             }
   3661         }
   3662 
   3663         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
   3664         return results;
   3665     }
   3666 
   3667     @Override
   3668     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
   3669             int userId) {
   3670         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3671         ComponentName comp = intent.getComponent();
   3672         if (comp == null) {
   3673             if (intent.getSelector() != null) {
   3674                 intent = intent.getSelector();
   3675                 comp = intent.getComponent();
   3676             }
   3677         }
   3678         if (comp != null) {
   3679             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   3680             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
   3681             if (ai != null) {
   3682                 ResolveInfo ri = new ResolveInfo();
   3683                 ri.activityInfo = ai;
   3684                 list.add(ri);
   3685             }
   3686             return list;
   3687         }
   3688 
   3689         // reader
   3690         synchronized (mPackages) {
   3691             String pkgName = intent.getPackage();
   3692             if (pkgName == null) {
   3693                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
   3694             }
   3695             final PackageParser.Package pkg = mPackages.get(pkgName);
   3696             if (pkg != null) {
   3697                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
   3698                         userId);
   3699             }
   3700             return null;
   3701         }
   3702     }
   3703 
   3704     @Override
   3705     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
   3706         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
   3707         if (!sUserManager.exists(userId)) return null;
   3708         if (query != null) {
   3709             if (query.size() >= 1) {
   3710                 // If there is more than one service with the same priority,
   3711                 // just arbitrarily pick the first one.
   3712                 return query.get(0);
   3713             }
   3714         }
   3715         return null;
   3716     }
   3717 
   3718     @Override
   3719     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
   3720             int userId) {
   3721         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3722         ComponentName comp = intent.getComponent();
   3723         if (comp == null) {
   3724             if (intent.getSelector() != null) {
   3725                 intent = intent.getSelector();
   3726                 comp = intent.getComponent();
   3727             }
   3728         }
   3729         if (comp != null) {
   3730             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   3731             final ServiceInfo si = getServiceInfo(comp, flags, userId);
   3732             if (si != null) {
   3733                 final ResolveInfo ri = new ResolveInfo();
   3734                 ri.serviceInfo = si;
   3735                 list.add(ri);
   3736             }
   3737             return list;
   3738         }
   3739 
   3740         // reader
   3741         synchronized (mPackages) {
   3742             String pkgName = intent.getPackage();
   3743             if (pkgName == null) {
   3744                 return mServices.queryIntent(intent, resolvedType, flags, userId);
   3745             }
   3746             final PackageParser.Package pkg = mPackages.get(pkgName);
   3747             if (pkg != null) {
   3748                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
   3749                         userId);
   3750             }
   3751             return null;
   3752         }
   3753     }
   3754 
   3755     @Override
   3756     public List<ResolveInfo> queryIntentContentProviders(
   3757             Intent intent, String resolvedType, int flags, int userId) {
   3758         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3759         ComponentName comp = intent.getComponent();
   3760         if (comp == null) {
   3761             if (intent.getSelector() != null) {
   3762                 intent = intent.getSelector();
   3763                 comp = intent.getComponent();
   3764             }
   3765         }
   3766         if (comp != null) {
   3767             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   3768             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
   3769             if (pi != null) {
   3770                 final ResolveInfo ri = new ResolveInfo();
   3771                 ri.providerInfo = pi;
   3772                 list.add(ri);
   3773             }
   3774             return list;
   3775         }
   3776 
   3777         // reader
   3778         synchronized (mPackages) {
   3779             String pkgName = intent.getPackage();
   3780             if (pkgName == null) {
   3781                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
   3782             }
   3783             final PackageParser.Package pkg = mPackages.get(pkgName);
   3784             if (pkg != null) {
   3785                 return mProviders.queryIntentForPackage(
   3786                         intent, resolvedType, flags, pkg.providers, userId);
   3787             }
   3788             return null;
   3789         }
   3790     }
   3791 
   3792     @Override
   3793     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
   3794         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   3795 
   3796         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
   3797 
   3798         // writer
   3799         synchronized (mPackages) {
   3800             ArrayList<PackageInfo> list;
   3801             if (listUninstalled) {
   3802                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
   3803                 for (PackageSetting ps : mSettings.mPackages.values()) {
   3804                     PackageInfo pi;
   3805                     if (ps.pkg != null) {
   3806                         pi = generatePackageInfo(ps.pkg, flags, userId);
   3807                     } else {
   3808                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
   3809                     }
   3810                     if (pi != null) {
   3811                         list.add(pi);
   3812                     }
   3813                 }
   3814             } else {
   3815                 list = new ArrayList<PackageInfo>(mPackages.size());
   3816                 for (PackageParser.Package p : mPackages.values()) {
   3817                     PackageInfo pi = generatePackageInfo(p, flags, userId);
   3818                     if (pi != null) {
   3819                         list.add(pi);
   3820                     }
   3821                 }
   3822             }
   3823 
   3824             return new ParceledListSlice<PackageInfo>(list);
   3825         }
   3826     }
   3827 
   3828     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
   3829             String[] permissions, boolean[] tmp, int flags, int userId) {
   3830         int numMatch = 0;
   3831         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   3832         for (int i=0; i<permissions.length; i++) {
   3833             if (gp.grantedPermissions.contains(permissions[i])) {
   3834                 tmp[i] = true;
   3835                 numMatch++;
   3836             } else {
   3837                 tmp[i] = false;
   3838             }
   3839         }
   3840         if (numMatch == 0) {
   3841             return;
   3842         }
   3843         PackageInfo pi;
   3844         if (ps.pkg != null) {
   3845             pi = generatePackageInfo(ps.pkg, flags, userId);
   3846         } else {
   3847             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
   3848         }
   3849         // The above might return null in cases of uninstalled apps or install-state
   3850         // skew across users/profiles.
   3851         if (pi != null) {
   3852             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
   3853                 if (numMatch == permissions.length) {
   3854                     pi.requestedPermissions = permissions;
   3855                 } else {
   3856                     pi.requestedPermissions = new String[numMatch];
   3857                     numMatch = 0;
   3858                     for (int i=0; i<permissions.length; i++) {
   3859                         if (tmp[i]) {
   3860                             pi.requestedPermissions[numMatch] = permissions[i];
   3861                             numMatch++;
   3862                         }
   3863                     }
   3864                 }
   3865             }
   3866             list.add(pi);
   3867         }
   3868     }
   3869 
   3870     @Override
   3871     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
   3872             String[] permissions, int flags, int userId) {
   3873         if (!sUserManager.exists(userId)) return null;
   3874         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   3875 
   3876         // writer
   3877         synchronized (mPackages) {
   3878             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
   3879             boolean[] tmpBools = new boolean[permissions.length];
   3880             if (listUninstalled) {
   3881                 for (PackageSetting ps : mSettings.mPackages.values()) {
   3882                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
   3883                 }
   3884             } else {
   3885                 for (PackageParser.Package pkg : mPackages.values()) {
   3886                     PackageSetting ps = (PackageSetting)pkg.mExtras;
   3887                     if (ps != null) {
   3888                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
   3889                                 userId);
   3890                     }
   3891                 }
   3892             }
   3893 
   3894             return new ParceledListSlice<PackageInfo>(list);
   3895         }
   3896     }
   3897 
   3898     @Override
   3899     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
   3900         if (!sUserManager.exists(userId)) return null;
   3901         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   3902 
   3903         // writer
   3904         synchronized (mPackages) {
   3905             ArrayList<ApplicationInfo> list;
   3906             if (listUninstalled) {
   3907                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
   3908                 for (PackageSetting ps : mSettings.mPackages.values()) {
   3909                     ApplicationInfo ai;
   3910                     if (ps.pkg != null) {
   3911                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
   3912                                 ps.readUserState(userId), userId);
   3913                     } else {
   3914                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
   3915                     }
   3916                     if (ai != null) {
   3917                         list.add(ai);
   3918                     }
   3919                 }
   3920             } else {
   3921                 list = new ArrayList<ApplicationInfo>(mPackages.size());
   3922                 for (PackageParser.Package p : mPackages.values()) {
   3923                     if (p.mExtras != null) {
   3924                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
   3925                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
   3926                         if (ai != null) {
   3927                             list.add(ai);
   3928                         }
   3929                     }
   3930                 }
   3931             }
   3932 
   3933             return new ParceledListSlice<ApplicationInfo>(list);
   3934         }
   3935     }
   3936 
   3937     public List<ApplicationInfo> getPersistentApplications(int flags) {
   3938         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
   3939 
   3940         // reader
   3941         synchronized (mPackages) {
   3942             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
   3943             final int userId = UserHandle.getCallingUserId();
   3944             while (i.hasNext()) {
   3945                 final PackageParser.Package p = i.next();
   3946                 if (p.applicationInfo != null
   3947                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
   3948                         && (!mSafeMode || isSystemApp(p))) {
   3949                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
   3950                     if (ps != null) {
   3951                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
   3952                                 ps.readUserState(userId), userId);
   3953                         if (ai != null) {
   3954                             finalList.add(ai);
   3955                         }
   3956                     }
   3957                 }
   3958             }
   3959         }
   3960 
   3961         return finalList;
   3962     }
   3963 
   3964     @Override
   3965     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
   3966         if (!sUserManager.exists(userId)) return null;
   3967         // reader
   3968         synchronized (mPackages) {
   3969             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
   3970             PackageSetting ps = provider != null
   3971                     ? mSettings.mPackages.get(provider.owner.packageName)
   3972                     : null;
   3973             return ps != null
   3974                     && mSettings.isEnabledLPr(provider.info, flags, userId)
   3975                     && (!mSafeMode || (provider.info.applicationInfo.flags
   3976                             &ApplicationInfo.FLAG_SYSTEM) != 0)
   3977                     ? PackageParser.generateProviderInfo(provider, flags,
   3978                             ps.readUserState(userId), userId)
   3979                     : null;
   3980         }
   3981     }
   3982 
   3983     /**
   3984      * @deprecated
   3985      */
   3986     @Deprecated
   3987     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
   3988         // reader
   3989         synchronized (mPackages) {
   3990             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
   3991                     .entrySet().iterator();
   3992             final int userId = UserHandle.getCallingUserId();
   3993             while (i.hasNext()) {
   3994                 Map.Entry<String, PackageParser.Provider> entry = i.next();
   3995                 PackageParser.Provider p = entry.getValue();
   3996                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
   3997 
   3998                 if (ps != null && p.syncable
   3999                         && (!mSafeMode || (p.info.applicationInfo.flags
   4000                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
   4001                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
   4002                             ps.readUserState(userId), userId);
   4003                     if (info != null) {
   4004                         outNames.add(entry.getKey());
   4005                         outInfo.add(info);
   4006                     }
   4007                 }
   4008             }
   4009         }
   4010     }
   4011 
   4012     @Override
   4013     public List<ProviderInfo> queryContentProviders(String processName,
   4014             int uid, int flags) {
   4015         ArrayList<ProviderInfo> finalList = null;
   4016         // reader
   4017         synchronized (mPackages) {
   4018             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
   4019             final int userId = processName != null ?
   4020                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
   4021             while (i.hasNext()) {
   4022                 final PackageParser.Provider p = i.next();
   4023                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
   4024                 if (ps != null && p.info.authority != null
   4025                         && (processName == null
   4026                                 || (p.info.processName.equals(processName)
   4027                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
   4028                         && mSettings.isEnabledLPr(p.info, flags, userId)
   4029                         && (!mSafeMode
   4030                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
   4031                     if (finalList == null) {
   4032                         finalList = new ArrayList<ProviderInfo>(3);
   4033                     }
   4034                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
   4035                             ps.readUserState(userId), userId);
   4036                     if (info != null) {
   4037                         finalList.add(info);
   4038                     }
   4039                 }
   4040             }
   4041         }
   4042 
   4043         if (finalList != null) {
   4044             Collections.sort(finalList, mProviderInitOrderSorter);
   4045         }
   4046 
   4047         return finalList;
   4048     }
   4049 
   4050     @Override
   4051     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
   4052             int flags) {
   4053         // reader
   4054         synchronized (mPackages) {
   4055             final PackageParser.Instrumentation i = mInstrumentation.get(name);
   4056             return PackageParser.generateInstrumentationInfo(i, flags);
   4057         }
   4058     }
   4059 
   4060     @Override
   4061     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
   4062             int flags) {
   4063         ArrayList<InstrumentationInfo> finalList =
   4064             new ArrayList<InstrumentationInfo>();
   4065 
   4066         // reader
   4067         synchronized (mPackages) {
   4068             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
   4069             while (i.hasNext()) {
   4070                 final PackageParser.Instrumentation p = i.next();
   4071                 if (targetPackage == null
   4072                         || targetPackage.equals(p.info.targetPackage)) {
   4073                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
   4074                             flags);
   4075                     if (ii != null) {
   4076                         finalList.add(ii);
   4077                     }
   4078                 }
   4079             }
   4080         }
   4081 
   4082         return finalList;
   4083     }
   4084 
   4085     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
   4086         ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
   4087         if (overlays == null) {
   4088             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
   4089             return;
   4090         }
   4091         for (PackageParser.Package opkg : overlays.values()) {
   4092             // Not much to do if idmap fails: we already logged the error
   4093             // and we certainly don't want to abort installation of pkg simply
   4094             // because an overlay didn't fit properly. For these reasons,
   4095             // ignore the return value of createIdmapForPackagePairLI.
   4096             createIdmapForPackagePairLI(pkg, opkg);
   4097         }
   4098     }
   4099 
   4100     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
   4101             PackageParser.Package opkg) {
   4102         if (!opkg.mTrustedOverlay) {
   4103             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
   4104                     opkg.baseCodePath + ": overlay not trusted");
   4105             return false;
   4106         }
   4107         ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
   4108         if (overlaySet == null) {
   4109             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
   4110                     opkg.baseCodePath + " but target package has no known overlays");
   4111             return false;
   4112         }
   4113         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   4114         // TODO: generate idmap for split APKs
   4115         if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
   4116             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
   4117                     + opkg.baseCodePath);
   4118             return false;
   4119         }
   4120         PackageParser.Package[] overlayArray =
   4121             overlaySet.values().toArray(new PackageParser.Package[0]);
   4122         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
   4123             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
   4124                 return p1.mOverlayPriority - p2.mOverlayPriority;
   4125             }
   4126         };
   4127         Arrays.sort(overlayArray, cmp);
   4128 
   4129         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
   4130         int i = 0;
   4131         for (PackageParser.Package p : overlayArray) {
   4132             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
   4133         }
   4134         return true;
   4135     }
   4136 
   4137     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
   4138         final File[] files = dir.listFiles();
   4139         if (ArrayUtils.isEmpty(files)) {
   4140             Log.d(TAG, "No files in app dir " + dir);
   4141             return;
   4142         }
   4143 
   4144         if (DEBUG_PACKAGE_SCANNING) {
   4145             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
   4146                     + " flags=0x" + Integer.toHexString(parseFlags));
   4147         }
   4148 
   4149         for (File file : files) {
   4150             final boolean isPackage = (isApkFile(file) || file.isDirectory())
   4151                     && !PackageInstallerService.isStageName(file.getName());
   4152             if (!isPackage) {
   4153                 // Ignore entries which are not packages
   4154                 continue;
   4155             }
   4156             try {
   4157                 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
   4158                         scanFlags, currentTime, null);
   4159             } catch (PackageManagerException e) {
   4160                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
   4161 
   4162                 // Delete invalid userdata apps
   4163                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
   4164                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
   4165                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
   4166                     if (file.isDirectory()) {
   4167                         FileUtils.deleteContents(file);
   4168                     }
   4169                     file.delete();
   4170                 }
   4171             }
   4172         }
   4173     }
   4174 
   4175     private static File getSettingsProblemFile() {
   4176         File dataDir = Environment.getDataDirectory();
   4177         File systemDir = new File(dataDir, "system");
   4178         File fname = new File(systemDir, "uiderrors.txt");
   4179         return fname;
   4180     }
   4181 
   4182     static void reportSettingsProblem(int priority, String msg) {
   4183         logCriticalInfo(priority, msg);
   4184     }
   4185 
   4186     static void logCriticalInfo(int priority, String msg) {
   4187         Slog.println(priority, TAG, msg);
   4188         EventLogTags.writePmCriticalInfo(msg);
   4189         try {
   4190             File fname = getSettingsProblemFile();
   4191             FileOutputStream out = new FileOutputStream(fname, true);
   4192             PrintWriter pw = new FastPrintWriter(out);
   4193             SimpleDateFormat formatter = new SimpleDateFormat();
   4194             String dateString = formatter.format(new Date(System.currentTimeMillis()));
   4195             pw.println(dateString + ": " + msg);
   4196             pw.close();
   4197             FileUtils.setPermissions(
   4198                     fname.toString(),
   4199                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
   4200                     -1, -1);
   4201         } catch (java.io.IOException e) {
   4202         }
   4203     }
   4204 
   4205     private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
   4206             PackageParser.Package pkg, File srcFile, int parseFlags)
   4207             throws PackageManagerException {
   4208         if (ps != null
   4209                 && ps.codePath.equals(srcFile)
   4210                 && ps.timeStamp == srcFile.lastModified()
   4211                 && !isCompatSignatureUpdateNeeded(pkg)
   4212                 && !isRecoverSignatureUpdateNeeded(pkg)) {
   4213             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
   4214             if (ps.signatures.mSignatures != null
   4215                     && ps.signatures.mSignatures.length != 0
   4216                     && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
   4217                 // Optimization: reuse the existing cached certificates
   4218                 // if the package appears to be unchanged.
   4219                 pkg.mSignatures = ps.signatures.mSignatures;
   4220                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
   4221                 synchronized (mPackages) {
   4222                     pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
   4223                 }
   4224                 return;
   4225             }
   4226 
   4227             Slog.w(TAG, "PackageSetting for " + ps.name
   4228                     + " is missing signatures.  Collecting certs again to recover them.");
   4229         } else {
   4230             Log.i(TAG, srcFile.toString() + " changed; collecting certs");
   4231         }
   4232 
   4233         try {
   4234             pp.collectCertificates(pkg, parseFlags);
   4235             pp.collectManifestDigest(pkg);
   4236         } catch (PackageParserException e) {
   4237             throw PackageManagerException.from(e);
   4238         }
   4239     }
   4240 
   4241     /*
   4242      *  Scan a package and return the newly parsed package.
   4243      *  Returns null in case of errors and the error code is stored in mLastScanError
   4244      */
   4245     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
   4246             long currentTime, UserHandle user) throws PackageManagerException {
   4247         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
   4248         parseFlags |= mDefParseFlags;
   4249         PackageParser pp = new PackageParser();
   4250         pp.setSeparateProcesses(mSeparateProcesses);
   4251         pp.setOnlyCoreApps(mOnlyCore);
   4252         pp.setDisplayMetrics(mMetrics);
   4253 
   4254         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
   4255             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
   4256         }
   4257 
   4258         final PackageParser.Package pkg;
   4259         try {
   4260             pkg = pp.parsePackage(scanFile, parseFlags);
   4261         } catch (PackageParserException e) {
   4262             throw PackageManagerException.from(e);
   4263         }
   4264 
   4265         PackageSetting ps = null;
   4266         PackageSetting updatedPkg;
   4267         // reader
   4268         synchronized (mPackages) {
   4269             // Look to see if we already know about this package.
   4270             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
   4271             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
   4272                 // This package has been renamed to its original name.  Let's
   4273                 // use that.
   4274                 ps = mSettings.peekPackageLPr(oldName);
   4275             }
   4276             // If there was no original package, see one for the real package name.
   4277             if (ps == null) {
   4278                 ps = mSettings.peekPackageLPr(pkg.packageName);
   4279             }
   4280             // Check to see if this package could be hiding/updating a system
   4281             // package.  Must look for it either under the original or real
   4282             // package name depending on our state.
   4283             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
   4284             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
   4285         }
   4286         boolean updatedPkgBetter = false;
   4287         // First check if this is a system package that may involve an update
   4288         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   4289             // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
   4290             // it needs to drop FLAG_PRIVILEGED.
   4291             if (locationIsPrivileged(scanFile)) {
   4292                 updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
   4293             } else {
   4294                 updatedPkg.pkgFlags &= ~ApplicationInfo.FLAG_PRIVILEGED;
   4295             }
   4296 
   4297             if (ps != null && !ps.codePath.equals(scanFile)) {
   4298                 // The path has changed from what was last scanned...  check the
   4299                 // version of the new path against what we have stored to determine
   4300                 // what to do.
   4301                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
   4302                 if (pkg.mVersionCode <= ps.versionCode) {
   4303                     // The system package has been updated and the code path does not match
   4304                     // Ignore entry. Skip it.
   4305                     Slog.i(TAG, "Package " + ps.name + " at " + scanFile
   4306                             + " ignored: updated version " + ps.versionCode
   4307                             + " better than this " + pkg.mVersionCode);
   4308                     if (!updatedPkg.codePath.equals(scanFile)) {
   4309                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
   4310                                 + ps.name + " changing from " + updatedPkg.codePathString
   4311                                 + " to " + scanFile);
   4312                         updatedPkg.codePath = scanFile;
   4313                         updatedPkg.codePathString = scanFile.toString();
   4314                     }
   4315                     updatedPkg.pkg = pkg;
   4316                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
   4317                 } else {
   4318                     // The current app on the system partition is better than
   4319                     // what we have updated to on the data partition; switch
   4320                     // back to the system partition version.
   4321                     // At this point, its safely assumed that package installation for
   4322                     // apps in system partition will go through. If not there won't be a working
   4323                     // version of the app
   4324                     // writer
   4325                     synchronized (mPackages) {
   4326                         // Just remove the loaded entries from package lists.
   4327                         mPackages.remove(ps.name);
   4328                     }
   4329 
   4330                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
   4331                             + " reverting from " + ps.codePathString
   4332                             + ": new version " + pkg.mVersionCode
   4333                             + " better than installed " + ps.versionCode);
   4334 
   4335                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   4336                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
   4337                             getAppDexInstructionSets(ps));
   4338                     synchronized (mInstallLock) {
   4339                         args.cleanUpResourcesLI();
   4340                     }
   4341                     synchronized (mPackages) {
   4342                         mSettings.enableSystemPackageLPw(ps.name);
   4343                     }
   4344                     updatedPkgBetter = true;
   4345                 }
   4346             }
   4347         }
   4348 
   4349         if (updatedPkg != null) {
   4350             // An updated system app will not have the PARSE_IS_SYSTEM flag set
   4351             // initially
   4352             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
   4353 
   4354             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
   4355             // flag set initially
   4356             if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
   4357                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   4358             }
   4359         }
   4360 
   4361         // Verify certificates against what was last scanned
   4362         collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
   4363 
   4364         /*
   4365          * A new system app appeared, but we already had a non-system one of the
   4366          * same name installed earlier.
   4367          */
   4368         boolean shouldHideSystemApp = false;
   4369         if (updatedPkg == null && ps != null
   4370                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
   4371             /*
   4372              * Check to make sure the signatures match first. If they don't,
   4373              * wipe the installed application and its data.
   4374              */
   4375             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
   4376                     != PackageManager.SIGNATURE_MATCH) {
   4377                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
   4378                         + " signatures don't match existing userdata copy; removing");
   4379                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
   4380                 ps = null;
   4381             } else {
   4382                 /*
   4383                  * If the newly-added system app is an older version than the
   4384                  * already installed version, hide it. It will be scanned later
   4385                  * and re-added like an update.
   4386                  */
   4387                 if (pkg.mVersionCode <= ps.versionCode) {
   4388                     shouldHideSystemApp = true;
   4389                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
   4390                             + " but new version " + pkg.mVersionCode + " better than installed "
   4391                             + ps.versionCode + "; hiding system");
   4392                 } else {
   4393                     /*
   4394                      * The newly found system app is a newer version that the
   4395                      * one previously installed. Simply remove the
   4396                      * already-installed application and replace it with our own
   4397                      * while keeping the application data.
   4398                      */
   4399                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
   4400                             + " reverting from " + ps.codePathString + ": new version "
   4401                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
   4402                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   4403                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
   4404                             getAppDexInstructionSets(ps));
   4405                     synchronized (mInstallLock) {
   4406                         args.cleanUpResourcesLI();
   4407                     }
   4408                 }
   4409             }
   4410         }
   4411 
   4412         // The apk is forward locked (not public) if its code and resources
   4413         // are kept in different files. (except for app in either system or
   4414         // vendor path).
   4415         // TODO grab this value from PackageSettings
   4416         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   4417             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
   4418                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   4419             }
   4420         }
   4421 
   4422         // TODO: extend to support forward-locked splits
   4423         String resourcePath = null;
   4424         String baseResourcePath = null;
   4425         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
   4426             if (ps != null && ps.resourcePathString != null) {
   4427                 resourcePath = ps.resourcePathString;
   4428                 baseResourcePath = ps.resourcePathString;
   4429             } else {
   4430                 // Should not happen at all. Just log an error.
   4431                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
   4432             }
   4433         } else {
   4434             resourcePath = pkg.codePath;
   4435             baseResourcePath = pkg.baseCodePath;
   4436         }
   4437 
   4438         // Set application objects path explicitly.
   4439         pkg.applicationInfo.setCodePath(pkg.codePath);
   4440         pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
   4441         pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
   4442         pkg.applicationInfo.setResourcePath(resourcePath);
   4443         pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
   4444         pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
   4445 
   4446         // Note that we invoke the following method only if we are about to unpack an application
   4447         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
   4448                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
   4449 
   4450         /*
   4451          * If the system app should be overridden by a previously installed
   4452          * data, hide the system app now and let the /data/app scan pick it up
   4453          * again.
   4454          */
   4455         if (shouldHideSystemApp) {
   4456             synchronized (mPackages) {
   4457                 /*
   4458                  * We have to grant systems permissions before we hide, because
   4459                  * grantPermissions will assume the package update is trying to
   4460                  * expand its permissions.
   4461                  */
   4462                 grantPermissionsLPw(pkg, true, pkg.packageName);
   4463                 mSettings.disableSystemPackageLPw(pkg.packageName);
   4464             }
   4465         }
   4466 
   4467         return scannedPkg;
   4468     }
   4469 
   4470     private static String fixProcessName(String defProcessName,
   4471             String processName, int uid) {
   4472         if (processName == null) {
   4473             return defProcessName;
   4474         }
   4475         return processName;
   4476     }
   4477 
   4478     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
   4479             throws PackageManagerException {
   4480         if (pkgSetting.signatures.mSignatures != null) {
   4481             // Already existing package. Make sure signatures match
   4482             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
   4483                     == PackageManager.SIGNATURE_MATCH;
   4484             if (!match) {
   4485                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
   4486                         == PackageManager.SIGNATURE_MATCH;
   4487             }
   4488             if (!match) {
   4489                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
   4490                         == PackageManager.SIGNATURE_MATCH;
   4491             }
   4492             if (!match) {
   4493                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
   4494                         + pkg.packageName + " signatures do not match the "
   4495                         + "previously installed version; ignoring!");
   4496             }
   4497         }
   4498 
   4499         // Check for shared user signatures
   4500         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
   4501             // Already existing package. Make sure signatures match
   4502             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   4503                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
   4504             if (!match) {
   4505                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
   4506                         == PackageManager.SIGNATURE_MATCH;
   4507             }
   4508             if (!match) {
   4509                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
   4510                         == PackageManager.SIGNATURE_MATCH;
   4511             }
   4512             if (!match) {
   4513                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
   4514                         "Package " + pkg.packageName
   4515                         + " has no signatures that match those in shared user "
   4516                         + pkgSetting.sharedUser.name + "; ignoring!");
   4517             }
   4518         }
   4519     }
   4520 
   4521     /**
   4522      * Enforces that only the system UID or root's UID can call a method exposed
   4523      * via Binder.
   4524      *
   4525      * @param message used as message if SecurityException is thrown
   4526      * @throws SecurityException if the caller is not system or root
   4527      */
   4528     private static final void enforceSystemOrRoot(String message) {
   4529         final int uid = Binder.getCallingUid();
   4530         if (uid != Process.SYSTEM_UID && uid != 0) {
   4531             throw new SecurityException(message);
   4532         }
   4533     }
   4534 
   4535     @Override
   4536     public void performBootDexOpt() {
   4537         enforceSystemOrRoot("Only the system can request dexopt be performed");
   4538 
   4539         // Before everything else, see whether we need to fstrim.
   4540         try {
   4541             IMountService ms = PackageHelper.getMountService();
   4542             if (ms != null) {
   4543                 final boolean isUpgrade = isUpgrade();
   4544                 boolean doTrim = isUpgrade;
   4545                 if (doTrim) {
   4546                     Slog.w(TAG, "Running disk maintenance immediately due to system update");
   4547                 } else {
   4548                     final long interval = android.provider.Settings.Global.getLong(
   4549                             mContext.getContentResolver(),
   4550                             android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
   4551                             DEFAULT_MANDATORY_FSTRIM_INTERVAL);
   4552                     if (interval > 0) {
   4553                         final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance();
   4554                         if (timeSinceLast > interval) {
   4555                             doTrim = true;
   4556                             Slog.w(TAG, "No disk maintenance in " + timeSinceLast
   4557                                     + "; running immediately");
   4558                         }
   4559                     }
   4560                 }
   4561                 if (doTrim) {
   4562                     if (!isFirstBoot()) {
   4563                         try {
   4564                             ActivityManagerNative.getDefault().showBootMessage(
   4565                                     mContext.getResources().getString(
   4566                                             R.string.android_upgrading_fstrim), true);
   4567                         } catch (RemoteException e) {
   4568                         }
   4569                     }
   4570                     ms.runMaintenance();
   4571                 }
   4572             } else {
   4573                 Slog.e(TAG, "Mount service unavailable!");
   4574             }
   4575         } catch (RemoteException e) {
   4576             // Can't happen; MountService is local
   4577         }
   4578 
   4579         final ArraySet<PackageParser.Package> pkgs;
   4580         synchronized (mPackages) {
   4581             pkgs = mDeferredDexOpt;
   4582             mDeferredDexOpt = null;
   4583         }
   4584 
   4585         if (pkgs != null) {
   4586             // Sort apps by importance for dexopt ordering. Important apps are given more priority
   4587             // in case the device runs out of space.
   4588             ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
   4589             // Give priority to core apps.
   4590             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4591                 PackageParser.Package pkg = it.next();
   4592                 if (pkg.coreApp) {
   4593                     if (DEBUG_DEXOPT) {
   4594                         Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
   4595                     }
   4596                     sortedPkgs.add(pkg);
   4597                     it.remove();
   4598                 }
   4599             }
   4600             // Give priority to system apps that listen for pre boot complete.
   4601             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   4602             ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
   4603             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4604                 PackageParser.Package pkg = it.next();
   4605                 if (pkgNames.contains(pkg.packageName)) {
   4606                     if (DEBUG_DEXOPT) {
   4607                         Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
   4608                     }
   4609                     sortedPkgs.add(pkg);
   4610                     it.remove();
   4611                 }
   4612             }
   4613             // Give priority to system apps.
   4614             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4615                 PackageParser.Package pkg = it.next();
   4616                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
   4617                     if (DEBUG_DEXOPT) {
   4618                         Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
   4619                     }
   4620                     sortedPkgs.add(pkg);
   4621                     it.remove();
   4622                 }
   4623             }
   4624             // Give priority to updated system apps.
   4625             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4626                 PackageParser.Package pkg = it.next();
   4627                 if (isUpdatedSystemApp(pkg)) {
   4628                     if (DEBUG_DEXOPT) {
   4629                         Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
   4630                     }
   4631                     sortedPkgs.add(pkg);
   4632                     it.remove();
   4633                 }
   4634             }
   4635             // Give priority to apps that listen for boot complete.
   4636             intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
   4637             pkgNames = getPackageNamesForIntent(intent);
   4638             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4639                 PackageParser.Package pkg = it.next();
   4640                 if (pkgNames.contains(pkg.packageName)) {
   4641                     if (DEBUG_DEXOPT) {
   4642                         Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
   4643                     }
   4644                     sortedPkgs.add(pkg);
   4645                     it.remove();
   4646                 }
   4647             }
   4648             // Filter out packages that aren't recently used.
   4649             filterRecentlyUsedApps(pkgs);
   4650             // Add all remaining apps.
   4651             for (PackageParser.Package pkg : pkgs) {
   4652                 if (DEBUG_DEXOPT) {
   4653                     Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
   4654                 }
   4655                 sortedPkgs.add(pkg);
   4656             }
   4657 
   4658             // If we want to be lazy, filter everything that wasn't recently used.
   4659             if (mLazyDexOpt) {
   4660                 filterRecentlyUsedApps(sortedPkgs);
   4661             }
   4662 
   4663             int i = 0;
   4664             int total = sortedPkgs.size();
   4665             File dataDir = Environment.getDataDirectory();
   4666             long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
   4667             if (lowThreshold == 0) {
   4668                 throw new IllegalStateException("Invalid low memory threshold");
   4669             }
   4670             for (PackageParser.Package pkg : sortedPkgs) {
   4671                 long usableSpace = dataDir.getUsableSpace();
   4672                 if (usableSpace < lowThreshold) {
   4673                     Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
   4674                     break;
   4675                 }
   4676                 performBootDexOpt(pkg, ++i, total);
   4677             }
   4678         }
   4679     }
   4680 
   4681     private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) {
   4682         // Filter out packages that aren't recently used.
   4683         //
   4684         // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
   4685         // should do a full dexopt.
   4686         if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
   4687             int total = pkgs.size();
   4688             int skipped = 0;
   4689             long now = System.currentTimeMillis();
   4690             for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
   4691                 PackageParser.Package pkg = i.next();
   4692                 long then = pkg.mLastPackageUsageTimeInMills;
   4693                 if (then + mDexOptLRUThresholdInMills < now) {
   4694                     if (DEBUG_DEXOPT) {
   4695                         Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
   4696                               ((then == 0) ? "never" : new Date(then)));
   4697                     }
   4698                     i.remove();
   4699                     skipped++;
   4700                 }
   4701             }
   4702             if (DEBUG_DEXOPT) {
   4703                 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
   4704             }
   4705         }
   4706     }
   4707 
   4708     private ArraySet<String> getPackageNamesForIntent(Intent intent) {
   4709         List<ResolveInfo> ris = null;
   4710         try {
   4711             ris = AppGlobals.getPackageManager().queryIntentReceivers(
   4712                     intent, null, 0, UserHandle.USER_OWNER);
   4713         } catch (RemoteException e) {
   4714         }
   4715         ArraySet<String> pkgNames = new ArraySet<String>();
   4716         if (ris != null) {
   4717             for (ResolveInfo ri : ris) {
   4718                 pkgNames.add(ri.activityInfo.packageName);
   4719             }
   4720         }
   4721         return pkgNames;
   4722     }
   4723 
   4724     private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
   4725         if (DEBUG_DEXOPT) {
   4726             Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
   4727         }
   4728         if (!isFirstBoot()) {
   4729             try {
   4730                 ActivityManagerNative.getDefault().showBootMessage(
   4731                         mContext.getResources().getString(R.string.android_upgrading_apk,
   4732                                 curr, total), true);
   4733             } catch (RemoteException e) {
   4734             }
   4735         }
   4736         PackageParser.Package p = pkg;
   4737         synchronized (mInstallLock) {
   4738             performDexOptLI(p, null /* instruction sets */, false /* force dex */,
   4739                             false /* defer */, true /* include dependencies */);
   4740         }
   4741     }
   4742 
   4743     @Override
   4744     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
   4745         return performDexOpt(packageName, instructionSet, false);
   4746     }
   4747 
   4748     private static String getPrimaryInstructionSet(ApplicationInfo info) {
   4749         if (info.primaryCpuAbi == null) {
   4750             return getPreferredInstructionSet();
   4751         }
   4752 
   4753         return VMRuntime.getInstructionSet(info.primaryCpuAbi);
   4754     }
   4755 
   4756     public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
   4757         boolean dexopt = mLazyDexOpt || backgroundDexopt;
   4758         boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
   4759         if (!dexopt && !updateUsage) {
   4760             // We aren't going to dexopt or update usage, so bail early.
   4761             return false;
   4762         }
   4763         PackageParser.Package p;
   4764         final String targetInstructionSet;
   4765         synchronized (mPackages) {
   4766             p = mPackages.get(packageName);
   4767             if (p == null) {
   4768                 return false;
   4769             }
   4770             if (updateUsage) {
   4771                 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
   4772             }
   4773             mPackageUsage.write(false);
   4774             if (!dexopt) {
   4775                 // We aren't going to dexopt, so bail early.
   4776                 return false;
   4777             }
   4778 
   4779             targetInstructionSet = instructionSet != null ? instructionSet :
   4780                     getPrimaryInstructionSet(p.applicationInfo);
   4781             if (p.mDexOptPerformed.contains(targetInstructionSet)) {
   4782                 return false;
   4783             }
   4784         }
   4785 
   4786         synchronized (mInstallLock) {
   4787             final String[] instructionSets = new String[] { targetInstructionSet };
   4788             return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */,
   4789                     true /* include dependencies */) == DEX_OPT_PERFORMED;
   4790         }
   4791     }
   4792 
   4793     public ArraySet<String> getPackagesThatNeedDexOpt() {
   4794         ArraySet<String> pkgs = null;
   4795         synchronized (mPackages) {
   4796             for (PackageParser.Package p : mPackages.values()) {
   4797                 if (DEBUG_DEXOPT) {
   4798                     Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
   4799                 }
   4800                 if (!p.mDexOptPerformed.isEmpty()) {
   4801                     continue;
   4802                 }
   4803                 if (pkgs == null) {
   4804                     pkgs = new ArraySet<String>();
   4805                 }
   4806                 pkgs.add(p.packageName);
   4807             }
   4808         }
   4809         return pkgs;
   4810     }
   4811 
   4812     public void shutdown() {
   4813         mPackageUsage.write(true);
   4814     }
   4815 
   4816     private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
   4817              boolean forceDex, boolean defer, ArraySet<String> done) {
   4818         for (int i=0; i<libs.size(); i++) {
   4819             PackageParser.Package libPkg;
   4820             String libName;
   4821             synchronized (mPackages) {
   4822                 libName = libs.get(i);
   4823                 SharedLibraryEntry lib = mSharedLibraries.get(libName);
   4824                 if (lib != null && lib.apk != null) {
   4825                     libPkg = mPackages.get(lib.apk);
   4826                 } else {
   4827                     libPkg = null;
   4828                 }
   4829             }
   4830             if (libPkg != null && !done.contains(libName)) {
   4831                 performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
   4832             }
   4833         }
   4834     }
   4835 
   4836     static final int DEX_OPT_SKIPPED = 0;
   4837     static final int DEX_OPT_PERFORMED = 1;
   4838     static final int DEX_OPT_DEFERRED = 2;
   4839     static final int DEX_OPT_FAILED = -1;
   4840 
   4841     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
   4842             boolean forceDex, boolean defer, ArraySet<String> done) {
   4843         final String[] instructionSets = targetInstructionSets != null ?
   4844                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
   4845 
   4846         if (done != null) {
   4847             done.add(pkg.packageName);
   4848             if (pkg.usesLibraries != null) {
   4849                 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
   4850             }
   4851             if (pkg.usesOptionalLibraries != null) {
   4852                 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done);
   4853             }
   4854         }
   4855 
   4856         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
   4857             return DEX_OPT_SKIPPED;
   4858         }
   4859 
   4860         final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
   4861 
   4862         final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
   4863         boolean performedDexOpt = false;
   4864         // There are three basic cases here:
   4865         // 1.) we need to dexopt, either because we are forced or it is needed
   4866         // 2.) we are defering a needed dexopt
   4867         // 3.) we are skipping an unneeded dexopt
   4868         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
   4869         for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   4870             if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
   4871                 continue;
   4872             }
   4873 
   4874             for (String path : paths) {
   4875                 try {
   4876                     // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
   4877                     // patckage or the one we find does not match the image checksum (i.e. it was
   4878                     // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
   4879                     // odex file and it matches the checksum of the image but not its base address,
   4880                     // meaning we need to move it.
   4881                     final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
   4882                             pkg.packageName, dexCodeInstructionSet, defer);
   4883                     if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
   4884                         Log.i(TAG, "Running dexopt on: " + path + " pkg="
   4885                                 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
   4886                                 + " vmSafeMode=" + vmSafeMode);
   4887                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   4888                         final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
   4889                                 pkg.packageName, dexCodeInstructionSet, vmSafeMode);
   4890 
   4891                         if (ret < 0) {
   4892                             // Don't bother running dexopt again if we failed, it will probably
   4893                             // just result in an error again. Also, don't bother dexopting for other
   4894                             // paths & ISAs.
   4895                             return DEX_OPT_FAILED;
   4896                         }
   4897 
   4898                         performedDexOpt = true;
   4899                     } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
   4900                         Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
   4901                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   4902                         final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
   4903                                 pkg.packageName, dexCodeInstructionSet);
   4904 
   4905                         if (ret < 0) {
   4906                             // Don't bother running patchoat again if we failed, it will probably
   4907                             // just result in an error again. Also, don't bother dexopting for other
   4908                             // paths & ISAs.
   4909                             return DEX_OPT_FAILED;
   4910                         }
   4911 
   4912                         performedDexOpt = true;
   4913                     }
   4914 
   4915                     // We're deciding to defer a needed dexopt. Don't bother dexopting for other
   4916                     // paths and instruction sets. We'll deal with them all together when we process
   4917                     // our list of deferred dexopts.
   4918                     if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
   4919                         if (mDeferredDexOpt == null) {
   4920                             mDeferredDexOpt = new ArraySet<PackageParser.Package>();
   4921                         }
   4922                         mDeferredDexOpt.add(pkg);
   4923                         return DEX_OPT_DEFERRED;
   4924                     }
   4925                 } catch (FileNotFoundException e) {
   4926                     Slog.w(TAG, "Apk not found for dexopt: " + path);
   4927                     return DEX_OPT_FAILED;
   4928                 } catch (IOException e) {
   4929                     Slog.w(TAG, "IOException reading apk: " + path, e);
   4930                     return DEX_OPT_FAILED;
   4931                 } catch (StaleDexCacheError e) {
   4932                     Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
   4933                     return DEX_OPT_FAILED;
   4934                 } catch (Exception e) {
   4935                     Slog.w(TAG, "Exception when doing dexopt : ", e);
   4936                     return DEX_OPT_FAILED;
   4937                 }
   4938             }
   4939 
   4940             // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
   4941             // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
   4942             // it isn't required. We therefore mark that this package doesn't need dexopt unless
   4943             // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
   4944             // it.
   4945             pkg.mDexOptPerformed.add(dexCodeInstructionSet);
   4946         }
   4947 
   4948         // If we've gotten here, we're sure that no error occurred and that we haven't
   4949         // deferred dex-opt. We've either dex-opted one more paths or instruction sets or
   4950         // we've skipped all of them because they are up to date. In both cases this
   4951         // package doesn't need dexopt any longer.
   4952         return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
   4953     }
   4954 
   4955     private static String[] getAppDexInstructionSets(ApplicationInfo info) {
   4956         if (info.primaryCpuAbi != null) {
   4957             if (info.secondaryCpuAbi != null) {
   4958                 return new String[] {
   4959                         VMRuntime.getInstructionSet(info.primaryCpuAbi),
   4960                         VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
   4961             } else {
   4962                 return new String[] {
   4963                         VMRuntime.getInstructionSet(info.primaryCpuAbi) };
   4964             }
   4965         }
   4966 
   4967         return new String[] { getPreferredInstructionSet() };
   4968     }
   4969 
   4970     private static String[] getAppDexInstructionSets(PackageSetting ps) {
   4971         if (ps.primaryCpuAbiString != null) {
   4972             if (ps.secondaryCpuAbiString != null) {
   4973                 return new String[] {
   4974                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
   4975                         VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
   4976             } else {
   4977                 return new String[] {
   4978                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
   4979             }
   4980         }
   4981 
   4982         return new String[] { getPreferredInstructionSet() };
   4983     }
   4984 
   4985     private static String getPreferredInstructionSet() {
   4986         if (sPreferredInstructionSet == null) {
   4987             sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
   4988         }
   4989 
   4990         return sPreferredInstructionSet;
   4991     }
   4992 
   4993     private static List<String> getAllInstructionSets() {
   4994         final String[] allAbis = Build.SUPPORTED_ABIS;
   4995         final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
   4996 
   4997         for (String abi : allAbis) {
   4998             final String instructionSet = VMRuntime.getInstructionSet(abi);
   4999             if (!allInstructionSets.contains(instructionSet)) {
   5000                 allInstructionSets.add(instructionSet);
   5001             }
   5002         }
   5003 
   5004         return allInstructionSets;
   5005     }
   5006 
   5007     /**
   5008      * Returns the instruction set that should be used to compile dex code. In the presence of
   5009      * a native bridge this might be different than the one shared libraries use.
   5010      */
   5011     private static String getDexCodeInstructionSet(String sharedLibraryIsa) {
   5012         String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
   5013         return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
   5014     }
   5015 
   5016     private static String[] getDexCodeInstructionSets(String[] instructionSets) {
   5017         ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length);
   5018         for (String instructionSet : instructionSets) {
   5019             dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
   5020         }
   5021         return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
   5022     }
   5023 
   5024     /**
   5025      * Returns deduplicated list of supported instructions for dex code.
   5026      */
   5027     public static String[] getAllDexCodeInstructionSets() {
   5028         String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
   5029         for (int i = 0; i < supportedInstructionSets.length; i++) {
   5030             String abi = Build.SUPPORTED_ABIS[i];
   5031             supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
   5032         }
   5033         return getDexCodeInstructionSets(supportedInstructionSets);
   5034     }
   5035 
   5036     @Override
   5037     public void forceDexOpt(String packageName) {
   5038         enforceSystemOrRoot("forceDexOpt");
   5039 
   5040         PackageParser.Package pkg;
   5041         synchronized (mPackages) {
   5042             pkg = mPackages.get(packageName);
   5043             if (pkg == null) {
   5044                 throw new IllegalArgumentException("Missing package: " + packageName);
   5045             }
   5046         }
   5047 
   5048         synchronized (mInstallLock) {
   5049             final String[] instructionSets = new String[] {
   5050                     getPrimaryInstructionSet(pkg.applicationInfo) };
   5051             final int res = performDexOptLI(pkg, instructionSets, true, false, true);
   5052             if (res != DEX_OPT_PERFORMED) {
   5053                 throw new IllegalStateException("Failed to dexopt: " + res);
   5054             }
   5055         }
   5056     }
   5057 
   5058     private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets,
   5059                                 boolean forceDex, boolean defer, boolean inclDependencies) {
   5060         ArraySet<String> done;
   5061         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
   5062             done = new ArraySet<String>();
   5063             done.add(pkg.packageName);
   5064         } else {
   5065             done = null;
   5066         }
   5067         return performDexOptLI(pkg, instructionSets,  forceDex, defer, done);
   5068     }
   5069 
   5070     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
   5071         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   5072             Slog.w(TAG, "Unable to update from " + oldPkg.name
   5073                     + " to " + newPkg.packageName
   5074                     + ": old package not in system partition");
   5075             return false;
   5076         } else if (mPackages.get(oldPkg.name) != null) {
   5077             Slog.w(TAG, "Unable to update from " + oldPkg.name
   5078                     + " to " + newPkg.packageName
   5079                     + ": old package still exists");
   5080             return false;
   5081         }
   5082         return true;
   5083     }
   5084 
   5085     File getDataPathForUser(int userId) {
   5086         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
   5087     }
   5088 
   5089     private File getDataPathForPackage(String packageName, int userId) {
   5090         /*
   5091          * Until we fully support multiple users, return the directory we
   5092          * previously would have. The PackageManagerTests will need to be
   5093          * revised when this is changed back..
   5094          */
   5095         if (userId == 0) {
   5096             return new File(mAppDataDir, packageName);
   5097         } else {
   5098             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
   5099                 + File.separator + packageName);
   5100         }
   5101     }
   5102 
   5103     private int createDataDirsLI(String packageName, int uid, String seinfo) {
   5104         int[] users = sUserManager.getUserIds();
   5105         int res = mInstaller.install(packageName, uid, uid, seinfo);
   5106         if (res < 0) {
   5107             return res;
   5108         }
   5109         for (int user : users) {
   5110             if (user != 0) {
   5111                 res = mInstaller.createUserData(packageName,
   5112                         UserHandle.getUid(user, uid), user, seinfo);
   5113                 if (res < 0) {
   5114                     return res;
   5115                 }
   5116             }
   5117         }
   5118         return res;
   5119     }
   5120 
   5121     private int removeDataDirsLI(String packageName) {
   5122         int[] users = sUserManager.getUserIds();
   5123         int res = 0;
   5124         for (int user : users) {
   5125             int resInner = mInstaller.remove(packageName, user);
   5126             if (resInner < 0) {
   5127                 res = resInner;
   5128             }
   5129         }
   5130 
   5131         return res;
   5132     }
   5133 
   5134     private int deleteCodeCacheDirsLI(String packageName) {
   5135         int[] users = sUserManager.getUserIds();
   5136         int res = 0;
   5137         for (int user : users) {
   5138             int resInner = mInstaller.deleteCodeCacheFiles(packageName, user);
   5139             if (resInner < 0) {
   5140                 res = resInner;
   5141             }
   5142         }
   5143         return res;
   5144     }
   5145 
   5146     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
   5147             PackageParser.Package changingLib) {
   5148         if (file.path != null) {
   5149             usesLibraryFiles.add(file.path);
   5150             return;
   5151         }
   5152         PackageParser.Package p = mPackages.get(file.apk);
   5153         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
   5154             // If we are doing this while in the middle of updating a library apk,
   5155             // then we need to make sure to use that new apk for determining the
   5156             // dependencies here.  (We haven't yet finished committing the new apk
   5157             // to the package manager state.)
   5158             if (p == null || p.packageName.equals(changingLib.packageName)) {
   5159                 p = changingLib;
   5160             }
   5161         }
   5162         if (p != null) {
   5163             usesLibraryFiles.addAll(p.getAllCodePaths());
   5164         }
   5165     }
   5166 
   5167     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
   5168             PackageParser.Package changingLib) throws PackageManagerException {
   5169         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
   5170             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
   5171             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
   5172             for (int i=0; i<N; i++) {
   5173                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
   5174                 if (file == null) {
   5175                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
   5176                             "Package " + pkg.packageName + " requires unavailable shared library "
   5177                             + pkg.usesLibraries.get(i) + "; failing!");
   5178                 }
   5179                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
   5180             }
   5181             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
   5182             for (int i=0; i<N; i++) {
   5183                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
   5184                 if (file == null) {
   5185                     Slog.w(TAG, "Package " + pkg.packageName
   5186                             + " desires unavailable shared library "
   5187                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
   5188                 } else {
   5189                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
   5190                 }
   5191             }
   5192             N = usesLibraryFiles.size();
   5193             if (N > 0) {
   5194                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
   5195             } else {
   5196                 pkg.usesLibraryFiles = null;
   5197             }
   5198         }
   5199     }
   5200 
   5201     private static boolean hasString(List<String> list, List<String> which) {
   5202         if (list == null) {
   5203             return false;
   5204         }
   5205         for (int i=list.size()-1; i>=0; i--) {
   5206             for (int j=which.size()-1; j>=0; j--) {
   5207                 if (which.get(j).equals(list.get(i))) {
   5208                     return true;
   5209                 }
   5210             }
   5211         }
   5212         return false;
   5213     }
   5214 
   5215     private void updateAllSharedLibrariesLPw() {
   5216         for (PackageParser.Package pkg : mPackages.values()) {
   5217             try {
   5218                 updateSharedLibrariesLPw(pkg, null);
   5219             } catch (PackageManagerException e) {
   5220                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
   5221             }
   5222         }
   5223     }
   5224 
   5225     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
   5226             PackageParser.Package changingPkg) {
   5227         ArrayList<PackageParser.Package> res = null;
   5228         for (PackageParser.Package pkg : mPackages.values()) {
   5229             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
   5230                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
   5231                 if (res == null) {
   5232                     res = new ArrayList<PackageParser.Package>();
   5233                 }
   5234                 res.add(pkg);
   5235                 try {
   5236                     updateSharedLibrariesLPw(pkg, changingPkg);
   5237                 } catch (PackageManagerException e) {
   5238                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
   5239                 }
   5240             }
   5241         }
   5242         return res;
   5243     }
   5244 
   5245     /**
   5246      * Derive the value of the {@code cpuAbiOverride} based on the provided
   5247      * value and an optional stored value from the package settings.
   5248      */
   5249     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
   5250         String cpuAbiOverride = null;
   5251 
   5252         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
   5253             cpuAbiOverride = null;
   5254         } else if (abiOverride != null) {
   5255             cpuAbiOverride = abiOverride;
   5256         } else if (settings != null) {
   5257             cpuAbiOverride = settings.cpuAbiOverrideString;
   5258         }
   5259 
   5260         return cpuAbiOverride;
   5261     }
   5262 
   5263     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
   5264             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
   5265         boolean success = false;
   5266         try {
   5267             final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
   5268                     currentTime, user);
   5269             success = true;
   5270             return res;
   5271         } finally {
   5272             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
   5273                 removeDataDirsLI(pkg.packageName);
   5274             }
   5275         }
   5276     }
   5277 
   5278     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
   5279             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
   5280         final File scanFile = new File(pkg.codePath);
   5281         if (pkg.applicationInfo.getCodePath() == null ||
   5282                 pkg.applicationInfo.getResourcePath() == null) {
   5283             // Bail out. The resource and code paths haven't been set.
   5284             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
   5285                     "Code and resource paths haven't been set correctly");
   5286         }
   5287 
   5288         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   5289             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
   5290         } else {
   5291             // Only allow system apps to be flagged as core apps.
   5292             pkg.coreApp = false;
   5293         }
   5294 
   5295         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
   5296             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
   5297         }
   5298 
   5299         if (mCustomResolverComponentName != null &&
   5300                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
   5301             setUpCustomResolverActivity(pkg);
   5302         }
   5303 
   5304         if (pkg.packageName.equals("android")) {
   5305             synchronized (mPackages) {
   5306                 if (mAndroidApplication != null) {
   5307                     Slog.w(TAG, "*************************************************");
   5308                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
   5309                     Slog.w(TAG, " file=" + scanFile);
   5310                     Slog.w(TAG, "*************************************************");
   5311                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
   5312                             "Core android package being redefined.  Skipping.");
   5313                 }
   5314 
   5315                 // Set up information for our fall-back user intent resolution activity.
   5316                 mPlatformPackage = pkg;
   5317                 pkg.mVersionCode = mSdkVersion;
   5318                 mAndroidApplication = pkg.applicationInfo;
   5319 
   5320                 if (!mResolverReplaced) {
   5321                     mResolveActivity.applicationInfo = mAndroidApplication;
   5322                     mResolveActivity.name = ResolverActivity.class.getName();
   5323                     mResolveActivity.packageName = mAndroidApplication.packageName;
   5324                     mResolveActivity.processName = "system:ui";
   5325                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   5326                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
   5327                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
   5328                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
   5329                     mResolveActivity.exported = true;
   5330                     mResolveActivity.enabled = true;
   5331                     mResolveInfo.activityInfo = mResolveActivity;
   5332                     mResolveInfo.priority = 0;
   5333                     mResolveInfo.preferredOrder = 0;
   5334                     mResolveInfo.match = 0;
   5335                     mResolveComponentName = new ComponentName(
   5336                             mAndroidApplication.packageName, mResolveActivity.name);
   5337                 }
   5338             }
   5339         }
   5340 
   5341         if (DEBUG_PACKAGE_SCANNING) {
   5342             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   5343                 Log.d(TAG, "Scanning package " + pkg.packageName);
   5344         }
   5345 
   5346         if (mPackages.containsKey(pkg.packageName)
   5347                 || mSharedLibraries.containsKey(pkg.packageName)) {
   5348             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
   5349                     "Application package " + pkg.packageName
   5350                     + " already installed.  Skipping duplicate.");
   5351         }
   5352 
   5353         // If we're only installing presumed-existing packages, require that the
   5354         // scanned APK is both already known and at the path previously established
   5355         // for it.  Previously unknown packages we pick up normally, but if we have an
   5356         // a priori expectation about this package's install presence, enforce it.
   5357         if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
   5358             PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
   5359             if (known != null) {
   5360                 if (DEBUG_PACKAGE_SCANNING) {
   5361                     Log.d(TAG, "Examining " + pkg.codePath
   5362                             + " and requiring known paths " + known.codePathString
   5363                             + " & " + known.resourcePathString);
   5364                 }
   5365                 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
   5366                         || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
   5367                     throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
   5368                             "Application package " + pkg.packageName
   5369                             + " found at " + pkg.applicationInfo.getCodePath()
   5370                             + " but expected at " + known.codePathString + "; ignoring.");
   5371                 }
   5372             }
   5373         }
   5374 
   5375         // Initialize package source and resource directories
   5376         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
   5377         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
   5378 
   5379         SharedUserSetting suid = null;
   5380         PackageSetting pkgSetting = null;
   5381 
   5382         if (!isSystemApp(pkg)) {
   5383             // Only system apps can use these features.
   5384             pkg.mOriginalPackages = null;
   5385             pkg.mRealPackage = null;
   5386             pkg.mAdoptPermissions = null;
   5387         }
   5388 
   5389         // writer
   5390         synchronized (mPackages) {
   5391             if (pkg.mSharedUserId != null) {
   5392                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
   5393                 if (suid == null) {
   5394                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
   5395                             "Creating application package " + pkg.packageName
   5396                             + " for shared user failed");
   5397                 }
   5398                 if (DEBUG_PACKAGE_SCANNING) {
   5399                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   5400                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
   5401                                 + "): packages=" + suid.packages);
   5402                 }
   5403             }
   5404 
   5405             // Check if we are renaming from an original package name.
   5406             PackageSetting origPackage = null;
   5407             String realName = null;
   5408             if (pkg.mOriginalPackages != null) {
   5409                 // This package may need to be renamed to a previously
   5410                 // installed name.  Let's check on that...
   5411                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
   5412                 if (pkg.mOriginalPackages.contains(renamed)) {
   5413                     // This package had originally been installed as the
   5414                     // original name, and we have already taken care of
   5415                     // transitioning to the new one.  Just update the new
   5416                     // one to continue using the old name.
   5417                     realName = pkg.mRealPackage;
   5418                     if (!pkg.packageName.equals(renamed)) {
   5419                         // Callers into this function may have already taken
   5420                         // care of renaming the package; only do it here if
   5421                         // it is not already done.
   5422                         pkg.setPackageName(renamed);
   5423                     }
   5424 
   5425                 } else {
   5426                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
   5427                         if ((origPackage = mSettings.peekPackageLPr(
   5428                                 pkg.mOriginalPackages.get(i))) != null) {
   5429                             // We do have the package already installed under its
   5430                             // original name...  should we use it?
   5431                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
   5432                                 // New package is not compatible with original.
   5433                                 origPackage = null;
   5434                                 continue;
   5435                             } else if (origPackage.sharedUser != null) {
   5436                                 // Make sure uid is compatible between packages.
   5437                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
   5438                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
   5439                                             + " to " + pkg.packageName + ": old uid "
   5440                                             + origPackage.sharedUser.name
   5441                                             + " differs from " + pkg.mSharedUserId);
   5442                                     origPackage = null;
   5443                                     continue;
   5444                                 }
   5445                             } else {
   5446                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
   5447                                         + pkg.packageName + " to old name " + origPackage.name);
   5448                             }
   5449                             break;
   5450                         }
   5451                     }
   5452                 }
   5453             }
   5454 
   5455             if (mTransferedPackages.contains(pkg.packageName)) {
   5456                 Slog.w(TAG, "Package " + pkg.packageName
   5457                         + " was transferred to another, but its .apk remains");
   5458             }
   5459 
   5460             // Just create the setting, don't add it yet. For already existing packages
   5461             // the PkgSetting exists already and doesn't have to be created.
   5462             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
   5463                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
   5464                     pkg.applicationInfo.primaryCpuAbi,
   5465                     pkg.applicationInfo.secondaryCpuAbi,
   5466                     pkg.applicationInfo.flags, user, false);
   5467             if (pkgSetting == null) {
   5468                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
   5469                         "Creating application package " + pkg.packageName + " failed");
   5470             }
   5471 
   5472             if (pkgSetting.origPackage != null) {
   5473                 // If we are first transitioning from an original package,
   5474                 // fix up the new package's name now.  We need to do this after
   5475                 // looking up the package under its new name, so getPackageLP
   5476                 // can take care of fiddling things correctly.
   5477                 pkg.setPackageName(origPackage.name);
   5478 
   5479                 // File a report about this.
   5480                 String msg = "New package " + pkgSetting.realName
   5481                         + " renamed to replace old package " + pkgSetting.name;
   5482                 reportSettingsProblem(Log.WARN, msg);
   5483 
   5484                 // Make a note of it.
   5485                 mTransferedPackages.add(origPackage.name);
   5486 
   5487                 // No longer need to retain this.
   5488                 pkgSetting.origPackage = null;
   5489             }
   5490 
   5491             if (realName != null) {
   5492                 // Make a note of it.
   5493                 mTransferedPackages.add(pkg.packageName);
   5494             }
   5495 
   5496             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
   5497                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   5498             }
   5499 
   5500             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   5501                 // Check all shared libraries and map to their actual file path.
   5502                 // We only do this here for apps not on a system dir, because those
   5503                 // are the only ones that can fail an install due to this.  We
   5504                 // will take care of the system apps by updating all of their
   5505                 // library paths after the scan is done.
   5506                 updateSharedLibrariesLPw(pkg, null);
   5507             }
   5508 
   5509             if (mFoundPolicyFile) {
   5510                 SELinuxMMAC.assignSeinfoValue(pkg);
   5511             }
   5512 
   5513             pkg.applicationInfo.uid = pkgSetting.appId;
   5514             pkg.mExtras = pkgSetting;
   5515             if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
   5516                 try {
   5517                     verifySignaturesLP(pkgSetting, pkg);
   5518                     // We just determined the app is signed correctly, so bring
   5519                     // over the latest parsed certs.
   5520                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   5521                 } catch (PackageManagerException e) {
   5522                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   5523                         throw e;
   5524                     }
   5525                     // The signature has changed, but this package is in the system
   5526                     // image...  let's recover!
   5527                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   5528                     // However...  if this package is part of a shared user, but it
   5529                     // doesn't match the signature of the shared user, let's fail.
   5530                     // What this means is that you can't change the signatures
   5531                     // associated with an overall shared user, which doesn't seem all
   5532                     // that unreasonable.
   5533                     if (pkgSetting.sharedUser != null) {
   5534                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   5535                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   5536                             throw new PackageManagerException(
   5537                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
   5538                                             "Signature mismatch for shared user : "
   5539                                             + pkgSetting.sharedUser);
   5540                         }
   5541                     }
   5542                     // File a report about this.
   5543                     String msg = "System package " + pkg.packageName
   5544                         + " signature changed; retaining data.";
   5545                     reportSettingsProblem(Log.WARN, msg);
   5546                 }
   5547             } else {
   5548                 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
   5549                     throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
   5550                             + pkg.packageName + " upgrade keys do not match the "
   5551                             + "previously installed version");
   5552                 } else {
   5553                     // We just determined the app is signed correctly, so bring
   5554                     // over the latest parsed certs.
   5555                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   5556                 }
   5557             }
   5558             // Verify that this new package doesn't have any content providers
   5559             // that conflict with existing packages.  Only do this if the
   5560             // package isn't already installed, since we don't want to break
   5561             // things that are installed.
   5562             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
   5563                 final int N = pkg.providers.size();
   5564                 int i;
   5565                 for (i=0; i<N; i++) {
   5566                     PackageParser.Provider p = pkg.providers.get(i);
   5567                     if (p.info.authority != null) {
   5568                         String names[] = p.info.authority.split(";");
   5569                         for (int j = 0; j < names.length; j++) {
   5570                             if (mProvidersByAuthority.containsKey(names[j])) {
   5571                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
   5572                                 final String otherPackageName =
   5573                                         ((other != null && other.getComponentName() != null) ?
   5574                                                 other.getComponentName().getPackageName() : "?");
   5575                                 throw new PackageManagerException(
   5576                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
   5577                                                 "Can't install because provider name " + names[j]
   5578                                                 + " (in package " + pkg.applicationInfo.packageName
   5579                                                 + ") is already used by " + otherPackageName);
   5580                             }
   5581                         }
   5582                     }
   5583                 }
   5584             }
   5585 
   5586             if (pkg.mAdoptPermissions != null) {
   5587                 // This package wants to adopt ownership of permissions from
   5588                 // another package.
   5589                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
   5590                     final String origName = pkg.mAdoptPermissions.get(i);
   5591                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
   5592                     if (orig != null) {
   5593                         if (verifyPackageUpdateLPr(orig, pkg)) {
   5594                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
   5595                                     + pkg.packageName);
   5596                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
   5597                         }
   5598                     }
   5599                 }
   5600             }
   5601         }
   5602 
   5603         final String pkgName = pkg.packageName;
   5604 
   5605         final long scanFileTime = scanFile.lastModified();
   5606         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
   5607         pkg.applicationInfo.processName = fixProcessName(
   5608                 pkg.applicationInfo.packageName,
   5609                 pkg.applicationInfo.processName,
   5610                 pkg.applicationInfo.uid);
   5611 
   5612         File dataPath;
   5613         if (mPlatformPackage == pkg) {
   5614             // The system package is special.
   5615             dataPath = new File(Environment.getDataDirectory(), "system");
   5616 
   5617             pkg.applicationInfo.dataDir = dataPath.getPath();
   5618 
   5619         } else {
   5620             // This is a normal package, need to make its data directory.
   5621             dataPath = getDataPathForPackage(pkg.packageName, 0);
   5622 
   5623             boolean uidError = false;
   5624             if (dataPath.exists()) {
   5625                 int currentUid = 0;
   5626                 try {
   5627                     StructStat stat = Os.stat(dataPath.getPath());
   5628                     currentUid = stat.st_uid;
   5629                 } catch (ErrnoException e) {
   5630                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
   5631                 }
   5632 
   5633                 // If we have mismatched owners for the data path, we have a problem.
   5634                 if (currentUid != pkg.applicationInfo.uid) {
   5635                     boolean recovered = false;
   5636                     if (currentUid == 0) {
   5637                         // The directory somehow became owned by root.  Wow.
   5638                         // This is probably because the system was stopped while
   5639                         // installd was in the middle of messing with its libs
   5640                         // directory.  Ask installd to fix that.
   5641                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
   5642                                 pkg.applicationInfo.uid);
   5643                         if (ret >= 0) {
   5644                             recovered = true;
   5645                             String msg = "Package " + pkg.packageName
   5646                                     + " unexpectedly changed to uid 0; recovered to " +
   5647                                     + pkg.applicationInfo.uid;
   5648                             reportSettingsProblem(Log.WARN, msg);
   5649                         }
   5650                     }
   5651                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
   5652                             || (scanFlags&SCAN_BOOTING) != 0)) {
   5653                         // If this is a system app, we can at least delete its
   5654                         // current data so the application will still work.
   5655                         int ret = removeDataDirsLI(pkgName);
   5656                         if (ret >= 0) {
   5657                             // TODO: Kill the processes first
   5658                             // Old data gone!
   5659                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
   5660                                     ? "System package " : "Third party package ";
   5661                             String msg = prefix + pkg.packageName
   5662                                     + " has changed from uid: "
   5663                                     + currentUid + " to "
   5664                                     + pkg.applicationInfo.uid + "; old data erased";
   5665                             reportSettingsProblem(Log.WARN, msg);
   5666                             recovered = true;
   5667 
   5668                             // And now re-install the app.
   5669                             ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
   5670                                                    pkg.applicationInfo.seinfo);
   5671                             if (ret == -1) {
   5672                                 // Ack should not happen!
   5673                                 msg = prefix + pkg.packageName
   5674                                         + " could not have data directory re-created after delete.";
   5675                                 reportSettingsProblem(Log.WARN, msg);
   5676                                 throw new PackageManagerException(
   5677                                         INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
   5678                             }
   5679                         }
   5680                         if (!recovered) {
   5681                             mHasSystemUidErrors = true;
   5682                         }
   5683                     } else if (!recovered) {
   5684                         // If we allow this install to proceed, we will be broken.
   5685                         // Abort, abort!
   5686                         throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
   5687                                 "scanPackageLI");
   5688                     }
   5689                     if (!recovered) {
   5690                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
   5691                             + pkg.applicationInfo.uid + "/fs_"
   5692                             + currentUid;
   5693                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
   5694                         pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
   5695                         String msg = "Package " + pkg.packageName
   5696                                 + " has mismatched uid: "
   5697                                 + currentUid + " on disk, "
   5698                                 + pkg.applicationInfo.uid + " in settings";
   5699                         // writer
   5700                         synchronized (mPackages) {
   5701                             mSettings.mReadMessages.append(msg);
   5702                             mSettings.mReadMessages.append('\n');
   5703                             uidError = true;
   5704                             if (!pkgSetting.uidError) {
   5705                                 reportSettingsProblem(Log.ERROR, msg);
   5706                             }
   5707                         }
   5708                     }
   5709                 }
   5710                 pkg.applicationInfo.dataDir = dataPath.getPath();
   5711                 if (mShouldRestoreconData) {
   5712                     Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
   5713                     mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
   5714                                 pkg.applicationInfo.uid);
   5715                 }
   5716             } else {
   5717                 if (DEBUG_PACKAGE_SCANNING) {
   5718                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   5719                         Log.v(TAG, "Want this data dir: " + dataPath);
   5720                 }
   5721                 //invoke installer to do the actual installation
   5722                 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
   5723                                            pkg.applicationInfo.seinfo);
   5724                 if (ret < 0) {
   5725                     // Error from installer
   5726                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
   5727                             "Unable to create data dirs [errorCode=" + ret + "]");
   5728                 }
   5729 
   5730                 if (dataPath.exists()) {
   5731                     pkg.applicationInfo.dataDir = dataPath.getPath();
   5732                 } else {
   5733                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
   5734                     pkg.applicationInfo.dataDir = null;
   5735                 }
   5736             }
   5737 
   5738             pkgSetting.uidError = uidError;
   5739         }
   5740 
   5741         final String path = scanFile.getPath();
   5742         final String codePath = pkg.applicationInfo.getCodePath();
   5743         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
   5744         if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
   5745             setBundledAppAbisAndRoots(pkg, pkgSetting);
   5746 
   5747             // If we haven't found any native libraries for the app, check if it has
   5748             // renderscript code. We'll need to force the app to 32 bit if it has
   5749             // renderscript bitcode.
   5750             if (pkg.applicationInfo.primaryCpuAbi == null
   5751                     && pkg.applicationInfo.secondaryCpuAbi == null
   5752                     && Build.SUPPORTED_64_BIT_ABIS.length >  0) {
   5753                 NativeLibraryHelper.Handle handle = null;
   5754                 try {
   5755                     handle = NativeLibraryHelper.Handle.create(scanFile);
   5756                     if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
   5757                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   5758                     }
   5759                 } catch (IOException ioe) {
   5760                     Slog.w(TAG, "Error scanning system app : " + ioe);
   5761                 } finally {
   5762                     IoUtils.closeQuietly(handle);
   5763                 }
   5764             }
   5765 
   5766             setNativeLibraryPaths(pkg);
   5767         } else {
   5768             // TODO: We can probably be smarter about this stuff. For installed apps,
   5769             // we can calculate this information at install time once and for all. For
   5770             // system apps, we can probably assume that this information doesn't change
   5771             // after the first boot scan. As things stand, we do lots of unnecessary work.
   5772 
   5773             // Give ourselves some initial paths; we'll come back for another
   5774             // pass once we've determined ABI below.
   5775             setNativeLibraryPaths(pkg);
   5776 
   5777             final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg);
   5778             final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
   5779             final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
   5780 
   5781             NativeLibraryHelper.Handle handle = null;
   5782             try {
   5783                 handle = NativeLibraryHelper.Handle.create(scanFile);
   5784                 // TODO(multiArch): This can be null for apps that didn't go through the
   5785                 // usual installation process. We can calculate it again, like we
   5786                 // do during install time.
   5787                 //
   5788                 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
   5789                 // unnecessary.
   5790                 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
   5791 
   5792                 // Null out the abis so that they can be recalculated.
   5793                 pkg.applicationInfo.primaryCpuAbi = null;
   5794                 pkg.applicationInfo.secondaryCpuAbi = null;
   5795                 if (isMultiArch(pkg.applicationInfo)) {
   5796                     // Warn if we've set an abiOverride for multi-lib packages..
   5797                     // By definition, we need to copy both 32 and 64 bit libraries for
   5798                     // such packages.
   5799                     if (pkg.cpuAbiOverride != null
   5800                             && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
   5801                         Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
   5802                     }
   5803 
   5804                     int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
   5805                     int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
   5806                     if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
   5807                         if (isAsec) {
   5808                             abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
   5809                         } else {
   5810                             abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   5811                                     nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
   5812                                     useIsaSpecificSubdirs);
   5813                         }
   5814                     }
   5815 
   5816                     maybeThrowExceptionForMultiArchCopy(
   5817                             "Error unpackaging 32 bit native libs for multiarch app.", abi32);
   5818 
   5819                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
   5820                         if (isAsec) {
   5821                             abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
   5822                         } else {
   5823                             abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   5824                                     nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
   5825                                     useIsaSpecificSubdirs);
   5826                         }
   5827                     }
   5828 
   5829                     maybeThrowExceptionForMultiArchCopy(
   5830                             "Error unpackaging 64 bit native libs for multiarch app.", abi64);
   5831 
   5832                     if (abi64 >= 0) {
   5833                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
   5834                     }
   5835 
   5836                     if (abi32 >= 0) {
   5837                         final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
   5838                         if (abi64 >= 0) {
   5839                             pkg.applicationInfo.secondaryCpuAbi = abi;
   5840                         } else {
   5841                             pkg.applicationInfo.primaryCpuAbi = abi;
   5842                         }
   5843                     }
   5844                 } else {
   5845                     String[] abiList = (cpuAbiOverride != null) ?
   5846                             new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
   5847 
   5848                     // Enable gross and lame hacks for apps that are built with old
   5849                     // SDK tools. We must scan their APKs for renderscript bitcode and
   5850                     // not launch them if it's present. Don't bother checking on devices
   5851                     // that don't have 64 bit support.
   5852                     boolean needsRenderScriptOverride = false;
   5853                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
   5854                             NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
   5855                         abiList = Build.SUPPORTED_32_BIT_ABIS;
   5856                         needsRenderScriptOverride = true;
   5857                     }
   5858 
   5859                     final int copyRet;
   5860                     if (isAsec) {
   5861                         copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
   5862                     } else {
   5863                         copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   5864                                 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
   5865                     }
   5866 
   5867                     if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
   5868                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
   5869                                 "Error unpackaging native libs for app, errorCode=" + copyRet);
   5870                     }
   5871 
   5872                     if (copyRet >= 0) {
   5873                         pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
   5874                     } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
   5875                         pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
   5876                     } else if (needsRenderScriptOverride) {
   5877                         pkg.applicationInfo.primaryCpuAbi = abiList[0];
   5878                     }
   5879                 }
   5880             } catch (IOException ioe) {
   5881                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
   5882             } finally {
   5883                 IoUtils.closeQuietly(handle);
   5884             }
   5885 
   5886             // Now that we've calculated the ABIs and determined if it's an internal app,
   5887             // we will go ahead and populate the nativeLibraryPath.
   5888             setNativeLibraryPaths(pkg);
   5889 
   5890             if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
   5891             final int[] userIds = sUserManager.getUserIds();
   5892             synchronized (mInstallLock) {
   5893                 // Create a native library symlink only if we have native libraries
   5894                 // and if the native libraries are 32 bit libraries. We do not provide
   5895                 // this symlink for 64 bit libraries.
   5896                 if (pkg.applicationInfo.primaryCpuAbi != null &&
   5897                         !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
   5898                     final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
   5899                     for (int userId : userIds) {
   5900                         if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
   5901                             throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
   5902                                     "Failed linking native library dir (user=" + userId + ")");
   5903                         }
   5904                     }
   5905                 }
   5906             }
   5907         }
   5908 
   5909         // This is a special case for the "system" package, where the ABI is
   5910         // dictated by the zygote configuration (and init.rc). We should keep track
   5911         // of this ABI so that we can deal with "normal" applications that run under
   5912         // the same UID correctly.
   5913         if (mPlatformPackage == pkg) {
   5914             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
   5915                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
   5916         }
   5917 
   5918         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
   5919         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
   5920         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
   5921         // Copy the derived override back to the parsed package, so that we can
   5922         // update the package settings accordingly.
   5923         pkg.cpuAbiOverride = cpuAbiOverride;
   5924 
   5925         if (DEBUG_ABI_SELECTION) {
   5926             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
   5927                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
   5928                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
   5929         }
   5930 
   5931         // Push the derived path down into PackageSettings so we know what to
   5932         // clean up at uninstall time.
   5933         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
   5934 
   5935         if (DEBUG_ABI_SELECTION) {
   5936             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
   5937                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
   5938                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
   5939         }
   5940 
   5941         if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
   5942             // We don't do this here during boot because we can do it all
   5943             // at once after scanning all existing packages.
   5944             //
   5945             // We also do this *before* we perform dexopt on this package, so that
   5946             // we can avoid redundant dexopts, and also to make sure we've got the
   5947             // code and package path correct.
   5948             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
   5949                     pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
   5950         }
   5951 
   5952         if ((scanFlags & SCAN_NO_DEX) == 0) {
   5953             if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
   5954                     (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
   5955                 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
   5956             }
   5957         }
   5958 
   5959         if (mFactoryTest && pkg.requestedPermissions.contains(
   5960                 android.Manifest.permission.FACTORY_TEST)) {
   5961             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
   5962         }
   5963 
   5964         ArrayList<PackageParser.Package> clientLibPkgs = null;
   5965 
   5966         // writer
   5967         synchronized (mPackages) {
   5968             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   5969                 // Only system apps can add new shared libraries.
   5970                 if (pkg.libraryNames != null) {
   5971                     for (int i=0; i<pkg.libraryNames.size(); i++) {
   5972                         String name = pkg.libraryNames.get(i);
   5973                         boolean allowed = false;
   5974                         if (isUpdatedSystemApp(pkg)) {
   5975                             // New library entries can only be added through the
   5976                             // system image.  This is important to get rid of a lot
   5977                             // of nasty edge cases: for example if we allowed a non-
   5978                             // system update of the app to add a library, then uninstalling
   5979                             // the update would make the library go away, and assumptions
   5980                             // we made such as through app install filtering would now
   5981                             // have allowed apps on the device which aren't compatible
   5982                             // with it.  Better to just have the restriction here, be
   5983                             // conservative, and create many fewer cases that can negatively
   5984                             // impact the user experience.
   5985                             final PackageSetting sysPs = mSettings
   5986                                     .getDisabledSystemPkgLPr(pkg.packageName);
   5987                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
   5988                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
   5989                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
   5990                                         allowed = true;
   5991                                         allowed = true;
   5992                                         break;
   5993                                     }
   5994                                 }
   5995                             }
   5996                         } else {
   5997                             allowed = true;
   5998                         }
   5999                         if (allowed) {
   6000                             if (!mSharedLibraries.containsKey(name)) {
   6001                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
   6002                             } else if (!name.equals(pkg.packageName)) {
   6003                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
   6004                                         + name + " already exists; skipping");
   6005                             }
   6006                         } else {
   6007                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
   6008                                     + name + " that is not declared on system image; skipping");
   6009                         }
   6010                     }
   6011                     if ((scanFlags&SCAN_BOOTING) == 0) {
   6012                         // If we are not booting, we need to update any applications
   6013                         // that are clients of our shared library.  If we are booting,
   6014                         // this will all be done once the scan is complete.
   6015                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
   6016                     }
   6017                 }
   6018             }
   6019         }
   6020 
   6021         // We also need to dexopt any apps that are dependent on this library.  Note that
   6022         // if these fail, we should abort the install since installing the library will
   6023         // result in some apps being broken.
   6024         if (clientLibPkgs != null) {
   6025             if ((scanFlags & SCAN_NO_DEX) == 0) {
   6026                 for (int i = 0; i < clientLibPkgs.size(); i++) {
   6027                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
   6028                     if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
   6029                             (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
   6030                         throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
   6031                                 "scanPackageLI failed to dexopt clientLibPkgs");
   6032                     }
   6033                 }
   6034             }
   6035         }
   6036 
   6037         // Request the ActivityManager to kill the process(only for existing packages)
   6038         // so that we do not end up in a confused state while the user is still using the older
   6039         // version of the application while the new one gets installed.
   6040         if ((scanFlags & SCAN_REPLACING) != 0) {
   6041             killApplication(pkg.applicationInfo.packageName,
   6042                         pkg.applicationInfo.uid, "update pkg");
   6043         }
   6044 
   6045         // Also need to kill any apps that are dependent on the library.
   6046         if (clientLibPkgs != null) {
   6047             for (int i=0; i<clientLibPkgs.size(); i++) {
   6048                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
   6049                 killApplication(clientPkg.applicationInfo.packageName,
   6050                         clientPkg.applicationInfo.uid, "update lib");
   6051             }
   6052         }
   6053 
   6054         // writer
   6055         synchronized (mPackages) {
   6056             // We don't expect installation to fail beyond this point
   6057 
   6058             // Add the new setting to mSettings
   6059             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
   6060             // Add the new setting to mPackages
   6061             mPackages.put(pkg.applicationInfo.packageName, pkg);
   6062             // Make sure we don't accidentally delete its data.
   6063             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
   6064             while (iter.hasNext()) {
   6065                 PackageCleanItem item = iter.next();
   6066                 if (pkgName.equals(item.packageName)) {
   6067                     iter.remove();
   6068                 }
   6069             }
   6070 
   6071             // Take care of first install / last update times.
   6072             if (currentTime != 0) {
   6073                 if (pkgSetting.firstInstallTime == 0) {
   6074                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
   6075                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
   6076                     pkgSetting.lastUpdateTime = currentTime;
   6077                 }
   6078             } else if (pkgSetting.firstInstallTime == 0) {
   6079                 // We need *something*.  Take time time stamp of the file.
   6080                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
   6081             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
   6082                 if (scanFileTime != pkgSetting.timeStamp) {
   6083                     // A package on the system image has changed; consider this
   6084                     // to be an update.
   6085                     pkgSetting.lastUpdateTime = scanFileTime;
   6086                 }
   6087             }
   6088 
   6089             // Add the package's KeySets to the global KeySetManagerService
   6090             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   6091             try {
   6092                 // Old KeySetData no longer valid.
   6093                 ksms.removeAppKeySetDataLPw(pkg.packageName);
   6094                 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
   6095                 if (pkg.mKeySetMapping != null) {
   6096                     for (Map.Entry<String, ArraySet<PublicKey>> entry :
   6097                             pkg.mKeySetMapping.entrySet()) {
   6098                         if (entry.getValue() != null) {
   6099                             ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
   6100                                                           entry.getValue(), entry.getKey());
   6101                         }
   6102                     }
   6103                     if (pkg.mUpgradeKeySets != null) {
   6104                         for (String upgradeAlias : pkg.mUpgradeKeySets) {
   6105                             ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
   6106                         }
   6107                     }
   6108                 }
   6109             } catch (NullPointerException e) {
   6110                 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
   6111             } catch (IllegalArgumentException e) {
   6112                 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
   6113             }
   6114 
   6115             int N = pkg.providers.size();
   6116             StringBuilder r = null;
   6117             int i;
   6118             for (i=0; i<N; i++) {
   6119                 PackageParser.Provider p = pkg.providers.get(i);
   6120                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
   6121                         p.info.processName, pkg.applicationInfo.uid);
   6122                 mProviders.addProvider(p);
   6123                 p.syncable = p.info.isSyncable;
   6124                 if (p.info.authority != null) {
   6125                     String names[] = p.info.authority.split(";");
   6126                     p.info.authority = null;
   6127                     for (int j = 0; j < names.length; j++) {
   6128                         if (j == 1 && p.syncable) {
   6129                             // We only want the first authority for a provider to possibly be
   6130                             // syncable, so if we already added this provider using a different
   6131                             // authority clear the syncable flag. We copy the provider before
   6132                             // changing it because the mProviders object contains a reference
   6133                             // to a provider that we don't want to change.
   6134                             // Only do this for the second authority since the resulting provider
   6135                             // object can be the same for all future authorities for this provider.
   6136                             p = new PackageParser.Provider(p);
   6137                             p.syncable = false;
   6138                         }
   6139                         if (!mProvidersByAuthority.containsKey(names[j])) {
   6140                             mProvidersByAuthority.put(names[j], p);
   6141                             if (p.info.authority == null) {
   6142                                 p.info.authority = names[j];
   6143                             } else {
   6144                                 p.info.authority = p.info.authority + ";" + names[j];
   6145                             }
   6146                             if (DEBUG_PACKAGE_SCANNING) {
   6147                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   6148                                     Log.d(TAG, "Registered content provider: " + names[j]
   6149                                             + ", className = " + p.info.name + ", isSyncable = "
   6150                                             + p.info.isSyncable);
   6151                             }
   6152                         } else {
   6153                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
   6154                             Slog.w(TAG, "Skipping provider name " + names[j] +
   6155                                     " (in package " + pkg.applicationInfo.packageName +
   6156                                     "): name already used by "
   6157                                     + ((other != null && other.getComponentName() != null)
   6158                                             ? other.getComponentName().getPackageName() : "?"));
   6159                         }
   6160                     }
   6161                 }
   6162                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6163                     if (r == null) {
   6164                         r = new StringBuilder(256);
   6165                     } else {
   6166                         r.append(' ');
   6167                     }
   6168                     r.append(p.info.name);
   6169                 }
   6170             }
   6171             if (r != null) {
   6172                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
   6173             }
   6174 
   6175             N = pkg.services.size();
   6176             r = null;
   6177             for (i=0; i<N; i++) {
   6178                 PackageParser.Service s = pkg.services.get(i);
   6179                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
   6180                         s.info.processName, pkg.applicationInfo.uid);
   6181                 mServices.addService(s);
   6182                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6183                     if (r == null) {
   6184                         r = new StringBuilder(256);
   6185                     } else {
   6186                         r.append(' ');
   6187                     }
   6188                     r.append(s.info.name);
   6189                 }
   6190             }
   6191             if (r != null) {
   6192                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
   6193             }
   6194 
   6195             N = pkg.receivers.size();
   6196             r = null;
   6197             for (i=0; i<N; i++) {
   6198                 PackageParser.Activity a = pkg.receivers.get(i);
   6199                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   6200                         a.info.processName, pkg.applicationInfo.uid);
   6201                 mReceivers.addActivity(a, "receiver");
   6202                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6203                     if (r == null) {
   6204                         r = new StringBuilder(256);
   6205                     } else {
   6206                         r.append(' ');
   6207                     }
   6208                     r.append(a.info.name);
   6209                 }
   6210             }
   6211             if (r != null) {
   6212                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
   6213             }
   6214 
   6215             N = pkg.activities.size();
   6216             r = null;
   6217             for (i=0; i<N; i++) {
   6218                 PackageParser.Activity a = pkg.activities.get(i);
   6219                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   6220                         a.info.processName, pkg.applicationInfo.uid);
   6221                 mActivities.addActivity(a, "activity");
   6222                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6223                     if (r == null) {
   6224                         r = new StringBuilder(256);
   6225                     } else {
   6226                         r.append(' ');
   6227                     }
   6228                     r.append(a.info.name);
   6229                 }
   6230             }
   6231             if (r != null) {
   6232                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
   6233             }
   6234 
   6235             N = pkg.permissionGroups.size();
   6236             r = null;
   6237             for (i=0; i<N; i++) {
   6238                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
   6239                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
   6240                 if (cur == null) {
   6241                     mPermissionGroups.put(pg.info.name, pg);
   6242                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6243                         if (r == null) {
   6244                             r = new StringBuilder(256);
   6245                         } else {
   6246                             r.append(' ');
   6247                         }
   6248                         r.append(pg.info.name);
   6249                     }
   6250                 } else {
   6251                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
   6252                             + pg.info.packageName + " ignored: original from "
   6253                             + cur.info.packageName);
   6254                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6255                         if (r == null) {
   6256                             r = new StringBuilder(256);
   6257                         } else {
   6258                             r.append(' ');
   6259                         }
   6260                         r.append("DUP:");
   6261                         r.append(pg.info.name);
   6262                     }
   6263                 }
   6264             }
   6265             if (r != null) {
   6266                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
   6267             }
   6268 
   6269             N = pkg.permissions.size();
   6270             r = null;
   6271             for (i=0; i<N; i++) {
   6272                 PackageParser.Permission p = pkg.permissions.get(i);
   6273                 ArrayMap<String, BasePermission> permissionMap =
   6274                         p.tree ? mSettings.mPermissionTrees
   6275                         : mSettings.mPermissions;
   6276                 p.group = mPermissionGroups.get(p.info.group);
   6277                 if (p.info.group == null || p.group != null) {
   6278                     BasePermission bp = permissionMap.get(p.info.name);
   6279 
   6280                     // Allow system apps to redefine non-system permissions
   6281                     if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
   6282                         final boolean currentOwnerIsSystem = (bp.perm != null
   6283                                 && isSystemApp(bp.perm.owner));
   6284                         if (isSystemApp(p.owner)) {
   6285                             if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
   6286                                 // It's a built-in permission and no owner, take ownership now
   6287                                 bp.packageSetting = pkgSetting;
   6288                                 bp.perm = p;
   6289                                 bp.uid = pkg.applicationInfo.uid;
   6290                                 bp.sourcePackage = p.info.packageName;
   6291                             } else if (!currentOwnerIsSystem) {
   6292                                 String msg = "New decl " + p.owner + " of permission  "
   6293                                         + p.info.name + " is system; overriding " + bp.sourcePackage;
   6294                                 reportSettingsProblem(Log.WARN, msg);
   6295                                 bp = null;
   6296                             }
   6297                         }
   6298                     }
   6299 
   6300                     if (bp == null) {
   6301                         bp = new BasePermission(p.info.name, p.info.packageName,
   6302                                 BasePermission.TYPE_NORMAL);
   6303                         permissionMap.put(p.info.name, bp);
   6304                     }
   6305 
   6306                     if (bp.perm == null) {
   6307                         if (bp.sourcePackage == null
   6308                                 || bp.sourcePackage.equals(p.info.packageName)) {
   6309                             BasePermission tree = findPermissionTreeLP(p.info.name);
   6310                             if (tree == null
   6311                                     || tree.sourcePackage.equals(p.info.packageName)) {
   6312                                 bp.packageSetting = pkgSetting;
   6313                                 bp.perm = p;
   6314                                 bp.uid = pkg.applicationInfo.uid;
   6315                                 bp.sourcePackage = p.info.packageName;
   6316                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6317                                     if (r == null) {
   6318                                         r = new StringBuilder(256);
   6319                                     } else {
   6320                                         r.append(' ');
   6321                                     }
   6322                                     r.append(p.info.name);
   6323                                 }
   6324                             } else {
   6325                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
   6326                                         + p.info.packageName + " ignored: base tree "
   6327                                         + tree.name + " is from package "
   6328                                         + tree.sourcePackage);
   6329                             }
   6330                         } else {
   6331                             Slog.w(TAG, "Permission " + p.info.name + " from package "
   6332                                     + p.info.packageName + " ignored: original from "
   6333                                     + bp.sourcePackage);
   6334                         }
   6335                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6336                         if (r == null) {
   6337                             r = new StringBuilder(256);
   6338                         } else {
   6339                             r.append(' ');
   6340                         }
   6341                         r.append("DUP:");
   6342                         r.append(p.info.name);
   6343                     }
   6344                     if (bp.perm == p) {
   6345                         bp.protectionLevel = p.info.protectionLevel;
   6346                     }
   6347                 } else {
   6348                     Slog.w(TAG, "Permission " + p.info.name + " from package "
   6349                             + p.info.packageName + " ignored: no group "
   6350                             + p.group);
   6351                 }
   6352             }
   6353             if (r != null) {
   6354                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
   6355             }
   6356 
   6357             N = pkg.instrumentation.size();
   6358             r = null;
   6359             for (i=0; i<N; i++) {
   6360                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   6361                 a.info.packageName = pkg.applicationInfo.packageName;
   6362                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
   6363                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
   6364                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
   6365                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
   6366                 a.info.dataDir = pkg.applicationInfo.dataDir;
   6367 
   6368                 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
   6369                 // need other information about the application, like the ABI and what not ?
   6370                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
   6371                 mInstrumentation.put(a.getComponentName(), a);
   6372                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6373                     if (r == null) {
   6374                         r = new StringBuilder(256);
   6375                     } else {
   6376                         r.append(' ');
   6377                     }
   6378                     r.append(a.info.name);
   6379                 }
   6380             }
   6381             if (r != null) {
   6382                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
   6383             }
   6384 
   6385             if (pkg.protectedBroadcasts != null) {
   6386                 N = pkg.protectedBroadcasts.size();
   6387                 for (i=0; i<N; i++) {
   6388                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
   6389                 }
   6390             }
   6391 
   6392             pkgSetting.setTimeStamp(scanFileTime);
   6393 
   6394             // Create idmap files for pairs of (packages, overlay packages).
   6395             // Note: "android", ie framework-res.apk, is handled by native layers.
   6396             if (pkg.mOverlayTarget != null) {
   6397                 // This is an overlay package.
   6398                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
   6399                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
   6400                         mOverlays.put(pkg.mOverlayTarget,
   6401                                 new ArrayMap<String, PackageParser.Package>());
   6402                     }
   6403                     ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
   6404                     map.put(pkg.packageName, pkg);
   6405                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
   6406                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
   6407                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
   6408                                 "scanPackageLI failed to createIdmap");
   6409                     }
   6410                 }
   6411             } else if (mOverlays.containsKey(pkg.packageName) &&
   6412                     !pkg.packageName.equals("android")) {
   6413                 // This is a regular package, with one or more known overlay packages.
   6414                 createIdmapsForPackageLI(pkg);
   6415             }
   6416         }
   6417 
   6418         return pkg;
   6419     }
   6420 
   6421     /**
   6422      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
   6423      * i.e, so that all packages can be run inside a single process if required.
   6424      *
   6425      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
   6426      * this function will either try and make the ABI for all packages in {@code packagesForUser}
   6427      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
   6428      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
   6429      * updating a package that belongs to a shared user.
   6430      *
   6431      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
   6432      * adds unnecessary complexity.
   6433      */
   6434     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
   6435             PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
   6436         String requiredInstructionSet = null;
   6437         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
   6438             requiredInstructionSet = VMRuntime.getInstructionSet(
   6439                      scannedPackage.applicationInfo.primaryCpuAbi);
   6440         }
   6441 
   6442         PackageSetting requirer = null;
   6443         for (PackageSetting ps : packagesForUser) {
   6444             // If packagesForUser contains scannedPackage, we skip it. This will happen
   6445             // when scannedPackage is an update of an existing package. Without this check,
   6446             // we will never be able to change the ABI of any package belonging to a shared
   6447             // user, even if it's compatible with other packages.
   6448             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
   6449                 if (ps.primaryCpuAbiString == null) {
   6450                     continue;
   6451                 }
   6452 
   6453                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
   6454                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
   6455                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
   6456                     // this but there's not much we can do.
   6457                     String errorMessage = "Instruction set mismatch, "
   6458                             + ((requirer == null) ? "[caller]" : requirer)
   6459                             + " requires " + requiredInstructionSet + " whereas " + ps
   6460                             + " requires " + instructionSet;
   6461                     Slog.w(TAG, errorMessage);
   6462                 }
   6463 
   6464                 if (requiredInstructionSet == null) {
   6465                     requiredInstructionSet = instructionSet;
   6466                     requirer = ps;
   6467                 }
   6468             }
   6469         }
   6470 
   6471         if (requiredInstructionSet != null) {
   6472             String adjustedAbi;
   6473             if (requirer != null) {
   6474                 // requirer != null implies that either scannedPackage was null or that scannedPackage
   6475                 // did not require an ABI, in which case we have to adjust scannedPackage to match
   6476                 // the ABI of the set (which is the same as requirer's ABI)
   6477                 adjustedAbi = requirer.primaryCpuAbiString;
   6478                 if (scannedPackage != null) {
   6479                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
   6480                 }
   6481             } else {
   6482                 // requirer == null implies that we're updating all ABIs in the set to
   6483                 // match scannedPackage.
   6484                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
   6485             }
   6486 
   6487             for (PackageSetting ps : packagesForUser) {
   6488                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
   6489                     if (ps.primaryCpuAbiString != null) {
   6490                         continue;
   6491                     }
   6492 
   6493                     ps.primaryCpuAbiString = adjustedAbi;
   6494                     if (ps.pkg != null && ps.pkg.applicationInfo != null) {
   6495                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
   6496                         Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
   6497 
   6498                         if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt,
   6499                                 deferDexOpt, true) == DEX_OPT_FAILED) {
   6500                             ps.primaryCpuAbiString = null;
   6501                             ps.pkg.applicationInfo.primaryCpuAbi = null;
   6502                             return;
   6503                         } else {
   6504                             mInstaller.rmdex(ps.codePathString,
   6505                                              getDexCodeInstructionSet(getPreferredInstructionSet()));
   6506                         }
   6507                     }
   6508                 }
   6509             }
   6510         }
   6511     }
   6512 
   6513     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
   6514         synchronized (mPackages) {
   6515             mResolverReplaced = true;
   6516             // Set up information for custom user intent resolution activity.
   6517             mResolveActivity.applicationInfo = pkg.applicationInfo;
   6518             mResolveActivity.name = mCustomResolverComponentName.getClassName();
   6519             mResolveActivity.packageName = pkg.applicationInfo.packageName;
   6520             mResolveActivity.processName = pkg.applicationInfo.packageName;
   6521             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   6522             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
   6523                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
   6524             mResolveActivity.theme = 0;
   6525             mResolveActivity.exported = true;
   6526             mResolveActivity.enabled = true;
   6527             mResolveInfo.activityInfo = mResolveActivity;
   6528             mResolveInfo.priority = 0;
   6529             mResolveInfo.preferredOrder = 0;
   6530             mResolveInfo.match = 0;
   6531             mResolveComponentName = mCustomResolverComponentName;
   6532             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
   6533                     mResolveComponentName);
   6534         }
   6535     }
   6536 
   6537     private static String calculateBundledApkRoot(final String codePathString) {
   6538         final File codePath = new File(codePathString);
   6539         final File codeRoot;
   6540         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
   6541             codeRoot = Environment.getRootDirectory();
   6542         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
   6543             codeRoot = Environment.getOemDirectory();
   6544         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
   6545             codeRoot = Environment.getVendorDirectory();
   6546         } else {
   6547             // Unrecognized code path; take its top real segment as the apk root:
   6548             // e.g. /something/app/blah.apk => /something
   6549             try {
   6550                 File f = codePath.getCanonicalFile();
   6551                 File parent = f.getParentFile();    // non-null because codePath is a file
   6552                 File tmp;
   6553                 while ((tmp = parent.getParentFile()) != null) {
   6554                     f = parent;
   6555                     parent = tmp;
   6556                 }
   6557                 codeRoot = f;
   6558                 Slog.w(TAG, "Unrecognized code path "
   6559                         + codePath + " - using " + codeRoot);
   6560             } catch (IOException e) {
   6561                 // Can't canonicalize the code path -- shenanigans?
   6562                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
   6563                 return Environment.getRootDirectory().getPath();
   6564             }
   6565         }
   6566         return codeRoot.getPath();
   6567     }
   6568 
   6569     /**
   6570      * Derive and set the location of native libraries for the given package,
   6571      * which varies depending on where and how the package was installed.
   6572      */
   6573     private void setNativeLibraryPaths(PackageParser.Package pkg) {
   6574         final ApplicationInfo info = pkg.applicationInfo;
   6575         final String codePath = pkg.codePath;
   6576         final File codeFile = new File(codePath);
   6577         final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
   6578         final boolean asecApp = isForwardLocked(info) || isExternal(info);
   6579 
   6580         info.nativeLibraryRootDir = null;
   6581         info.nativeLibraryRootRequiresIsa = false;
   6582         info.nativeLibraryDir = null;
   6583         info.secondaryNativeLibraryDir = null;
   6584 
   6585         if (isApkFile(codeFile)) {
   6586             // Monolithic install
   6587             if (bundledApp) {
   6588                 // If "/system/lib64/apkname" exists, assume that is the per-package
   6589                 // native library directory to use; otherwise use "/system/lib/apkname".
   6590                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
   6591                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
   6592                         getPrimaryInstructionSet(info));
   6593 
   6594                 // This is a bundled system app so choose the path based on the ABI.
   6595                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
   6596                 // is just the default path.
   6597                 final String apkName = deriveCodePathName(codePath);
   6598                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
   6599                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
   6600                         apkName).getAbsolutePath();
   6601 
   6602                 if (info.secondaryCpuAbi != null) {
   6603                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
   6604                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
   6605                             secondaryLibDir, apkName).getAbsolutePath();
   6606                 }
   6607             } else if (asecApp) {
   6608                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
   6609                         .getAbsolutePath();
   6610             } else {
   6611                 final String apkName = deriveCodePathName(codePath);
   6612                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
   6613                         .getAbsolutePath();
   6614             }
   6615 
   6616             info.nativeLibraryRootRequiresIsa = false;
   6617             info.nativeLibraryDir = info.nativeLibraryRootDir;
   6618         } else {
   6619             // Cluster install
   6620             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
   6621             info.nativeLibraryRootRequiresIsa = true;
   6622 
   6623             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
   6624                     getPrimaryInstructionSet(info)).getAbsolutePath();
   6625 
   6626             if (info.secondaryCpuAbi != null) {
   6627                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
   6628                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
   6629             }
   6630         }
   6631     }
   6632 
   6633     /**
   6634      * Calculate the abis and roots for a bundled app. These can uniquely
   6635      * be determined from the contents of the system partition, i.e whether
   6636      * it contains 64 or 32 bit shared libraries etc. We do not validate any
   6637      * of this information, and instead assume that the system was built
   6638      * sensibly.
   6639      */
   6640     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
   6641                                            PackageSetting pkgSetting) {
   6642         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
   6643 
   6644         // If "/system/lib64/apkname" exists, assume that is the per-package
   6645         // native library directory to use; otherwise use "/system/lib/apkname".
   6646         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
   6647         setBundledAppAbi(pkg, apkRoot, apkName);
   6648         // pkgSetting might be null during rescan following uninstall of updates
   6649         // to a bundled app, so accommodate that possibility.  The settings in
   6650         // that case will be established later from the parsed package.
   6651         //
   6652         // If the settings aren't null, sync them up with what we've just derived.
   6653         // note that apkRoot isn't stored in the package settings.
   6654         if (pkgSetting != null) {
   6655             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
   6656             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
   6657         }
   6658     }
   6659 
   6660     /**
   6661      * Deduces the ABI of a bundled app and sets the relevant fields on the
   6662      * parsed pkg object.
   6663      *
   6664      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
   6665      *        under which system libraries are installed.
   6666      * @param apkName the name of the installed package.
   6667      */
   6668     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
   6669         final File codeFile = new File(pkg.codePath);
   6670 
   6671         final boolean has64BitLibs;
   6672         final boolean has32BitLibs;
   6673         if (isApkFile(codeFile)) {
   6674             // Monolithic install
   6675             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
   6676             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
   6677         } else {
   6678             // Cluster install
   6679             final File rootDir = new File(codeFile, LIB_DIR_NAME);
   6680             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
   6681                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
   6682                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
   6683                 has64BitLibs = (new File(rootDir, isa)).exists();
   6684             } else {
   6685                 has64BitLibs = false;
   6686             }
   6687             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
   6688                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
   6689                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
   6690                 has32BitLibs = (new File(rootDir, isa)).exists();
   6691             } else {
   6692                 has32BitLibs = false;
   6693             }
   6694         }
   6695 
   6696         if (has64BitLibs && !has32BitLibs) {
   6697             // The package has 64 bit libs, but not 32 bit libs. Its primary
   6698             // ABI should be 64 bit. We can safely assume here that the bundled
   6699             // native libraries correspond to the most preferred ABI in the list.
   6700 
   6701             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   6702             pkg.applicationInfo.secondaryCpuAbi = null;
   6703         } else if (has32BitLibs && !has64BitLibs) {
   6704             // The package has 32 bit libs but not 64 bit libs. Its primary
   6705             // ABI should be 32 bit.
   6706 
   6707             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   6708             pkg.applicationInfo.secondaryCpuAbi = null;
   6709         } else if (has32BitLibs && has64BitLibs) {
   6710             // The application has both 64 and 32 bit bundled libraries. We check
   6711             // here that the app declares multiArch support, and warn if it doesn't.
   6712             //
   6713             // We will be lenient here and record both ABIs. The primary will be the
   6714             // ABI that's higher on the list, i.e, a device that's configured to prefer
   6715             // 64 bit apps will see a 64 bit primary ABI,
   6716 
   6717             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
   6718                 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
   6719             }
   6720 
   6721             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
   6722                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   6723                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   6724             } else {
   6725                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   6726                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   6727             }
   6728         } else {
   6729             pkg.applicationInfo.primaryCpuAbi = null;
   6730             pkg.applicationInfo.secondaryCpuAbi = null;
   6731         }
   6732     }
   6733 
   6734     private void killApplication(String pkgName, int appId, String reason) {
   6735         // Request the ActivityManager to kill the process(only for existing packages)
   6736         // so that we do not end up in a confused state while the user is still using the older
   6737         // version of the application while the new one gets installed.
   6738         IActivityManager am = ActivityManagerNative.getDefault();
   6739         if (am != null) {
   6740             try {
   6741                 am.killApplicationWithAppId(pkgName, appId, reason);
   6742             } catch (RemoteException e) {
   6743             }
   6744         }
   6745     }
   6746 
   6747     void removePackageLI(PackageSetting ps, boolean chatty) {
   6748         if (DEBUG_INSTALL) {
   6749             if (chatty)
   6750                 Log.d(TAG, "Removing package " + ps.name);
   6751         }
   6752 
   6753         // writer
   6754         synchronized (mPackages) {
   6755             mPackages.remove(ps.name);
   6756             final PackageParser.Package pkg = ps.pkg;
   6757             if (pkg != null) {
   6758                 cleanPackageDataStructuresLILPw(pkg, chatty);
   6759             }
   6760         }
   6761     }
   6762 
   6763     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
   6764         if (DEBUG_INSTALL) {
   6765             if (chatty)
   6766                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
   6767         }
   6768 
   6769         // writer
   6770         synchronized (mPackages) {
   6771             mPackages.remove(pkg.applicationInfo.packageName);
   6772             cleanPackageDataStructuresLILPw(pkg, chatty);
   6773         }
   6774     }
   6775 
   6776     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
   6777         int N = pkg.providers.size();
   6778         StringBuilder r = null;
   6779         int i;
   6780         for (i=0; i<N; i++) {
   6781             PackageParser.Provider p = pkg.providers.get(i);
   6782             mProviders.removeProvider(p);
   6783             if (p.info.authority == null) {
   6784 
   6785                 /* There was another ContentProvider with this authority when
   6786                  * this app was installed so this authority is null,
   6787                  * Ignore it as we don't have to unregister the provider.
   6788                  */
   6789                 continue;
   6790             }
   6791             String names[] = p.info.authority.split(";");
   6792             for (int j = 0; j < names.length; j++) {
   6793                 if (mProvidersByAuthority.get(names[j]) == p) {
   6794                     mProvidersByAuthority.remove(names[j]);
   6795                     if (DEBUG_REMOVE) {
   6796                         if (chatty)
   6797                             Log.d(TAG, "Unregistered content provider: " + names[j]
   6798                                     + ", className = " + p.info.name + ", isSyncable = "
   6799                                     + p.info.isSyncable);
   6800                     }
   6801                 }
   6802             }
   6803             if (DEBUG_REMOVE && chatty) {
   6804                 if (r == null) {
   6805                     r = new StringBuilder(256);
   6806                 } else {
   6807                     r.append(' ');
   6808                 }
   6809                 r.append(p.info.name);
   6810             }
   6811         }
   6812         if (r != null) {
   6813             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
   6814         }
   6815 
   6816         N = pkg.services.size();
   6817         r = null;
   6818         for (i=0; i<N; i++) {
   6819             PackageParser.Service s = pkg.services.get(i);
   6820             mServices.removeService(s);
   6821             if (chatty) {
   6822                 if (r == null) {
   6823                     r = new StringBuilder(256);
   6824                 } else {
   6825                     r.append(' ');
   6826                 }
   6827                 r.append(s.info.name);
   6828             }
   6829         }
   6830         if (r != null) {
   6831             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
   6832         }
   6833 
   6834         N = pkg.receivers.size();
   6835         r = null;
   6836         for (i=0; i<N; i++) {
   6837             PackageParser.Activity a = pkg.receivers.get(i);
   6838             mReceivers.removeActivity(a, "receiver");
   6839             if (DEBUG_REMOVE && chatty) {
   6840                 if (r == null) {
   6841                     r = new StringBuilder(256);
   6842                 } else {
   6843                     r.append(' ');
   6844                 }
   6845                 r.append(a.info.name);
   6846             }
   6847         }
   6848         if (r != null) {
   6849             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
   6850         }
   6851 
   6852         N = pkg.activities.size();
   6853         r = null;
   6854         for (i=0; i<N; i++) {
   6855             PackageParser.Activity a = pkg.activities.get(i);
   6856             mActivities.removeActivity(a, "activity");
   6857             if (DEBUG_REMOVE && chatty) {
   6858                 if (r == null) {
   6859                     r = new StringBuilder(256);
   6860                 } else {
   6861                     r.append(' ');
   6862                 }
   6863                 r.append(a.info.name);
   6864             }
   6865         }
   6866         if (r != null) {
   6867             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
   6868         }
   6869 
   6870         N = pkg.permissions.size();
   6871         r = null;
   6872         for (i=0; i<N; i++) {
   6873             PackageParser.Permission p = pkg.permissions.get(i);
   6874             BasePermission bp = mSettings.mPermissions.get(p.info.name);
   6875             if (bp == null) {
   6876                 bp = mSettings.mPermissionTrees.get(p.info.name);
   6877             }
   6878             if (bp != null && bp.perm == p) {
   6879                 bp.perm = null;
   6880                 if (DEBUG_REMOVE && chatty) {
   6881                     if (r == null) {
   6882                         r = new StringBuilder(256);
   6883                     } else {
   6884                         r.append(' ');
   6885                     }
   6886                     r.append(p.info.name);
   6887                 }
   6888             }
   6889             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   6890                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
   6891                 if (appOpPerms != null) {
   6892                     appOpPerms.remove(pkg.packageName);
   6893                 }
   6894             }
   6895         }
   6896         if (r != null) {
   6897             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   6898         }
   6899 
   6900         N = pkg.requestedPermissions.size();
   6901         r = null;
   6902         for (i=0; i<N; i++) {
   6903             String perm = pkg.requestedPermissions.get(i);
   6904             BasePermission bp = mSettings.mPermissions.get(perm);
   6905             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   6906                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
   6907                 if (appOpPerms != null) {
   6908                     appOpPerms.remove(pkg.packageName);
   6909                     if (appOpPerms.isEmpty()) {
   6910                         mAppOpPermissionPackages.remove(perm);
   6911                     }
   6912                 }
   6913             }
   6914         }
   6915         if (r != null) {
   6916             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   6917         }
   6918 
   6919         N = pkg.instrumentation.size();
   6920         r = null;
   6921         for (i=0; i<N; i++) {
   6922             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   6923             mInstrumentation.remove(a.getComponentName());
   6924             if (DEBUG_REMOVE && chatty) {
   6925                 if (r == null) {
   6926                     r = new StringBuilder(256);
   6927                 } else {
   6928                     r.append(' ');
   6929                 }
   6930                 r.append(a.info.name);
   6931             }
   6932         }
   6933         if (r != null) {
   6934             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
   6935         }
   6936 
   6937         r = null;
   6938         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   6939             // Only system apps can hold shared libraries.
   6940             if (pkg.libraryNames != null) {
   6941                 for (i=0; i<pkg.libraryNames.size(); i++) {
   6942                     String name = pkg.libraryNames.get(i);
   6943                     SharedLibraryEntry cur = mSharedLibraries.get(name);
   6944                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
   6945                         mSharedLibraries.remove(name);
   6946                         if (DEBUG_REMOVE && chatty) {
   6947                             if (r == null) {
   6948                                 r = new StringBuilder(256);
   6949                             } else {
   6950                                 r.append(' ');
   6951                             }
   6952                             r.append(name);
   6953                         }
   6954                     }
   6955                 }
   6956             }
   6957         }
   6958         if (r != null) {
   6959             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
   6960         }
   6961     }
   6962 
   6963     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
   6964         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
   6965             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
   6966                 return true;
   6967             }
   6968         }
   6969         return false;
   6970     }
   6971 
   6972     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
   6973     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
   6974     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
   6975 
   6976     private void updatePermissionsLPw(String changingPkg,
   6977             PackageParser.Package pkgInfo, int flags) {
   6978         // Make sure there are no dangling permission trees.
   6979         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
   6980         while (it.hasNext()) {
   6981             final BasePermission bp = it.next();
   6982             if (bp.packageSetting == null) {
   6983                 // We may not yet have parsed the package, so just see if
   6984                 // we still know about its settings.
   6985                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   6986             }
   6987             if (bp.packageSetting == null) {
   6988                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
   6989                         + " from package " + bp.sourcePackage);
   6990                 it.remove();
   6991             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   6992                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   6993                     Slog.i(TAG, "Removing old permission tree: " + bp.name
   6994                             + " from package " + bp.sourcePackage);
   6995                     flags |= UPDATE_PERMISSIONS_ALL;
   6996                     it.remove();
   6997                 }
   6998             }
   6999         }
   7000 
   7001         // Make sure all dynamic permissions have been assigned to a package,
   7002         // and make sure there are no dangling permissions.
   7003         it = mSettings.mPermissions.values().iterator();
   7004         while (it.hasNext()) {
   7005             final BasePermission bp = it.next();
   7006             if (bp.type == BasePermission.TYPE_DYNAMIC) {
   7007                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
   7008                         + bp.name + " pkg=" + bp.sourcePackage
   7009                         + " info=" + bp.pendingInfo);
   7010                 if (bp.packageSetting == null && bp.pendingInfo != null) {
   7011                     final BasePermission tree = findPermissionTreeLP(bp.name);
   7012                     if (tree != null && tree.perm != null) {
   7013                         bp.packageSetting = tree.packageSetting;
   7014                         bp.perm = new PackageParser.Permission(tree.perm.owner,
   7015                                 new PermissionInfo(bp.pendingInfo));
   7016                         bp.perm.info.packageName = tree.perm.info.packageName;
   7017                         bp.perm.info.name = bp.name;
   7018                         bp.uid = tree.uid;
   7019                     }
   7020                 }
   7021             }
   7022             if (bp.packageSetting == null) {
   7023                 // We may not yet have parsed the package, so just see if
   7024                 // we still know about its settings.
   7025                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   7026             }
   7027             if (bp.packageSetting == null) {
   7028                 Slog.w(TAG, "Removing dangling permission: " + bp.name
   7029                         + " from package " + bp.sourcePackage);
   7030                 it.remove();
   7031             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   7032                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   7033                     Slog.i(TAG, "Removing old permission: " + bp.name
   7034                             + " from package " + bp.sourcePackage);
   7035                     flags |= UPDATE_PERMISSIONS_ALL;
   7036                     it.remove();
   7037                 }
   7038             }
   7039         }
   7040 
   7041         // Now update the permissions for all packages, in particular
   7042         // replace the granted permissions of the system packages.
   7043         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
   7044             for (PackageParser.Package pkg : mPackages.values()) {
   7045                 if (pkg != pkgInfo) {
   7046                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
   7047                             changingPkg);
   7048                 }
   7049             }
   7050         }
   7051 
   7052         if (pkgInfo != null) {
   7053             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
   7054         }
   7055     }
   7056 
   7057     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
   7058             String packageOfInterest) {
   7059         final PackageSetting ps = (PackageSetting) pkg.mExtras;
   7060         if (ps == null) {
   7061             return;
   7062         }
   7063         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   7064         ArraySet<String> origPermissions = gp.grantedPermissions;
   7065         boolean changedPermission = false;
   7066 
   7067         if (replace) {
   7068             ps.permissionsFixed = false;
   7069             if (gp == ps) {
   7070                 origPermissions = new ArraySet<String>(gp.grantedPermissions);
   7071                 gp.grantedPermissions.clear();
   7072                 gp.gids = mGlobalGids;
   7073             }
   7074         }
   7075 
   7076         if (gp.gids == null) {
   7077             gp.gids = mGlobalGids;
   7078         }
   7079 
   7080         final int N = pkg.requestedPermissions.size();
   7081         for (int i=0; i<N; i++) {
   7082             final String name = pkg.requestedPermissions.get(i);
   7083             final boolean required = pkg.requestedPermissionsRequired.get(i);
   7084             final BasePermission bp = mSettings.mPermissions.get(name);
   7085             if (DEBUG_INSTALL) {
   7086                 if (gp != ps) {
   7087                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
   7088                 }
   7089             }
   7090 
   7091             if (bp == null || bp.packageSetting == null) {
   7092                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
   7093                     Slog.w(TAG, "Unknown permission " + name
   7094                             + " in package " + pkg.packageName);
   7095                 }
   7096                 continue;
   7097             }
   7098 
   7099             final String perm = bp.name;
   7100             boolean allowed;
   7101             boolean allowedSig = false;
   7102             if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   7103                 // Keep track of app op permissions.
   7104                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
   7105                 if (pkgs == null) {
   7106                     pkgs = new ArraySet<>();
   7107                     mAppOpPermissionPackages.put(bp.name, pkgs);
   7108                 }
   7109                 pkgs.add(pkg.packageName);
   7110             }
   7111             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
   7112             if (level == PermissionInfo.PROTECTION_NORMAL
   7113                     || level == PermissionInfo.PROTECTION_DANGEROUS) {
   7114                 // We grant a normal or dangerous permission if any of the following
   7115                 // are true:
   7116                 // 1) The permission is required
   7117                 // 2) The permission is optional, but was granted in the past
   7118                 // 3) The permission is optional, but was requested by an
   7119                 //    app in /system (not /data)
   7120                 //
   7121                 // Otherwise, reject the permission.
   7122                 allowed = (required || origPermissions.contains(perm)
   7123                         || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
   7124             } else if (bp.packageSetting == null) {
   7125                 // This permission is invalid; skip it.
   7126                 allowed = false;
   7127             } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
   7128                 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
   7129                 if (allowed) {
   7130                     allowedSig = true;
   7131                 }
   7132             } else {
   7133                 allowed = false;
   7134             }
   7135             if (DEBUG_INSTALL) {
   7136                 if (gp != ps) {
   7137                     Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
   7138                 }
   7139             }
   7140             if (allowed) {
   7141                 if (!isSystemApp(ps) && ps.permissionsFixed) {
   7142                     // If this is an existing, non-system package, then
   7143                     // we can't add any new permissions to it.
   7144                     if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
   7145                         // Except...  if this is a permission that was added
   7146                         // to the platform (note: need to only do this when
   7147                         // updating the platform).
   7148                         allowed = isNewPlatformPermissionForPackage(perm, pkg);
   7149                     }
   7150                 }
   7151                 if (allowed) {
   7152                     if (!gp.grantedPermissions.contains(perm)) {
   7153                         changedPermission = true;
   7154                         gp.grantedPermissions.add(perm);
   7155                         gp.gids = appendInts(gp.gids, bp.gids);
   7156                     } else if (!ps.haveGids) {
   7157                         gp.gids = appendInts(gp.gids, bp.gids);
   7158                     }
   7159                 } else {
   7160                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
   7161                         Slog.w(TAG, "Not granting permission " + perm
   7162                                 + " to package " + pkg.packageName
   7163                                 + " because it was previously installed without");
   7164                     }
   7165                 }
   7166             } else {
   7167                 if (gp.grantedPermissions.remove(perm)) {
   7168                     changedPermission = true;
   7169                     gp.gids = removeInts(gp.gids, bp.gids);
   7170                     Slog.i(TAG, "Un-granting permission " + perm
   7171                             + " from package " + pkg.packageName
   7172                             + " (protectionLevel=" + bp.protectionLevel
   7173                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   7174                             + ")");
   7175                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
   7176                     // Don't print warning for app op permissions, since it is fine for them
   7177                     // not to be granted, there is a UI for the user to decide.
   7178                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
   7179                         Slog.w(TAG, "Not granting permission " + perm
   7180                                 + " to package " + pkg.packageName
   7181                                 + " (protectionLevel=" + bp.protectionLevel
   7182                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   7183                                 + ")");
   7184                     }
   7185                 }
   7186             }
   7187         }
   7188 
   7189         if ((changedPermission || replace) && !ps.permissionsFixed &&
   7190                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
   7191             // This is the first that we have heard about this package, so the
   7192             // permissions we have now selected are fixed until explicitly
   7193             // changed.
   7194             ps.permissionsFixed = true;
   7195         }
   7196         ps.haveGids = true;
   7197     }
   7198 
   7199     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
   7200         boolean allowed = false;
   7201         final int NP = PackageParser.NEW_PERMISSIONS.length;
   7202         for (int ip=0; ip<NP; ip++) {
   7203             final PackageParser.NewPermissionInfo npi
   7204                     = PackageParser.NEW_PERMISSIONS[ip];
   7205             if (npi.name.equals(perm)
   7206                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
   7207                 allowed = true;
   7208                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
   7209                         + pkg.packageName);
   7210                 break;
   7211             }
   7212         }
   7213         return allowed;
   7214     }
   7215 
   7216     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
   7217                                           BasePermission bp, ArraySet<String> origPermissions) {
   7218         boolean allowed;
   7219         allowed = (compareSignatures(
   7220                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
   7221                         == PackageManager.SIGNATURE_MATCH)
   7222                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
   7223                         == PackageManager.SIGNATURE_MATCH);
   7224         if (!allowed && (bp.protectionLevel
   7225                 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
   7226             if (isSystemApp(pkg)) {
   7227                 // For updated system applications, a system permission
   7228                 // is granted only if it had been defined by the original application.
   7229                 if (isUpdatedSystemApp(pkg)) {
   7230                     final PackageSetting sysPs = mSettings
   7231                             .getDisabledSystemPkgLPr(pkg.packageName);
   7232                     final GrantedPermissions origGp = sysPs.sharedUser != null
   7233                             ? sysPs.sharedUser : sysPs;
   7234 
   7235                     if (origGp.grantedPermissions.contains(perm)) {
   7236                         // If the original was granted this permission, we take
   7237                         // that grant decision as read and propagate it to the
   7238                         // update.
   7239                         if (sysPs.isPrivileged()) {
   7240                             allowed = true;
   7241                         }
   7242                     } else {
   7243                         // The system apk may have been updated with an older
   7244                         // version of the one on the data partition, but which
   7245                         // granted a new system permission that it didn't have
   7246                         // before.  In this case we do want to allow the app to
   7247                         // now get the new permission if the ancestral apk is
   7248                         // privileged to get it.
   7249                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
   7250                             for (int j=0;
   7251                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
   7252                                 if (perm.equals(
   7253                                         sysPs.pkg.requestedPermissions.get(j))) {
   7254                                     allowed = true;
   7255                                     break;
   7256                                 }
   7257                             }
   7258                         }
   7259                     }
   7260                 } else {
   7261                     allowed = isPrivilegedApp(pkg);
   7262                 }
   7263             }
   7264         }
   7265         if (!allowed && (bp.protectionLevel
   7266                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
   7267             // For development permissions, a development permission
   7268             // is granted only if it was already granted.
   7269             allowed = origPermissions.contains(perm);
   7270         }
   7271         return allowed;
   7272     }
   7273 
   7274     final class ActivityIntentResolver
   7275             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
   7276         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   7277                 boolean defaultOnly, int userId) {
   7278             if (!sUserManager.exists(userId)) return null;
   7279             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   7280             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   7281         }
   7282 
   7283         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   7284                 int userId) {
   7285             if (!sUserManager.exists(userId)) return null;
   7286             mFlags = flags;
   7287             return super.queryIntent(intent, resolvedType,
   7288                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   7289         }
   7290 
   7291         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   7292                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
   7293             if (!sUserManager.exists(userId)) return null;
   7294             if (packageActivities == null) {
   7295                 return null;
   7296             }
   7297             mFlags = flags;
   7298             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   7299             final int N = packageActivities.size();
   7300             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
   7301                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
   7302 
   7303             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
   7304             for (int i = 0; i < N; ++i) {
   7305                 intentFilters = packageActivities.get(i).intents;
   7306                 if (intentFilters != null && intentFilters.size() > 0) {
   7307                     PackageParser.ActivityIntentInfo[] array =
   7308                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
   7309                     intentFilters.toArray(array);
   7310                     listCut.add(array);
   7311                 }
   7312             }
   7313             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   7314         }
   7315 
   7316         public final void addActivity(PackageParser.Activity a, String type) {
   7317             final boolean systemApp = isSystemApp(a.info.applicationInfo);
   7318             mActivities.put(a.getComponentName(), a);
   7319             if (DEBUG_SHOW_INFO)
   7320                 Log.v(
   7321                 TAG, "  " + type + " " +
   7322                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
   7323             if (DEBUG_SHOW_INFO)
   7324                 Log.v(TAG, "    Class=" + a.info.name);
   7325             final int NI = a.intents.size();
   7326             for (int j=0; j<NI; j++) {
   7327                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   7328                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
   7329                     intent.setPriority(0);
   7330                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
   7331                             + a.className + " with priority > 0, forcing to 0");
   7332                 }
   7333                 if (DEBUG_SHOW_INFO) {
   7334                     Log.v(TAG, "    IntentFilter:");
   7335                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7336                 }
   7337                 if (!intent.debugCheck()) {
   7338                     Log.w(TAG, "==> For Activity " + a.info.name);
   7339                 }
   7340                 addFilter(intent);
   7341             }
   7342         }
   7343 
   7344         public final void removeActivity(PackageParser.Activity a, String type) {
   7345             mActivities.remove(a.getComponentName());
   7346             if (DEBUG_SHOW_INFO) {
   7347                 Log.v(TAG, "  " + type + " "
   7348                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
   7349                                 : a.info.name) + ":");
   7350                 Log.v(TAG, "    Class=" + a.info.name);
   7351             }
   7352             final int NI = a.intents.size();
   7353             for (int j=0; j<NI; j++) {
   7354                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   7355                 if (DEBUG_SHOW_INFO) {
   7356                     Log.v(TAG, "    IntentFilter:");
   7357                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7358                 }
   7359                 removeFilter(intent);
   7360             }
   7361         }
   7362 
   7363         @Override
   7364         protected boolean allowFilterResult(
   7365                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
   7366             ActivityInfo filterAi = filter.activity.info;
   7367             for (int i=dest.size()-1; i>=0; i--) {
   7368                 ActivityInfo destAi = dest.get(i).activityInfo;
   7369                 if (destAi.name == filterAi.name
   7370                         && destAi.packageName == filterAi.packageName) {
   7371                     return false;
   7372                 }
   7373             }
   7374             return true;
   7375         }
   7376 
   7377         @Override
   7378         protected ActivityIntentInfo[] newArray(int size) {
   7379             return new ActivityIntentInfo[size];
   7380         }
   7381 
   7382         @Override
   7383         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
   7384             if (!sUserManager.exists(userId)) return true;
   7385             PackageParser.Package p = filter.activity.owner;
   7386             if (p != null) {
   7387                 PackageSetting ps = (PackageSetting)p.mExtras;
   7388                 if (ps != null) {
   7389                     // System apps are never considered stopped for purposes of
   7390                     // filtering, because there may be no way for the user to
   7391                     // actually re-launch them.
   7392                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
   7393                             && ps.getStopped(userId);
   7394                 }
   7395             }
   7396             return false;
   7397         }
   7398 
   7399         @Override
   7400         protected boolean isPackageForFilter(String packageName,
   7401                 PackageParser.ActivityIntentInfo info) {
   7402             return packageName.equals(info.activity.owner.packageName);
   7403         }
   7404 
   7405         @Override
   7406         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
   7407                 int match, int userId) {
   7408             if (!sUserManager.exists(userId)) return null;
   7409             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
   7410                 return null;
   7411             }
   7412             final PackageParser.Activity activity = info.activity;
   7413             if (mSafeMode && (activity.info.applicationInfo.flags
   7414                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   7415                 return null;
   7416             }
   7417             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
   7418             if (ps == null) {
   7419                 return null;
   7420             }
   7421             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
   7422                     ps.readUserState(userId), userId);
   7423             if (ai == null) {
   7424                 return null;
   7425             }
   7426             final ResolveInfo res = new ResolveInfo();
   7427             res.activityInfo = ai;
   7428             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   7429                 res.filter = info;
   7430             }
   7431             res.priority = info.getPriority();
   7432             res.preferredOrder = activity.owner.mPreferredOrder;
   7433             //System.out.println("Result: " + res.activityInfo.className +
   7434             //                   " = " + res.priority);
   7435             res.match = match;
   7436             res.isDefault = info.hasDefault;
   7437             res.labelRes = info.labelRes;
   7438             res.nonLocalizedLabel = info.nonLocalizedLabel;
   7439             if (userNeedsBadging(userId)) {
   7440                 res.noResourceId = true;
   7441             } else {
   7442                 res.icon = info.icon;
   7443             }
   7444             res.system = isSystemApp(res.activityInfo.applicationInfo);
   7445             return res;
   7446         }
   7447 
   7448         @Override
   7449         protected void sortResults(List<ResolveInfo> results) {
   7450             Collections.sort(results, mResolvePrioritySorter);
   7451         }
   7452 
   7453         @Override
   7454         protected void dumpFilter(PrintWriter out, String prefix,
   7455                 PackageParser.ActivityIntentInfo filter) {
   7456             out.print(prefix); out.print(
   7457                     Integer.toHexString(System.identityHashCode(filter.activity)));
   7458                     out.print(' ');
   7459                     filter.activity.printComponentShortName(out);
   7460                     out.print(" filter ");
   7461                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   7462         }
   7463 
   7464         @Override
   7465         protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
   7466             return filter.activity;
   7467         }
   7468 
   7469         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
   7470             PackageParser.Activity activity = (PackageParser.Activity)label;
   7471             out.print(prefix); out.print(
   7472                     Integer.toHexString(System.identityHashCode(activity)));
   7473                     out.print(' ');
   7474                     activity.printComponentShortName(out);
   7475             if (count > 1) {
   7476                 out.print(" ("); out.print(count); out.print(" filters)");
   7477             }
   7478             out.println();
   7479         }
   7480 
   7481 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   7482 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   7483 //            final List<ResolveInfo> retList = Lists.newArrayList();
   7484 //            while (i.hasNext()) {
   7485 //                final ResolveInfo resolveInfo = i.next();
   7486 //                if (isEnabledLP(resolveInfo.activityInfo)) {
   7487 //                    retList.add(resolveInfo);
   7488 //                }
   7489 //            }
   7490 //            return retList;
   7491 //        }
   7492 
   7493         // Keys are String (activity class name), values are Activity.
   7494         private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
   7495                 = new ArrayMap<ComponentName, PackageParser.Activity>();
   7496         private int mFlags;
   7497     }
   7498 
   7499     private final class ServiceIntentResolver
   7500             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
   7501         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   7502                 boolean defaultOnly, int userId) {
   7503             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   7504             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   7505         }
   7506 
   7507         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   7508                 int userId) {
   7509             if (!sUserManager.exists(userId)) return null;
   7510             mFlags = flags;
   7511             return super.queryIntent(intent, resolvedType,
   7512                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   7513         }
   7514 
   7515         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   7516                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
   7517             if (!sUserManager.exists(userId)) return null;
   7518             if (packageServices == null) {
   7519                 return null;
   7520             }
   7521             mFlags = flags;
   7522             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   7523             final int N = packageServices.size();
   7524             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
   7525                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
   7526 
   7527             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
   7528             for (int i = 0; i < N; ++i) {
   7529                 intentFilters = packageServices.get(i).intents;
   7530                 if (intentFilters != null && intentFilters.size() > 0) {
   7531                     PackageParser.ServiceIntentInfo[] array =
   7532                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
   7533                     intentFilters.toArray(array);
   7534                     listCut.add(array);
   7535                 }
   7536             }
   7537             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   7538         }
   7539 
   7540         public final void addService(PackageParser.Service s) {
   7541             mServices.put(s.getComponentName(), s);
   7542             if (DEBUG_SHOW_INFO) {
   7543                 Log.v(TAG, "  "
   7544                         + (s.info.nonLocalizedLabel != null
   7545                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   7546                 Log.v(TAG, "    Class=" + s.info.name);
   7547             }
   7548             final int NI = s.intents.size();
   7549             int j;
   7550             for (j=0; j<NI; j++) {
   7551                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   7552                 if (DEBUG_SHOW_INFO) {
   7553                     Log.v(TAG, "    IntentFilter:");
   7554                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7555                 }
   7556                 if (!intent.debugCheck()) {
   7557                     Log.w(TAG, "==> For Service " + s.info.name);
   7558                 }
   7559                 addFilter(intent);
   7560             }
   7561         }
   7562 
   7563         public final void removeService(PackageParser.Service s) {
   7564             mServices.remove(s.getComponentName());
   7565             if (DEBUG_SHOW_INFO) {
   7566                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
   7567                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   7568                 Log.v(TAG, "    Class=" + s.info.name);
   7569             }
   7570             final int NI = s.intents.size();
   7571             int j;
   7572             for (j=0; j<NI; j++) {
   7573                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   7574                 if (DEBUG_SHOW_INFO) {
   7575                     Log.v(TAG, "    IntentFilter:");
   7576                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7577                 }
   7578                 removeFilter(intent);
   7579             }
   7580         }
   7581 
   7582         @Override
   7583         protected boolean allowFilterResult(
   7584                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
   7585             ServiceInfo filterSi = filter.service.info;
   7586             for (int i=dest.size()-1; i>=0; i--) {
   7587                 ServiceInfo destAi = dest.get(i).serviceInfo;
   7588                 if (destAi.name == filterSi.name
   7589                         && destAi.packageName == filterSi.packageName) {
   7590                     return false;
   7591                 }
   7592             }
   7593             return true;
   7594         }
   7595 
   7596         @Override
   7597         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
   7598             return new PackageParser.ServiceIntentInfo[size];
   7599         }
   7600 
   7601         @Override
   7602         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
   7603             if (!sUserManager.exists(userId)) return true;
   7604             PackageParser.Package p = filter.service.owner;
   7605             if (p != null) {
   7606                 PackageSetting ps = (PackageSetting)p.mExtras;
   7607                 if (ps != null) {
   7608                     // System apps are never considered stopped for purposes of
   7609                     // filtering, because there may be no way for the user to
   7610                     // actually re-launch them.
   7611                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
   7612                             && ps.getStopped(userId);
   7613                 }
   7614             }
   7615             return false;
   7616         }
   7617 
   7618         @Override
   7619         protected boolean isPackageForFilter(String packageName,
   7620                 PackageParser.ServiceIntentInfo info) {
   7621             return packageName.equals(info.service.owner.packageName);
   7622         }
   7623 
   7624         @Override
   7625         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
   7626                 int match, int userId) {
   7627             if (!sUserManager.exists(userId)) return null;
   7628             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
   7629             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
   7630                 return null;
   7631             }
   7632             final PackageParser.Service service = info.service;
   7633             if (mSafeMode && (service.info.applicationInfo.flags
   7634                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   7635                 return null;
   7636             }
   7637             PackageSetting ps = (PackageSetting) service.owner.mExtras;
   7638             if (ps == null) {
   7639                 return null;
   7640             }
   7641             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
   7642                     ps.readUserState(userId), userId);
   7643             if (si == null) {
   7644                 return null;
   7645             }
   7646             final ResolveInfo res = new ResolveInfo();
   7647             res.serviceInfo = si;
   7648             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   7649                 res.filter = filter;
   7650             }
   7651             res.priority = info.getPriority();
   7652             res.preferredOrder = service.owner.mPreferredOrder;
   7653             //System.out.println("Result: " + res.activityInfo.className +
   7654             //                   " = " + res.priority);
   7655             res.match = match;
   7656             res.isDefault = info.hasDefault;
   7657             res.labelRes = info.labelRes;
   7658             res.nonLocalizedLabel = info.nonLocalizedLabel;
   7659             res.icon = info.icon;
   7660             res.system = isSystemApp(res.serviceInfo.applicationInfo);
   7661             return res;
   7662         }
   7663 
   7664         @Override
   7665         protected void sortResults(List<ResolveInfo> results) {
   7666             Collections.sort(results, mResolvePrioritySorter);
   7667         }
   7668 
   7669         @Override
   7670         protected void dumpFilter(PrintWriter out, String prefix,
   7671                 PackageParser.ServiceIntentInfo filter) {
   7672             out.print(prefix); out.print(
   7673                     Integer.toHexString(System.identityHashCode(filter.service)));
   7674                     out.print(' ');
   7675                     filter.service.printComponentShortName(out);
   7676                     out.print(" filter ");
   7677                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   7678         }
   7679 
   7680         @Override
   7681         protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
   7682             return filter.service;
   7683         }
   7684 
   7685         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
   7686             PackageParser.Service service = (PackageParser.Service)label;
   7687             out.print(prefix); out.print(
   7688                     Integer.toHexString(System.identityHashCode(service)));
   7689                     out.print(' ');
   7690                     service.printComponentShortName(out);
   7691             if (count > 1) {
   7692                 out.print(" ("); out.print(count); out.print(" filters)");
   7693             }
   7694             out.println();
   7695         }
   7696 
   7697 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   7698 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   7699 //            final List<ResolveInfo> retList = Lists.newArrayList();
   7700 //            while (i.hasNext()) {
   7701 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
   7702 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
   7703 //                    retList.add(resolveInfo);
   7704 //                }
   7705 //            }
   7706 //            return retList;
   7707 //        }
   7708 
   7709         // Keys are String (activity class name), values are Activity.
   7710         private final ArrayMap<ComponentName, PackageParser.Service> mServices
   7711                 = new ArrayMap<ComponentName, PackageParser.Service>();
   7712         private int mFlags;
   7713     };
   7714 
   7715     private final class ProviderIntentResolver
   7716             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
   7717         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   7718                 boolean defaultOnly, int userId) {
   7719             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   7720             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   7721         }
   7722 
   7723         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   7724                 int userId) {
   7725             if (!sUserManager.exists(userId))
   7726                 return null;
   7727             mFlags = flags;
   7728             return super.queryIntent(intent, resolvedType,
   7729                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   7730         }
   7731 
   7732         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   7733                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
   7734             if (!sUserManager.exists(userId))
   7735                 return null;
   7736             if (packageProviders == null) {
   7737                 return null;
   7738             }
   7739             mFlags = flags;
   7740             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
   7741             final int N = packageProviders.size();
   7742             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
   7743                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
   7744 
   7745             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
   7746             for (int i = 0; i < N; ++i) {
   7747                 intentFilters = packageProviders.get(i).intents;
   7748                 if (intentFilters != null && intentFilters.size() > 0) {
   7749                     PackageParser.ProviderIntentInfo[] array =
   7750                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
   7751                     intentFilters.toArray(array);
   7752                     listCut.add(array);
   7753                 }
   7754             }
   7755             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   7756         }
   7757 
   7758         public final void addProvider(PackageParser.Provider p) {
   7759             if (mProviders.containsKey(p.getComponentName())) {
   7760                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
   7761                 return;
   7762             }
   7763 
   7764             mProviders.put(p.getComponentName(), p);
   7765             if (DEBUG_SHOW_INFO) {
   7766                 Log.v(TAG, "  "
   7767                         + (p.info.nonLocalizedLabel != null
   7768                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
   7769                 Log.v(TAG, "    Class=" + p.info.name);
   7770             }
   7771             final int NI = p.intents.size();
   7772             int j;
   7773             for (j = 0; j < NI; j++) {
   7774                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
   7775                 if (DEBUG_SHOW_INFO) {
   7776                     Log.v(TAG, "    IntentFilter:");
   7777                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7778                 }
   7779                 if (!intent.debugCheck()) {
   7780                     Log.w(TAG, "==> For Provider " + p.info.name);
   7781                 }
   7782                 addFilter(intent);
   7783             }
   7784         }
   7785 
   7786         public final void removeProvider(PackageParser.Provider p) {
   7787             mProviders.remove(p.getComponentName());
   7788             if (DEBUG_SHOW_INFO) {
   7789                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
   7790                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
   7791                 Log.v(TAG, "    Class=" + p.info.name);
   7792             }
   7793             final int NI = p.intents.size();
   7794             int j;
   7795             for (j = 0; j < NI; j++) {
   7796                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
   7797                 if (DEBUG_SHOW_INFO) {
   7798                     Log.v(TAG, "    IntentFilter:");
   7799                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7800                 }
   7801                 removeFilter(intent);
   7802             }
   7803         }
   7804 
   7805         @Override
   7806         protected boolean allowFilterResult(
   7807                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
   7808             ProviderInfo filterPi = filter.provider.info;
   7809             for (int i = dest.size() - 1; i >= 0; i--) {
   7810                 ProviderInfo destPi = dest.get(i).providerInfo;
   7811                 if (destPi.name == filterPi.name
   7812                         && destPi.packageName == filterPi.packageName) {
   7813                     return false;
   7814                 }
   7815             }
   7816             return true;
   7817         }
   7818 
   7819         @Override
   7820         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
   7821             return new PackageParser.ProviderIntentInfo[size];
   7822         }
   7823 
   7824         @Override
   7825         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
   7826             if (!sUserManager.exists(userId))
   7827                 return true;
   7828             PackageParser.Package p = filter.provider.owner;
   7829             if (p != null) {
   7830                 PackageSetting ps = (PackageSetting) p.mExtras;
   7831                 if (ps != null) {
   7832                     // System apps are never considered stopped for purposes of
   7833                     // filtering, because there may be no way for the user to
   7834                     // actually re-launch them.
   7835                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
   7836                             && ps.getStopped(userId);
   7837                 }
   7838             }
   7839             return false;
   7840         }
   7841 
   7842         @Override
   7843         protected boolean isPackageForFilter(String packageName,
   7844                 PackageParser.ProviderIntentInfo info) {
   7845             return packageName.equals(info.provider.owner.packageName);
   7846         }
   7847 
   7848         @Override
   7849         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
   7850                 int match, int userId) {
   7851             if (!sUserManager.exists(userId))
   7852                 return null;
   7853             final PackageParser.ProviderIntentInfo info = filter;
   7854             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
   7855                 return null;
   7856             }
   7857             final PackageParser.Provider provider = info.provider;
   7858             if (mSafeMode && (provider.info.applicationInfo.flags
   7859                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
   7860                 return null;
   7861             }
   7862             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
   7863             if (ps == null) {
   7864                 return null;
   7865             }
   7866             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
   7867                     ps.readUserState(userId), userId);
   7868             if (pi == null) {
   7869                 return null;
   7870             }
   7871             final ResolveInfo res = new ResolveInfo();
   7872             res.providerInfo = pi;
   7873             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
   7874                 res.filter = filter;
   7875             }
   7876             res.priority = info.getPriority();
   7877             res.preferredOrder = provider.owner.mPreferredOrder;
   7878             res.match = match;
   7879             res.isDefault = info.hasDefault;
   7880             res.labelRes = info.labelRes;
   7881             res.nonLocalizedLabel = info.nonLocalizedLabel;
   7882             res.icon = info.icon;
   7883             res.system = isSystemApp(res.providerInfo.applicationInfo);
   7884             return res;
   7885         }
   7886 
   7887         @Override
   7888         protected void sortResults(List<ResolveInfo> results) {
   7889             Collections.sort(results, mResolvePrioritySorter);
   7890         }
   7891 
   7892         @Override
   7893         protected void dumpFilter(PrintWriter out, String prefix,
   7894                 PackageParser.ProviderIntentInfo filter) {
   7895             out.print(prefix);
   7896             out.print(
   7897                     Integer.toHexString(System.identityHashCode(filter.provider)));
   7898             out.print(' ');
   7899             filter.provider.printComponentShortName(out);
   7900             out.print(" filter ");
   7901             out.println(Integer.toHexString(System.identityHashCode(filter)));
   7902         }
   7903 
   7904         @Override
   7905         protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
   7906             return filter.provider;
   7907         }
   7908 
   7909         protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
   7910             PackageParser.Provider provider = (PackageParser.Provider)label;
   7911             out.print(prefix); out.print(
   7912                     Integer.toHexString(System.identityHashCode(provider)));
   7913                     out.print(' ');
   7914                     provider.printComponentShortName(out);
   7915             if (count > 1) {
   7916                 out.print(" ("); out.print(count); out.print(" filters)");
   7917             }
   7918             out.println();
   7919         }
   7920 
   7921         private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
   7922                 = new ArrayMap<ComponentName, PackageParser.Provider>();
   7923         private int mFlags;
   7924     };
   7925 
   7926     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
   7927             new Comparator<ResolveInfo>() {
   7928         public int compare(ResolveInfo r1, ResolveInfo r2) {
   7929             int v1 = r1.priority;
   7930             int v2 = r2.priority;
   7931             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
   7932             if (v1 != v2) {
   7933                 return (v1 > v2) ? -1 : 1;
   7934             }
   7935             v1 = r1.preferredOrder;
   7936             v2 = r2.preferredOrder;
   7937             if (v1 != v2) {
   7938                 return (v1 > v2) ? -1 : 1;
   7939             }
   7940             if (r1.isDefault != r2.isDefault) {
   7941                 return r1.isDefault ? -1 : 1;
   7942             }
   7943             v1 = r1.match;
   7944             v2 = r2.match;
   7945             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
   7946             if (v1 != v2) {
   7947                 return (v1 > v2) ? -1 : 1;
   7948             }
   7949             if (r1.system != r2.system) {
   7950                 return r1.system ? -1 : 1;
   7951             }
   7952             return 0;
   7953         }
   7954     };
   7955 
   7956     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
   7957             new Comparator<ProviderInfo>() {
   7958         public int compare(ProviderInfo p1, ProviderInfo p2) {
   7959             final int v1 = p1.initOrder;
   7960             final int v2 = p2.initOrder;
   7961             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
   7962         }
   7963     };
   7964 
   7965     static final void sendPackageBroadcast(String action, String pkg,
   7966             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
   7967             int[] userIds) {
   7968         IActivityManager am = ActivityManagerNative.getDefault();
   7969         if (am != null) {
   7970             try {
   7971                 if (userIds == null) {
   7972                     userIds = am.getRunningUserIds();
   7973                 }
   7974                 for (int id : userIds) {
   7975                     final Intent intent = new Intent(action,
   7976                             pkg != null ? Uri.fromParts("package", pkg, null) : null);
   7977                     if (extras != null) {
   7978                         intent.putExtras(extras);
   7979                     }
   7980                     if (targetPkg != null) {
   7981                         intent.setPackage(targetPkg);
   7982                     }
   7983                     // Modify the UID when posting to other users
   7984                     int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
   7985                     if (uid > 0 && UserHandle.getUserId(uid) != id) {
   7986                         uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
   7987                         intent.putExtra(Intent.EXTRA_UID, uid);
   7988                     }
   7989                     intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
   7990                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
   7991                     if (DEBUG_BROADCASTS) {
   7992                         RuntimeException here = new RuntimeException("here");
   7993                         here.fillInStackTrace();
   7994                         Slog.d(TAG, "Sending to user " + id + ": "
   7995                                 + intent.toShortString(false, true, false, false)
   7996                                 + " " + intent.getExtras(), here);
   7997                     }
   7998                     am.broadcastIntent(null, intent, null, finishedReceiver,
   7999                             0, null, null, null, android.app.AppOpsManager.OP_NONE,
   8000                             finishedReceiver != null, false, id);
   8001                 }
   8002             } catch (RemoteException ex) {
   8003             }
   8004         }
   8005     }
   8006 
   8007     /**
   8008      * Check if the external storage media is available. This is true if there
   8009      * is a mounted external storage medium or if the external storage is
   8010      * emulated.
   8011      */
   8012     private boolean isExternalMediaAvailable() {
   8013         return mMediaMounted || Environment.isExternalStorageEmulated();
   8014     }
   8015 
   8016     @Override
   8017     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
   8018         // writer
   8019         synchronized (mPackages) {
   8020             if (!isExternalMediaAvailable()) {
   8021                 // If the external storage is no longer mounted at this point,
   8022                 // the caller may not have been able to delete all of this
   8023                 // packages files and can not delete any more.  Bail.
   8024                 return null;
   8025             }
   8026             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
   8027             if (lastPackage != null) {
   8028                 pkgs.remove(lastPackage);
   8029             }
   8030             if (pkgs.size() > 0) {
   8031                 return pkgs.get(0);
   8032             }
   8033         }
   8034         return null;
   8035     }
   8036 
   8037     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
   8038         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
   8039                 userId, andCode ? 1 : 0, packageName);
   8040         if (mSystemReady) {
   8041             msg.sendToTarget();
   8042         } else {
   8043             if (mPostSystemReadyMessages == null) {
   8044                 mPostSystemReadyMessages = new ArrayList<>();
   8045             }
   8046             mPostSystemReadyMessages.add(msg);
   8047         }
   8048     }
   8049 
   8050     void startCleaningPackages() {
   8051         // reader
   8052         synchronized (mPackages) {
   8053             if (!isExternalMediaAvailable()) {
   8054                 return;
   8055             }
   8056             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
   8057                 return;
   8058             }
   8059         }
   8060         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
   8061         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
   8062         IActivityManager am = ActivityManagerNative.getDefault();
   8063         if (am != null) {
   8064             try {
   8065                 am.startService(null, intent, null, UserHandle.USER_OWNER);
   8066             } catch (RemoteException e) {
   8067             }
   8068         }
   8069     }
   8070 
   8071     @Override
   8072     public void installPackage(String originPath, IPackageInstallObserver2 observer,
   8073             int installFlags, String installerPackageName, VerificationParams verificationParams,
   8074             String packageAbiOverride) {
   8075         installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams,
   8076                 packageAbiOverride, UserHandle.getCallingUserId());
   8077     }
   8078 
   8079     @Override
   8080     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
   8081             int installFlags, String installerPackageName, VerificationParams verificationParams,
   8082             String packageAbiOverride, int userId) {
   8083         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
   8084 
   8085         final int callingUid = Binder.getCallingUid();
   8086         enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
   8087 
   8088         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
   8089             try {
   8090                 if (observer != null) {
   8091                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
   8092                 }
   8093             } catch (RemoteException re) {
   8094             }
   8095             return;
   8096         }
   8097 
   8098         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
   8099             installFlags |= PackageManager.INSTALL_FROM_ADB;
   8100 
   8101         } else {
   8102             // Caller holds INSTALL_PACKAGES permission, so we're less strict
   8103             // about installerPackageName.
   8104 
   8105             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
   8106             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
   8107         }
   8108 
   8109         UserHandle user;
   8110         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
   8111             user = UserHandle.ALL;
   8112         } else {
   8113             user = new UserHandle(userId);
   8114         }
   8115 
   8116         verificationParams.setInstallerUid(callingUid);
   8117 
   8118         final File originFile = new File(originPath);
   8119         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
   8120 
   8121         final Message msg = mHandler.obtainMessage(INIT_COPY);
   8122         msg.obj = new InstallParams(origin, observer, installFlags,
   8123                 installerPackageName, verificationParams, user, packageAbiOverride);
   8124         mHandler.sendMessage(msg);
   8125     }
   8126 
   8127     void installStage(String packageName, File stagedDir, String stagedCid,
   8128             IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
   8129             String installerPackageName, int installerUid, UserHandle user) {
   8130         final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
   8131                 params.referrerUri, installerUid, null);
   8132 
   8133         final OriginInfo origin;
   8134         if (stagedDir != null) {
   8135             origin = OriginInfo.fromStagedFile(stagedDir);
   8136         } else {
   8137             origin = OriginInfo.fromStagedContainer(stagedCid);
   8138         }
   8139 
   8140         final Message msg = mHandler.obtainMessage(INIT_COPY);
   8141         msg.obj = new InstallParams(origin, observer, params.installFlags,
   8142                 installerPackageName, verifParams, user, params.abiOverride);
   8143         mHandler.sendMessage(msg);
   8144     }
   8145 
   8146     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
   8147         Bundle extras = new Bundle(1);
   8148         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
   8149 
   8150         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
   8151                 packageName, extras, null, null, new int[] {userId});
   8152         try {
   8153             IActivityManager am = ActivityManagerNative.getDefault();
   8154             final boolean isSystem =
   8155                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
   8156             if (isSystem && am.isUserRunning(userId, false)) {
   8157                 // The just-installed/enabled app is bundled on the system, so presumed
   8158                 // to be able to run automatically without needing an explicit launch.
   8159                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
   8160                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
   8161                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
   8162                         .setPackage(packageName);
   8163                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
   8164                         android.app.AppOpsManager.OP_NONE, false, false, userId);
   8165             }
   8166         } catch (RemoteException e) {
   8167             // shouldn't happen
   8168             Slog.w(TAG, "Unable to bootstrap installed package", e);
   8169         }
   8170     }
   8171 
   8172     @Override
   8173     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
   8174             int userId) {
   8175         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
   8176         PackageSetting pkgSetting;
   8177         final int uid = Binder.getCallingUid();
   8178         enforceCrossUserPermission(uid, userId, true, true,
   8179                 "setApplicationHiddenSetting for user " + userId);
   8180 
   8181         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
   8182             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
   8183             return false;
   8184         }
   8185 
   8186         long callingId = Binder.clearCallingIdentity();
   8187         try {
   8188             boolean sendAdded = false;
   8189             boolean sendRemoved = false;
   8190             // writer
   8191             synchronized (mPackages) {
   8192                 pkgSetting = mSettings.mPackages.get(packageName);
   8193                 if (pkgSetting == null) {
   8194                     return false;
   8195                 }
   8196                 if (pkgSetting.getHidden(userId) != hidden) {
   8197                     pkgSetting.setHidden(hidden, userId);
   8198                     mSettings.writePackageRestrictionsLPr(userId);
   8199                     if (hidden) {
   8200                         sendRemoved = true;
   8201                     } else {
   8202                         sendAdded = true;
   8203                     }
   8204                 }
   8205             }
   8206             if (sendAdded) {
   8207                 sendPackageAddedForUser(packageName, pkgSetting, userId);
   8208                 return true;
   8209             }
   8210             if (sendRemoved) {
   8211                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
   8212                         "hiding pkg");
   8213                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
   8214             }
   8215         } finally {
   8216             Binder.restoreCallingIdentity(callingId);
   8217         }
   8218         return false;
   8219     }
   8220 
   8221     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
   8222             int userId) {
   8223         final PackageRemovedInfo info = new PackageRemovedInfo();
   8224         info.removedPackage = packageName;
   8225         info.removedUsers = new int[] {userId};
   8226         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
   8227         info.sendBroadcast(false, false, false);
   8228     }
   8229 
   8230     /**
   8231      * Returns true if application is not found or there was an error. Otherwise it returns
   8232      * the hidden state of the package for the given user.
   8233      */
   8234     @Override
   8235     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
   8236         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
   8237         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
   8238                 false, "getApplicationHidden for user " + userId);
   8239         PackageSetting pkgSetting;
   8240         long callingId = Binder.clearCallingIdentity();
   8241         try {
   8242             // writer
   8243             synchronized (mPackages) {
   8244                 pkgSetting = mSettings.mPackages.get(packageName);
   8245                 if (pkgSetting == null) {
   8246                     return true;
   8247                 }
   8248                 return pkgSetting.getHidden(userId);
   8249             }
   8250         } finally {
   8251             Binder.restoreCallingIdentity(callingId);
   8252         }
   8253     }
   8254 
   8255     /**
   8256      * @hide
   8257      */
   8258     @Override
   8259     public int installExistingPackageAsUser(String packageName, int userId) {
   8260         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
   8261                 null);
   8262         PackageSetting pkgSetting;
   8263         final int uid = Binder.getCallingUid();
   8264         enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
   8265                 + userId);
   8266         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
   8267             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
   8268         }
   8269 
   8270         long callingId = Binder.clearCallingIdentity();
   8271         try {
   8272             boolean sendAdded = false;
   8273             Bundle extras = new Bundle(1);
   8274 
   8275             // writer
   8276             synchronized (mPackages) {
   8277                 pkgSetting = mSettings.mPackages.get(packageName);
   8278                 if (pkgSetting == null) {
   8279                     return PackageManager.INSTALL_FAILED_INVALID_URI;
   8280                 }
   8281                 if (!pkgSetting.getInstalled(userId)) {
   8282                     pkgSetting.setInstalled(true, userId);
   8283                     pkgSetting.setHidden(false, userId);
   8284                     mSettings.writePackageRestrictionsLPr(userId);
   8285                     sendAdded = true;
   8286                 }
   8287             }
   8288 
   8289             if (sendAdded) {
   8290                 sendPackageAddedForUser(packageName, pkgSetting, userId);
   8291             }
   8292         } finally {
   8293             Binder.restoreCallingIdentity(callingId);
   8294         }
   8295 
   8296         return PackageManager.INSTALL_SUCCEEDED;
   8297     }
   8298 
   8299     boolean isUserRestricted(int userId, String restrictionKey) {
   8300         Bundle restrictions = sUserManager.getUserRestrictions(userId);
   8301         if (restrictions.getBoolean(restrictionKey, false)) {
   8302             Log.w(TAG, "User is restricted: " + restrictionKey);
   8303             return true;
   8304         }
   8305         return false;
   8306     }
   8307 
   8308     @Override
   8309     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
   8310         mContext.enforceCallingOrSelfPermission(
   8311                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   8312                 "Only package verification agents can verify applications");
   8313 
   8314         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
   8315         final PackageVerificationResponse response = new PackageVerificationResponse(
   8316                 verificationCode, Binder.getCallingUid());
   8317         msg.arg1 = id;
   8318         msg.obj = response;
   8319         mHandler.sendMessage(msg);
   8320     }
   8321 
   8322     @Override
   8323     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
   8324             long millisecondsToDelay) {
   8325         mContext.enforceCallingOrSelfPermission(
   8326                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   8327                 "Only package verification agents can extend verification timeouts");
   8328 
   8329         final PackageVerificationState state = mPendingVerification.get(id);
   8330         final PackageVerificationResponse response = new PackageVerificationResponse(
   8331                 verificationCodeAtTimeout, Binder.getCallingUid());
   8332 
   8333         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
   8334             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
   8335         }
   8336         if (millisecondsToDelay < 0) {
   8337             millisecondsToDelay = 0;
   8338         }
   8339         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
   8340                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
   8341             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
   8342         }
   8343 
   8344         if ((state != null) && !state.timeoutExtended()) {
   8345             state.extendTimeout();
   8346 
   8347             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
   8348             msg.arg1 = id;
   8349             msg.obj = response;
   8350             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
   8351         }
   8352     }
   8353 
   8354     private void broadcastPackageVerified(int verificationId, Uri packageUri,
   8355             int verificationCode, UserHandle user) {
   8356         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
   8357         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
   8358         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   8359         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
   8360         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
   8361 
   8362         mContext.sendBroadcastAsUser(intent, user,
   8363                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
   8364     }
   8365 
   8366     private ComponentName matchComponentForVerifier(String packageName,
   8367             List<ResolveInfo> receivers) {
   8368         ActivityInfo targetReceiver = null;
   8369 
   8370         final int NR = receivers.size();
   8371         for (int i = 0; i < NR; i++) {
   8372             final ResolveInfo info = receivers.get(i);
   8373             if (info.activityInfo == null) {
   8374                 continue;
   8375             }
   8376 
   8377             if (packageName.equals(info.activityInfo.packageName)) {
   8378                 targetReceiver = info.activityInfo;
   8379                 break;
   8380             }
   8381         }
   8382 
   8383         if (targetReceiver == null) {
   8384             return null;
   8385         }
   8386 
   8387         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
   8388     }
   8389 
   8390     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
   8391             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
   8392         if (pkgInfo.verifiers.length == 0) {
   8393             return null;
   8394         }
   8395 
   8396         final int N = pkgInfo.verifiers.length;
   8397         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
   8398         for (int i = 0; i < N; i++) {
   8399             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
   8400 
   8401             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
   8402                     receivers);
   8403             if (comp == null) {
   8404                 continue;
   8405             }
   8406 
   8407             final int verifierUid = getUidForVerifier(verifierInfo);
   8408             if (verifierUid == -1) {
   8409                 continue;
   8410             }
   8411 
   8412             if (DEBUG_VERIFY) {
   8413                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
   8414                         + " with the correct signature");
   8415             }
   8416             sufficientVerifiers.add(comp);
   8417             verificationState.addSufficientVerifier(verifierUid);
   8418         }
   8419 
   8420         return sufficientVerifiers;
   8421     }
   8422 
   8423     private int getUidForVerifier(VerifierInfo verifierInfo) {
   8424         synchronized (mPackages) {
   8425             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
   8426             if (pkg == null) {
   8427                 return -1;
   8428             } else if (pkg.mSignatures.length != 1) {
   8429                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
   8430                         + " has more than one signature; ignoring");
   8431                 return -1;
   8432             }
   8433 
   8434             /*
   8435              * If the public key of the package's signature does not match
   8436              * our expected public key, then this is a different package and
   8437              * we should skip.
   8438              */
   8439 
   8440             final byte[] expectedPublicKey;
   8441             try {
   8442                 final Signature verifierSig = pkg.mSignatures[0];
   8443                 final PublicKey publicKey = verifierSig.getPublicKey();
   8444                 expectedPublicKey = publicKey.getEncoded();
   8445             } catch (CertificateException e) {
   8446                 return -1;
   8447             }
   8448 
   8449             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
   8450 
   8451             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
   8452                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
   8453                         + " does not have the expected public key; ignoring");
   8454                 return -1;
   8455             }
   8456 
   8457             return pkg.applicationInfo.uid;
   8458         }
   8459     }
   8460 
   8461     @Override
   8462     public void finishPackageInstall(int token) {
   8463         enforceSystemOrRoot("Only the system is allowed to finish installs");
   8464 
   8465         if (DEBUG_INSTALL) {
   8466             Slog.v(TAG, "BM finishing package install for " + token);
   8467         }
   8468 
   8469         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   8470         mHandler.sendMessage(msg);
   8471     }
   8472 
   8473     /**
   8474      * Get the verification agent timeout.
   8475      *
   8476      * @return verification timeout in milliseconds
   8477      */
   8478     private long getVerificationTimeout() {
   8479         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
   8480                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
   8481                 DEFAULT_VERIFICATION_TIMEOUT);
   8482     }
   8483 
   8484     /**
   8485      * Get the default verification agent response code.
   8486      *
   8487      * @return default verification response code
   8488      */
   8489     private int getDefaultVerificationResponse() {
   8490         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   8491                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
   8492                 DEFAULT_VERIFICATION_RESPONSE);
   8493     }
   8494 
   8495     /**
   8496      * Check whether or not package verification has been enabled.
   8497      *
   8498      * @return true if verification should be performed
   8499      */
   8500     private boolean isVerificationEnabled(int userId, int installFlags) {
   8501         if (!DEFAULT_VERIFY_ENABLE) {
   8502             return false;
   8503         }
   8504 
   8505         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
   8506 
   8507         // Check if installing from ADB
   8508         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
   8509             // Do not run verification in a test harness environment
   8510             if (ActivityManager.isRunningInTestHarness()) {
   8511                 return false;
   8512             }
   8513             if (ensureVerifyAppsEnabled) {
   8514                 return true;
   8515             }
   8516             // Check if the developer does not want package verification for ADB installs
   8517             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   8518                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
   8519                 return false;
   8520             }
   8521         }
   8522 
   8523         if (ensureVerifyAppsEnabled) {
   8524             return true;
   8525         }
   8526 
   8527         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   8528                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
   8529     }
   8530 
   8531     /**
   8532      * Get the "allow unknown sources" setting.
   8533      *
   8534      * @return the current "allow unknown sources" setting
   8535      */
   8536     private int getUnknownSourcesSettings() {
   8537         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   8538                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
   8539                 -1);
   8540     }
   8541 
   8542     @Override
   8543     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
   8544         final int uid = Binder.getCallingUid();
   8545         // writer
   8546         synchronized (mPackages) {
   8547             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
   8548             if (targetPackageSetting == null) {
   8549                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
   8550             }
   8551 
   8552             PackageSetting installerPackageSetting;
   8553             if (installerPackageName != null) {
   8554                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
   8555                 if (installerPackageSetting == null) {
   8556                     throw new IllegalArgumentException("Unknown installer package: "
   8557                             + installerPackageName);
   8558                 }
   8559             } else {
   8560                 installerPackageSetting = null;
   8561             }
   8562 
   8563             Signature[] callerSignature;
   8564             Object obj = mSettings.getUserIdLPr(uid);
   8565             if (obj != null) {
   8566                 if (obj instanceof SharedUserSetting) {
   8567                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
   8568                 } else if (obj instanceof PackageSetting) {
   8569                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
   8570                 } else {
   8571                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
   8572                 }
   8573             } else {
   8574                 throw new SecurityException("Unknown calling uid " + uid);
   8575             }
   8576 
   8577             // Verify: can't set installerPackageName to a package that is
   8578             // not signed with the same cert as the caller.
   8579             if (installerPackageSetting != null) {
   8580                 if (compareSignatures(callerSignature,
   8581                         installerPackageSetting.signatures.mSignatures)
   8582                         != PackageManager.SIGNATURE_MATCH) {
   8583                     throw new SecurityException(
   8584                             "Caller does not have same cert as new installer package "
   8585                             + installerPackageName);
   8586                 }
   8587             }
   8588 
   8589             // Verify: if target already has an installer package, it must
   8590             // be signed with the same cert as the caller.
   8591             if (targetPackageSetting.installerPackageName != null) {
   8592                 PackageSetting setting = mSettings.mPackages.get(
   8593                         targetPackageSetting.installerPackageName);
   8594                 // If the currently set package isn't valid, then it's always
   8595                 // okay to change it.
   8596                 if (setting != null) {
   8597                     if (compareSignatures(callerSignature,
   8598                             setting.signatures.mSignatures)
   8599                             != PackageManager.SIGNATURE_MATCH) {
   8600                         throw new SecurityException(
   8601                                 "Caller does not have same cert as old installer package "
   8602                                 + targetPackageSetting.installerPackageName);
   8603                     }
   8604                 }
   8605             }
   8606 
   8607             // Okay!
   8608             targetPackageSetting.installerPackageName = installerPackageName;
   8609             scheduleWriteSettingsLocked();
   8610         }
   8611     }
   8612 
   8613     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
   8614         // Queue up an async operation since the package installation may take a little while.
   8615         mHandler.post(new Runnable() {
   8616             public void run() {
   8617                 mHandler.removeCallbacks(this);
   8618                  // Result object to be returned
   8619                 PackageInstalledInfo res = new PackageInstalledInfo();
   8620                 res.returnCode = currentStatus;
   8621                 res.uid = -1;
   8622                 res.pkg = null;
   8623                 res.removedInfo = new PackageRemovedInfo();
   8624                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   8625                     args.doPreInstall(res.returnCode);
   8626                     synchronized (mInstallLock) {
   8627                         installPackageLI(args, res);
   8628                     }
   8629                     args.doPostInstall(res.returnCode, res.uid);
   8630                 }
   8631 
   8632                 // A restore should be performed at this point if (a) the install
   8633                 // succeeded, (b) the operation is not an update, and (c) the new
   8634                 // package has not opted out of backup participation.
   8635                 final boolean update = res.removedInfo.removedPackage != null;
   8636                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
   8637                 boolean doRestore = !update
   8638                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
   8639 
   8640                 // Set up the post-install work request bookkeeping.  This will be used
   8641                 // and cleaned up by the post-install event handling regardless of whether
   8642                 // there's a restore pass performed.  Token values are >= 1.
   8643                 int token;
   8644                 if (mNextInstallToken < 0) mNextInstallToken = 1;
   8645                 token = mNextInstallToken++;
   8646 
   8647                 PostInstallData data = new PostInstallData(args, res);
   8648                 mRunningInstalls.put(token, data);
   8649                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
   8650 
   8651                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
   8652                     // Pass responsibility to the Backup Manager.  It will perform a
   8653                     // restore if appropriate, then pass responsibility back to the
   8654                     // Package Manager to run the post-install observer callbacks
   8655                     // and broadcasts.
   8656                     IBackupManager bm = IBackupManager.Stub.asInterface(
   8657                             ServiceManager.getService(Context.BACKUP_SERVICE));
   8658                     if (bm != null) {
   8659                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
   8660                                 + " to BM for possible restore");
   8661                         try {
   8662                             if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) {
   8663                                 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
   8664                             } else {
   8665                                 doRestore = false;
   8666                             }
   8667                         } catch (RemoteException e) {
   8668                             // can't happen; the backup manager is local
   8669                         } catch (Exception e) {
   8670                             Slog.e(TAG, "Exception trying to enqueue restore", e);
   8671                             doRestore = false;
   8672                         }
   8673                     } else {
   8674                         Slog.e(TAG, "Backup Manager not found!");
   8675                         doRestore = false;
   8676                     }
   8677                 }
   8678 
   8679                 if (!doRestore) {
   8680                     // No restore possible, or the Backup Manager was mysteriously not
   8681                     // available -- just fire the post-install work request directly.
   8682                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
   8683                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   8684                     mHandler.sendMessage(msg);
   8685                 }
   8686             }
   8687         });
   8688     }
   8689 
   8690     private abstract class HandlerParams {
   8691         private static final int MAX_RETRIES = 4;
   8692 
   8693         /**
   8694          * Number of times startCopy() has been attempted and had a non-fatal
   8695          * error.
   8696          */
   8697         private int mRetries = 0;
   8698 
   8699         /** User handle for the user requesting the information or installation. */
   8700         private final UserHandle mUser;
   8701 
   8702         HandlerParams(UserHandle user) {
   8703             mUser = user;
   8704         }
   8705 
   8706         UserHandle getUser() {
   8707             return mUser;
   8708         }
   8709 
   8710         final boolean startCopy() {
   8711             boolean res;
   8712             try {
   8713                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
   8714 
   8715                 if (++mRetries > MAX_RETRIES) {
   8716                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
   8717                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
   8718                     handleServiceError();
   8719                     return false;
   8720                 } else {
   8721                     handleStartCopy();
   8722                     res = true;
   8723                 }
   8724             } catch (RemoteException e) {
   8725                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
   8726                 mHandler.sendEmptyMessage(MCS_RECONNECT);
   8727                 res = false;
   8728             }
   8729             handleReturnCode();
   8730             return res;
   8731         }
   8732 
   8733         final void serviceError() {
   8734             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
   8735             handleServiceError();
   8736             handleReturnCode();
   8737         }
   8738 
   8739         abstract void handleStartCopy() throws RemoteException;
   8740         abstract void handleServiceError();
   8741         abstract void handleReturnCode();
   8742     }
   8743 
   8744     class MeasureParams extends HandlerParams {
   8745         private final PackageStats mStats;
   8746         private boolean mSuccess;
   8747 
   8748         private final IPackageStatsObserver mObserver;
   8749 
   8750         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
   8751             super(new UserHandle(stats.userHandle));
   8752             mObserver = observer;
   8753             mStats = stats;
   8754         }
   8755 
   8756         @Override
   8757         public String toString() {
   8758             return "MeasureParams{"
   8759                 + Integer.toHexString(System.identityHashCode(this))
   8760                 + " " + mStats.packageName + "}";
   8761         }
   8762 
   8763         @Override
   8764         void handleStartCopy() throws RemoteException {
   8765             synchronized (mInstallLock) {
   8766                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
   8767             }
   8768 
   8769             if (mSuccess) {
   8770                 final boolean mounted;
   8771                 if (Environment.isExternalStorageEmulated()) {
   8772                     mounted = true;
   8773                 } else {
   8774                     final String status = Environment.getExternalStorageState();
   8775                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
   8776                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
   8777                 }
   8778 
   8779                 if (mounted) {
   8780                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
   8781 
   8782                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
   8783                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
   8784 
   8785                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
   8786                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
   8787 
   8788                     // Always subtract cache size, since it's a subdirectory
   8789                     mStats.externalDataSize -= mStats.externalCacheSize;
   8790 
   8791                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
   8792                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
   8793 
   8794                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
   8795                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
   8796                 }
   8797             }
   8798         }
   8799 
   8800         @Override
   8801         void handleReturnCode() {
   8802             if (mObserver != null) {
   8803                 try {
   8804                     mObserver.onGetStatsCompleted(mStats, mSuccess);
   8805                 } catch (RemoteException e) {
   8806                     Slog.i(TAG, "Observer no longer exists.");
   8807                 }
   8808             }
   8809         }
   8810 
   8811         @Override
   8812         void handleServiceError() {
   8813             Slog.e(TAG, "Could not measure application " + mStats.packageName
   8814                             + " external storage");
   8815         }
   8816     }
   8817 
   8818     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
   8819             throws RemoteException {
   8820         long result = 0;
   8821         for (File path : paths) {
   8822             result += mcs.calculateDirectorySize(path.getAbsolutePath());
   8823         }
   8824         return result;
   8825     }
   8826 
   8827     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
   8828         for (File path : paths) {
   8829             try {
   8830                 mcs.clearDirectory(path.getAbsolutePath());
   8831             } catch (RemoteException e) {
   8832             }
   8833         }
   8834     }
   8835 
   8836     static class OriginInfo {
   8837         /**
   8838          * Location where install is coming from, before it has been
   8839          * copied/renamed into place. This could be a single monolithic APK
   8840          * file, or a cluster directory. This location may be untrusted.
   8841          */
   8842         final File file;
   8843         final String cid;
   8844 
   8845         /**
   8846          * Flag indicating that {@link #file} or {@link #cid} has already been
   8847          * staged, meaning downstream users don't need to defensively copy the
   8848          * contents.
   8849          */
   8850         final boolean staged;
   8851 
   8852         /**
   8853          * Flag indicating that {@link #file} or {@link #cid} is an already
   8854          * installed app that is being moved.
   8855          */
   8856         final boolean existing;
   8857 
   8858         final String resolvedPath;
   8859         final File resolvedFile;
   8860 
   8861         static OriginInfo fromNothing() {
   8862             return new OriginInfo(null, null, false, false);
   8863         }
   8864 
   8865         static OriginInfo fromUntrustedFile(File file) {
   8866             return new OriginInfo(file, null, false, false);
   8867         }
   8868 
   8869         static OriginInfo fromExistingFile(File file) {
   8870             return new OriginInfo(file, null, false, true);
   8871         }
   8872 
   8873         static OriginInfo fromStagedFile(File file) {
   8874             return new OriginInfo(file, null, true, false);
   8875         }
   8876 
   8877         static OriginInfo fromStagedContainer(String cid) {
   8878             return new OriginInfo(null, cid, true, false);
   8879         }
   8880 
   8881         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
   8882             this.file = file;
   8883             this.cid = cid;
   8884             this.staged = staged;
   8885             this.existing = existing;
   8886 
   8887             if (cid != null) {
   8888                 resolvedPath = PackageHelper.getSdDir(cid);
   8889                 resolvedFile = new File(resolvedPath);
   8890             } else if (file != null) {
   8891                 resolvedPath = file.getAbsolutePath();
   8892                 resolvedFile = file;
   8893             } else {
   8894                 resolvedPath = null;
   8895                 resolvedFile = null;
   8896             }
   8897         }
   8898     }
   8899 
   8900     class InstallParams extends HandlerParams {
   8901         final OriginInfo origin;
   8902         final IPackageInstallObserver2 observer;
   8903         int installFlags;
   8904         final String installerPackageName;
   8905         final VerificationParams verificationParams;
   8906         private InstallArgs mArgs;
   8907         private int mRet;
   8908         final String packageAbiOverride;
   8909 
   8910         InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
   8911                 String installerPackageName, VerificationParams verificationParams, UserHandle user,
   8912                 String packageAbiOverride) {
   8913             super(user);
   8914             this.origin = origin;
   8915             this.observer = observer;
   8916             this.installFlags = installFlags;
   8917             this.installerPackageName = installerPackageName;
   8918             this.verificationParams = verificationParams;
   8919             this.packageAbiOverride = packageAbiOverride;
   8920         }
   8921 
   8922         @Override
   8923         public String toString() {
   8924             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
   8925                     + " file=" + origin.file + " cid=" + origin.cid + "}";
   8926         }
   8927 
   8928         public ManifestDigest getManifestDigest() {
   8929             if (verificationParams == null) {
   8930                 return null;
   8931             }
   8932             return verificationParams.getManifestDigest();
   8933         }
   8934 
   8935         private int installLocationPolicy(PackageInfoLite pkgLite) {
   8936             String packageName = pkgLite.packageName;
   8937             int installLocation = pkgLite.installLocation;
   8938             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   8939             // reader
   8940             synchronized (mPackages) {
   8941                 PackageParser.Package pkg = mPackages.get(packageName);
   8942                 if (pkg != null) {
   8943                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   8944                         // Check for downgrading.
   8945                         if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
   8946                             try {
   8947                                 checkDowngrade(pkg, pkgLite);
   8948                             } catch (PackageManagerException e) {
   8949                                 Slog.w(TAG, "Downgrade detected: " + e.getMessage());
   8950                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
   8951                             }
   8952                         }
   8953                         // Check for updated system application.
   8954                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   8955                             if (onSd) {
   8956                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
   8957                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
   8958                             }
   8959                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   8960                         } else {
   8961                             if (onSd) {
   8962                                 // Install flag overrides everything.
   8963                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   8964                             }
   8965                             // If current upgrade specifies particular preference
   8966                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
   8967                                 // Application explicitly specified internal.
   8968                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   8969                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
   8970                                 // App explictly prefers external. Let policy decide
   8971                             } else {
   8972                                 // Prefer previous location
   8973                                 if (isExternal(pkg)) {
   8974                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   8975                                 }
   8976                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   8977                             }
   8978                         }
   8979                     } else {
   8980                         // Invalid install. Return error code
   8981                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
   8982                     }
   8983                 }
   8984             }
   8985             // All the special cases have been taken care of.
   8986             // Return result based on recommended install location.
   8987             if (onSd) {
   8988                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   8989             }
   8990             return pkgLite.recommendedInstallLocation;
   8991         }
   8992 
   8993         /*
   8994          * Invoke remote method to get package information and install
   8995          * location values. Override install location based on default
   8996          * policy if needed and then create install arguments based
   8997          * on the install location.
   8998          */
   8999         public void handleStartCopy() throws RemoteException {
   9000             int ret = PackageManager.INSTALL_SUCCEEDED;
   9001 
   9002             // If we're already staged, we've firmly committed to an install location
   9003             if (origin.staged) {
   9004                 if (origin.file != null) {
   9005                     installFlags |= PackageManager.INSTALL_INTERNAL;
   9006                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
   9007                 } else if (origin.cid != null) {
   9008                     installFlags |= PackageManager.INSTALL_EXTERNAL;
   9009                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
   9010                 } else {
   9011                     throw new IllegalStateException("Invalid stage location");
   9012                 }
   9013             }
   9014 
   9015             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   9016             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
   9017 
   9018             PackageInfoLite pkgLite = null;
   9019 
   9020             if (onInt && onSd) {
   9021                 // Check if both bits are set.
   9022                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
   9023                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   9024             } else {
   9025                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
   9026                         packageAbiOverride);
   9027 
   9028                 /*
   9029                  * If we have too little free space, try to free cache
   9030                  * before giving up.
   9031                  */
   9032                 if (!origin.staged && pkgLite.recommendedInstallLocation
   9033                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
   9034                     // TODO: focus freeing disk space on the target device
   9035                     final StorageManager storage = StorageManager.from(mContext);
   9036                     final long lowThreshold = storage.getStorageLowBytes(
   9037                             Environment.getDataDirectory());
   9038 
   9039                     final long sizeBytes = mContainerService.calculateInstalledSize(
   9040                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
   9041 
   9042                     if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) {
   9043                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
   9044                                 installFlags, packageAbiOverride);
   9045                     }
   9046 
   9047                     /*
   9048                      * The cache free must have deleted the file we
   9049                      * downloaded to install.
   9050                      *
   9051                      * TODO: fix the "freeCache" call to not delete
   9052                      *       the file we care about.
   9053                      */
   9054                     if (pkgLite.recommendedInstallLocation
   9055                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
   9056                         pkgLite.recommendedInstallLocation
   9057                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
   9058                     }
   9059                 }
   9060             }
   9061 
   9062             if (ret == PackageManager.INSTALL_SUCCEEDED) {
   9063                 int loc = pkgLite.recommendedInstallLocation;
   9064                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
   9065                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   9066                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
   9067                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   9068                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
   9069                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   9070                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
   9071                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
   9072                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
   9073                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
   9074                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
   9075                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
   9076                 } else {
   9077                     // Override with defaults if needed.
   9078                     loc = installLocationPolicy(pkgLite);
   9079                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
   9080                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
   9081                     } else if (!onSd && !onInt) {
   9082                         // Override install location with flags
   9083                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
   9084                             // Set the flag to install on external media.
   9085                             installFlags |= PackageManager.INSTALL_EXTERNAL;
   9086                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
   9087                         } else {
   9088                             // Make sure the flag for installing on external
   9089                             // media is unset
   9090                             installFlags |= PackageManager.INSTALL_INTERNAL;
   9091                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
   9092                         }
   9093                     }
   9094                 }
   9095             }
   9096 
   9097             final InstallArgs args = createInstallArgs(this);
   9098             mArgs = args;
   9099 
   9100             if (ret == PackageManager.INSTALL_SUCCEEDED) {
   9101                  /*
   9102                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
   9103                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
   9104                  */
   9105                 int userIdentifier = getUser().getIdentifier();
   9106                 if (userIdentifier == UserHandle.USER_ALL
   9107                         && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
   9108                     userIdentifier = UserHandle.USER_OWNER;
   9109                 }
   9110 
   9111                 /*
   9112                  * Determine if we have any installed package verifiers. If we
   9113                  * do, then we'll defer to them to verify the packages.
   9114                  */
   9115                 final int requiredUid = mRequiredVerifierPackage == null ? -1
   9116                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
   9117                 if (!origin.existing && requiredUid != -1
   9118                         && isVerificationEnabled(userIdentifier, installFlags)) {
   9119                     final Intent verification = new Intent(
   9120                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
   9121                     verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
   9122                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
   9123                             PACKAGE_MIME_TYPE);
   9124                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   9125 
   9126                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
   9127                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
   9128                             0 /* TODO: Which userId? */);
   9129 
   9130                     if (DEBUG_VERIFY) {
   9131                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
   9132                                 + verification.toString() + " with " + pkgLite.verifiers.length
   9133                                 + " optional verifiers");
   9134                     }
   9135 
   9136                     final int verificationId = mPendingVerificationToken++;
   9137 
   9138                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
   9139 
   9140                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
   9141                             installerPackageName);
   9142 
   9143                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
   9144                             installFlags);
   9145 
   9146                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
   9147                             pkgLite.packageName);
   9148 
   9149                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
   9150                             pkgLite.versionCode);
   9151 
   9152                     if (verificationParams != null) {
   9153                         if (verificationParams.getVerificationURI() != null) {
   9154                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
   9155                                  verificationParams.getVerificationURI());
   9156                         }
   9157                         if (verificationParams.getOriginatingURI() != null) {
   9158                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
   9159                                   verificationParams.getOriginatingURI());
   9160                         }
   9161                         if (verificationParams.getReferrer() != null) {
   9162                             verification.putExtra(Intent.EXTRA_REFERRER,
   9163                                   verificationParams.getReferrer());
   9164                         }
   9165                         if (verificationParams.getOriginatingUid() >= 0) {
   9166                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
   9167                                   verificationParams.getOriginatingUid());
   9168                         }
   9169                         if (verificationParams.getInstallerUid() >= 0) {
   9170                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
   9171                                   verificationParams.getInstallerUid());
   9172                         }
   9173                     }
   9174 
   9175                     final PackageVerificationState verificationState = new PackageVerificationState(
   9176                             requiredUid, args);
   9177 
   9178                     mPendingVerification.append(verificationId, verificationState);
   9179 
   9180                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
   9181                             receivers, verificationState);
   9182 
   9183                     /*
   9184                      * If any sufficient verifiers were listed in the package
   9185                      * manifest, attempt to ask them.
   9186                      */
   9187                     if (sufficientVerifiers != null) {
   9188                         final int N = sufficientVerifiers.size();
   9189                         if (N == 0) {
   9190                             Slog.i(TAG, "Additional verifiers required, but none installed.");
   9191                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   9192                         } else {
   9193                             for (int i = 0; i < N; i++) {
   9194                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
   9195 
   9196                                 final Intent sufficientIntent = new Intent(verification);
   9197                                 sufficientIntent.setComponent(verifierComponent);
   9198 
   9199                                 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
   9200                             }
   9201                         }
   9202                     }
   9203 
   9204                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
   9205                             mRequiredVerifierPackage, receivers);
   9206                     if (ret == PackageManager.INSTALL_SUCCEEDED
   9207                             && mRequiredVerifierPackage != null) {
   9208                         /*
   9209                          * Send the intent to the required verification agent,
   9210                          * but only start the verification timeout after the
   9211                          * target BroadcastReceivers have run.
   9212                          */
   9213                         verification.setComponent(requiredVerifierComponent);
   9214                         mContext.sendOrderedBroadcastAsUser(verification, getUser(),
   9215                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   9216                                 new BroadcastReceiver() {
   9217                                     @Override
   9218                                     public void onReceive(Context context, Intent intent) {
   9219                                         final Message msg = mHandler
   9220                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
   9221                                         msg.arg1 = verificationId;
   9222                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
   9223                                     }
   9224                                 }, null, 0, null, null);
   9225 
   9226                         /*
   9227                          * We don't want the copy to proceed until verification
   9228                          * succeeds, so null out this field.
   9229                          */
   9230                         mArgs = null;
   9231                     }
   9232                 } else {
   9233                     /*
   9234                      * No package verification is enabled, so immediately start
   9235                      * the remote call to initiate copy using temporary file.
   9236                      */
   9237                     ret = args.copyApk(mContainerService, true);
   9238                 }
   9239             }
   9240 
   9241             mRet = ret;
   9242         }
   9243 
   9244         @Override
   9245         void handleReturnCode() {
   9246             // If mArgs is null, then MCS couldn't be reached. When it
   9247             // reconnects, it will try again to install. At that point, this
   9248             // will succeed.
   9249             if (mArgs != null) {
   9250                 processPendingInstall(mArgs, mRet);
   9251             }
   9252         }
   9253 
   9254         @Override
   9255         void handleServiceError() {
   9256             mArgs = createInstallArgs(this);
   9257             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   9258         }
   9259 
   9260         public boolean isForwardLocked() {
   9261             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   9262         }
   9263     }
   9264 
   9265     /**
   9266      * Used during creation of InstallArgs
   9267      *
   9268      * @param installFlags package installation flags
   9269      * @return true if should be installed on external storage
   9270      */
   9271     private static boolean installOnSd(int installFlags) {
   9272         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
   9273             return false;
   9274         }
   9275         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
   9276             return true;
   9277         }
   9278         return false;
   9279     }
   9280 
   9281     /**
   9282      * Used during creation of InstallArgs
   9283      *
   9284      * @param installFlags package installation flags
   9285      * @return true if should be installed as forward locked
   9286      */
   9287     private static boolean installForwardLocked(int installFlags) {
   9288         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   9289     }
   9290 
   9291     private InstallArgs createInstallArgs(InstallParams params) {
   9292         if (installOnSd(params.installFlags) || params.isForwardLocked()) {
   9293             return new AsecInstallArgs(params);
   9294         } else {
   9295             return new FileInstallArgs(params);
   9296         }
   9297     }
   9298 
   9299     /**
   9300      * Create args that describe an existing installed package. Typically used
   9301      * when cleaning up old installs, or used as a move source.
   9302      */
   9303     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
   9304             String resourcePath, String nativeLibraryRoot, String[] instructionSets) {
   9305         final boolean isInAsec;
   9306         if (installOnSd(installFlags)) {
   9307             /* Apps on SD card are always in ASEC containers. */
   9308             isInAsec = true;
   9309         } else if (installForwardLocked(installFlags)
   9310                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
   9311             /*
   9312              * Forward-locked apps are only in ASEC containers if they're the
   9313              * new style
   9314              */
   9315             isInAsec = true;
   9316         } else {
   9317             isInAsec = false;
   9318         }
   9319 
   9320         if (isInAsec) {
   9321             return new AsecInstallArgs(codePath, instructionSets,
   9322                     installOnSd(installFlags), installForwardLocked(installFlags));
   9323         } else {
   9324             return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot,
   9325                     instructionSets);
   9326         }
   9327     }
   9328 
   9329     static abstract class InstallArgs {
   9330         /** @see InstallParams#origin */
   9331         final OriginInfo origin;
   9332 
   9333         final IPackageInstallObserver2 observer;
   9334         // Always refers to PackageManager flags only
   9335         final int installFlags;
   9336         final String installerPackageName;
   9337         final ManifestDigest manifestDigest;
   9338         final UserHandle user;
   9339         final String abiOverride;
   9340 
   9341         // The list of instruction sets supported by this app. This is currently
   9342         // only used during the rmdex() phase to clean up resources. We can get rid of this
   9343         // if we move dex files under the common app path.
   9344         /* nullable */ String[] instructionSets;
   9345 
   9346         InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
   9347                 String installerPackageName, ManifestDigest manifestDigest, UserHandle user,
   9348                 String[] instructionSets, String abiOverride) {
   9349             this.origin = origin;
   9350             this.installFlags = installFlags;
   9351             this.observer = observer;
   9352             this.installerPackageName = installerPackageName;
   9353             this.manifestDigest = manifestDigest;
   9354             this.user = user;
   9355             this.instructionSets = instructionSets;
   9356             this.abiOverride = abiOverride;
   9357         }
   9358 
   9359         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
   9360         abstract int doPreInstall(int status);
   9361 
   9362         /**
   9363          * Rename package into final resting place. All paths on the given
   9364          * scanned package should be updated to reflect the rename.
   9365          */
   9366         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
   9367         abstract int doPostInstall(int status, int uid);
   9368 
   9369         /** @see PackageSettingBase#codePathString */
   9370         abstract String getCodePath();
   9371         /** @see PackageSettingBase#resourcePathString */
   9372         abstract String getResourcePath();
   9373         abstract String getLegacyNativeLibraryPath();
   9374 
   9375         // Need installer lock especially for dex file removal.
   9376         abstract void cleanUpResourcesLI();
   9377         abstract boolean doPostDeleteLI(boolean delete);
   9378         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
   9379 
   9380         /**
   9381          * Called before the source arguments are copied. This is used mostly
   9382          * for MoveParams when it needs to read the source file to put it in the
   9383          * destination.
   9384          */
   9385         int doPreCopy() {
   9386             return PackageManager.INSTALL_SUCCEEDED;
   9387         }
   9388 
   9389         /**
   9390          * Called after the source arguments are copied. This is used mostly for
   9391          * MoveParams when it needs to read the source file to put it in the
   9392          * destination.
   9393          *
   9394          * @return
   9395          */
   9396         int doPostCopy(int uid) {
   9397             return PackageManager.INSTALL_SUCCEEDED;
   9398         }
   9399 
   9400         protected boolean isFwdLocked() {
   9401             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   9402         }
   9403 
   9404         protected boolean isExternal() {
   9405             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   9406         }
   9407 
   9408         UserHandle getUser() {
   9409             return user;
   9410         }
   9411     }
   9412 
   9413     /**
   9414      * Logic to handle installation of non-ASEC applications, including copying
   9415      * and renaming logic.
   9416      */
   9417     class FileInstallArgs extends InstallArgs {
   9418         private File codeFile;
   9419         private File resourceFile;
   9420         private File legacyNativeLibraryPath;
   9421 
   9422         // Example topology:
   9423         // /data/app/com.example/base.apk
   9424         // /data/app/com.example/split_foo.apk
   9425         // /data/app/com.example/lib/arm/libfoo.so
   9426         // /data/app/com.example/lib/arm64/libfoo.so
   9427         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
   9428 
   9429         /** New install */
   9430         FileInstallArgs(InstallParams params) {
   9431             super(params.origin, params.observer, params.installFlags,
   9432                     params.installerPackageName, params.getManifestDigest(), params.getUser(),
   9433                     null /* instruction sets */, params.packageAbiOverride);
   9434             if (isFwdLocked()) {
   9435                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
   9436             }
   9437         }
   9438 
   9439         /** Existing install */
   9440         FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath,
   9441                 String[] instructionSets) {
   9442             super(OriginInfo.fromNothing(), null, 0, null, null, null, instructionSets, null);
   9443             this.codeFile = (codePath != null) ? new File(codePath) : null;
   9444             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
   9445             this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ?
   9446                     new File(legacyNativeLibraryPath) : null;
   9447         }
   9448 
   9449         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
   9450             final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(),
   9451                     isFwdLocked(), abiOverride);
   9452 
   9453             final StorageManager storage = StorageManager.from(mContext);
   9454             return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
   9455         }
   9456 
   9457         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   9458             if (origin.staged) {
   9459                 Slog.d(TAG, origin.file + " already staged; skipping copy");
   9460                 codeFile = origin.file;
   9461                 resourceFile = origin.file;
   9462                 return PackageManager.INSTALL_SUCCEEDED;
   9463             }
   9464 
   9465             try {
   9466                 final File tempDir = mInstallerService.allocateInternalStageDirLegacy();
   9467                 codeFile = tempDir;
   9468                 resourceFile = tempDir;
   9469             } catch (IOException e) {
   9470                 Slog.w(TAG, "Failed to create copy file: " + e);
   9471                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   9472             }
   9473 
   9474             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
   9475                 @Override
   9476                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
   9477                     if (!FileUtils.isValidExtFilename(name)) {
   9478                         throw new IllegalArgumentException("Invalid filename: " + name);
   9479                     }
   9480                     try {
   9481                         final File file = new File(codeFile, name);
   9482                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
   9483                                 O_RDWR | O_CREAT, 0644);
   9484                         Os.chmod(file.getAbsolutePath(), 0644);
   9485                         return new ParcelFileDescriptor(fd);
   9486                     } catch (ErrnoException e) {
   9487                         throw new RemoteException("Failed to open: " + e.getMessage());
   9488                     }
   9489                 }
   9490             };
   9491 
   9492             int ret = PackageManager.INSTALL_SUCCEEDED;
   9493             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
   9494             if (ret != PackageManager.INSTALL_SUCCEEDED) {
   9495                 Slog.e(TAG, "Failed to copy package");
   9496                 return ret;
   9497             }
   9498 
   9499             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
   9500             NativeLibraryHelper.Handle handle = null;
   9501             try {
   9502                 handle = NativeLibraryHelper.Handle.create(codeFile);
   9503                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
   9504                         abiOverride);
   9505             } catch (IOException e) {
   9506                 Slog.e(TAG, "Copying native libraries failed", e);
   9507                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   9508             } finally {
   9509                 IoUtils.closeQuietly(handle);
   9510             }
   9511 
   9512             return ret;
   9513         }
   9514 
   9515         int doPreInstall(int status) {
   9516             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9517                 cleanUp();
   9518             }
   9519             return status;
   9520         }
   9521 
   9522         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
   9523             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9524                 cleanUp();
   9525                 return false;
   9526             } else {
   9527                 final File beforeCodeFile = codeFile;
   9528                 final File afterCodeFile = getNextCodePath(pkg.packageName);
   9529 
   9530                 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
   9531                 try {
   9532                     Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
   9533                 } catch (ErrnoException e) {
   9534                     Slog.d(TAG, "Failed to rename", e);
   9535                     return false;
   9536                 }
   9537 
   9538                 if (!SELinux.restoreconRecursive(afterCodeFile)) {
   9539                     Slog.d(TAG, "Failed to restorecon");
   9540                     return false;
   9541                 }
   9542 
   9543                 // Reflect the rename internally
   9544                 codeFile = afterCodeFile;
   9545                 resourceFile = afterCodeFile;
   9546 
   9547                 // Reflect the rename in scanned details
   9548                 pkg.codePath = afterCodeFile.getAbsolutePath();
   9549                 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
   9550                         pkg.baseCodePath);
   9551                 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
   9552                         pkg.splitCodePaths);
   9553 
   9554                 // Reflect the rename in app info
   9555                 pkg.applicationInfo.setCodePath(pkg.codePath);
   9556                 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
   9557                 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
   9558                 pkg.applicationInfo.setResourcePath(pkg.codePath);
   9559                 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
   9560                 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
   9561 
   9562                 return true;
   9563             }
   9564         }
   9565 
   9566         int doPostInstall(int status, int uid) {
   9567             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9568                 cleanUp();
   9569             }
   9570             return status;
   9571         }
   9572 
   9573         @Override
   9574         String getCodePath() {
   9575             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
   9576         }
   9577 
   9578         @Override
   9579         String getResourcePath() {
   9580             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
   9581         }
   9582 
   9583         @Override
   9584         String getLegacyNativeLibraryPath() {
   9585             return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null;
   9586         }
   9587 
   9588         private boolean cleanUp() {
   9589             if (codeFile == null || !codeFile.exists()) {
   9590                 return false;
   9591             }
   9592 
   9593             if (codeFile.isDirectory()) {
   9594                 FileUtils.deleteContents(codeFile);
   9595             }
   9596             codeFile.delete();
   9597 
   9598             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
   9599                 resourceFile.delete();
   9600             }
   9601 
   9602             if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) {
   9603                 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) {
   9604                     Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath);
   9605                 }
   9606                 legacyNativeLibraryPath.delete();
   9607             }
   9608 
   9609             return true;
   9610         }
   9611 
   9612         void cleanUpResourcesLI() {
   9613             // Try enumerating all code paths before deleting
   9614             List<String> allCodePaths = Collections.EMPTY_LIST;
   9615             if (codeFile != null && codeFile.exists()) {
   9616                 try {
   9617                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
   9618                     allCodePaths = pkg.getAllCodePaths();
   9619                 } catch (PackageParserException e) {
   9620                     // Ignored; we tried our best
   9621                 }
   9622             }
   9623 
   9624             cleanUp();
   9625 
   9626             if (!allCodePaths.isEmpty()) {
   9627                 if (instructionSets == null) {
   9628                     throw new IllegalStateException("instructionSet == null");
   9629                 }
   9630                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
   9631                 for (String codePath : allCodePaths) {
   9632                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   9633                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
   9634                         if (retCode < 0) {
   9635                             Slog.w(TAG, "Couldn't remove dex file for package: "
   9636                                     + " at location " + codePath + ", retcode=" + retCode);
   9637                             // we don't consider this to be a failure of the core package deletion
   9638                         }
   9639                     }
   9640                 }
   9641             }
   9642         }
   9643 
   9644         boolean doPostDeleteLI(boolean delete) {
   9645             // XXX err, shouldn't we respect the delete flag?
   9646             cleanUpResourcesLI();
   9647             return true;
   9648         }
   9649     }
   9650 
   9651     private boolean isAsecExternal(String cid) {
   9652         final String asecPath = PackageHelper.getSdFilesystem(cid);
   9653         return !asecPath.startsWith(mAsecInternalPath);
   9654     }
   9655 
   9656     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
   9657             PackageManagerException {
   9658         if (copyRet < 0) {
   9659             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
   9660                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
   9661                 throw new PackageManagerException(copyRet, message);
   9662             }
   9663         }
   9664     }
   9665 
   9666     /**
   9667      * Extract the MountService "container ID" from the full code path of an
   9668      * .apk.
   9669      */
   9670     static String cidFromCodePath(String fullCodePath) {
   9671         int eidx = fullCodePath.lastIndexOf("/");
   9672         String subStr1 = fullCodePath.substring(0, eidx);
   9673         int sidx = subStr1.lastIndexOf("/");
   9674         return subStr1.substring(sidx+1, eidx);
   9675     }
   9676 
   9677     /**
   9678      * Logic to handle installation of ASEC applications, including copying and
   9679      * renaming logic.
   9680      */
   9681     class AsecInstallArgs extends InstallArgs {
   9682         static final String RES_FILE_NAME = "pkg.apk";
   9683         static final String PUBLIC_RES_FILE_NAME = "res.zip";
   9684 
   9685         String cid;
   9686         String packagePath;
   9687         String resourcePath;
   9688         String legacyNativeLibraryDir;
   9689 
   9690         /** New install */
   9691         AsecInstallArgs(InstallParams params) {
   9692             super(params.origin, params.observer, params.installFlags,
   9693                     params.installerPackageName, params.getManifestDigest(),
   9694                     params.getUser(), null /* instruction sets */,
   9695                     params.packageAbiOverride);
   9696         }
   9697 
   9698         /** Existing install */
   9699         AsecInstallArgs(String fullCodePath, String[] instructionSets,
   9700                         boolean isExternal, boolean isForwardLocked) {
   9701             super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0)
   9702                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
   9703                     instructionSets, null);
   9704             // Hackily pretend we're still looking at a full code path
   9705             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
   9706                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
   9707             }
   9708 
   9709             // Extract cid from fullCodePath
   9710             int eidx = fullCodePath.lastIndexOf("/");
   9711             String subStr1 = fullCodePath.substring(0, eidx);
   9712             int sidx = subStr1.lastIndexOf("/");
   9713             cid = subStr1.substring(sidx+1, eidx);
   9714             setMountPath(subStr1);
   9715         }
   9716 
   9717         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
   9718             super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
   9719                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
   9720                     instructionSets, null);
   9721             this.cid = cid;
   9722             setMountPath(PackageHelper.getSdDir(cid));
   9723         }
   9724 
   9725         void createCopyFile() {
   9726             cid = mInstallerService.allocateExternalStageCidLegacy();
   9727         }
   9728 
   9729         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
   9730             final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(),
   9731                     abiOverride);
   9732 
   9733             final File target;
   9734             if (isExternal()) {
   9735                 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
   9736             } else {
   9737                 target = Environment.getDataDirectory();
   9738             }
   9739 
   9740             final StorageManager storage = StorageManager.from(mContext);
   9741             return (sizeBytes <= storage.getStorageBytesUntilLow(target));
   9742         }
   9743 
   9744         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   9745             if (origin.staged) {
   9746                 Slog.d(TAG, origin.cid + " already staged; skipping copy");
   9747                 cid = origin.cid;
   9748                 setMountPath(PackageHelper.getSdDir(cid));
   9749                 return PackageManager.INSTALL_SUCCEEDED;
   9750             }
   9751 
   9752             if (temp) {
   9753                 createCopyFile();
   9754             } else {
   9755                 /*
   9756                  * Pre-emptively destroy the container since it's destroyed if
   9757                  * copying fails due to it existing anyway.
   9758                  */
   9759                 PackageHelper.destroySdDir(cid);
   9760             }
   9761 
   9762             final String newMountPath = imcs.copyPackageToContainer(
   9763                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
   9764                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
   9765 
   9766             if (newMountPath != null) {
   9767                 setMountPath(newMountPath);
   9768                 return PackageManager.INSTALL_SUCCEEDED;
   9769             } else {
   9770                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9771             }
   9772         }
   9773 
   9774         @Override
   9775         String getCodePath() {
   9776             return packagePath;
   9777         }
   9778 
   9779         @Override
   9780         String getResourcePath() {
   9781             return resourcePath;
   9782         }
   9783 
   9784         @Override
   9785         String getLegacyNativeLibraryPath() {
   9786             return legacyNativeLibraryDir;
   9787         }
   9788 
   9789         int doPreInstall(int status) {
   9790             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9791                 // Destroy container
   9792                 PackageHelper.destroySdDir(cid);
   9793             } else {
   9794                 boolean mounted = PackageHelper.isContainerMounted(cid);
   9795                 if (!mounted) {
   9796                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
   9797                             Process.SYSTEM_UID);
   9798                     if (newMountPath != null) {
   9799                         setMountPath(newMountPath);
   9800                     } else {
   9801                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9802                     }
   9803                 }
   9804             }
   9805             return status;
   9806         }
   9807 
   9808         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
   9809             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
   9810             String newMountPath = null;
   9811             if (PackageHelper.isContainerMounted(cid)) {
   9812                 // Unmount the container
   9813                 if (!PackageHelper.unMountSdDir(cid)) {
   9814                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
   9815                     return false;
   9816                 }
   9817             }
   9818             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   9819                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
   9820                         " which might be stale. Will try to clean up.");
   9821                 // Clean up the stale container and proceed to recreate.
   9822                 if (!PackageHelper.destroySdDir(newCacheId)) {
   9823                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
   9824                     return false;
   9825                 }
   9826                 // Successfully cleaned up stale container. Try to rename again.
   9827                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   9828                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
   9829                             + " inspite of cleaning it up.");
   9830                     return false;
   9831                 }
   9832             }
   9833             if (!PackageHelper.isContainerMounted(newCacheId)) {
   9834                 Slog.w(TAG, "Mounting container " + newCacheId);
   9835                 newMountPath = PackageHelper.mountSdDir(newCacheId,
   9836                         getEncryptKey(), Process.SYSTEM_UID);
   9837             } else {
   9838                 newMountPath = PackageHelper.getSdDir(newCacheId);
   9839             }
   9840             if (newMountPath == null) {
   9841                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
   9842                 return false;
   9843             }
   9844             Log.i(TAG, "Succesfully renamed " + cid +
   9845                     " to " + newCacheId +
   9846                     " at new path: " + newMountPath);
   9847             cid = newCacheId;
   9848 
   9849             final File beforeCodeFile = new File(packagePath);
   9850             setMountPath(newMountPath);
   9851             final File afterCodeFile = new File(packagePath);
   9852 
   9853             // Reflect the rename in scanned details
   9854             pkg.codePath = afterCodeFile.getAbsolutePath();
   9855             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
   9856                     pkg.baseCodePath);
   9857             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
   9858                     pkg.splitCodePaths);
   9859 
   9860             // Reflect the rename in app info
   9861             pkg.applicationInfo.setCodePath(pkg.codePath);
   9862             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
   9863             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
   9864             pkg.applicationInfo.setResourcePath(pkg.codePath);
   9865             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
   9866             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
   9867 
   9868             return true;
   9869         }
   9870 
   9871         private void setMountPath(String mountPath) {
   9872             final File mountFile = new File(mountPath);
   9873 
   9874             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
   9875             if (monolithicFile.exists()) {
   9876                 packagePath = monolithicFile.getAbsolutePath();
   9877                 if (isFwdLocked()) {
   9878                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
   9879                 } else {
   9880                     resourcePath = packagePath;
   9881                 }
   9882             } else {
   9883                 packagePath = mountFile.getAbsolutePath();
   9884                 resourcePath = packagePath;
   9885             }
   9886 
   9887             legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
   9888         }
   9889 
   9890         int doPostInstall(int status, int uid) {
   9891             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9892                 cleanUp();
   9893             } else {
   9894                 final int groupOwner;
   9895                 final String protectedFile;
   9896                 if (isFwdLocked()) {
   9897                     groupOwner = UserHandle.getSharedAppGid(uid);
   9898                     protectedFile = RES_FILE_NAME;
   9899                 } else {
   9900                     groupOwner = -1;
   9901                     protectedFile = null;
   9902                 }
   9903 
   9904                 if (uid < Process.FIRST_APPLICATION_UID
   9905                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
   9906                     Slog.e(TAG, "Failed to finalize " + cid);
   9907                     PackageHelper.destroySdDir(cid);
   9908                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9909                 }
   9910 
   9911                 boolean mounted = PackageHelper.isContainerMounted(cid);
   9912                 if (!mounted) {
   9913                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
   9914                 }
   9915             }
   9916             return status;
   9917         }
   9918 
   9919         private void cleanUp() {
   9920             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
   9921 
   9922             // Destroy secure container
   9923             PackageHelper.destroySdDir(cid);
   9924         }
   9925 
   9926         private List<String> getAllCodePaths() {
   9927             final File codeFile = new File(getCodePath());
   9928             if (codeFile != null && codeFile.exists()) {
   9929                 try {
   9930                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
   9931                     return pkg.getAllCodePaths();
   9932                 } catch (PackageParserException e) {
   9933                     // Ignored; we tried our best
   9934                 }
   9935             }
   9936             return Collections.EMPTY_LIST;
   9937         }
   9938 
   9939         void cleanUpResourcesLI() {
   9940             // Enumerate all code paths before deleting
   9941             cleanUpResourcesLI(getAllCodePaths());
   9942         }
   9943 
   9944         private void cleanUpResourcesLI(List<String> allCodePaths) {
   9945             cleanUp();
   9946 
   9947             if (!allCodePaths.isEmpty()) {
   9948                 if (instructionSets == null) {
   9949                     throw new IllegalStateException("instructionSet == null");
   9950                 }
   9951                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
   9952                 for (String codePath : allCodePaths) {
   9953                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   9954                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
   9955                         if (retCode < 0) {
   9956                             Slog.w(TAG, "Couldn't remove dex file for package: "
   9957                                     + " at location " + codePath + ", retcode=" + retCode);
   9958                             // we don't consider this to be a failure of the core package deletion
   9959                         }
   9960                     }
   9961                 }
   9962             }
   9963         }
   9964 
   9965         boolean matchContainer(String app) {
   9966             if (cid.startsWith(app)) {
   9967                 return true;
   9968             }
   9969             return false;
   9970         }
   9971 
   9972         String getPackageName() {
   9973             return getAsecPackageName(cid);
   9974         }
   9975 
   9976         boolean doPostDeleteLI(boolean delete) {
   9977             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
   9978             final List<String> allCodePaths = getAllCodePaths();
   9979             boolean mounted = PackageHelper.isContainerMounted(cid);
   9980             if (mounted) {
   9981                 // Unmount first
   9982                 if (PackageHelper.unMountSdDir(cid)) {
   9983                     mounted = false;
   9984                 }
   9985             }
   9986             if (!mounted && delete) {
   9987                 cleanUpResourcesLI(allCodePaths);
   9988             }
   9989             return !mounted;
   9990         }
   9991 
   9992         @Override
   9993         int doPreCopy() {
   9994             if (isFwdLocked()) {
   9995                 if (!PackageHelper.fixSdPermissions(cid,
   9996                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
   9997                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9998                 }
   9999             }
   10000 
   10001             return PackageManager.INSTALL_SUCCEEDED;
   10002         }
   10003 
   10004         @Override
   10005         int doPostCopy(int uid) {
   10006             if (isFwdLocked()) {
   10007                 if (uid < Process.FIRST_APPLICATION_UID
   10008                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
   10009                                 RES_FILE_NAME)) {
   10010                     Slog.e(TAG, "Failed to finalize " + cid);
   10011                     PackageHelper.destroySdDir(cid);
   10012                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   10013                 }
   10014             }
   10015 
   10016             return PackageManager.INSTALL_SUCCEEDED;
   10017         }
   10018     }
   10019 
   10020     static String getAsecPackageName(String packageCid) {
   10021         int idx = packageCid.lastIndexOf("-");
   10022         if (idx == -1) {
   10023             return packageCid;
   10024         }
   10025         return packageCid.substring(0, idx);
   10026     }
   10027 
   10028     // Utility method used to create code paths based on package name and available index.
   10029     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
   10030         String idxStr = "";
   10031         int idx = 1;
   10032         // Fall back to default value of idx=1 if prefix is not
   10033         // part of oldCodePath
   10034         if (oldCodePath != null) {
   10035             String subStr = oldCodePath;
   10036             // Drop the suffix right away
   10037             if (suffix != null && subStr.endsWith(suffix)) {
   10038                 subStr = subStr.substring(0, subStr.length() - suffix.length());
   10039             }
   10040             // If oldCodePath already contains prefix find out the
   10041             // ending index to either increment or decrement.
   10042             int sidx = subStr.lastIndexOf(prefix);
   10043             if (sidx != -1) {
   10044                 subStr = subStr.substring(sidx + prefix.length());
   10045                 if (subStr != null) {
   10046                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
   10047                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
   10048                     }
   10049                     try {
   10050                         idx = Integer.parseInt(subStr);
   10051                         if (idx <= 1) {
   10052                             idx++;
   10053                         } else {
   10054                             idx--;
   10055                         }
   10056                     } catch(NumberFormatException e) {
   10057                     }
   10058                 }
   10059             }
   10060         }
   10061         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
   10062         return prefix + idxStr;
   10063     }
   10064 
   10065     private File getNextCodePath(String packageName) {
   10066         int suffix = 1;
   10067         File result;
   10068         do {
   10069             result = new File(mAppInstallDir, packageName + "-" + suffix);
   10070             suffix++;
   10071         } while (result.exists());
   10072         return result;
   10073     }
   10074 
   10075     // Utility method used to ignore ADD/REMOVE events
   10076     // by directory observer.
   10077     private static boolean ignoreCodePath(String fullPathStr) {
   10078         String apkName = deriveCodePathName(fullPathStr);
   10079         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
   10080         if (idx != -1 && ((idx+1) < apkName.length())) {
   10081             // Make sure the package ends with a numeral
   10082             String version = apkName.substring(idx+1);
   10083             try {
   10084                 Integer.parseInt(version);
   10085                 return true;
   10086             } catch (NumberFormatException e) {}
   10087         }
   10088         return false;
   10089     }
   10090 
   10091     // Utility method that returns the relative package path with respect
   10092     // to the installation directory. Like say for /data/data/com.test-1.apk
   10093     // string com.test-1 is returned.
   10094     static String deriveCodePathName(String codePath) {
   10095         if (codePath == null) {
   10096             return null;
   10097         }
   10098         final File codeFile = new File(codePath);
   10099         final String name = codeFile.getName();
   10100         if (codeFile.isDirectory()) {
   10101             return name;
   10102         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
   10103             final int lastDot = name.lastIndexOf('.');
   10104             return name.substring(0, lastDot);
   10105         } else {
   10106             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
   10107             return null;
   10108         }
   10109     }
   10110 
   10111     class PackageInstalledInfo {
   10112         String name;
   10113         int uid;
   10114         // The set of users that originally had this package installed.
   10115         int[] origUsers;
   10116         // The set of users that now have this package installed.
   10117         int[] newUsers;
   10118         PackageParser.Package pkg;
   10119         int returnCode;
   10120         String returnMsg;
   10121         PackageRemovedInfo removedInfo;
   10122 
   10123         public void setError(int code, String msg) {
   10124             returnCode = code;
   10125             returnMsg = msg;
   10126             Slog.w(TAG, msg);
   10127         }
   10128 
   10129         public void setError(String msg, PackageParserException e) {
   10130             returnCode = e.error;
   10131             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
   10132             Slog.w(TAG, msg, e);
   10133         }
   10134 
   10135         public void setError(String msg, PackageManagerException e) {
   10136             returnCode = e.error;
   10137             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
   10138             Slog.w(TAG, msg, e);
   10139         }
   10140 
   10141         // In some error cases we want to convey more info back to the observer
   10142         String origPackage;
   10143         String origPermission;
   10144     }
   10145 
   10146     /*
   10147      * Install a non-existing package.
   10148      */
   10149     private void installNewPackageLI(PackageParser.Package pkg,
   10150             int parseFlags, int scanFlags, UserHandle user,
   10151             String installerPackageName, PackageInstalledInfo res) {
   10152         // Remember this for later, in case we need to rollback this install
   10153         String pkgName = pkg.packageName;
   10154 
   10155         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
   10156         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
   10157         synchronized(mPackages) {
   10158             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
   10159                 // A package with the same name is already installed, though
   10160                 // it has been renamed to an older name.  The package we
   10161                 // are trying to install should be installed as an update to
   10162                 // the existing one, but that has not been requested, so bail.
   10163                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
   10164                         + " without first uninstalling package running as "
   10165                         + mSettings.mRenamedPackages.get(pkgName));
   10166                 return;
   10167             }
   10168             if (mPackages.containsKey(pkgName)) {
   10169                 // Don't allow installation over an existing package with the same name.
   10170                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
   10171                         + " without first uninstalling.");
   10172                 return;
   10173             }
   10174         }
   10175 
   10176         try {
   10177             PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
   10178                     System.currentTimeMillis(), user);
   10179 
   10180             updateSettingsLI(newPackage, installerPackageName, null, null, res);
   10181             // delete the partially installed application. the data directory will have to be
   10182             // restored if it was already existing
   10183             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   10184                 // remove package from internal structures.  Note that we want deletePackageX to
   10185                 // delete the package data and cache directories that it created in
   10186                 // scanPackageLocked, unless those directories existed before we even tried to
   10187                 // install.
   10188                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
   10189                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
   10190                                 res.removedInfo, true);
   10191             }
   10192 
   10193         } catch (PackageManagerException e) {
   10194             res.setError("Package couldn't be installed in " + pkg.codePath, e);
   10195         }
   10196     }
   10197 
   10198     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
   10199         // Upgrade keysets are being used.  Determine if new package has a superset of the
   10200         // required keys.
   10201         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
   10202         KeySetManagerService ksms = mSettings.mKeySetManagerService;
   10203         for (int i = 0; i < upgradeKeySets.length; i++) {
   10204             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
   10205             if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
   10206                 return true;
   10207             }
   10208         }
   10209         return false;
   10210     }
   10211 
   10212     private void replacePackageLI(PackageParser.Package pkg,
   10213             int parseFlags, int scanFlags, UserHandle user,
   10214             String installerPackageName, PackageInstalledInfo res) {
   10215         PackageParser.Package oldPackage;
   10216         String pkgName = pkg.packageName;
   10217         int[] allUsers;
   10218         boolean[] perUserInstalled;
   10219 
   10220         // First find the old package info and check signatures
   10221         synchronized(mPackages) {
   10222             oldPackage = mPackages.get(pkgName);
   10223             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
   10224             PackageSetting ps = mSettings.mPackages.get(pkgName);
   10225             if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
   10226                 // default to original signature matching
   10227                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
   10228                     != PackageManager.SIGNATURE_MATCH) {
   10229                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
   10230                             "New package has a different signature: " + pkgName);
   10231                     return;
   10232                 }
   10233             } else {
   10234                 if(!checkUpgradeKeySetLP(ps, pkg)) {
   10235                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
   10236                             "New package not signed by keys specified by upgrade-keysets: "
   10237                             + pkgName);
   10238                     return;
   10239                 }
   10240             }
   10241 
   10242             // In case of rollback, remember per-user/profile install state
   10243             allUsers = sUserManager.getUserIds();
   10244             perUserInstalled = new boolean[allUsers.length];
   10245             for (int i = 0; i < allUsers.length; i++) {
   10246                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
   10247             }
   10248         }
   10249 
   10250         boolean sysPkg = (isSystemApp(oldPackage));
   10251         if (sysPkg) {
   10252             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
   10253                     user, allUsers, perUserInstalled, installerPackageName, res);
   10254         } else {
   10255             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
   10256                     user, allUsers, perUserInstalled, installerPackageName, res);
   10257         }
   10258     }
   10259 
   10260     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
   10261             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
   10262             int[] allUsers, boolean[] perUserInstalled,
   10263             String installerPackageName, PackageInstalledInfo res) {
   10264         String pkgName = deletedPackage.packageName;
   10265         boolean deletedPkg = true;
   10266         boolean updatedSettings = false;
   10267 
   10268         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
   10269                 + deletedPackage);
   10270         long origUpdateTime;
   10271         if (pkg.mExtras != null) {
   10272             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
   10273         } else {
   10274             origUpdateTime = 0;
   10275         }
   10276 
   10277         // First delete the existing package while retaining the data directory
   10278         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
   10279                 res.removedInfo, true)) {
   10280             // If the existing package wasn't successfully deleted
   10281             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
   10282             deletedPkg = false;
   10283         } else {
   10284             // Successfully deleted the old package; proceed with replace.
   10285 
   10286             // If deleted package lived in a container, give users a chance to
   10287             // relinquish resources before killing.
   10288             if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) {
   10289                 if (DEBUG_INSTALL) {
   10290                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
   10291                 }
   10292                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
   10293                 final ArrayList<String> pkgList = new ArrayList<String>(1);
   10294                 pkgList.add(deletedPackage.applicationInfo.packageName);
   10295                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
   10296             }
   10297 
   10298             deleteCodeCacheDirsLI(pkgName);
   10299             try {
   10300                 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
   10301                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
   10302                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
   10303                 updatedSettings = true;
   10304             } catch (PackageManagerException e) {
   10305                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
   10306             }
   10307         }
   10308 
   10309         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   10310             // remove package from internal structures.  Note that we want deletePackageX to
   10311             // delete the package data and cache directories that it created in
   10312             // scanPackageLocked, unless those directories existed before we even tried to
   10313             // install.
   10314             if(updatedSettings) {
   10315                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
   10316                 deletePackageLI(
   10317                         pkgName, null, true, allUsers, perUserInstalled,
   10318                         PackageManager.DELETE_KEEP_DATA,
   10319                                 res.removedInfo, true);
   10320             }
   10321             // Since we failed to install the new package we need to restore the old
   10322             // package that we deleted.
   10323             if (deletedPkg) {
   10324                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
   10325                 File restoreFile = new File(deletedPackage.codePath);
   10326                 // Parse old package
   10327                 boolean oldOnSd = isExternal(deletedPackage);
   10328                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
   10329                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
   10330                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
   10331                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
   10332                 try {
   10333                     scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
   10334                 } catch (PackageManagerException e) {
   10335                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
   10336                             + e.getMessage());
   10337                     return;
   10338                 }
   10339                 // Restore of old package succeeded. Update permissions.
   10340                 // writer
   10341                 synchronized (mPackages) {
   10342                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
   10343                             UPDATE_PERMISSIONS_ALL);
   10344                     // can downgrade to reader
   10345                     mSettings.writeLPr();
   10346                 }
   10347                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
   10348             }
   10349         }
   10350     }
   10351 
   10352     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
   10353             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
   10354             int[] allUsers, boolean[] perUserInstalled,
   10355             String installerPackageName, PackageInstalledInfo res) {
   10356         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
   10357                 + ", old=" + deletedPackage);
   10358         boolean disabledSystem = false;
   10359         boolean updatedSettings = false;
   10360         parseFlags |= PackageParser.PARSE_IS_SYSTEM;
   10361         if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
   10362             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   10363         }
   10364         String packageName = deletedPackage.packageName;
   10365         if (packageName == null) {
   10366             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
   10367                     "Attempt to delete null packageName.");
   10368             return;
   10369         }
   10370         PackageParser.Package oldPkg;
   10371         PackageSetting oldPkgSetting;
   10372         // reader
   10373         synchronized (mPackages) {
   10374             oldPkg = mPackages.get(packageName);
   10375             oldPkgSetting = mSettings.mPackages.get(packageName);
   10376             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
   10377                     (oldPkgSetting == null)) {
   10378                 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
   10379                         "Couldn't find package:" + packageName + " information");
   10380                 return;
   10381             }
   10382         }
   10383 
   10384         killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
   10385 
   10386         res.removedInfo.uid = oldPkg.applicationInfo.uid;
   10387         res.removedInfo.removedPackage = packageName;
   10388         // Remove existing system package
   10389         removePackageLI(oldPkgSetting, true);
   10390         // writer
   10391         synchronized (mPackages) {
   10392             disabledSystem = mSettings.disableSystemPackageLPw(packageName);
   10393             if (!disabledSystem && deletedPackage != null) {
   10394                 // We didn't need to disable the .apk as a current system package,
   10395                 // which means we are replacing another update that is already
   10396                 // installed.  We need to make sure to delete the older one's .apk.
   10397                 res.removedInfo.args = createInstallArgsForExisting(0,
   10398                         deletedPackage.applicationInfo.getCodePath(),
   10399                         deletedPackage.applicationInfo.getResourcePath(),
   10400                         deletedPackage.applicationInfo.nativeLibraryRootDir,
   10401                         getAppDexInstructionSets(deletedPackage.applicationInfo));
   10402             } else {
   10403                 res.removedInfo.args = null;
   10404             }
   10405         }
   10406 
   10407         // Successfully disabled the old package. Now proceed with re-installation
   10408         deleteCodeCacheDirsLI(packageName);
   10409 
   10410         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   10411         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   10412 
   10413         PackageParser.Package newPackage = null;
   10414         try {
   10415             newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
   10416             if (newPackage.mExtras != null) {
   10417                 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
   10418                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
   10419                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
   10420 
   10421                 // is the update attempting to change shared user? that isn't going to work...
   10422                 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
   10423                     res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
   10424                             "Forbidding shared user change from " + oldPkgSetting.sharedUser
   10425                             + " to " + newPkgSetting.sharedUser);
   10426                     updatedSettings = true;
   10427                 }
   10428             }
   10429 
   10430             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   10431                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
   10432                 updatedSettings = true;
   10433             }
   10434 
   10435         } catch (PackageManagerException e) {
   10436             res.setError("Package couldn't be installed in " + pkg.codePath, e);
   10437         }
   10438 
   10439         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   10440             // Re installation failed. Restore old information
   10441             // Remove new pkg information
   10442             if (newPackage != null) {
   10443                 removeInstalledPackageLI(newPackage, true);
   10444             }
   10445             // Add back the old system package
   10446             try {
   10447                 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
   10448             } catch (PackageManagerException e) {
   10449                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
   10450             }
   10451             // Restore the old system information in Settings
   10452             synchronized (mPackages) {
   10453                 if (disabledSystem) {
   10454                     mSettings.enableSystemPackageLPw(packageName);
   10455                 }
   10456                 if (updatedSettings) {
   10457                     mSettings.setInstallerPackageName(packageName,
   10458                             oldPkgSetting.installerPackageName);
   10459                 }
   10460                 mSettings.writeLPr();
   10461             }
   10462         }
   10463     }
   10464 
   10465     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
   10466             int[] allUsers, boolean[] perUserInstalled,
   10467             PackageInstalledInfo res) {
   10468         String pkgName = newPackage.packageName;
   10469         synchronized (mPackages) {
   10470             //write settings. the installStatus will be incomplete at this stage.
   10471             //note that the new package setting would have already been
   10472             //added to mPackages. It hasn't been persisted yet.
   10473             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
   10474             mSettings.writeLPr();
   10475         }
   10476 
   10477         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
   10478 
   10479         synchronized (mPackages) {
   10480             updatePermissionsLPw(newPackage.packageName, newPackage,
   10481                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
   10482                             ? UPDATE_PERMISSIONS_ALL : 0));
   10483             // For system-bundled packages, we assume that installing an upgraded version
   10484             // of the package implies that the user actually wants to run that new code,
   10485             // so we enable the package.
   10486             if (isSystemApp(newPackage)) {
   10487                 // NB: implicit assumption that system package upgrades apply to all users
   10488                 if (DEBUG_INSTALL) {
   10489                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
   10490                 }
   10491                 PackageSetting ps = mSettings.mPackages.get(pkgName);
   10492                 if (ps != null) {
   10493                     if (res.origUsers != null) {
   10494                         for (int userHandle : res.origUsers) {
   10495                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
   10496                                     userHandle, installerPackageName);
   10497                         }
   10498                     }
   10499                     // Also convey the prior install/uninstall state
   10500                     if (allUsers != null && perUserInstalled != null) {
   10501                         for (int i = 0; i < allUsers.length; i++) {
   10502                             if (DEBUG_INSTALL) {
   10503                                 Slog.d(TAG, "    user " + allUsers[i]
   10504                                         + " => " + perUserInstalled[i]);
   10505                             }
   10506                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
   10507                         }
   10508                         // these install state changes will be persisted in the
   10509                         // upcoming call to mSettings.writeLPr().
   10510                     }
   10511                 }
   10512             }
   10513             res.name = pkgName;
   10514             res.uid = newPackage.applicationInfo.uid;
   10515             res.pkg = newPackage;
   10516             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
   10517             mSettings.setInstallerPackageName(pkgName, installerPackageName);
   10518             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   10519             //to update install status
   10520             mSettings.writeLPr();
   10521         }
   10522     }
   10523 
   10524     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
   10525         final int installFlags = args.installFlags;
   10526         String installerPackageName = args.installerPackageName;
   10527         File tmpPackageFile = new File(args.getCodePath());
   10528         boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
   10529         boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
   10530         boolean replace = false;
   10531         final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
   10532         // Result object to be returned
   10533         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   10534 
   10535         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
   10536         // Retrieve PackageSettings and parse package
   10537         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
   10538                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
   10539                 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
   10540         PackageParser pp = new PackageParser();
   10541         pp.setSeparateProcesses(mSeparateProcesses);
   10542         pp.setDisplayMetrics(mMetrics);
   10543 
   10544         final PackageParser.Package pkg;
   10545         try {
   10546             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
   10547         } catch (PackageParserException e) {
   10548             res.setError("Failed parse during installPackageLI", e);
   10549             return;
   10550         }
   10551 
   10552         // Mark that we have an install time CPU ABI override.
   10553         pkg.cpuAbiOverride = args.abiOverride;
   10554 
   10555         String pkgName = res.name = pkg.packageName;
   10556         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
   10557             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
   10558                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
   10559                 return;
   10560             }
   10561         }
   10562 
   10563         try {
   10564             pp.collectCertificates(pkg, parseFlags);
   10565             pp.collectManifestDigest(pkg);
   10566         } catch (PackageParserException e) {
   10567             res.setError("Failed collect during installPackageLI", e);
   10568             return;
   10569         }
   10570 
   10571         /* If the installer passed in a manifest digest, compare it now. */
   10572         if (args.manifestDigest != null) {
   10573             if (DEBUG_INSTALL) {
   10574                 final String parsedManifest = pkg.manifestDigest == null ? "null"
   10575                         : pkg.manifestDigest.toString();
   10576                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
   10577                         + parsedManifest);
   10578             }
   10579 
   10580             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
   10581                 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
   10582                 return;
   10583             }
   10584         } else if (DEBUG_INSTALL) {
   10585             final String parsedManifest = pkg.manifestDigest == null
   10586                     ? "null" : pkg.manifestDigest.toString();
   10587             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
   10588         }
   10589 
   10590         // Get rid of all references to package scan path via parser.
   10591         pp = null;
   10592         String oldCodePath = null;
   10593         boolean systemApp = false;
   10594         synchronized (mPackages) {
   10595             // Check if installing already existing package
   10596             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   10597                 String oldName = mSettings.mRenamedPackages.get(pkgName);
   10598                 if (pkg.mOriginalPackages != null
   10599                         && pkg.mOriginalPackages.contains(oldName)
   10600                         && mPackages.containsKey(oldName)) {
   10601                     // This package is derived from an original package,
   10602                     // and this device has been updating from that original
   10603                     // name.  We must continue using the original name, so
   10604                     // rename the new package here.
   10605                     pkg.setPackageName(oldName);
   10606                     pkgName = pkg.packageName;
   10607                     replace = true;
   10608                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
   10609                             + oldName + " pkgName=" + pkgName);
   10610                 } else if (mPackages.containsKey(pkgName)) {
   10611                     // This package, under its official name, already exists
   10612                     // on the device; we should replace it.
   10613                     replace = true;
   10614                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
   10615                 }
   10616             }
   10617 
   10618             PackageSetting ps = mSettings.mPackages.get(pkgName);
   10619             if (ps != null) {
   10620                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
   10621 
   10622                 // Quick sanity check that we're signed correctly if updating;
   10623                 // we'll check this again later when scanning, but we want to
   10624                 // bail early here before tripping over redefined permissions.
   10625                 if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
   10626                     try {
   10627                         verifySignaturesLP(ps, pkg);
   10628                     } catch (PackageManagerException e) {
   10629                         res.setError(e.error, e.getMessage());
   10630                         return;
   10631                     }
   10632                 } else {
   10633                     if (!checkUpgradeKeySetLP(ps, pkg)) {
   10634                         res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
   10635                                 + pkg.packageName + " upgrade keys do not match the "
   10636                                 + "previously installed version");
   10637                         return;
   10638                     }
   10639                 }
   10640 
   10641                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
   10642                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
   10643                     systemApp = (ps.pkg.applicationInfo.flags &
   10644                             ApplicationInfo.FLAG_SYSTEM) != 0;
   10645                 }
   10646                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
   10647             }
   10648 
   10649             // Check whether the newly-scanned package wants to define an already-defined perm
   10650             int N = pkg.permissions.size();
   10651             for (int i = N-1; i >= 0; i--) {
   10652                 PackageParser.Permission perm = pkg.permissions.get(i);
   10653                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
   10654                 if (bp != null) {
   10655                     // If the defining package is signed with our cert, it's okay.  This
   10656                     // also includes the "updating the same package" case, of course.
   10657                     // "updating same package" could also involve key-rotation.
   10658                     final boolean sigsOk;
   10659                     if (!bp.sourcePackage.equals(pkg.packageName)
   10660                             || !(bp.packageSetting instanceof PackageSetting)
   10661                             || !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
   10662                             || ((PackageSetting) bp.packageSetting).sharedUser != null) {
   10663                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
   10664                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
   10665                     } else {
   10666                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
   10667                     }
   10668                     if (!sigsOk) {
   10669                         // If the owning package is the system itself, we log but allow
   10670                         // install to proceed; we fail the install on all other permission
   10671                         // redefinitions.
   10672                         if (!bp.sourcePackage.equals("android")) {
   10673                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
   10674                                     + pkg.packageName + " attempting to redeclare permission "
   10675                                     + perm.info.name + " already owned by " + bp.sourcePackage);
   10676                             res.origPermission = perm.info.name;
   10677                             res.origPackage = bp.sourcePackage;
   10678                             return;
   10679                         } else {
   10680                             Slog.w(TAG, "Package " + pkg.packageName
   10681                                     + " attempting to redeclare system permission "
   10682                                     + perm.info.name + "; ignoring new declaration");
   10683                             pkg.permissions.remove(i);
   10684                         }
   10685                     }
   10686                 }
   10687             }
   10688 
   10689         }
   10690 
   10691         if (systemApp && onSd) {
   10692             // Disable updates to system apps on sdcard
   10693             res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
   10694                     "Cannot install updates to system apps on sdcard");
   10695             return;
   10696         }
   10697 
   10698         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
   10699             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
   10700             return;
   10701         }
   10702 
   10703         if (replace) {
   10704             replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
   10705                     installerPackageName, res);
   10706         } else {
   10707             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
   10708                     args.user, installerPackageName, res);
   10709         }
   10710         synchronized (mPackages) {
   10711             final PackageSetting ps = mSettings.mPackages.get(pkgName);
   10712             if (ps != null) {
   10713                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
   10714             }
   10715         }
   10716     }
   10717 
   10718     private static boolean isForwardLocked(PackageParser.Package pkg) {
   10719         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
   10720     }
   10721 
   10722     private static boolean isForwardLocked(ApplicationInfo info) {
   10723         return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
   10724     }
   10725 
   10726     private boolean isForwardLocked(PackageSetting ps) {
   10727         return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
   10728     }
   10729 
   10730     private static boolean isMultiArch(PackageSetting ps) {
   10731         return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
   10732     }
   10733 
   10734     private static boolean isMultiArch(ApplicationInfo info) {
   10735         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
   10736     }
   10737 
   10738     private static boolean isExternal(PackageParser.Package pkg) {
   10739         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   10740     }
   10741 
   10742     private static boolean isExternal(PackageSetting ps) {
   10743         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   10744     }
   10745 
   10746     private static boolean isExternal(ApplicationInfo info) {
   10747         return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   10748     }
   10749 
   10750     private static boolean isSystemApp(PackageParser.Package pkg) {
   10751         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   10752     }
   10753 
   10754     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
   10755         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
   10756     }
   10757 
   10758     private static boolean isSystemApp(ApplicationInfo info) {
   10759         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   10760     }
   10761 
   10762     private static boolean isSystemApp(PackageSetting ps) {
   10763         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
   10764     }
   10765 
   10766     private static boolean isUpdatedSystemApp(PackageSetting ps) {
   10767         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   10768     }
   10769 
   10770     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
   10771         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   10772     }
   10773 
   10774     private static boolean isUpdatedSystemApp(ApplicationInfo info) {
   10775         return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   10776     }
   10777 
   10778     private int packageFlagsToInstallFlags(PackageSetting ps) {
   10779         int installFlags = 0;
   10780         if (isExternal(ps)) {
   10781             installFlags |= PackageManager.INSTALL_EXTERNAL;
   10782         }
   10783         if (isForwardLocked(ps)) {
   10784             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
   10785         }
   10786         return installFlags;
   10787     }
   10788 
   10789     private void deleteTempPackageFiles() {
   10790         final FilenameFilter filter = new FilenameFilter() {
   10791             public boolean accept(File dir, String name) {
   10792                 return name.startsWith("vmdl") && name.endsWith(".tmp");
   10793             }
   10794         };
   10795         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
   10796             file.delete();
   10797         }
   10798     }
   10799 
   10800     @Override
   10801     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
   10802             int flags) {
   10803         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
   10804                 flags);
   10805     }
   10806 
   10807     @Override
   10808     public void deletePackage(final String packageName,
   10809             final IPackageDeleteObserver2 observer, final int userId, final int flags) {
   10810         mContext.enforceCallingOrSelfPermission(
   10811                 android.Manifest.permission.DELETE_PACKAGES, null);
   10812         final int uid = Binder.getCallingUid();
   10813         if (UserHandle.getUserId(uid) != userId) {
   10814             mContext.enforceCallingPermission(
   10815                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10816                     "deletePackage for user " + userId);
   10817         }
   10818         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
   10819             try {
   10820                 observer.onPackageDeleted(packageName,
   10821                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
   10822             } catch (RemoteException re) {
   10823             }
   10824             return;
   10825         }
   10826 
   10827         boolean uninstallBlocked = false;
   10828         if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
   10829             int[] users = sUserManager.getUserIds();
   10830             for (int i = 0; i < users.length; ++i) {
   10831                 if (getBlockUninstallForUser(packageName, users[i])) {
   10832                     uninstallBlocked = true;
   10833                     break;
   10834                 }
   10835             }
   10836         } else {
   10837             uninstallBlocked = getBlockUninstallForUser(packageName, userId);
   10838         }
   10839         if (uninstallBlocked) {
   10840             try {
   10841                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
   10842                         null);
   10843             } catch (RemoteException re) {
   10844             }
   10845             return;
   10846         }
   10847 
   10848         if (DEBUG_REMOVE) {
   10849             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
   10850         }
   10851         // Queue up an async operation since the package deletion may take a little while.
   10852         mHandler.post(new Runnable() {
   10853             public void run() {
   10854                 mHandler.removeCallbacks(this);
   10855                 final int returnCode = deletePackageX(packageName, userId, flags);
   10856                 if (observer != null) {
   10857                     try {
   10858                         observer.onPackageDeleted(packageName, returnCode, null);
   10859                     } catch (RemoteException e) {
   10860                         Log.i(TAG, "Observer no longer exists.");
   10861                     } //end catch
   10862                 } //end if
   10863             } //end run
   10864         });
   10865     }
   10866 
   10867     private boolean isPackageDeviceAdmin(String packageName, int userId) {
   10868         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
   10869                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
   10870         try {
   10871             if (dpm != null) {
   10872                 if (dpm.isDeviceOwner(packageName)) {
   10873                     return true;
   10874                 }
   10875                 int[] users;
   10876                 if (userId == UserHandle.USER_ALL) {
   10877                     users = sUserManager.getUserIds();
   10878                 } else {
   10879                     users = new int[]{userId};
   10880                 }
   10881                 for (int i = 0; i < users.length; ++i) {
   10882                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
   10883                         return true;
   10884                     }
   10885                 }
   10886             }
   10887         } catch (RemoteException e) {
   10888         }
   10889         return false;
   10890     }
   10891 
   10892     /**
   10893      *  This method is an internal method that could be get invoked either
   10894      *  to delete an installed package or to clean up a failed installation.
   10895      *  After deleting an installed package, a broadcast is sent to notify any
   10896      *  listeners that the package has been installed. For cleaning up a failed
   10897      *  installation, the broadcast is not necessary since the package's
   10898      *  installation wouldn't have sent the initial broadcast either
   10899      *  The key steps in deleting a package are
   10900      *  deleting the package information in internal structures like mPackages,
   10901      *  deleting the packages base directories through installd
   10902      *  updating mSettings to reflect current status
   10903      *  persisting settings for later use
   10904      *  sending a broadcast if necessary
   10905      */
   10906     private int deletePackageX(String packageName, int userId, int flags) {
   10907         final PackageRemovedInfo info = new PackageRemovedInfo();
   10908         final boolean res;
   10909 
   10910         final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
   10911                 ? UserHandle.ALL : new UserHandle(userId);
   10912 
   10913         if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
   10914             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
   10915             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
   10916         }
   10917 
   10918         boolean removedForAllUsers = false;
   10919         boolean systemUpdate = false;
   10920 
   10921         // for the uninstall-updates case and restricted profiles, remember the per-
   10922         // userhandle installed state
   10923         int[] allUsers;
   10924         boolean[] perUserInstalled;
   10925         synchronized (mPackages) {
   10926             PackageSetting ps = mSettings.mPackages.get(packageName);
   10927             allUsers = sUserManager.getUserIds();
   10928             perUserInstalled = new boolean[allUsers.length];
   10929             for (int i = 0; i < allUsers.length; i++) {
   10930                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
   10931             }
   10932         }
   10933 
   10934         synchronized (mInstallLock) {
   10935             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
   10936             res = deletePackageLI(packageName, removeForUser,
   10937                     true, allUsers, perUserInstalled,
   10938                     flags | REMOVE_CHATTY, info, true);
   10939             systemUpdate = info.isRemovedPackageSystemUpdate;
   10940             if (res && !systemUpdate && mPackages.get(packageName) == null) {
   10941                 removedForAllUsers = true;
   10942             }
   10943             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
   10944                     + " removedForAllUsers=" + removedForAllUsers);
   10945         }
   10946 
   10947         if (res) {
   10948             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
   10949 
   10950             // If the removed package was a system update, the old system package
   10951             // was re-enabled; we need to broadcast this information
   10952             if (systemUpdate) {
   10953                 Bundle extras = new Bundle(1);
   10954                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
   10955                         ? info.removedAppId : info.uid);
   10956                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   10957 
   10958                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
   10959                         extras, null, null, null);
   10960                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
   10961                         extras, null, null, null);
   10962                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
   10963                         null, packageName, null, null);
   10964             }
   10965         }
   10966         // Force a gc here.
   10967         Runtime.getRuntime().gc();
   10968         // Delete the resources here after sending the broadcast to let
   10969         // other processes clean up before deleting resources.
   10970         if (info.args != null) {
   10971             synchronized (mInstallLock) {
   10972                 info.args.doPostDeleteLI(true);
   10973             }
   10974         }
   10975 
   10976         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
   10977     }
   10978 
   10979     static class PackageRemovedInfo {
   10980         String removedPackage;
   10981         int uid = -1;
   10982         int removedAppId = -1;
   10983         int[] removedUsers = null;
   10984         boolean isRemovedPackageSystemUpdate = false;
   10985         // Clean up resources deleted packages.
   10986         InstallArgs args = null;
   10987 
   10988         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
   10989             Bundle extras = new Bundle(1);
   10990             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
   10991             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
   10992             if (replacing) {
   10993                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   10994             }
   10995             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
   10996             if (removedPackage != null) {
   10997                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
   10998                         extras, null, null, removedUsers);
   10999                 if (fullRemove && !replacing) {
   11000                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
   11001                             extras, null, null, removedUsers);
   11002                 }
   11003             }
   11004             if (removedAppId >= 0) {
   11005                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
   11006                         removedUsers);
   11007             }
   11008         }
   11009     }
   11010 
   11011     /*
   11012      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
   11013      * flag is not set, the data directory is removed as well.
   11014      * make sure this flag is set for partially installed apps. If not its meaningless to
   11015      * delete a partially installed application.
   11016      */
   11017     private void removePackageDataLI(PackageSetting ps,
   11018             int[] allUserHandles, boolean[] perUserInstalled,
   11019             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
   11020         String packageName = ps.name;
   11021         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
   11022         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
   11023         // Retrieve object to delete permissions for shared user later on
   11024         final PackageSetting deletedPs;
   11025         // reader
   11026         synchronized (mPackages) {
   11027             deletedPs = mSettings.mPackages.get(packageName);
   11028             if (outInfo != null) {
   11029                 outInfo.removedPackage = packageName;
   11030                 outInfo.removedUsers = deletedPs != null
   11031                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
   11032                         : null;
   11033             }
   11034         }
   11035         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
   11036             removeDataDirsLI(packageName);
   11037             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
   11038         }
   11039         // writer
   11040         synchronized (mPackages) {
   11041             if (deletedPs != null) {
   11042                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
   11043                     if (outInfo != null) {
   11044                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
   11045                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
   11046                     }
   11047                     if (deletedPs != null) {
   11048                         updatePermissionsLPw(deletedPs.name, null, 0);
   11049                         if (deletedPs.sharedUser != null) {
   11050                             // remove permissions associated with package
   11051                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
   11052                         }
   11053                     }
   11054                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
   11055                 }
   11056                 // make sure to preserve per-user disabled state if this removal was just
   11057                 // a downgrade of a system app to the factory package
   11058                 if (allUserHandles != null && perUserInstalled != null) {
   11059                     if (DEBUG_REMOVE) {
   11060                         Slog.d(TAG, "Propagating install state across downgrade");
   11061                     }
   11062                     for (int i = 0; i < allUserHandles.length; i++) {
   11063                         if (DEBUG_REMOVE) {
   11064                             Slog.d(TAG, "    user " + allUserHandles[i]
   11065                                     + " => " + perUserInstalled[i]);
   11066                         }
   11067                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
   11068                     }
   11069                 }
   11070             }
   11071             // can downgrade to reader
   11072             if (writeSettings) {
   11073                 // Save settings now
   11074                 mSettings.writeLPr();
   11075             }
   11076         }
   11077         if (outInfo != null) {
   11078             // A user ID was deleted here. Go through all users and remove it
   11079             // from KeyStore.
   11080             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
   11081         }
   11082     }
   11083 
   11084     static boolean locationIsPrivileged(File path) {
   11085         try {
   11086             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
   11087                     .getCanonicalPath();
   11088             return path.getCanonicalPath().startsWith(privilegedAppDir);
   11089         } catch (IOException e) {
   11090             Slog.e(TAG, "Unable to access code path " + path);
   11091         }
   11092         return false;
   11093     }
   11094 
   11095     /*
   11096      * Tries to delete system package.
   11097      */
   11098     private boolean deleteSystemPackageLI(PackageSetting newPs,
   11099             int[] allUserHandles, boolean[] perUserInstalled,
   11100             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
   11101         final boolean applyUserRestrictions
   11102                 = (allUserHandles != null) && (perUserInstalled != null);
   11103         PackageSetting disabledPs = null;
   11104         // Confirm if the system package has been updated
   11105         // An updated system app can be deleted. This will also have to restore
   11106         // the system pkg from system partition
   11107         // reader
   11108         synchronized (mPackages) {
   11109             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
   11110         }
   11111         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
   11112                 + " disabledPs=" + disabledPs);
   11113         if (disabledPs == null) {
   11114             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
   11115             return false;
   11116         } else if (DEBUG_REMOVE) {
   11117             Slog.d(TAG, "Deleting system pkg from data partition");
   11118         }
   11119         if (DEBUG_REMOVE) {
   11120             if (applyUserRestrictions) {
   11121                 Slog.d(TAG, "Remembering install states:");
   11122                 for (int i = 0; i < allUserHandles.length; i++) {
   11123                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
   11124                 }
   11125             }
   11126         }
   11127         // Delete the updated package
   11128         outInfo.isRemovedPackageSystemUpdate = true;
   11129         if (disabledPs.versionCode < newPs.versionCode) {
   11130             // Delete data for downgrades
   11131             flags &= ~PackageManager.DELETE_KEEP_DATA;
   11132         } else {
   11133             // Preserve data by setting flag
   11134             flags |= PackageManager.DELETE_KEEP_DATA;
   11135         }
   11136         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
   11137                 allUserHandles, perUserInstalled, outInfo, writeSettings);
   11138         if (!ret) {
   11139             return false;
   11140         }
   11141         // writer
   11142         synchronized (mPackages) {
   11143             // Reinstate the old system package
   11144             mSettings.enableSystemPackageLPw(newPs.name);
   11145             // Remove any native libraries from the upgraded package.
   11146             NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
   11147         }
   11148         // Install the system package
   11149         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
   11150         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
   11151         if (locationIsPrivileged(disabledPs.codePath)) {
   11152             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   11153         }
   11154 
   11155         final PackageParser.Package newPkg;
   11156         try {
   11157             newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
   11158         } catch (PackageManagerException e) {
   11159             Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
   11160             return false;
   11161         }
   11162 
   11163         // writer
   11164         synchronized (mPackages) {
   11165             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
   11166             updatePermissionsLPw(newPkg.packageName, newPkg,
   11167                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
   11168             if (applyUserRestrictions) {
   11169                 if (DEBUG_REMOVE) {
   11170                     Slog.d(TAG, "Propagating install state across reinstall");
   11171                 }
   11172                 for (int i = 0; i < allUserHandles.length; i++) {
   11173                     if (DEBUG_REMOVE) {
   11174                         Slog.d(TAG, "    user " + allUserHandles[i]
   11175                                 + " => " + perUserInstalled[i]);
   11176                     }
   11177                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
   11178                 }
   11179                 // Regardless of writeSettings we need to ensure that this restriction
   11180                 // state propagation is persisted
   11181                 mSettings.writeAllUsersPackageRestrictionsLPr();
   11182             }
   11183             // can downgrade to reader here
   11184             if (writeSettings) {
   11185                 mSettings.writeLPr();
   11186             }
   11187         }
   11188         return true;
   11189     }
   11190 
   11191     private boolean deleteInstalledPackageLI(PackageSetting ps,
   11192             boolean deleteCodeAndResources, int flags,
   11193             int[] allUserHandles, boolean[] perUserInstalled,
   11194             PackageRemovedInfo outInfo, boolean writeSettings) {
   11195         if (outInfo != null) {
   11196             outInfo.uid = ps.appId;
   11197         }
   11198 
   11199         // Delete package data from internal structures and also remove data if flag is set
   11200         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
   11201 
   11202         // Delete application code and resources
   11203         if (deleteCodeAndResources && (outInfo != null)) {
   11204             outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   11205                     ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
   11206                     getAppDexInstructionSets(ps));
   11207             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
   11208         }
   11209         return true;
   11210     }
   11211 
   11212     @Override
   11213     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
   11214             int userId) {
   11215         mContext.enforceCallingOrSelfPermission(
   11216                 android.Manifest.permission.DELETE_PACKAGES, null);
   11217         synchronized (mPackages) {
   11218             PackageSetting ps = mSettings.mPackages.get(packageName);
   11219             if (ps == null) {
   11220                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
   11221                 return false;
   11222             }
   11223             if (!ps.getInstalled(userId)) {
   11224                 // Can't block uninstall for an app that is not installed or enabled.
   11225                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
   11226                 return false;
   11227             }
   11228             ps.setBlockUninstall(blockUninstall, userId);
   11229             mSettings.writePackageRestrictionsLPr(userId);
   11230         }
   11231         return true;
   11232     }
   11233 
   11234     @Override
   11235     public boolean getBlockUninstallForUser(String packageName, int userId) {
   11236         synchronized (mPackages) {
   11237             PackageSetting ps = mSettings.mPackages.get(packageName);
   11238             if (ps == null) {
   11239                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
   11240                 return false;
   11241             }
   11242             return ps.getBlockUninstall(userId);
   11243         }
   11244     }
   11245 
   11246     /*
   11247      * This method handles package deletion in general
   11248      */
   11249     private boolean deletePackageLI(String packageName, UserHandle user,
   11250             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
   11251             int flags, PackageRemovedInfo outInfo,
   11252             boolean writeSettings) {
   11253         if (packageName == null) {
   11254             Slog.w(TAG, "Attempt to delete null packageName.");
   11255             return false;
   11256         }
   11257         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
   11258         PackageSetting ps;
   11259         boolean dataOnly = false;
   11260         int removeUser = -1;
   11261         int appId = -1;
   11262         synchronized (mPackages) {
   11263             ps = mSettings.mPackages.get(packageName);
   11264             if (ps == null) {
   11265                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
   11266                 return false;
   11267             }
   11268             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
   11269                     && user.getIdentifier() != UserHandle.USER_ALL) {
   11270                 // The caller is asking that the package only be deleted for a single
   11271                 // user.  To do this, we just mark its uninstalled state and delete
   11272                 // its data.  If this is a system app, we only allow this to happen if
   11273                 // they have set the special DELETE_SYSTEM_APP which requests different
   11274                 // semantics than normal for uninstalling system apps.
   11275                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
   11276                 ps.setUserState(user.getIdentifier(),
   11277                         COMPONENT_ENABLED_STATE_DEFAULT,
   11278                         false, //installed
   11279                         true,  //stopped
   11280                         true,  //notLaunched
   11281                         false, //hidden
   11282                         null, null, null,
   11283                         false // blockUninstall
   11284                         );
   11285                 if (!isSystemApp(ps)) {
   11286                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
   11287                         // Other user still have this package installed, so all
   11288                         // we need to do is clear this user's data and save that
   11289                         // it is uninstalled.
   11290                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
   11291                         removeUser = user.getIdentifier();
   11292                         appId = ps.appId;
   11293                         mSettings.writePackageRestrictionsLPr(removeUser);
   11294                     } else {
   11295                         // We need to set it back to 'installed' so the uninstall
   11296                         // broadcasts will be sent correctly.
   11297                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
   11298                         ps.setInstalled(true, user.getIdentifier());
   11299                     }
   11300                 } else {
   11301                     // This is a system app, so we assume that the
   11302                     // other users still have this package installed, so all
   11303                     // we need to do is clear this user's data and save that
   11304                     // it is uninstalled.
   11305                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
   11306                     removeUser = user.getIdentifier();
   11307                     appId = ps.appId;
   11308                     mSettings.writePackageRestrictionsLPr(removeUser);
   11309                 }
   11310             }
   11311         }
   11312 
   11313         if (removeUser >= 0) {
   11314             // From above, we determined that we are deleting this only
   11315             // for a single user.  Continue the work here.
   11316             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
   11317             if (outInfo != null) {
   11318                 outInfo.removedPackage = packageName;
   11319                 outInfo.removedAppId = appId;
   11320                 outInfo.removedUsers = new int[] {removeUser};
   11321             }
   11322             mInstaller.clearUserData(packageName, removeUser);
   11323             removeKeystoreDataIfNeeded(removeUser, appId);
   11324             schedulePackageCleaning(packageName, removeUser, false);
   11325             return true;
   11326         }
   11327 
   11328         if (dataOnly) {
   11329             // Delete application data first
   11330             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
   11331             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
   11332             return true;
   11333         }
   11334 
   11335         boolean ret = false;
   11336         if (isSystemApp(ps)) {
   11337             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
   11338             // When an updated system application is deleted we delete the existing resources as well and
   11339             // fall back to existing code in system partition
   11340             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
   11341                     flags, outInfo, writeSettings);
   11342         } else {
   11343             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
   11344             // Kill application pre-emptively especially for apps on sd.
   11345             killApplication(packageName, ps.appId, "uninstall pkg");
   11346             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
   11347                     allUserHandles, perUserInstalled,
   11348                     outInfo, writeSettings);
   11349         }
   11350 
   11351         return ret;
   11352     }
   11353 
   11354     private final class ClearStorageConnection implements ServiceConnection {
   11355         IMediaContainerService mContainerService;
   11356 
   11357         @Override
   11358         public void onServiceConnected(ComponentName name, IBinder service) {
   11359             synchronized (this) {
   11360                 mContainerService = IMediaContainerService.Stub.asInterface(service);
   11361                 notifyAll();
   11362             }
   11363         }
   11364 
   11365         @Override
   11366         public void onServiceDisconnected(ComponentName name) {
   11367         }
   11368     }
   11369 
   11370     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
   11371         final boolean mounted;
   11372         if (Environment.isExternalStorageEmulated()) {
   11373             mounted = true;
   11374         } else {
   11375             final String status = Environment.getExternalStorageState();
   11376 
   11377             mounted = status.equals(Environment.MEDIA_MOUNTED)
   11378                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
   11379         }
   11380 
   11381         if (!mounted) {
   11382             return;
   11383         }
   11384 
   11385         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
   11386         int[] users;
   11387         if (userId == UserHandle.USER_ALL) {
   11388             users = sUserManager.getUserIds();
   11389         } else {
   11390             users = new int[] { userId };
   11391         }
   11392         final ClearStorageConnection conn = new ClearStorageConnection();
   11393         if (mContext.bindServiceAsUser(
   11394                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
   11395             try {
   11396                 for (int curUser : users) {
   11397                     long timeout = SystemClock.uptimeMillis() + 5000;
   11398                     synchronized (conn) {
   11399                         long now = SystemClock.uptimeMillis();
   11400                         while (conn.mContainerService == null && now < timeout) {
   11401                             try {
   11402                                 conn.wait(timeout - now);
   11403                             } catch (InterruptedException e) {
   11404                             }
   11405                         }
   11406                     }
   11407                     if (conn.mContainerService == null) {
   11408                         return;
   11409                     }
   11410 
   11411                     final UserEnvironment userEnv = new UserEnvironment(curUser);
   11412                     clearDirectory(conn.mContainerService,
   11413                             userEnv.buildExternalStorageAppCacheDirs(packageName));
   11414                     if (allData) {
   11415                         clearDirectory(conn.mContainerService,
   11416                                 userEnv.buildExternalStorageAppDataDirs(packageName));
   11417                         clearDirectory(conn.mContainerService,
   11418                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
   11419                     }
   11420                 }
   11421             } finally {
   11422                 mContext.unbindService(conn);
   11423             }
   11424         }
   11425     }
   11426 
   11427     @Override
   11428     public void clearApplicationUserData(final String packageName,
   11429             final IPackageDataObserver observer, final int userId) {
   11430         mContext.enforceCallingOrSelfPermission(
   11431                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
   11432         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
   11433         // Queue up an async operation since the package deletion may take a little while.
   11434         mHandler.post(new Runnable() {
   11435             public void run() {
   11436                 mHandler.removeCallbacks(this);
   11437                 final boolean succeeded;
   11438                 synchronized (mInstallLock) {
   11439                     succeeded = clearApplicationUserDataLI(packageName, userId);
   11440                 }
   11441                 clearExternalStorageDataSync(packageName, userId, true);
   11442                 if (succeeded) {
   11443                     // invoke DeviceStorageMonitor's update method to clear any notifications
   11444                     DeviceStorageMonitorInternal
   11445                             dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
   11446                     if (dsm != null) {
   11447                         dsm.checkMemory();
   11448                     }
   11449                 }
   11450                 if(observer != null) {
   11451                     try {
   11452                         observer.onRemoveCompleted(packageName, succeeded);
   11453                     } catch (RemoteException e) {
   11454                         Log.i(TAG, "Observer no longer exists.");
   11455                     }
   11456                 } //end if observer
   11457             } //end run
   11458         });
   11459     }
   11460 
   11461     private boolean clearApplicationUserDataLI(String packageName, int userId) {
   11462         if (packageName == null) {
   11463             Slog.w(TAG, "Attempt to delete null packageName.");
   11464             return false;
   11465         }
   11466 
   11467         // Try finding details about the requested package
   11468         PackageParser.Package pkg;
   11469         synchronized (mPackages) {
   11470             pkg = mPackages.get(packageName);
   11471             if (pkg == null) {
   11472                 final PackageSetting ps = mSettings.mPackages.get(packageName);
   11473                 if (ps != null) {
   11474                     pkg = ps.pkg;
   11475                 }
   11476             }
   11477         }
   11478 
   11479         if (pkg == null) {
   11480             Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
   11481         }
   11482 
   11483         // Always delete data directories for package, even if we found no other
   11484         // record of app. This helps users recover from UID mismatches without
   11485         // resorting to a full data wipe.
   11486         int retCode = mInstaller.clearUserData(packageName, userId);
   11487         if (retCode < 0) {
   11488             Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
   11489             return false;
   11490         }
   11491 
   11492         if (pkg == null) {
   11493             return false;
   11494         }
   11495 
   11496         if (pkg != null && pkg.applicationInfo != null) {
   11497             final int appId = pkg.applicationInfo.uid;
   11498             removeKeystoreDataIfNeeded(userId, appId);
   11499         }
   11500 
   11501         // Create a native library symlink only if we have native libraries
   11502         // and if the native libraries are 32 bit libraries. We do not provide
   11503         // this symlink for 64 bit libraries.
   11504         if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
   11505                 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
   11506             final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
   11507             if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
   11508                 Slog.w(TAG, "Failed linking native library dir");
   11509                 return false;
   11510             }
   11511         }
   11512 
   11513         return true;
   11514     }
   11515 
   11516     /**
   11517      * Remove entries from the keystore daemon. Will only remove it if the
   11518      * {@code appId} is valid.
   11519      */
   11520     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
   11521         if (appId < 0) {
   11522             return;
   11523         }
   11524 
   11525         final KeyStore keyStore = KeyStore.getInstance();
   11526         if (keyStore != null) {
   11527             if (userId == UserHandle.USER_ALL) {
   11528                 for (final int individual : sUserManager.getUserIds()) {
   11529                     keyStore.clearUid(UserHandle.getUid(individual, appId));
   11530                 }
   11531             } else {
   11532                 keyStore.clearUid(UserHandle.getUid(userId, appId));
   11533             }
   11534         } else {
   11535             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
   11536         }
   11537     }
   11538 
   11539     @Override
   11540     public void deleteApplicationCacheFiles(final String packageName,
   11541             final IPackageDataObserver observer) {
   11542         mContext.enforceCallingOrSelfPermission(
   11543                 android.Manifest.permission.DELETE_CACHE_FILES, null);
   11544         // Queue up an async operation since the package deletion may take a little while.
   11545         final int userId = UserHandle.getCallingUserId();
   11546         mHandler.post(new Runnable() {
   11547             public void run() {
   11548                 mHandler.removeCallbacks(this);
   11549                 final boolean succeded;
   11550                 synchronized (mInstallLock) {
   11551                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
   11552                 }
   11553                 clearExternalStorageDataSync(packageName, userId, false);
   11554                 if(observer != null) {
   11555                     try {
   11556                         observer.onRemoveCompleted(packageName, succeded);
   11557                     } catch (RemoteException e) {
   11558                         Log.i(TAG, "Observer no longer exists.");
   11559                     }
   11560                 } //end if observer
   11561             } //end run
   11562         });
   11563     }
   11564 
   11565     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
   11566         if (packageName == null) {
   11567             Slog.w(TAG, "Attempt to delete null packageName.");
   11568             return false;
   11569         }
   11570         PackageParser.Package p;
   11571         synchronized (mPackages) {
   11572             p = mPackages.get(packageName);
   11573         }
   11574         if (p == null) {
   11575             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   11576             return false;
   11577         }
   11578         final ApplicationInfo applicationInfo = p.applicationInfo;
   11579         if (applicationInfo == null) {
   11580             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
   11581             return false;
   11582         }
   11583         int retCode = mInstaller.deleteCacheFiles(packageName, userId);
   11584         if (retCode < 0) {
   11585             Slog.w(TAG, "Couldn't remove cache files for package: "
   11586                        + packageName + " u" + userId);
   11587             return false;
   11588         }
   11589         return true;
   11590     }
   11591 
   11592     @Override
   11593     public void getPackageSizeInfo(final String packageName, int userHandle,
   11594             final IPackageStatsObserver observer) {
   11595         mContext.enforceCallingOrSelfPermission(
   11596                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
   11597         if (packageName == null) {
   11598             throw new IllegalArgumentException("Attempt to get size of null packageName");
   11599         }
   11600 
   11601         PackageStats stats = new PackageStats(packageName, userHandle);
   11602 
   11603         /*
   11604          * Queue up an async operation since the package measurement may take a
   11605          * little while.
   11606          */
   11607         Message msg = mHandler.obtainMessage(INIT_COPY);
   11608         msg.obj = new MeasureParams(stats, observer);
   11609         mHandler.sendMessage(msg);
   11610     }
   11611 
   11612     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
   11613             PackageStats pStats) {
   11614         if (packageName == null) {
   11615             Slog.w(TAG, "Attempt to get size of null packageName.");
   11616             return false;
   11617         }
   11618         PackageParser.Package p;
   11619         boolean dataOnly = false;
   11620         String libDirRoot = null;
   11621         String asecPath = null;
   11622         PackageSetting ps = null;
   11623         synchronized (mPackages) {
   11624             p = mPackages.get(packageName);
   11625             ps = mSettings.mPackages.get(packageName);
   11626             if(p == null) {
   11627                 dataOnly = true;
   11628                 if((ps == null) || (ps.pkg == null)) {
   11629                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   11630                     return false;
   11631                 }
   11632                 p = ps.pkg;
   11633             }
   11634             if (ps != null) {
   11635                 libDirRoot = ps.legacyNativeLibraryPathString;
   11636             }
   11637             if (p != null && (isExternal(p) || isForwardLocked(p))) {
   11638                 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
   11639                 if (secureContainerId != null) {
   11640                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
   11641                 }
   11642             }
   11643         }
   11644         String publicSrcDir = null;
   11645         if(!dataOnly) {
   11646             final ApplicationInfo applicationInfo = p.applicationInfo;
   11647             if (applicationInfo == null) {
   11648                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
   11649                 return false;
   11650             }
   11651             if (isForwardLocked(p)) {
   11652                 publicSrcDir = applicationInfo.getBaseResourcePath();
   11653             }
   11654         }
   11655         // TODO: extend to measure size of split APKs
   11656         // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
   11657         // not just the first level.
   11658         // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
   11659         // just the primary.
   11660         String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
   11661         int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
   11662                 publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
   11663         if (res < 0) {
   11664             return false;
   11665         }
   11666 
   11667         // Fix-up for forward-locked applications in ASEC containers.
   11668         if (!isExternal(p)) {
   11669             pStats.codeSize += pStats.externalCodeSize;
   11670             pStats.externalCodeSize = 0L;
   11671         }
   11672 
   11673         return true;
   11674     }
   11675 
   11676 
   11677     @Override
   11678     public void addPackageToPreferred(String packageName) {
   11679         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
   11680     }
   11681 
   11682     @Override
   11683     public void removePackageFromPreferred(String packageName) {
   11684         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
   11685     }
   11686 
   11687     @Override
   11688     public List<PackageInfo> getPreferredPackages(int flags) {
   11689         return new ArrayList<PackageInfo>();
   11690     }
   11691 
   11692     private int getUidTargetSdkVersionLockedLPr(int uid) {
   11693         Object obj = mSettings.getUserIdLPr(uid);
   11694         if (obj instanceof SharedUserSetting) {
   11695             final SharedUserSetting sus = (SharedUserSetting) obj;
   11696             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
   11697             final Iterator<PackageSetting> it = sus.packages.iterator();
   11698             while (it.hasNext()) {
   11699                 final PackageSetting ps = it.next();
   11700                 if (ps.pkg != null) {
   11701                     int v = ps.pkg.applicationInfo.targetSdkVersion;
   11702                     if (v < vers) vers = v;
   11703                 }
   11704             }
   11705             return vers;
   11706         } else if (obj instanceof PackageSetting) {
   11707             final PackageSetting ps = (PackageSetting) obj;
   11708             if (ps.pkg != null) {
   11709                 return ps.pkg.applicationInfo.targetSdkVersion;
   11710             }
   11711         }
   11712         return Build.VERSION_CODES.CUR_DEVELOPMENT;
   11713     }
   11714 
   11715     @Override
   11716     public void addPreferredActivity(IntentFilter filter, int match,
   11717             ComponentName[] set, ComponentName activity, int userId) {
   11718         addPreferredActivityInternal(filter, match, set, activity, true, userId,
   11719                 "Adding preferred");
   11720     }
   11721 
   11722     private void addPreferredActivityInternal(IntentFilter filter, int match,
   11723             ComponentName[] set, ComponentName activity, boolean always, int userId,
   11724             String opname) {
   11725         // writer
   11726         int callingUid = Binder.getCallingUid();
   11727         enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
   11728         if (filter.countActions() == 0) {
   11729             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
   11730             return;
   11731         }
   11732         synchronized (mPackages) {
   11733             if (mContext.checkCallingOrSelfPermission(
   11734                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   11735                     != PackageManager.PERMISSION_GRANTED) {
   11736                 if (getUidTargetSdkVersionLockedLPr(callingUid)
   11737                         < Build.VERSION_CODES.FROYO) {
   11738                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
   11739                             + callingUid);
   11740                     return;
   11741                 }
   11742                 mContext.enforceCallingOrSelfPermission(
   11743                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   11744             }
   11745 
   11746             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
   11747             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
   11748                     + userId + ":");
   11749             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11750             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
   11751             scheduleWritePackageRestrictionsLocked(userId);
   11752         }
   11753     }
   11754 
   11755     @Override
   11756     public void replacePreferredActivity(IntentFilter filter, int match,
   11757             ComponentName[] set, ComponentName activity, int userId) {
   11758         if (filter.countActions() != 1) {
   11759             throw new IllegalArgumentException(
   11760                     "replacePreferredActivity expects filter to have only 1 action.");
   11761         }
   11762         if (filter.countDataAuthorities() != 0
   11763                 || filter.countDataPaths() != 0
   11764                 || filter.countDataSchemes() > 1
   11765                 || filter.countDataTypes() != 0) {
   11766             throw new IllegalArgumentException(
   11767                     "replacePreferredActivity expects filter to have no data authorities, " +
   11768                     "paths, or types; and at most one scheme.");
   11769         }
   11770 
   11771         final int callingUid = Binder.getCallingUid();
   11772         enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
   11773         synchronized (mPackages) {
   11774             if (mContext.checkCallingOrSelfPermission(
   11775                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   11776                     != PackageManager.PERMISSION_GRANTED) {
   11777                 if (getUidTargetSdkVersionLockedLPr(callingUid)
   11778                         < Build.VERSION_CODES.FROYO) {
   11779                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
   11780                             + Binder.getCallingUid());
   11781                     return;
   11782                 }
   11783                 mContext.enforceCallingOrSelfPermission(
   11784                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   11785             }
   11786 
   11787             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   11788             if (pir != null) {
   11789                 // Get all of the existing entries that exactly match this filter.
   11790                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
   11791                 if (existing != null && existing.size() == 1) {
   11792                     PreferredActivity cur = existing.get(0);
   11793                     if (DEBUG_PREFERRED) {
   11794                         Slog.i(TAG, "Checking replace of preferred:");
   11795                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11796                         if (!cur.mPref.mAlways) {
   11797                             Slog.i(TAG, "  -- CUR; not mAlways!");
   11798                         } else {
   11799                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
   11800                             Slog.i(TAG, "  -- CUR: mSet="
   11801                                     + Arrays.toString(cur.mPref.mSetComponents));
   11802                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
   11803                             Slog.i(TAG, "  -- NEW: mMatch="
   11804                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
   11805                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
   11806                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
   11807                         }
   11808                     }
   11809                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
   11810                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
   11811                             && cur.mPref.sameSet(set)) {
   11812                         // Setting the preferred activity to what it happens to be already
   11813                         if (DEBUG_PREFERRED) {
   11814                             Slog.i(TAG, "Replacing with same preferred activity "
   11815                                     + cur.mPref.mShortComponent + " for user "
   11816                                     + userId + ":");
   11817                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11818                         }
   11819                         return;
   11820                     }
   11821                 }
   11822 
   11823                 if (existing != null) {
   11824                     if (DEBUG_PREFERRED) {
   11825                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
   11826                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11827                     }
   11828                     for (int i = 0; i < existing.size(); i++) {
   11829                         PreferredActivity pa = existing.get(i);
   11830                         if (DEBUG_PREFERRED) {
   11831                             Slog.i(TAG, "Removing existing preferred activity "
   11832                                     + pa.mPref.mComponent + ":");
   11833                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11834                         }
   11835                         pir.removeFilter(pa);
   11836                     }
   11837                 }
   11838             }
   11839             addPreferredActivityInternal(filter, match, set, activity, true, userId,
   11840                     "Replacing preferred");
   11841         }
   11842     }
   11843 
   11844     @Override
   11845     public void clearPackagePreferredActivities(String packageName) {
   11846         final int uid = Binder.getCallingUid();
   11847         // writer
   11848         synchronized (mPackages) {
   11849             PackageParser.Package pkg = mPackages.get(packageName);
   11850             if (pkg == null || pkg.applicationInfo.uid != uid) {
   11851                 if (mContext.checkCallingOrSelfPermission(
   11852                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   11853                         != PackageManager.PERMISSION_GRANTED) {
   11854                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
   11855                             < Build.VERSION_CODES.FROYO) {
   11856                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
   11857                                 + Binder.getCallingUid());
   11858                         return;
   11859                     }
   11860                     mContext.enforceCallingOrSelfPermission(
   11861                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   11862                 }
   11863             }
   11864 
   11865             int user = UserHandle.getCallingUserId();
   11866             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
   11867                 scheduleWritePackageRestrictionsLocked(user);
   11868             }
   11869         }
   11870     }
   11871 
   11872     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
   11873     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
   11874         ArrayList<PreferredActivity> removed = null;
   11875         boolean changed = false;
   11876         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   11877             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
   11878             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   11879             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
   11880                 continue;
   11881             }
   11882             Iterator<PreferredActivity> it = pir.filterIterator();
   11883             while (it.hasNext()) {
   11884                 PreferredActivity pa = it.next();
   11885                 // Mark entry for removal only if it matches the package name
   11886                 // and the entry is of type "always".
   11887                 if (packageName == null ||
   11888                         (pa.mPref.mComponent.getPackageName().equals(packageName)
   11889                                 && pa.mPref.mAlways)) {
   11890                     if (removed == null) {
   11891                         removed = new ArrayList<PreferredActivity>();
   11892                     }
   11893                     removed.add(pa);
   11894                 }
   11895             }
   11896             if (removed != null) {
   11897                 for (int j=0; j<removed.size(); j++) {
   11898                     PreferredActivity pa = removed.get(j);
   11899                     pir.removeFilter(pa);
   11900                 }
   11901                 changed = true;
   11902             }
   11903         }
   11904         return changed;
   11905     }
   11906 
   11907     @Override
   11908     public void resetPreferredActivities(int userId) {
   11909         /* TODO: Actually use userId. Why is it being passed in? */
   11910         mContext.enforceCallingOrSelfPermission(
   11911                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   11912         // writer
   11913         synchronized (mPackages) {
   11914             int user = UserHandle.getCallingUserId();
   11915             clearPackagePreferredActivitiesLPw(null, user);
   11916             mSettings.readDefaultPreferredAppsLPw(this, user);
   11917             scheduleWritePackageRestrictionsLocked(user);
   11918         }
   11919     }
   11920 
   11921     @Override
   11922     public int getPreferredActivities(List<IntentFilter> outFilters,
   11923             List<ComponentName> outActivities, String packageName) {
   11924 
   11925         int num = 0;
   11926         final int userId = UserHandle.getCallingUserId();
   11927         // reader
   11928         synchronized (mPackages) {
   11929             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   11930             if (pir != null) {
   11931                 final Iterator<PreferredActivity> it = pir.filterIterator();
   11932                 while (it.hasNext()) {
   11933                     final PreferredActivity pa = it.next();
   11934                     if (packageName == null
   11935                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
   11936                                     && pa.mPref.mAlways)) {
   11937                         if (outFilters != null) {
   11938                             outFilters.add(new IntentFilter(pa));
   11939                         }
   11940                         if (outActivities != null) {
   11941                             outActivities.add(pa.mPref.mComponent);
   11942                         }
   11943                     }
   11944                 }
   11945             }
   11946         }
   11947 
   11948         return num;
   11949     }
   11950 
   11951     @Override
   11952     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
   11953             int userId) {
   11954         int callingUid = Binder.getCallingUid();
   11955         if (callingUid != Process.SYSTEM_UID) {
   11956             throw new SecurityException(
   11957                     "addPersistentPreferredActivity can only be run by the system");
   11958         }
   11959         if (filter.countActions() == 0) {
   11960             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
   11961             return;
   11962         }
   11963         synchronized (mPackages) {
   11964             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
   11965                     " :");
   11966             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11967             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
   11968                     new PersistentPreferredActivity(filter, activity));
   11969             scheduleWritePackageRestrictionsLocked(userId);
   11970         }
   11971     }
   11972 
   11973     @Override
   11974     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
   11975         int callingUid = Binder.getCallingUid();
   11976         if (callingUid != Process.SYSTEM_UID) {
   11977             throw new SecurityException(
   11978                     "clearPackagePersistentPreferredActivities can only be run by the system");
   11979         }
   11980         ArrayList<PersistentPreferredActivity> removed = null;
   11981         boolean changed = false;
   11982         synchronized (mPackages) {
   11983             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
   11984                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
   11985                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
   11986                         .valueAt(i);
   11987                 if (userId != thisUserId) {
   11988                     continue;
   11989                 }
   11990                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
   11991                 while (it.hasNext()) {
   11992                     PersistentPreferredActivity ppa = it.next();
   11993                     // Mark entry for removal only if it matches the package name.
   11994                     if (ppa.mComponent.getPackageName().equals(packageName)) {
   11995                         if (removed == null) {
   11996                             removed = new ArrayList<PersistentPreferredActivity>();
   11997                         }
   11998                         removed.add(ppa);
   11999                     }
   12000                 }
   12001                 if (removed != null) {
   12002                     for (int j=0; j<removed.size(); j++) {
   12003                         PersistentPreferredActivity ppa = removed.get(j);
   12004                         ppir.removeFilter(ppa);
   12005                     }
   12006                     changed = true;
   12007                 }
   12008             }
   12009 
   12010             if (changed) {
   12011                 scheduleWritePackageRestrictionsLocked(userId);
   12012             }
   12013         }
   12014     }
   12015 
   12016     @Override
   12017     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
   12018             int ownerUserId, int sourceUserId, int targetUserId, int flags) {
   12019         mContext.enforceCallingOrSelfPermission(
   12020                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   12021         int callingUid = Binder.getCallingUid();
   12022         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
   12023         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
   12024         if (intentFilter.countActions() == 0) {
   12025             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
   12026             return;
   12027         }
   12028         synchronized (mPackages) {
   12029             CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
   12030                     ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
   12031             CrossProfileIntentResolver resolver =
   12032                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
   12033             ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
   12034             // We have all those whose filter is equal. Now checking if the rest is equal as well.
   12035             if (existing != null) {
   12036                 int size = existing.size();
   12037                 for (int i = 0; i < size; i++) {
   12038                     if (newFilter.equalsIgnoreFilter(existing.get(i))) {
   12039                         return;
   12040                     }
   12041                 }
   12042             }
   12043             resolver.addFilter(newFilter);
   12044             scheduleWritePackageRestrictionsLocked(sourceUserId);
   12045         }
   12046     }
   12047 
   12048     @Override
   12049     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
   12050             int ownerUserId) {
   12051         mContext.enforceCallingOrSelfPermission(
   12052                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   12053         int callingUid = Binder.getCallingUid();
   12054         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
   12055         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
   12056         int callingUserId = UserHandle.getUserId(callingUid);
   12057         synchronized (mPackages) {
   12058             CrossProfileIntentResolver resolver =
   12059                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
   12060             ArraySet<CrossProfileIntentFilter> set =
   12061                     new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
   12062             for (CrossProfileIntentFilter filter : set) {
   12063                 if (filter.getOwnerPackage().equals(ownerPackage)
   12064                         && filter.getOwnerUserId() == callingUserId) {
   12065                     resolver.removeFilter(filter);
   12066                 }
   12067             }
   12068             scheduleWritePackageRestrictionsLocked(sourceUserId);
   12069         }
   12070     }
   12071 
   12072     // Enforcing that callingUid is owning pkg on userId
   12073     private void enforceOwnerRights(String pkg, int userId, int callingUid) {
   12074         // The system owns everything.
   12075         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
   12076             return;
   12077         }
   12078         int callingUserId = UserHandle.getUserId(callingUid);
   12079         if (callingUserId != userId) {
   12080             throw new SecurityException("calling uid " + callingUid
   12081                     + " pretends to own " + pkg + " on user " + userId + " but belongs to user "
   12082                     + callingUserId);
   12083         }
   12084         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
   12085         if (pi == null) {
   12086             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
   12087                     + callingUserId);
   12088         }
   12089         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
   12090             throw new SecurityException("Calling uid " + callingUid
   12091                     + " does not own package " + pkg);
   12092         }
   12093     }
   12094 
   12095     @Override
   12096     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
   12097         Intent intent = new Intent(Intent.ACTION_MAIN);
   12098         intent.addCategory(Intent.CATEGORY_HOME);
   12099 
   12100         final int callingUserId = UserHandle.getCallingUserId();
   12101         List<ResolveInfo> list = queryIntentActivities(intent, null,
   12102                 PackageManager.GET_META_DATA, callingUserId);
   12103         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
   12104                 true, false, false, callingUserId);
   12105 
   12106         allHomeCandidates.clear();
   12107         if (list != null) {
   12108             for (ResolveInfo ri : list) {
   12109                 allHomeCandidates.add(ri);
   12110             }
   12111         }
   12112         return (preferred == null || preferred.activityInfo == null)
   12113                 ? null
   12114                 : new ComponentName(preferred.activityInfo.packageName,
   12115                         preferred.activityInfo.name);
   12116     }
   12117 
   12118     @Override
   12119     public void setApplicationEnabledSetting(String appPackageName,
   12120             int newState, int flags, int userId, String callingPackage) {
   12121         if (!sUserManager.exists(userId)) return;
   12122         if (callingPackage == null) {
   12123             callingPackage = Integer.toString(Binder.getCallingUid());
   12124         }
   12125         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
   12126     }
   12127 
   12128     @Override
   12129     public void setComponentEnabledSetting(ComponentName componentName,
   12130             int newState, int flags, int userId) {
   12131         if (!sUserManager.exists(userId)) return;
   12132         setEnabledSetting(componentName.getPackageName(),
   12133                 componentName.getClassName(), newState, flags, userId, null);
   12134     }
   12135 
   12136     private void setEnabledSetting(final String packageName, String className, int newState,
   12137             final int flags, int userId, String callingPackage) {
   12138         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
   12139               || newState == COMPONENT_ENABLED_STATE_ENABLED
   12140               || newState == COMPONENT_ENABLED_STATE_DISABLED
   12141               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
   12142               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
   12143             throw new IllegalArgumentException("Invalid new component state: "
   12144                     + newState);
   12145         }
   12146         PackageSetting pkgSetting;
   12147         final int uid = Binder.getCallingUid();
   12148         final int permission = mContext.checkCallingOrSelfPermission(
   12149                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
   12150         enforceCrossUserPermission(uid, userId, false, true, "set enabled");
   12151         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
   12152         boolean sendNow = false;
   12153         boolean isApp = (className == null);
   12154         String componentName = isApp ? packageName : className;
   12155         int packageUid = -1;
   12156         ArrayList<String> components;
   12157 
   12158         // writer
   12159         synchronized (mPackages) {
   12160             pkgSetting = mSettings.mPackages.get(packageName);
   12161             if (pkgSetting == null) {
   12162                 if (className == null) {
   12163                     throw new IllegalArgumentException(
   12164                             "Unknown package: " + packageName);
   12165                 }
   12166                 throw new IllegalArgumentException(
   12167                         "Unknown component: " + packageName
   12168                         + "/" + className);
   12169             }
   12170             // Allow root and verify that userId is not being specified by a different user
   12171             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
   12172                 throw new SecurityException(
   12173                         "Permission Denial: attempt to change component state from pid="
   12174                         + Binder.getCallingPid()
   12175                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
   12176             }
   12177             if (className == null) {
   12178                 // We're dealing with an application/package level state change
   12179                 if (pkgSetting.getEnabled(userId) == newState) {
   12180                     // Nothing to do
   12181                     return;
   12182                 }
   12183                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
   12184                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
   12185                     // Don't care about who enables an app.
   12186                     callingPackage = null;
   12187                 }
   12188                 pkgSetting.setEnabled(newState, userId, callingPackage);
   12189                 // pkgSetting.pkg.mSetEnabled = newState;
   12190             } else {
   12191                 // We're dealing with a component level state change
   12192                 // First, verify that this is a valid class name.
   12193                 PackageParser.Package pkg = pkgSetting.pkg;
   12194                 if (pkg == null || !pkg.hasComponentClassName(className)) {
   12195                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
   12196                         throw new IllegalArgumentException("Component class " + className
   12197                                 + " does not exist in " + packageName);
   12198                     } else {
   12199                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
   12200                                 + className + " does not exist in " + packageName);
   12201                     }
   12202                 }
   12203                 switch (newState) {
   12204                 case COMPONENT_ENABLED_STATE_ENABLED:
   12205                     if (!pkgSetting.enableComponentLPw(className, userId)) {
   12206                         return;
   12207                     }
   12208                     break;
   12209                 case COMPONENT_ENABLED_STATE_DISABLED:
   12210                     if (!pkgSetting.disableComponentLPw(className, userId)) {
   12211                         return;
   12212                     }
   12213                     break;
   12214                 case COMPONENT_ENABLED_STATE_DEFAULT:
   12215                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
   12216                         return;
   12217                     }
   12218                     break;
   12219                 default:
   12220                     Slog.e(TAG, "Invalid new component state: " + newState);
   12221                     return;
   12222                 }
   12223             }
   12224             mSettings.writePackageRestrictionsLPr(userId);
   12225             components = mPendingBroadcasts.get(userId, packageName);
   12226             final boolean newPackage = components == null;
   12227             if (newPackage) {
   12228                 components = new ArrayList<String>();
   12229             }
   12230             if (!components.contains(componentName)) {
   12231                 components.add(componentName);
   12232             }
   12233             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
   12234                 sendNow = true;
   12235                 // Purge entry from pending broadcast list if another one exists already
   12236                 // since we are sending one right away.
   12237                 mPendingBroadcasts.remove(userId, packageName);
   12238             } else {
   12239                 if (newPackage) {
   12240                     mPendingBroadcasts.put(userId, packageName, components);
   12241                 }
   12242                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
   12243                     // Schedule a message
   12244                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
   12245                 }
   12246             }
   12247         }
   12248 
   12249         long callingId = Binder.clearCallingIdentity();
   12250         try {
   12251             if (sendNow) {
   12252                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
   12253                 sendPackageChangedBroadcast(packageName,
   12254                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
   12255             }
   12256         } finally {
   12257             Binder.restoreCallingIdentity(callingId);
   12258         }
   12259     }
   12260 
   12261     private void sendPackageChangedBroadcast(String packageName,
   12262             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
   12263         if (DEBUG_INSTALL)
   12264             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
   12265                     + componentNames);
   12266         Bundle extras = new Bundle(4);
   12267         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
   12268         String nameList[] = new String[componentNames.size()];
   12269         componentNames.toArray(nameList);
   12270         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
   12271         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
   12272         extras.putInt(Intent.EXTRA_UID, packageUid);
   12273         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
   12274                 new int[] {UserHandle.getUserId(packageUid)});
   12275     }
   12276 
   12277     @Override
   12278     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
   12279         if (!sUserManager.exists(userId)) return;
   12280         final int uid = Binder.getCallingUid();
   12281         final int permission = mContext.checkCallingOrSelfPermission(
   12282                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
   12283         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
   12284         enforceCrossUserPermission(uid, userId, true, true, "stop package");
   12285         // writer
   12286         synchronized (mPackages) {
   12287             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
   12288                     uid, userId)) {
   12289                 scheduleWritePackageRestrictionsLocked(userId);
   12290             }
   12291         }
   12292     }
   12293 
   12294     @Override
   12295     public String getInstallerPackageName(String packageName) {
   12296         // reader
   12297         synchronized (mPackages) {
   12298             return mSettings.getInstallerPackageNameLPr(packageName);
   12299         }
   12300     }
   12301 
   12302     @Override
   12303     public int getApplicationEnabledSetting(String packageName, int userId) {
   12304         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
   12305         int uid = Binder.getCallingUid();
   12306         enforceCrossUserPermission(uid, userId, false, false, "get enabled");
   12307         // reader
   12308         synchronized (mPackages) {
   12309             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
   12310         }
   12311     }
   12312 
   12313     @Override
   12314     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
   12315         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
   12316         int uid = Binder.getCallingUid();
   12317         enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
   12318         // reader
   12319         synchronized (mPackages) {
   12320             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
   12321         }
   12322     }
   12323 
   12324     @Override
   12325     public void enterSafeMode() {
   12326         enforceSystemOrRoot("Only the system can request entering safe mode");
   12327 
   12328         if (!mSystemReady) {
   12329             mSafeMode = true;
   12330         }
   12331     }
   12332 
   12333     @Override
   12334     public void systemReady() {
   12335         mSystemReady = true;
   12336 
   12337         // Read the compatibilty setting when the system is ready.
   12338         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
   12339                 mContext.getContentResolver(),
   12340                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
   12341         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
   12342         if (DEBUG_SETTINGS) {
   12343             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
   12344         }
   12345 
   12346         synchronized (mPackages) {
   12347             // Verify that all of the preferred activity components actually
   12348             // exist.  It is possible for applications to be updated and at
   12349             // that point remove a previously declared activity component that
   12350             // had been set as a preferred activity.  We try to clean this up
   12351             // the next time we encounter that preferred activity, but it is
   12352             // possible for the user flow to never be able to return to that
   12353             // situation so here we do a sanity check to make sure we haven't
   12354             // left any junk around.
   12355             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
   12356             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   12357                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   12358                 removed.clear();
   12359                 for (PreferredActivity pa : pir.filterSet()) {
   12360                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
   12361                         removed.add(pa);
   12362                     }
   12363                 }
   12364                 if (removed.size() > 0) {
   12365                     for (int r=0; r<removed.size(); r++) {
   12366                         PreferredActivity pa = removed.get(r);
   12367                         Slog.w(TAG, "Removing dangling preferred activity: "
   12368                                 + pa.mPref.mComponent);
   12369                         pir.removeFilter(pa);
   12370                     }
   12371                     mSettings.writePackageRestrictionsLPr(
   12372                             mSettings.mPreferredActivities.keyAt(i));
   12373                 }
   12374             }
   12375         }
   12376         sUserManager.systemReady();
   12377 
   12378         // Kick off any messages waiting for system ready
   12379         if (mPostSystemReadyMessages != null) {
   12380             for (Message msg : mPostSystemReadyMessages) {
   12381                 msg.sendToTarget();
   12382             }
   12383             mPostSystemReadyMessages = null;
   12384         }
   12385     }
   12386 
   12387     @Override
   12388     public boolean isSafeMode() {
   12389         return mSafeMode;
   12390     }
   12391 
   12392     @Override
   12393     public boolean hasSystemUidErrors() {
   12394         return mHasSystemUidErrors;
   12395     }
   12396 
   12397     static String arrayToString(int[] array) {
   12398         StringBuffer buf = new StringBuffer(128);
   12399         buf.append('[');
   12400         if (array != null) {
   12401             for (int i=0; i<array.length; i++) {
   12402                 if (i > 0) buf.append(", ");
   12403                 buf.append(array[i]);
   12404             }
   12405         }
   12406         buf.append(']');
   12407         return buf.toString();
   12408     }
   12409 
   12410     static class DumpState {
   12411         public static final int DUMP_LIBS = 1 << 0;
   12412         public static final int DUMP_FEATURES = 1 << 1;
   12413         public static final int DUMP_RESOLVERS = 1 << 2;
   12414         public static final int DUMP_PERMISSIONS = 1 << 3;
   12415         public static final int DUMP_PACKAGES = 1 << 4;
   12416         public static final int DUMP_SHARED_USERS = 1 << 5;
   12417         public static final int DUMP_MESSAGES = 1 << 6;
   12418         public static final int DUMP_PROVIDERS = 1 << 7;
   12419         public static final int DUMP_VERIFIERS = 1 << 8;
   12420         public static final int DUMP_PREFERRED = 1 << 9;
   12421         public static final int DUMP_PREFERRED_XML = 1 << 10;
   12422         public static final int DUMP_KEYSETS = 1 << 11;
   12423         public static final int DUMP_VERSION = 1 << 12;
   12424         public static final int DUMP_INSTALLS = 1 << 13;
   12425 
   12426         public static final int OPTION_SHOW_FILTERS = 1 << 0;
   12427 
   12428         private int mTypes;
   12429 
   12430         private int mOptions;
   12431 
   12432         private boolean mTitlePrinted;
   12433 
   12434         private SharedUserSetting mSharedUser;
   12435 
   12436         public boolean isDumping(int type) {
   12437             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
   12438                 return true;
   12439             }
   12440 
   12441             return (mTypes & type) != 0;
   12442         }
   12443 
   12444         public void setDump(int type) {
   12445             mTypes |= type;
   12446         }
   12447 
   12448         public boolean isOptionEnabled(int option) {
   12449             return (mOptions & option) != 0;
   12450         }
   12451 
   12452         public void setOptionEnabled(int option) {
   12453             mOptions |= option;
   12454         }
   12455 
   12456         public boolean onTitlePrinted() {
   12457             final boolean printed = mTitlePrinted;
   12458             mTitlePrinted = true;
   12459             return printed;
   12460         }
   12461 
   12462         public boolean getTitlePrinted() {
   12463             return mTitlePrinted;
   12464         }
   12465 
   12466         public void setTitlePrinted(boolean enabled) {
   12467             mTitlePrinted = enabled;
   12468         }
   12469 
   12470         public SharedUserSetting getSharedUser() {
   12471             return mSharedUser;
   12472         }
   12473 
   12474         public void setSharedUser(SharedUserSetting user) {
   12475             mSharedUser = user;
   12476         }
   12477     }
   12478 
   12479     @Override
   12480     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   12481         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
   12482                 != PackageManager.PERMISSION_GRANTED) {
   12483             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   12484                     + Binder.getCallingPid()
   12485                     + ", uid=" + Binder.getCallingUid()
   12486                     + " without permission "
   12487                     + android.Manifest.permission.DUMP);
   12488             return;
   12489         }
   12490 
   12491         DumpState dumpState = new DumpState();
   12492         boolean fullPreferred = false;
   12493         boolean checkin = false;
   12494 
   12495         String packageName = null;
   12496 
   12497         int opti = 0;
   12498         while (opti < args.length) {
   12499             String opt = args[opti];
   12500             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   12501                 break;
   12502             }
   12503             opti++;
   12504 
   12505             if ("-a".equals(opt)) {
   12506                 // Right now we only know how to print all.
   12507             } else if ("-h".equals(opt)) {
   12508                 pw.println("Package manager dump options:");
   12509                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
   12510                 pw.println("    --checkin: dump for a checkin");
   12511                 pw.println("    -f: print details of intent filters");
   12512                 pw.println("    -h: print this help");
   12513                 pw.println("  cmd may be one of:");
   12514                 pw.println("    l[ibraries]: list known shared libraries");
   12515                 pw.println("    f[ibraries]: list device features");
   12516                 pw.println("    k[eysets]: print known keysets");
   12517                 pw.println("    r[esolvers]: dump intent resolvers");
   12518                 pw.println("    perm[issions]: dump permissions");
   12519                 pw.println("    pref[erred]: print preferred package settings");
   12520                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
   12521                 pw.println("    prov[iders]: dump content providers");
   12522                 pw.println("    p[ackages]: dump installed packages");
   12523                 pw.println("    s[hared-users]: dump shared user IDs");
   12524                 pw.println("    m[essages]: print collected runtime messages");
   12525                 pw.println("    v[erifiers]: print package verifier info");
   12526                 pw.println("    version: print database version info");
   12527                 pw.println("    write: write current settings now");
   12528                 pw.println("    <package.name>: info about given package");
   12529                 pw.println("    installs: details about install sessions");
   12530                 return;
   12531             } else if ("--checkin".equals(opt)) {
   12532                 checkin = true;
   12533             } else if ("-f".equals(opt)) {
   12534                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
   12535             } else {
   12536                 pw.println("Unknown argument: " + opt + "; use -h for help");
   12537             }
   12538         }
   12539 
   12540         // Is the caller requesting to dump a particular piece of data?
   12541         if (opti < args.length) {
   12542             String cmd = args[opti];
   12543             opti++;
   12544             // Is this a package name?
   12545             if ("android".equals(cmd) || cmd.contains(".")) {
   12546                 packageName = cmd;
   12547                 // When dumping a single package, we always dump all of its
   12548                 // filter information since the amount of data will be reasonable.
   12549                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
   12550             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
   12551                 dumpState.setDump(DumpState.DUMP_LIBS);
   12552             } else if ("f".equals(cmd) || "features".equals(cmd)) {
   12553                 dumpState.setDump(DumpState.DUMP_FEATURES);
   12554             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
   12555                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
   12556             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
   12557                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
   12558             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
   12559                 dumpState.setDump(DumpState.DUMP_PREFERRED);
   12560             } else if ("preferred-xml".equals(cmd)) {
   12561                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
   12562                 if (opti < args.length && "--full".equals(args[opti])) {
   12563                     fullPreferred = true;
   12564                     opti++;
   12565                 }
   12566             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
   12567                 dumpState.setDump(DumpState.DUMP_PACKAGES);
   12568             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
   12569                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
   12570             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
   12571                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
   12572             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
   12573                 dumpState.setDump(DumpState.DUMP_MESSAGES);
   12574             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
   12575                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
   12576             } else if ("version".equals(cmd)) {
   12577                 dumpState.setDump(DumpState.DUMP_VERSION);
   12578             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
   12579                 dumpState.setDump(DumpState.DUMP_KEYSETS);
   12580             } else if ("installs".equals(cmd)) {
   12581                 dumpState.setDump(DumpState.DUMP_INSTALLS);
   12582             } else if ("write".equals(cmd)) {
   12583                 synchronized (mPackages) {
   12584                     mSettings.writeLPr();
   12585                     pw.println("Settings written.");
   12586                     return;
   12587                 }
   12588             }
   12589         }
   12590 
   12591         if (checkin) {
   12592             pw.println("vers,1");
   12593         }
   12594 
   12595         // reader
   12596         synchronized (mPackages) {
   12597             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
   12598                 if (!checkin) {
   12599                     if (dumpState.onTitlePrinted())
   12600                         pw.println();
   12601                     pw.println("Database versions:");
   12602                     pw.print("  SDK Version:");
   12603                     pw.print(" internal=");
   12604                     pw.print(mSettings.mInternalSdkPlatform);
   12605                     pw.print(" external=");
   12606                     pw.println(mSettings.mExternalSdkPlatform);
   12607                     pw.print("  DB Version:");
   12608                     pw.print(" internal=");
   12609                     pw.print(mSettings.mInternalDatabaseVersion);
   12610                     pw.print(" external=");
   12611                     pw.println(mSettings.mExternalDatabaseVersion);
   12612                 }
   12613             }
   12614 
   12615             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
   12616                 if (!checkin) {
   12617                     if (dumpState.onTitlePrinted())
   12618                         pw.println();
   12619                     pw.println("Verifiers:");
   12620                     pw.print("  Required: ");
   12621                     pw.print(mRequiredVerifierPackage);
   12622                     pw.print(" (uid=");
   12623                     pw.print(getPackageUid(mRequiredVerifierPackage, 0));
   12624                     pw.println(")");
   12625                 } else if (mRequiredVerifierPackage != null) {
   12626                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
   12627                     pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
   12628                 }
   12629             }
   12630 
   12631             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
   12632                 boolean printedHeader = false;
   12633                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
   12634                 while (it.hasNext()) {
   12635                     String name = it.next();
   12636                     SharedLibraryEntry ent = mSharedLibraries.get(name);
   12637                     if (!checkin) {
   12638                         if (!printedHeader) {
   12639                             if (dumpState.onTitlePrinted())
   12640                                 pw.println();
   12641                             pw.println("Libraries:");
   12642                             printedHeader = true;
   12643                         }
   12644                         pw.print("  ");
   12645                     } else {
   12646                         pw.print("lib,");
   12647                     }
   12648                     pw.print(name);
   12649                     if (!checkin) {
   12650                         pw.print(" -> ");
   12651                     }
   12652                     if (ent.path != null) {
   12653                         if (!checkin) {
   12654                             pw.print("(jar) ");
   12655                             pw.print(ent.path);
   12656                         } else {
   12657                             pw.print(",jar,");
   12658                             pw.print(ent.path);
   12659                         }
   12660                     } else {
   12661                         if (!checkin) {
   12662                             pw.print("(apk) ");
   12663                             pw.print(ent.apk);
   12664                         } else {
   12665                             pw.print(",apk,");
   12666                             pw.print(ent.apk);
   12667                         }
   12668                     }
   12669                     pw.println();
   12670                 }
   12671             }
   12672 
   12673             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
   12674                 if (dumpState.onTitlePrinted())
   12675                     pw.println();
   12676                 if (!checkin) {
   12677                     pw.println("Features:");
   12678                 }
   12679                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
   12680                 while (it.hasNext()) {
   12681                     String name = it.next();
   12682                     if (!checkin) {
   12683                         pw.print("  ");
   12684                     } else {
   12685                         pw.print("feat,");
   12686                     }
   12687                     pw.println(name);
   12688                 }
   12689             }
   12690 
   12691             if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
   12692                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
   12693                         : "Activity Resolver Table:", "  ", packageName,
   12694                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
   12695                     dumpState.setTitlePrinted(true);
   12696                 }
   12697                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
   12698                         : "Receiver Resolver Table:", "  ", packageName,
   12699                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
   12700                     dumpState.setTitlePrinted(true);
   12701                 }
   12702                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
   12703                         : "Service Resolver Table:", "  ", packageName,
   12704                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
   12705                     dumpState.setTitlePrinted(true);
   12706                 }
   12707                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
   12708                         : "Provider Resolver Table:", "  ", packageName,
   12709                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
   12710                     dumpState.setTitlePrinted(true);
   12711                 }
   12712             }
   12713 
   12714             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
   12715                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   12716                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   12717                     int user = mSettings.mPreferredActivities.keyAt(i);
   12718                     if (pir.dump(pw,
   12719                             dumpState.getTitlePrinted()
   12720                                 ? "\nPreferred Activities User " + user + ":"
   12721                                 : "Preferred Activities User " + user + ":", "  ",
   12722                             packageName, true, false)) {
   12723                         dumpState.setTitlePrinted(true);
   12724                     }
   12725                 }
   12726             }
   12727 
   12728             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
   12729                 pw.flush();
   12730                 FileOutputStream fout = new FileOutputStream(fd);
   12731                 BufferedOutputStream str = new BufferedOutputStream(fout);
   12732                 XmlSerializer serializer = new FastXmlSerializer();
   12733                 try {
   12734                     serializer.setOutput(str, "utf-8");
   12735                     serializer.startDocument(null, true);
   12736                     serializer.setFeature(
   12737                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
   12738                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
   12739                     serializer.endDocument();
   12740                     serializer.flush();
   12741                 } catch (IllegalArgumentException e) {
   12742                     pw.println("Failed writing: " + e);
   12743                 } catch (IllegalStateException e) {
   12744                     pw.println("Failed writing: " + e);
   12745                 } catch (IOException e) {
   12746                     pw.println("Failed writing: " + e);
   12747                 }
   12748             }
   12749 
   12750             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
   12751                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
   12752                 if (packageName == null) {
   12753                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
   12754                         if (iperm == 0) {
   12755                             if (dumpState.onTitlePrinted())
   12756                                 pw.println();
   12757                             pw.println("AppOp Permissions:");
   12758                         }
   12759                         pw.print("  AppOp Permission ");
   12760                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
   12761                         pw.println(":");
   12762                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
   12763                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
   12764                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
   12765                         }
   12766                     }
   12767                 }
   12768             }
   12769 
   12770             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
   12771                 boolean printedSomething = false;
   12772                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
   12773                     if (packageName != null && !packageName.equals(p.info.packageName)) {
   12774                         continue;
   12775                     }
   12776                     if (!printedSomething) {
   12777                         if (dumpState.onTitlePrinted())
   12778                             pw.println();
   12779                         pw.println("Registered ContentProviders:");
   12780                         printedSomething = true;
   12781                     }
   12782                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
   12783                     pw.print("    "); pw.println(p.toString());
   12784                 }
   12785                 printedSomething = false;
   12786                 for (Map.Entry<String, PackageParser.Provider> entry :
   12787                         mProvidersByAuthority.entrySet()) {
   12788                     PackageParser.Provider p = entry.getValue();
   12789                     if (packageName != null && !packageName.equals(p.info.packageName)) {
   12790                         continue;
   12791                     }
   12792                     if (!printedSomething) {
   12793                         if (dumpState.onTitlePrinted())
   12794                             pw.println();
   12795                         pw.println("ContentProvider Authorities:");
   12796                         printedSomething = true;
   12797                     }
   12798                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
   12799                     pw.print("    "); pw.println(p.toString());
   12800                     if (p.info != null && p.info.applicationInfo != null) {
   12801                         final String appInfo = p.info.applicationInfo.toString();
   12802                         pw.print("      applicationInfo="); pw.println(appInfo);
   12803                     }
   12804                 }
   12805             }
   12806 
   12807             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
   12808                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
   12809             }
   12810 
   12811             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
   12812                 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
   12813             }
   12814 
   12815             if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
   12816                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin);
   12817             }
   12818 
   12819             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
   12820                 // XXX should handle packageName != null by dumping only install data that
   12821                 // the given package is involved with.
   12822                 if (dumpState.onTitlePrinted()) pw.println();
   12823                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
   12824             }
   12825 
   12826             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
   12827                 if (dumpState.onTitlePrinted()) pw.println();
   12828                 mSettings.dumpReadMessagesLPr(pw, dumpState);
   12829 
   12830                 pw.println();
   12831                 pw.println("Package warning messages:");
   12832                 BufferedReader in = null;
   12833                 String line = null;
   12834                 try {
   12835                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
   12836                     while ((line = in.readLine()) != null) {
   12837                         if (line.contains("ignored: updated version")) continue;
   12838                         pw.println(line);
   12839                     }
   12840                 } catch (IOException ignored) {
   12841                 } finally {
   12842                     IoUtils.closeQuietly(in);
   12843                 }
   12844             }
   12845 
   12846             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
   12847                 BufferedReader in = null;
   12848                 String line = null;
   12849                 try {
   12850                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
   12851                     while ((line = in.readLine()) != null) {
   12852                         if (line.contains("ignored: updated version")) continue;
   12853                         pw.print("msg,");
   12854                         pw.println(line);
   12855                     }
   12856                 } catch (IOException ignored) {
   12857                 } finally {
   12858                     IoUtils.closeQuietly(in);
   12859                 }
   12860             }
   12861         }
   12862     }
   12863 
   12864     // ------- apps on sdcard specific code -------
   12865     static final boolean DEBUG_SD_INSTALL = false;
   12866 
   12867     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
   12868 
   12869     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
   12870 
   12871     private boolean mMediaMounted = false;
   12872 
   12873     static String getEncryptKey() {
   12874         try {
   12875             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
   12876                     SD_ENCRYPTION_KEYSTORE_NAME);
   12877             if (sdEncKey == null) {
   12878                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
   12879                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
   12880                 if (sdEncKey == null) {
   12881                     Slog.e(TAG, "Failed to create encryption keys");
   12882                     return null;
   12883                 }
   12884             }
   12885             return sdEncKey;
   12886         } catch (NoSuchAlgorithmException nsae) {
   12887             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
   12888             return null;
   12889         } catch (IOException ioe) {
   12890             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
   12891             return null;
   12892         }
   12893     }
   12894 
   12895     /*
   12896      * Update media status on PackageManager.
   12897      */
   12898     @Override
   12899     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
   12900         int callingUid = Binder.getCallingUid();
   12901         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   12902             throw new SecurityException("Media status can only be updated by the system");
   12903         }
   12904         // reader; this apparently protects mMediaMounted, but should probably
   12905         // be a different lock in that case.
   12906         synchronized (mPackages) {
   12907             Log.i(TAG, "Updating external media status from "
   12908                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
   12909                     + (mediaStatus ? "mounted" : "unmounted"));
   12910             if (DEBUG_SD_INSTALL)
   12911                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
   12912                         + ", mMediaMounted=" + mMediaMounted);
   12913             if (mediaStatus == mMediaMounted) {
   12914                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
   12915                         : 0, -1);
   12916                 mHandler.sendMessage(msg);
   12917                 return;
   12918             }
   12919             mMediaMounted = mediaStatus;
   12920         }
   12921         // Queue up an async operation since the package installation may take a
   12922         // little while.
   12923         mHandler.post(new Runnable() {
   12924             public void run() {
   12925                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
   12926             }
   12927         });
   12928     }
   12929 
   12930     /**
   12931      * Called by MountService when the initial ASECs to scan are available.
   12932      * Should block until all the ASEC containers are finished being scanned.
   12933      */
   12934     public void scanAvailableAsecs() {
   12935         updateExternalMediaStatusInner(true, false, false);
   12936         if (mShouldRestoreconData) {
   12937             SELinuxMMAC.setRestoreconDone();
   12938             mShouldRestoreconData = false;
   12939         }
   12940     }
   12941 
   12942     /*
   12943      * Collect information of applications on external media, map them against
   12944      * existing containers and update information based on current mount status.
   12945      * Please note that we always have to report status if reportStatus has been
   12946      * set to true especially when unloading packages.
   12947      */
   12948     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
   12949             boolean externalStorage) {
   12950         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
   12951         int[] uidArr = EmptyArray.INT;
   12952 
   12953         final String[] list = PackageHelper.getSecureContainerList();
   12954         if (ArrayUtils.isEmpty(list)) {
   12955             Log.i(TAG, "No secure containers found");
   12956         } else {
   12957             // Process list of secure containers and categorize them
   12958             // as active or stale based on their package internal state.
   12959 
   12960             // reader
   12961             synchronized (mPackages) {
   12962                 for (String cid : list) {
   12963                     // Leave stages untouched for now; installer service owns them
   12964                     if (PackageInstallerService.isStageName(cid)) continue;
   12965 
   12966                     if (DEBUG_SD_INSTALL)
   12967                         Log.i(TAG, "Processing container " + cid);
   12968                     String pkgName = getAsecPackageName(cid);
   12969                     if (pkgName == null) {
   12970                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
   12971                         continue;
   12972                     }
   12973                     if (DEBUG_SD_INSTALL)
   12974                         Log.i(TAG, "Looking for pkg : " + pkgName);
   12975 
   12976                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
   12977                     if (ps == null) {
   12978                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
   12979                         continue;
   12980                     }
   12981 
   12982                     /*
   12983                      * Skip packages that are not external if we're unmounting
   12984                      * external storage.
   12985                      */
   12986                     if (externalStorage && !isMounted && !isExternal(ps)) {
   12987                         continue;
   12988                     }
   12989 
   12990                     final AsecInstallArgs args = new AsecInstallArgs(cid,
   12991                             getAppDexInstructionSets(ps), isForwardLocked(ps));
   12992                     // The package status is changed only if the code path
   12993                     // matches between settings and the container id.
   12994                     if (ps.codePathString != null
   12995                             && ps.codePathString.startsWith(args.getCodePath())) {
   12996                         if (DEBUG_SD_INSTALL) {
   12997                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
   12998                                     + " at code path: " + ps.codePathString);
   12999                         }
   13000 
   13001                         // We do have a valid package installed on sdcard
   13002                         processCids.put(args, ps.codePathString);
   13003                         final int uid = ps.appId;
   13004                         if (uid != -1) {
   13005                             uidArr = ArrayUtils.appendInt(uidArr, uid);
   13006                         }
   13007                     } else {
   13008                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
   13009                                 + ps.codePathString);
   13010                     }
   13011                 }
   13012             }
   13013 
   13014             Arrays.sort(uidArr);
   13015         }
   13016 
   13017         // Process packages with valid entries.
   13018         if (isMounted) {
   13019             if (DEBUG_SD_INSTALL)
   13020                 Log.i(TAG, "Loading packages");
   13021             loadMediaPackages(processCids, uidArr);
   13022             startCleaningPackages();
   13023             mInstallerService.onSecureContainersAvailable();
   13024         } else {
   13025             if (DEBUG_SD_INSTALL)
   13026                 Log.i(TAG, "Unloading packages");
   13027             unloadMediaPackages(processCids, uidArr, reportStatus);
   13028         }
   13029     }
   13030 
   13031     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
   13032             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
   13033         int size = pkgList.size();
   13034         if (size > 0) {
   13035             // Send broadcasts here
   13036             Bundle extras = new Bundle();
   13037             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
   13038                     .toArray(new String[size]));
   13039             if (uidArr != null) {
   13040                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
   13041             }
   13042             if (replacing) {
   13043                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
   13044             }
   13045             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
   13046                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
   13047             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
   13048         }
   13049     }
   13050 
   13051    /*
   13052      * Look at potentially valid container ids from processCids If package
   13053      * information doesn't match the one on record or package scanning fails,
   13054      * the cid is added to list of removeCids. We currently don't delete stale
   13055      * containers.
   13056      */
   13057     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
   13058         ArrayList<String> pkgList = new ArrayList<String>();
   13059         Set<AsecInstallArgs> keys = processCids.keySet();
   13060 
   13061         for (AsecInstallArgs args : keys) {
   13062             String codePath = processCids.get(args);
   13063             if (DEBUG_SD_INSTALL)
   13064                 Log.i(TAG, "Loading container : " + args.cid);
   13065             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   13066             try {
   13067                 // Make sure there are no container errors first.
   13068                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
   13069                     Slog.e(TAG, "Failed to mount cid : " + args.cid
   13070                             + " when installing from sdcard");
   13071                     continue;
   13072                 }
   13073                 // Check code path here.
   13074                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
   13075                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
   13076                             + " does not match one in settings " + codePath);
   13077                     continue;
   13078                 }
   13079                 // Parse package
   13080                 int parseFlags = mDefParseFlags;
   13081                 if (args.isExternal()) {
   13082                     parseFlags |= PackageParser.PARSE_ON_SDCARD;
   13083                 }
   13084                 if (args.isFwdLocked()) {
   13085                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   13086                 }
   13087 
   13088                 synchronized (mInstallLock) {
   13089                     PackageParser.Package pkg = null;
   13090                     try {
   13091                         pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
   13092                     } catch (PackageManagerException e) {
   13093                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
   13094                     }
   13095                     // Scan the package
   13096                     if (pkg != null) {
   13097                         /*
   13098                          * TODO why is the lock being held? doPostInstall is
   13099                          * called in other places without the lock. This needs
   13100                          * to be straightened out.
   13101                          */
   13102                         // writer
   13103                         synchronized (mPackages) {
   13104                             retCode = PackageManager.INSTALL_SUCCEEDED;
   13105                             pkgList.add(pkg.packageName);
   13106                             // Post process args
   13107                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
   13108                                     pkg.applicationInfo.uid);
   13109                         }
   13110                     } else {
   13111                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
   13112                     }
   13113                 }
   13114 
   13115             } finally {
   13116                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
   13117                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
   13118                 }
   13119             }
   13120         }
   13121         // writer
   13122         synchronized (mPackages) {
   13123             // If the platform SDK has changed since the last time we booted,
   13124             // we need to re-grant app permission to catch any new ones that
   13125             // appear. This is really a hack, and means that apps can in some
   13126             // cases get permissions that the user didn't initially explicitly
   13127             // allow... it would be nice to have some better way to handle
   13128             // this situation.
   13129             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
   13130             if (regrantPermissions)
   13131                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
   13132                         + mSdkVersion + "; regranting permissions for external storage");
   13133             mSettings.mExternalSdkPlatform = mSdkVersion;
   13134 
   13135             // Make sure group IDs have been assigned, and any permission
   13136             // changes in other apps are accounted for
   13137             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
   13138                     | (regrantPermissions
   13139                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
   13140                             : 0));
   13141 
   13142             mSettings.updateExternalDatabaseVersion();
   13143 
   13144             // can downgrade to reader
   13145             // Persist settings
   13146             mSettings.writeLPr();
   13147         }
   13148         // Send a broadcast to let everyone know we are done processing
   13149         if (pkgList.size() > 0) {
   13150             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
   13151         }
   13152     }
   13153 
   13154    /*
   13155      * Utility method to unload a list of specified containers
   13156      */
   13157     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
   13158         // Just unmount all valid containers.
   13159         for (AsecInstallArgs arg : cidArgs) {
   13160             synchronized (mInstallLock) {
   13161                 arg.doPostDeleteLI(false);
   13162            }
   13163        }
   13164    }
   13165 
   13166     /*
   13167      * Unload packages mounted on external media. This involves deleting package
   13168      * data from internal structures, sending broadcasts about diabled packages,
   13169      * gc'ing to free up references, unmounting all secure containers
   13170      * corresponding to packages on external media, and posting a
   13171      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
   13172      * that we always have to post this message if status has been requested no
   13173      * matter what.
   13174      */
   13175     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
   13176             final boolean reportStatus) {
   13177         if (DEBUG_SD_INSTALL)
   13178             Log.i(TAG, "unloading media packages");
   13179         ArrayList<String> pkgList = new ArrayList<String>();
   13180         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
   13181         final Set<AsecInstallArgs> keys = processCids.keySet();
   13182         for (AsecInstallArgs args : keys) {
   13183             String pkgName = args.getPackageName();
   13184             if (DEBUG_SD_INSTALL)
   13185                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
   13186             // Delete package internally
   13187             PackageRemovedInfo outInfo = new PackageRemovedInfo();
   13188             synchronized (mInstallLock) {
   13189                 boolean res = deletePackageLI(pkgName, null, false, null, null,
   13190                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
   13191                 if (res) {
   13192                     pkgList.add(pkgName);
   13193                 } else {
   13194                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
   13195                     failedList.add(args);
   13196                 }
   13197             }
   13198         }
   13199 
   13200         // reader
   13201         synchronized (mPackages) {
   13202             // We didn't update the settings after removing each package;
   13203             // write them now for all packages.
   13204             mSettings.writeLPr();
   13205         }
   13206 
   13207         // We have to absolutely send UPDATED_MEDIA_STATUS only
   13208         // after confirming that all the receivers processed the ordered
   13209         // broadcast when packages get disabled, force a gc to clean things up.
   13210         // and unload all the containers.
   13211         if (pkgList.size() > 0) {
   13212             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
   13213                     new IIntentReceiver.Stub() {
   13214                 public void performReceive(Intent intent, int resultCode, String data,
   13215                         Bundle extras, boolean ordered, boolean sticky,
   13216                         int sendingUser) throws RemoteException {
   13217                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
   13218                             reportStatus ? 1 : 0, 1, keys);
   13219                     mHandler.sendMessage(msg);
   13220                 }
   13221             });
   13222         } else {
   13223             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
   13224                     keys);
   13225             mHandler.sendMessage(msg);
   13226         }
   13227     }
   13228 
   13229     /** Binder call */
   13230     @Override
   13231     public void movePackage(final String packageName, final IPackageMoveObserver observer,
   13232             final int flags) {
   13233         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
   13234         UserHandle user = new UserHandle(UserHandle.getCallingUserId());
   13235         int returnCode = PackageManager.MOVE_SUCCEEDED;
   13236         int currInstallFlags = 0;
   13237         int newInstallFlags = 0;
   13238 
   13239         File codeFile = null;
   13240         String installerPackageName = null;
   13241         String packageAbiOverride = null;
   13242 
   13243         // reader
   13244         synchronized (mPackages) {
   13245             final PackageParser.Package pkg = mPackages.get(packageName);
   13246             final PackageSetting ps = mSettings.mPackages.get(packageName);
   13247             if (pkg == null || ps == null) {
   13248                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
   13249             } else {
   13250                 // Disable moving fwd locked apps and system packages
   13251                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
   13252                     Slog.w(TAG, "Cannot move system application");
   13253                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
   13254                 } else if (pkg.mOperationPending) {
   13255                     Slog.w(TAG, "Attempt to move package which has pending operations");
   13256                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
   13257                 } else {
   13258                     // Find install location first
   13259                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
   13260                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
   13261                         Slog.w(TAG, "Ambigous flags specified for move location.");
   13262                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
   13263                     } else {
   13264                         newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
   13265                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
   13266                         currInstallFlags = isExternal(pkg)
   13267                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
   13268 
   13269                         if (newInstallFlags == currInstallFlags) {
   13270                             Slog.w(TAG, "No move required. Trying to move to same location");
   13271                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
   13272                         } else {
   13273                             if (isForwardLocked(pkg)) {
   13274                                 currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
   13275                                 newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
   13276                             }
   13277                         }
   13278                     }
   13279                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
   13280                         pkg.mOperationPending = true;
   13281                     }
   13282                 }
   13283 
   13284                 codeFile = new File(pkg.codePath);
   13285                 installerPackageName = ps.installerPackageName;
   13286                 packageAbiOverride = ps.cpuAbiOverrideString;
   13287             }
   13288         }
   13289 
   13290         if (returnCode != PackageManager.MOVE_SUCCEEDED) {
   13291             try {
   13292                 observer.packageMoved(packageName, returnCode);
   13293             } catch (RemoteException ignored) {
   13294             }
   13295             return;
   13296         }
   13297 
   13298         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
   13299             @Override
   13300             public void onUserActionRequired(Intent intent) throws RemoteException {
   13301                 throw new IllegalStateException();
   13302             }
   13303 
   13304             @Override
   13305             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
   13306                     Bundle extras) throws RemoteException {
   13307                 Slog.d(TAG, "Install result for move: "
   13308                         + PackageManager.installStatusToString(returnCode, msg));
   13309 
   13310                 // We usually have a new package now after the install, but if
   13311                 // we failed we need to clear the pending flag on the original
   13312                 // package object.
   13313                 synchronized (mPackages) {
   13314                     final PackageParser.Package pkg = mPackages.get(packageName);
   13315                     if (pkg != null) {
   13316                         pkg.mOperationPending = false;
   13317                     }
   13318                 }
   13319 
   13320                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
   13321                 switch (status) {
   13322                     case PackageInstaller.STATUS_SUCCESS:
   13323                         observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED);
   13324                         break;
   13325                     case PackageInstaller.STATUS_FAILURE_STORAGE:
   13326                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
   13327                         break;
   13328                     default:
   13329                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
   13330                         break;
   13331                 }
   13332             }
   13333         };
   13334 
   13335         // Treat a move like reinstalling an existing app, which ensures that we
   13336         // process everythign uniformly, like unpacking native libraries.
   13337         newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
   13338 
   13339         final Message msg = mHandler.obtainMessage(INIT_COPY);
   13340         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
   13341         msg.obj = new InstallParams(origin, installObserver, newInstallFlags,
   13342                 installerPackageName, null, user, packageAbiOverride);
   13343         mHandler.sendMessage(msg);
   13344     }
   13345 
   13346     @Override
   13347     public boolean setInstallLocation(int loc) {
   13348         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
   13349                 null);
   13350         if (getInstallLocation() == loc) {
   13351             return true;
   13352         }
   13353         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
   13354                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
   13355             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
   13356                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
   13357             return true;
   13358         }
   13359         return false;
   13360    }
   13361 
   13362     @Override
   13363     public int getInstallLocation() {
   13364         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   13365                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
   13366                 PackageHelper.APP_INSTALL_AUTO);
   13367     }
   13368 
   13369     /** Called by UserManagerService */
   13370     void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
   13371         mDirtyUsers.remove(userHandle);
   13372         mSettings.removeUserLPw(userHandle);
   13373         mPendingBroadcasts.remove(userHandle);
   13374         if (mInstaller != null) {
   13375             // Technically, we shouldn't be doing this with the package lock
   13376             // held.  However, this is very rare, and there is already so much
   13377             // other disk I/O going on, that we'll let it slide for now.
   13378             mInstaller.removeUserDataDirs(userHandle);
   13379         }
   13380         mUserNeedsBadging.delete(userHandle);
   13381         removeUnusedPackagesLILPw(userManager, userHandle);
   13382     }
   13383 
   13384     /**
   13385      * We're removing userHandle and would like to remove any downloaded packages
   13386      * that are no longer in use by any other user.
   13387      * @param userHandle the user being removed
   13388      */
   13389     private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
   13390         final boolean DEBUG_CLEAN_APKS = false;
   13391         int [] users = userManager.getUserIdsLPr();
   13392         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
   13393         while (psit.hasNext()) {
   13394             PackageSetting ps = psit.next();
   13395             if (ps.pkg == null) {
   13396                 continue;
   13397             }
   13398             final String packageName = ps.pkg.packageName;
   13399             // Skip over if system app
   13400             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   13401                 continue;
   13402             }
   13403             if (DEBUG_CLEAN_APKS) {
   13404                 Slog.i(TAG, "Checking package " + packageName);
   13405             }
   13406             boolean keep = false;
   13407             for (int i = 0; i < users.length; i++) {
   13408                 if (users[i] != userHandle && ps.getInstalled(users[i])) {
   13409                     keep = true;
   13410                     if (DEBUG_CLEAN_APKS) {
   13411                         Slog.i(TAG, "  Keeping package " + packageName + " for user "
   13412                                 + users[i]);
   13413                     }
   13414                     break;
   13415                 }
   13416             }
   13417             if (!keep) {
   13418                 if (DEBUG_CLEAN_APKS) {
   13419                     Slog.i(TAG, "  Removing package " + packageName);
   13420                 }
   13421                 mHandler.post(new Runnable() {
   13422                     public void run() {
   13423                         deletePackageX(packageName, userHandle, 0);
   13424                     } //end run
   13425                 });
   13426             }
   13427         }
   13428     }
   13429 
   13430     /** Called by UserManagerService */
   13431     void createNewUserLILPw(int userHandle, File path) {
   13432         if (mInstaller != null) {
   13433             mInstaller.createUserConfig(userHandle);
   13434             mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
   13435         }
   13436     }
   13437 
   13438     @Override
   13439     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
   13440         mContext.enforceCallingOrSelfPermission(
   13441                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   13442                 "Only package verification agents can read the verifier device identity");
   13443 
   13444         synchronized (mPackages) {
   13445             return mSettings.getVerifierDeviceIdentityLPw();
   13446         }
   13447     }
   13448 
   13449     @Override
   13450     public void setPermissionEnforced(String permission, boolean enforced) {
   13451         mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
   13452         if (READ_EXTERNAL_STORAGE.equals(permission)) {
   13453             synchronized (mPackages) {
   13454                 if (mSettings.mReadExternalStorageEnforced == null
   13455                         || mSettings.mReadExternalStorageEnforced != enforced) {
   13456                     mSettings.mReadExternalStorageEnforced = enforced;
   13457                     mSettings.writeLPr();
   13458                 }
   13459             }
   13460             // kill any non-foreground processes so we restart them and
   13461             // grant/revoke the GID.
   13462             final IActivityManager am = ActivityManagerNative.getDefault();
   13463             if (am != null) {
   13464                 final long token = Binder.clearCallingIdentity();
   13465                 try {
   13466                     am.killProcessesBelowForeground("setPermissionEnforcement");
   13467                 } catch (RemoteException e) {
   13468                 } finally {
   13469                     Binder.restoreCallingIdentity(token);
   13470                 }
   13471             }
   13472         } else {
   13473             throw new IllegalArgumentException("No selective enforcement for " + permission);
   13474         }
   13475     }
   13476 
   13477     @Override
   13478     @Deprecated
   13479     public boolean isPermissionEnforced(String permission) {
   13480         return true;
   13481     }
   13482 
   13483     @Override
   13484     public boolean isStorageLow() {
   13485         final long token = Binder.clearCallingIdentity();
   13486         try {
   13487             final DeviceStorageMonitorInternal
   13488                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
   13489             if (dsm != null) {
   13490                 return dsm.isMemoryLow();
   13491             } else {
   13492                 return false;
   13493             }
   13494         } finally {
   13495             Binder.restoreCallingIdentity(token);
   13496         }
   13497     }
   13498 
   13499     @Override
   13500     public IPackageInstaller getPackageInstaller() {
   13501         return mInstallerService;
   13502     }
   13503 
   13504     private boolean userNeedsBadging(int userId) {
   13505         int index = mUserNeedsBadging.indexOfKey(userId);
   13506         if (index < 0) {
   13507             final UserInfo userInfo;
   13508             final long token = Binder.clearCallingIdentity();
   13509             try {
   13510                 userInfo = sUserManager.getUserInfo(userId);
   13511             } finally {
   13512                 Binder.restoreCallingIdentity(token);
   13513             }
   13514             final boolean b;
   13515             if (userInfo != null && userInfo.isManagedProfile()) {
   13516                 b = true;
   13517             } else {
   13518                 b = false;
   13519             }
   13520             mUserNeedsBadging.put(userId, b);
   13521             return b;
   13522         }
   13523         return mUserNeedsBadging.valueAt(index);
   13524     }
   13525 
   13526     @Override
   13527     public KeySet getKeySetByAlias(String packageName, String alias) {
   13528         if (packageName == null || alias == null) {
   13529             return null;
   13530         }
   13531         synchronized(mPackages) {
   13532             final PackageParser.Package pkg = mPackages.get(packageName);
   13533             if (pkg == null) {
   13534                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
   13535                 throw new IllegalArgumentException("Unknown package: " + packageName);
   13536             }
   13537             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   13538             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
   13539         }
   13540     }
   13541 
   13542     @Override
   13543     public KeySet getSigningKeySet(String packageName) {
   13544         if (packageName == null) {
   13545             return null;
   13546         }
   13547         synchronized(mPackages) {
   13548             final PackageParser.Package pkg = mPackages.get(packageName);
   13549             if (pkg == null) {
   13550                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
   13551                 throw new IllegalArgumentException("Unknown package: " + packageName);
   13552             }
   13553             if (pkg.applicationInfo.uid != Binder.getCallingUid()
   13554                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
   13555                 throw new SecurityException("May not access signing KeySet of other apps.");
   13556             }
   13557             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   13558             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
   13559         }
   13560     }
   13561 
   13562     @Override
   13563     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
   13564         if (packageName == null || ks == null) {
   13565             return false;
   13566         }
   13567         synchronized(mPackages) {
   13568             final PackageParser.Package pkg = mPackages.get(packageName);
   13569             if (pkg == null) {
   13570                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
   13571                 throw new IllegalArgumentException("Unknown package: " + packageName);
   13572             }
   13573             IBinder ksh = ks.getToken();
   13574             if (ksh instanceof KeySetHandle) {
   13575                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
   13576                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
   13577             }
   13578             return false;
   13579         }
   13580     }
   13581 
   13582     @Override
   13583     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
   13584         if (packageName == null || ks == null) {
   13585             return false;
   13586         }
   13587         synchronized(mPackages) {
   13588             final PackageParser.Package pkg = mPackages.get(packageName);
   13589             if (pkg == null) {
   13590                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
   13591                 throw new IllegalArgumentException("Unknown package: " + packageName);
   13592             }
   13593             IBinder ksh = ks.getToken();
   13594             if (ksh instanceof KeySetHandle) {
   13595                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
   13596                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
   13597             }
   13598             return false;
   13599         }
   13600     }
   13601 
   13602     public void getUsageStatsIfNoPackageUsageInfo() {
   13603         if (!mPackageUsage.isHistoricalPackageUsageAvailable()) {
   13604             UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
   13605             if (usm == null) {
   13606                 throw new IllegalStateException("UsageStatsManager must be initialized");
   13607             }
   13608             long now = System.currentTimeMillis();
   13609             Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now);
   13610             for (Map.Entry<String, UsageStats> entry : stats.entrySet()) {
   13611                 String packageName = entry.getKey();
   13612                 PackageParser.Package pkg = mPackages.get(packageName);
   13613                 if (pkg == null) {
   13614                     continue;
   13615                 }
   13616                 UsageStats usage = entry.getValue();
   13617                 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed();
   13618                 mPackageUsage.mIsHistoricalPackageUsageAvailable = true;
   13619             }
   13620         }
   13621     }
   13622 
   13623     /**
   13624      * Check and throw if the given before/after packages would be considered a
   13625      * downgrade.
   13626      */
   13627     private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
   13628             throws PackageManagerException {
   13629         if (after.versionCode < before.mVersionCode) {
   13630             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
   13631                     "Update version code " + after.versionCode + " is older than current "
   13632                     + before.mVersionCode);
   13633         } else if (after.versionCode == before.mVersionCode) {
   13634             if (after.baseRevisionCode < before.baseRevisionCode) {
   13635                 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
   13636                         "Update base revision code " + after.baseRevisionCode
   13637                         + " is older than current " + before.baseRevisionCode);
   13638             }
   13639 
   13640             if (!ArrayUtils.isEmpty(after.splitNames)) {
   13641                 for (int i = 0; i < after.splitNames.length; i++) {
   13642                     final String splitName = after.splitNames[i];
   13643                     final int j = ArrayUtils.indexOf(before.splitNames, splitName);
   13644                     if (j != -1) {
   13645                         if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
   13646                             throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
   13647                                     "Update split " + splitName + " revision code "
   13648                                     + after.splitRevisionCodes[i] + " is older than current "
   13649                                     + before.splitRevisionCodes[j]);
   13650                         }
   13651                     }
   13652                 }
   13653             }
   13654         }
   13655     }
   13656 }
   13657