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_FORWARD_LOCK;
     45 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
     46 import static android.content.pm.PackageParser.isApkFile;
     47 import static android.os.Process.PACKAGE_INFO_GID;
     48 import static android.os.Process.SYSTEM_UID;
     49 import static android.system.OsConstants.O_CREAT;
     50 import static android.system.OsConstants.O_RDWR;
     51 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
     52 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
     53 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
     54 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
     55 import static com.android.internal.util.ArrayUtils.appendInt;
     56 import static com.android.internal.util.ArrayUtils.removeInt;
     57 
     58 import android.util.ArrayMap;
     59 
     60 import com.android.internal.R;
     61 import com.android.internal.app.IMediaContainerService;
     62 import com.android.internal.app.ResolverActivity;
     63 import com.android.internal.content.NativeLibraryHelper;
     64 import com.android.internal.content.PackageHelper;
     65 import com.android.internal.os.IParcelFileDescriptorFactory;
     66 import com.android.internal.util.ArrayUtils;
     67 import com.android.internal.util.FastPrintWriter;
     68 import com.android.internal.util.FastXmlSerializer;
     69 import com.android.internal.util.IndentingPrintWriter;
     70 import com.android.server.EventLogTags;
     71 import com.android.server.IntentResolver;
     72 import com.android.server.LocalServices;
     73 import com.android.server.ServiceThread;
     74 import com.android.server.SystemConfig;
     75 import com.android.server.Watchdog;
     76 import com.android.server.pm.Settings.DatabaseVersion;
     77 import com.android.server.storage.DeviceStorageMonitorInternal;
     78 
     79 import org.xmlpull.v1.XmlSerializer;
     80 
     81 import android.app.ActivityManager;
     82 import android.app.ActivityManagerNative;
     83 import android.app.AppGlobals;
     84 import android.app.IActivityManager;
     85 import android.app.admin.IDevicePolicyManager;
     86 import android.app.backup.IBackupManager;
     87 import android.content.BroadcastReceiver;
     88 import android.content.ComponentName;
     89 import android.content.Context;
     90 import android.content.IIntentReceiver;
     91 import android.content.Intent;
     92 import android.content.IntentFilter;
     93 import android.content.IntentSender;
     94 import android.content.IntentSender.SendIntentException;
     95 import android.content.ServiceConnection;
     96 import android.content.pm.ActivityInfo;
     97 import android.content.pm.ApplicationInfo;
     98 import android.content.pm.FeatureInfo;
     99 import android.content.pm.IPackageDataObserver;
    100 import android.content.pm.IPackageDeleteObserver;
    101 import android.content.pm.IPackageDeleteObserver2;
    102 import android.content.pm.IPackageInstallObserver2;
    103 import android.content.pm.IPackageInstaller;
    104 import android.content.pm.IPackageManager;
    105 import android.content.pm.IPackageMoveObserver;
    106 import android.content.pm.IPackageStatsObserver;
    107 import android.content.pm.InstrumentationInfo;
    108 import android.content.pm.KeySet;
    109 import android.content.pm.ManifestDigest;
    110 import android.content.pm.PackageCleanItem;
    111 import android.content.pm.PackageInfo;
    112 import android.content.pm.PackageInfoLite;
    113 import android.content.pm.PackageInstaller;
    114 import android.content.pm.PackageManager;
    115 import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
    116 import android.content.pm.PackageParser.ActivityIntentInfo;
    117 import android.content.pm.PackageParser.PackageLite;
    118 import android.content.pm.PackageParser.PackageParserException;
    119 import android.content.pm.PackageParser;
    120 import android.content.pm.PackageStats;
    121 import android.content.pm.PackageUserState;
    122 import android.content.pm.ParceledListSlice;
    123 import android.content.pm.PermissionGroupInfo;
    124 import android.content.pm.PermissionInfo;
    125 import android.content.pm.ProviderInfo;
    126 import android.content.pm.ResolveInfo;
    127 import android.content.pm.ServiceInfo;
    128 import android.content.pm.Signature;
    129 import android.content.pm.UserInfo;
    130 import android.content.pm.VerificationParams;
    131 import android.content.pm.VerifierDeviceIdentity;
    132 import android.content.pm.VerifierInfo;
    133 import android.content.res.Resources;
    134 import android.hardware.display.DisplayManager;
    135 import android.net.Uri;
    136 import android.os.Binder;
    137 import android.os.Build;
    138 import android.os.Bundle;
    139 import android.os.Environment;
    140 import android.os.Environment.UserEnvironment;
    141 import android.os.storage.StorageManager;
    142 import android.os.Debug;
    143 import android.os.FileUtils;
    144 import android.os.Handler;
    145 import android.os.IBinder;
    146 import android.os.Looper;
    147 import android.os.Message;
    148 import android.os.Parcel;
    149 import android.os.ParcelFileDescriptor;
    150 import android.os.Process;
    151 import android.os.RemoteException;
    152 import android.os.SELinux;
    153 import android.os.ServiceManager;
    154 import android.os.SystemClock;
    155 import android.os.SystemProperties;
    156 import android.os.UserHandle;
    157 import android.os.UserManager;
    158 import android.security.KeyStore;
    159 import android.security.SystemKeyStore;
    160 import android.system.ErrnoException;
    161 import android.system.Os;
    162 import android.system.StructStat;
    163 import android.text.TextUtils;
    164 import android.util.ArraySet;
    165 import android.util.AtomicFile;
    166 import android.util.DisplayMetrics;
    167 import android.util.EventLog;
    168 import android.util.ExceptionUtils;
    169 import android.util.Log;
    170 import android.util.LogPrinter;
    171 import android.util.PrintStreamPrinter;
    172 import android.util.Slog;
    173 import android.util.SparseArray;
    174 import android.util.SparseBooleanArray;
    175 import android.view.Display;
    176 
    177 import java.io.BufferedInputStream;
    178 import java.io.BufferedOutputStream;
    179 import java.io.BufferedReader;
    180 import java.io.File;
    181 import java.io.FileDescriptor;
    182 import java.io.FileInputStream;
    183 import java.io.FileNotFoundException;
    184 import java.io.FileOutputStream;
    185 import java.io.FileReader;
    186 import java.io.FilenameFilter;
    187 import java.io.IOException;
    188 import java.io.InputStream;
    189 import java.io.PrintWriter;
    190 import java.nio.charset.StandardCharsets;
    191 import java.security.NoSuchAlgorithmException;
    192 import java.security.PublicKey;
    193 import java.security.cert.CertificateEncodingException;
    194 import java.security.cert.CertificateException;
    195 import java.text.SimpleDateFormat;
    196 import java.util.ArrayList;
    197 import java.util.Arrays;
    198 import java.util.Collection;
    199 import java.util.Collections;
    200 import java.util.Comparator;
    201 import java.util.Date;
    202 import java.util.HashMap;
    203 import java.util.HashSet;
    204 import java.util.Iterator;
    205 import java.util.List;
    206 import java.util.Map;
    207 import java.util.Objects;
    208 import java.util.Set;
    209 import java.util.concurrent.atomic.AtomicBoolean;
    210 import java.util.concurrent.atomic.AtomicLong;
    211 
    212 import dalvik.system.DexFile;
    213 import dalvik.system.StaleDexCacheError;
    214 import dalvik.system.VMRuntime;
    215 
    216 import libcore.io.IoUtils;
    217 import libcore.util.EmptyArray;
    218 
    219 /**
    220  * Keep track of all those .apks everywhere.
    221  *
    222  * This is very central to the platform's security; please run the unit
    223  * tests whenever making modifications here:
    224  *
    225 mmm frameworks/base/tests/AndroidTests
    226 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk
    227 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner
    228  *
    229  * {@hide}
    230  */
    231 public class PackageManagerService extends IPackageManager.Stub {
    232     static final String TAG = "PackageManager";
    233     static final boolean DEBUG_SETTINGS = false;
    234     static final boolean DEBUG_PREFERRED = false;
    235     static final boolean DEBUG_UPGRADE = false;
    236     private static final boolean DEBUG_INSTALL = false;
    237     private static final boolean DEBUG_REMOVE = false;
    238     private static final boolean DEBUG_BROADCASTS = false;
    239     private static final boolean DEBUG_SHOW_INFO = false;
    240     private static final boolean DEBUG_PACKAGE_INFO = false;
    241     private static final boolean DEBUG_INTENT_MATCHING = false;
    242     private static final boolean DEBUG_PACKAGE_SCANNING = false;
    243     private static final boolean DEBUG_VERIFY = false;
    244     private static final boolean DEBUG_DEXOPT = false;
    245     private static final boolean DEBUG_ABI_SELECTION = false;
    246 
    247     private static final int RADIO_UID = Process.PHONE_UID;
    248     private static final int LOG_UID = Process.LOG_UID;
    249     private static final int NFC_UID = Process.NFC_UID;
    250     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
    251     private static final int SHELL_UID = Process.SHELL_UID;
    252 
    253     // Cap the size of permission trees that 3rd party apps can define
    254     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
    255 
    256     // Suffix used during package installation when copying/moving
    257     // package apks to install directory.
    258     private static final String INSTALL_PACKAGE_SUFFIX = "-";
    259 
    260     static final int SCAN_NO_DEX = 1<<1;
    261     static final int SCAN_FORCE_DEX = 1<<2;
    262     static final int SCAN_UPDATE_SIGNATURE = 1<<3;
    263     static final int SCAN_NEW_INSTALL = 1<<4;
    264     static final int SCAN_NO_PATHS = 1<<5;
    265     static final int SCAN_UPDATE_TIME = 1<<6;
    266     static final int SCAN_DEFER_DEX = 1<<7;
    267     static final int SCAN_BOOTING = 1<<8;
    268     static final int SCAN_TRUSTED_OVERLAY = 1<<9;
    269     static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10;
    270     static final int SCAN_REPLACING = 1<<11;
    271 
    272     static final int REMOVE_CHATTY = 1<<16;
    273 
    274     /**
    275      * Timeout (in milliseconds) after which the watchdog should declare that
    276      * our handler thread is wedged.  The usual default for such things is one
    277      * minute but we sometimes do very lengthy I/O operations on this thread,
    278      * such as installing multi-gigabyte applications, so ours needs to be longer.
    279      */
    280     private static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
    281 
    282     /**
    283      * Whether verification is enabled by default.
    284      */
    285     private static final boolean DEFAULT_VERIFY_ENABLE = true;
    286 
    287     /**
    288      * The default maximum time to wait for the verification agent to return in
    289      * milliseconds.
    290      */
    291     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
    292 
    293     /**
    294      * The default response for package verification timeout.
    295      *
    296      * This can be either PackageManager.VERIFICATION_ALLOW or
    297      * PackageManager.VERIFICATION_REJECT.
    298      */
    299     private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
    300 
    301     static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
    302 
    303     static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
    304             DEFAULT_CONTAINER_PACKAGE,
    305             "com.android.defcontainer.DefaultContainerService");
    306 
    307     private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
    308 
    309     private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
    310 
    311     private static String sPreferredInstructionSet;
    312 
    313     final ServiceThread mHandlerThread;
    314 
    315     private static final String IDMAP_PREFIX = "/data/resource-cache/";
    316     private static final String IDMAP_SUFFIX = "@idmap";
    317 
    318     final PackageHandler mHandler;
    319 
    320     /**
    321      * Messages for {@link #mHandler} that need to wait for system ready before
    322      * being dispatched.
    323      */
    324     private ArrayList<Message> mPostSystemReadyMessages;
    325 
    326     final int mSdkVersion = Build.VERSION.SDK_INT;
    327 
    328     final Context mContext;
    329     final boolean mFactoryTest;
    330     final boolean mOnlyCore;
    331     final boolean mLazyDexOpt;
    332     final DisplayMetrics mMetrics;
    333     final int mDefParseFlags;
    334     final String[] mSeparateProcesses;
    335 
    336     // This is where all application persistent data goes.
    337     final File mAppDataDir;
    338 
    339     // This is where all application persistent data goes for secondary users.
    340     final File mUserAppDataDir;
    341 
    342     /** The location for ASEC container files on internal storage. */
    343     final String mAsecInternalPath;
    344 
    345     // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
    346     // LOCK HELD.  Can be called with mInstallLock held.
    347     final Installer mInstaller;
    348 
    349     /** Directory where installed third-party apps stored */
    350     final File mAppInstallDir;
    351 
    352     /**
    353      * Directory to which applications installed internally have their
    354      * 32 bit native libraries copied.
    355      */
    356     private File mAppLib32InstallDir;
    357 
    358     // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
    359     // apps.
    360     final File mDrmAppPrivateInstallDir;
    361 
    362     // ----------------------------------------------------------------
    363 
    364     // Lock for state used when installing and doing other long running
    365     // operations.  Methods that must be called with this lock held have
    366     // the suffix "LI".
    367     final Object mInstallLock = new Object();
    368 
    369     // ----------------------------------------------------------------
    370 
    371     // Keys are String (package name), values are Package.  This also serves
    372     // as the lock for the global state.  Methods that must be called with
    373     // this lock held have the prefix "LP".
    374     final HashMap<String, PackageParser.Package> mPackages =
    375             new HashMap<String, PackageParser.Package>();
    376 
    377     // Tracks available target package names -> overlay package paths.
    378     final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays =
    379         new HashMap<String, HashMap<String, PackageParser.Package>>();
    380 
    381     final Settings mSettings;
    382     boolean mRestoredSettings;
    383 
    384     // System configuration read by SystemConfig.
    385     final int[] mGlobalGids;
    386     final SparseArray<HashSet<String>> mSystemPermissions;
    387     final HashMap<String, FeatureInfo> mAvailableFeatures;
    388 
    389     // If mac_permissions.xml was found for seinfo labeling.
    390     boolean mFoundPolicyFile;
    391 
    392     // If a recursive restorecon of /data/data/<pkg> is needed.
    393     private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon();
    394 
    395     public static final class SharedLibraryEntry {
    396         public final String path;
    397         public final String apk;
    398 
    399         SharedLibraryEntry(String _path, String _apk) {
    400             path = _path;
    401             apk = _apk;
    402         }
    403     }
    404 
    405     // Currently known shared libraries.
    406     final HashMap<String, SharedLibraryEntry> mSharedLibraries =
    407             new HashMap<String, SharedLibraryEntry>();
    408 
    409     // All available activities, for your resolving pleasure.
    410     final ActivityIntentResolver mActivities =
    411             new ActivityIntentResolver();
    412 
    413     // All available receivers, for your resolving pleasure.
    414     final ActivityIntentResolver mReceivers =
    415             new ActivityIntentResolver();
    416 
    417     // All available services, for your resolving pleasure.
    418     final ServiceIntentResolver mServices = new ServiceIntentResolver();
    419 
    420     // All available providers, for your resolving pleasure.
    421     final ProviderIntentResolver mProviders = new ProviderIntentResolver();
    422 
    423     // Mapping from provider base names (first directory in content URI codePath)
    424     // to the provider information.
    425     final HashMap<String, PackageParser.Provider> mProvidersByAuthority =
    426             new HashMap<String, PackageParser.Provider>();
    427 
    428     // Mapping from instrumentation class names to info about them.
    429     final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
    430             new HashMap<ComponentName, PackageParser.Instrumentation>();
    431 
    432     // Mapping from permission names to info about them.
    433     final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups =
    434             new HashMap<String, PackageParser.PermissionGroup>();
    435 
    436     // Packages whose data we have transfered into another package, thus
    437     // should no longer exist.
    438     final HashSet<String> mTransferedPackages = new HashSet<String>();
    439 
    440     // Broadcast actions that are only available to the system.
    441     final HashSet<String> mProtectedBroadcasts = new HashSet<String>();
    442 
    443     /** List of packages waiting for verification. */
    444     final SparseArray<PackageVerificationState> mPendingVerification
    445             = new SparseArray<PackageVerificationState>();
    446 
    447     /** Set of packages associated with each app op permission. */
    448     final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
    449 
    450     final PackageInstallerService mInstallerService;
    451 
    452     HashSet<PackageParser.Package> mDeferredDexOpt = null;
    453 
    454     // Cache of users who need badging.
    455     SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
    456 
    457     /** Token for keys in mPendingVerification. */
    458     private int mPendingVerificationToken = 0;
    459 
    460     volatile boolean mSystemReady;
    461     volatile boolean mSafeMode;
    462     volatile boolean mHasSystemUidErrors;
    463 
    464     ApplicationInfo mAndroidApplication;
    465     final ActivityInfo mResolveActivity = new ActivityInfo();
    466     final ResolveInfo mResolveInfo = new ResolveInfo();
    467     ComponentName mResolveComponentName;
    468     PackageParser.Package mPlatformPackage;
    469     ComponentName mCustomResolverComponentName;
    470 
    471     boolean mResolverReplaced = false;
    472 
    473     // Set of pending broadcasts for aggregating enable/disable of components.
    474     static class PendingPackageBroadcasts {
    475         // for each user id, a map of <package name -> components within that package>
    476         final SparseArray<HashMap<String, ArrayList<String>>> mUidMap;
    477 
    478         public PendingPackageBroadcasts() {
    479             mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2);
    480         }
    481 
    482         public ArrayList<String> get(int userId, String packageName) {
    483             HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
    484             return packages.get(packageName);
    485         }
    486 
    487         public void put(int userId, String packageName, ArrayList<String> components) {
    488             HashMap<String, ArrayList<String>> packages = getOrAllocate(userId);
    489             packages.put(packageName, components);
    490         }
    491 
    492         public void remove(int userId, String packageName) {
    493             HashMap<String, ArrayList<String>> packages = mUidMap.get(userId);
    494             if (packages != null) {
    495                 packages.remove(packageName);
    496             }
    497         }
    498 
    499         public void remove(int userId) {
    500             mUidMap.remove(userId);
    501         }
    502 
    503         public int userIdCount() {
    504             return mUidMap.size();
    505         }
    506 
    507         public int userIdAt(int n) {
    508             return mUidMap.keyAt(n);
    509         }
    510 
    511         public HashMap<String, ArrayList<String>> packagesForUserId(int userId) {
    512             return mUidMap.get(userId);
    513         }
    514 
    515         public int size() {
    516             // total number of pending broadcast entries across all userIds
    517             int num = 0;
    518             for (int i = 0; i< mUidMap.size(); i++) {
    519                 num += mUidMap.valueAt(i).size();
    520             }
    521             return num;
    522         }
    523 
    524         public void clear() {
    525             mUidMap.clear();
    526         }
    527 
    528         private HashMap<String, ArrayList<String>> getOrAllocate(int userId) {
    529             HashMap<String, ArrayList<String>> map = mUidMap.get(userId);
    530             if (map == null) {
    531                 map = new HashMap<String, ArrayList<String>>();
    532                 mUidMap.put(userId, map);
    533             }
    534             return map;
    535         }
    536     }
    537     final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
    538 
    539     // Service Connection to remote media container service to copy
    540     // package uri's from external media onto secure containers
    541     // or internal storage.
    542     private IMediaContainerService mContainerService = null;
    543 
    544     static final int SEND_PENDING_BROADCAST = 1;
    545     static final int MCS_BOUND = 3;
    546     static final int END_COPY = 4;
    547     static final int INIT_COPY = 5;
    548     static final int MCS_UNBIND = 6;
    549     static final int START_CLEANING_PACKAGE = 7;
    550     static final int FIND_INSTALL_LOC = 8;
    551     static final int POST_INSTALL = 9;
    552     static final int MCS_RECONNECT = 10;
    553     static final int MCS_GIVE_UP = 11;
    554     static final int UPDATED_MEDIA_STATUS = 12;
    555     static final int WRITE_SETTINGS = 13;
    556     static final int WRITE_PACKAGE_RESTRICTIONS = 14;
    557     static final int PACKAGE_VERIFIED = 15;
    558     static final int CHECK_PENDING_VERIFICATION = 16;
    559 
    560     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
    561 
    562     // Delay time in millisecs
    563     static final int BROADCAST_DELAY = 10 * 1000;
    564 
    565     static UserManagerService sUserManager;
    566 
    567     // Stores a list of users whose package restrictions file needs to be updated
    568     private HashSet<Integer> mDirtyUsers = new HashSet<Integer>();
    569 
    570     final private DefaultContainerConnection mDefContainerConn =
    571             new DefaultContainerConnection();
    572     class DefaultContainerConnection implements ServiceConnection {
    573         public void onServiceConnected(ComponentName name, IBinder service) {
    574             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
    575             IMediaContainerService imcs =
    576                 IMediaContainerService.Stub.asInterface(service);
    577             mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
    578         }
    579 
    580         public void onServiceDisconnected(ComponentName name) {
    581             if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
    582         }
    583     };
    584 
    585     // Recordkeeping of restore-after-install operations that are currently in flight
    586     // between the Package Manager and the Backup Manager
    587     class PostInstallData {
    588         public InstallArgs args;
    589         public PackageInstalledInfo res;
    590 
    591         PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
    592             args = _a;
    593             res = _r;
    594         }
    595     };
    596     final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
    597     int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
    598 
    599     private final String mRequiredVerifierPackage;
    600 
    601     private final PackageUsage mPackageUsage = new PackageUsage();
    602 
    603     private class PackageUsage {
    604         private static final int WRITE_INTERVAL
    605             = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms
    606 
    607         private final Object mFileLock = new Object();
    608         private final AtomicLong mLastWritten = new AtomicLong(0);
    609         private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false);
    610 
    611         private boolean mIsHistoricalPackageUsageAvailable = true;
    612 
    613         boolean isHistoricalPackageUsageAvailable() {
    614             return mIsHistoricalPackageUsageAvailable;
    615         }
    616 
    617         void write(boolean force) {
    618             if (force) {
    619                 writeInternal();
    620                 return;
    621             }
    622             if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL
    623                 && !DEBUG_DEXOPT) {
    624                 return;
    625             }
    626             if (mBackgroundWriteRunning.compareAndSet(false, true)) {
    627                 new Thread("PackageUsage_DiskWriter") {
    628                     @Override
    629                     public void run() {
    630                         try {
    631                             writeInternal();
    632                         } finally {
    633                             mBackgroundWriteRunning.set(false);
    634                         }
    635                     }
    636                 }.start();
    637             }
    638         }
    639 
    640         private void writeInternal() {
    641             synchronized (mPackages) {
    642                 synchronized (mFileLock) {
    643                     AtomicFile file = getFile();
    644                     FileOutputStream f = null;
    645                     try {
    646                         f = file.startWrite();
    647                         BufferedOutputStream out = new BufferedOutputStream(f);
    648                         FileUtils.setPermissions(file.getBaseFile().getPath(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
    649                         StringBuilder sb = new StringBuilder();
    650                         for (PackageParser.Package pkg : mPackages.values()) {
    651                             if (pkg.mLastPackageUsageTimeInMills == 0) {
    652                                 continue;
    653                             }
    654                             sb.setLength(0);
    655                             sb.append(pkg.packageName);
    656                             sb.append(' ');
    657                             sb.append((long)pkg.mLastPackageUsageTimeInMills);
    658                             sb.append('\n');
    659                             out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
    660                         }
    661                         out.flush();
    662                         file.finishWrite(f);
    663                     } catch (IOException e) {
    664                         if (f != null) {
    665                             file.failWrite(f);
    666                         }
    667                         Log.e(TAG, "Failed to write package usage times", e);
    668                     }
    669                 }
    670             }
    671             mLastWritten.set(SystemClock.elapsedRealtime());
    672         }
    673 
    674         void readLP() {
    675             synchronized (mFileLock) {
    676                 AtomicFile file = getFile();
    677                 BufferedInputStream in = null;
    678                 try {
    679                     in = new BufferedInputStream(file.openRead());
    680                     StringBuffer sb = new StringBuffer();
    681                     while (true) {
    682                         String packageName = readToken(in, sb, ' ');
    683                         if (packageName == null) {
    684                             break;
    685                         }
    686                         String timeInMillisString = readToken(in, sb, '\n');
    687                         if (timeInMillisString == null) {
    688                             throw new IOException("Failed to find last usage time for package "
    689                                                   + packageName);
    690                         }
    691                         PackageParser.Package pkg = mPackages.get(packageName);
    692                         if (pkg == null) {
    693                             continue;
    694                         }
    695                         long timeInMillis;
    696                         try {
    697                             timeInMillis = Long.parseLong(timeInMillisString.toString());
    698                         } catch (NumberFormatException e) {
    699                             throw new IOException("Failed to parse " + timeInMillisString
    700                                                   + " as a long.", e);
    701                         }
    702                         pkg.mLastPackageUsageTimeInMills = timeInMillis;
    703                     }
    704                 } catch (FileNotFoundException expected) {
    705                     mIsHistoricalPackageUsageAvailable = false;
    706                 } catch (IOException e) {
    707                     Log.w(TAG, "Failed to read package usage times", e);
    708                 } finally {
    709                     IoUtils.closeQuietly(in);
    710                 }
    711             }
    712             mLastWritten.set(SystemClock.elapsedRealtime());
    713         }
    714 
    715         private String readToken(InputStream in, StringBuffer sb, char endOfToken)
    716                 throws IOException {
    717             sb.setLength(0);
    718             while (true) {
    719                 int ch = in.read();
    720                 if (ch == -1) {
    721                     if (sb.length() == 0) {
    722                         return null;
    723                     }
    724                     throw new IOException("Unexpected EOF");
    725                 }
    726                 if (ch == endOfToken) {
    727                     return sb.toString();
    728                 }
    729                 sb.append((char)ch);
    730             }
    731         }
    732 
    733         private AtomicFile getFile() {
    734             File dataDir = Environment.getDataDirectory();
    735             File systemDir = new File(dataDir, "system");
    736             File fname = new File(systemDir, "package-usage.list");
    737             return new AtomicFile(fname);
    738         }
    739     }
    740 
    741     class PackageHandler extends Handler {
    742         private boolean mBound = false;
    743         final ArrayList<HandlerParams> mPendingInstalls =
    744             new ArrayList<HandlerParams>();
    745 
    746         private boolean connectToService() {
    747             if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
    748                     " DefaultContainerService");
    749             Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
    750             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    751             if (mContext.bindServiceAsUser(service, mDefContainerConn,
    752                     Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
    753                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    754                 mBound = true;
    755                 return true;
    756             }
    757             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    758             return false;
    759         }
    760 
    761         private void disconnectService() {
    762             mContainerService = null;
    763             mBound = false;
    764             Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    765             mContext.unbindService(mDefContainerConn);
    766             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    767         }
    768 
    769         PackageHandler(Looper looper) {
    770             super(looper);
    771         }
    772 
    773         public void handleMessage(Message msg) {
    774             try {
    775                 doHandleMessage(msg);
    776             } finally {
    777                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    778             }
    779         }
    780 
    781         void doHandleMessage(Message msg) {
    782             switch (msg.what) {
    783                 case INIT_COPY: {
    784                     HandlerParams params = (HandlerParams) msg.obj;
    785                     int idx = mPendingInstalls.size();
    786                     if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
    787                     // If a bind was already initiated we dont really
    788                     // need to do anything. The pending install
    789                     // will be processed later on.
    790                     if (!mBound) {
    791                         // If this is the only one pending we might
    792                         // have to bind to the service again.
    793                         if (!connectToService()) {
    794                             Slog.e(TAG, "Failed to bind to media container service");
    795                             params.serviceError();
    796                             return;
    797                         } else {
    798                             // Once we bind to the service, the first
    799                             // pending request will be processed.
    800                             mPendingInstalls.add(idx, params);
    801                         }
    802                     } else {
    803                         mPendingInstalls.add(idx, params);
    804                         // Already bound to the service. Just make
    805                         // sure we trigger off processing the first request.
    806                         if (idx == 0) {
    807                             mHandler.sendEmptyMessage(MCS_BOUND);
    808                         }
    809                     }
    810                     break;
    811                 }
    812                 case MCS_BOUND: {
    813                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
    814                     if (msg.obj != null) {
    815                         mContainerService = (IMediaContainerService) msg.obj;
    816                     }
    817                     if (mContainerService == null) {
    818                         // Something seriously wrong. Bail out
    819                         Slog.e(TAG, "Cannot bind to media container service");
    820                         for (HandlerParams params : mPendingInstalls) {
    821                             // Indicate service bind error
    822                             params.serviceError();
    823                         }
    824                         mPendingInstalls.clear();
    825                     } else if (mPendingInstalls.size() > 0) {
    826                         HandlerParams params = mPendingInstalls.get(0);
    827                         if (params != null) {
    828                             if (params.startCopy()) {
    829                                 // We are done...  look for more work or to
    830                                 // go idle.
    831                                 if (DEBUG_SD_INSTALL) Log.i(TAG,
    832                                         "Checking for more work or unbind...");
    833                                 // Delete pending install
    834                                 if (mPendingInstalls.size() > 0) {
    835                                     mPendingInstalls.remove(0);
    836                                 }
    837                                 if (mPendingInstalls.size() == 0) {
    838                                     if (mBound) {
    839                                         if (DEBUG_SD_INSTALL) Log.i(TAG,
    840                                                 "Posting delayed MCS_UNBIND");
    841                                         removeMessages(MCS_UNBIND);
    842                                         Message ubmsg = obtainMessage(MCS_UNBIND);
    843                                         // Unbind after a little delay, to avoid
    844                                         // continual thrashing.
    845                                         sendMessageDelayed(ubmsg, 10000);
    846                                     }
    847                                 } else {
    848                                     // There are more pending requests in queue.
    849                                     // Just post MCS_BOUND message to trigger processing
    850                                     // of next pending install.
    851                                     if (DEBUG_SD_INSTALL) Log.i(TAG,
    852                                             "Posting MCS_BOUND for next work");
    853                                     mHandler.sendEmptyMessage(MCS_BOUND);
    854                                 }
    855                             }
    856                         }
    857                     } else {
    858                         // Should never happen ideally.
    859                         Slog.w(TAG, "Empty queue");
    860                     }
    861                     break;
    862                 }
    863                 case MCS_RECONNECT: {
    864                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
    865                     if (mPendingInstalls.size() > 0) {
    866                         if (mBound) {
    867                             disconnectService();
    868                         }
    869                         if (!connectToService()) {
    870                             Slog.e(TAG, "Failed to bind to media container service");
    871                             for (HandlerParams params : mPendingInstalls) {
    872                                 // Indicate service bind error
    873                                 params.serviceError();
    874                             }
    875                             mPendingInstalls.clear();
    876                         }
    877                     }
    878                     break;
    879                 }
    880                 case MCS_UNBIND: {
    881                     // If there is no actual work left, then time to unbind.
    882                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
    883 
    884                     if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
    885                         if (mBound) {
    886                             if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
    887 
    888                             disconnectService();
    889                         }
    890                     } else if (mPendingInstalls.size() > 0) {
    891                         // There are more pending requests in queue.
    892                         // Just post MCS_BOUND message to trigger processing
    893                         // of next pending install.
    894                         mHandler.sendEmptyMessage(MCS_BOUND);
    895                     }
    896 
    897                     break;
    898                 }
    899                 case MCS_GIVE_UP: {
    900                     if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
    901                     mPendingInstalls.remove(0);
    902                     break;
    903                 }
    904                 case SEND_PENDING_BROADCAST: {
    905                     String packages[];
    906                     ArrayList<String> components[];
    907                     int size = 0;
    908                     int uids[];
    909                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    910                     synchronized (mPackages) {
    911                         if (mPendingBroadcasts == null) {
    912                             return;
    913                         }
    914                         size = mPendingBroadcasts.size();
    915                         if (size <= 0) {
    916                             // Nothing to be done. Just return
    917                             return;
    918                         }
    919                         packages = new String[size];
    920                         components = new ArrayList[size];
    921                         uids = new int[size];
    922                         int i = 0;  // filling out the above arrays
    923 
    924                         for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
    925                             int packageUserId = mPendingBroadcasts.userIdAt(n);
    926                             Iterator<Map.Entry<String, ArrayList<String>>> it
    927                                     = mPendingBroadcasts.packagesForUserId(packageUserId)
    928                                             .entrySet().iterator();
    929                             while (it.hasNext() && i < size) {
    930                                 Map.Entry<String, ArrayList<String>> ent = it.next();
    931                                 packages[i] = ent.getKey();
    932                                 components[i] = ent.getValue();
    933                                 PackageSetting ps = mSettings.mPackages.get(ent.getKey());
    934                                 uids[i] = (ps != null)
    935                                         ? UserHandle.getUid(packageUserId, ps.appId)
    936                                         : -1;
    937                                 i++;
    938                             }
    939                         }
    940                         size = i;
    941                         mPendingBroadcasts.clear();
    942                     }
    943                     // Send broadcasts
    944                     for (int i = 0; i < size; i++) {
    945                         sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
    946                     }
    947                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    948                     break;
    949                 }
    950                 case START_CLEANING_PACKAGE: {
    951                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
    952                     final String packageName = (String)msg.obj;
    953                     final int userId = msg.arg1;
    954                     final boolean andCode = msg.arg2 != 0;
    955                     synchronized (mPackages) {
    956                         if (userId == UserHandle.USER_ALL) {
    957                             int[] users = sUserManager.getUserIds();
    958                             for (int user : users) {
    959                                 mSettings.addPackageToCleanLPw(
    960                                         new PackageCleanItem(user, packageName, andCode));
    961                             }
    962                         } else {
    963                             mSettings.addPackageToCleanLPw(
    964                                     new PackageCleanItem(userId, packageName, andCode));
    965                         }
    966                     }
    967                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    968                     startCleaningPackages();
    969                 } break;
    970                 case POST_INSTALL: {
    971                     if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
    972                     PostInstallData data = mRunningInstalls.get(msg.arg1);
    973                     mRunningInstalls.delete(msg.arg1);
    974                     boolean deleteOld = false;
    975 
    976                     if (data != null) {
    977                         InstallArgs args = data.args;
    978                         PackageInstalledInfo res = data.res;
    979 
    980                         if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
    981                             res.removedInfo.sendBroadcast(false, true, false);
    982                             Bundle extras = new Bundle(1);
    983                             extras.putInt(Intent.EXTRA_UID, res.uid);
    984                             // Determine the set of users who are adding this
    985                             // package for the first time vs. those who are seeing
    986                             // an update.
    987                             int[] firstUsers;
    988                             int[] updateUsers = new int[0];
    989                             if (res.origUsers == null || res.origUsers.length == 0) {
    990                                 firstUsers = res.newUsers;
    991                             } else {
    992                                 firstUsers = new int[0];
    993                                 for (int i=0; i<res.newUsers.length; i++) {
    994                                     int user = res.newUsers[i];
    995                                     boolean isNew = true;
    996                                     for (int j=0; j<res.origUsers.length; j++) {
    997                                         if (res.origUsers[j] == user) {
    998                                             isNew = false;
    999                                             break;
   1000                                         }
   1001                                     }
   1002                                     if (isNew) {
   1003                                         int[] newFirst = new int[firstUsers.length+1];
   1004                                         System.arraycopy(firstUsers, 0, newFirst, 0,
   1005                                                 firstUsers.length);
   1006                                         newFirst[firstUsers.length] = user;
   1007                                         firstUsers = newFirst;
   1008                                     } else {
   1009                                         int[] newUpdate = new int[updateUsers.length+1];
   1010                                         System.arraycopy(updateUsers, 0, newUpdate, 0,
   1011                                                 updateUsers.length);
   1012                                         newUpdate[updateUsers.length] = user;
   1013                                         updateUsers = newUpdate;
   1014                                     }
   1015                                 }
   1016                             }
   1017                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
   1018                                     res.pkg.applicationInfo.packageName,
   1019                                     extras, null, null, firstUsers);
   1020                             final boolean update = res.removedInfo.removedPackage != null;
   1021                             if (update) {
   1022                                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   1023                             }
   1024                             sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
   1025                                     res.pkg.applicationInfo.packageName,
   1026                                     extras, null, null, updateUsers);
   1027                             if (update) {
   1028                                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
   1029                                         res.pkg.applicationInfo.packageName,
   1030                                         extras, null, null, updateUsers);
   1031                                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
   1032                                         null, null,
   1033                                         res.pkg.applicationInfo.packageName, null, updateUsers);
   1034 
   1035                                 // treat asec-hosted packages like removable media on upgrade
   1036                                 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) {
   1037                                     if (DEBUG_INSTALL) {
   1038                                         Slog.i(TAG, "upgrading pkg " + res.pkg
   1039                                                 + " is ASEC-hosted -> AVAILABLE");
   1040                                     }
   1041                                     int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
   1042                                     ArrayList<String> pkgList = new ArrayList<String>(1);
   1043                                     pkgList.add(res.pkg.applicationInfo.packageName);
   1044                                     sendResourcesChangedBroadcast(true, true,
   1045                                             pkgList,uidArray, null);
   1046                                 }
   1047                             }
   1048                             if (res.removedInfo.args != null) {
   1049                                 // Remove the replaced package's older resources safely now
   1050                                 deleteOld = true;
   1051                             }
   1052 
   1053                             // Log current value of "unknown sources" setting
   1054                             EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
   1055                                 getUnknownSourcesSettings());
   1056                         }
   1057                         // Force a gc to clear up things
   1058                         Runtime.getRuntime().gc();
   1059                         // We delete after a gc for applications  on sdcard.
   1060                         if (deleteOld) {
   1061                             synchronized (mInstallLock) {
   1062                                 res.removedInfo.args.doPostDeleteLI(true);
   1063                             }
   1064                         }
   1065                         if (args.observer != null) {
   1066                             try {
   1067                                 Bundle extras = extrasForInstallResult(res);
   1068                                 args.observer.onPackageInstalled(res.name, res.returnCode,
   1069                                         res.returnMsg, extras);
   1070                             } catch (RemoteException e) {
   1071                                 Slog.i(TAG, "Observer no longer exists.");
   1072                             }
   1073                         }
   1074                     } else {
   1075                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
   1076                     }
   1077                 } break;
   1078                 case UPDATED_MEDIA_STATUS: {
   1079                     if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
   1080                     boolean reportStatus = msg.arg1 == 1;
   1081                     boolean doGc = msg.arg2 == 1;
   1082                     if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
   1083                     if (doGc) {
   1084                         // Force a gc to clear up stale containers.
   1085                         Runtime.getRuntime().gc();
   1086                     }
   1087                     if (msg.obj != null) {
   1088                         @SuppressWarnings("unchecked")
   1089                         Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
   1090                         if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
   1091                         // Unload containers
   1092                         unloadAllContainers(args);
   1093                     }
   1094                     if (reportStatus) {
   1095                         try {
   1096                             if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back");
   1097                             PackageHelper.getMountService().finishMediaUpdate();
   1098                         } catch (RemoteException e) {
   1099                             Log.e(TAG, "MountService not running?");
   1100                         }
   1101                     }
   1102                 } break;
   1103                 case WRITE_SETTINGS: {
   1104                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1105                     synchronized (mPackages) {
   1106                         removeMessages(WRITE_SETTINGS);
   1107                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
   1108                         mSettings.writeLPr();
   1109                         mDirtyUsers.clear();
   1110                     }
   1111                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1112                 } break;
   1113                 case WRITE_PACKAGE_RESTRICTIONS: {
   1114                     Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
   1115                     synchronized (mPackages) {
   1116                         removeMessages(WRITE_PACKAGE_RESTRICTIONS);
   1117                         for (int userId : mDirtyUsers) {
   1118                             mSettings.writePackageRestrictionsLPr(userId);
   1119                         }
   1120                         mDirtyUsers.clear();
   1121                     }
   1122                     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
   1123                 } break;
   1124                 case CHECK_PENDING_VERIFICATION: {
   1125                     final int verificationId = msg.arg1;
   1126                     final PackageVerificationState state = mPendingVerification.get(verificationId);
   1127 
   1128                     if ((state != null) && !state.timeoutExtended()) {
   1129                         final InstallArgs args = state.getInstallArgs();
   1130                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
   1131 
   1132                         Slog.i(TAG, "Verification timed out for " + originUri);
   1133                         mPendingVerification.remove(verificationId);
   1134 
   1135                         int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   1136 
   1137                         if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) {
   1138                             Slog.i(TAG, "Continuing with installation of " + originUri);
   1139                             state.setVerifierResponse(Binder.getCallingUid(),
   1140                                     PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
   1141                             broadcastPackageVerified(verificationId, originUri,
   1142                                     PackageManager.VERIFICATION_ALLOW,
   1143                                     state.getInstallArgs().getUser());
   1144                             try {
   1145                                 ret = args.copyApk(mContainerService, true);
   1146                             } catch (RemoteException e) {
   1147                                 Slog.e(TAG, "Could not contact the ContainerService");
   1148                             }
   1149                         } else {
   1150                             broadcastPackageVerified(verificationId, originUri,
   1151                                     PackageManager.VERIFICATION_REJECT,
   1152                                     state.getInstallArgs().getUser());
   1153                         }
   1154 
   1155                         processPendingInstall(args, ret);
   1156                         mHandler.sendEmptyMessage(MCS_UNBIND);
   1157                     }
   1158                     break;
   1159                 }
   1160                 case PACKAGE_VERIFIED: {
   1161                     final int verificationId = msg.arg1;
   1162 
   1163                     final PackageVerificationState state = mPendingVerification.get(verificationId);
   1164                     if (state == null) {
   1165                         Slog.w(TAG, "Invalid verification token " + verificationId + " received");
   1166                         break;
   1167                     }
   1168 
   1169                     final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
   1170 
   1171                     state.setVerifierResponse(response.callerUid, response.code);
   1172 
   1173                     if (state.isVerificationComplete()) {
   1174                         mPendingVerification.remove(verificationId);
   1175 
   1176                         final InstallArgs args = state.getInstallArgs();
   1177                         final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
   1178 
   1179                         int ret;
   1180                         if (state.isInstallAllowed()) {
   1181                             ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   1182                             broadcastPackageVerified(verificationId, originUri,
   1183                                     response.code, state.getInstallArgs().getUser());
   1184                             try {
   1185                                 ret = args.copyApk(mContainerService, true);
   1186                             } catch (RemoteException e) {
   1187                                 Slog.e(TAG, "Could not contact the ContainerService");
   1188                             }
   1189                         } else {
   1190                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   1191                         }
   1192 
   1193                         processPendingInstall(args, ret);
   1194 
   1195                         mHandler.sendEmptyMessage(MCS_UNBIND);
   1196                     }
   1197 
   1198                     break;
   1199                 }
   1200             }
   1201         }
   1202     }
   1203 
   1204     Bundle extrasForInstallResult(PackageInstalledInfo res) {
   1205         Bundle extras = null;
   1206         switch (res.returnCode) {
   1207             case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
   1208                 extras = new Bundle();
   1209                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
   1210                         res.origPermission);
   1211                 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
   1212                         res.origPackage);
   1213                 break;
   1214             }
   1215         }
   1216         return extras;
   1217     }
   1218 
   1219     void scheduleWriteSettingsLocked() {
   1220         if (!mHandler.hasMessages(WRITE_SETTINGS)) {
   1221             mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
   1222         }
   1223     }
   1224 
   1225     void scheduleWritePackageRestrictionsLocked(int userId) {
   1226         if (!sUserManager.exists(userId)) return;
   1227         mDirtyUsers.add(userId);
   1228         if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
   1229             mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
   1230         }
   1231     }
   1232 
   1233     public static final PackageManagerService main(Context context, Installer installer,
   1234             boolean factoryTest, boolean onlyCore) {
   1235         PackageManagerService m = new PackageManagerService(context, installer,
   1236                 factoryTest, onlyCore);
   1237         ServiceManager.addService("package", m);
   1238         return m;
   1239     }
   1240 
   1241     static String[] splitString(String str, char sep) {
   1242         int count = 1;
   1243         int i = 0;
   1244         while ((i=str.indexOf(sep, i)) >= 0) {
   1245             count++;
   1246             i++;
   1247         }
   1248 
   1249         String[] res = new String[count];
   1250         i=0;
   1251         count = 0;
   1252         int lastI=0;
   1253         while ((i=str.indexOf(sep, i)) >= 0) {
   1254             res[count] = str.substring(lastI, i);
   1255             count++;
   1256             i++;
   1257             lastI = i;
   1258         }
   1259         res[count] = str.substring(lastI, str.length());
   1260         return res;
   1261     }
   1262 
   1263     private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
   1264         DisplayManager displayManager = (DisplayManager) context.getSystemService(
   1265                 Context.DISPLAY_SERVICE);
   1266         displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
   1267     }
   1268 
   1269     public PackageManagerService(Context context, Installer installer,
   1270             boolean factoryTest, boolean onlyCore) {
   1271         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
   1272                 SystemClock.uptimeMillis());
   1273 
   1274         if (mSdkVersion <= 0) {
   1275             Slog.w(TAG, "**** ro.build.version.sdk not set!");
   1276         }
   1277 
   1278         mContext = context;
   1279         mFactoryTest = factoryTest;
   1280         mOnlyCore = onlyCore;
   1281         mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type"));
   1282         mMetrics = new DisplayMetrics();
   1283         mSettings = new Settings(context);
   1284         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
   1285                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1286         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
   1287                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1288         mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
   1289                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1290         mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
   1291                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1292         mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
   1293                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1294         mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
   1295                 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED);
   1296 
   1297         String separateProcesses = SystemProperties.get("debug.separate_processes");
   1298         if (separateProcesses != null && separateProcesses.length() > 0) {
   1299             if ("*".equals(separateProcesses)) {
   1300                 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
   1301                 mSeparateProcesses = null;
   1302                 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
   1303             } else {
   1304                 mDefParseFlags = 0;
   1305                 mSeparateProcesses = separateProcesses.split(",");
   1306                 Slog.w(TAG, "Running with debug.separate_processes: "
   1307                         + separateProcesses);
   1308             }
   1309         } else {
   1310             mDefParseFlags = 0;
   1311             mSeparateProcesses = null;
   1312         }
   1313 
   1314         mInstaller = installer;
   1315 
   1316         getDefaultDisplayMetrics(context, mMetrics);
   1317 
   1318         SystemConfig systemConfig = SystemConfig.getInstance();
   1319         mGlobalGids = systemConfig.getGlobalGids();
   1320         mSystemPermissions = systemConfig.getSystemPermissions();
   1321         mAvailableFeatures = systemConfig.getAvailableFeatures();
   1322 
   1323         synchronized (mInstallLock) {
   1324         // writer
   1325         synchronized (mPackages) {
   1326             mHandlerThread = new ServiceThread(TAG,
   1327                     Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
   1328             mHandlerThread.start();
   1329             mHandler = new PackageHandler(mHandlerThread.getLooper());
   1330             Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
   1331 
   1332             File dataDir = Environment.getDataDirectory();
   1333             mAppDataDir = new File(dataDir, "data");
   1334             mAppInstallDir = new File(dataDir, "app");
   1335             mAppLib32InstallDir = new File(dataDir, "app-lib");
   1336             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
   1337             mUserAppDataDir = new File(dataDir, "user");
   1338             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
   1339 
   1340             sUserManager = new UserManagerService(context, this,
   1341                     mInstallLock, mPackages);
   1342 
   1343             // Propagate permission configuration in to package manager.
   1344             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
   1345                     = systemConfig.getPermissions();
   1346             for (int i=0; i<permConfig.size(); i++) {
   1347                 SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
   1348                 BasePermission bp = mSettings.mPermissions.get(perm.name);
   1349                 if (bp == null) {
   1350                     bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
   1351                     mSettings.mPermissions.put(perm.name, bp);
   1352                 }
   1353                 if (perm.gids != null) {
   1354                     bp.gids = appendInts(bp.gids, perm.gids);
   1355                 }
   1356             }
   1357 
   1358             ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
   1359             for (int i=0; i<libConfig.size(); i++) {
   1360                 mSharedLibraries.put(libConfig.keyAt(i),
   1361                         new SharedLibraryEntry(libConfig.valueAt(i), null));
   1362             }
   1363 
   1364             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
   1365 
   1366             mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false),
   1367                     mSdkVersion, mOnlyCore);
   1368 
   1369             String customResolverActivity = Resources.getSystem().getString(
   1370                     R.string.config_customResolverActivity);
   1371             if (TextUtils.isEmpty(customResolverActivity)) {
   1372                 customResolverActivity = null;
   1373             } else {
   1374                 mCustomResolverComponentName = ComponentName.unflattenFromString(
   1375                         customResolverActivity);
   1376             }
   1377 
   1378             long startTime = SystemClock.uptimeMillis();
   1379 
   1380             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
   1381                     startTime);
   1382 
   1383             // Set flag to monitor and not change apk file paths when
   1384             // scanning install directories.
   1385             final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
   1386 
   1387             final HashSet<String> alreadyDexOpted = new HashSet<String>();
   1388 
   1389             /**
   1390              * Add everything in the in the boot class path to the
   1391              * list of process files because dexopt will have been run
   1392              * if necessary during zygote startup.
   1393              */
   1394             final String bootClassPath = System.getenv("BOOTCLASSPATH");
   1395             final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
   1396 
   1397             if (bootClassPath != null) {
   1398                 String[] bootClassPathElements = splitString(bootClassPath, ':');
   1399                 for (String element : bootClassPathElements) {
   1400                     alreadyDexOpted.add(element);
   1401                 }
   1402             } else {
   1403                 Slog.w(TAG, "No BOOTCLASSPATH found!");
   1404             }
   1405 
   1406             if (systemServerClassPath != null) {
   1407                 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':');
   1408                 for (String element : systemServerClassPathElements) {
   1409                     alreadyDexOpted.add(element);
   1410                 }
   1411             } else {
   1412                 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
   1413             }
   1414 
   1415             boolean didDexOptLibraryOrTool = false;
   1416 
   1417             final List<String> allInstructionSets = getAllInstructionSets();
   1418             final String[] dexCodeInstructionSets =
   1419                 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()]));
   1420 
   1421             /**
   1422              * Ensure all external libraries have had dexopt run on them.
   1423              */
   1424             if (mSharedLibraries.size() > 0) {
   1425                 // NOTE: For now, we're compiling these system "shared libraries"
   1426                 // (and framework jars) into all available architectures. It's possible
   1427                 // to compile them only when we come across an app that uses them (there's
   1428                 // already logic for that in scanPackageLI) but that adds some complexity.
   1429                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   1430                     for (SharedLibraryEntry libEntry : mSharedLibraries.values()) {
   1431                         final String lib = libEntry.path;
   1432                         if (lib == null) {
   1433                             continue;
   1434                         }
   1435 
   1436                         try {
   1437                             byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
   1438                                                                                  dexCodeInstructionSet,
   1439                                                                                  false);
   1440                             if (dexoptRequired != DexFile.UP_TO_DATE) {
   1441                                 alreadyDexOpted.add(lib);
   1442 
   1443                                 // The list of "shared libraries" we have at this point is
   1444                                 if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
   1445                                     mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
   1446                                 } else {
   1447                                     mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet);
   1448                                 }
   1449                                 didDexOptLibraryOrTool = true;
   1450                             }
   1451                         } catch (FileNotFoundException e) {
   1452                             Slog.w(TAG, "Library not found: " + lib);
   1453                         } catch (IOException e) {
   1454                             Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
   1455                                     + e.getMessage());
   1456                         }
   1457                     }
   1458                 }
   1459             }
   1460 
   1461             File frameworkDir = new File(Environment.getRootDirectory(), "framework");
   1462 
   1463             // Gross hack for now: we know this file doesn't contain any
   1464             // code, so don't dexopt it to avoid the resulting log spew.
   1465             alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk");
   1466 
   1467             // Gross hack for now: we know this file is only part of
   1468             // the boot class path for art, so don't dexopt it to
   1469             // avoid the resulting log spew.
   1470             alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar");
   1471 
   1472             /**
   1473              * And there are a number of commands implemented in Java, which
   1474              * we currently need to do the dexopt on so that they can be
   1475              * run from a non-root shell.
   1476              */
   1477             String[] frameworkFiles = frameworkDir.list();
   1478             if (frameworkFiles != null) {
   1479                 // TODO: We could compile these only for the most preferred ABI. We should
   1480                 // first double check that the dex files for these commands are not referenced
   1481                 // by other system apps.
   1482                 for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   1483                     for (int i=0; i<frameworkFiles.length; i++) {
   1484                         File libPath = new File(frameworkDir, frameworkFiles[i]);
   1485                         String path = libPath.getPath();
   1486                         // Skip the file if we already did it.
   1487                         if (alreadyDexOpted.contains(path)) {
   1488                             continue;
   1489                         }
   1490                         // Skip the file if it is not a type we want to dexopt.
   1491                         if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
   1492                             continue;
   1493                         }
   1494                         try {
   1495                             byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
   1496                                                                                  dexCodeInstructionSet,
   1497                                                                                  false);
   1498                             if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
   1499                                 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
   1500                                 didDexOptLibraryOrTool = true;
   1501                             } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
   1502                                 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet);
   1503                                 didDexOptLibraryOrTool = true;
   1504                             }
   1505                         } catch (FileNotFoundException e) {
   1506                             Slog.w(TAG, "Jar not found: " + path);
   1507                         } catch (IOException e) {
   1508                             Slog.w(TAG, "Exception reading jar: " + path, e);
   1509                         }
   1510                     }
   1511                 }
   1512             }
   1513 
   1514             // Collect vendor overlay packages.
   1515             // (Do this before scanning any apps.)
   1516             // For security and version matching reason, only consider
   1517             // overlay packages if they reside in VENDOR_OVERLAY_DIR.
   1518             File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
   1519             scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
   1520                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
   1521 
   1522             // Find base frameworks (resource packages without code).
   1523             scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM
   1524                     | PackageParser.PARSE_IS_SYSTEM_DIR
   1525                     | PackageParser.PARSE_IS_PRIVILEGED,
   1526                     scanFlags | SCAN_NO_DEX, 0);
   1527 
   1528             // Collected privileged system packages.
   1529             final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
   1530             scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
   1531                     | PackageParser.PARSE_IS_SYSTEM_DIR
   1532                     | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
   1533 
   1534             // Collect ordinary system packages.
   1535             final File systemAppDir = new File(Environment.getRootDirectory(), "app");
   1536             scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM
   1537                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   1538 
   1539             // Collect all vendor packages.
   1540             File vendorAppDir = new File("/vendor/app");
   1541             try {
   1542                 vendorAppDir = vendorAppDir.getCanonicalFile();
   1543             } catch (IOException e) {
   1544                 // failed to look up canonical path, continue with original one
   1545             }
   1546             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
   1547                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   1548 
   1549             // Collect all OEM packages.
   1550             final File oemAppDir = new File(Environment.getOemDirectory(), "app");
   1551             scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
   1552                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
   1553 
   1554             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
   1555             mInstaller.moveFiles();
   1556 
   1557             // Prune any system packages that no longer exist.
   1558             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
   1559             final ArrayMap<String, File> expectingBetter = new ArrayMap<>();
   1560             if (!mOnlyCore) {
   1561                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
   1562                 while (psit.hasNext()) {
   1563                     PackageSetting ps = psit.next();
   1564 
   1565                     /*
   1566                      * If this is not a system app, it can't be a
   1567                      * disable system app.
   1568                      */
   1569                     if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
   1570                         continue;
   1571                     }
   1572 
   1573                     /*
   1574                      * If the package is scanned, it's not erased.
   1575                      */
   1576                     final PackageParser.Package scannedPkg = mPackages.get(ps.name);
   1577                     if (scannedPkg != null) {
   1578                         /*
   1579                          * If the system app is both scanned and in the
   1580                          * disabled packages list, then it must have been
   1581                          * added via OTA. Remove it from the currently
   1582                          * scanned package so the previously user-installed
   1583                          * application can be scanned.
   1584                          */
   1585                         if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
   1586                             logCriticalInfo(Log.WARN, "Expecting better updated system app for "
   1587                                     + ps.name + "; removing system app.  Last known codePath="
   1588                                     + ps.codePathString + ", installStatus=" + ps.installStatus
   1589                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
   1590                                     + scannedPkg.mVersionCode);
   1591                             removePackageLI(ps, true);
   1592                             expectingBetter.put(ps.name, ps.codePath);
   1593                         }
   1594 
   1595                         continue;
   1596                     }
   1597 
   1598                     if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
   1599                         psit.remove();
   1600                         logCriticalInfo(Log.WARN, "System package " + ps.name
   1601                                 + " no longer exists; wiping its data");
   1602                         removeDataDirsLI(ps.name);
   1603                     } else {
   1604                         final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
   1605                         if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
   1606                             possiblyDeletedUpdatedSystemApps.add(ps.name);
   1607                         }
   1608                     }
   1609                 }
   1610             }
   1611 
   1612             //look for any incomplete package installations
   1613             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
   1614             //clean up list
   1615             for(int i = 0; i < deletePkgsList.size(); i++) {
   1616                 //clean up here
   1617                 cleanupInstallFailedPackage(deletePkgsList.get(i));
   1618             }
   1619             //delete tmp files
   1620             deleteTempPackageFiles();
   1621 
   1622             // Remove any shared userIDs that have no associated packages
   1623             mSettings.pruneSharedUsersLPw();
   1624 
   1625             if (!mOnlyCore) {
   1626                 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
   1627                         SystemClock.uptimeMillis());
   1628                 scanDirLI(mAppInstallDir, 0, scanFlags, 0);
   1629 
   1630                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
   1631                         scanFlags, 0);
   1632 
   1633                 /**
   1634                  * Remove disable package settings for any updated system
   1635                  * apps that were removed via an OTA. If they're not a
   1636                  * previously-updated app, remove them completely.
   1637                  * Otherwise, just revoke their system-level permissions.
   1638                  */
   1639                 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
   1640                     PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
   1641                     mSettings.removeDisabledSystemPackageLPw(deletedAppName);
   1642 
   1643                     String msg;
   1644                     if (deletedPkg == null) {
   1645                         msg = "Updated system package " + deletedAppName
   1646                                 + " no longer exists; wiping its data";
   1647                         removeDataDirsLI(deletedAppName);
   1648                     } else {
   1649                         msg = "Updated system app + " + deletedAppName
   1650                                 + " no longer present; removing system privileges for "
   1651                                 + deletedAppName;
   1652 
   1653                         deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
   1654 
   1655                         PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
   1656                         deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
   1657                     }
   1658                     logCriticalInfo(Log.WARN, msg);
   1659                 }
   1660 
   1661                 /**
   1662                  * Make sure all system apps that we expected to appear on
   1663                  * the userdata partition actually showed up. If they never
   1664                  * appeared, crawl back and revive the system version.
   1665                  */
   1666                 for (int i = 0; i < expectingBetter.size(); i++) {
   1667                     final String packageName = expectingBetter.keyAt(i);
   1668                     if (!mPackages.containsKey(packageName)) {
   1669                         final File scanFile = expectingBetter.valueAt(i);
   1670 
   1671                         logCriticalInfo(Log.WARN, "Expected better " + packageName
   1672                                 + " but never showed up; reverting to system");
   1673 
   1674                         final int reparseFlags;
   1675                         if (FileUtils.contains(privilegedAppDir, scanFile)) {
   1676                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   1677                                     | PackageParser.PARSE_IS_SYSTEM_DIR
   1678                                     | PackageParser.PARSE_IS_PRIVILEGED;
   1679                         } else if (FileUtils.contains(systemAppDir, scanFile)) {
   1680                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   1681                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   1682                         } else if (FileUtils.contains(vendorAppDir, scanFile)) {
   1683                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   1684                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   1685                         } else if (FileUtils.contains(oemAppDir, scanFile)) {
   1686                             reparseFlags = PackageParser.PARSE_IS_SYSTEM
   1687                                     | PackageParser.PARSE_IS_SYSTEM_DIR;
   1688                         } else {
   1689                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
   1690                             continue;
   1691                         }
   1692 
   1693                         mSettings.enableSystemPackageLPw(packageName);
   1694 
   1695                         try {
   1696                             scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null);
   1697                         } catch (PackageManagerException e) {
   1698                             Slog.e(TAG, "Failed to parse original system package: "
   1699                                     + e.getMessage());
   1700                         }
   1701                     }
   1702                 }
   1703             }
   1704 
   1705             // Now that we know all of the shared libraries, update all clients to have
   1706             // the correct library paths.
   1707             updateAllSharedLibrariesLPw();
   1708 
   1709             for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
   1710                 // NOTE: We ignore potential failures here during a system scan (like
   1711                 // the rest of the commands above) because there's precious little we
   1712                 // can do about it. A settings error is reported, though.
   1713                 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
   1714                         false /* force dexopt */, false /* defer dexopt */);
   1715             }
   1716 
   1717             // Now that we know all the packages we are keeping,
   1718             // read and update their last usage times.
   1719             mPackageUsage.readLP();
   1720 
   1721             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
   1722                     SystemClock.uptimeMillis());
   1723             Slog.i(TAG, "Time to scan packages: "
   1724                     + ((SystemClock.uptimeMillis()-startTime)/1000f)
   1725                     + " seconds");
   1726 
   1727             // If the platform SDK has changed since the last time we booted,
   1728             // we need to re-grant app permission to catch any new ones that
   1729             // appear.  This is really a hack, and means that apps can in some
   1730             // cases get permissions that the user didn't initially explicitly
   1731             // allow...  it would be nice to have some better way to handle
   1732             // this situation.
   1733             final boolean regrantPermissions = mSettings.mInternalSdkPlatform
   1734                     != mSdkVersion;
   1735             if (regrantPermissions) Slog.i(TAG, "Platform changed from "
   1736                     + mSettings.mInternalSdkPlatform + " to " + mSdkVersion
   1737                     + "; regranting permissions for internal storage");
   1738             mSettings.mInternalSdkPlatform = mSdkVersion;
   1739 
   1740             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
   1741                     | (regrantPermissions
   1742                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
   1743                             : 0));
   1744 
   1745             // If this is the first boot, and it is a normal boot, then
   1746             // we need to initialize the default preferred apps.
   1747             if (!mRestoredSettings && !onlyCore) {
   1748                 mSettings.readDefaultPreferredAppsLPw(this, 0);
   1749             }
   1750 
   1751             // If this is first boot after an OTA, and a normal boot, then
   1752             // we need to clear code cache directories.
   1753             if (!Build.FINGERPRINT.equals(mSettings.mFingerprint) && !onlyCore) {
   1754                 Slog.i(TAG, "Build fingerprint changed; clearing code caches");
   1755                 for (String pkgName : mSettings.mPackages.keySet()) {
   1756                     deleteCodeCacheDirsLI(pkgName);
   1757                 }
   1758                 mSettings.mFingerprint = Build.FINGERPRINT;
   1759             }
   1760 
   1761             // All the changes are done during package scanning.
   1762             mSettings.updateInternalDatabaseVersion();
   1763 
   1764             // can downgrade to reader
   1765             mSettings.writeLPr();
   1766 
   1767             EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
   1768                     SystemClock.uptimeMillis());
   1769 
   1770 
   1771             mRequiredVerifierPackage = getRequiredVerifierLPr();
   1772         } // synchronized (mPackages)
   1773         } // synchronized (mInstallLock)
   1774 
   1775         mInstallerService = new PackageInstallerService(context, this, mAppInstallDir);
   1776 
   1777         // Now after opening every single application zip, make sure they
   1778         // are all flushed.  Not really needed, but keeps things nice and
   1779         // tidy.
   1780         Runtime.getRuntime().gc();
   1781     }
   1782 
   1783     @Override
   1784     public boolean isFirstBoot() {
   1785         return !mRestoredSettings;
   1786     }
   1787 
   1788     @Override
   1789     public boolean isOnlyCoreApps() {
   1790         return mOnlyCore;
   1791     }
   1792 
   1793     private String getRequiredVerifierLPr() {
   1794         final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
   1795         final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE,
   1796                 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */);
   1797 
   1798         String requiredVerifier = null;
   1799 
   1800         final int N = receivers.size();
   1801         for (int i = 0; i < N; i++) {
   1802             final ResolveInfo info = receivers.get(i);
   1803 
   1804             if (info.activityInfo == null) {
   1805                 continue;
   1806             }
   1807 
   1808             final String packageName = info.activityInfo.packageName;
   1809 
   1810             final PackageSetting ps = mSettings.mPackages.get(packageName);
   1811             if (ps == null) {
   1812                 continue;
   1813             }
   1814 
   1815             final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   1816             if (!gp.grantedPermissions
   1817                     .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) {
   1818                 continue;
   1819             }
   1820 
   1821             if (requiredVerifier != null) {
   1822                 throw new RuntimeException("There can be only one required verifier");
   1823             }
   1824 
   1825             requiredVerifier = packageName;
   1826         }
   1827 
   1828         return requiredVerifier;
   1829     }
   1830 
   1831     @Override
   1832     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1833             throws RemoteException {
   1834         try {
   1835             return super.onTransact(code, data, reply, flags);
   1836         } catch (RuntimeException e) {
   1837             if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
   1838                 Slog.wtf(TAG, "Package Manager Crash", e);
   1839             }
   1840             throw e;
   1841         }
   1842     }
   1843 
   1844     void cleanupInstallFailedPackage(PackageSetting ps) {
   1845         logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name);
   1846 
   1847         removeDataDirsLI(ps.name);
   1848         if (ps.codePath != null) {
   1849             if (ps.codePath.isDirectory()) {
   1850                 FileUtils.deleteContents(ps.codePath);
   1851             }
   1852             ps.codePath.delete();
   1853         }
   1854         if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) {
   1855             if (ps.resourcePath.isDirectory()) {
   1856                 FileUtils.deleteContents(ps.resourcePath);
   1857             }
   1858             ps.resourcePath.delete();
   1859         }
   1860         mSettings.removePackageLPw(ps.name);
   1861     }
   1862 
   1863     static int[] appendInts(int[] cur, int[] add) {
   1864         if (add == null) return cur;
   1865         if (cur == null) return add;
   1866         final int N = add.length;
   1867         for (int i=0; i<N; i++) {
   1868             cur = appendInt(cur, add[i]);
   1869         }
   1870         return cur;
   1871     }
   1872 
   1873     static int[] removeInts(int[] cur, int[] rem) {
   1874         if (rem == null) return cur;
   1875         if (cur == null) return cur;
   1876         final int N = rem.length;
   1877         for (int i=0; i<N; i++) {
   1878             cur = removeInt(cur, rem[i]);
   1879         }
   1880         return cur;
   1881     }
   1882 
   1883     PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) {
   1884         if (!sUserManager.exists(userId)) return null;
   1885         final PackageSetting ps = (PackageSetting) p.mExtras;
   1886         if (ps == null) {
   1887             return null;
   1888         }
   1889         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   1890         final PackageUserState state = ps.readUserState(userId);
   1891         return PackageParser.generatePackageInfo(p, gp.gids, flags,
   1892                 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions,
   1893                 state, userId);
   1894     }
   1895 
   1896     @Override
   1897     public boolean isPackageAvailable(String packageName, int userId) {
   1898         if (!sUserManager.exists(userId)) return false;
   1899         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
   1900         synchronized (mPackages) {
   1901             PackageParser.Package p = mPackages.get(packageName);
   1902             if (p != null) {
   1903                 final PackageSetting ps = (PackageSetting) p.mExtras;
   1904                 if (ps != null) {
   1905                     final PackageUserState state = ps.readUserState(userId);
   1906                     if (state != null) {
   1907                         return PackageParser.isAvailable(state);
   1908                     }
   1909                 }
   1910             }
   1911         }
   1912         return false;
   1913     }
   1914 
   1915     @Override
   1916     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
   1917         if (!sUserManager.exists(userId)) return null;
   1918         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
   1919         // reader
   1920         synchronized (mPackages) {
   1921             PackageParser.Package p = mPackages.get(packageName);
   1922             if (DEBUG_PACKAGE_INFO)
   1923                 Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
   1924             if (p != null) {
   1925                 return generatePackageInfo(p, flags, userId);
   1926             }
   1927             if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   1928                 return generatePackageInfoFromSettingsLPw(packageName, flags, userId);
   1929             }
   1930         }
   1931         return null;
   1932     }
   1933 
   1934     @Override
   1935     public String[] currentToCanonicalPackageNames(String[] names) {
   1936         String[] out = new String[names.length];
   1937         // reader
   1938         synchronized (mPackages) {
   1939             for (int i=names.length-1; i>=0; i--) {
   1940                 PackageSetting ps = mSettings.mPackages.get(names[i]);
   1941                 out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
   1942             }
   1943         }
   1944         return out;
   1945     }
   1946 
   1947     @Override
   1948     public String[] canonicalToCurrentPackageNames(String[] names) {
   1949         String[] out = new String[names.length];
   1950         // reader
   1951         synchronized (mPackages) {
   1952             for (int i=names.length-1; i>=0; i--) {
   1953                 String cur = mSettings.mRenamedPackages.get(names[i]);
   1954                 out[i] = cur != null ? cur : names[i];
   1955             }
   1956         }
   1957         return out;
   1958     }
   1959 
   1960     @Override
   1961     public int getPackageUid(String packageName, int userId) {
   1962         if (!sUserManager.exists(userId)) return -1;
   1963         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
   1964         // reader
   1965         synchronized (mPackages) {
   1966             PackageParser.Package p = mPackages.get(packageName);
   1967             if(p != null) {
   1968                 return UserHandle.getUid(userId, p.applicationInfo.uid);
   1969             }
   1970             PackageSetting ps = mSettings.mPackages.get(packageName);
   1971             if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) {
   1972                 return -1;
   1973             }
   1974             p = ps.pkg;
   1975             return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1;
   1976         }
   1977     }
   1978 
   1979     @Override
   1980     public int[] getPackageGids(String packageName) {
   1981         // reader
   1982         synchronized (mPackages) {
   1983             PackageParser.Package p = mPackages.get(packageName);
   1984             if (DEBUG_PACKAGE_INFO)
   1985                 Log.v(TAG, "getPackageGids" + packageName + ": " + p);
   1986             if (p != null) {
   1987                 final PackageSetting ps = (PackageSetting)p.mExtras;
   1988                 return ps.getGids();
   1989             }
   1990         }
   1991         // stupid thing to indicate an error.
   1992         return new int[0];
   1993     }
   1994 
   1995     static final PermissionInfo generatePermissionInfo(
   1996             BasePermission bp, int flags) {
   1997         if (bp.perm != null) {
   1998             return PackageParser.generatePermissionInfo(bp.perm, flags);
   1999         }
   2000         PermissionInfo pi = new PermissionInfo();
   2001         pi.name = bp.name;
   2002         pi.packageName = bp.sourcePackage;
   2003         pi.nonLocalizedLabel = bp.name;
   2004         pi.protectionLevel = bp.protectionLevel;
   2005         return pi;
   2006     }
   2007 
   2008     @Override
   2009     public PermissionInfo getPermissionInfo(String name, int flags) {
   2010         // reader
   2011         synchronized (mPackages) {
   2012             final BasePermission p = mSettings.mPermissions.get(name);
   2013             if (p != null) {
   2014                 return generatePermissionInfo(p, flags);
   2015             }
   2016             return null;
   2017         }
   2018     }
   2019 
   2020     @Override
   2021     public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) {
   2022         // reader
   2023         synchronized (mPackages) {
   2024             ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
   2025             for (BasePermission p : mSettings.mPermissions.values()) {
   2026                 if (group == null) {
   2027                     if (p.perm == null || p.perm.info.group == null) {
   2028                         out.add(generatePermissionInfo(p, flags));
   2029                     }
   2030                 } else {
   2031                     if (p.perm != null && group.equals(p.perm.info.group)) {
   2032                         out.add(PackageParser.generatePermissionInfo(p.perm, flags));
   2033                     }
   2034                 }
   2035             }
   2036 
   2037             if (out.size() > 0) {
   2038                 return out;
   2039             }
   2040             return mPermissionGroups.containsKey(group) ? out : null;
   2041         }
   2042     }
   2043 
   2044     @Override
   2045     public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
   2046         // reader
   2047         synchronized (mPackages) {
   2048             return PackageParser.generatePermissionGroupInfo(
   2049                     mPermissionGroups.get(name), flags);
   2050         }
   2051     }
   2052 
   2053     @Override
   2054     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
   2055         // reader
   2056         synchronized (mPackages) {
   2057             final int N = mPermissionGroups.size();
   2058             ArrayList<PermissionGroupInfo> out
   2059                     = new ArrayList<PermissionGroupInfo>(N);
   2060             for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
   2061                 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
   2062             }
   2063             return out;
   2064         }
   2065     }
   2066 
   2067     private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
   2068             int userId) {
   2069         if (!sUserManager.exists(userId)) return null;
   2070         PackageSetting ps = mSettings.mPackages.get(packageName);
   2071         if (ps != null) {
   2072             if (ps.pkg == null) {
   2073                 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName,
   2074                         flags, userId);
   2075                 if (pInfo != null) {
   2076                     return pInfo.applicationInfo;
   2077                 }
   2078                 return null;
   2079             }
   2080             return PackageParser.generateApplicationInfo(ps.pkg, flags,
   2081                     ps.readUserState(userId), userId);
   2082         }
   2083         return null;
   2084     }
   2085 
   2086     private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags,
   2087             int userId) {
   2088         if (!sUserManager.exists(userId)) return null;
   2089         PackageSetting ps = mSettings.mPackages.get(packageName);
   2090         if (ps != null) {
   2091             PackageParser.Package pkg = ps.pkg;
   2092             if (pkg == null) {
   2093                 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) {
   2094                     return null;
   2095                 }
   2096                 // Only data remains, so we aren't worried about code paths
   2097                 pkg = new PackageParser.Package(packageName);
   2098                 pkg.applicationInfo.packageName = packageName;
   2099                 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY;
   2100                 pkg.applicationInfo.dataDir =
   2101                         getDataPathForPackage(packageName, 0).getPath();
   2102                 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
   2103                 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
   2104             }
   2105             return generatePackageInfo(pkg, flags, userId);
   2106         }
   2107         return null;
   2108     }
   2109 
   2110     @Override
   2111     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
   2112         if (!sUserManager.exists(userId)) return null;
   2113         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
   2114         // writer
   2115         synchronized (mPackages) {
   2116             PackageParser.Package p = mPackages.get(packageName);
   2117             if (DEBUG_PACKAGE_INFO) Log.v(
   2118                     TAG, "getApplicationInfo " + packageName
   2119                     + ": " + p);
   2120             if (p != null) {
   2121                 PackageSetting ps = mSettings.mPackages.get(packageName);
   2122                 if (ps == null) return null;
   2123                 // Note: isEnabledLP() does not apply here - always return info
   2124                 return PackageParser.generateApplicationInfo(
   2125                         p, flags, ps.readUserState(userId), userId);
   2126             }
   2127             if ("android".equals(packageName)||"system".equals(packageName)) {
   2128                 return mAndroidApplication;
   2129             }
   2130             if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) {
   2131                 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
   2132             }
   2133         }
   2134         return null;
   2135     }
   2136 
   2137 
   2138     @Override
   2139     public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) {
   2140         mContext.enforceCallingOrSelfPermission(
   2141                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   2142         // Queue up an async operation since clearing cache may take a little while.
   2143         mHandler.post(new Runnable() {
   2144             public void run() {
   2145                 mHandler.removeCallbacks(this);
   2146                 int retCode = -1;
   2147                 synchronized (mInstallLock) {
   2148                     retCode = mInstaller.freeCache(freeStorageSize);
   2149                     if (retCode < 0) {
   2150                         Slog.w(TAG, "Couldn't clear application caches");
   2151                     }
   2152                 }
   2153                 if (observer != null) {
   2154                     try {
   2155                         observer.onRemoveCompleted(null, (retCode >= 0));
   2156                     } catch (RemoteException e) {
   2157                         Slog.w(TAG, "RemoveException when invoking call back");
   2158                     }
   2159                 }
   2160             }
   2161         });
   2162     }
   2163 
   2164     @Override
   2165     public void freeStorage(final long freeStorageSize, final IntentSender pi) {
   2166         mContext.enforceCallingOrSelfPermission(
   2167                 android.Manifest.permission.CLEAR_APP_CACHE, null);
   2168         // Queue up an async operation since clearing cache may take a little while.
   2169         mHandler.post(new Runnable() {
   2170             public void run() {
   2171                 mHandler.removeCallbacks(this);
   2172                 int retCode = -1;
   2173                 synchronized (mInstallLock) {
   2174                     retCode = mInstaller.freeCache(freeStorageSize);
   2175                     if (retCode < 0) {
   2176                         Slog.w(TAG, "Couldn't clear application caches");
   2177                     }
   2178                 }
   2179                 if(pi != null) {
   2180                     try {
   2181                         // Callback via pending intent
   2182                         int code = (retCode >= 0) ? 1 : 0;
   2183                         pi.sendIntent(null, code, null,
   2184                                 null, null);
   2185                     } catch (SendIntentException e1) {
   2186                         Slog.i(TAG, "Failed to send pending intent");
   2187                     }
   2188                 }
   2189             }
   2190         });
   2191     }
   2192 
   2193     void freeStorage(long freeStorageSize) throws IOException {
   2194         synchronized (mInstallLock) {
   2195             if (mInstaller.freeCache(freeStorageSize) < 0) {
   2196                 throw new IOException("Failed to free enough space");
   2197             }
   2198         }
   2199     }
   2200 
   2201     @Override
   2202     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
   2203         if (!sUserManager.exists(userId)) return null;
   2204         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
   2205         synchronized (mPackages) {
   2206             PackageParser.Activity a = mActivities.mActivities.get(component);
   2207 
   2208             if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
   2209             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
   2210                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   2211                 if (ps == null) return null;
   2212                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
   2213                         userId);
   2214             }
   2215             if (mResolveComponentName.equals(component)) {
   2216                 return PackageParser.generateActivityInfo(mResolveActivity, flags,
   2217                         new PackageUserState(), userId);
   2218             }
   2219         }
   2220         return null;
   2221     }
   2222 
   2223     @Override
   2224     public boolean activitySupportsIntent(ComponentName component, Intent intent,
   2225             String resolvedType) {
   2226         synchronized (mPackages) {
   2227             PackageParser.Activity a = mActivities.mActivities.get(component);
   2228             if (a == null) {
   2229                 return false;
   2230             }
   2231             for (int i=0; i<a.intents.size(); i++) {
   2232                 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
   2233                         intent.getData(), intent.getCategories(), TAG) >= 0) {
   2234                     return true;
   2235                 }
   2236             }
   2237             return false;
   2238         }
   2239     }
   2240 
   2241     @Override
   2242     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
   2243         if (!sUserManager.exists(userId)) return null;
   2244         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
   2245         synchronized (mPackages) {
   2246             PackageParser.Activity a = mReceivers.mActivities.get(component);
   2247             if (DEBUG_PACKAGE_INFO) Log.v(
   2248                 TAG, "getReceiverInfo " + component + ": " + a);
   2249             if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) {
   2250                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   2251                 if (ps == null) return null;
   2252                 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId),
   2253                         userId);
   2254             }
   2255         }
   2256         return null;
   2257     }
   2258 
   2259     @Override
   2260     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
   2261         if (!sUserManager.exists(userId)) return null;
   2262         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
   2263         synchronized (mPackages) {
   2264             PackageParser.Service s = mServices.mServices.get(component);
   2265             if (DEBUG_PACKAGE_INFO) Log.v(
   2266                 TAG, "getServiceInfo " + component + ": " + s);
   2267             if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) {
   2268                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   2269                 if (ps == null) return null;
   2270                 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId),
   2271                         userId);
   2272             }
   2273         }
   2274         return null;
   2275     }
   2276 
   2277     @Override
   2278     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
   2279         if (!sUserManager.exists(userId)) return null;
   2280         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
   2281         synchronized (mPackages) {
   2282             PackageParser.Provider p = mProviders.mProviders.get(component);
   2283             if (DEBUG_PACKAGE_INFO) Log.v(
   2284                 TAG, "getProviderInfo " + component + ": " + p);
   2285             if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) {
   2286                 PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
   2287                 if (ps == null) return null;
   2288                 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId),
   2289                         userId);
   2290             }
   2291         }
   2292         return null;
   2293     }
   2294 
   2295     @Override
   2296     public String[] getSystemSharedLibraryNames() {
   2297         Set<String> libSet;
   2298         synchronized (mPackages) {
   2299             libSet = mSharedLibraries.keySet();
   2300             int size = libSet.size();
   2301             if (size > 0) {
   2302                 String[] libs = new String[size];
   2303                 libSet.toArray(libs);
   2304                 return libs;
   2305             }
   2306         }
   2307         return null;
   2308     }
   2309 
   2310     @Override
   2311     public FeatureInfo[] getSystemAvailableFeatures() {
   2312         Collection<FeatureInfo> featSet;
   2313         synchronized (mPackages) {
   2314             featSet = mAvailableFeatures.values();
   2315             int size = featSet.size();
   2316             if (size > 0) {
   2317                 FeatureInfo[] features = new FeatureInfo[size+1];
   2318                 featSet.toArray(features);
   2319                 FeatureInfo fi = new FeatureInfo();
   2320                 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
   2321                         FeatureInfo.GL_ES_VERSION_UNDEFINED);
   2322                 features[size] = fi;
   2323                 return features;
   2324             }
   2325         }
   2326         return null;
   2327     }
   2328 
   2329     @Override
   2330     public boolean hasSystemFeature(String name) {
   2331         synchronized (mPackages) {
   2332             return mAvailableFeatures.containsKey(name);
   2333         }
   2334     }
   2335 
   2336     private void checkValidCaller(int uid, int userId) {
   2337         if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0)
   2338             return;
   2339 
   2340         throw new SecurityException("Caller uid=" + uid
   2341                 + " is not privileged to communicate with user=" + userId);
   2342     }
   2343 
   2344     @Override
   2345     public int checkPermission(String permName, String pkgName) {
   2346         synchronized (mPackages) {
   2347             PackageParser.Package p = mPackages.get(pkgName);
   2348             if (p != null && p.mExtras != null) {
   2349                 PackageSetting ps = (PackageSetting)p.mExtras;
   2350                 if (ps.sharedUser != null) {
   2351                     if (ps.sharedUser.grantedPermissions.contains(permName)) {
   2352                         return PackageManager.PERMISSION_GRANTED;
   2353                     }
   2354                 } else if (ps.grantedPermissions.contains(permName)) {
   2355                     return PackageManager.PERMISSION_GRANTED;
   2356                 }
   2357             }
   2358         }
   2359         return PackageManager.PERMISSION_DENIED;
   2360     }
   2361 
   2362     @Override
   2363     public int checkUidPermission(String permName, int uid) {
   2364         synchronized (mPackages) {
   2365             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   2366             if (obj != null) {
   2367                 GrantedPermissions gp = (GrantedPermissions)obj;
   2368                 if (gp.grantedPermissions.contains(permName)) {
   2369                     return PackageManager.PERMISSION_GRANTED;
   2370                 }
   2371             } else {
   2372                 HashSet<String> perms = mSystemPermissions.get(uid);
   2373                 if (perms != null && perms.contains(permName)) {
   2374                     return PackageManager.PERMISSION_GRANTED;
   2375                 }
   2376             }
   2377         }
   2378         return PackageManager.PERMISSION_DENIED;
   2379     }
   2380 
   2381     /**
   2382      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
   2383      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
   2384      * @param checkShell TODO(yamasani):
   2385      * @param message the message to log on security exception
   2386      */
   2387     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
   2388             boolean checkShell, String message) {
   2389         if (userId < 0) {
   2390             throw new IllegalArgumentException("Invalid userId " + userId);
   2391         }
   2392         if (checkShell) {
   2393             enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
   2394         }
   2395         if (userId == UserHandle.getUserId(callingUid)) return;
   2396         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
   2397             if (requireFullPermission) {
   2398                 mContext.enforceCallingOrSelfPermission(
   2399                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
   2400             } else {
   2401                 try {
   2402                     mContext.enforceCallingOrSelfPermission(
   2403                             android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
   2404                 } catch (SecurityException se) {
   2405                     mContext.enforceCallingOrSelfPermission(
   2406                             android.Manifest.permission.INTERACT_ACROSS_USERS, message);
   2407                 }
   2408             }
   2409         }
   2410     }
   2411 
   2412     void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
   2413         if (callingUid == Process.SHELL_UID) {
   2414             if (userHandle >= 0
   2415                     && sUserManager.hasUserRestriction(restriction, userHandle)) {
   2416                 throw new SecurityException("Shell does not have permission to access user "
   2417                         + userHandle);
   2418             } else if (userHandle < 0) {
   2419                 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
   2420                         + Debug.getCallers(3));
   2421             }
   2422         }
   2423     }
   2424 
   2425     private BasePermission findPermissionTreeLP(String permName) {
   2426         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
   2427             if (permName.startsWith(bp.name) &&
   2428                     permName.length() > bp.name.length() &&
   2429                     permName.charAt(bp.name.length()) == '.') {
   2430                 return bp;
   2431             }
   2432         }
   2433         return null;
   2434     }
   2435 
   2436     private BasePermission checkPermissionTreeLP(String permName) {
   2437         if (permName != null) {
   2438             BasePermission bp = findPermissionTreeLP(permName);
   2439             if (bp != null) {
   2440                 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
   2441                     return bp;
   2442                 }
   2443                 throw new SecurityException("Calling uid "
   2444                         + Binder.getCallingUid()
   2445                         + " is not allowed to add to permission tree "
   2446                         + bp.name + " owned by uid " + bp.uid);
   2447             }
   2448         }
   2449         throw new SecurityException("No permission tree found for " + permName);
   2450     }
   2451 
   2452     static boolean compareStrings(CharSequence s1, CharSequence s2) {
   2453         if (s1 == null) {
   2454             return s2 == null;
   2455         }
   2456         if (s2 == null) {
   2457             return false;
   2458         }
   2459         if (s1.getClass() != s2.getClass()) {
   2460             return false;
   2461         }
   2462         return s1.equals(s2);
   2463     }
   2464 
   2465     static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
   2466         if (pi1.icon != pi2.icon) return false;
   2467         if (pi1.logo != pi2.logo) return false;
   2468         if (pi1.protectionLevel != pi2.protectionLevel) return false;
   2469         if (!compareStrings(pi1.name, pi2.name)) return false;
   2470         if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
   2471         // We'll take care of setting this one.
   2472         if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
   2473         // These are not currently stored in settings.
   2474         //if (!compareStrings(pi1.group, pi2.group)) return false;
   2475         //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
   2476         //if (pi1.labelRes != pi2.labelRes) return false;
   2477         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
   2478         return true;
   2479     }
   2480 
   2481     int permissionInfoFootprint(PermissionInfo info) {
   2482         int size = info.name.length();
   2483         if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
   2484         if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
   2485         return size;
   2486     }
   2487 
   2488     int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
   2489         int size = 0;
   2490         for (BasePermission perm : mSettings.mPermissions.values()) {
   2491             if (perm.uid == tree.uid) {
   2492                 size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
   2493             }
   2494         }
   2495         return size;
   2496     }
   2497 
   2498     void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
   2499         // We calculate the max size of permissions defined by this uid and throw
   2500         // if that plus the size of 'info' would exceed our stated maximum.
   2501         if (tree.uid != Process.SYSTEM_UID) {
   2502             final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
   2503             if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
   2504                 throw new SecurityException("Permission tree size cap exceeded");
   2505             }
   2506         }
   2507     }
   2508 
   2509     boolean addPermissionLocked(PermissionInfo info, boolean async) {
   2510         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
   2511             throw new SecurityException("Label must be specified in permission");
   2512         }
   2513         BasePermission tree = checkPermissionTreeLP(info.name);
   2514         BasePermission bp = mSettings.mPermissions.get(info.name);
   2515         boolean added = bp == null;
   2516         boolean changed = true;
   2517         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
   2518         if (added) {
   2519             enforcePermissionCapLocked(info, tree);
   2520             bp = new BasePermission(info.name, tree.sourcePackage,
   2521                     BasePermission.TYPE_DYNAMIC);
   2522         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
   2523             throw new SecurityException(
   2524                     "Not allowed to modify non-dynamic permission "
   2525                     + info.name);
   2526         } else {
   2527             if (bp.protectionLevel == fixedLevel
   2528                     && bp.perm.owner.equals(tree.perm.owner)
   2529                     && bp.uid == tree.uid
   2530                     && comparePermissionInfos(bp.perm.info, info)) {
   2531                 changed = false;
   2532             }
   2533         }
   2534         bp.protectionLevel = fixedLevel;
   2535         info = new PermissionInfo(info);
   2536         info.protectionLevel = fixedLevel;
   2537         bp.perm = new PackageParser.Permission(tree.perm.owner, info);
   2538         bp.perm.info.packageName = tree.perm.info.packageName;
   2539         bp.uid = tree.uid;
   2540         if (added) {
   2541             mSettings.mPermissions.put(info.name, bp);
   2542         }
   2543         if (changed) {
   2544             if (!async) {
   2545                 mSettings.writeLPr();
   2546             } else {
   2547                 scheduleWriteSettingsLocked();
   2548             }
   2549         }
   2550         return added;
   2551     }
   2552 
   2553     @Override
   2554     public boolean addPermission(PermissionInfo info) {
   2555         synchronized (mPackages) {
   2556             return addPermissionLocked(info, false);
   2557         }
   2558     }
   2559 
   2560     @Override
   2561     public boolean addPermissionAsync(PermissionInfo info) {
   2562         synchronized (mPackages) {
   2563             return addPermissionLocked(info, true);
   2564         }
   2565     }
   2566 
   2567     @Override
   2568     public void removePermission(String name) {
   2569         synchronized (mPackages) {
   2570             checkPermissionTreeLP(name);
   2571             BasePermission bp = mSettings.mPermissions.get(name);
   2572             if (bp != null) {
   2573                 if (bp.type != BasePermission.TYPE_DYNAMIC) {
   2574                     throw new SecurityException(
   2575                             "Not allowed to modify non-dynamic permission "
   2576                             + name);
   2577                 }
   2578                 mSettings.mPermissions.remove(name);
   2579                 mSettings.writeLPr();
   2580             }
   2581         }
   2582     }
   2583 
   2584     private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) {
   2585         int index = pkg.requestedPermissions.indexOf(bp.name);
   2586         if (index == -1) {
   2587             throw new SecurityException("Package " + pkg.packageName
   2588                     + " has not requested permission " + bp.name);
   2589         }
   2590         boolean isNormal =
   2591                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
   2592                         == PermissionInfo.PROTECTION_NORMAL);
   2593         boolean isDangerous =
   2594                 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE)
   2595                         == PermissionInfo.PROTECTION_DANGEROUS);
   2596         boolean isDevelopment =
   2597                 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
   2598 
   2599         if (!isNormal && !isDangerous && !isDevelopment) {
   2600             throw new SecurityException("Permission " + bp.name
   2601                     + " is not a changeable permission type");
   2602         }
   2603 
   2604         if (isNormal || isDangerous) {
   2605             if (pkg.requestedPermissionsRequired.get(index)) {
   2606                 throw new SecurityException("Can't change " + bp.name
   2607                         + ". It is required by the application");
   2608             }
   2609         }
   2610     }
   2611 
   2612     @Override
   2613     public void grantPermission(String packageName, String permissionName) {
   2614         mContext.enforceCallingOrSelfPermission(
   2615                 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
   2616         synchronized (mPackages) {
   2617             final PackageParser.Package pkg = mPackages.get(packageName);
   2618             if (pkg == null) {
   2619                 throw new IllegalArgumentException("Unknown package: " + packageName);
   2620             }
   2621             final BasePermission bp = mSettings.mPermissions.get(permissionName);
   2622             if (bp == null) {
   2623                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
   2624             }
   2625 
   2626             checkGrantRevokePermissions(pkg, bp);
   2627 
   2628             final PackageSetting ps = (PackageSetting) pkg.mExtras;
   2629             if (ps == null) {
   2630                 return;
   2631             }
   2632             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
   2633             if (gp.grantedPermissions.add(permissionName)) {
   2634                 if (ps.haveGids) {
   2635                     gp.gids = appendInts(gp.gids, bp.gids);
   2636                 }
   2637                 mSettings.writeLPr();
   2638             }
   2639         }
   2640     }
   2641 
   2642     @Override
   2643     public void revokePermission(String packageName, String permissionName) {
   2644         int changedAppId = -1;
   2645 
   2646         synchronized (mPackages) {
   2647             final PackageParser.Package pkg = mPackages.get(packageName);
   2648             if (pkg == null) {
   2649                 throw new IllegalArgumentException("Unknown package: " + packageName);
   2650             }
   2651             if (pkg.applicationInfo.uid != Binder.getCallingUid()) {
   2652                 mContext.enforceCallingOrSelfPermission(
   2653                         android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
   2654             }
   2655             final BasePermission bp = mSettings.mPermissions.get(permissionName);
   2656             if (bp == null) {
   2657                 throw new IllegalArgumentException("Unknown permission: " + permissionName);
   2658             }
   2659 
   2660             checkGrantRevokePermissions(pkg, bp);
   2661 
   2662             final PackageSetting ps = (PackageSetting) pkg.mExtras;
   2663             if (ps == null) {
   2664                 return;
   2665             }
   2666             final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
   2667             if (gp.grantedPermissions.remove(permissionName)) {
   2668                 gp.grantedPermissions.remove(permissionName);
   2669                 if (ps.haveGids) {
   2670                     gp.gids = removeInts(gp.gids, bp.gids);
   2671                 }
   2672                 mSettings.writeLPr();
   2673                 changedAppId = ps.appId;
   2674             }
   2675         }
   2676 
   2677         if (changedAppId >= 0) {
   2678             // We changed the perm on someone, kill its processes.
   2679             IActivityManager am = ActivityManagerNative.getDefault();
   2680             if (am != null) {
   2681                 final int callingUserId = UserHandle.getCallingUserId();
   2682                 final long ident = Binder.clearCallingIdentity();
   2683                 try {
   2684                     //XXX we should only revoke for the calling user's app permissions,
   2685                     // but for now we impact all users.
   2686                     //am.killUid(UserHandle.getUid(callingUserId, changedAppId),
   2687                     //        "revoke " + permissionName);
   2688                     int[] users = sUserManager.getUserIds();
   2689                     for (int user : users) {
   2690                         am.killUid(UserHandle.getUid(user, changedAppId),
   2691                                 "revoke " + permissionName);
   2692                     }
   2693                 } catch (RemoteException e) {
   2694                 } finally {
   2695                     Binder.restoreCallingIdentity(ident);
   2696                 }
   2697             }
   2698         }
   2699     }
   2700 
   2701     @Override
   2702     public boolean isProtectedBroadcast(String actionName) {
   2703         synchronized (mPackages) {
   2704             return mProtectedBroadcasts.contains(actionName);
   2705         }
   2706     }
   2707 
   2708     @Override
   2709     public int checkSignatures(String pkg1, String pkg2) {
   2710         synchronized (mPackages) {
   2711             final PackageParser.Package p1 = mPackages.get(pkg1);
   2712             final PackageParser.Package p2 = mPackages.get(pkg2);
   2713             if (p1 == null || p1.mExtras == null
   2714                     || p2 == null || p2.mExtras == null) {
   2715                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2716             }
   2717             return compareSignatures(p1.mSignatures, p2.mSignatures);
   2718         }
   2719     }
   2720 
   2721     @Override
   2722     public int checkUidSignatures(int uid1, int uid2) {
   2723         // Map to base uids.
   2724         uid1 = UserHandle.getAppId(uid1);
   2725         uid2 = UserHandle.getAppId(uid2);
   2726         // reader
   2727         synchronized (mPackages) {
   2728             Signature[] s1;
   2729             Signature[] s2;
   2730             Object obj = mSettings.getUserIdLPr(uid1);
   2731             if (obj != null) {
   2732                 if (obj instanceof SharedUserSetting) {
   2733                     s1 = ((SharedUserSetting)obj).signatures.mSignatures;
   2734                 } else if (obj instanceof PackageSetting) {
   2735                     s1 = ((PackageSetting)obj).signatures.mSignatures;
   2736                 } else {
   2737                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2738                 }
   2739             } else {
   2740                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2741             }
   2742             obj = mSettings.getUserIdLPr(uid2);
   2743             if (obj != null) {
   2744                 if (obj instanceof SharedUserSetting) {
   2745                     s2 = ((SharedUserSetting)obj).signatures.mSignatures;
   2746                 } else if (obj instanceof PackageSetting) {
   2747                     s2 = ((PackageSetting)obj).signatures.mSignatures;
   2748                 } else {
   2749                     return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2750                 }
   2751             } else {
   2752                 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
   2753             }
   2754             return compareSignatures(s1, s2);
   2755         }
   2756     }
   2757 
   2758     /**
   2759      * Compares two sets of signatures. Returns:
   2760      * <br />
   2761      * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
   2762      * <br />
   2763      * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
   2764      * <br />
   2765      * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
   2766      * <br />
   2767      * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
   2768      * <br />
   2769      * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
   2770      */
   2771     static int compareSignatures(Signature[] s1, Signature[] s2) {
   2772         if (s1 == null) {
   2773             return s2 == null
   2774                     ? PackageManager.SIGNATURE_NEITHER_SIGNED
   2775                     : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
   2776         }
   2777 
   2778         if (s2 == null) {
   2779             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
   2780         }
   2781 
   2782         if (s1.length != s2.length) {
   2783             return PackageManager.SIGNATURE_NO_MATCH;
   2784         }
   2785 
   2786         // Since both signature sets are of size 1, we can compare without HashSets.
   2787         if (s1.length == 1) {
   2788             return s1[0].equals(s2[0]) ?
   2789                     PackageManager.SIGNATURE_MATCH :
   2790                     PackageManager.SIGNATURE_NO_MATCH;
   2791         }
   2792 
   2793         HashSet<Signature> set1 = new HashSet<Signature>();
   2794         for (Signature sig : s1) {
   2795             set1.add(sig);
   2796         }
   2797         HashSet<Signature> set2 = new HashSet<Signature>();
   2798         for (Signature sig : s2) {
   2799             set2.add(sig);
   2800         }
   2801         // Make sure s2 contains all signatures in s1.
   2802         if (set1.equals(set2)) {
   2803             return PackageManager.SIGNATURE_MATCH;
   2804         }
   2805         return PackageManager.SIGNATURE_NO_MATCH;
   2806     }
   2807 
   2808     /**
   2809      * If the database version for this type of package (internal storage or
   2810      * external storage) is less than the version where package signatures
   2811      * were updated, return true.
   2812      */
   2813     private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
   2814         return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan(
   2815                 DatabaseVersion.SIGNATURE_END_ENTITY))
   2816                 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan(
   2817                         DatabaseVersion.SIGNATURE_END_ENTITY));
   2818     }
   2819 
   2820     /**
   2821      * Used for backward compatibility to make sure any packages with
   2822      * certificate chains get upgraded to the new style. {@code existingSigs}
   2823      * will be in the old format (since they were stored on disk from before the
   2824      * system upgrade) and {@code scannedSigs} will be in the newer format.
   2825      */
   2826     private int compareSignaturesCompat(PackageSignatures existingSigs,
   2827             PackageParser.Package scannedPkg) {
   2828         if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
   2829             return PackageManager.SIGNATURE_NO_MATCH;
   2830         }
   2831 
   2832         HashSet<Signature> existingSet = new HashSet<Signature>();
   2833         for (Signature sig : existingSigs.mSignatures) {
   2834             existingSet.add(sig);
   2835         }
   2836         HashSet<Signature> scannedCompatSet = new HashSet<Signature>();
   2837         for (Signature sig : scannedPkg.mSignatures) {
   2838             try {
   2839                 Signature[] chainSignatures = sig.getChainSignatures();
   2840                 for (Signature chainSig : chainSignatures) {
   2841                     scannedCompatSet.add(chainSig);
   2842                 }
   2843             } catch (CertificateEncodingException e) {
   2844                 scannedCompatSet.add(sig);
   2845             }
   2846         }
   2847         /*
   2848          * Make sure the expanded scanned set contains all signatures in the
   2849          * existing one.
   2850          */
   2851         if (scannedCompatSet.equals(existingSet)) {
   2852             // Migrate the old signatures to the new scheme.
   2853             existingSigs.assignSignatures(scannedPkg.mSignatures);
   2854             // The new KeySets will be re-added later in the scanning process.
   2855             synchronized (mPackages) {
   2856                 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
   2857             }
   2858             return PackageManager.SIGNATURE_MATCH;
   2859         }
   2860         return PackageManager.SIGNATURE_NO_MATCH;
   2861     }
   2862 
   2863     private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
   2864         if (isExternal(scannedPkg)) {
   2865             return mSettings.isExternalDatabaseVersionOlderThan(
   2866                     DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
   2867         } else {
   2868             return mSettings.isInternalDatabaseVersionOlderThan(
   2869                     DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
   2870         }
   2871     }
   2872 
   2873     private int compareSignaturesRecover(PackageSignatures existingSigs,
   2874             PackageParser.Package scannedPkg) {
   2875         if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
   2876             return PackageManager.SIGNATURE_NO_MATCH;
   2877         }
   2878 
   2879         String msg = null;
   2880         try {
   2881             if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
   2882                 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
   2883                         + scannedPkg.packageName);
   2884                 return PackageManager.SIGNATURE_MATCH;
   2885             }
   2886         } catch (CertificateException e) {
   2887             msg = e.getMessage();
   2888         }
   2889 
   2890         logCriticalInfo(Log.INFO,
   2891                 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
   2892         return PackageManager.SIGNATURE_NO_MATCH;
   2893     }
   2894 
   2895     @Override
   2896     public String[] getPackagesForUid(int uid) {
   2897         uid = UserHandle.getAppId(uid);
   2898         // reader
   2899         synchronized (mPackages) {
   2900             Object obj = mSettings.getUserIdLPr(uid);
   2901             if (obj instanceof SharedUserSetting) {
   2902                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2903                 final int N = sus.packages.size();
   2904                 final String[] res = new String[N];
   2905                 final Iterator<PackageSetting> it = sus.packages.iterator();
   2906                 int i = 0;
   2907                 while (it.hasNext()) {
   2908                     res[i++] = it.next().name;
   2909                 }
   2910                 return res;
   2911             } else if (obj instanceof PackageSetting) {
   2912                 final PackageSetting ps = (PackageSetting) obj;
   2913                 return new String[] { ps.name };
   2914             }
   2915         }
   2916         return null;
   2917     }
   2918 
   2919     @Override
   2920     public String getNameForUid(int uid) {
   2921         // reader
   2922         synchronized (mPackages) {
   2923             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   2924             if (obj instanceof SharedUserSetting) {
   2925                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2926                 return sus.name + ":" + sus.userId;
   2927             } else if (obj instanceof PackageSetting) {
   2928                 final PackageSetting ps = (PackageSetting) obj;
   2929                 return ps.name;
   2930             }
   2931         }
   2932         return null;
   2933     }
   2934 
   2935     @Override
   2936     public int getUidForSharedUser(String sharedUserName) {
   2937         if(sharedUserName == null) {
   2938             return -1;
   2939         }
   2940         // reader
   2941         synchronized (mPackages) {
   2942             final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false);
   2943             if (suid == null) {
   2944                 return -1;
   2945             }
   2946             return suid.userId;
   2947         }
   2948     }
   2949 
   2950     @Override
   2951     public int getFlagsForUid(int uid) {
   2952         synchronized (mPackages) {
   2953             Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
   2954             if (obj instanceof SharedUserSetting) {
   2955                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2956                 return sus.pkgFlags;
   2957             } else if (obj instanceof PackageSetting) {
   2958                 final PackageSetting ps = (PackageSetting) obj;
   2959                 return ps.pkgFlags;
   2960             }
   2961         }
   2962         return 0;
   2963     }
   2964 
   2965     @Override
   2966     public boolean isUidPrivileged(int uid) {
   2967         uid = UserHandle.getAppId(uid);
   2968         // reader
   2969         synchronized (mPackages) {
   2970             Object obj = mSettings.getUserIdLPr(uid);
   2971             if (obj instanceof SharedUserSetting) {
   2972                 final SharedUserSetting sus = (SharedUserSetting) obj;
   2973                 final Iterator<PackageSetting> it = sus.packages.iterator();
   2974                 while (it.hasNext()) {
   2975                     if (it.next().isPrivileged()) {
   2976                         return true;
   2977                     }
   2978                 }
   2979             } else if (obj instanceof PackageSetting) {
   2980                 final PackageSetting ps = (PackageSetting) obj;
   2981                 return ps.isPrivileged();
   2982             }
   2983         }
   2984         return false;
   2985     }
   2986 
   2987     @Override
   2988     public String[] getAppOpPermissionPackages(String permissionName) {
   2989         synchronized (mPackages) {
   2990             ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
   2991             if (pkgs == null) {
   2992                 return null;
   2993             }
   2994             return pkgs.toArray(new String[pkgs.size()]);
   2995         }
   2996     }
   2997 
   2998     @Override
   2999     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
   3000             int flags, int userId) {
   3001         if (!sUserManager.exists(userId)) return null;
   3002         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
   3003         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
   3004         return chooseBestActivity(intent, resolvedType, flags, query, userId);
   3005     }
   3006 
   3007     @Override
   3008     public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
   3009             IntentFilter filter, int match, ComponentName activity) {
   3010         final int userId = UserHandle.getCallingUserId();
   3011         if (DEBUG_PREFERRED) {
   3012             Log.v(TAG, "setLastChosenActivity intent=" + intent
   3013                 + " resolvedType=" + resolvedType
   3014                 + " flags=" + flags
   3015                 + " filter=" + filter
   3016                 + " match=" + match
   3017                 + " activity=" + activity);
   3018             filter.dump(new PrintStreamPrinter(System.out), "    ");
   3019         }
   3020         intent.setComponent(null);
   3021         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
   3022         // Find any earlier preferred or last chosen entries and nuke them
   3023         findPreferredActivity(intent, resolvedType,
   3024                 flags, query, 0, false, true, false, userId);
   3025         // Add the new activity as the last chosen for this filter
   3026         addPreferredActivityInternal(filter, match, null, activity, false, userId,
   3027                 "Setting last chosen");
   3028     }
   3029 
   3030     @Override
   3031     public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
   3032         final int userId = UserHandle.getCallingUserId();
   3033         if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
   3034         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
   3035         return findPreferredActivity(intent, resolvedType, flags, query, 0,
   3036                 false, false, false, userId);
   3037     }
   3038 
   3039     private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
   3040             int flags, List<ResolveInfo> query, int userId) {
   3041         if (query != null) {
   3042             final int N = query.size();
   3043             if (N == 1) {
   3044                 return query.get(0);
   3045             } else if (N > 1) {
   3046                 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
   3047                 // If there is more than one activity with the same priority,
   3048                 // then let the user decide between them.
   3049                 ResolveInfo r0 = query.get(0);
   3050                 ResolveInfo r1 = query.get(1);
   3051                 if (DEBUG_INTENT_MATCHING || debug) {
   3052                     Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
   3053                             + r1.activityInfo.name + "=" + r1.priority);
   3054                 }
   3055                 // If the first activity has a higher priority, or a different
   3056                 // default, then it is always desireable to pick it.
   3057                 if (r0.priority != r1.priority
   3058                         || r0.preferredOrder != r1.preferredOrder
   3059                         || r0.isDefault != r1.isDefault) {
   3060                     return query.get(0);
   3061                 }
   3062                 // If we have saved a preference for a preferred activity for
   3063                 // this Intent, use that.
   3064                 ResolveInfo ri = findPreferredActivity(intent, resolvedType,
   3065                         flags, query, r0.priority, true, false, debug, userId);
   3066                 if (ri != null) {
   3067                     return ri;
   3068                 }
   3069                 if (userId != 0) {
   3070                     ri = new ResolveInfo(mResolveInfo);
   3071                     ri.activityInfo = new ActivityInfo(ri.activityInfo);
   3072                     ri.activityInfo.applicationInfo = new ApplicationInfo(
   3073                             ri.activityInfo.applicationInfo);
   3074                     ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
   3075                             UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
   3076                     return ri;
   3077                 }
   3078                 return mResolveInfo;
   3079             }
   3080         }
   3081         return null;
   3082     }
   3083 
   3084     private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
   3085             int flags, List<ResolveInfo> query, boolean debug, int userId) {
   3086         final int N = query.size();
   3087         PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
   3088                 .get(userId);
   3089         // Get the list of persistent preferred activities that handle the intent
   3090         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
   3091         List<PersistentPreferredActivity> pprefs = ppir != null
   3092                 ? ppir.queryIntent(intent, resolvedType,
   3093                         (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
   3094                 : null;
   3095         if (pprefs != null && pprefs.size() > 0) {
   3096             final int M = pprefs.size();
   3097             for (int i=0; i<M; i++) {
   3098                 final PersistentPreferredActivity ppa = pprefs.get(i);
   3099                 if (DEBUG_PREFERRED || debug) {
   3100                     Slog.v(TAG, "Checking PersistentPreferredActivity ds="
   3101                             + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
   3102                             + "\n  component=" + ppa.mComponent);
   3103                     ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   3104                 }
   3105                 final ActivityInfo ai = getActivityInfo(ppa.mComponent,
   3106                         flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
   3107                 if (DEBUG_PREFERRED || debug) {
   3108                     Slog.v(TAG, "Found persistent preferred activity:");
   3109                     if (ai != null) {
   3110                         ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   3111                     } else {
   3112                         Slog.v(TAG, "  null");
   3113                     }
   3114                 }
   3115                 if (ai == null) {
   3116                     // This previously registered persistent preferred activity
   3117                     // component is no longer known. Ignore it and do NOT remove it.
   3118                     continue;
   3119                 }
   3120                 for (int j=0; j<N; j++) {
   3121                     final ResolveInfo ri = query.get(j);
   3122                     if (!ri.activityInfo.applicationInfo.packageName
   3123                             .equals(ai.applicationInfo.packageName)) {
   3124                         continue;
   3125                     }
   3126                     if (!ri.activityInfo.name.equals(ai.name)) {
   3127                         continue;
   3128                     }
   3129                     //  Found a persistent preference that can handle the intent.
   3130                     if (DEBUG_PREFERRED || debug) {
   3131                         Slog.v(TAG, "Returning persistent preferred activity: " +
   3132                                 ri.activityInfo.packageName + "/" + ri.activityInfo.name);
   3133                     }
   3134                     return ri;
   3135                 }
   3136             }
   3137         }
   3138         return null;
   3139     }
   3140 
   3141     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
   3142             List<ResolveInfo> query, int priority, boolean always,
   3143             boolean removeMatches, boolean debug, int userId) {
   3144         if (!sUserManager.exists(userId)) return null;
   3145         // writer
   3146         synchronized (mPackages) {
   3147             if (intent.getSelector() != null) {
   3148                 intent = intent.getSelector();
   3149             }
   3150             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
   3151 
   3152             // Try to find a matching persistent preferred activity.
   3153             ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
   3154                     debug, userId);
   3155 
   3156             // If a persistent preferred activity matched, use it.
   3157             if (pri != null) {
   3158                 return pri;
   3159             }
   3160 
   3161             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   3162             // Get the list of preferred activities that handle the intent
   3163             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
   3164             List<PreferredActivity> prefs = pir != null
   3165                     ? pir.queryIntent(intent, resolvedType,
   3166                             (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
   3167                     : null;
   3168             if (prefs != null && prefs.size() > 0) {
   3169                 boolean changed = false;
   3170                 try {
   3171                     // First figure out how good the original match set is.
   3172                     // We will only allow preferred activities that came
   3173                     // from the same match quality.
   3174                     int match = 0;
   3175 
   3176                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
   3177 
   3178                     final int N = query.size();
   3179                     for (int j=0; j<N; j++) {
   3180                         final ResolveInfo ri = query.get(j);
   3181                         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
   3182                                 + ": 0x" + Integer.toHexString(match));
   3183                         if (ri.match > match) {
   3184                             match = ri.match;
   3185                         }
   3186                     }
   3187 
   3188                     if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
   3189                             + Integer.toHexString(match));
   3190 
   3191                     match &= IntentFilter.MATCH_CATEGORY_MASK;
   3192                     final int M = prefs.size();
   3193                     for (int i=0; i<M; i++) {
   3194                         final PreferredActivity pa = prefs.get(i);
   3195                         if (DEBUG_PREFERRED || debug) {
   3196                             Slog.v(TAG, "Checking PreferredActivity ds="
   3197                                     + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
   3198                                     + "\n  component=" + pa.mPref.mComponent);
   3199                             pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   3200                         }
   3201                         if (pa.mPref.mMatch != match) {
   3202                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
   3203                                     + Integer.toHexString(pa.mPref.mMatch));
   3204                             continue;
   3205                         }
   3206                         // If it's not an "always" type preferred activity and that's what we're
   3207                         // looking for, skip it.
   3208                         if (always && !pa.mPref.mAlways) {
   3209                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
   3210                             continue;
   3211                         }
   3212                         final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent,
   3213                                 flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
   3214                         if (DEBUG_PREFERRED || debug) {
   3215                             Slog.v(TAG, "Found preferred activity:");
   3216                             if (ai != null) {
   3217                                 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
   3218                             } else {
   3219                                 Slog.v(TAG, "  null");
   3220                             }
   3221                         }
   3222                         if (ai == null) {
   3223                             // This previously registered preferred activity
   3224                             // component is no longer known.  Most likely an update
   3225                             // to the app was installed and in the new version this
   3226                             // component no longer exists.  Clean it up by removing
   3227                             // it from the preferred activities list, and skip it.
   3228                             Slog.w(TAG, "Removing dangling preferred activity: "
   3229                                     + pa.mPref.mComponent);
   3230                             pir.removeFilter(pa);
   3231                             changed = true;
   3232                             continue;
   3233                         }
   3234                         for (int j=0; j<N; j++) {
   3235                             final ResolveInfo ri = query.get(j);
   3236                             if (!ri.activityInfo.applicationInfo.packageName
   3237                                     .equals(ai.applicationInfo.packageName)) {
   3238                                 continue;
   3239                             }
   3240                             if (!ri.activityInfo.name.equals(ai.name)) {
   3241                                 continue;
   3242                             }
   3243 
   3244                             if (removeMatches) {
   3245                                 pir.removeFilter(pa);
   3246                                 changed = true;
   3247                                 if (DEBUG_PREFERRED) {
   3248                                     Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
   3249                                 }
   3250                                 break;
   3251                             }
   3252 
   3253                             // Okay we found a previously set preferred or last chosen app.
   3254                             // If the result set is different from when this
   3255                             // was created, we need to clear it and re-ask the
   3256                             // user their preference, if we're looking for an "always" type entry.
   3257                             if (always && !pa.mPref.sameSet(query, priority)) {
   3258                                 Slog.i(TAG, "Result set changed, dropping preferred activity for "
   3259                                         + intent + " type " + resolvedType);
   3260                                 if (DEBUG_PREFERRED) {
   3261                                     Slog.v(TAG, "Removing preferred activity since set changed "
   3262                                             + pa.mPref.mComponent);
   3263                                 }
   3264                                 pir.removeFilter(pa);
   3265                                 // Re-add the filter as a "last chosen" entry (!always)
   3266                                 PreferredActivity lastChosen = new PreferredActivity(
   3267                                         pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
   3268                                 pir.addFilter(lastChosen);
   3269                                 changed = true;
   3270                                 return null;
   3271                             }
   3272 
   3273                             // Yay! Either the set matched or we're looking for the last chosen
   3274                             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
   3275                                     + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
   3276                             return ri;
   3277                         }
   3278                     }
   3279                 } finally {
   3280                     if (changed) {
   3281                         if (DEBUG_PREFERRED) {
   3282                             Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
   3283                         }
   3284                         mSettings.writePackageRestrictionsLPr(userId);
   3285                     }
   3286                 }
   3287             }
   3288         }
   3289         if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
   3290         return null;
   3291     }
   3292 
   3293     /*
   3294      * Returns if intent can be forwarded from the sourceUserId to the targetUserId
   3295      */
   3296     @Override
   3297     public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
   3298             int targetUserId) {
   3299         mContext.enforceCallingOrSelfPermission(
   3300                 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   3301         List<CrossProfileIntentFilter> matches =
   3302                 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
   3303         if (matches != null) {
   3304             int size = matches.size();
   3305             for (int i = 0; i < size; i++) {
   3306                 if (matches.get(i).getTargetUserId() == targetUserId) return true;
   3307             }
   3308         }
   3309         return false;
   3310     }
   3311 
   3312     private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
   3313             String resolvedType, int userId) {
   3314         CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
   3315         if (resolver != null) {
   3316             return resolver.queryIntent(intent, resolvedType, false, userId);
   3317         }
   3318         return null;
   3319     }
   3320 
   3321     @Override
   3322     public List<ResolveInfo> queryIntentActivities(Intent intent,
   3323             String resolvedType, int flags, int userId) {
   3324         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3325         enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
   3326         ComponentName comp = intent.getComponent();
   3327         if (comp == null) {
   3328             if (intent.getSelector() != null) {
   3329                 intent = intent.getSelector();
   3330                 comp = intent.getComponent();
   3331             }
   3332         }
   3333 
   3334         if (comp != null) {
   3335             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   3336             final ActivityInfo ai = getActivityInfo(comp, flags, userId);
   3337             if (ai != null) {
   3338                 final ResolveInfo ri = new ResolveInfo();
   3339                 ri.activityInfo = ai;
   3340                 list.add(ri);
   3341             }
   3342             return list;
   3343         }
   3344 
   3345         // reader
   3346         synchronized (mPackages) {
   3347             final String pkgName = intent.getPackage();
   3348             if (pkgName == null) {
   3349                 List<CrossProfileIntentFilter> matchingFilters =
   3350                         getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
   3351                 // Check for results that need to skip the current profile.
   3352                 ResolveInfo resolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
   3353                         resolvedType, flags, userId);
   3354                 if (resolveInfo != null) {
   3355                     List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
   3356                     result.add(resolveInfo);
   3357                     return result;
   3358                 }
   3359                 // Check for cross profile results.
   3360                 resolveInfo = queryCrossProfileIntents(
   3361                         matchingFilters, intent, resolvedType, flags, userId);
   3362 
   3363                 // Check for results in the current profile.
   3364                 List<ResolveInfo> result = mActivities.queryIntent(
   3365                         intent, resolvedType, flags, userId);
   3366                 if (resolveInfo != null) {
   3367                     result.add(resolveInfo);
   3368                     Collections.sort(result, mResolvePrioritySorter);
   3369                 }
   3370                 return result;
   3371             }
   3372             final PackageParser.Package pkg = mPackages.get(pkgName);
   3373             if (pkg != null) {
   3374                 return mActivities.queryIntentForPackage(intent, resolvedType, flags,
   3375                         pkg.activities, userId);
   3376             }
   3377             return new ArrayList<ResolveInfo>();
   3378         }
   3379     }
   3380 
   3381     private ResolveInfo querySkipCurrentProfileIntents(
   3382             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
   3383             int flags, int sourceUserId) {
   3384         if (matchingFilters != null) {
   3385             int size = matchingFilters.size();
   3386             for (int i = 0; i < size; i ++) {
   3387                 CrossProfileIntentFilter filter = matchingFilters.get(i);
   3388                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
   3389                     // Checking if there are activities in the target user that can handle the
   3390                     // intent.
   3391                     ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType,
   3392                             flags, sourceUserId);
   3393                     if (resolveInfo != null) {
   3394                         return resolveInfo;
   3395                     }
   3396                 }
   3397             }
   3398         }
   3399         return null;
   3400     }
   3401 
   3402     // Return matching ResolveInfo if any for skip current profile intent filters.
   3403     private ResolveInfo queryCrossProfileIntents(
   3404             List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
   3405             int flags, int sourceUserId) {
   3406         if (matchingFilters != null) {
   3407             // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
   3408             // match the same intent. For performance reasons, it is better not to
   3409             // run queryIntent twice for the same userId
   3410             SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
   3411             int size = matchingFilters.size();
   3412             for (int i = 0; i < size; i++) {
   3413                 CrossProfileIntentFilter filter = matchingFilters.get(i);
   3414                 int targetUserId = filter.getTargetUserId();
   3415                 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
   3416                         && !alreadyTriedUserIds.get(targetUserId)) {
   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) return resolveInfo;
   3422                     alreadyTriedUserIds.put(targetUserId, true);
   3423                 }
   3424             }
   3425         }
   3426         return null;
   3427     }
   3428 
   3429     private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent,
   3430             String resolvedType, int flags, int sourceUserId) {
   3431         List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
   3432                 resolvedType, flags, filter.getTargetUserId());
   3433         if (resultTargetUser != null && !resultTargetUser.isEmpty()) {
   3434             return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId());
   3435         }
   3436         return null;
   3437     }
   3438 
   3439     private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
   3440             int sourceUserId, int targetUserId) {
   3441         ResolveInfo forwardingResolveInfo = new ResolveInfo();
   3442         String className;
   3443         if (targetUserId == UserHandle.USER_OWNER) {
   3444             className = FORWARD_INTENT_TO_USER_OWNER;
   3445         } else {
   3446             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
   3447         }
   3448         ComponentName forwardingActivityComponentName = new ComponentName(
   3449                 mAndroidApplication.packageName, className);
   3450         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
   3451                 sourceUserId);
   3452         if (targetUserId == UserHandle.USER_OWNER) {
   3453             forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
   3454             forwardingResolveInfo.noResourceId = true;
   3455         }
   3456         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
   3457         forwardingResolveInfo.priority = 0;
   3458         forwardingResolveInfo.preferredOrder = 0;
   3459         forwardingResolveInfo.match = 0;
   3460         forwardingResolveInfo.isDefault = true;
   3461         forwardingResolveInfo.filter = filter;
   3462         forwardingResolveInfo.targetUserId = targetUserId;
   3463         return forwardingResolveInfo;
   3464     }
   3465 
   3466     @Override
   3467     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
   3468             Intent[] specifics, String[] specificTypes, Intent intent,
   3469             String resolvedType, int flags, int userId) {
   3470         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3471         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
   3472                 false, "query intent activity options");
   3473         final String resultsAction = intent.getAction();
   3474 
   3475         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
   3476                 | PackageManager.GET_RESOLVED_FILTER, userId);
   3477 
   3478         if (DEBUG_INTENT_MATCHING) {
   3479             Log.v(TAG, "Query " + intent + ": " + results);
   3480         }
   3481 
   3482         int specificsPos = 0;
   3483         int N;
   3484 
   3485         // todo: note that the algorithm used here is O(N^2).  This
   3486         // isn't a problem in our current environment, but if we start running
   3487         // into situations where we have more than 5 or 10 matches then this
   3488         // should probably be changed to something smarter...
   3489 
   3490         // First we go through and resolve each of the specific items
   3491         // that were supplied, taking care of removing any corresponding
   3492         // duplicate items in the generic resolve list.
   3493         if (specifics != null) {
   3494             for (int i=0; i<specifics.length; i++) {
   3495                 final Intent sintent = specifics[i];
   3496                 if (sintent == null) {
   3497                     continue;
   3498                 }
   3499 
   3500                 if (DEBUG_INTENT_MATCHING) {
   3501                     Log.v(TAG, "Specific #" + i + ": " + sintent);
   3502                 }
   3503 
   3504                 String action = sintent.getAction();
   3505                 if (resultsAction != null && resultsAction.equals(action)) {
   3506                     // If this action was explicitly requested, then don't
   3507                     // remove things that have it.
   3508                     action = null;
   3509                 }
   3510 
   3511                 ResolveInfo ri = null;
   3512                 ActivityInfo ai = null;
   3513 
   3514                 ComponentName comp = sintent.getComponent();
   3515                 if (comp == null) {
   3516                     ri = resolveIntent(
   3517                         sintent,
   3518                         specificTypes != null ? specificTypes[i] : null,
   3519                             flags, userId);
   3520                     if (ri == null) {
   3521                         continue;
   3522                     }
   3523                     if (ri == mResolveInfo) {
   3524                         // ACK!  Must do something better with this.
   3525                     }
   3526                     ai = ri.activityInfo;
   3527                     comp = new ComponentName(ai.applicationInfo.packageName,
   3528                             ai.name);
   3529                 } else {
   3530                     ai = getActivityInfo(comp, flags, userId);
   3531                     if (ai == null) {
   3532                         continue;
   3533                     }
   3534                 }
   3535 
   3536                 // Look for any generic query activities that are duplicates
   3537                 // of this specific one, and remove them from the results.
   3538                 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
   3539                 N = results.size();
   3540                 int j;
   3541                 for (j=specificsPos; j<N; j++) {
   3542                     ResolveInfo sri = results.get(j);
   3543                     if ((sri.activityInfo.name.equals(comp.getClassName())
   3544                             && sri.activityInfo.applicationInfo.packageName.equals(
   3545                                     comp.getPackageName()))
   3546                         || (action != null && sri.filter.matchAction(action))) {
   3547                         results.remove(j);
   3548                         if (DEBUG_INTENT_MATCHING) Log.v(
   3549                             TAG, "Removing duplicate item from " + j
   3550                             + " due to specific " + specificsPos);
   3551                         if (ri == null) {
   3552                             ri = sri;
   3553                         }
   3554                         j--;
   3555                         N--;
   3556                     }
   3557                 }
   3558 
   3559                 // Add this specific item to its proper place.
   3560                 if (ri == null) {
   3561                     ri = new ResolveInfo();
   3562                     ri.activityInfo = ai;
   3563                 }
   3564                 results.add(specificsPos, ri);
   3565                 ri.specificIndex = i;
   3566                 specificsPos++;
   3567             }
   3568         }
   3569 
   3570         // Now we go through the remaining generic results and remove any
   3571         // duplicate actions that are found here.
   3572         N = results.size();
   3573         for (int i=specificsPos; i<N-1; i++) {
   3574             final ResolveInfo rii = results.get(i);
   3575             if (rii.filter == null) {
   3576                 continue;
   3577             }
   3578 
   3579             // Iterate over all of the actions of this result's intent
   3580             // filter...  typically this should be just one.
   3581             final Iterator<String> it = rii.filter.actionsIterator();
   3582             if (it == null) {
   3583                 continue;
   3584             }
   3585             while (it.hasNext()) {
   3586                 final String action = it.next();
   3587                 if (resultsAction != null && resultsAction.equals(action)) {
   3588                     // If this action was explicitly requested, then don't
   3589                     // remove things that have it.
   3590                     continue;
   3591                 }
   3592                 for (int j=i+1; j<N; j++) {
   3593                     final ResolveInfo rij = results.get(j);
   3594                     if (rij.filter != null && rij.filter.hasAction(action)) {
   3595                         results.remove(j);
   3596                         if (DEBUG_INTENT_MATCHING) Log.v(
   3597                             TAG, "Removing duplicate item from " + j
   3598                             + " due to action " + action + " at " + i);
   3599                         j--;
   3600                         N--;
   3601                     }
   3602                 }
   3603             }
   3604 
   3605             // If the caller didn't request filter information, drop it now
   3606             // so we don't have to marshall/unmarshall it.
   3607             if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   3608                 rii.filter = null;
   3609             }
   3610         }
   3611 
   3612         // Filter out the caller activity if so requested.
   3613         if (caller != null) {
   3614             N = results.size();
   3615             for (int i=0; i<N; i++) {
   3616                 ActivityInfo ainfo = results.get(i).activityInfo;
   3617                 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
   3618                         && caller.getClassName().equals(ainfo.name)) {
   3619                     results.remove(i);
   3620                     break;
   3621                 }
   3622             }
   3623         }
   3624 
   3625         // If the caller didn't request filter information,
   3626         // drop them now so we don't have to
   3627         // marshall/unmarshall it.
   3628         if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
   3629             N = results.size();
   3630             for (int i=0; i<N; i++) {
   3631                 results.get(i).filter = null;
   3632             }
   3633         }
   3634 
   3635         if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
   3636         return results;
   3637     }
   3638 
   3639     @Override
   3640     public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags,
   3641             int userId) {
   3642         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3643         ComponentName comp = intent.getComponent();
   3644         if (comp == null) {
   3645             if (intent.getSelector() != null) {
   3646                 intent = intent.getSelector();
   3647                 comp = intent.getComponent();
   3648             }
   3649         }
   3650         if (comp != null) {
   3651             List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   3652             ActivityInfo ai = getReceiverInfo(comp, flags, userId);
   3653             if (ai != null) {
   3654                 ResolveInfo ri = new ResolveInfo();
   3655                 ri.activityInfo = ai;
   3656                 list.add(ri);
   3657             }
   3658             return list;
   3659         }
   3660 
   3661         // reader
   3662         synchronized (mPackages) {
   3663             String pkgName = intent.getPackage();
   3664             if (pkgName == null) {
   3665                 return mReceivers.queryIntent(intent, resolvedType, flags, userId);
   3666             }
   3667             final PackageParser.Package pkg = mPackages.get(pkgName);
   3668             if (pkg != null) {
   3669                 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers,
   3670                         userId);
   3671             }
   3672             return null;
   3673         }
   3674     }
   3675 
   3676     @Override
   3677     public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
   3678         List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId);
   3679         if (!sUserManager.exists(userId)) return null;
   3680         if (query != null) {
   3681             if (query.size() >= 1) {
   3682                 // If there is more than one service with the same priority,
   3683                 // just arbitrarily pick the first one.
   3684                 return query.get(0);
   3685             }
   3686         }
   3687         return null;
   3688     }
   3689 
   3690     @Override
   3691     public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags,
   3692             int userId) {
   3693         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3694         ComponentName comp = intent.getComponent();
   3695         if (comp == null) {
   3696             if (intent.getSelector() != null) {
   3697                 intent = intent.getSelector();
   3698                 comp = intent.getComponent();
   3699             }
   3700         }
   3701         if (comp != null) {
   3702             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   3703             final ServiceInfo si = getServiceInfo(comp, flags, userId);
   3704             if (si != null) {
   3705                 final ResolveInfo ri = new ResolveInfo();
   3706                 ri.serviceInfo = si;
   3707                 list.add(ri);
   3708             }
   3709             return list;
   3710         }
   3711 
   3712         // reader
   3713         synchronized (mPackages) {
   3714             String pkgName = intent.getPackage();
   3715             if (pkgName == null) {
   3716                 return mServices.queryIntent(intent, resolvedType, flags, userId);
   3717             }
   3718             final PackageParser.Package pkg = mPackages.get(pkgName);
   3719             if (pkg != null) {
   3720                 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
   3721                         userId);
   3722             }
   3723             return null;
   3724         }
   3725     }
   3726 
   3727     @Override
   3728     public List<ResolveInfo> queryIntentContentProviders(
   3729             Intent intent, String resolvedType, int flags, int userId) {
   3730         if (!sUserManager.exists(userId)) return Collections.emptyList();
   3731         ComponentName comp = intent.getComponent();
   3732         if (comp == null) {
   3733             if (intent.getSelector() != null) {
   3734                 intent = intent.getSelector();
   3735                 comp = intent.getComponent();
   3736             }
   3737         }
   3738         if (comp != null) {
   3739             final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
   3740             final ProviderInfo pi = getProviderInfo(comp, flags, userId);
   3741             if (pi != null) {
   3742                 final ResolveInfo ri = new ResolveInfo();
   3743                 ri.providerInfo = pi;
   3744                 list.add(ri);
   3745             }
   3746             return list;
   3747         }
   3748 
   3749         // reader
   3750         synchronized (mPackages) {
   3751             String pkgName = intent.getPackage();
   3752             if (pkgName == null) {
   3753                 return mProviders.queryIntent(intent, resolvedType, flags, userId);
   3754             }
   3755             final PackageParser.Package pkg = mPackages.get(pkgName);
   3756             if (pkg != null) {
   3757                 return mProviders.queryIntentForPackage(
   3758                         intent, resolvedType, flags, pkg.providers, userId);
   3759             }
   3760             return null;
   3761         }
   3762     }
   3763 
   3764     @Override
   3765     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
   3766         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   3767 
   3768         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
   3769 
   3770         // writer
   3771         synchronized (mPackages) {
   3772             ArrayList<PackageInfo> list;
   3773             if (listUninstalled) {
   3774                 list = new ArrayList<PackageInfo>(mSettings.mPackages.size());
   3775                 for (PackageSetting ps : mSettings.mPackages.values()) {
   3776                     PackageInfo pi;
   3777                     if (ps.pkg != null) {
   3778                         pi = generatePackageInfo(ps.pkg, flags, userId);
   3779                     } else {
   3780                         pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
   3781                     }
   3782                     if (pi != null) {
   3783                         list.add(pi);
   3784                     }
   3785                 }
   3786             } else {
   3787                 list = new ArrayList<PackageInfo>(mPackages.size());
   3788                 for (PackageParser.Package p : mPackages.values()) {
   3789                     PackageInfo pi = generatePackageInfo(p, flags, userId);
   3790                     if (pi != null) {
   3791                         list.add(pi);
   3792                     }
   3793                 }
   3794             }
   3795 
   3796             return new ParceledListSlice<PackageInfo>(list);
   3797         }
   3798     }
   3799 
   3800     private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
   3801             String[] permissions, boolean[] tmp, int flags, int userId) {
   3802         int numMatch = 0;
   3803         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   3804         for (int i=0; i<permissions.length; i++) {
   3805             if (gp.grantedPermissions.contains(permissions[i])) {
   3806                 tmp[i] = true;
   3807                 numMatch++;
   3808             } else {
   3809                 tmp[i] = false;
   3810             }
   3811         }
   3812         if (numMatch == 0) {
   3813             return;
   3814         }
   3815         PackageInfo pi;
   3816         if (ps.pkg != null) {
   3817             pi = generatePackageInfo(ps.pkg, flags, userId);
   3818         } else {
   3819             pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId);
   3820         }
   3821         // The above might return null in cases of uninstalled apps or install-state
   3822         // skew across users/profiles.
   3823         if (pi != null) {
   3824             if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
   3825                 if (numMatch == permissions.length) {
   3826                     pi.requestedPermissions = permissions;
   3827                 } else {
   3828                     pi.requestedPermissions = new String[numMatch];
   3829                     numMatch = 0;
   3830                     for (int i=0; i<permissions.length; i++) {
   3831                         if (tmp[i]) {
   3832                             pi.requestedPermissions[numMatch] = permissions[i];
   3833                             numMatch++;
   3834                         }
   3835                     }
   3836                 }
   3837             }
   3838             list.add(pi);
   3839         }
   3840     }
   3841 
   3842     @Override
   3843     public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
   3844             String[] permissions, int flags, int userId) {
   3845         if (!sUserManager.exists(userId)) return null;
   3846         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   3847 
   3848         // writer
   3849         synchronized (mPackages) {
   3850             ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
   3851             boolean[] tmpBools = new boolean[permissions.length];
   3852             if (listUninstalled) {
   3853                 for (PackageSetting ps : mSettings.mPackages.values()) {
   3854                     addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
   3855                 }
   3856             } else {
   3857                 for (PackageParser.Package pkg : mPackages.values()) {
   3858                     PackageSetting ps = (PackageSetting)pkg.mExtras;
   3859                     if (ps != null) {
   3860                         addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
   3861                                 userId);
   3862                     }
   3863                 }
   3864             }
   3865 
   3866             return new ParceledListSlice<PackageInfo>(list);
   3867         }
   3868     }
   3869 
   3870     @Override
   3871     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
   3872         if (!sUserManager.exists(userId)) return null;
   3873         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
   3874 
   3875         // writer
   3876         synchronized (mPackages) {
   3877             ArrayList<ApplicationInfo> list;
   3878             if (listUninstalled) {
   3879                 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
   3880                 for (PackageSetting ps : mSettings.mPackages.values()) {
   3881                     ApplicationInfo ai;
   3882                     if (ps.pkg != null) {
   3883                         ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
   3884                                 ps.readUserState(userId), userId);
   3885                     } else {
   3886                         ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
   3887                     }
   3888                     if (ai != null) {
   3889                         list.add(ai);
   3890                     }
   3891                 }
   3892             } else {
   3893                 list = new ArrayList<ApplicationInfo>(mPackages.size());
   3894                 for (PackageParser.Package p : mPackages.values()) {
   3895                     if (p.mExtras != null) {
   3896                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
   3897                                 ((PackageSetting)p.mExtras).readUserState(userId), userId);
   3898                         if (ai != null) {
   3899                             list.add(ai);
   3900                         }
   3901                     }
   3902                 }
   3903             }
   3904 
   3905             return new ParceledListSlice<ApplicationInfo>(list);
   3906         }
   3907     }
   3908 
   3909     public List<ApplicationInfo> getPersistentApplications(int flags) {
   3910         final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
   3911 
   3912         // reader
   3913         synchronized (mPackages) {
   3914             final Iterator<PackageParser.Package> i = mPackages.values().iterator();
   3915             final int userId = UserHandle.getCallingUserId();
   3916             while (i.hasNext()) {
   3917                 final PackageParser.Package p = i.next();
   3918                 if (p.applicationInfo != null
   3919                         && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0
   3920                         && (!mSafeMode || isSystemApp(p))) {
   3921                     PackageSetting ps = mSettings.mPackages.get(p.packageName);
   3922                     if (ps != null) {
   3923                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
   3924                                 ps.readUserState(userId), userId);
   3925                         if (ai != null) {
   3926                             finalList.add(ai);
   3927                         }
   3928                     }
   3929                 }
   3930             }
   3931         }
   3932 
   3933         return finalList;
   3934     }
   3935 
   3936     @Override
   3937     public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
   3938         if (!sUserManager.exists(userId)) return null;
   3939         // reader
   3940         synchronized (mPackages) {
   3941             final PackageParser.Provider provider = mProvidersByAuthority.get(name);
   3942             PackageSetting ps = provider != null
   3943                     ? mSettings.mPackages.get(provider.owner.packageName)
   3944                     : null;
   3945             return ps != null
   3946                     && mSettings.isEnabledLPr(provider.info, flags, userId)
   3947                     && (!mSafeMode || (provider.info.applicationInfo.flags
   3948                             &ApplicationInfo.FLAG_SYSTEM) != 0)
   3949                     ? PackageParser.generateProviderInfo(provider, flags,
   3950                             ps.readUserState(userId), userId)
   3951                     : null;
   3952         }
   3953     }
   3954 
   3955     /**
   3956      * @deprecated
   3957      */
   3958     @Deprecated
   3959     public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
   3960         // reader
   3961         synchronized (mPackages) {
   3962             final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
   3963                     .entrySet().iterator();
   3964             final int userId = UserHandle.getCallingUserId();
   3965             while (i.hasNext()) {
   3966                 Map.Entry<String, PackageParser.Provider> entry = i.next();
   3967                 PackageParser.Provider p = entry.getValue();
   3968                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
   3969 
   3970                 if (ps != null && p.syncable
   3971                         && (!mSafeMode || (p.info.applicationInfo.flags
   3972                                 &ApplicationInfo.FLAG_SYSTEM) != 0)) {
   3973                     ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
   3974                             ps.readUserState(userId), userId);
   3975                     if (info != null) {
   3976                         outNames.add(entry.getKey());
   3977                         outInfo.add(info);
   3978                     }
   3979                 }
   3980             }
   3981         }
   3982     }
   3983 
   3984     @Override
   3985     public List<ProviderInfo> queryContentProviders(String processName,
   3986             int uid, int flags) {
   3987         ArrayList<ProviderInfo> finalList = null;
   3988         // reader
   3989         synchronized (mPackages) {
   3990             final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
   3991             final int userId = processName != null ?
   3992                     UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
   3993             while (i.hasNext()) {
   3994                 final PackageParser.Provider p = i.next();
   3995                 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
   3996                 if (ps != null && p.info.authority != null
   3997                         && (processName == null
   3998                                 || (p.info.processName.equals(processName)
   3999                                         && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
   4000                         && mSettings.isEnabledLPr(p.info, flags, userId)
   4001                         && (!mSafeMode
   4002                                 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
   4003                     if (finalList == null) {
   4004                         finalList = new ArrayList<ProviderInfo>(3);
   4005                     }
   4006                     ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
   4007                             ps.readUserState(userId), userId);
   4008                     if (info != null) {
   4009                         finalList.add(info);
   4010                     }
   4011                 }
   4012             }
   4013         }
   4014 
   4015         if (finalList != null) {
   4016             Collections.sort(finalList, mProviderInitOrderSorter);
   4017         }
   4018 
   4019         return finalList;
   4020     }
   4021 
   4022     @Override
   4023     public InstrumentationInfo getInstrumentationInfo(ComponentName name,
   4024             int flags) {
   4025         // reader
   4026         synchronized (mPackages) {
   4027             final PackageParser.Instrumentation i = mInstrumentation.get(name);
   4028             return PackageParser.generateInstrumentationInfo(i, flags);
   4029         }
   4030     }
   4031 
   4032     @Override
   4033     public List<InstrumentationInfo> queryInstrumentation(String targetPackage,
   4034             int flags) {
   4035         ArrayList<InstrumentationInfo> finalList =
   4036             new ArrayList<InstrumentationInfo>();
   4037 
   4038         // reader
   4039         synchronized (mPackages) {
   4040             final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
   4041             while (i.hasNext()) {
   4042                 final PackageParser.Instrumentation p = i.next();
   4043                 if (targetPackage == null
   4044                         || targetPackage.equals(p.info.targetPackage)) {
   4045                     InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
   4046                             flags);
   4047                     if (ii != null) {
   4048                         finalList.add(ii);
   4049                     }
   4050                 }
   4051             }
   4052         }
   4053 
   4054         return finalList;
   4055     }
   4056 
   4057     private void createIdmapsForPackageLI(PackageParser.Package pkg) {
   4058         HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
   4059         if (overlays == null) {
   4060             Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
   4061             return;
   4062         }
   4063         for (PackageParser.Package opkg : overlays.values()) {
   4064             // Not much to do if idmap fails: we already logged the error
   4065             // and we certainly don't want to abort installation of pkg simply
   4066             // because an overlay didn't fit properly. For these reasons,
   4067             // ignore the return value of createIdmapForPackagePairLI.
   4068             createIdmapForPackagePairLI(pkg, opkg);
   4069         }
   4070     }
   4071 
   4072     private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
   4073             PackageParser.Package opkg) {
   4074         if (!opkg.mTrustedOverlay) {
   4075             Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " +
   4076                     opkg.baseCodePath + ": overlay not trusted");
   4077             return false;
   4078         }
   4079         HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
   4080         if (overlaySet == null) {
   4081             Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " +
   4082                     opkg.baseCodePath + " but target package has no known overlays");
   4083             return false;
   4084         }
   4085         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   4086         // TODO: generate idmap for split APKs
   4087         if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) {
   4088             Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and "
   4089                     + opkg.baseCodePath);
   4090             return false;
   4091         }
   4092         PackageParser.Package[] overlayArray =
   4093             overlaySet.values().toArray(new PackageParser.Package[0]);
   4094         Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
   4095             public int compare(PackageParser.Package p1, PackageParser.Package p2) {
   4096                 return p1.mOverlayPriority - p2.mOverlayPriority;
   4097             }
   4098         };
   4099         Arrays.sort(overlayArray, cmp);
   4100 
   4101         pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
   4102         int i = 0;
   4103         for (PackageParser.Package p : overlayArray) {
   4104             pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath;
   4105         }
   4106         return true;
   4107     }
   4108 
   4109     private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
   4110         final File[] files = dir.listFiles();
   4111         if (ArrayUtils.isEmpty(files)) {
   4112             Log.d(TAG, "No files in app dir " + dir);
   4113             return;
   4114         }
   4115 
   4116         if (DEBUG_PACKAGE_SCANNING) {
   4117             Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
   4118                     + " flags=0x" + Integer.toHexString(parseFlags));
   4119         }
   4120 
   4121         for (File file : files) {
   4122             final boolean isPackage = (isApkFile(file) || file.isDirectory())
   4123                     && !PackageInstallerService.isStageName(file.getName());
   4124             if (!isPackage) {
   4125                 // Ignore entries which are not packages
   4126                 continue;
   4127             }
   4128             try {
   4129                 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
   4130                         scanFlags, currentTime, null);
   4131             } catch (PackageManagerException e) {
   4132                 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
   4133 
   4134                 // Delete invalid userdata apps
   4135                 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
   4136                         e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
   4137                     logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
   4138                     if (file.isDirectory()) {
   4139                         FileUtils.deleteContents(file);
   4140                     }
   4141                     file.delete();
   4142                 }
   4143             }
   4144         }
   4145     }
   4146 
   4147     private static File getSettingsProblemFile() {
   4148         File dataDir = Environment.getDataDirectory();
   4149         File systemDir = new File(dataDir, "system");
   4150         File fname = new File(systemDir, "uiderrors.txt");
   4151         return fname;
   4152     }
   4153 
   4154     static void reportSettingsProblem(int priority, String msg) {
   4155         logCriticalInfo(priority, msg);
   4156     }
   4157 
   4158     static void logCriticalInfo(int priority, String msg) {
   4159         Slog.println(priority, TAG, msg);
   4160         EventLogTags.writePmCriticalInfo(msg);
   4161         try {
   4162             File fname = getSettingsProblemFile();
   4163             FileOutputStream out = new FileOutputStream(fname, true);
   4164             PrintWriter pw = new FastPrintWriter(out);
   4165             SimpleDateFormat formatter = new SimpleDateFormat();
   4166             String dateString = formatter.format(new Date(System.currentTimeMillis()));
   4167             pw.println(dateString + ": " + msg);
   4168             pw.close();
   4169             FileUtils.setPermissions(
   4170                     fname.toString(),
   4171                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
   4172                     -1, -1);
   4173         } catch (java.io.IOException e) {
   4174         }
   4175     }
   4176 
   4177     private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
   4178             PackageParser.Package pkg, File srcFile, int parseFlags)
   4179             throws PackageManagerException {
   4180         if (ps != null
   4181                 && ps.codePath.equals(srcFile)
   4182                 && ps.timeStamp == srcFile.lastModified()
   4183                 && !isCompatSignatureUpdateNeeded(pkg)
   4184                 && !isRecoverSignatureUpdateNeeded(pkg)) {
   4185             long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
   4186             if (ps.signatures.mSignatures != null
   4187                     && ps.signatures.mSignatures.length != 0
   4188                     && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
   4189                 // Optimization: reuse the existing cached certificates
   4190                 // if the package appears to be unchanged.
   4191                 pkg.mSignatures = ps.signatures.mSignatures;
   4192                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
   4193                 synchronized (mPackages) {
   4194                     pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
   4195                 }
   4196                 return;
   4197             }
   4198 
   4199             Slog.w(TAG, "PackageSetting for " + ps.name
   4200                     + " is missing signatures.  Collecting certs again to recover them.");
   4201         } else {
   4202             Log.i(TAG, srcFile.toString() + " changed; collecting certs");
   4203         }
   4204 
   4205         try {
   4206             pp.collectCertificates(pkg, parseFlags);
   4207             pp.collectManifestDigest(pkg);
   4208         } catch (PackageParserException e) {
   4209             throw PackageManagerException.from(e);
   4210         }
   4211     }
   4212 
   4213     /*
   4214      *  Scan a package and return the newly parsed package.
   4215      *  Returns null in case of errors and the error code is stored in mLastScanError
   4216      */
   4217     private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
   4218             long currentTime, UserHandle user) throws PackageManagerException {
   4219         if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
   4220         parseFlags |= mDefParseFlags;
   4221         PackageParser pp = new PackageParser();
   4222         pp.setSeparateProcesses(mSeparateProcesses);
   4223         pp.setOnlyCoreApps(mOnlyCore);
   4224         pp.setDisplayMetrics(mMetrics);
   4225 
   4226         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
   4227             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
   4228         }
   4229 
   4230         final PackageParser.Package pkg;
   4231         try {
   4232             pkg = pp.parsePackage(scanFile, parseFlags);
   4233         } catch (PackageParserException e) {
   4234             throw PackageManagerException.from(e);
   4235         }
   4236 
   4237         PackageSetting ps = null;
   4238         PackageSetting updatedPkg;
   4239         // reader
   4240         synchronized (mPackages) {
   4241             // Look to see if we already know about this package.
   4242             String oldName = mSettings.mRenamedPackages.get(pkg.packageName);
   4243             if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
   4244                 // This package has been renamed to its original name.  Let's
   4245                 // use that.
   4246                 ps = mSettings.peekPackageLPr(oldName);
   4247             }
   4248             // If there was no original package, see one for the real package name.
   4249             if (ps == null) {
   4250                 ps = mSettings.peekPackageLPr(pkg.packageName);
   4251             }
   4252             // Check to see if this package could be hiding/updating a system
   4253             // package.  Must look for it either under the original or real
   4254             // package name depending on our state.
   4255             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
   4256             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
   4257         }
   4258         boolean updatedPkgBetter = false;
   4259         // First check if this is a system package that may involve an update
   4260         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   4261             if (ps != null && !ps.codePath.equals(scanFile)) {
   4262                 // The path has changed from what was last scanned...  check the
   4263                 // version of the new path against what we have stored to determine
   4264                 // what to do.
   4265                 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
   4266                 if (pkg.mVersionCode < ps.versionCode) {
   4267                     // The system package has been updated and the code path does not match
   4268                     // Ignore entry. Skip it.
   4269                     logCriticalInfo(Log.INFO, "Package " + ps.name + " at " + scanFile
   4270                             + " ignored: updated version " + ps.versionCode
   4271                             + " better than this " + pkg.mVersionCode);
   4272                     if (!updatedPkg.codePath.equals(scanFile)) {
   4273                         Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
   4274                                 + ps.name + " changing from " + updatedPkg.codePathString
   4275                                 + " to " + scanFile);
   4276                         updatedPkg.codePath = scanFile;
   4277                         updatedPkg.codePathString = scanFile.toString();
   4278                         // This is the point at which we know that the system-disk APK
   4279                         // for this package has moved during a reboot (e.g. due to an OTA),
   4280                         // so we need to reevaluate it for privilege policy.
   4281                         if (locationIsPrivileged(scanFile)) {
   4282                             updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
   4283                         }
   4284                     }
   4285                     updatedPkg.pkg = pkg;
   4286                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null);
   4287                 } else {
   4288                     // The current app on the system partition is better than
   4289                     // what we have updated to on the data partition; switch
   4290                     // back to the system partition version.
   4291                     // At this point, its safely assumed that package installation for
   4292                     // apps in system partition will go through. If not there won't be a working
   4293                     // version of the app
   4294                     // writer
   4295                     synchronized (mPackages) {
   4296                         // Just remove the loaded entries from package lists.
   4297                         mPackages.remove(ps.name);
   4298                     }
   4299 
   4300                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
   4301                             + " reverting from " + ps.codePathString
   4302                             + ": new version " + pkg.mVersionCode
   4303                             + " better than installed " + ps.versionCode);
   4304 
   4305                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   4306                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
   4307                             getAppDexInstructionSets(ps));
   4308                     synchronized (mInstallLock) {
   4309                         args.cleanUpResourcesLI();
   4310                     }
   4311                     synchronized (mPackages) {
   4312                         mSettings.enableSystemPackageLPw(ps.name);
   4313                     }
   4314                     updatedPkgBetter = true;
   4315                 }
   4316             }
   4317         }
   4318 
   4319         if (updatedPkg != null) {
   4320             // An updated system app will not have the PARSE_IS_SYSTEM flag set
   4321             // initially
   4322             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
   4323 
   4324             // An updated privileged app will not have the PARSE_IS_PRIVILEGED
   4325             // flag set initially
   4326             if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
   4327                 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   4328             }
   4329         }
   4330 
   4331         // Verify certificates against what was last scanned
   4332         collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
   4333 
   4334         /*
   4335          * A new system app appeared, but we already had a non-system one of the
   4336          * same name installed earlier.
   4337          */
   4338         boolean shouldHideSystemApp = false;
   4339         if (updatedPkg == null && ps != null
   4340                 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
   4341             /*
   4342              * Check to make sure the signatures match first. If they don't,
   4343              * wipe the installed application and its data.
   4344              */
   4345             if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
   4346                     != PackageManager.SIGNATURE_MATCH) {
   4347                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
   4348                         + " signatures don't match existing userdata copy; removing");
   4349                 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
   4350                 ps = null;
   4351             } else {
   4352                 /*
   4353                  * If the newly-added system app is an older version than the
   4354                  * already installed version, hide it. It will be scanned later
   4355                  * and re-added like an update.
   4356                  */
   4357                 if (pkg.mVersionCode < ps.versionCode) {
   4358                     shouldHideSystemApp = true;
   4359                     logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
   4360                             + " but new version " + pkg.mVersionCode + " better than installed "
   4361                             + ps.versionCode + "; hiding system");
   4362                 } else {
   4363                     /*
   4364                      * The newly found system app is a newer version that the
   4365                      * one previously installed. Simply remove the
   4366                      * already-installed application and replace it with our own
   4367                      * while keeping the application data.
   4368                      */
   4369                     logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
   4370                             + " reverting from " + ps.codePathString + ": new version "
   4371                             + pkg.mVersionCode + " better than installed " + ps.versionCode);
   4372                     InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   4373                             ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
   4374                             getAppDexInstructionSets(ps));
   4375                     synchronized (mInstallLock) {
   4376                         args.cleanUpResourcesLI();
   4377                     }
   4378                 }
   4379             }
   4380         }
   4381 
   4382         // The apk is forward locked (not public) if its code and resources
   4383         // are kept in different files. (except for app in either system or
   4384         // vendor path).
   4385         // TODO grab this value from PackageSettings
   4386         if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   4387             if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
   4388                 parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   4389             }
   4390         }
   4391 
   4392         // TODO: extend to support forward-locked splits
   4393         String resourcePath = null;
   4394         String baseResourcePath = null;
   4395         if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
   4396             if (ps != null && ps.resourcePathString != null) {
   4397                 resourcePath = ps.resourcePathString;
   4398                 baseResourcePath = ps.resourcePathString;
   4399             } else {
   4400                 // Should not happen at all. Just log an error.
   4401                 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName);
   4402             }
   4403         } else {
   4404             resourcePath = pkg.codePath;
   4405             baseResourcePath = pkg.baseCodePath;
   4406         }
   4407 
   4408         // Set application objects path explicitly.
   4409         pkg.applicationInfo.setCodePath(pkg.codePath);
   4410         pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
   4411         pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
   4412         pkg.applicationInfo.setResourcePath(resourcePath);
   4413         pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
   4414         pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
   4415 
   4416         // Note that we invoke the following method only if we are about to unpack an application
   4417         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
   4418                 | SCAN_UPDATE_SIGNATURE, currentTime, user);
   4419 
   4420         /*
   4421          * If the system app should be overridden by a previously installed
   4422          * data, hide the system app now and let the /data/app scan pick it up
   4423          * again.
   4424          */
   4425         if (shouldHideSystemApp) {
   4426             synchronized (mPackages) {
   4427                 /*
   4428                  * We have to grant systems permissions before we hide, because
   4429                  * grantPermissions will assume the package update is trying to
   4430                  * expand its permissions.
   4431                  */
   4432                 grantPermissionsLPw(pkg, true, pkg.packageName);
   4433                 mSettings.disableSystemPackageLPw(pkg.packageName);
   4434             }
   4435         }
   4436 
   4437         return scannedPkg;
   4438     }
   4439 
   4440     private static String fixProcessName(String defProcessName,
   4441             String processName, int uid) {
   4442         if (processName == null) {
   4443             return defProcessName;
   4444         }
   4445         return processName;
   4446     }
   4447 
   4448     private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
   4449             throws PackageManagerException {
   4450         if (pkgSetting.signatures.mSignatures != null) {
   4451             // Already existing package. Make sure signatures match
   4452             boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
   4453                     == PackageManager.SIGNATURE_MATCH;
   4454             if (!match) {
   4455                 match = compareSignaturesCompat(pkgSetting.signatures, pkg)
   4456                         == PackageManager.SIGNATURE_MATCH;
   4457             }
   4458             if (!match) {
   4459                 match = compareSignaturesRecover(pkgSetting.signatures, pkg)
   4460                         == PackageManager.SIGNATURE_MATCH;
   4461             }
   4462             if (!match) {
   4463                 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
   4464                         + pkg.packageName + " signatures do not match the "
   4465                         + "previously installed version; ignoring!");
   4466             }
   4467         }
   4468 
   4469         // Check for shared user signatures
   4470         if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
   4471             // Already existing package. Make sure signatures match
   4472             boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   4473                     pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
   4474             if (!match) {
   4475                 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
   4476                         == PackageManager.SIGNATURE_MATCH;
   4477             }
   4478             if (!match) {
   4479                 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
   4480                         == PackageManager.SIGNATURE_MATCH;
   4481             }
   4482             if (!match) {
   4483                 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
   4484                         "Package " + pkg.packageName
   4485                         + " has no signatures that match those in shared user "
   4486                         + pkgSetting.sharedUser.name + "; ignoring!");
   4487             }
   4488         }
   4489     }
   4490 
   4491     /**
   4492      * Enforces that only the system UID or root's UID can call a method exposed
   4493      * via Binder.
   4494      *
   4495      * @param message used as message if SecurityException is thrown
   4496      * @throws SecurityException if the caller is not system or root
   4497      */
   4498     private static final void enforceSystemOrRoot(String message) {
   4499         final int uid = Binder.getCallingUid();
   4500         if (uid != Process.SYSTEM_UID && uid != 0) {
   4501             throw new SecurityException(message);
   4502         }
   4503     }
   4504 
   4505     @Override
   4506     public void performBootDexOpt() {
   4507         enforceSystemOrRoot("Only the system can request dexopt be performed");
   4508 
   4509         final HashSet<PackageParser.Package> pkgs;
   4510         synchronized (mPackages) {
   4511             pkgs = mDeferredDexOpt;
   4512             mDeferredDexOpt = null;
   4513         }
   4514 
   4515         if (pkgs != null) {
   4516             // Sort apps by importance for dexopt ordering. Important apps are given more priority
   4517             // in case the device runs out of space.
   4518             ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>();
   4519             // Give priority to core apps.
   4520             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4521                 PackageParser.Package pkg = it.next();
   4522                 if (pkg.coreApp) {
   4523                     if (DEBUG_DEXOPT) {
   4524                         Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName);
   4525                     }
   4526                     sortedPkgs.add(pkg);
   4527                     it.remove();
   4528                 }
   4529             }
   4530             // Give priority to system apps that listen for pre boot complete.
   4531             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
   4532             HashSet<String> pkgNames = getPackageNamesForIntent(intent);
   4533             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4534                 PackageParser.Package pkg = it.next();
   4535                 if (pkgNames.contains(pkg.packageName)) {
   4536                     if (DEBUG_DEXOPT) {
   4537                         Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName);
   4538                     }
   4539                     sortedPkgs.add(pkg);
   4540                     it.remove();
   4541                 }
   4542             }
   4543             // Give priority to system apps.
   4544             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4545                 PackageParser.Package pkg = it.next();
   4546                 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
   4547                     if (DEBUG_DEXOPT) {
   4548                         Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName);
   4549                     }
   4550                     sortedPkgs.add(pkg);
   4551                     it.remove();
   4552                 }
   4553             }
   4554             // Give priority to updated system apps.
   4555             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4556                 PackageParser.Package pkg = it.next();
   4557                 if (isUpdatedSystemApp(pkg)) {
   4558                     if (DEBUG_DEXOPT) {
   4559                         Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName);
   4560                     }
   4561                     sortedPkgs.add(pkg);
   4562                     it.remove();
   4563                 }
   4564             }
   4565             // Give priority to apps that listen for boot complete.
   4566             intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
   4567             pkgNames = getPackageNamesForIntent(intent);
   4568             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
   4569                 PackageParser.Package pkg = it.next();
   4570                 if (pkgNames.contains(pkg.packageName)) {
   4571                     if (DEBUG_DEXOPT) {
   4572                         Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName);
   4573                     }
   4574                     sortedPkgs.add(pkg);
   4575                     it.remove();
   4576                 }
   4577             }
   4578             // Filter out packages that aren't recently used.
   4579             filterRecentlyUsedApps(pkgs);
   4580             // Add all remaining apps.
   4581             for (PackageParser.Package pkg : pkgs) {
   4582                 if (DEBUG_DEXOPT) {
   4583                     Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName);
   4584                 }
   4585                 sortedPkgs.add(pkg);
   4586             }
   4587 
   4588             int i = 0;
   4589             int total = sortedPkgs.size();
   4590             File dataDir = Environment.getDataDirectory();
   4591             long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir);
   4592             if (lowThreshold == 0) {
   4593                 throw new IllegalStateException("Invalid low memory threshold");
   4594             }
   4595             for (PackageParser.Package pkg : sortedPkgs) {
   4596                 long usableSpace = dataDir.getUsableSpace();
   4597                 if (usableSpace < lowThreshold) {
   4598                     Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace);
   4599                     break;
   4600                 }
   4601                 performBootDexOpt(pkg, ++i, total);
   4602             }
   4603         }
   4604     }
   4605 
   4606     private void filterRecentlyUsedApps(HashSet<PackageParser.Package> pkgs) {
   4607         // Filter out packages that aren't recently used.
   4608         //
   4609         // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which
   4610         // should do a full dexopt.
   4611         if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) {
   4612             // TODO: add a property to control this?
   4613             long dexOptLRUThresholdInMinutes;
   4614             if (mLazyDexOpt) {
   4615                 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds.
   4616             } else {
   4617                 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users.
   4618             }
   4619             long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000;
   4620 
   4621             int total = pkgs.size();
   4622             int skipped = 0;
   4623             long now = System.currentTimeMillis();
   4624             for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) {
   4625                 PackageParser.Package pkg = i.next();
   4626                 long then = pkg.mLastPackageUsageTimeInMills;
   4627                 if (then + dexOptLRUThresholdInMills < now) {
   4628                     if (DEBUG_DEXOPT) {
   4629                         Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " +
   4630                               ((then == 0) ? "never" : new Date(then)));
   4631                     }
   4632                     i.remove();
   4633                     skipped++;
   4634                 }
   4635             }
   4636             if (DEBUG_DEXOPT) {
   4637                 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total);
   4638             }
   4639         }
   4640     }
   4641 
   4642     private HashSet<String> getPackageNamesForIntent(Intent intent) {
   4643         List<ResolveInfo> ris = null;
   4644         try {
   4645             ris = AppGlobals.getPackageManager().queryIntentReceivers(
   4646                     intent, null, 0, UserHandle.USER_OWNER);
   4647         } catch (RemoteException e) {
   4648         }
   4649         HashSet<String> pkgNames = new HashSet<String>();
   4650         if (ris != null) {
   4651             for (ResolveInfo ri : ris) {
   4652                 pkgNames.add(ri.activityInfo.packageName);
   4653             }
   4654         }
   4655         return pkgNames;
   4656     }
   4657 
   4658     private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) {
   4659         if (DEBUG_DEXOPT) {
   4660             Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName);
   4661         }
   4662         if (!isFirstBoot()) {
   4663             try {
   4664                 ActivityManagerNative.getDefault().showBootMessage(
   4665                         mContext.getResources().getString(R.string.android_upgrading_apk,
   4666                                 curr, total), true);
   4667             } catch (RemoteException e) {
   4668             }
   4669         }
   4670         PackageParser.Package p = pkg;
   4671         synchronized (mInstallLock) {
   4672             performDexOptLI(p, null /* instruction sets */, false /* force dex */,
   4673                             false /* defer */, true /* include dependencies */);
   4674         }
   4675     }
   4676 
   4677     @Override
   4678     public boolean performDexOptIfNeeded(String packageName, String instructionSet) {
   4679         return performDexOpt(packageName, instructionSet, false);
   4680     }
   4681 
   4682     private static String getPrimaryInstructionSet(ApplicationInfo info) {
   4683         if (info.primaryCpuAbi == null) {
   4684             return getPreferredInstructionSet();
   4685         }
   4686 
   4687         return VMRuntime.getInstructionSet(info.primaryCpuAbi);
   4688     }
   4689 
   4690     public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) {
   4691         boolean dexopt = mLazyDexOpt || backgroundDexopt;
   4692         boolean updateUsage = !backgroundDexopt;  // Don't update usage if this is just a backgroundDexopt
   4693         if (!dexopt && !updateUsage) {
   4694             // We aren't going to dexopt or update usage, so bail early.
   4695             return false;
   4696         }
   4697         PackageParser.Package p;
   4698         final String targetInstructionSet;
   4699         synchronized (mPackages) {
   4700             p = mPackages.get(packageName);
   4701             if (p == null) {
   4702                 return false;
   4703             }
   4704             if (updateUsage) {
   4705                 p.mLastPackageUsageTimeInMills = System.currentTimeMillis();
   4706             }
   4707             mPackageUsage.write(false);
   4708             if (!dexopt) {
   4709                 // We aren't going to dexopt, so bail early.
   4710                 return false;
   4711             }
   4712 
   4713             targetInstructionSet = instructionSet != null ? instructionSet :
   4714                     getPrimaryInstructionSet(p.applicationInfo);
   4715             if (p.mDexOptPerformed.contains(targetInstructionSet)) {
   4716                 return false;
   4717             }
   4718         }
   4719 
   4720         synchronized (mInstallLock) {
   4721             final String[] instructionSets = new String[] { targetInstructionSet };
   4722             return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */,
   4723                     true /* include dependencies */) == DEX_OPT_PERFORMED;
   4724         }
   4725     }
   4726 
   4727     public HashSet<String> getPackagesThatNeedDexOpt() {
   4728         HashSet<String> pkgs = null;
   4729         synchronized (mPackages) {
   4730             for (PackageParser.Package p : mPackages.values()) {
   4731                 if (DEBUG_DEXOPT) {
   4732                     Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray());
   4733                 }
   4734                 if (!p.mDexOptPerformed.isEmpty()) {
   4735                     continue;
   4736                 }
   4737                 if (pkgs == null) {
   4738                     pkgs = new HashSet<String>();
   4739                 }
   4740                 pkgs.add(p.packageName);
   4741             }
   4742         }
   4743         return pkgs;
   4744     }
   4745 
   4746     public void shutdown() {
   4747         mPackageUsage.write(true);
   4748     }
   4749 
   4750     private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
   4751              boolean forceDex, boolean defer, HashSet<String> done) {
   4752         for (int i=0; i<libs.size(); i++) {
   4753             PackageParser.Package libPkg;
   4754             String libName;
   4755             synchronized (mPackages) {
   4756                 libName = libs.get(i);
   4757                 SharedLibraryEntry lib = mSharedLibraries.get(libName);
   4758                 if (lib != null && lib.apk != null) {
   4759                     libPkg = mPackages.get(lib.apk);
   4760                 } else {
   4761                     libPkg = null;
   4762                 }
   4763             }
   4764             if (libPkg != null && !done.contains(libName)) {
   4765                 performDexOptLI(libPkg, instructionSets, forceDex, defer, done);
   4766             }
   4767         }
   4768     }
   4769 
   4770     static final int DEX_OPT_SKIPPED = 0;
   4771     static final int DEX_OPT_PERFORMED = 1;
   4772     static final int DEX_OPT_DEFERRED = 2;
   4773     static final int DEX_OPT_FAILED = -1;
   4774 
   4775     private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
   4776             boolean forceDex, boolean defer, HashSet<String> done) {
   4777         final String[] instructionSets = targetInstructionSets != null ?
   4778                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
   4779 
   4780         if (done != null) {
   4781             done.add(pkg.packageName);
   4782             if (pkg.usesLibraries != null) {
   4783                 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done);
   4784             }
   4785             if (pkg.usesOptionalLibraries != null) {
   4786                 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done);
   4787             }
   4788         }
   4789 
   4790         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
   4791             return DEX_OPT_SKIPPED;
   4792         }
   4793 
   4794         final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
   4795 
   4796         final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
   4797         boolean performedDexOpt = false;
   4798         // There are three basic cases here:
   4799         // 1.) we need to dexopt, either because we are forced or it is needed
   4800         // 2.) we are defering a needed dexopt
   4801         // 3.) we are skipping an unneeded dexopt
   4802         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
   4803         for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   4804             if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) {
   4805                 continue;
   4806             }
   4807 
   4808             for (String path : paths) {
   4809                 try {
   4810                     // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
   4811                     // patckage or the one we find does not match the image checksum (i.e. it was
   4812                     // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
   4813                     // odex file and it matches the checksum of the image but not its base address,
   4814                     // meaning we need to move it.
   4815                     final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path,
   4816                             pkg.packageName, dexCodeInstructionSet, defer);
   4817                     if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) {
   4818                         Log.i(TAG, "Running dexopt on: " + path + " pkg="
   4819                                 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
   4820                                 + " vmSafeMode=" + vmSafeMode);
   4821                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   4822                         final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
   4823                                 pkg.packageName, dexCodeInstructionSet, vmSafeMode);
   4824 
   4825                         if (ret < 0) {
   4826                             // Don't bother running dexopt again if we failed, it will probably
   4827                             // just result in an error again. Also, don't bother dexopting for other
   4828                             // paths & ISAs.
   4829                             return DEX_OPT_FAILED;
   4830                         }
   4831 
   4832                         performedDexOpt = true;
   4833                     } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
   4834                         Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
   4835                         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
   4836                         final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
   4837                                 pkg.packageName, dexCodeInstructionSet);
   4838 
   4839                         if (ret < 0) {
   4840                             // Don't bother running patchoat again if we failed, it will probably
   4841                             // just result in an error again. Also, don't bother dexopting for other
   4842                             // paths & ISAs.
   4843                             return DEX_OPT_FAILED;
   4844                         }
   4845 
   4846                         performedDexOpt = true;
   4847                     }
   4848 
   4849                     // We're deciding to defer a needed dexopt. Don't bother dexopting for other
   4850                     // paths and instruction sets. We'll deal with them all together when we process
   4851                     // our list of deferred dexopts.
   4852                     if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) {
   4853                         if (mDeferredDexOpt == null) {
   4854                             mDeferredDexOpt = new HashSet<PackageParser.Package>();
   4855                         }
   4856                         mDeferredDexOpt.add(pkg);
   4857                         return DEX_OPT_DEFERRED;
   4858                     }
   4859                 } catch (FileNotFoundException e) {
   4860                     Slog.w(TAG, "Apk not found for dexopt: " + path);
   4861                     return DEX_OPT_FAILED;
   4862                 } catch (IOException e) {
   4863                     Slog.w(TAG, "IOException reading apk: " + path, e);
   4864                     return DEX_OPT_FAILED;
   4865                 } catch (StaleDexCacheError e) {
   4866                     Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e);
   4867                     return DEX_OPT_FAILED;
   4868                 } catch (Exception e) {
   4869                     Slog.w(TAG, "Exception when doing dexopt : ", e);
   4870                     return DEX_OPT_FAILED;
   4871                 }
   4872             }
   4873 
   4874             // At this point we haven't failed dexopt and we haven't deferred dexopt. We must
   4875             // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us
   4876             // it isn't required. We therefore mark that this package doesn't need dexopt unless
   4877             // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped
   4878             // it.
   4879             pkg.mDexOptPerformed.add(dexCodeInstructionSet);
   4880         }
   4881 
   4882         // If we've gotten here, we're sure that no error occurred and that we haven't
   4883         // deferred dex-opt. We've either dex-opted one more paths or instruction sets or
   4884         // we've skipped all of them because they are up to date. In both cases this
   4885         // package doesn't need dexopt any longer.
   4886         return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
   4887     }
   4888 
   4889     private static String[] getAppDexInstructionSets(ApplicationInfo info) {
   4890         if (info.primaryCpuAbi != null) {
   4891             if (info.secondaryCpuAbi != null) {
   4892                 return new String[] {
   4893                         VMRuntime.getInstructionSet(info.primaryCpuAbi),
   4894                         VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
   4895             } else {
   4896                 return new String[] {
   4897                         VMRuntime.getInstructionSet(info.primaryCpuAbi) };
   4898             }
   4899         }
   4900 
   4901         return new String[] { getPreferredInstructionSet() };
   4902     }
   4903 
   4904     private static String[] getAppDexInstructionSets(PackageSetting ps) {
   4905         if (ps.primaryCpuAbiString != null) {
   4906             if (ps.secondaryCpuAbiString != null) {
   4907                 return new String[] {
   4908                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
   4909                         VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
   4910             } else {
   4911                 return new String[] {
   4912                         VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
   4913             }
   4914         }
   4915 
   4916         return new String[] { getPreferredInstructionSet() };
   4917     }
   4918 
   4919     private static String getPreferredInstructionSet() {
   4920         if (sPreferredInstructionSet == null) {
   4921             sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
   4922         }
   4923 
   4924         return sPreferredInstructionSet;
   4925     }
   4926 
   4927     private static List<String> getAllInstructionSets() {
   4928         final String[] allAbis = Build.SUPPORTED_ABIS;
   4929         final List<String> allInstructionSets = new ArrayList<String>(allAbis.length);
   4930 
   4931         for (String abi : allAbis) {
   4932             final String instructionSet = VMRuntime.getInstructionSet(abi);
   4933             if (!allInstructionSets.contains(instructionSet)) {
   4934                 allInstructionSets.add(instructionSet);
   4935             }
   4936         }
   4937 
   4938         return allInstructionSets;
   4939     }
   4940 
   4941     /**
   4942      * Returns the instruction set that should be used to compile dex code. In the presence of
   4943      * a native bridge this might be different than the one shared libraries use.
   4944      */
   4945     private static String getDexCodeInstructionSet(String sharedLibraryIsa) {
   4946         String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa);
   4947         return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa);
   4948     }
   4949 
   4950     private static String[] getDexCodeInstructionSets(String[] instructionSets) {
   4951         HashSet<String> dexCodeInstructionSets = new HashSet<String>(instructionSets.length);
   4952         for (String instructionSet : instructionSets) {
   4953             dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet));
   4954         }
   4955         return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]);
   4956     }
   4957 
   4958     /**
   4959      * Returns deduplicated list of supported instructions for dex code.
   4960      */
   4961     public static String[] getAllDexCodeInstructionSets() {
   4962         String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length];
   4963         for (int i = 0; i < supportedInstructionSets.length; i++) {
   4964             String abi = Build.SUPPORTED_ABIS[i];
   4965             supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi);
   4966         }
   4967         return getDexCodeInstructionSets(supportedInstructionSets);
   4968     }
   4969 
   4970     @Override
   4971     public void forceDexOpt(String packageName) {
   4972         enforceSystemOrRoot("forceDexOpt");
   4973 
   4974         PackageParser.Package pkg;
   4975         synchronized (mPackages) {
   4976             pkg = mPackages.get(packageName);
   4977             if (pkg == null) {
   4978                 throw new IllegalArgumentException("Missing package: " + packageName);
   4979             }
   4980         }
   4981 
   4982         synchronized (mInstallLock) {
   4983             final String[] instructionSets = new String[] {
   4984                     getPrimaryInstructionSet(pkg.applicationInfo) };
   4985             final int res = performDexOptLI(pkg, instructionSets, true, false, true);
   4986             if (res != DEX_OPT_PERFORMED) {
   4987                 throw new IllegalStateException("Failed to dexopt: " + res);
   4988             }
   4989         }
   4990     }
   4991 
   4992     private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets,
   4993                                 boolean forceDex, boolean defer, boolean inclDependencies) {
   4994         HashSet<String> done;
   4995         if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
   4996             done = new HashSet<String>();
   4997             done.add(pkg.packageName);
   4998         } else {
   4999             done = null;
   5000         }
   5001         return performDexOptLI(pkg, instructionSets,  forceDex, defer, done);
   5002     }
   5003 
   5004     private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
   5005         if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
   5006             Slog.w(TAG, "Unable to update from " + oldPkg.name
   5007                     + " to " + newPkg.packageName
   5008                     + ": old package not in system partition");
   5009             return false;
   5010         } else if (mPackages.get(oldPkg.name) != null) {
   5011             Slog.w(TAG, "Unable to update from " + oldPkg.name
   5012                     + " to " + newPkg.packageName
   5013                     + ": old package still exists");
   5014             return false;
   5015         }
   5016         return true;
   5017     }
   5018 
   5019     File getDataPathForUser(int userId) {
   5020         return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId);
   5021     }
   5022 
   5023     private File getDataPathForPackage(String packageName, int userId) {
   5024         /*
   5025          * Until we fully support multiple users, return the directory we
   5026          * previously would have. The PackageManagerTests will need to be
   5027          * revised when this is changed back..
   5028          */
   5029         if (userId == 0) {
   5030             return new File(mAppDataDir, packageName);
   5031         } else {
   5032             return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
   5033                 + File.separator + packageName);
   5034         }
   5035     }
   5036 
   5037     private int createDataDirsLI(String packageName, int uid, String seinfo) {
   5038         int[] users = sUserManager.getUserIds();
   5039         int res = mInstaller.install(packageName, uid, uid, seinfo);
   5040         if (res < 0) {
   5041             return res;
   5042         }
   5043         for (int user : users) {
   5044             if (user != 0) {
   5045                 res = mInstaller.createUserData(packageName,
   5046                         UserHandle.getUid(user, uid), user, seinfo);
   5047                 if (res < 0) {
   5048                     return res;
   5049                 }
   5050             }
   5051         }
   5052         return res;
   5053     }
   5054 
   5055     private int removeDataDirsLI(String packageName) {
   5056         int[] users = sUserManager.getUserIds();
   5057         int res = 0;
   5058         for (int user : users) {
   5059             int resInner = mInstaller.remove(packageName, user);
   5060             if (resInner < 0) {
   5061                 res = resInner;
   5062             }
   5063         }
   5064 
   5065         return res;
   5066     }
   5067 
   5068     private int deleteCodeCacheDirsLI(String packageName) {
   5069         int[] users = sUserManager.getUserIds();
   5070         int res = 0;
   5071         for (int user : users) {
   5072             int resInner = mInstaller.deleteCodeCacheFiles(packageName, user);
   5073             if (resInner < 0) {
   5074                 res = resInner;
   5075             }
   5076         }
   5077         return res;
   5078     }
   5079 
   5080     private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
   5081             PackageParser.Package changingLib) {
   5082         if (file.path != null) {
   5083             usesLibraryFiles.add(file.path);
   5084             return;
   5085         }
   5086         PackageParser.Package p = mPackages.get(file.apk);
   5087         if (changingLib != null && changingLib.packageName.equals(file.apk)) {
   5088             // If we are doing this while in the middle of updating a library apk,
   5089             // then we need to make sure to use that new apk for determining the
   5090             // dependencies here.  (We haven't yet finished committing the new apk
   5091             // to the package manager state.)
   5092             if (p == null || p.packageName.equals(changingLib.packageName)) {
   5093                 p = changingLib;
   5094             }
   5095         }
   5096         if (p != null) {
   5097             usesLibraryFiles.addAll(p.getAllCodePaths());
   5098         }
   5099     }
   5100 
   5101     private void updateSharedLibrariesLPw(PackageParser.Package pkg,
   5102             PackageParser.Package changingLib) throws PackageManagerException {
   5103         if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) {
   5104             final ArraySet<String> usesLibraryFiles = new ArraySet<>();
   5105             int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0;
   5106             for (int i=0; i<N; i++) {
   5107                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i));
   5108                 if (file == null) {
   5109                     throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
   5110                             "Package " + pkg.packageName + " requires unavailable shared library "
   5111                             + pkg.usesLibraries.get(i) + "; failing!");
   5112                 }
   5113                 addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
   5114             }
   5115             N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0;
   5116             for (int i=0; i<N; i++) {
   5117                 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i));
   5118                 if (file == null) {
   5119                     Slog.w(TAG, "Package " + pkg.packageName
   5120                             + " desires unavailable shared library "
   5121                             + pkg.usesOptionalLibraries.get(i) + "; ignoring!");
   5122                 } else {
   5123                     addSharedLibraryLPw(usesLibraryFiles, file, changingLib);
   5124                 }
   5125             }
   5126             N = usesLibraryFiles.size();
   5127             if (N > 0) {
   5128                 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]);
   5129             } else {
   5130                 pkg.usesLibraryFiles = null;
   5131             }
   5132         }
   5133     }
   5134 
   5135     private static boolean hasString(List<String> list, List<String> which) {
   5136         if (list == null) {
   5137             return false;
   5138         }
   5139         for (int i=list.size()-1; i>=0; i--) {
   5140             for (int j=which.size()-1; j>=0; j--) {
   5141                 if (which.get(j).equals(list.get(i))) {
   5142                     return true;
   5143                 }
   5144             }
   5145         }
   5146         return false;
   5147     }
   5148 
   5149     private void updateAllSharedLibrariesLPw() {
   5150         for (PackageParser.Package pkg : mPackages.values()) {
   5151             try {
   5152                 updateSharedLibrariesLPw(pkg, null);
   5153             } catch (PackageManagerException e) {
   5154                 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
   5155             }
   5156         }
   5157     }
   5158 
   5159     private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
   5160             PackageParser.Package changingPkg) {
   5161         ArrayList<PackageParser.Package> res = null;
   5162         for (PackageParser.Package pkg : mPackages.values()) {
   5163             if (hasString(pkg.usesLibraries, changingPkg.libraryNames)
   5164                     || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) {
   5165                 if (res == null) {
   5166                     res = new ArrayList<PackageParser.Package>();
   5167                 }
   5168                 res.add(pkg);
   5169                 try {
   5170                     updateSharedLibrariesLPw(pkg, changingPkg);
   5171                 } catch (PackageManagerException e) {
   5172                     Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
   5173                 }
   5174             }
   5175         }
   5176         return res;
   5177     }
   5178 
   5179     /**
   5180      * Derive the value of the {@code cpuAbiOverride} based on the provided
   5181      * value and an optional stored value from the package settings.
   5182      */
   5183     private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
   5184         String cpuAbiOverride = null;
   5185 
   5186         if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
   5187             cpuAbiOverride = null;
   5188         } else if (abiOverride != null) {
   5189             cpuAbiOverride = abiOverride;
   5190         } else if (settings != null) {
   5191             cpuAbiOverride = settings.cpuAbiOverrideString;
   5192         }
   5193 
   5194         return cpuAbiOverride;
   5195     }
   5196 
   5197     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
   5198             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
   5199         boolean success = false;
   5200         try {
   5201             final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
   5202                     currentTime, user);
   5203             success = true;
   5204             return res;
   5205         } finally {
   5206             if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
   5207                 removeDataDirsLI(pkg.packageName);
   5208             }
   5209         }
   5210     }
   5211 
   5212     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
   5213             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
   5214         final File scanFile = new File(pkg.codePath);
   5215         if (pkg.applicationInfo.getCodePath() == null ||
   5216                 pkg.applicationInfo.getResourcePath() == null) {
   5217             // Bail out. The resource and code paths haven't been set.
   5218             throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
   5219                     "Code and resource paths haven't been set correctly");
   5220         }
   5221 
   5222         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
   5223             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
   5224         } else {
   5225             // Only allow system apps to be flagged as core apps.
   5226             pkg.coreApp = false;
   5227         }
   5228 
   5229         if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
   5230             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED;
   5231         }
   5232 
   5233         if (mCustomResolverComponentName != null &&
   5234                 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
   5235             setUpCustomResolverActivity(pkg);
   5236         }
   5237 
   5238         if (pkg.packageName.equals("android")) {
   5239             synchronized (mPackages) {
   5240                 if (mAndroidApplication != null) {
   5241                     Slog.w(TAG, "*************************************************");
   5242                     Slog.w(TAG, "Core android package being redefined.  Skipping.");
   5243                     Slog.w(TAG, " file=" + scanFile);
   5244                     Slog.w(TAG, "*************************************************");
   5245                     throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
   5246                             "Core android package being redefined.  Skipping.");
   5247                 }
   5248 
   5249                 // Set up information for our fall-back user intent resolution activity.
   5250                 mPlatformPackage = pkg;
   5251                 pkg.mVersionCode = mSdkVersion;
   5252                 mAndroidApplication = pkg.applicationInfo;
   5253 
   5254                 if (!mResolverReplaced) {
   5255                     mResolveActivity.applicationInfo = mAndroidApplication;
   5256                     mResolveActivity.name = ResolverActivity.class.getName();
   5257                     mResolveActivity.packageName = mAndroidApplication.packageName;
   5258                     mResolveActivity.processName = "system:ui";
   5259                     mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   5260                     mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
   5261                     mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
   5262                     mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
   5263                     mResolveActivity.exported = true;
   5264                     mResolveActivity.enabled = true;
   5265                     mResolveInfo.activityInfo = mResolveActivity;
   5266                     mResolveInfo.priority = 0;
   5267                     mResolveInfo.preferredOrder = 0;
   5268                     mResolveInfo.match = 0;
   5269                     mResolveComponentName = new ComponentName(
   5270                             mAndroidApplication.packageName, mResolveActivity.name);
   5271                 }
   5272             }
   5273         }
   5274 
   5275         if (DEBUG_PACKAGE_SCANNING) {
   5276             if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   5277                 Log.d(TAG, "Scanning package " + pkg.packageName);
   5278         }
   5279 
   5280         if (mPackages.containsKey(pkg.packageName)
   5281                 || mSharedLibraries.containsKey(pkg.packageName)) {
   5282             throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
   5283                     "Application package " + pkg.packageName
   5284                     + " already installed.  Skipping duplicate.");
   5285         }
   5286 
   5287         // Initialize package source and resource directories
   5288         File destCodeFile = new File(pkg.applicationInfo.getCodePath());
   5289         File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
   5290 
   5291         SharedUserSetting suid = null;
   5292         PackageSetting pkgSetting = null;
   5293 
   5294         if (!isSystemApp(pkg)) {
   5295             // Only system apps can use these features.
   5296             pkg.mOriginalPackages = null;
   5297             pkg.mRealPackage = null;
   5298             pkg.mAdoptPermissions = null;
   5299         }
   5300 
   5301         // writer
   5302         synchronized (mPackages) {
   5303             if (pkg.mSharedUserId != null) {
   5304                 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true);
   5305                 if (suid == null) {
   5306                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
   5307                             "Creating application package " + pkg.packageName
   5308                             + " for shared user failed");
   5309                 }
   5310                 if (DEBUG_PACKAGE_SCANNING) {
   5311                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   5312                         Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
   5313                                 + "): packages=" + suid.packages);
   5314                 }
   5315             }
   5316 
   5317             // Check if we are renaming from an original package name.
   5318             PackageSetting origPackage = null;
   5319             String realName = null;
   5320             if (pkg.mOriginalPackages != null) {
   5321                 // This package may need to be renamed to a previously
   5322                 // installed name.  Let's check on that...
   5323                 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
   5324                 if (pkg.mOriginalPackages.contains(renamed)) {
   5325                     // This package had originally been installed as the
   5326                     // original name, and we have already taken care of
   5327                     // transitioning to the new one.  Just update the new
   5328                     // one to continue using the old name.
   5329                     realName = pkg.mRealPackage;
   5330                     if (!pkg.packageName.equals(renamed)) {
   5331                         // Callers into this function may have already taken
   5332                         // care of renaming the package; only do it here if
   5333                         // it is not already done.
   5334                         pkg.setPackageName(renamed);
   5335                     }
   5336 
   5337                 } else {
   5338                     for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
   5339                         if ((origPackage = mSettings.peekPackageLPr(
   5340                                 pkg.mOriginalPackages.get(i))) != null) {
   5341                             // We do have the package already installed under its
   5342                             // original name...  should we use it?
   5343                             if (!verifyPackageUpdateLPr(origPackage, pkg)) {
   5344                                 // New package is not compatible with original.
   5345                                 origPackage = null;
   5346                                 continue;
   5347                             } else if (origPackage.sharedUser != null) {
   5348                                 // Make sure uid is compatible between packages.
   5349                                 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
   5350                                     Slog.w(TAG, "Unable to migrate data from " + origPackage.name
   5351                                             + " to " + pkg.packageName + ": old uid "
   5352                                             + origPackage.sharedUser.name
   5353                                             + " differs from " + pkg.mSharedUserId);
   5354                                     origPackage = null;
   5355                                     continue;
   5356                                 }
   5357                             } else {
   5358                                 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
   5359                                         + pkg.packageName + " to old name " + origPackage.name);
   5360                             }
   5361                             break;
   5362                         }
   5363                     }
   5364                 }
   5365             }
   5366 
   5367             if (mTransferedPackages.contains(pkg.packageName)) {
   5368                 Slog.w(TAG, "Package " + pkg.packageName
   5369                         + " was transferred to another, but its .apk remains");
   5370             }
   5371 
   5372             // Just create the setting, don't add it yet. For already existing packages
   5373             // the PkgSetting exists already and doesn't have to be created.
   5374             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
   5375                     destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
   5376                     pkg.applicationInfo.primaryCpuAbi,
   5377                     pkg.applicationInfo.secondaryCpuAbi,
   5378                     pkg.applicationInfo.flags, user, false);
   5379             if (pkgSetting == null) {
   5380                 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
   5381                         "Creating application package " + pkg.packageName + " failed");
   5382             }
   5383 
   5384             if (pkgSetting.origPackage != null) {
   5385                 // If we are first transitioning from an original package,
   5386                 // fix up the new package's name now.  We need to do this after
   5387                 // looking up the package under its new name, so getPackageLP
   5388                 // can take care of fiddling things correctly.
   5389                 pkg.setPackageName(origPackage.name);
   5390 
   5391                 // File a report about this.
   5392                 String msg = "New package " + pkgSetting.realName
   5393                         + " renamed to replace old package " + pkgSetting.name;
   5394                 reportSettingsProblem(Log.WARN, msg);
   5395 
   5396                 // Make a note of it.
   5397                 mTransferedPackages.add(origPackage.name);
   5398 
   5399                 // No longer need to retain this.
   5400                 pkgSetting.origPackage = null;
   5401             }
   5402 
   5403             if (realName != null) {
   5404                 // Make a note of it.
   5405                 mTransferedPackages.add(pkg.packageName);
   5406             }
   5407 
   5408             if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
   5409                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   5410             }
   5411 
   5412             if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   5413                 // Check all shared libraries and map to their actual file path.
   5414                 // We only do this here for apps not on a system dir, because those
   5415                 // are the only ones that can fail an install due to this.  We
   5416                 // will take care of the system apps by updating all of their
   5417                 // library paths after the scan is done.
   5418                 updateSharedLibrariesLPw(pkg, null);
   5419             }
   5420 
   5421             if (mFoundPolicyFile) {
   5422                 SELinuxMMAC.assignSeinfoValue(pkg);
   5423             }
   5424 
   5425             pkg.applicationInfo.uid = pkgSetting.appId;
   5426             pkg.mExtras = pkgSetting;
   5427             if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
   5428                 try {
   5429                     verifySignaturesLP(pkgSetting, pkg);
   5430                     // We just determined the app is signed correctly, so bring
   5431                     // over the latest parsed certs.
   5432                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   5433                 } catch (PackageManagerException e) {
   5434                     if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
   5435                         throw e;
   5436                     }
   5437                     // The signature has changed, but this package is in the system
   5438                     // image...  let's recover!
   5439                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   5440                     // However...  if this package is part of a shared user, but it
   5441                     // doesn't match the signature of the shared user, let's fail.
   5442                     // What this means is that you can't change the signatures
   5443                     // associated with an overall shared user, which doesn't seem all
   5444                     // that unreasonable.
   5445                     if (pkgSetting.sharedUser != null) {
   5446                         if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
   5447                                               pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
   5448                             throw new PackageManagerException(
   5449                                     INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
   5450                                             "Signature mismatch for shared user : "
   5451                                             + pkgSetting.sharedUser);
   5452                         }
   5453                     }
   5454                     // File a report about this.
   5455                     String msg = "System package " + pkg.packageName
   5456                         + " signature changed; retaining data.";
   5457                     reportSettingsProblem(Log.WARN, msg);
   5458                 }
   5459             } else {
   5460                 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) {
   5461                     throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
   5462                             + pkg.packageName + " upgrade keys do not match the "
   5463                             + "previously installed version");
   5464                 } else {
   5465                     // We just determined the app is signed correctly, so bring
   5466                     // over the latest parsed certs.
   5467                     pkgSetting.signatures.mSignatures = pkg.mSignatures;
   5468                 }
   5469             }
   5470             // Verify that this new package doesn't have any content providers
   5471             // that conflict with existing packages.  Only do this if the
   5472             // package isn't already installed, since we don't want to break
   5473             // things that are installed.
   5474             if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
   5475                 final int N = pkg.providers.size();
   5476                 int i;
   5477                 for (i=0; i<N; i++) {
   5478                     PackageParser.Provider p = pkg.providers.get(i);
   5479                     if (p.info.authority != null) {
   5480                         String names[] = p.info.authority.split(";");
   5481                         for (int j = 0; j < names.length; j++) {
   5482                             if (mProvidersByAuthority.containsKey(names[j])) {
   5483                                 PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
   5484                                 final String otherPackageName =
   5485                                         ((other != null && other.getComponentName() != null) ?
   5486                                                 other.getComponentName().getPackageName() : "?");
   5487                                 throw new PackageManagerException(
   5488                                         INSTALL_FAILED_CONFLICTING_PROVIDER,
   5489                                                 "Can't install because provider name " + names[j]
   5490                                                 + " (in package " + pkg.applicationInfo.packageName
   5491                                                 + ") is already used by " + otherPackageName);
   5492                             }
   5493                         }
   5494                     }
   5495                 }
   5496             }
   5497 
   5498             if (pkg.mAdoptPermissions != null) {
   5499                 // This package wants to adopt ownership of permissions from
   5500                 // another package.
   5501                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
   5502                     final String origName = pkg.mAdoptPermissions.get(i);
   5503                     final PackageSetting orig = mSettings.peekPackageLPr(origName);
   5504                     if (orig != null) {
   5505                         if (verifyPackageUpdateLPr(orig, pkg)) {
   5506                             Slog.i(TAG, "Adopting permissions from " + origName + " to "
   5507                                     + pkg.packageName);
   5508                             mSettings.transferPermissionsLPw(origName, pkg.packageName);
   5509                         }
   5510                     }
   5511                 }
   5512             }
   5513         }
   5514 
   5515         final String pkgName = pkg.packageName;
   5516 
   5517         final long scanFileTime = scanFile.lastModified();
   5518         final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0;
   5519         pkg.applicationInfo.processName = fixProcessName(
   5520                 pkg.applicationInfo.packageName,
   5521                 pkg.applicationInfo.processName,
   5522                 pkg.applicationInfo.uid);
   5523 
   5524         File dataPath;
   5525         if (mPlatformPackage == pkg) {
   5526             // The system package is special.
   5527             dataPath = new File(Environment.getDataDirectory(), "system");
   5528 
   5529             pkg.applicationInfo.dataDir = dataPath.getPath();
   5530 
   5531         } else {
   5532             // This is a normal package, need to make its data directory.
   5533             dataPath = getDataPathForPackage(pkg.packageName, 0);
   5534 
   5535             boolean uidError = false;
   5536             if (dataPath.exists()) {
   5537                 int currentUid = 0;
   5538                 try {
   5539                     StructStat stat = Os.stat(dataPath.getPath());
   5540                     currentUid = stat.st_uid;
   5541                 } catch (ErrnoException e) {
   5542                     Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e);
   5543                 }
   5544 
   5545                 // If we have mismatched owners for the data path, we have a problem.
   5546                 if (currentUid != pkg.applicationInfo.uid) {
   5547                     boolean recovered = false;
   5548                     if (currentUid == 0) {
   5549                         // The directory somehow became owned by root.  Wow.
   5550                         // This is probably because the system was stopped while
   5551                         // installd was in the middle of messing with its libs
   5552                         // directory.  Ask installd to fix that.
   5553                         int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid,
   5554                                 pkg.applicationInfo.uid);
   5555                         if (ret >= 0) {
   5556                             recovered = true;
   5557                             String msg = "Package " + pkg.packageName
   5558                                     + " unexpectedly changed to uid 0; recovered to " +
   5559                                     + pkg.applicationInfo.uid;
   5560                             reportSettingsProblem(Log.WARN, msg);
   5561                         }
   5562                     }
   5563                     if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
   5564                             || (scanFlags&SCAN_BOOTING) != 0)) {
   5565                         // If this is a system app, we can at least delete its
   5566                         // current data so the application will still work.
   5567                         int ret = removeDataDirsLI(pkgName);
   5568                         if (ret >= 0) {
   5569                             // TODO: Kill the processes first
   5570                             // Old data gone!
   5571                             String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
   5572                                     ? "System package " : "Third party package ";
   5573                             String msg = prefix + pkg.packageName
   5574                                     + " has changed from uid: "
   5575                                     + currentUid + " to "
   5576                                     + pkg.applicationInfo.uid + "; old data erased";
   5577                             reportSettingsProblem(Log.WARN, msg);
   5578                             recovered = true;
   5579 
   5580                             // And now re-install the app.
   5581                             ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
   5582                                                    pkg.applicationInfo.seinfo);
   5583                             if (ret == -1) {
   5584                                 // Ack should not happen!
   5585                                 msg = prefix + pkg.packageName
   5586                                         + " could not have data directory re-created after delete.";
   5587                                 reportSettingsProblem(Log.WARN, msg);
   5588                                 throw new PackageManagerException(
   5589                                         INSTALL_FAILED_INSUFFICIENT_STORAGE, msg);
   5590                             }
   5591                         }
   5592                         if (!recovered) {
   5593                             mHasSystemUidErrors = true;
   5594                         }
   5595                     } else if (!recovered) {
   5596                         // If we allow this install to proceed, we will be broken.
   5597                         // Abort, abort!
   5598                         throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED,
   5599                                 "scanPackageLI");
   5600                     }
   5601                     if (!recovered) {
   5602                         pkg.applicationInfo.dataDir = "/mismatched_uid/settings_"
   5603                             + pkg.applicationInfo.uid + "/fs_"
   5604                             + currentUid;
   5605                         pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
   5606                         pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir;
   5607                         String msg = "Package " + pkg.packageName
   5608                                 + " has mismatched uid: "
   5609                                 + currentUid + " on disk, "
   5610                                 + pkg.applicationInfo.uid + " in settings";
   5611                         // writer
   5612                         synchronized (mPackages) {
   5613                             mSettings.mReadMessages.append(msg);
   5614                             mSettings.mReadMessages.append('\n');
   5615                             uidError = true;
   5616                             if (!pkgSetting.uidError) {
   5617                                 reportSettingsProblem(Log.ERROR, msg);
   5618                             }
   5619                         }
   5620                     }
   5621                 }
   5622                 pkg.applicationInfo.dataDir = dataPath.getPath();
   5623                 if (mShouldRestoreconData) {
   5624                     Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued.");
   5625                     mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo,
   5626                                 pkg.applicationInfo.uid);
   5627                 }
   5628             } else {
   5629                 if (DEBUG_PACKAGE_SCANNING) {
   5630                     if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   5631                         Log.v(TAG, "Want this data dir: " + dataPath);
   5632                 }
   5633                 //invoke installer to do the actual installation
   5634                 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid,
   5635                                            pkg.applicationInfo.seinfo);
   5636                 if (ret < 0) {
   5637                     // Error from installer
   5638                     throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE,
   5639                             "Unable to create data dirs [errorCode=" + ret + "]");
   5640                 }
   5641 
   5642                 if (dataPath.exists()) {
   5643                     pkg.applicationInfo.dataDir = dataPath.getPath();
   5644                 } else {
   5645                     Slog.w(TAG, "Unable to create data directory: " + dataPath);
   5646                     pkg.applicationInfo.dataDir = null;
   5647                 }
   5648             }
   5649 
   5650             pkgSetting.uidError = uidError;
   5651         }
   5652 
   5653         final String path = scanFile.getPath();
   5654         final String codePath = pkg.applicationInfo.getCodePath();
   5655         final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
   5656         if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
   5657             setBundledAppAbisAndRoots(pkg, pkgSetting);
   5658 
   5659             // If we haven't found any native libraries for the app, check if it has
   5660             // renderscript code. We'll need to force the app to 32 bit if it has
   5661             // renderscript bitcode.
   5662             if (pkg.applicationInfo.primaryCpuAbi == null
   5663                     && pkg.applicationInfo.secondaryCpuAbi == null
   5664                     && Build.SUPPORTED_64_BIT_ABIS.length >  0) {
   5665                 NativeLibraryHelper.Handle handle = null;
   5666                 try {
   5667                     handle = NativeLibraryHelper.Handle.create(scanFile);
   5668                     if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
   5669                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   5670                     }
   5671                 } catch (IOException ioe) {
   5672                     Slog.w(TAG, "Error scanning system app : " + ioe);
   5673                 } finally {
   5674                     IoUtils.closeQuietly(handle);
   5675                 }
   5676             }
   5677 
   5678             setNativeLibraryPaths(pkg);
   5679         } else {
   5680             // TODO: We can probably be smarter about this stuff. For installed apps,
   5681             // we can calculate this information at install time once and for all. For
   5682             // system apps, we can probably assume that this information doesn't change
   5683             // after the first boot scan. As things stand, we do lots of unnecessary work.
   5684 
   5685             // Give ourselves some initial paths; we'll come back for another
   5686             // pass once we've determined ABI below.
   5687             setNativeLibraryPaths(pkg);
   5688 
   5689             final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg);
   5690             final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
   5691             final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
   5692 
   5693             NativeLibraryHelper.Handle handle = null;
   5694             try {
   5695                 handle = NativeLibraryHelper.Handle.create(scanFile);
   5696                 // TODO(multiArch): This can be null for apps that didn't go through the
   5697                 // usual installation process. We can calculate it again, like we
   5698                 // do during install time.
   5699                 //
   5700                 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
   5701                 // unnecessary.
   5702                 final File nativeLibraryRoot = new File(nativeLibraryRootStr);
   5703 
   5704                 // Null out the abis so that they can be recalculated.
   5705                 pkg.applicationInfo.primaryCpuAbi = null;
   5706                 pkg.applicationInfo.secondaryCpuAbi = null;
   5707                 if (isMultiArch(pkg.applicationInfo)) {
   5708                     // Warn if we've set an abiOverride for multi-lib packages..
   5709                     // By definition, we need to copy both 32 and 64 bit libraries for
   5710                     // such packages.
   5711                     if (pkg.cpuAbiOverride != null
   5712                             && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
   5713                         Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
   5714                     }
   5715 
   5716                     int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
   5717                     int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
   5718                     if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
   5719                         if (isAsec) {
   5720                             abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
   5721                         } else {
   5722                             abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   5723                                     nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
   5724                                     useIsaSpecificSubdirs);
   5725                         }
   5726                     }
   5727 
   5728                     maybeThrowExceptionForMultiArchCopy(
   5729                             "Error unpackaging 32 bit native libs for multiarch app.", abi32);
   5730 
   5731                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
   5732                         if (isAsec) {
   5733                             abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
   5734                         } else {
   5735                             abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   5736                                     nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
   5737                                     useIsaSpecificSubdirs);
   5738                         }
   5739                     }
   5740 
   5741                     maybeThrowExceptionForMultiArchCopy(
   5742                             "Error unpackaging 64 bit native libs for multiarch app.", abi64);
   5743 
   5744                     if (abi64 >= 0) {
   5745                         pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
   5746                     }
   5747 
   5748                     if (abi32 >= 0) {
   5749                         final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
   5750                         if (abi64 >= 0) {
   5751                             pkg.applicationInfo.secondaryCpuAbi = abi;
   5752                         } else {
   5753                             pkg.applicationInfo.primaryCpuAbi = abi;
   5754                         }
   5755                     }
   5756                 } else {
   5757                     String[] abiList = (cpuAbiOverride != null) ?
   5758                             new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
   5759 
   5760                     // Enable gross and lame hacks for apps that are built with old
   5761                     // SDK tools. We must scan their APKs for renderscript bitcode and
   5762                     // not launch them if it's present. Don't bother checking on devices
   5763                     // that don't have 64 bit support.
   5764                     boolean needsRenderScriptOverride = false;
   5765                     if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
   5766                             NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
   5767                         abiList = Build.SUPPORTED_32_BIT_ABIS;
   5768                         needsRenderScriptOverride = true;
   5769                     }
   5770 
   5771                     final int copyRet;
   5772                     if (isAsec) {
   5773                         copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
   5774                     } else {
   5775                         copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
   5776                                 nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
   5777                     }
   5778 
   5779                     if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
   5780                         throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
   5781                                 "Error unpackaging native libs for app, errorCode=" + copyRet);
   5782                     }
   5783 
   5784                     if (copyRet >= 0) {
   5785                         pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
   5786                     } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
   5787                         pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
   5788                     } else if (needsRenderScriptOverride) {
   5789                         pkg.applicationInfo.primaryCpuAbi = abiList[0];
   5790                     }
   5791                 }
   5792             } catch (IOException ioe) {
   5793                 Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
   5794             } finally {
   5795                 IoUtils.closeQuietly(handle);
   5796             }
   5797 
   5798             // Now that we've calculated the ABIs and determined if it's an internal app,
   5799             // we will go ahead and populate the nativeLibraryPath.
   5800             setNativeLibraryPaths(pkg);
   5801 
   5802             if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path);
   5803             final int[] userIds = sUserManager.getUserIds();
   5804             synchronized (mInstallLock) {
   5805                 // Create a native library symlink only if we have native libraries
   5806                 // and if the native libraries are 32 bit libraries. We do not provide
   5807                 // this symlink for 64 bit libraries.
   5808                 if (pkg.applicationInfo.primaryCpuAbi != null &&
   5809                         !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
   5810                     final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
   5811                     for (int userId : userIds) {
   5812                         if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
   5813                             throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
   5814                                     "Failed linking native library dir (user=" + userId + ")");
   5815                         }
   5816                     }
   5817                 }
   5818             }
   5819         }
   5820 
   5821         // This is a special case for the "system" package, where the ABI is
   5822         // dictated by the zygote configuration (and init.rc). We should keep track
   5823         // of this ABI so that we can deal with "normal" applications that run under
   5824         // the same UID correctly.
   5825         if (mPlatformPackage == pkg) {
   5826             pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
   5827                     Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
   5828         }
   5829 
   5830         pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
   5831         pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
   5832         pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
   5833         // Copy the derived override back to the parsed package, so that we can
   5834         // update the package settings accordingly.
   5835         pkg.cpuAbiOverride = cpuAbiOverride;
   5836 
   5837         if (DEBUG_ABI_SELECTION) {
   5838             Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
   5839                     + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
   5840                     + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
   5841         }
   5842 
   5843         // Push the derived path down into PackageSettings so we know what to
   5844         // clean up at uninstall time.
   5845         pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
   5846 
   5847         if (DEBUG_ABI_SELECTION) {
   5848             Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
   5849                     " primary=" + pkg.applicationInfo.primaryCpuAbi +
   5850                     " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
   5851         }
   5852 
   5853         if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
   5854             // We don't do this here during boot because we can do it all
   5855             // at once after scanning all existing packages.
   5856             //
   5857             // We also do this *before* we perform dexopt on this package, so that
   5858             // we can avoid redundant dexopts, and also to make sure we've got the
   5859             // code and package path correct.
   5860             adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
   5861                     pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0);
   5862         }
   5863 
   5864         if ((scanFlags & SCAN_NO_DEX) == 0) {
   5865             if (performDexOptLI(pkg, null /* instruction sets */, forceDex,
   5866                     (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
   5867                 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
   5868             }
   5869         }
   5870 
   5871         if (mFactoryTest && pkg.requestedPermissions.contains(
   5872                 android.Manifest.permission.FACTORY_TEST)) {
   5873             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
   5874         }
   5875 
   5876         ArrayList<PackageParser.Package> clientLibPkgs = null;
   5877 
   5878         // writer
   5879         synchronized (mPackages) {
   5880             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   5881                 // Only system apps can add new shared libraries.
   5882                 if (pkg.libraryNames != null) {
   5883                     for (int i=0; i<pkg.libraryNames.size(); i++) {
   5884                         String name = pkg.libraryNames.get(i);
   5885                         boolean allowed = false;
   5886                         if (isUpdatedSystemApp(pkg)) {
   5887                             // New library entries can only be added through the
   5888                             // system image.  This is important to get rid of a lot
   5889                             // of nasty edge cases: for example if we allowed a non-
   5890                             // system update of the app to add a library, then uninstalling
   5891                             // the update would make the library go away, and assumptions
   5892                             // we made such as through app install filtering would now
   5893                             // have allowed apps on the device which aren't compatible
   5894                             // with it.  Better to just have the restriction here, be
   5895                             // conservative, and create many fewer cases that can negatively
   5896                             // impact the user experience.
   5897                             final PackageSetting sysPs = mSettings
   5898                                     .getDisabledSystemPkgLPr(pkg.packageName);
   5899                             if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
   5900                                 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) {
   5901                                     if (name.equals(sysPs.pkg.libraryNames.get(j))) {
   5902                                         allowed = true;
   5903                                         allowed = true;
   5904                                         break;
   5905                                     }
   5906                                 }
   5907                             }
   5908                         } else {
   5909                             allowed = true;
   5910                         }
   5911                         if (allowed) {
   5912                             if (!mSharedLibraries.containsKey(name)) {
   5913                                 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName));
   5914                             } else if (!name.equals(pkg.packageName)) {
   5915                                 Slog.w(TAG, "Package " + pkg.packageName + " library "
   5916                                         + name + " already exists; skipping");
   5917                             }
   5918                         } else {
   5919                             Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
   5920                                     + name + " that is not declared on system image; skipping");
   5921                         }
   5922                     }
   5923                     if ((scanFlags&SCAN_BOOTING) == 0) {
   5924                         // If we are not booting, we need to update any applications
   5925                         // that are clients of our shared library.  If we are booting,
   5926                         // this will all be done once the scan is complete.
   5927                         clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
   5928                     }
   5929                 }
   5930             }
   5931         }
   5932 
   5933         // We also need to dexopt any apps that are dependent on this library.  Note that
   5934         // if these fail, we should abort the install since installing the library will
   5935         // result in some apps being broken.
   5936         if (clientLibPkgs != null) {
   5937             if ((scanFlags & SCAN_NO_DEX) == 0) {
   5938                 for (int i = 0; i < clientLibPkgs.size(); i++) {
   5939                     PackageParser.Package clientPkg = clientLibPkgs.get(i);
   5940                     if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex,
   5941                             (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) {
   5942                         throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
   5943                                 "scanPackageLI failed to dexopt clientLibPkgs");
   5944                     }
   5945                 }
   5946             }
   5947         }
   5948 
   5949         // Request the ActivityManager to kill the process(only for existing packages)
   5950         // so that we do not end up in a confused state while the user is still using the older
   5951         // version of the application while the new one gets installed.
   5952         if ((scanFlags & SCAN_REPLACING) != 0) {
   5953             killApplication(pkg.applicationInfo.packageName,
   5954                         pkg.applicationInfo.uid, "update pkg");
   5955         }
   5956 
   5957         // Also need to kill any apps that are dependent on the library.
   5958         if (clientLibPkgs != null) {
   5959             for (int i=0; i<clientLibPkgs.size(); i++) {
   5960                 PackageParser.Package clientPkg = clientLibPkgs.get(i);
   5961                 killApplication(clientPkg.applicationInfo.packageName,
   5962                         clientPkg.applicationInfo.uid, "update lib");
   5963             }
   5964         }
   5965 
   5966         // writer
   5967         synchronized (mPackages) {
   5968             // We don't expect installation to fail beyond this point
   5969 
   5970             // Add the new setting to mSettings
   5971             mSettings.insertPackageSettingLPw(pkgSetting, pkg);
   5972             // Add the new setting to mPackages
   5973             mPackages.put(pkg.applicationInfo.packageName, pkg);
   5974             // Make sure we don't accidentally delete its data.
   5975             final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
   5976             while (iter.hasNext()) {
   5977                 PackageCleanItem item = iter.next();
   5978                 if (pkgName.equals(item.packageName)) {
   5979                     iter.remove();
   5980                 }
   5981             }
   5982 
   5983             // Take care of first install / last update times.
   5984             if (currentTime != 0) {
   5985                 if (pkgSetting.firstInstallTime == 0) {
   5986                     pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
   5987                 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) {
   5988                     pkgSetting.lastUpdateTime = currentTime;
   5989                 }
   5990             } else if (pkgSetting.firstInstallTime == 0) {
   5991                 // We need *something*.  Take time time stamp of the file.
   5992                 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
   5993             } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
   5994                 if (scanFileTime != pkgSetting.timeStamp) {
   5995                     // A package on the system image has changed; consider this
   5996                     // to be an update.
   5997                     pkgSetting.lastUpdateTime = scanFileTime;
   5998                 }
   5999             }
   6000 
   6001             // Add the package's KeySets to the global KeySetManagerService
   6002             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   6003             try {
   6004                 // Old KeySetData no longer valid.
   6005                 ksms.removeAppKeySetDataLPw(pkg.packageName);
   6006                 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
   6007                 if (pkg.mKeySetMapping != null) {
   6008                     for (Map.Entry<String, ArraySet<PublicKey>> entry :
   6009                             pkg.mKeySetMapping.entrySet()) {
   6010                         if (entry.getValue() != null) {
   6011                             ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
   6012                                                           entry.getValue(), entry.getKey());
   6013                         }
   6014                     }
   6015                     if (pkg.mUpgradeKeySets != null) {
   6016                         for (String upgradeAlias : pkg.mUpgradeKeySets) {
   6017                             ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
   6018                         }
   6019                     }
   6020                 }
   6021             } catch (NullPointerException e) {
   6022                 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e);
   6023             } catch (IllegalArgumentException e) {
   6024                 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e);
   6025             }
   6026 
   6027             int N = pkg.providers.size();
   6028             StringBuilder r = null;
   6029             int i;
   6030             for (i=0; i<N; i++) {
   6031                 PackageParser.Provider p = pkg.providers.get(i);
   6032                 p.info.processName = fixProcessName(pkg.applicationInfo.processName,
   6033                         p.info.processName, pkg.applicationInfo.uid);
   6034                 mProviders.addProvider(p);
   6035                 p.syncable = p.info.isSyncable;
   6036                 if (p.info.authority != null) {
   6037                     String names[] = p.info.authority.split(";");
   6038                     p.info.authority = null;
   6039                     for (int j = 0; j < names.length; j++) {
   6040                         if (j == 1 && p.syncable) {
   6041                             // We only want the first authority for a provider to possibly be
   6042                             // syncable, so if we already added this provider using a different
   6043                             // authority clear the syncable flag. We copy the provider before
   6044                             // changing it because the mProviders object contains a reference
   6045                             // to a provider that we don't want to change.
   6046                             // Only do this for the second authority since the resulting provider
   6047                             // object can be the same for all future authorities for this provider.
   6048                             p = new PackageParser.Provider(p);
   6049                             p.syncable = false;
   6050                         }
   6051                         if (!mProvidersByAuthority.containsKey(names[j])) {
   6052                             mProvidersByAuthority.put(names[j], p);
   6053                             if (p.info.authority == null) {
   6054                                 p.info.authority = names[j];
   6055                             } else {
   6056                                 p.info.authority = p.info.authority + ";" + names[j];
   6057                             }
   6058                             if (DEBUG_PACKAGE_SCANNING) {
   6059                                 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
   6060                                     Log.d(TAG, "Registered content provider: " + names[j]
   6061                                             + ", className = " + p.info.name + ", isSyncable = "
   6062                                             + p.info.isSyncable);
   6063                             }
   6064                         } else {
   6065                             PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
   6066                             Slog.w(TAG, "Skipping provider name " + names[j] +
   6067                                     " (in package " + pkg.applicationInfo.packageName +
   6068                                     "): name already used by "
   6069                                     + ((other != null && other.getComponentName() != null)
   6070                                             ? other.getComponentName().getPackageName() : "?"));
   6071                         }
   6072                     }
   6073                 }
   6074                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6075                     if (r == null) {
   6076                         r = new StringBuilder(256);
   6077                     } else {
   6078                         r.append(' ');
   6079                     }
   6080                     r.append(p.info.name);
   6081                 }
   6082             }
   6083             if (r != null) {
   6084                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
   6085             }
   6086 
   6087             N = pkg.services.size();
   6088             r = null;
   6089             for (i=0; i<N; i++) {
   6090                 PackageParser.Service s = pkg.services.get(i);
   6091                 s.info.processName = fixProcessName(pkg.applicationInfo.processName,
   6092                         s.info.processName, pkg.applicationInfo.uid);
   6093                 mServices.addService(s);
   6094                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6095                     if (r == null) {
   6096                         r = new StringBuilder(256);
   6097                     } else {
   6098                         r.append(' ');
   6099                     }
   6100                     r.append(s.info.name);
   6101                 }
   6102             }
   6103             if (r != null) {
   6104                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
   6105             }
   6106 
   6107             N = pkg.receivers.size();
   6108             r = null;
   6109             for (i=0; i<N; i++) {
   6110                 PackageParser.Activity a = pkg.receivers.get(i);
   6111                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   6112                         a.info.processName, pkg.applicationInfo.uid);
   6113                 mReceivers.addActivity(a, "receiver");
   6114                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6115                     if (r == null) {
   6116                         r = new StringBuilder(256);
   6117                     } else {
   6118                         r.append(' ');
   6119                     }
   6120                     r.append(a.info.name);
   6121                 }
   6122             }
   6123             if (r != null) {
   6124                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
   6125             }
   6126 
   6127             N = pkg.activities.size();
   6128             r = null;
   6129             for (i=0; i<N; i++) {
   6130                 PackageParser.Activity a = pkg.activities.get(i);
   6131                 a.info.processName = fixProcessName(pkg.applicationInfo.processName,
   6132                         a.info.processName, pkg.applicationInfo.uid);
   6133                 mActivities.addActivity(a, "activity");
   6134                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6135                     if (r == null) {
   6136                         r = new StringBuilder(256);
   6137                     } else {
   6138                         r.append(' ');
   6139                     }
   6140                     r.append(a.info.name);
   6141                 }
   6142             }
   6143             if (r != null) {
   6144                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
   6145             }
   6146 
   6147             N = pkg.permissionGroups.size();
   6148             r = null;
   6149             for (i=0; i<N; i++) {
   6150                 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
   6151                 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
   6152                 if (cur == null) {
   6153                     mPermissionGroups.put(pg.info.name, pg);
   6154                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6155                         if (r == null) {
   6156                             r = new StringBuilder(256);
   6157                         } else {
   6158                             r.append(' ');
   6159                         }
   6160                         r.append(pg.info.name);
   6161                     }
   6162                 } else {
   6163                     Slog.w(TAG, "Permission group " + pg.info.name + " from package "
   6164                             + pg.info.packageName + " ignored: original from "
   6165                             + cur.info.packageName);
   6166                     if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6167                         if (r == null) {
   6168                             r = new StringBuilder(256);
   6169                         } else {
   6170                             r.append(' ');
   6171                         }
   6172                         r.append("DUP:");
   6173                         r.append(pg.info.name);
   6174                     }
   6175                 }
   6176             }
   6177             if (r != null) {
   6178                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
   6179             }
   6180 
   6181             N = pkg.permissions.size();
   6182             r = null;
   6183             for (i=0; i<N; i++) {
   6184                 PackageParser.Permission p = pkg.permissions.get(i);
   6185                 HashMap<String, BasePermission> permissionMap =
   6186                         p.tree ? mSettings.mPermissionTrees
   6187                         : mSettings.mPermissions;
   6188                 p.group = mPermissionGroups.get(p.info.group);
   6189                 if (p.info.group == null || p.group != null) {
   6190                     BasePermission bp = permissionMap.get(p.info.name);
   6191 
   6192                     // Allow system apps to redefine non-system permissions
   6193                     if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
   6194                         final boolean currentOwnerIsSystem = (bp.perm != null
   6195                                 && isSystemApp(bp.perm.owner));
   6196                         if (isSystemApp(p.owner)) {
   6197                             if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
   6198                                 // It's a built-in permission and no owner, take ownership now
   6199                                 bp.packageSetting = pkgSetting;
   6200                                 bp.perm = p;
   6201                                 bp.uid = pkg.applicationInfo.uid;
   6202                                 bp.sourcePackage = p.info.packageName;
   6203                             } else if (!currentOwnerIsSystem) {
   6204                                 String msg = "New decl " + p.owner + " of permission  "
   6205                                         + p.info.name + " is system; overriding " + bp.sourcePackage;
   6206                                 reportSettingsProblem(Log.WARN, msg);
   6207                                 bp = null;
   6208                             }
   6209                         }
   6210                     }
   6211 
   6212                     if (bp == null) {
   6213                         bp = new BasePermission(p.info.name, p.info.packageName,
   6214                                 BasePermission.TYPE_NORMAL);
   6215                         permissionMap.put(p.info.name, bp);
   6216                     }
   6217 
   6218                     if (bp.perm == null) {
   6219                         if (bp.sourcePackage == null
   6220                                 || bp.sourcePackage.equals(p.info.packageName)) {
   6221                             BasePermission tree = findPermissionTreeLP(p.info.name);
   6222                             if (tree == null
   6223                                     || tree.sourcePackage.equals(p.info.packageName)) {
   6224                                 bp.packageSetting = pkgSetting;
   6225                                 bp.perm = p;
   6226                                 bp.uid = pkg.applicationInfo.uid;
   6227                                 bp.sourcePackage = p.info.packageName;
   6228                                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6229                                     if (r == null) {
   6230                                         r = new StringBuilder(256);
   6231                                     } else {
   6232                                         r.append(' ');
   6233                                     }
   6234                                     r.append(p.info.name);
   6235                                 }
   6236                             } else {
   6237                                 Slog.w(TAG, "Permission " + p.info.name + " from package "
   6238                                         + p.info.packageName + " ignored: base tree "
   6239                                         + tree.name + " is from package "
   6240                                         + tree.sourcePackage);
   6241                             }
   6242                         } else {
   6243                             Slog.w(TAG, "Permission " + p.info.name + " from package "
   6244                                     + p.info.packageName + " ignored: original from "
   6245                                     + bp.sourcePackage);
   6246                         }
   6247                     } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6248                         if (r == null) {
   6249                             r = new StringBuilder(256);
   6250                         } else {
   6251                             r.append(' ');
   6252                         }
   6253                         r.append("DUP:");
   6254                         r.append(p.info.name);
   6255                     }
   6256                     if (bp.perm == p) {
   6257                         bp.protectionLevel = p.info.protectionLevel;
   6258                     }
   6259                 } else {
   6260                     Slog.w(TAG, "Permission " + p.info.name + " from package "
   6261                             + p.info.packageName + " ignored: no group "
   6262                             + p.group);
   6263                 }
   6264             }
   6265             if (r != null) {
   6266                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
   6267             }
   6268 
   6269             N = pkg.instrumentation.size();
   6270             r = null;
   6271             for (i=0; i<N; i++) {
   6272                 PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   6273                 a.info.packageName = pkg.applicationInfo.packageName;
   6274                 a.info.sourceDir = pkg.applicationInfo.sourceDir;
   6275                 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
   6276                 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
   6277                 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
   6278                 a.info.dataDir = pkg.applicationInfo.dataDir;
   6279 
   6280                 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it
   6281                 // need other information about the application, like the ABI and what not ?
   6282                 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
   6283                 mInstrumentation.put(a.getComponentName(), a);
   6284                 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) {
   6285                     if (r == null) {
   6286                         r = new StringBuilder(256);
   6287                     } else {
   6288                         r.append(' ');
   6289                     }
   6290                     r.append(a.info.name);
   6291                 }
   6292             }
   6293             if (r != null) {
   6294                 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
   6295             }
   6296 
   6297             if (pkg.protectedBroadcasts != null) {
   6298                 N = pkg.protectedBroadcasts.size();
   6299                 for (i=0; i<N; i++) {
   6300                     mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
   6301                 }
   6302             }
   6303 
   6304             pkgSetting.setTimeStamp(scanFileTime);
   6305 
   6306             // Create idmap files for pairs of (packages, overlay packages).
   6307             // Note: "android", ie framework-res.apk, is handled by native layers.
   6308             if (pkg.mOverlayTarget != null) {
   6309                 // This is an overlay package.
   6310                 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
   6311                     if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
   6312                         mOverlays.put(pkg.mOverlayTarget,
   6313                                 new HashMap<String, PackageParser.Package>());
   6314                     }
   6315                     HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
   6316                     map.put(pkg.packageName, pkg);
   6317                     PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
   6318                     if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
   6319                         throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
   6320                                 "scanPackageLI failed to createIdmap");
   6321                     }
   6322                 }
   6323             } else if (mOverlays.containsKey(pkg.packageName) &&
   6324                     !pkg.packageName.equals("android")) {
   6325                 // This is a regular package, with one or more known overlay packages.
   6326                 createIdmapsForPackageLI(pkg);
   6327             }
   6328         }
   6329 
   6330         return pkg;
   6331     }
   6332 
   6333     /**
   6334      * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
   6335      * i.e, so that all packages can be run inside a single process if required.
   6336      *
   6337      * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
   6338      * this function will either try and make the ABI for all packages in {@code packagesForUser}
   6339      * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
   6340      * the ABI selected for {@code packagesForUser}. This variant is used when installing or
   6341      * updating a package that belongs to a shared user.
   6342      *
   6343      * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
   6344      * adds unnecessary complexity.
   6345      */
   6346     private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
   6347             PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
   6348         String requiredInstructionSet = null;
   6349         if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
   6350             requiredInstructionSet = VMRuntime.getInstructionSet(
   6351                      scannedPackage.applicationInfo.primaryCpuAbi);
   6352         }
   6353 
   6354         PackageSetting requirer = null;
   6355         for (PackageSetting ps : packagesForUser) {
   6356             // If packagesForUser contains scannedPackage, we skip it. This will happen
   6357             // when scannedPackage is an update of an existing package. Without this check,
   6358             // we will never be able to change the ABI of any package belonging to a shared
   6359             // user, even if it's compatible with other packages.
   6360             if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
   6361                 if (ps.primaryCpuAbiString == null) {
   6362                     continue;
   6363                 }
   6364 
   6365                 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
   6366                 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
   6367                     // We have a mismatch between instruction sets (say arm vs arm64) warn about
   6368                     // this but there's not much we can do.
   6369                     String errorMessage = "Instruction set mismatch, "
   6370                             + ((requirer == null) ? "[caller]" : requirer)
   6371                             + " requires " + requiredInstructionSet + " whereas " + ps
   6372                             + " requires " + instructionSet;
   6373                     Slog.w(TAG, errorMessage);
   6374                 }
   6375 
   6376                 if (requiredInstructionSet == null) {
   6377                     requiredInstructionSet = instructionSet;
   6378                     requirer = ps;
   6379                 }
   6380             }
   6381         }
   6382 
   6383         if (requiredInstructionSet != null) {
   6384             String adjustedAbi;
   6385             if (requirer != null) {
   6386                 // requirer != null implies that either scannedPackage was null or that scannedPackage
   6387                 // did not require an ABI, in which case we have to adjust scannedPackage to match
   6388                 // the ABI of the set (which is the same as requirer's ABI)
   6389                 adjustedAbi = requirer.primaryCpuAbiString;
   6390                 if (scannedPackage != null) {
   6391                     scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
   6392                 }
   6393             } else {
   6394                 // requirer == null implies that we're updating all ABIs in the set to
   6395                 // match scannedPackage.
   6396                 adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
   6397             }
   6398 
   6399             for (PackageSetting ps : packagesForUser) {
   6400                 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
   6401                     if (ps.primaryCpuAbiString != null) {
   6402                         continue;
   6403                     }
   6404 
   6405                     ps.primaryCpuAbiString = adjustedAbi;
   6406                     if (ps.pkg != null && ps.pkg.applicationInfo != null) {
   6407                         ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
   6408                         Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
   6409 
   6410                         if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt,
   6411                                 deferDexOpt, true) == DEX_OPT_FAILED) {
   6412                             ps.primaryCpuAbiString = null;
   6413                             ps.pkg.applicationInfo.primaryCpuAbi = null;
   6414                             return;
   6415                         } else {
   6416                             mInstaller.rmdex(ps.codePathString,
   6417                                              getDexCodeInstructionSet(getPreferredInstructionSet()));
   6418                         }
   6419                     }
   6420                 }
   6421             }
   6422         }
   6423     }
   6424 
   6425     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
   6426         synchronized (mPackages) {
   6427             mResolverReplaced = true;
   6428             // Set up information for custom user intent resolution activity.
   6429             mResolveActivity.applicationInfo = pkg.applicationInfo;
   6430             mResolveActivity.name = mCustomResolverComponentName.getClassName();
   6431             mResolveActivity.packageName = pkg.applicationInfo.packageName;
   6432             mResolveActivity.processName = null;
   6433             mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
   6434             mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
   6435                     ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
   6436             mResolveActivity.theme = 0;
   6437             mResolveActivity.exported = true;
   6438             mResolveActivity.enabled = true;
   6439             mResolveInfo.activityInfo = mResolveActivity;
   6440             mResolveInfo.priority = 0;
   6441             mResolveInfo.preferredOrder = 0;
   6442             mResolveInfo.match = 0;
   6443             mResolveComponentName = mCustomResolverComponentName;
   6444             Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
   6445                     mResolveComponentName);
   6446         }
   6447     }
   6448 
   6449     private static String calculateBundledApkRoot(final String codePathString) {
   6450         final File codePath = new File(codePathString);
   6451         final File codeRoot;
   6452         if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
   6453             codeRoot = Environment.getRootDirectory();
   6454         } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
   6455             codeRoot = Environment.getOemDirectory();
   6456         } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
   6457             codeRoot = Environment.getVendorDirectory();
   6458         } else {
   6459             // Unrecognized code path; take its top real segment as the apk root:
   6460             // e.g. /something/app/blah.apk => /something
   6461             try {
   6462                 File f = codePath.getCanonicalFile();
   6463                 File parent = f.getParentFile();    // non-null because codePath is a file
   6464                 File tmp;
   6465                 while ((tmp = parent.getParentFile()) != null) {
   6466                     f = parent;
   6467                     parent = tmp;
   6468                 }
   6469                 codeRoot = f;
   6470                 Slog.w(TAG, "Unrecognized code path "
   6471                         + codePath + " - using " + codeRoot);
   6472             } catch (IOException e) {
   6473                 // Can't canonicalize the code path -- shenanigans?
   6474                 Slog.w(TAG, "Can't canonicalize code path " + codePath);
   6475                 return Environment.getRootDirectory().getPath();
   6476             }
   6477         }
   6478         return codeRoot.getPath();
   6479     }
   6480 
   6481     /**
   6482      * Derive and set the location of native libraries for the given package,
   6483      * which varies depending on where and how the package was installed.
   6484      */
   6485     private void setNativeLibraryPaths(PackageParser.Package pkg) {
   6486         final ApplicationInfo info = pkg.applicationInfo;
   6487         final String codePath = pkg.codePath;
   6488         final File codeFile = new File(codePath);
   6489         final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info);
   6490         final boolean asecApp = isForwardLocked(info) || isExternal(info);
   6491 
   6492         info.nativeLibraryRootDir = null;
   6493         info.nativeLibraryRootRequiresIsa = false;
   6494         info.nativeLibraryDir = null;
   6495         info.secondaryNativeLibraryDir = null;
   6496 
   6497         if (isApkFile(codeFile)) {
   6498             // Monolithic install
   6499             if (bundledApp) {
   6500                 // If "/system/lib64/apkname" exists, assume that is the per-package
   6501                 // native library directory to use; otherwise use "/system/lib/apkname".
   6502                 final String apkRoot = calculateBundledApkRoot(info.sourceDir);
   6503                 final boolean is64Bit = VMRuntime.is64BitInstructionSet(
   6504                         getPrimaryInstructionSet(info));
   6505 
   6506                 // This is a bundled system app so choose the path based on the ABI.
   6507                 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
   6508                 // is just the default path.
   6509                 final String apkName = deriveCodePathName(codePath);
   6510                 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
   6511                 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
   6512                         apkName).getAbsolutePath();
   6513 
   6514                 if (info.secondaryCpuAbi != null) {
   6515                     final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
   6516                     info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
   6517                             secondaryLibDir, apkName).getAbsolutePath();
   6518                 }
   6519             } else if (asecApp) {
   6520                 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
   6521                         .getAbsolutePath();
   6522             } else {
   6523                 final String apkName = deriveCodePathName(codePath);
   6524                 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName)
   6525                         .getAbsolutePath();
   6526             }
   6527 
   6528             info.nativeLibraryRootRequiresIsa = false;
   6529             info.nativeLibraryDir = info.nativeLibraryRootDir;
   6530         } else {
   6531             // Cluster install
   6532             info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
   6533             info.nativeLibraryRootRequiresIsa = true;
   6534 
   6535             info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
   6536                     getPrimaryInstructionSet(info)).getAbsolutePath();
   6537 
   6538             if (info.secondaryCpuAbi != null) {
   6539                 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
   6540                         VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
   6541             }
   6542         }
   6543     }
   6544 
   6545     /**
   6546      * Calculate the abis and roots for a bundled app. These can uniquely
   6547      * be determined from the contents of the system partition, i.e whether
   6548      * it contains 64 or 32 bit shared libraries etc. We do not validate any
   6549      * of this information, and instead assume that the system was built
   6550      * sensibly.
   6551      */
   6552     private void setBundledAppAbisAndRoots(PackageParser.Package pkg,
   6553                                            PackageSetting pkgSetting) {
   6554         final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
   6555 
   6556         // If "/system/lib64/apkname" exists, assume that is the per-package
   6557         // native library directory to use; otherwise use "/system/lib/apkname".
   6558         final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
   6559         setBundledAppAbi(pkg, apkRoot, apkName);
   6560         // pkgSetting might be null during rescan following uninstall of updates
   6561         // to a bundled app, so accommodate that possibility.  The settings in
   6562         // that case will be established later from the parsed package.
   6563         //
   6564         // If the settings aren't null, sync them up with what we've just derived.
   6565         // note that apkRoot isn't stored in the package settings.
   6566         if (pkgSetting != null) {
   6567             pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
   6568             pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
   6569         }
   6570     }
   6571 
   6572     /**
   6573      * Deduces the ABI of a bundled app and sets the relevant fields on the
   6574      * parsed pkg object.
   6575      *
   6576      * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
   6577      *        under which system libraries are installed.
   6578      * @param apkName the name of the installed package.
   6579      */
   6580     private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
   6581         final File codeFile = new File(pkg.codePath);
   6582 
   6583         final boolean has64BitLibs;
   6584         final boolean has32BitLibs;
   6585         if (isApkFile(codeFile)) {
   6586             // Monolithic install
   6587             has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
   6588             has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
   6589         } else {
   6590             // Cluster install
   6591             final File rootDir = new File(codeFile, LIB_DIR_NAME);
   6592             if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
   6593                     && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
   6594                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
   6595                 has64BitLibs = (new File(rootDir, isa)).exists();
   6596             } else {
   6597                 has64BitLibs = false;
   6598             }
   6599             if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
   6600                     && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
   6601                 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
   6602                 has32BitLibs = (new File(rootDir, isa)).exists();
   6603             } else {
   6604                 has32BitLibs = false;
   6605             }
   6606         }
   6607 
   6608         if (has64BitLibs && !has32BitLibs) {
   6609             // The package has 64 bit libs, but not 32 bit libs. Its primary
   6610             // ABI should be 64 bit. We can safely assume here that the bundled
   6611             // native libraries correspond to the most preferred ABI in the list.
   6612 
   6613             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   6614             pkg.applicationInfo.secondaryCpuAbi = null;
   6615         } else if (has32BitLibs && !has64BitLibs) {
   6616             // The package has 32 bit libs but not 64 bit libs. Its primary
   6617             // ABI should be 32 bit.
   6618 
   6619             pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   6620             pkg.applicationInfo.secondaryCpuAbi = null;
   6621         } else if (has32BitLibs && has64BitLibs) {
   6622             // The application has both 64 and 32 bit bundled libraries. We check
   6623             // here that the app declares multiArch support, and warn if it doesn't.
   6624             //
   6625             // We will be lenient here and record both ABIs. The primary will be the
   6626             // ABI that's higher on the list, i.e, a device that's configured to prefer
   6627             // 64 bit apps will see a 64 bit primary ABI,
   6628 
   6629             if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
   6630                 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch.");
   6631             }
   6632 
   6633             if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
   6634                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   6635                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   6636             } else {
   6637                 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
   6638                 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
   6639             }
   6640         } else {
   6641             pkg.applicationInfo.primaryCpuAbi = null;
   6642             pkg.applicationInfo.secondaryCpuAbi = null;
   6643         }
   6644     }
   6645 
   6646     private void killApplication(String pkgName, int appId, String reason) {
   6647         // Request the ActivityManager to kill the process(only for existing packages)
   6648         // so that we do not end up in a confused state while the user is still using the older
   6649         // version of the application while the new one gets installed.
   6650         IActivityManager am = ActivityManagerNative.getDefault();
   6651         if (am != null) {
   6652             try {
   6653                 am.killApplicationWithAppId(pkgName, appId, reason);
   6654             } catch (RemoteException e) {
   6655             }
   6656         }
   6657     }
   6658 
   6659     void removePackageLI(PackageSetting ps, boolean chatty) {
   6660         if (DEBUG_INSTALL) {
   6661             if (chatty)
   6662                 Log.d(TAG, "Removing package " + ps.name);
   6663         }
   6664 
   6665         // writer
   6666         synchronized (mPackages) {
   6667             mPackages.remove(ps.name);
   6668             final PackageParser.Package pkg = ps.pkg;
   6669             if (pkg != null) {
   6670                 cleanPackageDataStructuresLILPw(pkg, chatty);
   6671             }
   6672         }
   6673     }
   6674 
   6675     void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
   6676         if (DEBUG_INSTALL) {
   6677             if (chatty)
   6678                 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
   6679         }
   6680 
   6681         // writer
   6682         synchronized (mPackages) {
   6683             mPackages.remove(pkg.applicationInfo.packageName);
   6684             cleanPackageDataStructuresLILPw(pkg, chatty);
   6685         }
   6686     }
   6687 
   6688     void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
   6689         int N = pkg.providers.size();
   6690         StringBuilder r = null;
   6691         int i;
   6692         for (i=0; i<N; i++) {
   6693             PackageParser.Provider p = pkg.providers.get(i);
   6694             mProviders.removeProvider(p);
   6695             if (p.info.authority == null) {
   6696 
   6697                 /* There was another ContentProvider with this authority when
   6698                  * this app was installed so this authority is null,
   6699                  * Ignore it as we don't have to unregister the provider.
   6700                  */
   6701                 continue;
   6702             }
   6703             String names[] = p.info.authority.split(";");
   6704             for (int j = 0; j < names.length; j++) {
   6705                 if (mProvidersByAuthority.get(names[j]) == p) {
   6706                     mProvidersByAuthority.remove(names[j]);
   6707                     if (DEBUG_REMOVE) {
   6708                         if (chatty)
   6709                             Log.d(TAG, "Unregistered content provider: " + names[j]
   6710                                     + ", className = " + p.info.name + ", isSyncable = "
   6711                                     + p.info.isSyncable);
   6712                     }
   6713                 }
   6714             }
   6715             if (DEBUG_REMOVE && chatty) {
   6716                 if (r == null) {
   6717                     r = new StringBuilder(256);
   6718                 } else {
   6719                     r.append(' ');
   6720                 }
   6721                 r.append(p.info.name);
   6722             }
   6723         }
   6724         if (r != null) {
   6725             if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
   6726         }
   6727 
   6728         N = pkg.services.size();
   6729         r = null;
   6730         for (i=0; i<N; i++) {
   6731             PackageParser.Service s = pkg.services.get(i);
   6732             mServices.removeService(s);
   6733             if (chatty) {
   6734                 if (r == null) {
   6735                     r = new StringBuilder(256);
   6736                 } else {
   6737                     r.append(' ');
   6738                 }
   6739                 r.append(s.info.name);
   6740             }
   6741         }
   6742         if (r != null) {
   6743             if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
   6744         }
   6745 
   6746         N = pkg.receivers.size();
   6747         r = null;
   6748         for (i=0; i<N; i++) {
   6749             PackageParser.Activity a = pkg.receivers.get(i);
   6750             mReceivers.removeActivity(a, "receiver");
   6751             if (DEBUG_REMOVE && chatty) {
   6752                 if (r == null) {
   6753                     r = new StringBuilder(256);
   6754                 } else {
   6755                     r.append(' ');
   6756                 }
   6757                 r.append(a.info.name);
   6758             }
   6759         }
   6760         if (r != null) {
   6761             if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
   6762         }
   6763 
   6764         N = pkg.activities.size();
   6765         r = null;
   6766         for (i=0; i<N; i++) {
   6767             PackageParser.Activity a = pkg.activities.get(i);
   6768             mActivities.removeActivity(a, "activity");
   6769             if (DEBUG_REMOVE && chatty) {
   6770                 if (r == null) {
   6771                     r = new StringBuilder(256);
   6772                 } else {
   6773                     r.append(' ');
   6774                 }
   6775                 r.append(a.info.name);
   6776             }
   6777         }
   6778         if (r != null) {
   6779             if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
   6780         }
   6781 
   6782         N = pkg.permissions.size();
   6783         r = null;
   6784         for (i=0; i<N; i++) {
   6785             PackageParser.Permission p = pkg.permissions.get(i);
   6786             BasePermission bp = mSettings.mPermissions.get(p.info.name);
   6787             if (bp == null) {
   6788                 bp = mSettings.mPermissionTrees.get(p.info.name);
   6789             }
   6790             if (bp != null && bp.perm == p) {
   6791                 bp.perm = null;
   6792                 if (DEBUG_REMOVE && chatty) {
   6793                     if (r == null) {
   6794                         r = new StringBuilder(256);
   6795                     } else {
   6796                         r.append(' ');
   6797                     }
   6798                     r.append(p.info.name);
   6799                 }
   6800             }
   6801             if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   6802                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name);
   6803                 if (appOpPerms != null) {
   6804                     appOpPerms.remove(pkg.packageName);
   6805                 }
   6806             }
   6807         }
   6808         if (r != null) {
   6809             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   6810         }
   6811 
   6812         N = pkg.requestedPermissions.size();
   6813         r = null;
   6814         for (i=0; i<N; i++) {
   6815             String perm = pkg.requestedPermissions.get(i);
   6816             BasePermission bp = mSettings.mPermissions.get(perm);
   6817             if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   6818                 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm);
   6819                 if (appOpPerms != null) {
   6820                     appOpPerms.remove(pkg.packageName);
   6821                     if (appOpPerms.isEmpty()) {
   6822                         mAppOpPermissionPackages.remove(perm);
   6823                     }
   6824                 }
   6825             }
   6826         }
   6827         if (r != null) {
   6828             if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
   6829         }
   6830 
   6831         N = pkg.instrumentation.size();
   6832         r = null;
   6833         for (i=0; i<N; i++) {
   6834             PackageParser.Instrumentation a = pkg.instrumentation.get(i);
   6835             mInstrumentation.remove(a.getComponentName());
   6836             if (DEBUG_REMOVE && chatty) {
   6837                 if (r == null) {
   6838                     r = new StringBuilder(256);
   6839                 } else {
   6840                     r.append(' ');
   6841                 }
   6842                 r.append(a.info.name);
   6843             }
   6844         }
   6845         if (r != null) {
   6846             if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
   6847         }
   6848 
   6849         r = null;
   6850         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
   6851             // Only system apps can hold shared libraries.
   6852             if (pkg.libraryNames != null) {
   6853                 for (i=0; i<pkg.libraryNames.size(); i++) {
   6854                     String name = pkg.libraryNames.get(i);
   6855                     SharedLibraryEntry cur = mSharedLibraries.get(name);
   6856                     if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) {
   6857                         mSharedLibraries.remove(name);
   6858                         if (DEBUG_REMOVE && chatty) {
   6859                             if (r == null) {
   6860                                 r = new StringBuilder(256);
   6861                             } else {
   6862                                 r.append(' ');
   6863                             }
   6864                             r.append(name);
   6865                         }
   6866                     }
   6867                 }
   6868             }
   6869         }
   6870         if (r != null) {
   6871             if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
   6872         }
   6873     }
   6874 
   6875     private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
   6876         for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
   6877             if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
   6878                 return true;
   6879             }
   6880         }
   6881         return false;
   6882     }
   6883 
   6884     static final int UPDATE_PERMISSIONS_ALL = 1<<0;
   6885     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
   6886     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
   6887 
   6888     private void updatePermissionsLPw(String changingPkg,
   6889             PackageParser.Package pkgInfo, int flags) {
   6890         // Make sure there are no dangling permission trees.
   6891         Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
   6892         while (it.hasNext()) {
   6893             final BasePermission bp = it.next();
   6894             if (bp.packageSetting == null) {
   6895                 // We may not yet have parsed the package, so just see if
   6896                 // we still know about its settings.
   6897                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   6898             }
   6899             if (bp.packageSetting == null) {
   6900                 Slog.w(TAG, "Removing dangling permission tree: " + bp.name
   6901                         + " from package " + bp.sourcePackage);
   6902                 it.remove();
   6903             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   6904                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   6905                     Slog.i(TAG, "Removing old permission tree: " + bp.name
   6906                             + " from package " + bp.sourcePackage);
   6907                     flags |= UPDATE_PERMISSIONS_ALL;
   6908                     it.remove();
   6909                 }
   6910             }
   6911         }
   6912 
   6913         // Make sure all dynamic permissions have been assigned to a package,
   6914         // and make sure there are no dangling permissions.
   6915         it = mSettings.mPermissions.values().iterator();
   6916         while (it.hasNext()) {
   6917             final BasePermission bp = it.next();
   6918             if (bp.type == BasePermission.TYPE_DYNAMIC) {
   6919                 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
   6920                         + bp.name + " pkg=" + bp.sourcePackage
   6921                         + " info=" + bp.pendingInfo);
   6922                 if (bp.packageSetting == null && bp.pendingInfo != null) {
   6923                     final BasePermission tree = findPermissionTreeLP(bp.name);
   6924                     if (tree != null && tree.perm != null) {
   6925                         bp.packageSetting = tree.packageSetting;
   6926                         bp.perm = new PackageParser.Permission(tree.perm.owner,
   6927                                 new PermissionInfo(bp.pendingInfo));
   6928                         bp.perm.info.packageName = tree.perm.info.packageName;
   6929                         bp.perm.info.name = bp.name;
   6930                         bp.uid = tree.uid;
   6931                     }
   6932                 }
   6933             }
   6934             if (bp.packageSetting == null) {
   6935                 // We may not yet have parsed the package, so just see if
   6936                 // we still know about its settings.
   6937                 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
   6938             }
   6939             if (bp.packageSetting == null) {
   6940                 Slog.w(TAG, "Removing dangling permission: " + bp.name
   6941                         + " from package " + bp.sourcePackage);
   6942                 it.remove();
   6943             } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
   6944                 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
   6945                     Slog.i(TAG, "Removing old permission: " + bp.name
   6946                             + " from package " + bp.sourcePackage);
   6947                     flags |= UPDATE_PERMISSIONS_ALL;
   6948                     it.remove();
   6949                 }
   6950             }
   6951         }
   6952 
   6953         // Now update the permissions for all packages, in particular
   6954         // replace the granted permissions of the system packages.
   6955         if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
   6956             for (PackageParser.Package pkg : mPackages.values()) {
   6957                 if (pkg != pkgInfo) {
   6958                     grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0,
   6959                             changingPkg);
   6960                 }
   6961             }
   6962         }
   6963 
   6964         if (pkgInfo != null) {
   6965             grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg);
   6966         }
   6967     }
   6968 
   6969     private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
   6970             String packageOfInterest) {
   6971         final PackageSetting ps = (PackageSetting) pkg.mExtras;
   6972         if (ps == null) {
   6973             return;
   6974         }
   6975         final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps;
   6976         HashSet<String> origPermissions = gp.grantedPermissions;
   6977         boolean changedPermission = false;
   6978 
   6979         if (replace) {
   6980             ps.permissionsFixed = false;
   6981             if (gp == ps) {
   6982                 origPermissions = new HashSet<String>(gp.grantedPermissions);
   6983                 gp.grantedPermissions.clear();
   6984                 gp.gids = mGlobalGids;
   6985             }
   6986         }
   6987 
   6988         if (gp.gids == null) {
   6989             gp.gids = mGlobalGids;
   6990         }
   6991 
   6992         final int N = pkg.requestedPermissions.size();
   6993         for (int i=0; i<N; i++) {
   6994             final String name = pkg.requestedPermissions.get(i);
   6995             final boolean required = pkg.requestedPermissionsRequired.get(i);
   6996             final BasePermission bp = mSettings.mPermissions.get(name);
   6997             if (DEBUG_INSTALL) {
   6998                 if (gp != ps) {
   6999                     Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
   7000                 }
   7001             }
   7002 
   7003             if (bp == null || bp.packageSetting == null) {
   7004                 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
   7005                     Slog.w(TAG, "Unknown permission " + name
   7006                             + " in package " + pkg.packageName);
   7007                 }
   7008                 continue;
   7009             }
   7010 
   7011             final String perm = bp.name;
   7012             boolean allowed;
   7013             boolean allowedSig = false;
   7014             if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
   7015                 // Keep track of app op permissions.
   7016                 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
   7017                 if (pkgs == null) {
   7018                     pkgs = new ArraySet<>();
   7019                     mAppOpPermissionPackages.put(bp.name, pkgs);
   7020                 }
   7021                 pkgs.add(pkg.packageName);
   7022             }
   7023             final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
   7024             if (level == PermissionInfo.PROTECTION_NORMAL
   7025                     || level == PermissionInfo.PROTECTION_DANGEROUS) {
   7026                 // We grant a normal or dangerous permission if any of the following
   7027                 // are true:
   7028                 // 1) The permission is required
   7029                 // 2) The permission is optional, but was granted in the past
   7030                 // 3) The permission is optional, but was requested by an
   7031                 //    app in /system (not /data)
   7032                 //
   7033                 // Otherwise, reject the permission.
   7034                 allowed = (required || origPermissions.contains(perm)
   7035                         || (isSystemApp(ps) && !isUpdatedSystemApp(ps)));
   7036             } else if (bp.packageSetting == null) {
   7037                 // This permission is invalid; skip it.
   7038                 allowed = false;
   7039             } else if (level == PermissionInfo.PROTECTION_SIGNATURE) {
   7040                 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions);
   7041                 if (allowed) {
   7042                     allowedSig = true;
   7043                 }
   7044             } else {
   7045                 allowed = false;
   7046             }
   7047             if (DEBUG_INSTALL) {
   7048                 if (gp != ps) {
   7049                     Log.i(TAG, "Package " + pkg.packageName + " granting " + perm);
   7050                 }
   7051             }
   7052             if (allowed) {
   7053                 if (!isSystemApp(ps) && ps.permissionsFixed) {
   7054                     // If this is an existing, non-system package, then
   7055                     // we can't add any new permissions to it.
   7056                     if (!allowedSig && !gp.grantedPermissions.contains(perm)) {
   7057                         // Except...  if this is a permission that was added
   7058                         // to the platform (note: need to only do this when
   7059                         // updating the platform).
   7060                         allowed = isNewPlatformPermissionForPackage(perm, pkg);
   7061                     }
   7062                 }
   7063                 if (allowed) {
   7064                     if (!gp.grantedPermissions.contains(perm)) {
   7065                         changedPermission = true;
   7066                         gp.grantedPermissions.add(perm);
   7067                         gp.gids = appendInts(gp.gids, bp.gids);
   7068                     } else if (!ps.haveGids) {
   7069                         gp.gids = appendInts(gp.gids, bp.gids);
   7070                     }
   7071                 } else {
   7072                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
   7073                         Slog.w(TAG, "Not granting permission " + perm
   7074                                 + " to package " + pkg.packageName
   7075                                 + " because it was previously installed without");
   7076                     }
   7077                 }
   7078             } else {
   7079                 if (gp.grantedPermissions.remove(perm)) {
   7080                     changedPermission = true;
   7081                     gp.gids = removeInts(gp.gids, bp.gids);
   7082                     Slog.i(TAG, "Un-granting permission " + perm
   7083                             + " from package " + pkg.packageName
   7084                             + " (protectionLevel=" + bp.protectionLevel
   7085                             + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   7086                             + ")");
   7087                 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
   7088                     // Don't print warning for app op permissions, since it is fine for them
   7089                     // not to be granted, there is a UI for the user to decide.
   7090                     if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
   7091                         Slog.w(TAG, "Not granting permission " + perm
   7092                                 + " to package " + pkg.packageName
   7093                                 + " (protectionLevel=" + bp.protectionLevel
   7094                                 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
   7095                                 + ")");
   7096                     }
   7097                 }
   7098             }
   7099         }
   7100 
   7101         if ((changedPermission || replace) && !ps.permissionsFixed &&
   7102                 !isSystemApp(ps) || isUpdatedSystemApp(ps)){
   7103             // This is the first that we have heard about this package, so the
   7104             // permissions we have now selected are fixed until explicitly
   7105             // changed.
   7106             ps.permissionsFixed = true;
   7107         }
   7108         ps.haveGids = true;
   7109     }
   7110 
   7111     private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
   7112         boolean allowed = false;
   7113         final int NP = PackageParser.NEW_PERMISSIONS.length;
   7114         for (int ip=0; ip<NP; ip++) {
   7115             final PackageParser.NewPermissionInfo npi
   7116                     = PackageParser.NEW_PERMISSIONS[ip];
   7117             if (npi.name.equals(perm)
   7118                     && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
   7119                 allowed = true;
   7120                 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
   7121                         + pkg.packageName);
   7122                 break;
   7123             }
   7124         }
   7125         return allowed;
   7126     }
   7127 
   7128     private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
   7129                                           BasePermission bp, HashSet<String> origPermissions) {
   7130         boolean allowed;
   7131         allowed = (compareSignatures(
   7132                 bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
   7133                         == PackageManager.SIGNATURE_MATCH)
   7134                 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
   7135                         == PackageManager.SIGNATURE_MATCH);
   7136         if (!allowed && (bp.protectionLevel
   7137                 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
   7138             if (isSystemApp(pkg)) {
   7139                 // For updated system applications, a system permission
   7140                 // is granted only if it had been defined by the original application.
   7141                 if (isUpdatedSystemApp(pkg)) {
   7142                     final PackageSetting sysPs = mSettings
   7143                             .getDisabledSystemPkgLPr(pkg.packageName);
   7144                     final GrantedPermissions origGp = sysPs.sharedUser != null
   7145                             ? sysPs.sharedUser : sysPs;
   7146 
   7147                     if (origGp.grantedPermissions.contains(perm)) {
   7148                         // If the original was granted this permission, we take
   7149                         // that grant decision as read and propagate it to the
   7150                         // update.
   7151                         allowed = true;
   7152                     } else {
   7153                         // The system apk may have been updated with an older
   7154                         // version of the one on the data partition, but which
   7155                         // granted a new system permission that it didn't have
   7156                         // before.  In this case we do want to allow the app to
   7157                         // now get the new permission if the ancestral apk is
   7158                         // privileged to get it.
   7159                         if (sysPs.pkg != null && sysPs.isPrivileged()) {
   7160                             for (int j=0;
   7161                                     j<sysPs.pkg.requestedPermissions.size(); j++) {
   7162                                 if (perm.equals(
   7163                                         sysPs.pkg.requestedPermissions.get(j))) {
   7164                                     allowed = true;
   7165                                     break;
   7166                                 }
   7167                             }
   7168                         }
   7169                     }
   7170                 } else {
   7171                     allowed = isPrivilegedApp(pkg);
   7172                 }
   7173             }
   7174         }
   7175         if (!allowed && (bp.protectionLevel
   7176                 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
   7177             // For development permissions, a development permission
   7178             // is granted only if it was already granted.
   7179             allowed = origPermissions.contains(perm);
   7180         }
   7181         return allowed;
   7182     }
   7183 
   7184     final class ActivityIntentResolver
   7185             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
   7186         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   7187                 boolean defaultOnly, int userId) {
   7188             if (!sUserManager.exists(userId)) return null;
   7189             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   7190             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   7191         }
   7192 
   7193         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   7194                 int userId) {
   7195             if (!sUserManager.exists(userId)) return null;
   7196             mFlags = flags;
   7197             return super.queryIntent(intent, resolvedType,
   7198                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   7199         }
   7200 
   7201         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   7202                 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
   7203             if (!sUserManager.exists(userId)) return null;
   7204             if (packageActivities == null) {
   7205                 return null;
   7206             }
   7207             mFlags = flags;
   7208             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   7209             final int N = packageActivities.size();
   7210             ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
   7211                 new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
   7212 
   7213             ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
   7214             for (int i = 0; i < N; ++i) {
   7215                 intentFilters = packageActivities.get(i).intents;
   7216                 if (intentFilters != null && intentFilters.size() > 0) {
   7217                     PackageParser.ActivityIntentInfo[] array =
   7218                             new PackageParser.ActivityIntentInfo[intentFilters.size()];
   7219                     intentFilters.toArray(array);
   7220                     listCut.add(array);
   7221                 }
   7222             }
   7223             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   7224         }
   7225 
   7226         public final void addActivity(PackageParser.Activity a, String type) {
   7227             final boolean systemApp = isSystemApp(a.info.applicationInfo);
   7228             mActivities.put(a.getComponentName(), a);
   7229             if (DEBUG_SHOW_INFO)
   7230                 Log.v(
   7231                 TAG, "  " + type + " " +
   7232                 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
   7233             if (DEBUG_SHOW_INFO)
   7234                 Log.v(TAG, "    Class=" + a.info.name);
   7235             final int NI = a.intents.size();
   7236             for (int j=0; j<NI; j++) {
   7237                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   7238                 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) {
   7239                     intent.setPriority(0);
   7240                     Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity "
   7241                             + a.className + " with priority > 0, forcing to 0");
   7242                 }
   7243                 if (DEBUG_SHOW_INFO) {
   7244                     Log.v(TAG, "    IntentFilter:");
   7245                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7246                 }
   7247                 if (!intent.debugCheck()) {
   7248                     Log.w(TAG, "==> For Activity " + a.info.name);
   7249                 }
   7250                 addFilter(intent);
   7251             }
   7252         }
   7253 
   7254         public final void removeActivity(PackageParser.Activity a, String type) {
   7255             mActivities.remove(a.getComponentName());
   7256             if (DEBUG_SHOW_INFO) {
   7257                 Log.v(TAG, "  " + type + " "
   7258                         + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
   7259                                 : a.info.name) + ":");
   7260                 Log.v(TAG, "    Class=" + a.info.name);
   7261             }
   7262             final int NI = a.intents.size();
   7263             for (int j=0; j<NI; j++) {
   7264                 PackageParser.ActivityIntentInfo intent = a.intents.get(j);
   7265                 if (DEBUG_SHOW_INFO) {
   7266                     Log.v(TAG, "    IntentFilter:");
   7267                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7268                 }
   7269                 removeFilter(intent);
   7270             }
   7271         }
   7272 
   7273         @Override
   7274         protected boolean allowFilterResult(
   7275                 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
   7276             ActivityInfo filterAi = filter.activity.info;
   7277             for (int i=dest.size()-1; i>=0; i--) {
   7278                 ActivityInfo destAi = dest.get(i).activityInfo;
   7279                 if (destAi.name == filterAi.name
   7280                         && destAi.packageName == filterAi.packageName) {
   7281                     return false;
   7282                 }
   7283             }
   7284             return true;
   7285         }
   7286 
   7287         @Override
   7288         protected ActivityIntentInfo[] newArray(int size) {
   7289             return new ActivityIntentInfo[size];
   7290         }
   7291 
   7292         @Override
   7293         protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
   7294             if (!sUserManager.exists(userId)) return true;
   7295             PackageParser.Package p = filter.activity.owner;
   7296             if (p != null) {
   7297                 PackageSetting ps = (PackageSetting)p.mExtras;
   7298                 if (ps != null) {
   7299                     // System apps are never considered stopped for purposes of
   7300                     // filtering, because there may be no way for the user to
   7301                     // actually re-launch them.
   7302                     return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
   7303                             && ps.getStopped(userId);
   7304                 }
   7305             }
   7306             return false;
   7307         }
   7308 
   7309         @Override
   7310         protected boolean isPackageForFilter(String packageName,
   7311                 PackageParser.ActivityIntentInfo info) {
   7312             return packageName.equals(info.activity.owner.packageName);
   7313         }
   7314 
   7315         @Override
   7316         protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
   7317                 int match, int userId) {
   7318             if (!sUserManager.exists(userId)) return null;
   7319             if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) {
   7320                 return null;
   7321             }
   7322             final PackageParser.Activity activity = info.activity;
   7323             if (mSafeMode && (activity.info.applicationInfo.flags
   7324                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   7325                 return null;
   7326             }
   7327             PackageSetting ps = (PackageSetting) activity.owner.mExtras;
   7328             if (ps == null) {
   7329                 return null;
   7330             }
   7331             ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
   7332                     ps.readUserState(userId), userId);
   7333             if (ai == null) {
   7334                 return null;
   7335             }
   7336             final ResolveInfo res = new ResolveInfo();
   7337             res.activityInfo = ai;
   7338             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   7339                 res.filter = info;
   7340             }
   7341             res.priority = info.getPriority();
   7342             res.preferredOrder = activity.owner.mPreferredOrder;
   7343             //System.out.println("Result: " + res.activityInfo.className +
   7344             //                   " = " + res.priority);
   7345             res.match = match;
   7346             res.isDefault = info.hasDefault;
   7347             res.labelRes = info.labelRes;
   7348             res.nonLocalizedLabel = info.nonLocalizedLabel;
   7349             if (userNeedsBadging(userId)) {
   7350                 res.noResourceId = true;
   7351             } else {
   7352                 res.icon = info.icon;
   7353             }
   7354             res.system = isSystemApp(res.activityInfo.applicationInfo);
   7355             return res;
   7356         }
   7357 
   7358         @Override
   7359         protected void sortResults(List<ResolveInfo> results) {
   7360             Collections.sort(results, mResolvePrioritySorter);
   7361         }
   7362 
   7363         @Override
   7364         protected void dumpFilter(PrintWriter out, String prefix,
   7365                 PackageParser.ActivityIntentInfo filter) {
   7366             out.print(prefix); out.print(
   7367                     Integer.toHexString(System.identityHashCode(filter.activity)));
   7368                     out.print(' ');
   7369                     filter.activity.printComponentShortName(out);
   7370                     out.print(" filter ");
   7371                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   7372         }
   7373 
   7374 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   7375 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   7376 //            final List<ResolveInfo> retList = Lists.newArrayList();
   7377 //            while (i.hasNext()) {
   7378 //                final ResolveInfo resolveInfo = i.next();
   7379 //                if (isEnabledLP(resolveInfo.activityInfo)) {
   7380 //                    retList.add(resolveInfo);
   7381 //                }
   7382 //            }
   7383 //            return retList;
   7384 //        }
   7385 
   7386         // Keys are String (activity class name), values are Activity.
   7387         private final HashMap<ComponentName, PackageParser.Activity> mActivities
   7388                 = new HashMap<ComponentName, PackageParser.Activity>();
   7389         private int mFlags;
   7390     }
   7391 
   7392     private final class ServiceIntentResolver
   7393             extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
   7394         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   7395                 boolean defaultOnly, int userId) {
   7396             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   7397             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   7398         }
   7399 
   7400         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   7401                 int userId) {
   7402             if (!sUserManager.exists(userId)) return null;
   7403             mFlags = flags;
   7404             return super.queryIntent(intent, resolvedType,
   7405                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   7406         }
   7407 
   7408         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   7409                 int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
   7410             if (!sUserManager.exists(userId)) return null;
   7411             if (packageServices == null) {
   7412                 return null;
   7413             }
   7414             mFlags = flags;
   7415             final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
   7416             final int N = packageServices.size();
   7417             ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
   7418                 new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
   7419 
   7420             ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
   7421             for (int i = 0; i < N; ++i) {
   7422                 intentFilters = packageServices.get(i).intents;
   7423                 if (intentFilters != null && intentFilters.size() > 0) {
   7424                     PackageParser.ServiceIntentInfo[] array =
   7425                             new PackageParser.ServiceIntentInfo[intentFilters.size()];
   7426                     intentFilters.toArray(array);
   7427                     listCut.add(array);
   7428                 }
   7429             }
   7430             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   7431         }
   7432 
   7433         public final void addService(PackageParser.Service s) {
   7434             mServices.put(s.getComponentName(), s);
   7435             if (DEBUG_SHOW_INFO) {
   7436                 Log.v(TAG, "  "
   7437                         + (s.info.nonLocalizedLabel != null
   7438                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   7439                 Log.v(TAG, "    Class=" + s.info.name);
   7440             }
   7441             final int NI = s.intents.size();
   7442             int j;
   7443             for (j=0; j<NI; j++) {
   7444                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   7445                 if (DEBUG_SHOW_INFO) {
   7446                     Log.v(TAG, "    IntentFilter:");
   7447                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7448                 }
   7449                 if (!intent.debugCheck()) {
   7450                     Log.w(TAG, "==> For Service " + s.info.name);
   7451                 }
   7452                 addFilter(intent);
   7453             }
   7454         }
   7455 
   7456         public final void removeService(PackageParser.Service s) {
   7457             mServices.remove(s.getComponentName());
   7458             if (DEBUG_SHOW_INFO) {
   7459                 Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
   7460                         ? s.info.nonLocalizedLabel : s.info.name) + ":");
   7461                 Log.v(TAG, "    Class=" + s.info.name);
   7462             }
   7463             final int NI = s.intents.size();
   7464             int j;
   7465             for (j=0; j<NI; j++) {
   7466                 PackageParser.ServiceIntentInfo intent = s.intents.get(j);
   7467                 if (DEBUG_SHOW_INFO) {
   7468                     Log.v(TAG, "    IntentFilter:");
   7469                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7470                 }
   7471                 removeFilter(intent);
   7472             }
   7473         }
   7474 
   7475         @Override
   7476         protected boolean allowFilterResult(
   7477                 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
   7478             ServiceInfo filterSi = filter.service.info;
   7479             for (int i=dest.size()-1; i>=0; i--) {
   7480                 ServiceInfo destAi = dest.get(i).serviceInfo;
   7481                 if (destAi.name == filterSi.name
   7482                         && destAi.packageName == filterSi.packageName) {
   7483                     return false;
   7484                 }
   7485             }
   7486             return true;
   7487         }
   7488 
   7489         @Override
   7490         protected PackageParser.ServiceIntentInfo[] newArray(int size) {
   7491             return new PackageParser.ServiceIntentInfo[size];
   7492         }
   7493 
   7494         @Override
   7495         protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
   7496             if (!sUserManager.exists(userId)) return true;
   7497             PackageParser.Package p = filter.service.owner;
   7498             if (p != null) {
   7499                 PackageSetting ps = (PackageSetting)p.mExtras;
   7500                 if (ps != null) {
   7501                     // System apps are never considered stopped for purposes of
   7502                     // filtering, because there may be no way for the user to
   7503                     // actually re-launch them.
   7504                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
   7505                             && ps.getStopped(userId);
   7506                 }
   7507             }
   7508             return false;
   7509         }
   7510 
   7511         @Override
   7512         protected boolean isPackageForFilter(String packageName,
   7513                 PackageParser.ServiceIntentInfo info) {
   7514             return packageName.equals(info.service.owner.packageName);
   7515         }
   7516 
   7517         @Override
   7518         protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
   7519                 int match, int userId) {
   7520             if (!sUserManager.exists(userId)) return null;
   7521             final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
   7522             if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) {
   7523                 return null;
   7524             }
   7525             final PackageParser.Service service = info.service;
   7526             if (mSafeMode && (service.info.applicationInfo.flags
   7527                     &ApplicationInfo.FLAG_SYSTEM) == 0) {
   7528                 return null;
   7529             }
   7530             PackageSetting ps = (PackageSetting) service.owner.mExtras;
   7531             if (ps == null) {
   7532                 return null;
   7533             }
   7534             ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
   7535                     ps.readUserState(userId), userId);
   7536             if (si == null) {
   7537                 return null;
   7538             }
   7539             final ResolveInfo res = new ResolveInfo();
   7540             res.serviceInfo = si;
   7541             if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
   7542                 res.filter = filter;
   7543             }
   7544             res.priority = info.getPriority();
   7545             res.preferredOrder = service.owner.mPreferredOrder;
   7546             //System.out.println("Result: " + res.activityInfo.className +
   7547             //                   " = " + res.priority);
   7548             res.match = match;
   7549             res.isDefault = info.hasDefault;
   7550             res.labelRes = info.labelRes;
   7551             res.nonLocalizedLabel = info.nonLocalizedLabel;
   7552             res.icon = info.icon;
   7553             res.system = isSystemApp(res.serviceInfo.applicationInfo);
   7554             return res;
   7555         }
   7556 
   7557         @Override
   7558         protected void sortResults(List<ResolveInfo> results) {
   7559             Collections.sort(results, mResolvePrioritySorter);
   7560         }
   7561 
   7562         @Override
   7563         protected void dumpFilter(PrintWriter out, String prefix,
   7564                 PackageParser.ServiceIntentInfo filter) {
   7565             out.print(prefix); out.print(
   7566                     Integer.toHexString(System.identityHashCode(filter.service)));
   7567                     out.print(' ');
   7568                     filter.service.printComponentShortName(out);
   7569                     out.print(" filter ");
   7570                     out.println(Integer.toHexString(System.identityHashCode(filter)));
   7571         }
   7572 
   7573 //        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
   7574 //            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
   7575 //            final List<ResolveInfo> retList = Lists.newArrayList();
   7576 //            while (i.hasNext()) {
   7577 //                final ResolveInfo resolveInfo = (ResolveInfo) i;
   7578 //                if (isEnabledLP(resolveInfo.serviceInfo)) {
   7579 //                    retList.add(resolveInfo);
   7580 //                }
   7581 //            }
   7582 //            return retList;
   7583 //        }
   7584 
   7585         // Keys are String (activity class name), values are Activity.
   7586         private final HashMap<ComponentName, PackageParser.Service> mServices
   7587                 = new HashMap<ComponentName, PackageParser.Service>();
   7588         private int mFlags;
   7589     };
   7590 
   7591     private final class ProviderIntentResolver
   7592             extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
   7593         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
   7594                 boolean defaultOnly, int userId) {
   7595             mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
   7596             return super.queryIntent(intent, resolvedType, defaultOnly, userId);
   7597         }
   7598 
   7599         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
   7600                 int userId) {
   7601             if (!sUserManager.exists(userId))
   7602                 return null;
   7603             mFlags = flags;
   7604             return super.queryIntent(intent, resolvedType,
   7605                     (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
   7606         }
   7607 
   7608         public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
   7609                 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
   7610             if (!sUserManager.exists(userId))
   7611                 return null;
   7612             if (packageProviders == null) {
   7613                 return null;
   7614             }
   7615             mFlags = flags;
   7616             final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
   7617             final int N = packageProviders.size();
   7618             ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
   7619                     new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
   7620 
   7621             ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
   7622             for (int i = 0; i < N; ++i) {
   7623                 intentFilters = packageProviders.get(i).intents;
   7624                 if (intentFilters != null && intentFilters.size() > 0) {
   7625                     PackageParser.ProviderIntentInfo[] array =
   7626                             new PackageParser.ProviderIntentInfo[intentFilters.size()];
   7627                     intentFilters.toArray(array);
   7628                     listCut.add(array);
   7629                 }
   7630             }
   7631             return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
   7632         }
   7633 
   7634         public final void addProvider(PackageParser.Provider p) {
   7635             if (mProviders.containsKey(p.getComponentName())) {
   7636                 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
   7637                 return;
   7638             }
   7639 
   7640             mProviders.put(p.getComponentName(), p);
   7641             if (DEBUG_SHOW_INFO) {
   7642                 Log.v(TAG, "  "
   7643                         + (p.info.nonLocalizedLabel != null
   7644                                 ? p.info.nonLocalizedLabel : p.info.name) + ":");
   7645                 Log.v(TAG, "    Class=" + p.info.name);
   7646             }
   7647             final int NI = p.intents.size();
   7648             int j;
   7649             for (j = 0; j < NI; j++) {
   7650                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
   7651                 if (DEBUG_SHOW_INFO) {
   7652                     Log.v(TAG, "    IntentFilter:");
   7653                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7654                 }
   7655                 if (!intent.debugCheck()) {
   7656                     Log.w(TAG, "==> For Provider " + p.info.name);
   7657                 }
   7658                 addFilter(intent);
   7659             }
   7660         }
   7661 
   7662         public final void removeProvider(PackageParser.Provider p) {
   7663             mProviders.remove(p.getComponentName());
   7664             if (DEBUG_SHOW_INFO) {
   7665                 Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
   7666                         ? p.info.nonLocalizedLabel : p.info.name) + ":");
   7667                 Log.v(TAG, "    Class=" + p.info.name);
   7668             }
   7669             final int NI = p.intents.size();
   7670             int j;
   7671             for (j = 0; j < NI; j++) {
   7672                 PackageParser.ProviderIntentInfo intent = p.intents.get(j);
   7673                 if (DEBUG_SHOW_INFO) {
   7674                     Log.v(TAG, "    IntentFilter:");
   7675                     intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
   7676                 }
   7677                 removeFilter(intent);
   7678             }
   7679         }
   7680 
   7681         @Override
   7682         protected boolean allowFilterResult(
   7683                 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
   7684             ProviderInfo filterPi = filter.provider.info;
   7685             for (int i = dest.size() - 1; i >= 0; i--) {
   7686                 ProviderInfo destPi = dest.get(i).providerInfo;
   7687                 if (destPi.name == filterPi.name
   7688                         && destPi.packageName == filterPi.packageName) {
   7689                     return false;
   7690                 }
   7691             }
   7692             return true;
   7693         }
   7694 
   7695         @Override
   7696         protected PackageParser.ProviderIntentInfo[] newArray(int size) {
   7697             return new PackageParser.ProviderIntentInfo[size];
   7698         }
   7699 
   7700         @Override
   7701         protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
   7702             if (!sUserManager.exists(userId))
   7703                 return true;
   7704             PackageParser.Package p = filter.provider.owner;
   7705             if (p != null) {
   7706                 PackageSetting ps = (PackageSetting) p.mExtras;
   7707                 if (ps != null) {
   7708                     // System apps are never considered stopped for purposes of
   7709                     // filtering, because there may be no way for the user to
   7710                     // actually re-launch them.
   7711                     return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
   7712                             && ps.getStopped(userId);
   7713                 }
   7714             }
   7715             return false;
   7716         }
   7717 
   7718         @Override
   7719         protected boolean isPackageForFilter(String packageName,
   7720                 PackageParser.ProviderIntentInfo info) {
   7721             return packageName.equals(info.provider.owner.packageName);
   7722         }
   7723 
   7724         @Override
   7725         protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
   7726                 int match, int userId) {
   7727             if (!sUserManager.exists(userId))
   7728                 return null;
   7729             final PackageParser.ProviderIntentInfo info = filter;
   7730             if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) {
   7731                 return null;
   7732             }
   7733             final PackageParser.Provider provider = info.provider;
   7734             if (mSafeMode && (provider.info.applicationInfo.flags
   7735                     & ApplicationInfo.FLAG_SYSTEM) == 0) {
   7736                 return null;
   7737             }
   7738             PackageSetting ps = (PackageSetting) provider.owner.mExtras;
   7739             if (ps == null) {
   7740                 return null;
   7741             }
   7742             ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
   7743                     ps.readUserState(userId), userId);
   7744             if (pi == null) {
   7745                 return null;
   7746             }
   7747             final ResolveInfo res = new ResolveInfo();
   7748             res.providerInfo = pi;
   7749             if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
   7750                 res.filter = filter;
   7751             }
   7752             res.priority = info.getPriority();
   7753             res.preferredOrder = provider.owner.mPreferredOrder;
   7754             res.match = match;
   7755             res.isDefault = info.hasDefault;
   7756             res.labelRes = info.labelRes;
   7757             res.nonLocalizedLabel = info.nonLocalizedLabel;
   7758             res.icon = info.icon;
   7759             res.system = isSystemApp(res.providerInfo.applicationInfo);
   7760             return res;
   7761         }
   7762 
   7763         @Override
   7764         protected void sortResults(List<ResolveInfo> results) {
   7765             Collections.sort(results, mResolvePrioritySorter);
   7766         }
   7767 
   7768         @Override
   7769         protected void dumpFilter(PrintWriter out, String prefix,
   7770                 PackageParser.ProviderIntentInfo filter) {
   7771             out.print(prefix);
   7772             out.print(
   7773                     Integer.toHexString(System.identityHashCode(filter.provider)));
   7774             out.print(' ');
   7775             filter.provider.printComponentShortName(out);
   7776             out.print(" filter ");
   7777             out.println(Integer.toHexString(System.identityHashCode(filter)));
   7778         }
   7779 
   7780         private final HashMap<ComponentName, PackageParser.Provider> mProviders
   7781                 = new HashMap<ComponentName, PackageParser.Provider>();
   7782         private int mFlags;
   7783     };
   7784 
   7785     private static final Comparator<ResolveInfo> mResolvePrioritySorter =
   7786             new Comparator<ResolveInfo>() {
   7787         public int compare(ResolveInfo r1, ResolveInfo r2) {
   7788             int v1 = r1.priority;
   7789             int v2 = r2.priority;
   7790             //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
   7791             if (v1 != v2) {
   7792                 return (v1 > v2) ? -1 : 1;
   7793             }
   7794             v1 = r1.preferredOrder;
   7795             v2 = r2.preferredOrder;
   7796             if (v1 != v2) {
   7797                 return (v1 > v2) ? -1 : 1;
   7798             }
   7799             if (r1.isDefault != r2.isDefault) {
   7800                 return r1.isDefault ? -1 : 1;
   7801             }
   7802             v1 = r1.match;
   7803             v2 = r2.match;
   7804             //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
   7805             if (v1 != v2) {
   7806                 return (v1 > v2) ? -1 : 1;
   7807             }
   7808             if (r1.system != r2.system) {
   7809                 return r1.system ? -1 : 1;
   7810             }
   7811             return 0;
   7812         }
   7813     };
   7814 
   7815     private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
   7816             new Comparator<ProviderInfo>() {
   7817         public int compare(ProviderInfo p1, ProviderInfo p2) {
   7818             final int v1 = p1.initOrder;
   7819             final int v2 = p2.initOrder;
   7820             return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
   7821         }
   7822     };
   7823 
   7824     static final void sendPackageBroadcast(String action, String pkg,
   7825             Bundle extras, String targetPkg, IIntentReceiver finishedReceiver,
   7826             int[] userIds) {
   7827         IActivityManager am = ActivityManagerNative.getDefault();
   7828         if (am != null) {
   7829             try {
   7830                 if (userIds == null) {
   7831                     userIds = am.getRunningUserIds();
   7832                 }
   7833                 for (int id : userIds) {
   7834                     final Intent intent = new Intent(action,
   7835                             pkg != null ? Uri.fromParts("package", pkg, null) : null);
   7836                     if (extras != null) {
   7837                         intent.putExtras(extras);
   7838                     }
   7839                     if (targetPkg != null) {
   7840                         intent.setPackage(targetPkg);
   7841                     }
   7842                     // Modify the UID when posting to other users
   7843                     int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
   7844                     if (uid > 0 && UserHandle.getUserId(uid) != id) {
   7845                         uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
   7846                         intent.putExtra(Intent.EXTRA_UID, uid);
   7847                     }
   7848                     intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
   7849                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
   7850                     if (DEBUG_BROADCASTS) {
   7851                         RuntimeException here = new RuntimeException("here");
   7852                         here.fillInStackTrace();
   7853                         Slog.d(TAG, "Sending to user " + id + ": "
   7854                                 + intent.toShortString(false, true, false, false)
   7855                                 + " " + intent.getExtras(), here);
   7856                     }
   7857                     am.broadcastIntent(null, intent, null, finishedReceiver,
   7858                             0, null, null, null, android.app.AppOpsManager.OP_NONE,
   7859                             finishedReceiver != null, false, id);
   7860                 }
   7861             } catch (RemoteException ex) {
   7862             }
   7863         }
   7864     }
   7865 
   7866     /**
   7867      * Check if the external storage media is available. This is true if there
   7868      * is a mounted external storage medium or if the external storage is
   7869      * emulated.
   7870      */
   7871     private boolean isExternalMediaAvailable() {
   7872         return mMediaMounted || Environment.isExternalStorageEmulated();
   7873     }
   7874 
   7875     @Override
   7876     public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
   7877         // writer
   7878         synchronized (mPackages) {
   7879             if (!isExternalMediaAvailable()) {
   7880                 // If the external storage is no longer mounted at this point,
   7881                 // the caller may not have been able to delete all of this
   7882                 // packages files and can not delete any more.  Bail.
   7883                 return null;
   7884             }
   7885             final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
   7886             if (lastPackage != null) {
   7887                 pkgs.remove(lastPackage);
   7888             }
   7889             if (pkgs.size() > 0) {
   7890                 return pkgs.get(0);
   7891             }
   7892         }
   7893         return null;
   7894     }
   7895 
   7896     void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
   7897         final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
   7898                 userId, andCode ? 1 : 0, packageName);
   7899         if (mSystemReady) {
   7900             msg.sendToTarget();
   7901         } else {
   7902             if (mPostSystemReadyMessages == null) {
   7903                 mPostSystemReadyMessages = new ArrayList<>();
   7904             }
   7905             mPostSystemReadyMessages.add(msg);
   7906         }
   7907     }
   7908 
   7909     void startCleaningPackages() {
   7910         // reader
   7911         synchronized (mPackages) {
   7912             if (!isExternalMediaAvailable()) {
   7913                 return;
   7914             }
   7915             if (mSettings.mPackagesToBeCleaned.isEmpty()) {
   7916                 return;
   7917             }
   7918         }
   7919         Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
   7920         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
   7921         IActivityManager am = ActivityManagerNative.getDefault();
   7922         if (am != null) {
   7923             try {
   7924                 am.startService(null, intent, null, UserHandle.USER_OWNER);
   7925             } catch (RemoteException e) {
   7926             }
   7927         }
   7928     }
   7929 
   7930     @Override
   7931     public void installPackage(String originPath, IPackageInstallObserver2 observer,
   7932             int installFlags, String installerPackageName, VerificationParams verificationParams,
   7933             String packageAbiOverride) {
   7934         installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams,
   7935                 packageAbiOverride, UserHandle.getCallingUserId());
   7936     }
   7937 
   7938     @Override
   7939     public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
   7940             int installFlags, String installerPackageName, VerificationParams verificationParams,
   7941             String packageAbiOverride, int userId) {
   7942         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
   7943 
   7944         final int callingUid = Binder.getCallingUid();
   7945         enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser");
   7946 
   7947         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
   7948             try {
   7949                 if (observer != null) {
   7950                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
   7951                 }
   7952             } catch (RemoteException re) {
   7953             }
   7954             return;
   7955         }
   7956 
   7957         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
   7958             installFlags |= PackageManager.INSTALL_FROM_ADB;
   7959 
   7960         } else {
   7961             // Caller holds INSTALL_PACKAGES permission, so we're less strict
   7962             // about installerPackageName.
   7963 
   7964             installFlags &= ~PackageManager.INSTALL_FROM_ADB;
   7965             installFlags &= ~PackageManager.INSTALL_ALL_USERS;
   7966         }
   7967 
   7968         UserHandle user;
   7969         if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
   7970             user = UserHandle.ALL;
   7971         } else {
   7972             user = new UserHandle(userId);
   7973         }
   7974 
   7975         verificationParams.setInstallerUid(callingUid);
   7976 
   7977         final File originFile = new File(originPath);
   7978         final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
   7979 
   7980         final Message msg = mHandler.obtainMessage(INIT_COPY);
   7981         msg.obj = new InstallParams(origin, observer, installFlags,
   7982                 installerPackageName, verificationParams, user, packageAbiOverride);
   7983         mHandler.sendMessage(msg);
   7984     }
   7985 
   7986     void installStage(String packageName, File stagedDir, String stagedCid,
   7987             IPackageInstallObserver2 observer, PackageInstaller.SessionParams params,
   7988             String installerPackageName, int installerUid, UserHandle user) {
   7989         final VerificationParams verifParams = new VerificationParams(null, params.originatingUri,
   7990                 params.referrerUri, installerUid, null);
   7991 
   7992         final OriginInfo origin;
   7993         if (stagedDir != null) {
   7994             origin = OriginInfo.fromStagedFile(stagedDir);
   7995         } else {
   7996             origin = OriginInfo.fromStagedContainer(stagedCid);
   7997         }
   7998 
   7999         final Message msg = mHandler.obtainMessage(INIT_COPY);
   8000         msg.obj = new InstallParams(origin, observer, params.installFlags,
   8001                 installerPackageName, verifParams, user, params.abiOverride);
   8002         mHandler.sendMessage(msg);
   8003     }
   8004 
   8005     private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
   8006         Bundle extras = new Bundle(1);
   8007         extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
   8008 
   8009         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
   8010                 packageName, extras, null, null, new int[] {userId});
   8011         try {
   8012             IActivityManager am = ActivityManagerNative.getDefault();
   8013             final boolean isSystem =
   8014                     isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
   8015             if (isSystem && am.isUserRunning(userId, false)) {
   8016                 // The just-installed/enabled app is bundled on the system, so presumed
   8017                 // to be able to run automatically without needing an explicit launch.
   8018                 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one.
   8019                 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED)
   8020                         .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
   8021                         .setPackage(packageName);
   8022                 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null,
   8023                         android.app.AppOpsManager.OP_NONE, false, false, userId);
   8024             }
   8025         } catch (RemoteException e) {
   8026             // shouldn't happen
   8027             Slog.w(TAG, "Unable to bootstrap installed package", e);
   8028         }
   8029     }
   8030 
   8031     @Override
   8032     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
   8033             int userId) {
   8034         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
   8035         PackageSetting pkgSetting;
   8036         final int uid = Binder.getCallingUid();
   8037         enforceCrossUserPermission(uid, userId, true, true,
   8038                 "setApplicationHiddenSetting for user " + userId);
   8039 
   8040         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
   8041             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
   8042             return false;
   8043         }
   8044 
   8045         long callingId = Binder.clearCallingIdentity();
   8046         try {
   8047             boolean sendAdded = false;
   8048             boolean sendRemoved = false;
   8049             // writer
   8050             synchronized (mPackages) {
   8051                 pkgSetting = mSettings.mPackages.get(packageName);
   8052                 if (pkgSetting == null) {
   8053                     return false;
   8054                 }
   8055                 if (pkgSetting.getHidden(userId) != hidden) {
   8056                     pkgSetting.setHidden(hidden, userId);
   8057                     mSettings.writePackageRestrictionsLPr(userId);
   8058                     if (hidden) {
   8059                         sendRemoved = true;
   8060                     } else {
   8061                         sendAdded = true;
   8062                     }
   8063                 }
   8064             }
   8065             if (sendAdded) {
   8066                 sendPackageAddedForUser(packageName, pkgSetting, userId);
   8067                 return true;
   8068             }
   8069             if (sendRemoved) {
   8070                 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
   8071                         "hiding pkg");
   8072                 sendApplicationHiddenForUser(packageName, pkgSetting, userId);
   8073             }
   8074         } finally {
   8075             Binder.restoreCallingIdentity(callingId);
   8076         }
   8077         return false;
   8078     }
   8079 
   8080     private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
   8081             int userId) {
   8082         final PackageRemovedInfo info = new PackageRemovedInfo();
   8083         info.removedPackage = packageName;
   8084         info.removedUsers = new int[] {userId};
   8085         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
   8086         info.sendBroadcast(false, false, false);
   8087     }
   8088 
   8089     /**
   8090      * Returns true if application is not found or there was an error. Otherwise it returns
   8091      * the hidden state of the package for the given user.
   8092      */
   8093     @Override
   8094     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
   8095         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
   8096         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
   8097                 false, "getApplicationHidden for user " + userId);
   8098         PackageSetting pkgSetting;
   8099         long callingId = Binder.clearCallingIdentity();
   8100         try {
   8101             // writer
   8102             synchronized (mPackages) {
   8103                 pkgSetting = mSettings.mPackages.get(packageName);
   8104                 if (pkgSetting == null) {
   8105                     return true;
   8106                 }
   8107                 return pkgSetting.getHidden(userId);
   8108             }
   8109         } finally {
   8110             Binder.restoreCallingIdentity(callingId);
   8111         }
   8112     }
   8113 
   8114     /**
   8115      * @hide
   8116      */
   8117     @Override
   8118     public int installExistingPackageAsUser(String packageName, int userId) {
   8119         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
   8120                 null);
   8121         PackageSetting pkgSetting;
   8122         final int uid = Binder.getCallingUid();
   8123         enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
   8124                 + userId);
   8125         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
   8126             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
   8127         }
   8128 
   8129         long callingId = Binder.clearCallingIdentity();
   8130         try {
   8131             boolean sendAdded = false;
   8132             Bundle extras = new Bundle(1);
   8133 
   8134             // writer
   8135             synchronized (mPackages) {
   8136                 pkgSetting = mSettings.mPackages.get(packageName);
   8137                 if (pkgSetting == null) {
   8138                     return PackageManager.INSTALL_FAILED_INVALID_URI;
   8139                 }
   8140                 if (!pkgSetting.getInstalled(userId)) {
   8141                     pkgSetting.setInstalled(true, userId);
   8142                     pkgSetting.setHidden(false, userId);
   8143                     mSettings.writePackageRestrictionsLPr(userId);
   8144                     sendAdded = true;
   8145                 }
   8146             }
   8147 
   8148             if (sendAdded) {
   8149                 sendPackageAddedForUser(packageName, pkgSetting, userId);
   8150             }
   8151         } finally {
   8152             Binder.restoreCallingIdentity(callingId);
   8153         }
   8154 
   8155         return PackageManager.INSTALL_SUCCEEDED;
   8156     }
   8157 
   8158     boolean isUserRestricted(int userId, String restrictionKey) {
   8159         Bundle restrictions = sUserManager.getUserRestrictions(userId);
   8160         if (restrictions.getBoolean(restrictionKey, false)) {
   8161             Log.w(TAG, "User is restricted: " + restrictionKey);
   8162             return true;
   8163         }
   8164         return false;
   8165     }
   8166 
   8167     @Override
   8168     public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
   8169         mContext.enforceCallingOrSelfPermission(
   8170                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   8171                 "Only package verification agents can verify applications");
   8172 
   8173         final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
   8174         final PackageVerificationResponse response = new PackageVerificationResponse(
   8175                 verificationCode, Binder.getCallingUid());
   8176         msg.arg1 = id;
   8177         msg.obj = response;
   8178         mHandler.sendMessage(msg);
   8179     }
   8180 
   8181     @Override
   8182     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
   8183             long millisecondsToDelay) {
   8184         mContext.enforceCallingOrSelfPermission(
   8185                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   8186                 "Only package verification agents can extend verification timeouts");
   8187 
   8188         final PackageVerificationState state = mPendingVerification.get(id);
   8189         final PackageVerificationResponse response = new PackageVerificationResponse(
   8190                 verificationCodeAtTimeout, Binder.getCallingUid());
   8191 
   8192         if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
   8193             millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
   8194         }
   8195         if (millisecondsToDelay < 0) {
   8196             millisecondsToDelay = 0;
   8197         }
   8198         if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
   8199                 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
   8200             verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
   8201         }
   8202 
   8203         if ((state != null) && !state.timeoutExtended()) {
   8204             state.extendTimeout();
   8205 
   8206             final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
   8207             msg.arg1 = id;
   8208             msg.obj = response;
   8209             mHandler.sendMessageDelayed(msg, millisecondsToDelay);
   8210         }
   8211     }
   8212 
   8213     private void broadcastPackageVerified(int verificationId, Uri packageUri,
   8214             int verificationCode, UserHandle user) {
   8215         final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
   8216         intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
   8217         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   8218         intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
   8219         intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
   8220 
   8221         mContext.sendBroadcastAsUser(intent, user,
   8222                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
   8223     }
   8224 
   8225     private ComponentName matchComponentForVerifier(String packageName,
   8226             List<ResolveInfo> receivers) {
   8227         ActivityInfo targetReceiver = null;
   8228 
   8229         final int NR = receivers.size();
   8230         for (int i = 0; i < NR; i++) {
   8231             final ResolveInfo info = receivers.get(i);
   8232             if (info.activityInfo == null) {
   8233                 continue;
   8234             }
   8235 
   8236             if (packageName.equals(info.activityInfo.packageName)) {
   8237                 targetReceiver = info.activityInfo;
   8238                 break;
   8239             }
   8240         }
   8241 
   8242         if (targetReceiver == null) {
   8243             return null;
   8244         }
   8245 
   8246         return new ComponentName(targetReceiver.packageName, targetReceiver.name);
   8247     }
   8248 
   8249     private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
   8250             List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
   8251         if (pkgInfo.verifiers.length == 0) {
   8252             return null;
   8253         }
   8254 
   8255         final int N = pkgInfo.verifiers.length;
   8256         final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
   8257         for (int i = 0; i < N; i++) {
   8258             final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
   8259 
   8260             final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
   8261                     receivers);
   8262             if (comp == null) {
   8263                 continue;
   8264             }
   8265 
   8266             final int verifierUid = getUidForVerifier(verifierInfo);
   8267             if (verifierUid == -1) {
   8268                 continue;
   8269             }
   8270 
   8271             if (DEBUG_VERIFY) {
   8272                 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
   8273                         + " with the correct signature");
   8274             }
   8275             sufficientVerifiers.add(comp);
   8276             verificationState.addSufficientVerifier(verifierUid);
   8277         }
   8278 
   8279         return sufficientVerifiers;
   8280     }
   8281 
   8282     private int getUidForVerifier(VerifierInfo verifierInfo) {
   8283         synchronized (mPackages) {
   8284             final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
   8285             if (pkg == null) {
   8286                 return -1;
   8287             } else if (pkg.mSignatures.length != 1) {
   8288                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
   8289                         + " has more than one signature; ignoring");
   8290                 return -1;
   8291             }
   8292 
   8293             /*
   8294              * If the public key of the package's signature does not match
   8295              * our expected public key, then this is a different package and
   8296              * we should skip.
   8297              */
   8298 
   8299             final byte[] expectedPublicKey;
   8300             try {
   8301                 final Signature verifierSig = pkg.mSignatures[0];
   8302                 final PublicKey publicKey = verifierSig.getPublicKey();
   8303                 expectedPublicKey = publicKey.getEncoded();
   8304             } catch (CertificateException e) {
   8305                 return -1;
   8306             }
   8307 
   8308             final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
   8309 
   8310             if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
   8311                 Slog.i(TAG, "Verifier package " + verifierInfo.packageName
   8312                         + " does not have the expected public key; ignoring");
   8313                 return -1;
   8314             }
   8315 
   8316             return pkg.applicationInfo.uid;
   8317         }
   8318     }
   8319 
   8320     @Override
   8321     public void finishPackageInstall(int token) {
   8322         enforceSystemOrRoot("Only the system is allowed to finish installs");
   8323 
   8324         if (DEBUG_INSTALL) {
   8325             Slog.v(TAG, "BM finishing package install for " + token);
   8326         }
   8327 
   8328         final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   8329         mHandler.sendMessage(msg);
   8330     }
   8331 
   8332     /**
   8333      * Get the verification agent timeout.
   8334      *
   8335      * @return verification timeout in milliseconds
   8336      */
   8337     private long getVerificationTimeout() {
   8338         return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
   8339                 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
   8340                 DEFAULT_VERIFICATION_TIMEOUT);
   8341     }
   8342 
   8343     /**
   8344      * Get the default verification agent response code.
   8345      *
   8346      * @return default verification response code
   8347      */
   8348     private int getDefaultVerificationResponse() {
   8349         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   8350                 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
   8351                 DEFAULT_VERIFICATION_RESPONSE);
   8352     }
   8353 
   8354     /**
   8355      * Check whether or not package verification has been enabled.
   8356      *
   8357      * @return true if verification should be performed
   8358      */
   8359     private boolean isVerificationEnabled(int userId, int installFlags) {
   8360         if (!DEFAULT_VERIFY_ENABLE) {
   8361             return false;
   8362         }
   8363 
   8364         boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
   8365 
   8366         // Check if installing from ADB
   8367         if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
   8368             // Do not run verification in a test harness environment
   8369             if (ActivityManager.isRunningInTestHarness()) {
   8370                 return false;
   8371             }
   8372             if (ensureVerifyAppsEnabled) {
   8373                 return true;
   8374             }
   8375             // Check if the developer does not want package verification for ADB installs
   8376             if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   8377                     android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
   8378                 return false;
   8379             }
   8380         }
   8381 
   8382         if (ensureVerifyAppsEnabled) {
   8383             return true;
   8384         }
   8385 
   8386         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   8387                 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
   8388     }
   8389 
   8390     /**
   8391      * Get the "allow unknown sources" setting.
   8392      *
   8393      * @return the current "allow unknown sources" setting
   8394      */
   8395     private int getUnknownSourcesSettings() {
   8396         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   8397                 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS,
   8398                 -1);
   8399     }
   8400 
   8401     @Override
   8402     public void setInstallerPackageName(String targetPackage, String installerPackageName) {
   8403         final int uid = Binder.getCallingUid();
   8404         // writer
   8405         synchronized (mPackages) {
   8406             PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
   8407             if (targetPackageSetting == null) {
   8408                 throw new IllegalArgumentException("Unknown target package: " + targetPackage);
   8409             }
   8410 
   8411             PackageSetting installerPackageSetting;
   8412             if (installerPackageName != null) {
   8413                 installerPackageSetting = mSettings.mPackages.get(installerPackageName);
   8414                 if (installerPackageSetting == null) {
   8415                     throw new IllegalArgumentException("Unknown installer package: "
   8416                             + installerPackageName);
   8417                 }
   8418             } else {
   8419                 installerPackageSetting = null;
   8420             }
   8421 
   8422             Signature[] callerSignature;
   8423             Object obj = mSettings.getUserIdLPr(uid);
   8424             if (obj != null) {
   8425                 if (obj instanceof SharedUserSetting) {
   8426                     callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
   8427                 } else if (obj instanceof PackageSetting) {
   8428                     callerSignature = ((PackageSetting)obj).signatures.mSignatures;
   8429                 } else {
   8430                     throw new SecurityException("Bad object " + obj + " for uid " + uid);
   8431                 }
   8432             } else {
   8433                 throw new SecurityException("Unknown calling uid " + uid);
   8434             }
   8435 
   8436             // Verify: can't set installerPackageName to a package that is
   8437             // not signed with the same cert as the caller.
   8438             if (installerPackageSetting != null) {
   8439                 if (compareSignatures(callerSignature,
   8440                         installerPackageSetting.signatures.mSignatures)
   8441                         != PackageManager.SIGNATURE_MATCH) {
   8442                     throw new SecurityException(
   8443                             "Caller does not have same cert as new installer package "
   8444                             + installerPackageName);
   8445                 }
   8446             }
   8447 
   8448             // Verify: if target already has an installer package, it must
   8449             // be signed with the same cert as the caller.
   8450             if (targetPackageSetting.installerPackageName != null) {
   8451                 PackageSetting setting = mSettings.mPackages.get(
   8452                         targetPackageSetting.installerPackageName);
   8453                 // If the currently set package isn't valid, then it's always
   8454                 // okay to change it.
   8455                 if (setting != null) {
   8456                     if (compareSignatures(callerSignature,
   8457                             setting.signatures.mSignatures)
   8458                             != PackageManager.SIGNATURE_MATCH) {
   8459                         throw new SecurityException(
   8460                                 "Caller does not have same cert as old installer package "
   8461                                 + targetPackageSetting.installerPackageName);
   8462                     }
   8463                 }
   8464             }
   8465 
   8466             // Okay!
   8467             targetPackageSetting.installerPackageName = installerPackageName;
   8468             scheduleWriteSettingsLocked();
   8469         }
   8470     }
   8471 
   8472     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
   8473         // Queue up an async operation since the package installation may take a little while.
   8474         mHandler.post(new Runnable() {
   8475             public void run() {
   8476                 mHandler.removeCallbacks(this);
   8477                  // Result object to be returned
   8478                 PackageInstalledInfo res = new PackageInstalledInfo();
   8479                 res.returnCode = currentStatus;
   8480                 res.uid = -1;
   8481                 res.pkg = null;
   8482                 res.removedInfo = new PackageRemovedInfo();
   8483                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   8484                     args.doPreInstall(res.returnCode);
   8485                     synchronized (mInstallLock) {
   8486                         installPackageLI(args, res);
   8487                     }
   8488                     args.doPostInstall(res.returnCode, res.uid);
   8489                 }
   8490 
   8491                 // A restore should be performed at this point if (a) the install
   8492                 // succeeded, (b) the operation is not an update, and (c) the new
   8493                 // package has not opted out of backup participation.
   8494                 final boolean update = res.removedInfo.removedPackage != null;
   8495                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
   8496                 boolean doRestore = !update
   8497                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
   8498 
   8499                 // Set up the post-install work request bookkeeping.  This will be used
   8500                 // and cleaned up by the post-install event handling regardless of whether
   8501                 // there's a restore pass performed.  Token values are >= 1.
   8502                 int token;
   8503                 if (mNextInstallToken < 0) mNextInstallToken = 1;
   8504                 token = mNextInstallToken++;
   8505 
   8506                 PostInstallData data = new PostInstallData(args, res);
   8507                 mRunningInstalls.put(token, data);
   8508                 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
   8509 
   8510                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
   8511                     // Pass responsibility to the Backup Manager.  It will perform a
   8512                     // restore if appropriate, then pass responsibility back to the
   8513                     // Package Manager to run the post-install observer callbacks
   8514                     // and broadcasts.
   8515                     IBackupManager bm = IBackupManager.Stub.asInterface(
   8516                             ServiceManager.getService(Context.BACKUP_SERVICE));
   8517                     if (bm != null) {
   8518                         if (DEBUG_INSTALL) Log.v(TAG, "token " + token
   8519                                 + " to BM for possible restore");
   8520                         try {
   8521                             bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
   8522                         } catch (RemoteException e) {
   8523                             // can't happen; the backup manager is local
   8524                         } catch (Exception e) {
   8525                             Slog.e(TAG, "Exception trying to enqueue restore", e);
   8526                             doRestore = false;
   8527                         }
   8528                     } else {
   8529                         Slog.e(TAG, "Backup Manager not found!");
   8530                         doRestore = false;
   8531                     }
   8532                 }
   8533 
   8534                 if (!doRestore) {
   8535                     // No restore possible, or the Backup Manager was mysteriously not
   8536                     // available -- just fire the post-install work request directly.
   8537                     if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
   8538                     Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
   8539                     mHandler.sendMessage(msg);
   8540                 }
   8541             }
   8542         });
   8543     }
   8544 
   8545     private abstract class HandlerParams {
   8546         private static final int MAX_RETRIES = 4;
   8547 
   8548         /**
   8549          * Number of times startCopy() has been attempted and had a non-fatal
   8550          * error.
   8551          */
   8552         private int mRetries = 0;
   8553 
   8554         /** User handle for the user requesting the information or installation. */
   8555         private final UserHandle mUser;
   8556 
   8557         HandlerParams(UserHandle user) {
   8558             mUser = user;
   8559         }
   8560 
   8561         UserHandle getUser() {
   8562             return mUser;
   8563         }
   8564 
   8565         final boolean startCopy() {
   8566             boolean res;
   8567             try {
   8568                 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
   8569 
   8570                 if (++mRetries > MAX_RETRIES) {
   8571                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
   8572                     mHandler.sendEmptyMessage(MCS_GIVE_UP);
   8573                     handleServiceError();
   8574                     return false;
   8575                 } else {
   8576                     handleStartCopy();
   8577                     res = true;
   8578                 }
   8579             } catch (RemoteException e) {
   8580                 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
   8581                 mHandler.sendEmptyMessage(MCS_RECONNECT);
   8582                 res = false;
   8583             }
   8584             handleReturnCode();
   8585             return res;
   8586         }
   8587 
   8588         final void serviceError() {
   8589             if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
   8590             handleServiceError();
   8591             handleReturnCode();
   8592         }
   8593 
   8594         abstract void handleStartCopy() throws RemoteException;
   8595         abstract void handleServiceError();
   8596         abstract void handleReturnCode();
   8597     }
   8598 
   8599     class MeasureParams extends HandlerParams {
   8600         private final PackageStats mStats;
   8601         private boolean mSuccess;
   8602 
   8603         private final IPackageStatsObserver mObserver;
   8604 
   8605         public MeasureParams(PackageStats stats, IPackageStatsObserver observer) {
   8606             super(new UserHandle(stats.userHandle));
   8607             mObserver = observer;
   8608             mStats = stats;
   8609         }
   8610 
   8611         @Override
   8612         public String toString() {
   8613             return "MeasureParams{"
   8614                 + Integer.toHexString(System.identityHashCode(this))
   8615                 + " " + mStats.packageName + "}";
   8616         }
   8617 
   8618         @Override
   8619         void handleStartCopy() throws RemoteException {
   8620             synchronized (mInstallLock) {
   8621                 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats);
   8622             }
   8623 
   8624             if (mSuccess) {
   8625                 final boolean mounted;
   8626                 if (Environment.isExternalStorageEmulated()) {
   8627                     mounted = true;
   8628                 } else {
   8629                     final String status = Environment.getExternalStorageState();
   8630                     mounted = (Environment.MEDIA_MOUNTED.equals(status)
   8631                             || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status));
   8632                 }
   8633 
   8634                 if (mounted) {
   8635                     final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle);
   8636 
   8637                     mStats.externalCacheSize = calculateDirectorySize(mContainerService,
   8638                             userEnv.buildExternalStorageAppCacheDirs(mStats.packageName));
   8639 
   8640                     mStats.externalDataSize = calculateDirectorySize(mContainerService,
   8641                             userEnv.buildExternalStorageAppDataDirs(mStats.packageName));
   8642 
   8643                     // Always subtract cache size, since it's a subdirectory
   8644                     mStats.externalDataSize -= mStats.externalCacheSize;
   8645 
   8646                     mStats.externalMediaSize = calculateDirectorySize(mContainerService,
   8647                             userEnv.buildExternalStorageAppMediaDirs(mStats.packageName));
   8648 
   8649                     mStats.externalObbSize = calculateDirectorySize(mContainerService,
   8650                             userEnv.buildExternalStorageAppObbDirs(mStats.packageName));
   8651                 }
   8652             }
   8653         }
   8654 
   8655         @Override
   8656         void handleReturnCode() {
   8657             if (mObserver != null) {
   8658                 try {
   8659                     mObserver.onGetStatsCompleted(mStats, mSuccess);
   8660                 } catch (RemoteException e) {
   8661                     Slog.i(TAG, "Observer no longer exists.");
   8662                 }
   8663             }
   8664         }
   8665 
   8666         @Override
   8667         void handleServiceError() {
   8668             Slog.e(TAG, "Could not measure application " + mStats.packageName
   8669                             + " external storage");
   8670         }
   8671     }
   8672 
   8673     private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths)
   8674             throws RemoteException {
   8675         long result = 0;
   8676         for (File path : paths) {
   8677             result += mcs.calculateDirectorySize(path.getAbsolutePath());
   8678         }
   8679         return result;
   8680     }
   8681 
   8682     private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
   8683         for (File path : paths) {
   8684             try {
   8685                 mcs.clearDirectory(path.getAbsolutePath());
   8686             } catch (RemoteException e) {
   8687             }
   8688         }
   8689     }
   8690 
   8691     static class OriginInfo {
   8692         /**
   8693          * Location where install is coming from, before it has been
   8694          * copied/renamed into place. This could be a single monolithic APK
   8695          * file, or a cluster directory. This location may be untrusted.
   8696          */
   8697         final File file;
   8698         final String cid;
   8699 
   8700         /**
   8701          * Flag indicating that {@link #file} or {@link #cid} has already been
   8702          * staged, meaning downstream users don't need to defensively copy the
   8703          * contents.
   8704          */
   8705         final boolean staged;
   8706 
   8707         /**
   8708          * Flag indicating that {@link #file} or {@link #cid} is an already
   8709          * installed app that is being moved.
   8710          */
   8711         final boolean existing;
   8712 
   8713         final String resolvedPath;
   8714         final File resolvedFile;
   8715 
   8716         static OriginInfo fromNothing() {
   8717             return new OriginInfo(null, null, false, false);
   8718         }
   8719 
   8720         static OriginInfo fromUntrustedFile(File file) {
   8721             return new OriginInfo(file, null, false, false);
   8722         }
   8723 
   8724         static OriginInfo fromExistingFile(File file) {
   8725             return new OriginInfo(file, null, false, true);
   8726         }
   8727 
   8728         static OriginInfo fromStagedFile(File file) {
   8729             return new OriginInfo(file, null, true, false);
   8730         }
   8731 
   8732         static OriginInfo fromStagedContainer(String cid) {
   8733             return new OriginInfo(null, cid, true, false);
   8734         }
   8735 
   8736         private OriginInfo(File file, String cid, boolean staged, boolean existing) {
   8737             this.file = file;
   8738             this.cid = cid;
   8739             this.staged = staged;
   8740             this.existing = existing;
   8741 
   8742             if (cid != null) {
   8743                 resolvedPath = PackageHelper.getSdDir(cid);
   8744                 resolvedFile = new File(resolvedPath);
   8745             } else if (file != null) {
   8746                 resolvedPath = file.getAbsolutePath();
   8747                 resolvedFile = file;
   8748             } else {
   8749                 resolvedPath = null;
   8750                 resolvedFile = null;
   8751             }
   8752         }
   8753     }
   8754 
   8755     class InstallParams extends HandlerParams {
   8756         final OriginInfo origin;
   8757         final IPackageInstallObserver2 observer;
   8758         int installFlags;
   8759         final String installerPackageName;
   8760         final VerificationParams verificationParams;
   8761         private InstallArgs mArgs;
   8762         private int mRet;
   8763         final String packageAbiOverride;
   8764 
   8765         InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
   8766                 String installerPackageName, VerificationParams verificationParams, UserHandle user,
   8767                 String packageAbiOverride) {
   8768             super(user);
   8769             this.origin = origin;
   8770             this.observer = observer;
   8771             this.installFlags = installFlags;
   8772             this.installerPackageName = installerPackageName;
   8773             this.verificationParams = verificationParams;
   8774             this.packageAbiOverride = packageAbiOverride;
   8775         }
   8776 
   8777         @Override
   8778         public String toString() {
   8779             return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
   8780                     + " file=" + origin.file + " cid=" + origin.cid + "}";
   8781         }
   8782 
   8783         public ManifestDigest getManifestDigest() {
   8784             if (verificationParams == null) {
   8785                 return null;
   8786             }
   8787             return verificationParams.getManifestDigest();
   8788         }
   8789 
   8790         private int installLocationPolicy(PackageInfoLite pkgLite) {
   8791             String packageName = pkgLite.packageName;
   8792             int installLocation = pkgLite.installLocation;
   8793             boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   8794             // reader
   8795             synchronized (mPackages) {
   8796                 PackageParser.Package pkg = mPackages.get(packageName);
   8797                 if (pkg != null) {
   8798                     if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   8799                         // Check for downgrading.
   8800                         if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) {
   8801                             if (pkgLite.versionCode < pkg.mVersionCode) {
   8802                                 Slog.w(TAG, "Can't install update of " + packageName
   8803                                         + " update version " + pkgLite.versionCode
   8804                                         + " is older than installed version "
   8805                                         + pkg.mVersionCode);
   8806                                 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
   8807                             }
   8808                         }
   8809                         // Check for updated system application.
   8810                         if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   8811                             if (onSd) {
   8812                                 Slog.w(TAG, "Cannot install update to system app on sdcard");
   8813                                 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
   8814                             }
   8815                             return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   8816                         } else {
   8817                             if (onSd) {
   8818                                 // Install flag overrides everything.
   8819                                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   8820                             }
   8821                             // If current upgrade specifies particular preference
   8822                             if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
   8823                                 // Application explicitly specified internal.
   8824                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   8825                             } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
   8826                                 // App explictly prefers external. Let policy decide
   8827                             } else {
   8828                                 // Prefer previous location
   8829                                 if (isExternal(pkg)) {
   8830                                     return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   8831                                 }
   8832                                 return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
   8833                             }
   8834                         }
   8835                     } else {
   8836                         // Invalid install. Return error code
   8837                         return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
   8838                     }
   8839                 }
   8840             }
   8841             // All the special cases have been taken care of.
   8842             // Return result based on recommended install location.
   8843             if (onSd) {
   8844                 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
   8845             }
   8846             return pkgLite.recommendedInstallLocation;
   8847         }
   8848 
   8849         /*
   8850          * Invoke remote method to get package information and install
   8851          * location values. Override install location based on default
   8852          * policy if needed and then create install arguments based
   8853          * on the install location.
   8854          */
   8855         public void handleStartCopy() throws RemoteException {
   8856             int ret = PackageManager.INSTALL_SUCCEEDED;
   8857 
   8858             // If we're already staged, we've firmly committed to an install location
   8859             if (origin.staged) {
   8860                 if (origin.file != null) {
   8861                     installFlags |= PackageManager.INSTALL_INTERNAL;
   8862                     installFlags &= ~PackageManager.INSTALL_EXTERNAL;
   8863                 } else if (origin.cid != null) {
   8864                     installFlags |= PackageManager.INSTALL_EXTERNAL;
   8865                     installFlags &= ~PackageManager.INSTALL_INTERNAL;
   8866                 } else {
   8867                     throw new IllegalStateException("Invalid stage location");
   8868                 }
   8869             }
   8870 
   8871             final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   8872             final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
   8873 
   8874             PackageInfoLite pkgLite = null;
   8875 
   8876             if (onInt && onSd) {
   8877                 // Check if both bits are set.
   8878                 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
   8879                 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   8880             } else {
   8881                 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
   8882                         packageAbiOverride);
   8883 
   8884                 /*
   8885                  * If we have too little free space, try to free cache
   8886                  * before giving up.
   8887                  */
   8888                 if (!origin.staged && pkgLite.recommendedInstallLocation
   8889                         == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
   8890                     // TODO: focus freeing disk space on the target device
   8891                     final StorageManager storage = StorageManager.from(mContext);
   8892                     final long lowThreshold = storage.getStorageLowBytes(
   8893                             Environment.getDataDirectory());
   8894 
   8895                     final long sizeBytes = mContainerService.calculateInstalledSize(
   8896                             origin.resolvedPath, isForwardLocked(), packageAbiOverride);
   8897 
   8898                     if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) {
   8899                         pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
   8900                                 installFlags, packageAbiOverride);
   8901                     }
   8902 
   8903                     /*
   8904                      * The cache free must have deleted the file we
   8905                      * downloaded to install.
   8906                      *
   8907                      * TODO: fix the "freeCache" call to not delete
   8908                      *       the file we care about.
   8909                      */
   8910                     if (pkgLite.recommendedInstallLocation
   8911                             == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
   8912                         pkgLite.recommendedInstallLocation
   8913                             = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
   8914                     }
   8915                 }
   8916             }
   8917 
   8918             if (ret == PackageManager.INSTALL_SUCCEEDED) {
   8919                 int loc = pkgLite.recommendedInstallLocation;
   8920                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
   8921                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
   8922                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
   8923                     ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
   8924                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
   8925                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   8926                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
   8927                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
   8928                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
   8929                     ret = PackageManager.INSTALL_FAILED_INVALID_URI;
   8930                 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
   8931                     ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
   8932                 } else {
   8933                     // Override with defaults if needed.
   8934                     loc = installLocationPolicy(pkgLite);
   8935                     if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
   8936                         ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
   8937                     } else if (!onSd && !onInt) {
   8938                         // Override install location with flags
   8939                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
   8940                             // Set the flag to install on external media.
   8941                             installFlags |= PackageManager.INSTALL_EXTERNAL;
   8942                             installFlags &= ~PackageManager.INSTALL_INTERNAL;
   8943                         } else {
   8944                             // Make sure the flag for installing on external
   8945                             // media is unset
   8946                             installFlags |= PackageManager.INSTALL_INTERNAL;
   8947                             installFlags &= ~PackageManager.INSTALL_EXTERNAL;
   8948                         }
   8949                     }
   8950                 }
   8951             }
   8952 
   8953             final InstallArgs args = createInstallArgs(this);
   8954             mArgs = args;
   8955 
   8956             if (ret == PackageManager.INSTALL_SUCCEEDED) {
   8957                  /*
   8958                  * ADB installs appear as UserHandle.USER_ALL, and can only be performed by
   8959                  * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER.
   8960                  */
   8961                 int userIdentifier = getUser().getIdentifier();
   8962                 if (userIdentifier == UserHandle.USER_ALL
   8963                         && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) {
   8964                     userIdentifier = UserHandle.USER_OWNER;
   8965                 }
   8966 
   8967                 /*
   8968                  * Determine if we have any installed package verifiers. If we
   8969                  * do, then we'll defer to them to verify the packages.
   8970                  */
   8971                 final int requiredUid = mRequiredVerifierPackage == null ? -1
   8972                         : getPackageUid(mRequiredVerifierPackage, userIdentifier);
   8973                 if (!origin.existing && requiredUid != -1
   8974                         && isVerificationEnabled(userIdentifier, installFlags)) {
   8975                     final Intent verification = new Intent(
   8976                             Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
   8977                     verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
   8978                             PACKAGE_MIME_TYPE);
   8979                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
   8980 
   8981                     final List<ResolveInfo> receivers = queryIntentReceivers(verification,
   8982                             PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS,
   8983                             0 /* TODO: Which userId? */);
   8984 
   8985                     if (DEBUG_VERIFY) {
   8986                         Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
   8987                                 + verification.toString() + " with " + pkgLite.verifiers.length
   8988                                 + " optional verifiers");
   8989                     }
   8990 
   8991                     final int verificationId = mPendingVerificationToken++;
   8992 
   8993                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
   8994 
   8995                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
   8996                             installerPackageName);
   8997 
   8998                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
   8999                             installFlags);
   9000 
   9001                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
   9002                             pkgLite.packageName);
   9003 
   9004                     verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
   9005                             pkgLite.versionCode);
   9006 
   9007                     if (verificationParams != null) {
   9008                         if (verificationParams.getVerificationURI() != null) {
   9009                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
   9010                                  verificationParams.getVerificationURI());
   9011                         }
   9012                         if (verificationParams.getOriginatingURI() != null) {
   9013                             verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
   9014                                   verificationParams.getOriginatingURI());
   9015                         }
   9016                         if (verificationParams.getReferrer() != null) {
   9017                             verification.putExtra(Intent.EXTRA_REFERRER,
   9018                                   verificationParams.getReferrer());
   9019                         }
   9020                         if (verificationParams.getOriginatingUid() >= 0) {
   9021                             verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
   9022                                   verificationParams.getOriginatingUid());
   9023                         }
   9024                         if (verificationParams.getInstallerUid() >= 0) {
   9025                             verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
   9026                                   verificationParams.getInstallerUid());
   9027                         }
   9028                     }
   9029 
   9030                     final PackageVerificationState verificationState = new PackageVerificationState(
   9031                             requiredUid, args);
   9032 
   9033                     mPendingVerification.append(verificationId, verificationState);
   9034 
   9035                     final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
   9036                             receivers, verificationState);
   9037 
   9038                     /*
   9039                      * If any sufficient verifiers were listed in the package
   9040                      * manifest, attempt to ask them.
   9041                      */
   9042                     if (sufficientVerifiers != null) {
   9043                         final int N = sufficientVerifiers.size();
   9044                         if (N == 0) {
   9045                             Slog.i(TAG, "Additional verifiers required, but none installed.");
   9046                             ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
   9047                         } else {
   9048                             for (int i = 0; i < N; i++) {
   9049                                 final ComponentName verifierComponent = sufficientVerifiers.get(i);
   9050 
   9051                                 final Intent sufficientIntent = new Intent(verification);
   9052                                 sufficientIntent.setComponent(verifierComponent);
   9053 
   9054                                 mContext.sendBroadcastAsUser(sufficientIntent, getUser());
   9055                             }
   9056                         }
   9057                     }
   9058 
   9059                     final ComponentName requiredVerifierComponent = matchComponentForVerifier(
   9060                             mRequiredVerifierPackage, receivers);
   9061                     if (ret == PackageManager.INSTALL_SUCCEEDED
   9062                             && mRequiredVerifierPackage != null) {
   9063                         /*
   9064                          * Send the intent to the required verification agent,
   9065                          * but only start the verification timeout after the
   9066                          * target BroadcastReceivers have run.
   9067                          */
   9068                         verification.setComponent(requiredVerifierComponent);
   9069                         mContext.sendOrderedBroadcastAsUser(verification, getUser(),
   9070                                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   9071                                 new BroadcastReceiver() {
   9072                                     @Override
   9073                                     public void onReceive(Context context, Intent intent) {
   9074                                         final Message msg = mHandler
   9075                                                 .obtainMessage(CHECK_PENDING_VERIFICATION);
   9076                                         msg.arg1 = verificationId;
   9077                                         mHandler.sendMessageDelayed(msg, getVerificationTimeout());
   9078                                     }
   9079                                 }, null, 0, null, null);
   9080 
   9081                         /*
   9082                          * We don't want the copy to proceed until verification
   9083                          * succeeds, so null out this field.
   9084                          */
   9085                         mArgs = null;
   9086                     }
   9087                 } else {
   9088                     /*
   9089                      * No package verification is enabled, so immediately start
   9090                      * the remote call to initiate copy using temporary file.
   9091                      */
   9092                     ret = args.copyApk(mContainerService, true);
   9093                 }
   9094             }
   9095 
   9096             mRet = ret;
   9097         }
   9098 
   9099         @Override
   9100         void handleReturnCode() {
   9101             // If mArgs is null, then MCS couldn't be reached. When it
   9102             // reconnects, it will try again to install. At that point, this
   9103             // will succeed.
   9104             if (mArgs != null) {
   9105                 processPendingInstall(mArgs, mRet);
   9106             }
   9107         }
   9108 
   9109         @Override
   9110         void handleServiceError() {
   9111             mArgs = createInstallArgs(this);
   9112             mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   9113         }
   9114 
   9115         public boolean isForwardLocked() {
   9116             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   9117         }
   9118     }
   9119 
   9120     /**
   9121      * Used during creation of InstallArgs
   9122      *
   9123      * @param installFlags package installation flags
   9124      * @return true if should be installed on external storage
   9125      */
   9126     private static boolean installOnSd(int installFlags) {
   9127         if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
   9128             return false;
   9129         }
   9130         if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
   9131             return true;
   9132         }
   9133         return false;
   9134     }
   9135 
   9136     /**
   9137      * Used during creation of InstallArgs
   9138      *
   9139      * @param installFlags package installation flags
   9140      * @return true if should be installed as forward locked
   9141      */
   9142     private static boolean installForwardLocked(int installFlags) {
   9143         return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   9144     }
   9145 
   9146     private InstallArgs createInstallArgs(InstallParams params) {
   9147         if (installOnSd(params.installFlags) || params.isForwardLocked()) {
   9148             return new AsecInstallArgs(params);
   9149         } else {
   9150             return new FileInstallArgs(params);
   9151         }
   9152     }
   9153 
   9154     /**
   9155      * Create args that describe an existing installed package. Typically used
   9156      * when cleaning up old installs, or used as a move source.
   9157      */
   9158     private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
   9159             String resourcePath, String nativeLibraryRoot, String[] instructionSets) {
   9160         final boolean isInAsec;
   9161         if (installOnSd(installFlags)) {
   9162             /* Apps on SD card are always in ASEC containers. */
   9163             isInAsec = true;
   9164         } else if (installForwardLocked(installFlags)
   9165                 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
   9166             /*
   9167              * Forward-locked apps are only in ASEC containers if they're the
   9168              * new style
   9169              */
   9170             isInAsec = true;
   9171         } else {
   9172             isInAsec = false;
   9173         }
   9174 
   9175         if (isInAsec) {
   9176             return new AsecInstallArgs(codePath, instructionSets,
   9177                     installOnSd(installFlags), installForwardLocked(installFlags));
   9178         } else {
   9179             return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot,
   9180                     instructionSets);
   9181         }
   9182     }
   9183 
   9184     static abstract class InstallArgs {
   9185         /** @see InstallParams#origin */
   9186         final OriginInfo origin;
   9187 
   9188         final IPackageInstallObserver2 observer;
   9189         // Always refers to PackageManager flags only
   9190         final int installFlags;
   9191         final String installerPackageName;
   9192         final ManifestDigest manifestDigest;
   9193         final UserHandle user;
   9194         final String abiOverride;
   9195 
   9196         // The list of instruction sets supported by this app. This is currently
   9197         // only used during the rmdex() phase to clean up resources. We can get rid of this
   9198         // if we move dex files under the common app path.
   9199         /* nullable */ String[] instructionSets;
   9200 
   9201         InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags,
   9202                 String installerPackageName, ManifestDigest manifestDigest, UserHandle user,
   9203                 String[] instructionSets, String abiOverride) {
   9204             this.origin = origin;
   9205             this.installFlags = installFlags;
   9206             this.observer = observer;
   9207             this.installerPackageName = installerPackageName;
   9208             this.manifestDigest = manifestDigest;
   9209             this.user = user;
   9210             this.instructionSets = instructionSets;
   9211             this.abiOverride = abiOverride;
   9212         }
   9213 
   9214         abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
   9215         abstract int doPreInstall(int status);
   9216 
   9217         /**
   9218          * Rename package into final resting place. All paths on the given
   9219          * scanned package should be updated to reflect the rename.
   9220          */
   9221         abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
   9222         abstract int doPostInstall(int status, int uid);
   9223 
   9224         /** @see PackageSettingBase#codePathString */
   9225         abstract String getCodePath();
   9226         /** @see PackageSettingBase#resourcePathString */
   9227         abstract String getResourcePath();
   9228         abstract String getLegacyNativeLibraryPath();
   9229 
   9230         // Need installer lock especially for dex file removal.
   9231         abstract void cleanUpResourcesLI();
   9232         abstract boolean doPostDeleteLI(boolean delete);
   9233         abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
   9234 
   9235         /**
   9236          * Called before the source arguments are copied. This is used mostly
   9237          * for MoveParams when it needs to read the source file to put it in the
   9238          * destination.
   9239          */
   9240         int doPreCopy() {
   9241             return PackageManager.INSTALL_SUCCEEDED;
   9242         }
   9243 
   9244         /**
   9245          * Called after the source arguments are copied. This is used mostly for
   9246          * MoveParams when it needs to read the source file to put it in the
   9247          * destination.
   9248          *
   9249          * @return
   9250          */
   9251         int doPostCopy(int uid) {
   9252             return PackageManager.INSTALL_SUCCEEDED;
   9253         }
   9254 
   9255         protected boolean isFwdLocked() {
   9256             return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
   9257         }
   9258 
   9259         protected boolean isExternal() {
   9260             return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
   9261         }
   9262 
   9263         UserHandle getUser() {
   9264             return user;
   9265         }
   9266     }
   9267 
   9268     /**
   9269      * Logic to handle installation of non-ASEC applications, including copying
   9270      * and renaming logic.
   9271      */
   9272     class FileInstallArgs extends InstallArgs {
   9273         private File codeFile;
   9274         private File resourceFile;
   9275         private File legacyNativeLibraryPath;
   9276 
   9277         // Example topology:
   9278         // /data/app/com.example/base.apk
   9279         // /data/app/com.example/split_foo.apk
   9280         // /data/app/com.example/lib/arm/libfoo.so
   9281         // /data/app/com.example/lib/arm64/libfoo.so
   9282         // /data/app/com.example/dalvik/arm/base.apk@classes.dex
   9283 
   9284         /** New install */
   9285         FileInstallArgs(InstallParams params) {
   9286             super(params.origin, params.observer, params.installFlags,
   9287                     params.installerPackageName, params.getManifestDigest(), params.getUser(),
   9288                     null /* instruction sets */, params.packageAbiOverride);
   9289             if (isFwdLocked()) {
   9290                 throw new IllegalArgumentException("Forward locking only supported in ASEC");
   9291             }
   9292         }
   9293 
   9294         /** Existing install */
   9295         FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath,
   9296                 String[] instructionSets) {
   9297             super(OriginInfo.fromNothing(), null, 0, null, null, null, instructionSets, null);
   9298             this.codeFile = (codePath != null) ? new File(codePath) : null;
   9299             this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
   9300             this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ?
   9301                     new File(legacyNativeLibraryPath) : null;
   9302         }
   9303 
   9304         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
   9305             final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(),
   9306                     isFwdLocked(), abiOverride);
   9307 
   9308             final StorageManager storage = StorageManager.from(mContext);
   9309             return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory()));
   9310         }
   9311 
   9312         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   9313             if (origin.staged) {
   9314                 Slog.d(TAG, origin.file + " already staged; skipping copy");
   9315                 codeFile = origin.file;
   9316                 resourceFile = origin.file;
   9317                 return PackageManager.INSTALL_SUCCEEDED;
   9318             }
   9319 
   9320             try {
   9321                 final File tempDir = mInstallerService.allocateInternalStageDirLegacy();
   9322                 codeFile = tempDir;
   9323                 resourceFile = tempDir;
   9324             } catch (IOException e) {
   9325                 Slog.w(TAG, "Failed to create copy file: " + e);
   9326                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
   9327             }
   9328 
   9329             final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
   9330                 @Override
   9331                 public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
   9332                     if (!FileUtils.isValidExtFilename(name)) {
   9333                         throw new IllegalArgumentException("Invalid filename: " + name);
   9334                     }
   9335                     try {
   9336                         final File file = new File(codeFile, name);
   9337                         final FileDescriptor fd = Os.open(file.getAbsolutePath(),
   9338                                 O_RDWR | O_CREAT, 0644);
   9339                         Os.chmod(file.getAbsolutePath(), 0644);
   9340                         return new ParcelFileDescriptor(fd);
   9341                     } catch (ErrnoException e) {
   9342                         throw new RemoteException("Failed to open: " + e.getMessage());
   9343                     }
   9344                 }
   9345             };
   9346 
   9347             int ret = PackageManager.INSTALL_SUCCEEDED;
   9348             ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
   9349             if (ret != PackageManager.INSTALL_SUCCEEDED) {
   9350                 Slog.e(TAG, "Failed to copy package");
   9351                 return ret;
   9352             }
   9353 
   9354             final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
   9355             NativeLibraryHelper.Handle handle = null;
   9356             try {
   9357                 handle = NativeLibraryHelper.Handle.create(codeFile);
   9358                 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
   9359                         abiOverride);
   9360             } catch (IOException e) {
   9361                 Slog.e(TAG, "Copying native libraries failed", e);
   9362                 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
   9363             } finally {
   9364                 IoUtils.closeQuietly(handle);
   9365             }
   9366 
   9367             return ret;
   9368         }
   9369 
   9370         int doPreInstall(int status) {
   9371             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9372                 cleanUp();
   9373             }
   9374             return status;
   9375         }
   9376 
   9377         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
   9378             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9379                 cleanUp();
   9380                 return false;
   9381             } else {
   9382                 final File beforeCodeFile = codeFile;
   9383                 final File afterCodeFile = getNextCodePath(pkg.packageName);
   9384 
   9385                 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
   9386                 try {
   9387                     Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
   9388                 } catch (ErrnoException e) {
   9389                     Slog.d(TAG, "Failed to rename", e);
   9390                     return false;
   9391                 }
   9392 
   9393                 if (!SELinux.restoreconRecursive(afterCodeFile)) {
   9394                     Slog.d(TAG, "Failed to restorecon");
   9395                     return false;
   9396                 }
   9397 
   9398                 // Reflect the rename internally
   9399                 codeFile = afterCodeFile;
   9400                 resourceFile = afterCodeFile;
   9401 
   9402                 // Reflect the rename in scanned details
   9403                 pkg.codePath = afterCodeFile.getAbsolutePath();
   9404                 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
   9405                         pkg.baseCodePath);
   9406                 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
   9407                         pkg.splitCodePaths);
   9408 
   9409                 // Reflect the rename in app info
   9410                 pkg.applicationInfo.setCodePath(pkg.codePath);
   9411                 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
   9412                 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
   9413                 pkg.applicationInfo.setResourcePath(pkg.codePath);
   9414                 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
   9415                 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
   9416 
   9417                 return true;
   9418             }
   9419         }
   9420 
   9421         int doPostInstall(int status, int uid) {
   9422             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9423                 cleanUp();
   9424             }
   9425             return status;
   9426         }
   9427 
   9428         @Override
   9429         String getCodePath() {
   9430             return (codeFile != null) ? codeFile.getAbsolutePath() : null;
   9431         }
   9432 
   9433         @Override
   9434         String getResourcePath() {
   9435             return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
   9436         }
   9437 
   9438         @Override
   9439         String getLegacyNativeLibraryPath() {
   9440             return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null;
   9441         }
   9442 
   9443         private boolean cleanUp() {
   9444             if (codeFile == null || !codeFile.exists()) {
   9445                 return false;
   9446             }
   9447 
   9448             if (codeFile.isDirectory()) {
   9449                 FileUtils.deleteContents(codeFile);
   9450             }
   9451             codeFile.delete();
   9452 
   9453             if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
   9454                 resourceFile.delete();
   9455             }
   9456 
   9457             if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) {
   9458                 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) {
   9459                     Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath);
   9460                 }
   9461                 legacyNativeLibraryPath.delete();
   9462             }
   9463 
   9464             return true;
   9465         }
   9466 
   9467         void cleanUpResourcesLI() {
   9468             // Try enumerating all code paths before deleting
   9469             List<String> allCodePaths = Collections.EMPTY_LIST;
   9470             if (codeFile != null && codeFile.exists()) {
   9471                 try {
   9472                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
   9473                     allCodePaths = pkg.getAllCodePaths();
   9474                 } catch (PackageParserException e) {
   9475                     // Ignored; we tried our best
   9476                 }
   9477             }
   9478 
   9479             cleanUp();
   9480 
   9481             if (!allCodePaths.isEmpty()) {
   9482                 if (instructionSets == null) {
   9483                     throw new IllegalStateException("instructionSet == null");
   9484                 }
   9485                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
   9486                 for (String codePath : allCodePaths) {
   9487                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   9488                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
   9489                         if (retCode < 0) {
   9490                             Slog.w(TAG, "Couldn't remove dex file for package: "
   9491                                     + " at location " + codePath + ", retcode=" + retCode);
   9492                             // we don't consider this to be a failure of the core package deletion
   9493                         }
   9494                     }
   9495                 }
   9496             }
   9497         }
   9498 
   9499         boolean doPostDeleteLI(boolean delete) {
   9500             // XXX err, shouldn't we respect the delete flag?
   9501             cleanUpResourcesLI();
   9502             return true;
   9503         }
   9504     }
   9505 
   9506     private boolean isAsecExternal(String cid) {
   9507         final String asecPath = PackageHelper.getSdFilesystem(cid);
   9508         return !asecPath.startsWith(mAsecInternalPath);
   9509     }
   9510 
   9511     private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
   9512             PackageManagerException {
   9513         if (copyRet < 0) {
   9514             if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
   9515                     copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
   9516                 throw new PackageManagerException(copyRet, message);
   9517             }
   9518         }
   9519     }
   9520 
   9521     /**
   9522      * Extract the MountService "container ID" from the full code path of an
   9523      * .apk.
   9524      */
   9525     static String cidFromCodePath(String fullCodePath) {
   9526         int eidx = fullCodePath.lastIndexOf("/");
   9527         String subStr1 = fullCodePath.substring(0, eidx);
   9528         int sidx = subStr1.lastIndexOf("/");
   9529         return subStr1.substring(sidx+1, eidx);
   9530     }
   9531 
   9532     /**
   9533      * Logic to handle installation of ASEC applications, including copying and
   9534      * renaming logic.
   9535      */
   9536     class AsecInstallArgs extends InstallArgs {
   9537         static final String RES_FILE_NAME = "pkg.apk";
   9538         static final String PUBLIC_RES_FILE_NAME = "res.zip";
   9539 
   9540         String cid;
   9541         String packagePath;
   9542         String resourcePath;
   9543         String legacyNativeLibraryDir;
   9544 
   9545         /** New install */
   9546         AsecInstallArgs(InstallParams params) {
   9547             super(params.origin, params.observer, params.installFlags,
   9548                     params.installerPackageName, params.getManifestDigest(),
   9549                     params.getUser(), null /* instruction sets */,
   9550                     params.packageAbiOverride);
   9551         }
   9552 
   9553         /** Existing install */
   9554         AsecInstallArgs(String fullCodePath, String[] instructionSets,
   9555                         boolean isExternal, boolean isForwardLocked) {
   9556             super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0)
   9557                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
   9558                     instructionSets, null);
   9559             // Hackily pretend we're still looking at a full code path
   9560             if (!fullCodePath.endsWith(RES_FILE_NAME)) {
   9561                 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
   9562             }
   9563 
   9564             // Extract cid from fullCodePath
   9565             int eidx = fullCodePath.lastIndexOf("/");
   9566             String subStr1 = fullCodePath.substring(0, eidx);
   9567             int sidx = subStr1.lastIndexOf("/");
   9568             cid = subStr1.substring(sidx+1, eidx);
   9569             setMountPath(subStr1);
   9570         }
   9571 
   9572         AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
   9573             super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
   9574                     | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
   9575                     instructionSets, null);
   9576             this.cid = cid;
   9577             setMountPath(PackageHelper.getSdDir(cid));
   9578         }
   9579 
   9580         void createCopyFile() {
   9581             cid = mInstallerService.allocateExternalStageCidLegacy();
   9582         }
   9583 
   9584         boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
   9585             final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(),
   9586                     abiOverride);
   9587 
   9588             final File target;
   9589             if (isExternal()) {
   9590                 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory();
   9591             } else {
   9592                 target = Environment.getDataDirectory();
   9593             }
   9594 
   9595             final StorageManager storage = StorageManager.from(mContext);
   9596             return (sizeBytes <= storage.getStorageBytesUntilLow(target));
   9597         }
   9598 
   9599         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
   9600             if (origin.staged) {
   9601                 Slog.d(TAG, origin.cid + " already staged; skipping copy");
   9602                 cid = origin.cid;
   9603                 setMountPath(PackageHelper.getSdDir(cid));
   9604                 return PackageManager.INSTALL_SUCCEEDED;
   9605             }
   9606 
   9607             if (temp) {
   9608                 createCopyFile();
   9609             } else {
   9610                 /*
   9611                  * Pre-emptively destroy the container since it's destroyed if
   9612                  * copying fails due to it existing anyway.
   9613                  */
   9614                 PackageHelper.destroySdDir(cid);
   9615             }
   9616 
   9617             final String newMountPath = imcs.copyPackageToContainer(
   9618                     origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
   9619                     isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
   9620 
   9621             if (newMountPath != null) {
   9622                 setMountPath(newMountPath);
   9623                 return PackageManager.INSTALL_SUCCEEDED;
   9624             } else {
   9625                 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9626             }
   9627         }
   9628 
   9629         @Override
   9630         String getCodePath() {
   9631             return packagePath;
   9632         }
   9633 
   9634         @Override
   9635         String getResourcePath() {
   9636             return resourcePath;
   9637         }
   9638 
   9639         @Override
   9640         String getLegacyNativeLibraryPath() {
   9641             return legacyNativeLibraryDir;
   9642         }
   9643 
   9644         int doPreInstall(int status) {
   9645             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9646                 // Destroy container
   9647                 PackageHelper.destroySdDir(cid);
   9648             } else {
   9649                 boolean mounted = PackageHelper.isContainerMounted(cid);
   9650                 if (!mounted) {
   9651                     String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
   9652                             Process.SYSTEM_UID);
   9653                     if (newMountPath != null) {
   9654                         setMountPath(newMountPath);
   9655                     } else {
   9656                         return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9657                     }
   9658                 }
   9659             }
   9660             return status;
   9661         }
   9662 
   9663         boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
   9664             String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
   9665             String newMountPath = null;
   9666             if (PackageHelper.isContainerMounted(cid)) {
   9667                 // Unmount the container
   9668                 if (!PackageHelper.unMountSdDir(cid)) {
   9669                     Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
   9670                     return false;
   9671                 }
   9672             }
   9673             if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   9674                 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
   9675                         " which might be stale. Will try to clean up.");
   9676                 // Clean up the stale container and proceed to recreate.
   9677                 if (!PackageHelper.destroySdDir(newCacheId)) {
   9678                     Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
   9679                     return false;
   9680                 }
   9681                 // Successfully cleaned up stale container. Try to rename again.
   9682                 if (!PackageHelper.renameSdDir(cid, newCacheId)) {
   9683                     Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
   9684                             + " inspite of cleaning it up.");
   9685                     return false;
   9686                 }
   9687             }
   9688             if (!PackageHelper.isContainerMounted(newCacheId)) {
   9689                 Slog.w(TAG, "Mounting container " + newCacheId);
   9690                 newMountPath = PackageHelper.mountSdDir(newCacheId,
   9691                         getEncryptKey(), Process.SYSTEM_UID);
   9692             } else {
   9693                 newMountPath = PackageHelper.getSdDir(newCacheId);
   9694             }
   9695             if (newMountPath == null) {
   9696                 Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
   9697                 return false;
   9698             }
   9699             Log.i(TAG, "Succesfully renamed " + cid +
   9700                     " to " + newCacheId +
   9701                     " at new path: " + newMountPath);
   9702             cid = newCacheId;
   9703 
   9704             final File beforeCodeFile = new File(packagePath);
   9705             setMountPath(newMountPath);
   9706             final File afterCodeFile = new File(packagePath);
   9707 
   9708             // Reflect the rename in scanned details
   9709             pkg.codePath = afterCodeFile.getAbsolutePath();
   9710             pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
   9711                     pkg.baseCodePath);
   9712             pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
   9713                     pkg.splitCodePaths);
   9714 
   9715             // Reflect the rename in app info
   9716             pkg.applicationInfo.setCodePath(pkg.codePath);
   9717             pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
   9718             pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
   9719             pkg.applicationInfo.setResourcePath(pkg.codePath);
   9720             pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
   9721             pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
   9722 
   9723             return true;
   9724         }
   9725 
   9726         private void setMountPath(String mountPath) {
   9727             final File mountFile = new File(mountPath);
   9728 
   9729             final File monolithicFile = new File(mountFile, RES_FILE_NAME);
   9730             if (monolithicFile.exists()) {
   9731                 packagePath = monolithicFile.getAbsolutePath();
   9732                 if (isFwdLocked()) {
   9733                     resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
   9734                 } else {
   9735                     resourcePath = packagePath;
   9736                 }
   9737             } else {
   9738                 packagePath = mountFile.getAbsolutePath();
   9739                 resourcePath = packagePath;
   9740             }
   9741 
   9742             legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath();
   9743         }
   9744 
   9745         int doPostInstall(int status, int uid) {
   9746             if (status != PackageManager.INSTALL_SUCCEEDED) {
   9747                 cleanUp();
   9748             } else {
   9749                 final int groupOwner;
   9750                 final String protectedFile;
   9751                 if (isFwdLocked()) {
   9752                     groupOwner = UserHandle.getSharedAppGid(uid);
   9753                     protectedFile = RES_FILE_NAME;
   9754                 } else {
   9755                     groupOwner = -1;
   9756                     protectedFile = null;
   9757                 }
   9758 
   9759                 if (uid < Process.FIRST_APPLICATION_UID
   9760                         || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
   9761                     Slog.e(TAG, "Failed to finalize " + cid);
   9762                     PackageHelper.destroySdDir(cid);
   9763                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9764                 }
   9765 
   9766                 boolean mounted = PackageHelper.isContainerMounted(cid);
   9767                 if (!mounted) {
   9768                     PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
   9769                 }
   9770             }
   9771             return status;
   9772         }
   9773 
   9774         private void cleanUp() {
   9775             if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
   9776 
   9777             // Destroy secure container
   9778             PackageHelper.destroySdDir(cid);
   9779         }
   9780 
   9781         private List<String> getAllCodePaths() {
   9782             final File codeFile = new File(getCodePath());
   9783             if (codeFile != null && codeFile.exists()) {
   9784                 try {
   9785                     final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
   9786                     return pkg.getAllCodePaths();
   9787                 } catch (PackageParserException e) {
   9788                     // Ignored; we tried our best
   9789                 }
   9790             }
   9791             return Collections.EMPTY_LIST;
   9792         }
   9793 
   9794         void cleanUpResourcesLI() {
   9795             // Enumerate all code paths before deleting
   9796             cleanUpResourcesLI(getAllCodePaths());
   9797         }
   9798 
   9799         private void cleanUpResourcesLI(List<String> allCodePaths) {
   9800             cleanUp();
   9801 
   9802             if (!allCodePaths.isEmpty()) {
   9803                 if (instructionSets == null) {
   9804                     throw new IllegalStateException("instructionSet == null");
   9805                 }
   9806                 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
   9807                 for (String codePath : allCodePaths) {
   9808                     for (String dexCodeInstructionSet : dexCodeInstructionSets) {
   9809                         int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet);
   9810                         if (retCode < 0) {
   9811                             Slog.w(TAG, "Couldn't remove dex file for package: "
   9812                                     + " at location " + codePath + ", retcode=" + retCode);
   9813                             // we don't consider this to be a failure of the core package deletion
   9814                         }
   9815                     }
   9816                 }
   9817             }
   9818         }
   9819 
   9820         boolean matchContainer(String app) {
   9821             if (cid.startsWith(app)) {
   9822                 return true;
   9823             }
   9824             return false;
   9825         }
   9826 
   9827         String getPackageName() {
   9828             return getAsecPackageName(cid);
   9829         }
   9830 
   9831         boolean doPostDeleteLI(boolean delete) {
   9832             if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
   9833             final List<String> allCodePaths = getAllCodePaths();
   9834             boolean mounted = PackageHelper.isContainerMounted(cid);
   9835             if (mounted) {
   9836                 // Unmount first
   9837                 if (PackageHelper.unMountSdDir(cid)) {
   9838                     mounted = false;
   9839                 }
   9840             }
   9841             if (!mounted && delete) {
   9842                 cleanUpResourcesLI(allCodePaths);
   9843             }
   9844             return !mounted;
   9845         }
   9846 
   9847         @Override
   9848         int doPreCopy() {
   9849             if (isFwdLocked()) {
   9850                 if (!PackageHelper.fixSdPermissions(cid,
   9851                         getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) {
   9852                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9853                 }
   9854             }
   9855 
   9856             return PackageManager.INSTALL_SUCCEEDED;
   9857         }
   9858 
   9859         @Override
   9860         int doPostCopy(int uid) {
   9861             if (isFwdLocked()) {
   9862                 if (uid < Process.FIRST_APPLICATION_UID
   9863                         || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
   9864                                 RES_FILE_NAME)) {
   9865                     Slog.e(TAG, "Failed to finalize " + cid);
   9866                     PackageHelper.destroySdDir(cid);
   9867                     return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   9868                 }
   9869             }
   9870 
   9871             return PackageManager.INSTALL_SUCCEEDED;
   9872         }
   9873     }
   9874 
   9875     static String getAsecPackageName(String packageCid) {
   9876         int idx = packageCid.lastIndexOf("-");
   9877         if (idx == -1) {
   9878             return packageCid;
   9879         }
   9880         return packageCid.substring(0, idx);
   9881     }
   9882 
   9883     // Utility method used to create code paths based on package name and available index.
   9884     private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
   9885         String idxStr = "";
   9886         int idx = 1;
   9887         // Fall back to default value of idx=1 if prefix is not
   9888         // part of oldCodePath
   9889         if (oldCodePath != null) {
   9890             String subStr = oldCodePath;
   9891             // Drop the suffix right away
   9892             if (suffix != null && subStr.endsWith(suffix)) {
   9893                 subStr = subStr.substring(0, subStr.length() - suffix.length());
   9894             }
   9895             // If oldCodePath already contains prefix find out the
   9896             // ending index to either increment or decrement.
   9897             int sidx = subStr.lastIndexOf(prefix);
   9898             if (sidx != -1) {
   9899                 subStr = subStr.substring(sidx + prefix.length());
   9900                 if (subStr != null) {
   9901                     if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
   9902                         subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
   9903                     }
   9904                     try {
   9905                         idx = Integer.parseInt(subStr);
   9906                         if (idx <= 1) {
   9907                             idx++;
   9908                         } else {
   9909                             idx--;
   9910                         }
   9911                     } catch(NumberFormatException e) {
   9912                     }
   9913                 }
   9914             }
   9915         }
   9916         idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
   9917         return prefix + idxStr;
   9918     }
   9919 
   9920     private File getNextCodePath(String packageName) {
   9921         int suffix = 1;
   9922         File result;
   9923         do {
   9924             result = new File(mAppInstallDir, packageName + "-" + suffix);
   9925             suffix++;
   9926         } while (result.exists());
   9927         return result;
   9928     }
   9929 
   9930     // Utility method used to ignore ADD/REMOVE events
   9931     // by directory observer.
   9932     private static boolean ignoreCodePath(String fullPathStr) {
   9933         String apkName = deriveCodePathName(fullPathStr);
   9934         int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX);
   9935         if (idx != -1 && ((idx+1) < apkName.length())) {
   9936             // Make sure the package ends with a numeral
   9937             String version = apkName.substring(idx+1);
   9938             try {
   9939                 Integer.parseInt(version);
   9940                 return true;
   9941             } catch (NumberFormatException e) {}
   9942         }
   9943         return false;
   9944     }
   9945 
   9946     // Utility method that returns the relative package path with respect
   9947     // to the installation directory. Like say for /data/data/com.test-1.apk
   9948     // string com.test-1 is returned.
   9949     static String deriveCodePathName(String codePath) {
   9950         if (codePath == null) {
   9951             return null;
   9952         }
   9953         final File codeFile = new File(codePath);
   9954         final String name = codeFile.getName();
   9955         if (codeFile.isDirectory()) {
   9956             return name;
   9957         } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
   9958             final int lastDot = name.lastIndexOf('.');
   9959             return name.substring(0, lastDot);
   9960         } else {
   9961             Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
   9962             return null;
   9963         }
   9964     }
   9965 
   9966     class PackageInstalledInfo {
   9967         String name;
   9968         int uid;
   9969         // The set of users that originally had this package installed.
   9970         int[] origUsers;
   9971         // The set of users that now have this package installed.
   9972         int[] newUsers;
   9973         PackageParser.Package pkg;
   9974         int returnCode;
   9975         String returnMsg;
   9976         PackageRemovedInfo removedInfo;
   9977 
   9978         public void setError(int code, String msg) {
   9979             returnCode = code;
   9980             returnMsg = msg;
   9981             Slog.w(TAG, msg);
   9982         }
   9983 
   9984         public void setError(String msg, PackageParserException e) {
   9985             returnCode = e.error;
   9986             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
   9987             Slog.w(TAG, msg, e);
   9988         }
   9989 
   9990         public void setError(String msg, PackageManagerException e) {
   9991             returnCode = e.error;
   9992             returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
   9993             Slog.w(TAG, msg, e);
   9994         }
   9995 
   9996         // In some error cases we want to convey more info back to the observer
   9997         String origPackage;
   9998         String origPermission;
   9999     }
   10000 
   10001     /*
   10002      * Install a non-existing package.
   10003      */
   10004     private void installNewPackageLI(PackageParser.Package pkg,
   10005             int parseFlags, int scanFlags, UserHandle user,
   10006             String installerPackageName, PackageInstalledInfo res) {
   10007         // Remember this for later, in case we need to rollback this install
   10008         String pkgName = pkg.packageName;
   10009 
   10010         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
   10011         boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists();
   10012         synchronized(mPackages) {
   10013             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
   10014                 // A package with the same name is already installed, though
   10015                 // it has been renamed to an older name.  The package we
   10016                 // are trying to install should be installed as an update to
   10017                 // the existing one, but that has not been requested, so bail.
   10018                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
   10019                         + " without first uninstalling package running as "
   10020                         + mSettings.mRenamedPackages.get(pkgName));
   10021                 return;
   10022             }
   10023             if (mPackages.containsKey(pkgName)) {
   10024                 // Don't allow installation over an existing package with the same name.
   10025                 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
   10026                         + " without first uninstalling.");
   10027                 return;
   10028             }
   10029         }
   10030 
   10031         try {
   10032             PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags,
   10033                     System.currentTimeMillis(), user);
   10034 
   10035             updateSettingsLI(newPackage, installerPackageName, null, null, res);
   10036             // delete the partially installed application. the data directory will have to be
   10037             // restored if it was already existing
   10038             if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   10039                 // remove package from internal structures.  Note that we want deletePackageX to
   10040                 // delete the package data and cache directories that it created in
   10041                 // scanPackageLocked, unless those directories existed before we even tried to
   10042                 // install.
   10043                 deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
   10044                         dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
   10045                                 res.removedInfo, true);
   10046             }
   10047 
   10048         } catch (PackageManagerException e) {
   10049             res.setError("Package couldn't be installed in " + pkg.codePath, e);
   10050         }
   10051     }
   10052 
   10053     private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
   10054         // Upgrade keysets are being used.  Determine if new package has a superset of the
   10055         // required keys.
   10056         long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
   10057         KeySetManagerService ksms = mSettings.mKeySetManagerService;
   10058         for (int i = 0; i < upgradeKeySets.length; i++) {
   10059             Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
   10060             if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
   10061                 return true;
   10062             }
   10063         }
   10064         return false;
   10065     }
   10066 
   10067     private void replacePackageLI(PackageParser.Package pkg,
   10068             int parseFlags, int scanFlags, UserHandle user,
   10069             String installerPackageName, PackageInstalledInfo res) {
   10070         PackageParser.Package oldPackage;
   10071         String pkgName = pkg.packageName;
   10072         int[] allUsers;
   10073         boolean[] perUserInstalled;
   10074 
   10075         // First find the old package info and check signatures
   10076         synchronized(mPackages) {
   10077             oldPackage = mPackages.get(pkgName);
   10078             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
   10079             PackageSetting ps = mSettings.mPackages.get(pkgName);
   10080             if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) {
   10081                 // default to original signature matching
   10082                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
   10083                     != PackageManager.SIGNATURE_MATCH) {
   10084                     res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
   10085                             "New package has a different signature: " + pkgName);
   10086                     return;
   10087                 }
   10088             } else {
   10089                 if(!checkUpgradeKeySetLP(ps, pkg)) {
   10090                     res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
   10091                             "New package not signed by keys specified by upgrade-keysets: "
   10092                             + pkgName);
   10093                     return;
   10094                 }
   10095             }
   10096 
   10097             // In case of rollback, remember per-user/profile install state
   10098             allUsers = sUserManager.getUserIds();
   10099             perUserInstalled = new boolean[allUsers.length];
   10100             for (int i = 0; i < allUsers.length; i++) {
   10101                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
   10102             }
   10103         }
   10104 
   10105         boolean sysPkg = (isSystemApp(oldPackage));
   10106         if (sysPkg) {
   10107             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
   10108                     user, allUsers, perUserInstalled, installerPackageName, res);
   10109         } else {
   10110             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
   10111                     user, allUsers, perUserInstalled, installerPackageName, res);
   10112         }
   10113     }
   10114 
   10115     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
   10116             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
   10117             int[] allUsers, boolean[] perUserInstalled,
   10118             String installerPackageName, PackageInstalledInfo res) {
   10119         String pkgName = deletedPackage.packageName;
   10120         boolean deletedPkg = true;
   10121         boolean updatedSettings = false;
   10122 
   10123         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
   10124                 + deletedPackage);
   10125         long origUpdateTime;
   10126         if (pkg.mExtras != null) {
   10127             origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
   10128         } else {
   10129             origUpdateTime = 0;
   10130         }
   10131 
   10132         // First delete the existing package while retaining the data directory
   10133         if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
   10134                 res.removedInfo, true)) {
   10135             // If the existing package wasn't successfully deleted
   10136             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
   10137             deletedPkg = false;
   10138         } else {
   10139             // Successfully deleted the old package; proceed with replace.
   10140 
   10141             // If deleted package lived in a container, give users a chance to
   10142             // relinquish resources before killing.
   10143             if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) {
   10144                 if (DEBUG_INSTALL) {
   10145                     Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
   10146                 }
   10147                 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
   10148                 final ArrayList<String> pkgList = new ArrayList<String>(1);
   10149                 pkgList.add(deletedPackage.applicationInfo.packageName);
   10150                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
   10151             }
   10152 
   10153             deleteCodeCacheDirsLI(pkgName);
   10154             try {
   10155                 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
   10156                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
   10157                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
   10158                 updatedSettings = true;
   10159             } catch (PackageManagerException e) {
   10160                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
   10161             }
   10162         }
   10163 
   10164         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   10165             // remove package from internal structures.  Note that we want deletePackageX to
   10166             // delete the package data and cache directories that it created in
   10167             // scanPackageLocked, unless those directories existed before we even tried to
   10168             // install.
   10169             if(updatedSettings) {
   10170                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
   10171                 deletePackageLI(
   10172                         pkgName, null, true, allUsers, perUserInstalled,
   10173                         PackageManager.DELETE_KEEP_DATA,
   10174                                 res.removedInfo, true);
   10175             }
   10176             // Since we failed to install the new package we need to restore the old
   10177             // package that we deleted.
   10178             if (deletedPkg) {
   10179                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
   10180                 File restoreFile = new File(deletedPackage.codePath);
   10181                 // Parse old package
   10182                 boolean oldOnSd = isExternal(deletedPackage);
   10183                 int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
   10184                         (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
   10185                         (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
   10186                 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
   10187                 try {
   10188                     scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null);
   10189                 } catch (PackageManagerException e) {
   10190                     Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
   10191                             + e.getMessage());
   10192                     return;
   10193                 }
   10194                 // Restore of old package succeeded. Update permissions.
   10195                 // writer
   10196                 synchronized (mPackages) {
   10197                     updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
   10198                             UPDATE_PERMISSIONS_ALL);
   10199                     // can downgrade to reader
   10200                     mSettings.writeLPr();
   10201                 }
   10202                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
   10203             }
   10204         }
   10205     }
   10206 
   10207     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
   10208             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
   10209             int[] allUsers, boolean[] perUserInstalled,
   10210             String installerPackageName, PackageInstalledInfo res) {
   10211         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
   10212                 + ", old=" + deletedPackage);
   10213         boolean disabledSystem = false;
   10214         boolean updatedSettings = false;
   10215         parseFlags |= PackageParser.PARSE_IS_SYSTEM;
   10216         if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) {
   10217             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   10218         }
   10219         String packageName = deletedPackage.packageName;
   10220         if (packageName == null) {
   10221             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
   10222                     "Attempt to delete null packageName.");
   10223             return;
   10224         }
   10225         PackageParser.Package oldPkg;
   10226         PackageSetting oldPkgSetting;
   10227         // reader
   10228         synchronized (mPackages) {
   10229             oldPkg = mPackages.get(packageName);
   10230             oldPkgSetting = mSettings.mPackages.get(packageName);
   10231             if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
   10232                     (oldPkgSetting == null)) {
   10233                 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
   10234                         "Couldn't find package:" + packageName + " information");
   10235                 return;
   10236             }
   10237         }
   10238 
   10239         killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
   10240 
   10241         res.removedInfo.uid = oldPkg.applicationInfo.uid;
   10242         res.removedInfo.removedPackage = packageName;
   10243         // Remove existing system package
   10244         removePackageLI(oldPkgSetting, true);
   10245         // writer
   10246         synchronized (mPackages) {
   10247             disabledSystem = mSettings.disableSystemPackageLPw(packageName);
   10248             if (!disabledSystem && deletedPackage != null) {
   10249                 // We didn't need to disable the .apk as a current system package,
   10250                 // which means we are replacing another update that is already
   10251                 // installed.  We need to make sure to delete the older one's .apk.
   10252                 res.removedInfo.args = createInstallArgsForExisting(0,
   10253                         deletedPackage.applicationInfo.getCodePath(),
   10254                         deletedPackage.applicationInfo.getResourcePath(),
   10255                         deletedPackage.applicationInfo.nativeLibraryRootDir,
   10256                         getAppDexInstructionSets(deletedPackage.applicationInfo));
   10257             } else {
   10258                 res.removedInfo.args = null;
   10259             }
   10260         }
   10261 
   10262         // Successfully disabled the old package. Now proceed with re-installation
   10263         deleteCodeCacheDirsLI(packageName);
   10264 
   10265         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   10266         pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
   10267 
   10268         PackageParser.Package newPackage = null;
   10269         try {
   10270             newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user);
   10271             if (newPackage.mExtras != null) {
   10272                 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
   10273                 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
   10274                 newPkgSetting.lastUpdateTime = System.currentTimeMillis();
   10275 
   10276                 // is the update attempting to change shared user? that isn't going to work...
   10277                 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
   10278                     res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
   10279                             "Forbidding shared user change from " + oldPkgSetting.sharedUser
   10280                             + " to " + newPkgSetting.sharedUser);
   10281                     updatedSettings = true;
   10282                 }
   10283             }
   10284 
   10285             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
   10286                 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
   10287                 updatedSettings = true;
   10288             }
   10289 
   10290         } catch (PackageManagerException e) {
   10291             res.setError("Package couldn't be installed in " + pkg.codePath, e);
   10292         }
   10293 
   10294         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
   10295             // Re installation failed. Restore old information
   10296             // Remove new pkg information
   10297             if (newPackage != null) {
   10298                 removeInstalledPackageLI(newPackage, true);
   10299             }
   10300             // Add back the old system package
   10301             try {
   10302                 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
   10303             } catch (PackageManagerException e) {
   10304                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
   10305             }
   10306             // Restore the old system information in Settings
   10307             synchronized (mPackages) {
   10308                 if (disabledSystem) {
   10309                     mSettings.enableSystemPackageLPw(packageName);
   10310                 }
   10311                 if (updatedSettings) {
   10312                     mSettings.setInstallerPackageName(packageName,
   10313                             oldPkgSetting.installerPackageName);
   10314                 }
   10315                 mSettings.writeLPr();
   10316             }
   10317         }
   10318     }
   10319 
   10320     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
   10321             int[] allUsers, boolean[] perUserInstalled,
   10322             PackageInstalledInfo res) {
   10323         String pkgName = newPackage.packageName;
   10324         synchronized (mPackages) {
   10325             //write settings. the installStatus will be incomplete at this stage.
   10326             //note that the new package setting would have already been
   10327             //added to mPackages. It hasn't been persisted yet.
   10328             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
   10329             mSettings.writeLPr();
   10330         }
   10331 
   10332         if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
   10333 
   10334         synchronized (mPackages) {
   10335             updatePermissionsLPw(newPackage.packageName, newPackage,
   10336                     UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
   10337                             ? UPDATE_PERMISSIONS_ALL : 0));
   10338             // For system-bundled packages, we assume that installing an upgraded version
   10339             // of the package implies that the user actually wants to run that new code,
   10340             // so we enable the package.
   10341             if (isSystemApp(newPackage)) {
   10342                 // NB: implicit assumption that system package upgrades apply to all users
   10343                 if (DEBUG_INSTALL) {
   10344                     Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
   10345                 }
   10346                 PackageSetting ps = mSettings.mPackages.get(pkgName);
   10347                 if (ps != null) {
   10348                     if (res.origUsers != null) {
   10349                         for (int userHandle : res.origUsers) {
   10350                             ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
   10351                                     userHandle, installerPackageName);
   10352                         }
   10353                     }
   10354                     // Also convey the prior install/uninstall state
   10355                     if (allUsers != null && perUserInstalled != null) {
   10356                         for (int i = 0; i < allUsers.length; i++) {
   10357                             if (DEBUG_INSTALL) {
   10358                                 Slog.d(TAG, "    user " + allUsers[i]
   10359                                         + " => " + perUserInstalled[i]);
   10360                             }
   10361                             ps.setInstalled(perUserInstalled[i], allUsers[i]);
   10362                         }
   10363                         // these install state changes will be persisted in the
   10364                         // upcoming call to mSettings.writeLPr().
   10365                     }
   10366                 }
   10367             }
   10368             res.name = pkgName;
   10369             res.uid = newPackage.applicationInfo.uid;
   10370             res.pkg = newPackage;
   10371             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
   10372             mSettings.setInstallerPackageName(pkgName, installerPackageName);
   10373             res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   10374             //to update install status
   10375             mSettings.writeLPr();
   10376         }
   10377     }
   10378 
   10379     private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
   10380         final int installFlags = args.installFlags;
   10381         String installerPackageName = args.installerPackageName;
   10382         File tmpPackageFile = new File(args.getCodePath());
   10383         boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
   10384         boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0);
   10385         boolean replace = false;
   10386         final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE;
   10387         // Result object to be returned
   10388         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
   10389 
   10390         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
   10391         // Retrieve PackageSettings and parse package
   10392         final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
   10393                 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
   10394                 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
   10395         PackageParser pp = new PackageParser();
   10396         pp.setSeparateProcesses(mSeparateProcesses);
   10397         pp.setDisplayMetrics(mMetrics);
   10398 
   10399         final PackageParser.Package pkg;
   10400         try {
   10401             pkg = pp.parsePackage(tmpPackageFile, parseFlags);
   10402         } catch (PackageParserException e) {
   10403             res.setError("Failed parse during installPackageLI", e);
   10404             return;
   10405         }
   10406 
   10407         // Mark that we have an install time CPU ABI override.
   10408         pkg.cpuAbiOverride = args.abiOverride;
   10409 
   10410         String pkgName = res.name = pkg.packageName;
   10411         if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
   10412             if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
   10413                 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
   10414                 return;
   10415             }
   10416         }
   10417 
   10418         try {
   10419             pp.collectCertificates(pkg, parseFlags);
   10420             pp.collectManifestDigest(pkg);
   10421         } catch (PackageParserException e) {
   10422             res.setError("Failed collect during installPackageLI", e);
   10423             return;
   10424         }
   10425 
   10426         /* If the installer passed in a manifest digest, compare it now. */
   10427         if (args.manifestDigest != null) {
   10428             if (DEBUG_INSTALL) {
   10429                 final String parsedManifest = pkg.manifestDigest == null ? "null"
   10430                         : pkg.manifestDigest.toString();
   10431                 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. "
   10432                         + parsedManifest);
   10433             }
   10434 
   10435             if (!args.manifestDigest.equals(pkg.manifestDigest)) {
   10436                 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed");
   10437                 return;
   10438             }
   10439         } else if (DEBUG_INSTALL) {
   10440             final String parsedManifest = pkg.manifestDigest == null
   10441                     ? "null" : pkg.manifestDigest.toString();
   10442             Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest);
   10443         }
   10444 
   10445         // Get rid of all references to package scan path via parser.
   10446         pp = null;
   10447         String oldCodePath = null;
   10448         boolean systemApp = false;
   10449         synchronized (mPackages) {
   10450             // Check whether the newly-scanned package wants to define an already-defined perm
   10451             int N = pkg.permissions.size();
   10452             for (int i = N-1; i >= 0; i--) {
   10453                 PackageParser.Permission perm = pkg.permissions.get(i);
   10454                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
   10455                 if (bp != null) {
   10456                     // If the defining package is signed with our cert, it's okay.  This
   10457                     // also includes the "updating the same package" case, of course.
   10458                     // "updating same package" could also involve key-rotation.
   10459                     final boolean sigsOk;
   10460                     if (!bp.sourcePackage.equals(pkg.packageName)
   10461                             || !(bp.packageSetting instanceof PackageSetting)
   10462                             || !bp.packageSetting.keySetData.isUsingUpgradeKeySets()
   10463                             || ((PackageSetting) bp.packageSetting).sharedUser != null) {
   10464                         sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
   10465                                 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
   10466                     } else {
   10467                         sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
   10468                     }
   10469                     if (!sigsOk) {
   10470                         // If the owning package is the system itself, we log but allow
   10471                         // install to proceed; we fail the install on all other permission
   10472                         // redefinitions.
   10473                         if (!bp.sourcePackage.equals("android")) {
   10474                             res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
   10475                                     + pkg.packageName + " attempting to redeclare permission "
   10476                                     + perm.info.name + " already owned by " + bp.sourcePackage);
   10477                             res.origPermission = perm.info.name;
   10478                             res.origPackage = bp.sourcePackage;
   10479                             return;
   10480                         } else {
   10481                             Slog.w(TAG, "Package " + pkg.packageName
   10482                                     + " attempting to redeclare system permission "
   10483                                     + perm.info.name + "; ignoring new declaration");
   10484                             pkg.permissions.remove(i);
   10485                         }
   10486                     }
   10487                 }
   10488             }
   10489 
   10490             // Check if installing already existing package
   10491             if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
   10492                 String oldName = mSettings.mRenamedPackages.get(pkgName);
   10493                 if (pkg.mOriginalPackages != null
   10494                         && pkg.mOriginalPackages.contains(oldName)
   10495                         && mPackages.containsKey(oldName)) {
   10496                     // This package is derived from an original package,
   10497                     // and this device has been updating from that original
   10498                     // name.  We must continue using the original name, so
   10499                     // rename the new package here.
   10500                     pkg.setPackageName(oldName);
   10501                     pkgName = pkg.packageName;
   10502                     replace = true;
   10503                     if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
   10504                             + oldName + " pkgName=" + pkgName);
   10505                 } else if (mPackages.containsKey(pkgName)) {
   10506                     // This package, under its official name, already exists
   10507                     // on the device; we should replace it.
   10508                     replace = true;
   10509                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
   10510                 }
   10511             }
   10512             PackageSetting ps = mSettings.mPackages.get(pkgName);
   10513             if (ps != null) {
   10514                 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
   10515                 oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
   10516                 if (ps.pkg != null && ps.pkg.applicationInfo != null) {
   10517                     systemApp = (ps.pkg.applicationInfo.flags &
   10518                             ApplicationInfo.FLAG_SYSTEM) != 0;
   10519                 }
   10520                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
   10521             }
   10522         }
   10523 
   10524         if (systemApp && onSd) {
   10525             // Disable updates to system apps on sdcard
   10526             res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
   10527                     "Cannot install updates to system apps on sdcard");
   10528             return;
   10529         }
   10530 
   10531         if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
   10532             res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
   10533             return;
   10534         }
   10535 
   10536         if (replace) {
   10537             replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
   10538                     installerPackageName, res);
   10539         } else {
   10540             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
   10541                     args.user, installerPackageName, res);
   10542         }
   10543         synchronized (mPackages) {
   10544             final PackageSetting ps = mSettings.mPackages.get(pkgName);
   10545             if (ps != null) {
   10546                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
   10547             }
   10548         }
   10549     }
   10550 
   10551     private static boolean isForwardLocked(PackageParser.Package pkg) {
   10552         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
   10553     }
   10554 
   10555     private static boolean isForwardLocked(ApplicationInfo info) {
   10556         return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
   10557     }
   10558 
   10559     private boolean isForwardLocked(PackageSetting ps) {
   10560         return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0;
   10561     }
   10562 
   10563     private static boolean isMultiArch(PackageSetting ps) {
   10564         return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
   10565     }
   10566 
   10567     private static boolean isMultiArch(ApplicationInfo info) {
   10568         return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
   10569     }
   10570 
   10571     private static boolean isExternal(PackageParser.Package pkg) {
   10572         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   10573     }
   10574 
   10575     private static boolean isExternal(PackageSetting ps) {
   10576         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   10577     }
   10578 
   10579     private static boolean isExternal(ApplicationInfo info) {
   10580         return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
   10581     }
   10582 
   10583     private static boolean isSystemApp(PackageParser.Package pkg) {
   10584         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   10585     }
   10586 
   10587     private static boolean isPrivilegedApp(PackageParser.Package pkg) {
   10588         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
   10589     }
   10590 
   10591     private static boolean isSystemApp(ApplicationInfo info) {
   10592         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   10593     }
   10594 
   10595     private static boolean isSystemApp(PackageSetting ps) {
   10596         return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
   10597     }
   10598 
   10599     private static boolean isUpdatedSystemApp(PackageSetting ps) {
   10600         return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   10601     }
   10602 
   10603     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
   10604         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   10605     }
   10606 
   10607     private static boolean isUpdatedSystemApp(ApplicationInfo info) {
   10608         return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
   10609     }
   10610 
   10611     private int packageFlagsToInstallFlags(PackageSetting ps) {
   10612         int installFlags = 0;
   10613         if (isExternal(ps)) {
   10614             installFlags |= PackageManager.INSTALL_EXTERNAL;
   10615         }
   10616         if (isForwardLocked(ps)) {
   10617             installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
   10618         }
   10619         return installFlags;
   10620     }
   10621 
   10622     private void deleteTempPackageFiles() {
   10623         final FilenameFilter filter = new FilenameFilter() {
   10624             public boolean accept(File dir, String name) {
   10625                 return name.startsWith("vmdl") && name.endsWith(".tmp");
   10626             }
   10627         };
   10628         for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
   10629             file.delete();
   10630         }
   10631     }
   10632 
   10633     @Override
   10634     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId,
   10635             int flags) {
   10636         deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId,
   10637                 flags);
   10638     }
   10639 
   10640     @Override
   10641     public void deletePackage(final String packageName,
   10642             final IPackageDeleteObserver2 observer, final int userId, final int flags) {
   10643         mContext.enforceCallingOrSelfPermission(
   10644                 android.Manifest.permission.DELETE_PACKAGES, null);
   10645         final int uid = Binder.getCallingUid();
   10646         if (UserHandle.getUserId(uid) != userId) {
   10647             mContext.enforceCallingPermission(
   10648                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   10649                     "deletePackage for user " + userId);
   10650         }
   10651         if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
   10652             try {
   10653                 observer.onPackageDeleted(packageName,
   10654                         PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
   10655             } catch (RemoteException re) {
   10656             }
   10657             return;
   10658         }
   10659 
   10660         boolean uninstallBlocked = false;
   10661         if ((flags & PackageManager.DELETE_ALL_USERS) != 0) {
   10662             int[] users = sUserManager.getUserIds();
   10663             for (int i = 0; i < users.length; ++i) {
   10664                 if (getBlockUninstallForUser(packageName, users[i])) {
   10665                     uninstallBlocked = true;
   10666                     break;
   10667                 }
   10668             }
   10669         } else {
   10670             uninstallBlocked = getBlockUninstallForUser(packageName, userId);
   10671         }
   10672         if (uninstallBlocked) {
   10673             try {
   10674                 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED,
   10675                         null);
   10676             } catch (RemoteException re) {
   10677             }
   10678             return;
   10679         }
   10680 
   10681         if (DEBUG_REMOVE) {
   10682             Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId);
   10683         }
   10684         // Queue up an async operation since the package deletion may take a little while.
   10685         mHandler.post(new Runnable() {
   10686             public void run() {
   10687                 mHandler.removeCallbacks(this);
   10688                 final int returnCode = deletePackageX(packageName, userId, flags);
   10689                 if (observer != null) {
   10690                     try {
   10691                         observer.onPackageDeleted(packageName, returnCode, null);
   10692                     } catch (RemoteException e) {
   10693                         Log.i(TAG, "Observer no longer exists.");
   10694                     } //end catch
   10695                 } //end if
   10696             } //end run
   10697         });
   10698     }
   10699 
   10700     private boolean isPackageDeviceAdmin(String packageName, int userId) {
   10701         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
   10702                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
   10703         try {
   10704             if (dpm != null) {
   10705                 if (dpm.isDeviceOwner(packageName)) {
   10706                     return true;
   10707                 }
   10708                 int[] users;
   10709                 if (userId == UserHandle.USER_ALL) {
   10710                     users = sUserManager.getUserIds();
   10711                 } else {
   10712                     users = new int[]{userId};
   10713                 }
   10714                 for (int i = 0; i < users.length; ++i) {
   10715                     if (dpm.packageHasActiveAdmins(packageName, users[i])) {
   10716                         return true;
   10717                     }
   10718                 }
   10719             }
   10720         } catch (RemoteException e) {
   10721         }
   10722         return false;
   10723     }
   10724 
   10725     /**
   10726      *  This method is an internal method that could be get invoked either
   10727      *  to delete an installed package or to clean up a failed installation.
   10728      *  After deleting an installed package, a broadcast is sent to notify any
   10729      *  listeners that the package has been installed. For cleaning up a failed
   10730      *  installation, the broadcast is not necessary since the package's
   10731      *  installation wouldn't have sent the initial broadcast either
   10732      *  The key steps in deleting a package are
   10733      *  deleting the package information in internal structures like mPackages,
   10734      *  deleting the packages base directories through installd
   10735      *  updating mSettings to reflect current status
   10736      *  persisting settings for later use
   10737      *  sending a broadcast if necessary
   10738      */
   10739     private int deletePackageX(String packageName, int userId, int flags) {
   10740         final PackageRemovedInfo info = new PackageRemovedInfo();
   10741         final boolean res;
   10742 
   10743         final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
   10744                 ? UserHandle.ALL : new UserHandle(userId);
   10745 
   10746         if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
   10747             Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
   10748             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
   10749         }
   10750 
   10751         boolean removedForAllUsers = false;
   10752         boolean systemUpdate = false;
   10753 
   10754         // for the uninstall-updates case and restricted profiles, remember the per-
   10755         // userhandle installed state
   10756         int[] allUsers;
   10757         boolean[] perUserInstalled;
   10758         synchronized (mPackages) {
   10759             PackageSetting ps = mSettings.mPackages.get(packageName);
   10760             allUsers = sUserManager.getUserIds();
   10761             perUserInstalled = new boolean[allUsers.length];
   10762             for (int i = 0; i < allUsers.length; i++) {
   10763                 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
   10764             }
   10765         }
   10766 
   10767         synchronized (mInstallLock) {
   10768             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
   10769             res = deletePackageLI(packageName, removeForUser,
   10770                     true, allUsers, perUserInstalled,
   10771                     flags | REMOVE_CHATTY, info, true);
   10772             systemUpdate = info.isRemovedPackageSystemUpdate;
   10773             if (res && !systemUpdate && mPackages.get(packageName) == null) {
   10774                 removedForAllUsers = true;
   10775             }
   10776             if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
   10777                     + " removedForAllUsers=" + removedForAllUsers);
   10778         }
   10779 
   10780         if (res) {
   10781             info.sendBroadcast(true, systemUpdate, removedForAllUsers);
   10782 
   10783             // If the removed package was a system update, the old system package
   10784             // was re-enabled; we need to broadcast this information
   10785             if (systemUpdate) {
   10786                 Bundle extras = new Bundle(1);
   10787                 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
   10788                         ? info.removedAppId : info.uid);
   10789                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   10790 
   10791                 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
   10792                         extras, null, null, null);
   10793                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
   10794                         extras, null, null, null);
   10795                 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
   10796                         null, packageName, null, null);
   10797             }
   10798         }
   10799         // Force a gc here.
   10800         Runtime.getRuntime().gc();
   10801         // Delete the resources here after sending the broadcast to let
   10802         // other processes clean up before deleting resources.
   10803         if (info.args != null) {
   10804             synchronized (mInstallLock) {
   10805                 info.args.doPostDeleteLI(true);
   10806             }
   10807         }
   10808 
   10809         return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
   10810     }
   10811 
   10812     static class PackageRemovedInfo {
   10813         String removedPackage;
   10814         int uid = -1;
   10815         int removedAppId = -1;
   10816         int[] removedUsers = null;
   10817         boolean isRemovedPackageSystemUpdate = false;
   10818         // Clean up resources deleted packages.
   10819         InstallArgs args = null;
   10820 
   10821         void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
   10822             Bundle extras = new Bundle(1);
   10823             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
   10824             extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
   10825             if (replacing) {
   10826                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
   10827             }
   10828             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
   10829             if (removedPackage != null) {
   10830                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
   10831                         extras, null, null, removedUsers);
   10832                 if (fullRemove && !replacing) {
   10833                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
   10834                             extras, null, null, removedUsers);
   10835                 }
   10836             }
   10837             if (removedAppId >= 0) {
   10838                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null,
   10839                         removedUsers);
   10840             }
   10841         }
   10842     }
   10843 
   10844     /*
   10845      * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
   10846      * flag is not set, the data directory is removed as well.
   10847      * make sure this flag is set for partially installed apps. If not its meaningless to
   10848      * delete a partially installed application.
   10849      */
   10850     private void removePackageDataLI(PackageSetting ps,
   10851             int[] allUserHandles, boolean[] perUserInstalled,
   10852             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
   10853         String packageName = ps.name;
   10854         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
   10855         removePackageLI(ps, (flags&REMOVE_CHATTY) != 0);
   10856         // Retrieve object to delete permissions for shared user later on
   10857         final PackageSetting deletedPs;
   10858         // reader
   10859         synchronized (mPackages) {
   10860             deletedPs = mSettings.mPackages.get(packageName);
   10861             if (outInfo != null) {
   10862                 outInfo.removedPackage = packageName;
   10863                 outInfo.removedUsers = deletedPs != null
   10864                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
   10865                         : null;
   10866             }
   10867         }
   10868         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
   10869             removeDataDirsLI(packageName);
   10870             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
   10871         }
   10872         // writer
   10873         synchronized (mPackages) {
   10874             if (deletedPs != null) {
   10875                 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
   10876                     if (outInfo != null) {
   10877                         mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
   10878                         outInfo.removedAppId = mSettings.removePackageLPw(packageName);
   10879                     }
   10880                     if (deletedPs != null) {
   10881                         updatePermissionsLPw(deletedPs.name, null, 0);
   10882                         if (deletedPs.sharedUser != null) {
   10883                             // remove permissions associated with package
   10884                             mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
   10885                         }
   10886                     }
   10887                     clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
   10888                 }
   10889                 // make sure to preserve per-user disabled state if this removal was just
   10890                 // a downgrade of a system app to the factory package
   10891                 if (allUserHandles != null && perUserInstalled != null) {
   10892                     if (DEBUG_REMOVE) {
   10893                         Slog.d(TAG, "Propagating install state across downgrade");
   10894                     }
   10895                     for (int i = 0; i < allUserHandles.length; i++) {
   10896                         if (DEBUG_REMOVE) {
   10897                             Slog.d(TAG, "    user " + allUserHandles[i]
   10898                                     + " => " + perUserInstalled[i]);
   10899                         }
   10900                         ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
   10901                     }
   10902                 }
   10903             }
   10904             // can downgrade to reader
   10905             if (writeSettings) {
   10906                 // Save settings now
   10907                 mSettings.writeLPr();
   10908             }
   10909         }
   10910         if (outInfo != null) {
   10911             // A user ID was deleted here. Go through all users and remove it
   10912             // from KeyStore.
   10913             removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId);
   10914         }
   10915     }
   10916 
   10917     static boolean locationIsPrivileged(File path) {
   10918         try {
   10919             final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
   10920                     .getCanonicalPath();
   10921             return path.getCanonicalPath().startsWith(privilegedAppDir);
   10922         } catch (IOException e) {
   10923             Slog.e(TAG, "Unable to access code path " + path);
   10924         }
   10925         return false;
   10926     }
   10927 
   10928     /*
   10929      * Tries to delete system package.
   10930      */
   10931     private boolean deleteSystemPackageLI(PackageSetting newPs,
   10932             int[] allUserHandles, boolean[] perUserInstalled,
   10933             int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
   10934         final boolean applyUserRestrictions
   10935                 = (allUserHandles != null) && (perUserInstalled != null);
   10936         PackageSetting disabledPs = null;
   10937         // Confirm if the system package has been updated
   10938         // An updated system app can be deleted. This will also have to restore
   10939         // the system pkg from system partition
   10940         // reader
   10941         synchronized (mPackages) {
   10942             disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
   10943         }
   10944         if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
   10945                 + " disabledPs=" + disabledPs);
   10946         if (disabledPs == null) {
   10947             Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
   10948             return false;
   10949         } else if (DEBUG_REMOVE) {
   10950             Slog.d(TAG, "Deleting system pkg from data partition");
   10951         }
   10952         if (DEBUG_REMOVE) {
   10953             if (applyUserRestrictions) {
   10954                 Slog.d(TAG, "Remembering install states:");
   10955                 for (int i = 0; i < allUserHandles.length; i++) {
   10956                     Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
   10957                 }
   10958             }
   10959         }
   10960         // Delete the updated package
   10961         outInfo.isRemovedPackageSystemUpdate = true;
   10962         if (disabledPs.versionCode < newPs.versionCode) {
   10963             // Delete data for downgrades
   10964             flags &= ~PackageManager.DELETE_KEEP_DATA;
   10965         } else {
   10966             // Preserve data by setting flag
   10967             flags |= PackageManager.DELETE_KEEP_DATA;
   10968         }
   10969         boolean ret = deleteInstalledPackageLI(newPs, true, flags,
   10970                 allUserHandles, perUserInstalled, outInfo, writeSettings);
   10971         if (!ret) {
   10972             return false;
   10973         }
   10974         // writer
   10975         synchronized (mPackages) {
   10976             // Reinstate the old system package
   10977             mSettings.enableSystemPackageLPw(newPs.name);
   10978             // Remove any native libraries from the upgraded package.
   10979             NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
   10980         }
   10981         // Install the system package
   10982         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
   10983         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
   10984         if (locationIsPrivileged(disabledPs.codePath)) {
   10985             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
   10986         }
   10987 
   10988         final PackageParser.Package newPkg;
   10989         try {
   10990             newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
   10991         } catch (PackageManagerException e) {
   10992             Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
   10993             return false;
   10994         }
   10995 
   10996         // writer
   10997         synchronized (mPackages) {
   10998             PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
   10999             updatePermissionsLPw(newPkg.packageName, newPkg,
   11000                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
   11001             if (applyUserRestrictions) {
   11002                 if (DEBUG_REMOVE) {
   11003                     Slog.d(TAG, "Propagating install state across reinstall");
   11004                 }
   11005                 for (int i = 0; i < allUserHandles.length; i++) {
   11006                     if (DEBUG_REMOVE) {
   11007                         Slog.d(TAG, "    user " + allUserHandles[i]
   11008                                 + " => " + perUserInstalled[i]);
   11009                     }
   11010                     ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
   11011                 }
   11012                 // Regardless of writeSettings we need to ensure that this restriction
   11013                 // state propagation is persisted
   11014                 mSettings.writeAllUsersPackageRestrictionsLPr();
   11015             }
   11016             // can downgrade to reader here
   11017             if (writeSettings) {
   11018                 mSettings.writeLPr();
   11019             }
   11020         }
   11021         return true;
   11022     }
   11023 
   11024     private boolean deleteInstalledPackageLI(PackageSetting ps,
   11025             boolean deleteCodeAndResources, int flags,
   11026             int[] allUserHandles, boolean[] perUserInstalled,
   11027             PackageRemovedInfo outInfo, boolean writeSettings) {
   11028         if (outInfo != null) {
   11029             outInfo.uid = ps.appId;
   11030         }
   11031 
   11032         // Delete package data from internal structures and also remove data if flag is set
   11033         removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
   11034 
   11035         // Delete application code and resources
   11036         if (deleteCodeAndResources && (outInfo != null)) {
   11037             outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
   11038                     ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString,
   11039                     getAppDexInstructionSets(ps));
   11040             if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
   11041         }
   11042         return true;
   11043     }
   11044 
   11045     @Override
   11046     public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
   11047             int userId) {
   11048         mContext.enforceCallingOrSelfPermission(
   11049                 android.Manifest.permission.DELETE_PACKAGES, null);
   11050         synchronized (mPackages) {
   11051             PackageSetting ps = mSettings.mPackages.get(packageName);
   11052             if (ps == null) {
   11053                 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
   11054                 return false;
   11055             }
   11056             if (!ps.getInstalled(userId)) {
   11057                 // Can't block uninstall for an app that is not installed or enabled.
   11058                 Log.i(TAG, "Package not installed in set block uninstall " + packageName);
   11059                 return false;
   11060             }
   11061             ps.setBlockUninstall(blockUninstall, userId);
   11062             mSettings.writePackageRestrictionsLPr(userId);
   11063         }
   11064         return true;
   11065     }
   11066 
   11067     @Override
   11068     public boolean getBlockUninstallForUser(String packageName, int userId) {
   11069         synchronized (mPackages) {
   11070             PackageSetting ps = mSettings.mPackages.get(packageName);
   11071             if (ps == null) {
   11072                 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
   11073                 return false;
   11074             }
   11075             return ps.getBlockUninstall(userId);
   11076         }
   11077     }
   11078 
   11079     /*
   11080      * This method handles package deletion in general
   11081      */
   11082     private boolean deletePackageLI(String packageName, UserHandle user,
   11083             boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
   11084             int flags, PackageRemovedInfo outInfo,
   11085             boolean writeSettings) {
   11086         if (packageName == null) {
   11087             Slog.w(TAG, "Attempt to delete null packageName.");
   11088             return false;
   11089         }
   11090         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
   11091         PackageSetting ps;
   11092         boolean dataOnly = false;
   11093         int removeUser = -1;
   11094         int appId = -1;
   11095         synchronized (mPackages) {
   11096             ps = mSettings.mPackages.get(packageName);
   11097             if (ps == null) {
   11098                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
   11099                 return false;
   11100             }
   11101             if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
   11102                     && user.getIdentifier() != UserHandle.USER_ALL) {
   11103                 // The caller is asking that the package only be deleted for a single
   11104                 // user.  To do this, we just mark its uninstalled state and delete
   11105                 // its data.  If this is a system app, we only allow this to happen if
   11106                 // they have set the special DELETE_SYSTEM_APP which requests different
   11107                 // semantics than normal for uninstalling system apps.
   11108                 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
   11109                 ps.setUserState(user.getIdentifier(),
   11110                         COMPONENT_ENABLED_STATE_DEFAULT,
   11111                         false, //installed
   11112                         true,  //stopped
   11113                         true,  //notLaunched
   11114                         false, //hidden
   11115                         null, null, null,
   11116                         false // blockUninstall
   11117                         );
   11118                 if (!isSystemApp(ps)) {
   11119                     if (ps.isAnyInstalled(sUserManager.getUserIds())) {
   11120                         // Other user still have this package installed, so all
   11121                         // we need to do is clear this user's data and save that
   11122                         // it is uninstalled.
   11123                         if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
   11124                         removeUser = user.getIdentifier();
   11125                         appId = ps.appId;
   11126                         mSettings.writePackageRestrictionsLPr(removeUser);
   11127                     } else {
   11128                         // We need to set it back to 'installed' so the uninstall
   11129                         // broadcasts will be sent correctly.
   11130                         if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
   11131                         ps.setInstalled(true, user.getIdentifier());
   11132                     }
   11133                 } else {
   11134                     // This is a system app, so we assume that the
   11135                     // other users still have this package installed, so all
   11136                     // we need to do is clear this user's data and save that
   11137                     // it is uninstalled.
   11138                     if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
   11139                     removeUser = user.getIdentifier();
   11140                     appId = ps.appId;
   11141                     mSettings.writePackageRestrictionsLPr(removeUser);
   11142                 }
   11143             }
   11144         }
   11145 
   11146         if (removeUser >= 0) {
   11147             // From above, we determined that we are deleting this only
   11148             // for a single user.  Continue the work here.
   11149             if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
   11150             if (outInfo != null) {
   11151                 outInfo.removedPackage = packageName;
   11152                 outInfo.removedAppId = appId;
   11153                 outInfo.removedUsers = new int[] {removeUser};
   11154             }
   11155             mInstaller.clearUserData(packageName, removeUser);
   11156             removeKeystoreDataIfNeeded(removeUser, appId);
   11157             schedulePackageCleaning(packageName, removeUser, false);
   11158             return true;
   11159         }
   11160 
   11161         if (dataOnly) {
   11162             // Delete application data first
   11163             if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
   11164             removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
   11165             return true;
   11166         }
   11167 
   11168         boolean ret = false;
   11169         if (isSystemApp(ps)) {
   11170             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name);
   11171             // When an updated system application is deleted we delete the existing resources as well and
   11172             // fall back to existing code in system partition
   11173             ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
   11174                     flags, outInfo, writeSettings);
   11175         } else {
   11176             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name);
   11177             // Kill application pre-emptively especially for apps on sd.
   11178             killApplication(packageName, ps.appId, "uninstall pkg");
   11179             ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
   11180                     allUserHandles, perUserInstalled,
   11181                     outInfo, writeSettings);
   11182         }
   11183 
   11184         return ret;
   11185     }
   11186 
   11187     private final class ClearStorageConnection implements ServiceConnection {
   11188         IMediaContainerService mContainerService;
   11189 
   11190         @Override
   11191         public void onServiceConnected(ComponentName name, IBinder service) {
   11192             synchronized (this) {
   11193                 mContainerService = IMediaContainerService.Stub.asInterface(service);
   11194                 notifyAll();
   11195             }
   11196         }
   11197 
   11198         @Override
   11199         public void onServiceDisconnected(ComponentName name) {
   11200         }
   11201     }
   11202 
   11203     private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
   11204         final boolean mounted;
   11205         if (Environment.isExternalStorageEmulated()) {
   11206             mounted = true;
   11207         } else {
   11208             final String status = Environment.getExternalStorageState();
   11209 
   11210             mounted = status.equals(Environment.MEDIA_MOUNTED)
   11211                     || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
   11212         }
   11213 
   11214         if (!mounted) {
   11215             return;
   11216         }
   11217 
   11218         final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
   11219         int[] users;
   11220         if (userId == UserHandle.USER_ALL) {
   11221             users = sUserManager.getUserIds();
   11222         } else {
   11223             users = new int[] { userId };
   11224         }
   11225         final ClearStorageConnection conn = new ClearStorageConnection();
   11226         if (mContext.bindServiceAsUser(
   11227                 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
   11228             try {
   11229                 for (int curUser : users) {
   11230                     long timeout = SystemClock.uptimeMillis() + 5000;
   11231                     synchronized (conn) {
   11232                         long now = SystemClock.uptimeMillis();
   11233                         while (conn.mContainerService == null && now < timeout) {
   11234                             try {
   11235                                 conn.wait(timeout - now);
   11236                             } catch (InterruptedException e) {
   11237                             }
   11238                         }
   11239                     }
   11240                     if (conn.mContainerService == null) {
   11241                         return;
   11242                     }
   11243 
   11244                     final UserEnvironment userEnv = new UserEnvironment(curUser);
   11245                     clearDirectory(conn.mContainerService,
   11246                             userEnv.buildExternalStorageAppCacheDirs(packageName));
   11247                     if (allData) {
   11248                         clearDirectory(conn.mContainerService,
   11249                                 userEnv.buildExternalStorageAppDataDirs(packageName));
   11250                         clearDirectory(conn.mContainerService,
   11251                                 userEnv.buildExternalStorageAppMediaDirs(packageName));
   11252                     }
   11253                 }
   11254             } finally {
   11255                 mContext.unbindService(conn);
   11256             }
   11257         }
   11258     }
   11259 
   11260     @Override
   11261     public void clearApplicationUserData(final String packageName,
   11262             final IPackageDataObserver observer, final int userId) {
   11263         mContext.enforceCallingOrSelfPermission(
   11264                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
   11265         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
   11266         // Queue up an async operation since the package deletion may take a little while.
   11267         mHandler.post(new Runnable() {
   11268             public void run() {
   11269                 mHandler.removeCallbacks(this);
   11270                 final boolean succeeded;
   11271                 synchronized (mInstallLock) {
   11272                     succeeded = clearApplicationUserDataLI(packageName, userId);
   11273                 }
   11274                 clearExternalStorageDataSync(packageName, userId, true);
   11275                 if (succeeded) {
   11276                     // invoke DeviceStorageMonitor's update method to clear any notifications
   11277                     DeviceStorageMonitorInternal
   11278                             dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
   11279                     if (dsm != null) {
   11280                         dsm.checkMemory();
   11281                     }
   11282                 }
   11283                 if(observer != null) {
   11284                     try {
   11285                         observer.onRemoveCompleted(packageName, succeeded);
   11286                     } catch (RemoteException e) {
   11287                         Log.i(TAG, "Observer no longer exists.");
   11288                     }
   11289                 } //end if observer
   11290             } //end run
   11291         });
   11292     }
   11293 
   11294     private boolean clearApplicationUserDataLI(String packageName, int userId) {
   11295         if (packageName == null) {
   11296             Slog.w(TAG, "Attempt to delete null packageName.");
   11297             return false;
   11298         }
   11299 
   11300         // Try finding details about the requested package
   11301         PackageParser.Package pkg;
   11302         synchronized (mPackages) {
   11303             pkg = mPackages.get(packageName);
   11304             if (pkg == null) {
   11305                 final PackageSetting ps = mSettings.mPackages.get(packageName);
   11306                 if (ps != null) {
   11307                     pkg = ps.pkg;
   11308                 }
   11309             }
   11310         }
   11311 
   11312         if (pkg == null) {
   11313             Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
   11314         }
   11315 
   11316         // Always delete data directories for package, even if we found no other
   11317         // record of app. This helps users recover from UID mismatches without
   11318         // resorting to a full data wipe.
   11319         int retCode = mInstaller.clearUserData(packageName, userId);
   11320         if (retCode < 0) {
   11321             Slog.w(TAG, "Couldn't remove cache files for package: " + packageName);
   11322             return false;
   11323         }
   11324 
   11325         if (pkg == null) {
   11326             return false;
   11327         }
   11328 
   11329         if (pkg != null && pkg.applicationInfo != null) {
   11330             final int appId = pkg.applicationInfo.uid;
   11331             removeKeystoreDataIfNeeded(userId, appId);
   11332         }
   11333 
   11334         // Create a native library symlink only if we have native libraries
   11335         // and if the native libraries are 32 bit libraries. We do not provide
   11336         // this symlink for 64 bit libraries.
   11337         if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null &&
   11338                 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) {
   11339             final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir;
   11340             if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) {
   11341                 Slog.w(TAG, "Failed linking native library dir");
   11342                 return false;
   11343             }
   11344         }
   11345 
   11346         return true;
   11347     }
   11348 
   11349     /**
   11350      * Remove entries from the keystore daemon. Will only remove it if the
   11351      * {@code appId} is valid.
   11352      */
   11353     private static void removeKeystoreDataIfNeeded(int userId, int appId) {
   11354         if (appId < 0) {
   11355             return;
   11356         }
   11357 
   11358         final KeyStore keyStore = KeyStore.getInstance();
   11359         if (keyStore != null) {
   11360             if (userId == UserHandle.USER_ALL) {
   11361                 for (final int individual : sUserManager.getUserIds()) {
   11362                     keyStore.clearUid(UserHandle.getUid(individual, appId));
   11363                 }
   11364             } else {
   11365                 keyStore.clearUid(UserHandle.getUid(userId, appId));
   11366             }
   11367         } else {
   11368             Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
   11369         }
   11370     }
   11371 
   11372     @Override
   11373     public void deleteApplicationCacheFiles(final String packageName,
   11374             final IPackageDataObserver observer) {
   11375         mContext.enforceCallingOrSelfPermission(
   11376                 android.Manifest.permission.DELETE_CACHE_FILES, null);
   11377         // Queue up an async operation since the package deletion may take a little while.
   11378         final int userId = UserHandle.getCallingUserId();
   11379         mHandler.post(new Runnable() {
   11380             public void run() {
   11381                 mHandler.removeCallbacks(this);
   11382                 final boolean succeded;
   11383                 synchronized (mInstallLock) {
   11384                     succeded = deleteApplicationCacheFilesLI(packageName, userId);
   11385                 }
   11386                 clearExternalStorageDataSync(packageName, userId, false);
   11387                 if(observer != null) {
   11388                     try {
   11389                         observer.onRemoveCompleted(packageName, succeded);
   11390                     } catch (RemoteException e) {
   11391                         Log.i(TAG, "Observer no longer exists.");
   11392                     }
   11393                 } //end if observer
   11394             } //end run
   11395         });
   11396     }
   11397 
   11398     private boolean deleteApplicationCacheFilesLI(String packageName, int userId) {
   11399         if (packageName == null) {
   11400             Slog.w(TAG, "Attempt to delete null packageName.");
   11401             return false;
   11402         }
   11403         PackageParser.Package p;
   11404         synchronized (mPackages) {
   11405             p = mPackages.get(packageName);
   11406         }
   11407         if (p == null) {
   11408             Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   11409             return false;
   11410         }
   11411         final ApplicationInfo applicationInfo = p.applicationInfo;
   11412         if (applicationInfo == null) {
   11413             Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
   11414             return false;
   11415         }
   11416         int retCode = mInstaller.deleteCacheFiles(packageName, userId);
   11417         if (retCode < 0) {
   11418             Slog.w(TAG, "Couldn't remove cache files for package: "
   11419                        + packageName + " u" + userId);
   11420             return false;
   11421         }
   11422         return true;
   11423     }
   11424 
   11425     @Override
   11426     public void getPackageSizeInfo(final String packageName, int userHandle,
   11427             final IPackageStatsObserver observer) {
   11428         mContext.enforceCallingOrSelfPermission(
   11429                 android.Manifest.permission.GET_PACKAGE_SIZE, null);
   11430         if (packageName == null) {
   11431             throw new IllegalArgumentException("Attempt to get size of null packageName");
   11432         }
   11433 
   11434         PackageStats stats = new PackageStats(packageName, userHandle);
   11435 
   11436         /*
   11437          * Queue up an async operation since the package measurement may take a
   11438          * little while.
   11439          */
   11440         Message msg = mHandler.obtainMessage(INIT_COPY);
   11441         msg.obj = new MeasureParams(stats, observer);
   11442         mHandler.sendMessage(msg);
   11443     }
   11444 
   11445     private boolean getPackageSizeInfoLI(String packageName, int userHandle,
   11446             PackageStats pStats) {
   11447         if (packageName == null) {
   11448             Slog.w(TAG, "Attempt to get size of null packageName.");
   11449             return false;
   11450         }
   11451         PackageParser.Package p;
   11452         boolean dataOnly = false;
   11453         String libDirRoot = null;
   11454         String asecPath = null;
   11455         PackageSetting ps = null;
   11456         synchronized (mPackages) {
   11457             p = mPackages.get(packageName);
   11458             ps = mSettings.mPackages.get(packageName);
   11459             if(p == null) {
   11460                 dataOnly = true;
   11461                 if((ps == null) || (ps.pkg == null)) {
   11462                     Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
   11463                     return false;
   11464                 }
   11465                 p = ps.pkg;
   11466             }
   11467             if (ps != null) {
   11468                 libDirRoot = ps.legacyNativeLibraryPathString;
   11469             }
   11470             if (p != null && (isExternal(p) || isForwardLocked(p))) {
   11471                 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath());
   11472                 if (secureContainerId != null) {
   11473                     asecPath = PackageHelper.getSdFilesystem(secureContainerId);
   11474                 }
   11475             }
   11476         }
   11477         String publicSrcDir = null;
   11478         if(!dataOnly) {
   11479             final ApplicationInfo applicationInfo = p.applicationInfo;
   11480             if (applicationInfo == null) {
   11481                 Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
   11482                 return false;
   11483             }
   11484             if (isForwardLocked(p)) {
   11485                 publicSrcDir = applicationInfo.getBaseResourcePath();
   11486             }
   11487         }
   11488         // TODO: extend to measure size of split APKs
   11489         // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree,
   11490         // not just the first level.
   11491         // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not
   11492         // just the primary.
   11493         String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps));
   11494         int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot,
   11495                 publicSrcDir, asecPath, dexCodeInstructionSets, pStats);
   11496         if (res < 0) {
   11497             return false;
   11498         }
   11499 
   11500         // Fix-up for forward-locked applications in ASEC containers.
   11501         if (!isExternal(p)) {
   11502             pStats.codeSize += pStats.externalCodeSize;
   11503             pStats.externalCodeSize = 0L;
   11504         }
   11505 
   11506         return true;
   11507     }
   11508 
   11509 
   11510     @Override
   11511     public void addPackageToPreferred(String packageName) {
   11512         Slog.w(TAG, "addPackageToPreferred: this is now a no-op");
   11513     }
   11514 
   11515     @Override
   11516     public void removePackageFromPreferred(String packageName) {
   11517         Slog.w(TAG, "removePackageFromPreferred: this is now a no-op");
   11518     }
   11519 
   11520     @Override
   11521     public List<PackageInfo> getPreferredPackages(int flags) {
   11522         return new ArrayList<PackageInfo>();
   11523     }
   11524 
   11525     private int getUidTargetSdkVersionLockedLPr(int uid) {
   11526         Object obj = mSettings.getUserIdLPr(uid);
   11527         if (obj instanceof SharedUserSetting) {
   11528             final SharedUserSetting sus = (SharedUserSetting) obj;
   11529             int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
   11530             final Iterator<PackageSetting> it = sus.packages.iterator();
   11531             while (it.hasNext()) {
   11532                 final PackageSetting ps = it.next();
   11533                 if (ps.pkg != null) {
   11534                     int v = ps.pkg.applicationInfo.targetSdkVersion;
   11535                     if (v < vers) vers = v;
   11536                 }
   11537             }
   11538             return vers;
   11539         } else if (obj instanceof PackageSetting) {
   11540             final PackageSetting ps = (PackageSetting) obj;
   11541             if (ps.pkg != null) {
   11542                 return ps.pkg.applicationInfo.targetSdkVersion;
   11543             }
   11544         }
   11545         return Build.VERSION_CODES.CUR_DEVELOPMENT;
   11546     }
   11547 
   11548     @Override
   11549     public void addPreferredActivity(IntentFilter filter, int match,
   11550             ComponentName[] set, ComponentName activity, int userId) {
   11551         addPreferredActivityInternal(filter, match, set, activity, true, userId,
   11552                 "Adding preferred");
   11553     }
   11554 
   11555     private void addPreferredActivityInternal(IntentFilter filter, int match,
   11556             ComponentName[] set, ComponentName activity, boolean always, int userId,
   11557             String opname) {
   11558         // writer
   11559         int callingUid = Binder.getCallingUid();
   11560         enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
   11561         if (filter.countActions() == 0) {
   11562             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
   11563             return;
   11564         }
   11565         synchronized (mPackages) {
   11566             if (mContext.checkCallingOrSelfPermission(
   11567                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   11568                     != PackageManager.PERMISSION_GRANTED) {
   11569                 if (getUidTargetSdkVersionLockedLPr(callingUid)
   11570                         < Build.VERSION_CODES.FROYO) {
   11571                     Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
   11572                             + callingUid);
   11573                     return;
   11574                 }
   11575                 mContext.enforceCallingOrSelfPermission(
   11576                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   11577             }
   11578 
   11579             PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
   11580             Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
   11581                     + userId + ":");
   11582             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11583             pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
   11584             mSettings.writePackageRestrictionsLPr(userId);
   11585         }
   11586     }
   11587 
   11588     @Override
   11589     public void replacePreferredActivity(IntentFilter filter, int match,
   11590             ComponentName[] set, ComponentName activity, int userId) {
   11591         if (filter.countActions() != 1) {
   11592             throw new IllegalArgumentException(
   11593                     "replacePreferredActivity expects filter to have only 1 action.");
   11594         }
   11595         if (filter.countDataAuthorities() != 0
   11596                 || filter.countDataPaths() != 0
   11597                 || filter.countDataSchemes() > 1
   11598                 || filter.countDataTypes() != 0) {
   11599             throw new IllegalArgumentException(
   11600                     "replacePreferredActivity expects filter to have no data authorities, " +
   11601                     "paths, or types; and at most one scheme.");
   11602         }
   11603 
   11604         final int callingUid = Binder.getCallingUid();
   11605         enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
   11606         synchronized (mPackages) {
   11607             if (mContext.checkCallingOrSelfPermission(
   11608                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   11609                     != PackageManager.PERMISSION_GRANTED) {
   11610                 if (getUidTargetSdkVersionLockedLPr(callingUid)
   11611                         < Build.VERSION_CODES.FROYO) {
   11612                     Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
   11613                             + Binder.getCallingUid());
   11614                     return;
   11615                 }
   11616                 mContext.enforceCallingOrSelfPermission(
   11617                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   11618             }
   11619 
   11620             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   11621             if (pir != null) {
   11622                 // Get all of the existing entries that exactly match this filter.
   11623                 ArrayList<PreferredActivity> existing = pir.findFilters(filter);
   11624                 if (existing != null && existing.size() == 1) {
   11625                     PreferredActivity cur = existing.get(0);
   11626                     if (DEBUG_PREFERRED) {
   11627                         Slog.i(TAG, "Checking replace of preferred:");
   11628                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11629                         if (!cur.mPref.mAlways) {
   11630                             Slog.i(TAG, "  -- CUR; not mAlways!");
   11631                         } else {
   11632                             Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
   11633                             Slog.i(TAG, "  -- CUR: mSet="
   11634                                     + Arrays.toString(cur.mPref.mSetComponents));
   11635                             Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
   11636                             Slog.i(TAG, "  -- NEW: mMatch="
   11637                                     + (match&IntentFilter.MATCH_CATEGORY_MASK));
   11638                             Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
   11639                             Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
   11640                         }
   11641                     }
   11642                     if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
   11643                             && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
   11644                             && cur.mPref.sameSet(set)) {
   11645                         // Setting the preferred activity to what it happens to be already
   11646                         if (DEBUG_PREFERRED) {
   11647                             Slog.i(TAG, "Replacing with same preferred activity "
   11648                                     + cur.mPref.mShortComponent + " for user "
   11649                                     + userId + ":");
   11650                             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11651                         }
   11652                         return;
   11653                     }
   11654                 }
   11655 
   11656                 if (existing != null) {
   11657                     if (DEBUG_PREFERRED) {
   11658                         Slog.i(TAG, existing.size() + " existing preferred matches for:");
   11659                         filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11660                     }
   11661                     for (int i = 0; i < existing.size(); i++) {
   11662                         PreferredActivity pa = existing.get(i);
   11663                         if (DEBUG_PREFERRED) {
   11664                             Slog.i(TAG, "Removing existing preferred activity "
   11665                                     + pa.mPref.mComponent + ":");
   11666                             pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11667                         }
   11668                         pir.removeFilter(pa);
   11669                     }
   11670                 }
   11671             }
   11672             addPreferredActivityInternal(filter, match, set, activity, true, userId,
   11673                     "Replacing preferred");
   11674         }
   11675     }
   11676 
   11677     @Override
   11678     public void clearPackagePreferredActivities(String packageName) {
   11679         final int uid = Binder.getCallingUid();
   11680         // writer
   11681         synchronized (mPackages) {
   11682             PackageParser.Package pkg = mPackages.get(packageName);
   11683             if (pkg == null || pkg.applicationInfo.uid != uid) {
   11684                 if (mContext.checkCallingOrSelfPermission(
   11685                         android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
   11686                         != PackageManager.PERMISSION_GRANTED) {
   11687                     if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
   11688                             < Build.VERSION_CODES.FROYO) {
   11689                         Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
   11690                                 + Binder.getCallingUid());
   11691                         return;
   11692                     }
   11693                     mContext.enforceCallingOrSelfPermission(
   11694                             android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   11695                 }
   11696             }
   11697 
   11698             int user = UserHandle.getCallingUserId();
   11699             if (clearPackagePreferredActivitiesLPw(packageName, user)) {
   11700                 mSettings.writePackageRestrictionsLPr(user);
   11701                 scheduleWriteSettingsLocked();
   11702             }
   11703         }
   11704     }
   11705 
   11706     /** This method takes a specific user id as well as UserHandle.USER_ALL. */
   11707     boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
   11708         ArrayList<PreferredActivity> removed = null;
   11709         boolean changed = false;
   11710         for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   11711             final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
   11712             PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   11713             if (userId != UserHandle.USER_ALL && userId != thisUserId) {
   11714                 continue;
   11715             }
   11716             Iterator<PreferredActivity> it = pir.filterIterator();
   11717             while (it.hasNext()) {
   11718                 PreferredActivity pa = it.next();
   11719                 // Mark entry for removal only if it matches the package name
   11720                 // and the entry is of type "always".
   11721                 if (packageName == null ||
   11722                         (pa.mPref.mComponent.getPackageName().equals(packageName)
   11723                                 && pa.mPref.mAlways)) {
   11724                     if (removed == null) {
   11725                         removed = new ArrayList<PreferredActivity>();
   11726                     }
   11727                     removed.add(pa);
   11728                 }
   11729             }
   11730             if (removed != null) {
   11731                 for (int j=0; j<removed.size(); j++) {
   11732                     PreferredActivity pa = removed.get(j);
   11733                     pir.removeFilter(pa);
   11734                 }
   11735                 changed = true;
   11736             }
   11737         }
   11738         return changed;
   11739     }
   11740 
   11741     @Override
   11742     public void resetPreferredActivities(int userId) {
   11743         /* TODO: Actually use userId. Why is it being passed in? */
   11744         mContext.enforceCallingOrSelfPermission(
   11745                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
   11746         // writer
   11747         synchronized (mPackages) {
   11748             int user = UserHandle.getCallingUserId();
   11749             clearPackagePreferredActivitiesLPw(null, user);
   11750             mSettings.readDefaultPreferredAppsLPw(this, user);
   11751             mSettings.writePackageRestrictionsLPr(user);
   11752             scheduleWriteSettingsLocked();
   11753         }
   11754     }
   11755 
   11756     @Override
   11757     public int getPreferredActivities(List<IntentFilter> outFilters,
   11758             List<ComponentName> outActivities, String packageName) {
   11759 
   11760         int num = 0;
   11761         final int userId = UserHandle.getCallingUserId();
   11762         // reader
   11763         synchronized (mPackages) {
   11764             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
   11765             if (pir != null) {
   11766                 final Iterator<PreferredActivity> it = pir.filterIterator();
   11767                 while (it.hasNext()) {
   11768                     final PreferredActivity pa = it.next();
   11769                     if (packageName == null
   11770                             || (pa.mPref.mComponent.getPackageName().equals(packageName)
   11771                                     && pa.mPref.mAlways)) {
   11772                         if (outFilters != null) {
   11773                             outFilters.add(new IntentFilter(pa));
   11774                         }
   11775                         if (outActivities != null) {
   11776                             outActivities.add(pa.mPref.mComponent);
   11777                         }
   11778                     }
   11779                 }
   11780             }
   11781         }
   11782 
   11783         return num;
   11784     }
   11785 
   11786     @Override
   11787     public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
   11788             int userId) {
   11789         int callingUid = Binder.getCallingUid();
   11790         if (callingUid != Process.SYSTEM_UID) {
   11791             throw new SecurityException(
   11792                     "addPersistentPreferredActivity can only be run by the system");
   11793         }
   11794         if (filter.countActions() == 0) {
   11795             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
   11796             return;
   11797         }
   11798         synchronized (mPackages) {
   11799             Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
   11800                     " :");
   11801             filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
   11802             mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
   11803                     new PersistentPreferredActivity(filter, activity));
   11804             mSettings.writePackageRestrictionsLPr(userId);
   11805         }
   11806     }
   11807 
   11808     @Override
   11809     public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
   11810         int callingUid = Binder.getCallingUid();
   11811         if (callingUid != Process.SYSTEM_UID) {
   11812             throw new SecurityException(
   11813                     "clearPackagePersistentPreferredActivities can only be run by the system");
   11814         }
   11815         ArrayList<PersistentPreferredActivity> removed = null;
   11816         boolean changed = false;
   11817         synchronized (mPackages) {
   11818             for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
   11819                 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
   11820                 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
   11821                         .valueAt(i);
   11822                 if (userId != thisUserId) {
   11823                     continue;
   11824                 }
   11825                 Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
   11826                 while (it.hasNext()) {
   11827                     PersistentPreferredActivity ppa = it.next();
   11828                     // Mark entry for removal only if it matches the package name.
   11829                     if (ppa.mComponent.getPackageName().equals(packageName)) {
   11830                         if (removed == null) {
   11831                             removed = new ArrayList<PersistentPreferredActivity>();
   11832                         }
   11833                         removed.add(ppa);
   11834                     }
   11835                 }
   11836                 if (removed != null) {
   11837                     for (int j=0; j<removed.size(); j++) {
   11838                         PersistentPreferredActivity ppa = removed.get(j);
   11839                         ppir.removeFilter(ppa);
   11840                     }
   11841                     changed = true;
   11842                 }
   11843             }
   11844 
   11845             if (changed) {
   11846                 mSettings.writePackageRestrictionsLPr(userId);
   11847             }
   11848         }
   11849     }
   11850 
   11851     @Override
   11852     public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
   11853             int ownerUserId, int sourceUserId, int targetUserId, int flags) {
   11854         mContext.enforceCallingOrSelfPermission(
   11855                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   11856         int callingUid = Binder.getCallingUid();
   11857         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
   11858         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
   11859         if (intentFilter.countActions() == 0) {
   11860             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
   11861             return;
   11862         }
   11863         synchronized (mPackages) {
   11864             CrossProfileIntentFilter filter = new CrossProfileIntentFilter(intentFilter,
   11865                     ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags);
   11866             mSettings.editCrossProfileIntentResolverLPw(sourceUserId).addFilter(filter);
   11867             mSettings.writePackageRestrictionsLPr(sourceUserId);
   11868         }
   11869     }
   11870 
   11871     @Override
   11872     public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
   11873             int ownerUserId) {
   11874         mContext.enforceCallingOrSelfPermission(
   11875                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
   11876         int callingUid = Binder.getCallingUid();
   11877         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
   11878         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
   11879         int callingUserId = UserHandle.getUserId(callingUid);
   11880         synchronized (mPackages) {
   11881             CrossProfileIntentResolver resolver =
   11882                     mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
   11883             HashSet<CrossProfileIntentFilter> set =
   11884                     new HashSet<CrossProfileIntentFilter>(resolver.filterSet());
   11885             for (CrossProfileIntentFilter filter : set) {
   11886                 if (filter.getOwnerPackage().equals(ownerPackage)
   11887                         && filter.getOwnerUserId() == callingUserId) {
   11888                     resolver.removeFilter(filter);
   11889                 }
   11890             }
   11891             mSettings.writePackageRestrictionsLPr(sourceUserId);
   11892         }
   11893     }
   11894 
   11895     // Enforcing that callingUid is owning pkg on userId
   11896     private void enforceOwnerRights(String pkg, int userId, int callingUid) {
   11897         // The system owns everything.
   11898         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
   11899             return;
   11900         }
   11901         int callingUserId = UserHandle.getUserId(callingUid);
   11902         if (callingUserId != userId) {
   11903             throw new SecurityException("calling uid " + callingUid
   11904                     + " pretends to own " + pkg + " on user " + userId + " but belongs to user "
   11905                     + callingUserId);
   11906         }
   11907         PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
   11908         if (pi == null) {
   11909             throw new IllegalArgumentException("Unknown package " + pkg + " on user "
   11910                     + callingUserId);
   11911         }
   11912         if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
   11913             throw new SecurityException("Calling uid " + callingUid
   11914                     + " does not own package " + pkg);
   11915         }
   11916     }
   11917 
   11918     @Override
   11919     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
   11920         Intent intent = new Intent(Intent.ACTION_MAIN);
   11921         intent.addCategory(Intent.CATEGORY_HOME);
   11922 
   11923         final int callingUserId = UserHandle.getCallingUserId();
   11924         List<ResolveInfo> list = queryIntentActivities(intent, null,
   11925                 PackageManager.GET_META_DATA, callingUserId);
   11926         ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
   11927                 true, false, false, callingUserId);
   11928 
   11929         allHomeCandidates.clear();
   11930         if (list != null) {
   11931             for (ResolveInfo ri : list) {
   11932                 allHomeCandidates.add(ri);
   11933             }
   11934         }
   11935         return (preferred == null || preferred.activityInfo == null)
   11936                 ? null
   11937                 : new ComponentName(preferred.activityInfo.packageName,
   11938                         preferred.activityInfo.name);
   11939     }
   11940 
   11941     @Override
   11942     public void setApplicationEnabledSetting(String appPackageName,
   11943             int newState, int flags, int userId, String callingPackage) {
   11944         if (!sUserManager.exists(userId)) return;
   11945         if (callingPackage == null) {
   11946             callingPackage = Integer.toString(Binder.getCallingUid());
   11947         }
   11948         setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
   11949     }
   11950 
   11951     @Override
   11952     public void setComponentEnabledSetting(ComponentName componentName,
   11953             int newState, int flags, int userId) {
   11954         if (!sUserManager.exists(userId)) return;
   11955         setEnabledSetting(componentName.getPackageName(),
   11956                 componentName.getClassName(), newState, flags, userId, null);
   11957     }
   11958 
   11959     private void setEnabledSetting(final String packageName, String className, int newState,
   11960             final int flags, int userId, String callingPackage) {
   11961         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
   11962               || newState == COMPONENT_ENABLED_STATE_ENABLED
   11963               || newState == COMPONENT_ENABLED_STATE_DISABLED
   11964               || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
   11965               || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
   11966             throw new IllegalArgumentException("Invalid new component state: "
   11967                     + newState);
   11968         }
   11969         PackageSetting pkgSetting;
   11970         final int uid = Binder.getCallingUid();
   11971         final int permission = mContext.checkCallingOrSelfPermission(
   11972                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
   11973         enforceCrossUserPermission(uid, userId, false, true, "set enabled");
   11974         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
   11975         boolean sendNow = false;
   11976         boolean isApp = (className == null);
   11977         String componentName = isApp ? packageName : className;
   11978         int packageUid = -1;
   11979         ArrayList<String> components;
   11980 
   11981         // writer
   11982         synchronized (mPackages) {
   11983             pkgSetting = mSettings.mPackages.get(packageName);
   11984             if (pkgSetting == null) {
   11985                 if (className == null) {
   11986                     throw new IllegalArgumentException(
   11987                             "Unknown package: " + packageName);
   11988                 }
   11989                 throw new IllegalArgumentException(
   11990                         "Unknown component: " + packageName
   11991                         + "/" + className);
   11992             }
   11993             // Allow root and verify that userId is not being specified by a different user
   11994             if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) {
   11995                 throw new SecurityException(
   11996                         "Permission Denial: attempt to change component state from pid="
   11997                         + Binder.getCallingPid()
   11998                         + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
   11999             }
   12000             if (className == null) {
   12001                 // We're dealing with an application/package level state change
   12002                 if (pkgSetting.getEnabled(userId) == newState) {
   12003                     // Nothing to do
   12004                     return;
   12005                 }
   12006                 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
   12007                     || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
   12008                     // Don't care about who enables an app.
   12009                     callingPackage = null;
   12010                 }
   12011                 pkgSetting.setEnabled(newState, userId, callingPackage);
   12012                 // pkgSetting.pkg.mSetEnabled = newState;
   12013             } else {
   12014                 // We're dealing with a component level state change
   12015                 // First, verify that this is a valid class name.
   12016                 PackageParser.Package pkg = pkgSetting.pkg;
   12017                 if (pkg == null || !pkg.hasComponentClassName(className)) {
   12018                     if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) {
   12019                         throw new IllegalArgumentException("Component class " + className
   12020                                 + " does not exist in " + packageName);
   12021                     } else {
   12022                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
   12023                                 + className + " does not exist in " + packageName);
   12024                     }
   12025                 }
   12026                 switch (newState) {
   12027                 case COMPONENT_ENABLED_STATE_ENABLED:
   12028                     if (!pkgSetting.enableComponentLPw(className, userId)) {
   12029                         return;
   12030                     }
   12031                     break;
   12032                 case COMPONENT_ENABLED_STATE_DISABLED:
   12033                     if (!pkgSetting.disableComponentLPw(className, userId)) {
   12034                         return;
   12035                     }
   12036                     break;
   12037                 case COMPONENT_ENABLED_STATE_DEFAULT:
   12038                     if (!pkgSetting.restoreComponentLPw(className, userId)) {
   12039                         return;
   12040                     }
   12041                     break;
   12042                 default:
   12043                     Slog.e(TAG, "Invalid new component state: " + newState);
   12044                     return;
   12045                 }
   12046             }
   12047             mSettings.writePackageRestrictionsLPr(userId);
   12048             components = mPendingBroadcasts.get(userId, packageName);
   12049             final boolean newPackage = components == null;
   12050             if (newPackage) {
   12051                 components = new ArrayList<String>();
   12052             }
   12053             if (!components.contains(componentName)) {
   12054                 components.add(componentName);
   12055             }
   12056             if ((flags&PackageManager.DONT_KILL_APP) == 0) {
   12057                 sendNow = true;
   12058                 // Purge entry from pending broadcast list if another one exists already
   12059                 // since we are sending one right away.
   12060                 mPendingBroadcasts.remove(userId, packageName);
   12061             } else {
   12062                 if (newPackage) {
   12063                     mPendingBroadcasts.put(userId, packageName, components);
   12064                 }
   12065                 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
   12066                     // Schedule a message
   12067                     mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
   12068                 }
   12069             }
   12070         }
   12071 
   12072         long callingId = Binder.clearCallingIdentity();
   12073         try {
   12074             if (sendNow) {
   12075                 packageUid = UserHandle.getUid(userId, pkgSetting.appId);
   12076                 sendPackageChangedBroadcast(packageName,
   12077                         (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
   12078             }
   12079         } finally {
   12080             Binder.restoreCallingIdentity(callingId);
   12081         }
   12082     }
   12083 
   12084     private void sendPackageChangedBroadcast(String packageName,
   12085             boolean killFlag, ArrayList<String> componentNames, int packageUid) {
   12086         if (DEBUG_INSTALL)
   12087             Log.v(TAG, "Sending package changed: package=" + packageName + " components="
   12088                     + componentNames);
   12089         Bundle extras = new Bundle(4);
   12090         extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
   12091         String nameList[] = new String[componentNames.size()];
   12092         componentNames.toArray(nameList);
   12093         extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
   12094         extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
   12095         extras.putInt(Intent.EXTRA_UID, packageUid);
   12096         sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, null, null,
   12097                 new int[] {UserHandle.getUserId(packageUid)});
   12098     }
   12099 
   12100     @Override
   12101     public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
   12102         if (!sUserManager.exists(userId)) return;
   12103         final int uid = Binder.getCallingUid();
   12104         final int permission = mContext.checkCallingOrSelfPermission(
   12105                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
   12106         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
   12107         enforceCrossUserPermission(uid, userId, true, true, "stop package");
   12108         // writer
   12109         synchronized (mPackages) {
   12110             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
   12111                     uid, userId)) {
   12112                 scheduleWritePackageRestrictionsLocked(userId);
   12113             }
   12114         }
   12115     }
   12116 
   12117     @Override
   12118     public String getInstallerPackageName(String packageName) {
   12119         // reader
   12120         synchronized (mPackages) {
   12121             return mSettings.getInstallerPackageNameLPr(packageName);
   12122         }
   12123     }
   12124 
   12125     @Override
   12126     public int getApplicationEnabledSetting(String packageName, int userId) {
   12127         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
   12128         int uid = Binder.getCallingUid();
   12129         enforceCrossUserPermission(uid, userId, false, false, "get enabled");
   12130         // reader
   12131         synchronized (mPackages) {
   12132             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
   12133         }
   12134     }
   12135 
   12136     @Override
   12137     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
   12138         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
   12139         int uid = Binder.getCallingUid();
   12140         enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
   12141         // reader
   12142         synchronized (mPackages) {
   12143             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
   12144         }
   12145     }
   12146 
   12147     @Override
   12148     public void enterSafeMode() {
   12149         enforceSystemOrRoot("Only the system can request entering safe mode");
   12150 
   12151         if (!mSystemReady) {
   12152             mSafeMode = true;
   12153         }
   12154     }
   12155 
   12156     @Override
   12157     public void systemReady() {
   12158         mSystemReady = true;
   12159 
   12160         // Read the compatibilty setting when the system is ready.
   12161         boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
   12162                 mContext.getContentResolver(),
   12163                 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
   12164         PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
   12165         if (DEBUG_SETTINGS) {
   12166             Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
   12167         }
   12168 
   12169         synchronized (mPackages) {
   12170             // Verify that all of the preferred activity components actually
   12171             // exist.  It is possible for applications to be updated and at
   12172             // that point remove a previously declared activity component that
   12173             // had been set as a preferred activity.  We try to clean this up
   12174             // the next time we encounter that preferred activity, but it is
   12175             // possible for the user flow to never be able to return to that
   12176             // situation so here we do a sanity check to make sure we haven't
   12177             // left any junk around.
   12178             ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
   12179             for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   12180                 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   12181                 removed.clear();
   12182                 for (PreferredActivity pa : pir.filterSet()) {
   12183                     if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
   12184                         removed.add(pa);
   12185                     }
   12186                 }
   12187                 if (removed.size() > 0) {
   12188                     for (int r=0; r<removed.size(); r++) {
   12189                         PreferredActivity pa = removed.get(r);
   12190                         Slog.w(TAG, "Removing dangling preferred activity: "
   12191                                 + pa.mPref.mComponent);
   12192                         pir.removeFilter(pa);
   12193                     }
   12194                     mSettings.writePackageRestrictionsLPr(
   12195                             mSettings.mPreferredActivities.keyAt(i));
   12196                 }
   12197             }
   12198         }
   12199         sUserManager.systemReady();
   12200 
   12201         // Kick off any messages waiting for system ready
   12202         if (mPostSystemReadyMessages != null) {
   12203             for (Message msg : mPostSystemReadyMessages) {
   12204                 msg.sendToTarget();
   12205             }
   12206             mPostSystemReadyMessages = null;
   12207         }
   12208     }
   12209 
   12210     @Override
   12211     public boolean isSafeMode() {
   12212         return mSafeMode;
   12213     }
   12214 
   12215     @Override
   12216     public boolean hasSystemUidErrors() {
   12217         return mHasSystemUidErrors;
   12218     }
   12219 
   12220     static String arrayToString(int[] array) {
   12221         StringBuffer buf = new StringBuffer(128);
   12222         buf.append('[');
   12223         if (array != null) {
   12224             for (int i=0; i<array.length; i++) {
   12225                 if (i > 0) buf.append(", ");
   12226                 buf.append(array[i]);
   12227             }
   12228         }
   12229         buf.append(']');
   12230         return buf.toString();
   12231     }
   12232 
   12233     static class DumpState {
   12234         public static final int DUMP_LIBS = 1 << 0;
   12235         public static final int DUMP_FEATURES = 1 << 1;
   12236         public static final int DUMP_RESOLVERS = 1 << 2;
   12237         public static final int DUMP_PERMISSIONS = 1 << 3;
   12238         public static final int DUMP_PACKAGES = 1 << 4;
   12239         public static final int DUMP_SHARED_USERS = 1 << 5;
   12240         public static final int DUMP_MESSAGES = 1 << 6;
   12241         public static final int DUMP_PROVIDERS = 1 << 7;
   12242         public static final int DUMP_VERIFIERS = 1 << 8;
   12243         public static final int DUMP_PREFERRED = 1 << 9;
   12244         public static final int DUMP_PREFERRED_XML = 1 << 10;
   12245         public static final int DUMP_KEYSETS = 1 << 11;
   12246         public static final int DUMP_VERSION = 1 << 12;
   12247         public static final int DUMP_INSTALLS = 1 << 13;
   12248 
   12249         public static final int OPTION_SHOW_FILTERS = 1 << 0;
   12250 
   12251         private int mTypes;
   12252 
   12253         private int mOptions;
   12254 
   12255         private boolean mTitlePrinted;
   12256 
   12257         private SharedUserSetting mSharedUser;
   12258 
   12259         public boolean isDumping(int type) {
   12260             if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
   12261                 return true;
   12262             }
   12263 
   12264             return (mTypes & type) != 0;
   12265         }
   12266 
   12267         public void setDump(int type) {
   12268             mTypes |= type;
   12269         }
   12270 
   12271         public boolean isOptionEnabled(int option) {
   12272             return (mOptions & option) != 0;
   12273         }
   12274 
   12275         public void setOptionEnabled(int option) {
   12276             mOptions |= option;
   12277         }
   12278 
   12279         public boolean onTitlePrinted() {
   12280             final boolean printed = mTitlePrinted;
   12281             mTitlePrinted = true;
   12282             return printed;
   12283         }
   12284 
   12285         public boolean getTitlePrinted() {
   12286             return mTitlePrinted;
   12287         }
   12288 
   12289         public void setTitlePrinted(boolean enabled) {
   12290             mTitlePrinted = enabled;
   12291         }
   12292 
   12293         public SharedUserSetting getSharedUser() {
   12294             return mSharedUser;
   12295         }
   12296 
   12297         public void setSharedUser(SharedUserSetting user) {
   12298             mSharedUser = user;
   12299         }
   12300     }
   12301 
   12302     @Override
   12303     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   12304         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
   12305                 != PackageManager.PERMISSION_GRANTED) {
   12306             pw.println("Permission Denial: can't dump ActivityManager from from pid="
   12307                     + Binder.getCallingPid()
   12308                     + ", uid=" + Binder.getCallingUid()
   12309                     + " without permission "
   12310                     + android.Manifest.permission.DUMP);
   12311             return;
   12312         }
   12313 
   12314         DumpState dumpState = new DumpState();
   12315         boolean fullPreferred = false;
   12316         boolean checkin = false;
   12317 
   12318         String packageName = null;
   12319 
   12320         int opti = 0;
   12321         while (opti < args.length) {
   12322             String opt = args[opti];
   12323             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   12324                 break;
   12325             }
   12326             opti++;
   12327 
   12328             if ("-a".equals(opt)) {
   12329                 // Right now we only know how to print all.
   12330             } else if ("-h".equals(opt)) {
   12331                 pw.println("Package manager dump options:");
   12332                 pw.println("  [-h] [-f] [--checkin] [cmd] ...");
   12333                 pw.println("    --checkin: dump for a checkin");
   12334                 pw.println("    -f: print details of intent filters");
   12335                 pw.println("    -h: print this help");
   12336                 pw.println("  cmd may be one of:");
   12337                 pw.println("    l[ibraries]: list known shared libraries");
   12338                 pw.println("    f[ibraries]: list device features");
   12339                 pw.println("    k[eysets]: print known keysets");
   12340                 pw.println("    r[esolvers]: dump intent resolvers");
   12341                 pw.println("    perm[issions]: dump permissions");
   12342                 pw.println("    pref[erred]: print preferred package settings");
   12343                 pw.println("    preferred-xml [--full]: print preferred package settings as xml");
   12344                 pw.println("    prov[iders]: dump content providers");
   12345                 pw.println("    p[ackages]: dump installed packages");
   12346                 pw.println("    s[hared-users]: dump shared user IDs");
   12347                 pw.println("    m[essages]: print collected runtime messages");
   12348                 pw.println("    v[erifiers]: print package verifier info");
   12349                 pw.println("    version: print database version info");
   12350                 pw.println("    write: write current settings now");
   12351                 pw.println("    <package.name>: info about given package");
   12352                 pw.println("    installs: details about install sessions");
   12353                 return;
   12354             } else if ("--checkin".equals(opt)) {
   12355                 checkin = true;
   12356             } else if ("-f".equals(opt)) {
   12357                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
   12358             } else {
   12359                 pw.println("Unknown argument: " + opt + "; use -h for help");
   12360             }
   12361         }
   12362 
   12363         // Is the caller requesting to dump a particular piece of data?
   12364         if (opti < args.length) {
   12365             String cmd = args[opti];
   12366             opti++;
   12367             // Is this a package name?
   12368             if ("android".equals(cmd) || cmd.contains(".")) {
   12369                 packageName = cmd;
   12370                 // When dumping a single package, we always dump all of its
   12371                 // filter information since the amount of data will be reasonable.
   12372                 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
   12373             } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
   12374                 dumpState.setDump(DumpState.DUMP_LIBS);
   12375             } else if ("f".equals(cmd) || "features".equals(cmd)) {
   12376                 dumpState.setDump(DumpState.DUMP_FEATURES);
   12377             } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
   12378                 dumpState.setDump(DumpState.DUMP_RESOLVERS);
   12379             } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
   12380                 dumpState.setDump(DumpState.DUMP_PERMISSIONS);
   12381             } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
   12382                 dumpState.setDump(DumpState.DUMP_PREFERRED);
   12383             } else if ("preferred-xml".equals(cmd)) {
   12384                 dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
   12385                 if (opti < args.length && "--full".equals(args[opti])) {
   12386                     fullPreferred = true;
   12387                     opti++;
   12388                 }
   12389             } else if ("p".equals(cmd) || "packages".equals(cmd)) {
   12390                 dumpState.setDump(DumpState.DUMP_PACKAGES);
   12391             } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
   12392                 dumpState.setDump(DumpState.DUMP_SHARED_USERS);
   12393             } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
   12394                 dumpState.setDump(DumpState.DUMP_PROVIDERS);
   12395             } else if ("m".equals(cmd) || "messages".equals(cmd)) {
   12396                 dumpState.setDump(DumpState.DUMP_MESSAGES);
   12397             } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
   12398                 dumpState.setDump(DumpState.DUMP_VERIFIERS);
   12399             } else if ("version".equals(cmd)) {
   12400                 dumpState.setDump(DumpState.DUMP_VERSION);
   12401             } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
   12402                 dumpState.setDump(DumpState.DUMP_KEYSETS);
   12403             } else if ("installs".equals(cmd)) {
   12404                 dumpState.setDump(DumpState.DUMP_INSTALLS);
   12405             } else if ("write".equals(cmd)) {
   12406                 synchronized (mPackages) {
   12407                     mSettings.writeLPr();
   12408                     pw.println("Settings written.");
   12409                     return;
   12410                 }
   12411             }
   12412         }
   12413 
   12414         if (checkin) {
   12415             pw.println("vers,1");
   12416         }
   12417 
   12418         // reader
   12419         synchronized (mPackages) {
   12420             if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
   12421                 if (!checkin) {
   12422                     if (dumpState.onTitlePrinted())
   12423                         pw.println();
   12424                     pw.println("Database versions:");
   12425                     pw.print("  SDK Version:");
   12426                     pw.print(" internal=");
   12427                     pw.print(mSettings.mInternalSdkPlatform);
   12428                     pw.print(" external=");
   12429                     pw.println(mSettings.mExternalSdkPlatform);
   12430                     pw.print("  DB Version:");
   12431                     pw.print(" internal=");
   12432                     pw.print(mSettings.mInternalDatabaseVersion);
   12433                     pw.print(" external=");
   12434                     pw.println(mSettings.mExternalDatabaseVersion);
   12435                 }
   12436             }
   12437 
   12438             if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
   12439                 if (!checkin) {
   12440                     if (dumpState.onTitlePrinted())
   12441                         pw.println();
   12442                     pw.println("Verifiers:");
   12443                     pw.print("  Required: ");
   12444                     pw.print(mRequiredVerifierPackage);
   12445                     pw.print(" (uid=");
   12446                     pw.print(getPackageUid(mRequiredVerifierPackage, 0));
   12447                     pw.println(")");
   12448                 } else if (mRequiredVerifierPackage != null) {
   12449                     pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
   12450                     pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0));
   12451                 }
   12452             }
   12453 
   12454             if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
   12455                 boolean printedHeader = false;
   12456                 final Iterator<String> it = mSharedLibraries.keySet().iterator();
   12457                 while (it.hasNext()) {
   12458                     String name = it.next();
   12459                     SharedLibraryEntry ent = mSharedLibraries.get(name);
   12460                     if (!checkin) {
   12461                         if (!printedHeader) {
   12462                             if (dumpState.onTitlePrinted())
   12463                                 pw.println();
   12464                             pw.println("Libraries:");
   12465                             printedHeader = true;
   12466                         }
   12467                         pw.print("  ");
   12468                     } else {
   12469                         pw.print("lib,");
   12470                     }
   12471                     pw.print(name);
   12472                     if (!checkin) {
   12473                         pw.print(" -> ");
   12474                     }
   12475                     if (ent.path != null) {
   12476                         if (!checkin) {
   12477                             pw.print("(jar) ");
   12478                             pw.print(ent.path);
   12479                         } else {
   12480                             pw.print(",jar,");
   12481                             pw.print(ent.path);
   12482                         }
   12483                     } else {
   12484                         if (!checkin) {
   12485                             pw.print("(apk) ");
   12486                             pw.print(ent.apk);
   12487                         } else {
   12488                             pw.print(",apk,");
   12489                             pw.print(ent.apk);
   12490                         }
   12491                     }
   12492                     pw.println();
   12493                 }
   12494             }
   12495 
   12496             if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
   12497                 if (dumpState.onTitlePrinted())
   12498                     pw.println();
   12499                 if (!checkin) {
   12500                     pw.println("Features:");
   12501                 }
   12502                 Iterator<String> it = mAvailableFeatures.keySet().iterator();
   12503                 while (it.hasNext()) {
   12504                     String name = it.next();
   12505                     if (!checkin) {
   12506                         pw.print("  ");
   12507                     } else {
   12508                         pw.print("feat,");
   12509                     }
   12510                     pw.println(name);
   12511                 }
   12512             }
   12513 
   12514             if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) {
   12515                 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
   12516                         : "Activity Resolver Table:", "  ", packageName,
   12517                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
   12518                     dumpState.setTitlePrinted(true);
   12519                 }
   12520                 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
   12521                         : "Receiver Resolver Table:", "  ", packageName,
   12522                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
   12523                     dumpState.setTitlePrinted(true);
   12524                 }
   12525                 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
   12526                         : "Service Resolver Table:", "  ", packageName,
   12527                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
   12528                     dumpState.setTitlePrinted(true);
   12529                 }
   12530                 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
   12531                         : "Provider Resolver Table:", "  ", packageName,
   12532                         dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
   12533                     dumpState.setTitlePrinted(true);
   12534                 }
   12535             }
   12536 
   12537             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
   12538                 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
   12539                     PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
   12540                     int user = mSettings.mPreferredActivities.keyAt(i);
   12541                     if (pir.dump(pw,
   12542                             dumpState.getTitlePrinted()
   12543                                 ? "\nPreferred Activities User " + user + ":"
   12544                                 : "Preferred Activities User " + user + ":", "  ",
   12545                             packageName, true)) {
   12546                         dumpState.setTitlePrinted(true);
   12547                     }
   12548                 }
   12549             }
   12550 
   12551             if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
   12552                 pw.flush();
   12553                 FileOutputStream fout = new FileOutputStream(fd);
   12554                 BufferedOutputStream str = new BufferedOutputStream(fout);
   12555                 XmlSerializer serializer = new FastXmlSerializer();
   12556                 try {
   12557                     serializer.setOutput(str, "utf-8");
   12558                     serializer.startDocument(null, true);
   12559                     serializer.setFeature(
   12560                             "http://xmlpull.org/v1/doc/features.html#indent-output", true);
   12561                     mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
   12562                     serializer.endDocument();
   12563                     serializer.flush();
   12564                 } catch (IllegalArgumentException e) {
   12565                     pw.println("Failed writing: " + e);
   12566                 } catch (IllegalStateException e) {
   12567                     pw.println("Failed writing: " + e);
   12568                 } catch (IOException e) {
   12569                     pw.println("Failed writing: " + e);
   12570                 }
   12571             }
   12572 
   12573             if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
   12574                 mSettings.dumpPermissionsLPr(pw, packageName, dumpState);
   12575                 if (packageName == null) {
   12576                     for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
   12577                         if (iperm == 0) {
   12578                             if (dumpState.onTitlePrinted())
   12579                                 pw.println();
   12580                             pw.println("AppOp Permissions:");
   12581                         }
   12582                         pw.print("  AppOp Permission ");
   12583                         pw.print(mAppOpPermissionPackages.keyAt(iperm));
   12584                         pw.println(":");
   12585                         ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
   12586                         for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
   12587                             pw.print("    "); pw.println(pkgs.valueAt(ipkg));
   12588                         }
   12589                     }
   12590                 }
   12591             }
   12592 
   12593             if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
   12594                 boolean printedSomething = false;
   12595                 for (PackageParser.Provider p : mProviders.mProviders.values()) {
   12596                     if (packageName != null && !packageName.equals(p.info.packageName)) {
   12597                         continue;
   12598                     }
   12599                     if (!printedSomething) {
   12600                         if (dumpState.onTitlePrinted())
   12601                             pw.println();
   12602                         pw.println("Registered ContentProviders:");
   12603                         printedSomething = true;
   12604                     }
   12605                     pw.print("  "); p.printComponentShortName(pw); pw.println(":");
   12606                     pw.print("    "); pw.println(p.toString());
   12607                 }
   12608                 printedSomething = false;
   12609                 for (Map.Entry<String, PackageParser.Provider> entry :
   12610                         mProvidersByAuthority.entrySet()) {
   12611                     PackageParser.Provider p = entry.getValue();
   12612                     if (packageName != null && !packageName.equals(p.info.packageName)) {
   12613                         continue;
   12614                     }
   12615                     if (!printedSomething) {
   12616                         if (dumpState.onTitlePrinted())
   12617                             pw.println();
   12618                         pw.println("ContentProvider Authorities:");
   12619                         printedSomething = true;
   12620                     }
   12621                     pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
   12622                     pw.print("    "); pw.println(p.toString());
   12623                     if (p.info != null && p.info.applicationInfo != null) {
   12624                         final String appInfo = p.info.applicationInfo.toString();
   12625                         pw.print("      applicationInfo="); pw.println(appInfo);
   12626                     }
   12627                 }
   12628             }
   12629 
   12630             if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
   12631                 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
   12632             }
   12633 
   12634             if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
   12635                 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin);
   12636             }
   12637 
   12638             if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
   12639                 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState);
   12640             }
   12641 
   12642             if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
   12643                 // XXX should handle packageName != null by dumping only install data that
   12644                 // the given package is involved with.
   12645                 if (dumpState.onTitlePrinted()) pw.println();
   12646                 mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
   12647             }
   12648 
   12649             if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
   12650                 if (dumpState.onTitlePrinted()) pw.println();
   12651                 mSettings.dumpReadMessagesLPr(pw, dumpState);
   12652 
   12653                 pw.println();
   12654                 pw.println("Package warning messages:");
   12655                 final File fname = getSettingsProblemFile();
   12656                 FileInputStream in = null;
   12657                 try {
   12658                     in = new FileInputStream(fname);
   12659                     final int avail = in.available();
   12660                     final byte[] data = new byte[avail];
   12661                     in.read(data);
   12662                     pw.print(new String(data));
   12663                 } catch (FileNotFoundException e) {
   12664                 } catch (IOException e) {
   12665                 } finally {
   12666                     if (in != null) {
   12667                         try {
   12668                             in.close();
   12669                         } catch (IOException e) {
   12670                         }
   12671                     }
   12672                 }
   12673             }
   12674 
   12675             if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
   12676                 BufferedReader in = null;
   12677                 String line = null;
   12678                 try {
   12679                     in = new BufferedReader(new FileReader(getSettingsProblemFile()));
   12680                     while ((line = in.readLine()) != null) {
   12681                         pw.print("msg,");
   12682                         pw.println(line);
   12683                     }
   12684                 } catch (IOException ignored) {
   12685                 } finally {
   12686                     IoUtils.closeQuietly(in);
   12687                 }
   12688             }
   12689         }
   12690     }
   12691 
   12692     // ------- apps on sdcard specific code -------
   12693     static final boolean DEBUG_SD_INSTALL = false;
   12694 
   12695     private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
   12696 
   12697     private static final String SD_ENCRYPTION_ALGORITHM = "AES";
   12698 
   12699     private boolean mMediaMounted = false;
   12700 
   12701     static String getEncryptKey() {
   12702         try {
   12703             String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
   12704                     SD_ENCRYPTION_KEYSTORE_NAME);
   12705             if (sdEncKey == null) {
   12706                 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
   12707                         SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
   12708                 if (sdEncKey == null) {
   12709                     Slog.e(TAG, "Failed to create encryption keys");
   12710                     return null;
   12711                 }
   12712             }
   12713             return sdEncKey;
   12714         } catch (NoSuchAlgorithmException nsae) {
   12715             Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
   12716             return null;
   12717         } catch (IOException ioe) {
   12718             Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
   12719             return null;
   12720         }
   12721     }
   12722 
   12723     /*
   12724      * Update media status on PackageManager.
   12725      */
   12726     @Override
   12727     public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
   12728         int callingUid = Binder.getCallingUid();
   12729         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
   12730             throw new SecurityException("Media status can only be updated by the system");
   12731         }
   12732         // reader; this apparently protects mMediaMounted, but should probably
   12733         // be a different lock in that case.
   12734         synchronized (mPackages) {
   12735             Log.i(TAG, "Updating external media status from "
   12736                     + (mMediaMounted ? "mounted" : "unmounted") + " to "
   12737                     + (mediaStatus ? "mounted" : "unmounted"));
   12738             if (DEBUG_SD_INSTALL)
   12739                 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
   12740                         + ", mMediaMounted=" + mMediaMounted);
   12741             if (mediaStatus == mMediaMounted) {
   12742                 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
   12743                         : 0, -1);
   12744                 mHandler.sendMessage(msg);
   12745                 return;
   12746             }
   12747             mMediaMounted = mediaStatus;
   12748         }
   12749         // Queue up an async operation since the package installation may take a
   12750         // little while.
   12751         mHandler.post(new Runnable() {
   12752             public void run() {
   12753                 updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
   12754             }
   12755         });
   12756     }
   12757 
   12758     /**
   12759      * Called by MountService when the initial ASECs to scan are available.
   12760      * Should block until all the ASEC containers are finished being scanned.
   12761      */
   12762     public void scanAvailableAsecs() {
   12763         updateExternalMediaStatusInner(true, false, false);
   12764         if (mShouldRestoreconData) {
   12765             SELinuxMMAC.setRestoreconDone();
   12766             mShouldRestoreconData = false;
   12767         }
   12768     }
   12769 
   12770     /*
   12771      * Collect information of applications on external media, map them against
   12772      * existing containers and update information based on current mount status.
   12773      * Please note that we always have to report status if reportStatus has been
   12774      * set to true especially when unloading packages.
   12775      */
   12776     private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
   12777             boolean externalStorage) {
   12778         ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
   12779         int[] uidArr = EmptyArray.INT;
   12780 
   12781         final String[] list = PackageHelper.getSecureContainerList();
   12782         if (ArrayUtils.isEmpty(list)) {
   12783             Log.i(TAG, "No secure containers found");
   12784         } else {
   12785             // Process list of secure containers and categorize them
   12786             // as active or stale based on their package internal state.
   12787 
   12788             // reader
   12789             synchronized (mPackages) {
   12790                 for (String cid : list) {
   12791                     // Leave stages untouched for now; installer service owns them
   12792                     if (PackageInstallerService.isStageName(cid)) continue;
   12793 
   12794                     if (DEBUG_SD_INSTALL)
   12795                         Log.i(TAG, "Processing container " + cid);
   12796                     String pkgName = getAsecPackageName(cid);
   12797                     if (pkgName == null) {
   12798                         Slog.i(TAG, "Found stale container " + cid + " with no package name");
   12799                         continue;
   12800                     }
   12801                     if (DEBUG_SD_INSTALL)
   12802                         Log.i(TAG, "Looking for pkg : " + pkgName);
   12803 
   12804                     final PackageSetting ps = mSettings.mPackages.get(pkgName);
   12805                     if (ps == null) {
   12806                         Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
   12807                         continue;
   12808                     }
   12809 
   12810                     /*
   12811                      * Skip packages that are not external if we're unmounting
   12812                      * external storage.
   12813                      */
   12814                     if (externalStorage && !isMounted && !isExternal(ps)) {
   12815                         continue;
   12816                     }
   12817 
   12818                     final AsecInstallArgs args = new AsecInstallArgs(cid,
   12819                             getAppDexInstructionSets(ps), isForwardLocked(ps));
   12820                     // The package status is changed only if the code path
   12821                     // matches between settings and the container id.
   12822                     if (ps.codePathString != null
   12823                             && ps.codePathString.startsWith(args.getCodePath())) {
   12824                         if (DEBUG_SD_INSTALL) {
   12825                             Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
   12826                                     + " at code path: " + ps.codePathString);
   12827                         }
   12828 
   12829                         // We do have a valid package installed on sdcard
   12830                         processCids.put(args, ps.codePathString);
   12831                         final int uid = ps.appId;
   12832                         if (uid != -1) {
   12833                             uidArr = ArrayUtils.appendInt(uidArr, uid);
   12834                         }
   12835                     } else {
   12836                         Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
   12837                                 + ps.codePathString);
   12838                     }
   12839                 }
   12840             }
   12841 
   12842             Arrays.sort(uidArr);
   12843         }
   12844 
   12845         // Process packages with valid entries.
   12846         if (isMounted) {
   12847             if (DEBUG_SD_INSTALL)
   12848                 Log.i(TAG, "Loading packages");
   12849             loadMediaPackages(processCids, uidArr);
   12850             startCleaningPackages();
   12851             mInstallerService.onSecureContainersAvailable();
   12852         } else {
   12853             if (DEBUG_SD_INSTALL)
   12854                 Log.i(TAG, "Unloading packages");
   12855             unloadMediaPackages(processCids, uidArr, reportStatus);
   12856         }
   12857     }
   12858 
   12859     private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
   12860             ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
   12861         int size = pkgList.size();
   12862         if (size > 0) {
   12863             // Send broadcasts here
   12864             Bundle extras = new Bundle();
   12865             extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList
   12866                     .toArray(new String[size]));
   12867             if (uidArr != null) {
   12868                 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
   12869             }
   12870             if (replacing) {
   12871                 extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
   12872             }
   12873             String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
   12874                     : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
   12875             sendPackageBroadcast(action, null, extras, null, finishedReceiver, null);
   12876         }
   12877     }
   12878 
   12879    /*
   12880      * Look at potentially valid container ids from processCids If package
   12881      * information doesn't match the one on record or package scanning fails,
   12882      * the cid is added to list of removeCids. We currently don't delete stale
   12883      * containers.
   12884      */
   12885     private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) {
   12886         ArrayList<String> pkgList = new ArrayList<String>();
   12887         Set<AsecInstallArgs> keys = processCids.keySet();
   12888 
   12889         for (AsecInstallArgs args : keys) {
   12890             String codePath = processCids.get(args);
   12891             if (DEBUG_SD_INSTALL)
   12892                 Log.i(TAG, "Loading container : " + args.cid);
   12893             int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
   12894             try {
   12895                 // Make sure there are no container errors first.
   12896                 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
   12897                     Slog.e(TAG, "Failed to mount cid : " + args.cid
   12898                             + " when installing from sdcard");
   12899                     continue;
   12900                 }
   12901                 // Check code path here.
   12902                 if (codePath == null || !codePath.startsWith(args.getCodePath())) {
   12903                     Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
   12904                             + " does not match one in settings " + codePath);
   12905                     continue;
   12906                 }
   12907                 // Parse package
   12908                 int parseFlags = mDefParseFlags;
   12909                 if (args.isExternal()) {
   12910                     parseFlags |= PackageParser.PARSE_ON_SDCARD;
   12911                 }
   12912                 if (args.isFwdLocked()) {
   12913                     parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
   12914                 }
   12915 
   12916                 synchronized (mInstallLock) {
   12917                     PackageParser.Package pkg = null;
   12918                     try {
   12919                         pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
   12920                     } catch (PackageManagerException e) {
   12921                         Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
   12922                     }
   12923                     // Scan the package
   12924                     if (pkg != null) {
   12925                         /*
   12926                          * TODO why is the lock being held? doPostInstall is
   12927                          * called in other places without the lock. This needs
   12928                          * to be straightened out.
   12929                          */
   12930                         // writer
   12931                         synchronized (mPackages) {
   12932                             retCode = PackageManager.INSTALL_SUCCEEDED;
   12933                             pkgList.add(pkg.packageName);
   12934                             // Post process args
   12935                             args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
   12936                                     pkg.applicationInfo.uid);
   12937                         }
   12938                     } else {
   12939                         Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
   12940                     }
   12941                 }
   12942 
   12943             } finally {
   12944                 if (retCode != PackageManager.INSTALL_SUCCEEDED) {
   12945                     Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
   12946                 }
   12947             }
   12948         }
   12949         // writer
   12950         synchronized (mPackages) {
   12951             // If the platform SDK has changed since the last time we booted,
   12952             // we need to re-grant app permission to catch any new ones that
   12953             // appear. This is really a hack, and means that apps can in some
   12954             // cases get permissions that the user didn't initially explicitly
   12955             // allow... it would be nice to have some better way to handle
   12956             // this situation.
   12957             final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion;
   12958             if (regrantPermissions)
   12959                 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to "
   12960                         + mSdkVersion + "; regranting permissions for external storage");
   12961             mSettings.mExternalSdkPlatform = mSdkVersion;
   12962 
   12963             // Make sure group IDs have been assigned, and any permission
   12964             // changes in other apps are accounted for
   12965             updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
   12966                     | (regrantPermissions
   12967                             ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
   12968                             : 0));
   12969 
   12970             mSettings.updateExternalDatabaseVersion();
   12971 
   12972             // can downgrade to reader
   12973             // Persist settings
   12974             mSettings.writeLPr();
   12975         }
   12976         // Send a broadcast to let everyone know we are done processing
   12977         if (pkgList.size() > 0) {
   12978             sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
   12979         }
   12980     }
   12981 
   12982    /*
   12983      * Utility method to unload a list of specified containers
   12984      */
   12985     private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
   12986         // Just unmount all valid containers.
   12987         for (AsecInstallArgs arg : cidArgs) {
   12988             synchronized (mInstallLock) {
   12989                 arg.doPostDeleteLI(false);
   12990            }
   12991        }
   12992    }
   12993 
   12994     /*
   12995      * Unload packages mounted on external media. This involves deleting package
   12996      * data from internal structures, sending broadcasts about diabled packages,
   12997      * gc'ing to free up references, unmounting all secure containers
   12998      * corresponding to packages on external media, and posting a
   12999      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
   13000      * that we always have to post this message if status has been requested no
   13001      * matter what.
   13002      */
   13003     private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
   13004             final boolean reportStatus) {
   13005         if (DEBUG_SD_INSTALL)
   13006             Log.i(TAG, "unloading media packages");
   13007         ArrayList<String> pkgList = new ArrayList<String>();
   13008         ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
   13009         final Set<AsecInstallArgs> keys = processCids.keySet();
   13010         for (AsecInstallArgs args : keys) {
   13011             String pkgName = args.getPackageName();
   13012             if (DEBUG_SD_INSTALL)
   13013                 Log.i(TAG, "Trying to unload pkg : " + pkgName);
   13014             // Delete package internally
   13015             PackageRemovedInfo outInfo = new PackageRemovedInfo();
   13016             synchronized (mInstallLock) {
   13017                 boolean res = deletePackageLI(pkgName, null, false, null, null,
   13018                         PackageManager.DELETE_KEEP_DATA, outInfo, false);
   13019                 if (res) {
   13020                     pkgList.add(pkgName);
   13021                 } else {
   13022                     Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
   13023                     failedList.add(args);
   13024                 }
   13025             }
   13026         }
   13027 
   13028         // reader
   13029         synchronized (mPackages) {
   13030             // We didn't update the settings after removing each package;
   13031             // write them now for all packages.
   13032             mSettings.writeLPr();
   13033         }
   13034 
   13035         // We have to absolutely send UPDATED_MEDIA_STATUS only
   13036         // after confirming that all the receivers processed the ordered
   13037         // broadcast when packages get disabled, force a gc to clean things up.
   13038         // and unload all the containers.
   13039         if (pkgList.size() > 0) {
   13040             sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
   13041                     new IIntentReceiver.Stub() {
   13042                 public void performReceive(Intent intent, int resultCode, String data,
   13043                         Bundle extras, boolean ordered, boolean sticky,
   13044                         int sendingUser) throws RemoteException {
   13045                     Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
   13046                             reportStatus ? 1 : 0, 1, keys);
   13047                     mHandler.sendMessage(msg);
   13048                 }
   13049             });
   13050         } else {
   13051             Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
   13052                     keys);
   13053             mHandler.sendMessage(msg);
   13054         }
   13055     }
   13056 
   13057     /** Binder call */
   13058     @Override
   13059     public void movePackage(final String packageName, final IPackageMoveObserver observer,
   13060             final int flags) {
   13061         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
   13062         UserHandle user = new UserHandle(UserHandle.getCallingUserId());
   13063         int returnCode = PackageManager.MOVE_SUCCEEDED;
   13064         int currInstallFlags = 0;
   13065         int newInstallFlags = 0;
   13066 
   13067         File codeFile = null;
   13068         String installerPackageName = null;
   13069         String packageAbiOverride = null;
   13070 
   13071         // reader
   13072         synchronized (mPackages) {
   13073             final PackageParser.Package pkg = mPackages.get(packageName);
   13074             final PackageSetting ps = mSettings.mPackages.get(packageName);
   13075             if (pkg == null || ps == null) {
   13076                 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
   13077             } else {
   13078                 // Disable moving fwd locked apps and system packages
   13079                 if (pkg.applicationInfo != null && isSystemApp(pkg)) {
   13080                     Slog.w(TAG, "Cannot move system application");
   13081                     returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
   13082                 } else if (pkg.mOperationPending) {
   13083                     Slog.w(TAG, "Attempt to move package which has pending operations");
   13084                     returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING;
   13085                 } else {
   13086                     // Find install location first
   13087                     if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
   13088                             && (flags & PackageManager.MOVE_INTERNAL) != 0) {
   13089                         Slog.w(TAG, "Ambigous flags specified for move location.");
   13090                         returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
   13091                     } else {
   13092                         newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0
   13093                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
   13094                         currInstallFlags = isExternal(pkg)
   13095                                 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
   13096 
   13097                         if (newInstallFlags == currInstallFlags) {
   13098                             Slog.w(TAG, "No move required. Trying to move to same location");
   13099                             returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
   13100                         } else {
   13101                             if (isForwardLocked(pkg)) {
   13102                                 currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
   13103                                 newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK;
   13104                             }
   13105                         }
   13106                     }
   13107                     if (returnCode == PackageManager.MOVE_SUCCEEDED) {
   13108                         pkg.mOperationPending = true;
   13109                     }
   13110                 }
   13111 
   13112                 codeFile = new File(pkg.codePath);
   13113                 installerPackageName = ps.installerPackageName;
   13114                 packageAbiOverride = ps.cpuAbiOverrideString;
   13115             }
   13116         }
   13117 
   13118         if (returnCode != PackageManager.MOVE_SUCCEEDED) {
   13119             try {
   13120                 observer.packageMoved(packageName, returnCode);
   13121             } catch (RemoteException ignored) {
   13122             }
   13123             return;
   13124         }
   13125 
   13126         final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
   13127             @Override
   13128             public void onUserActionRequired(Intent intent) throws RemoteException {
   13129                 throw new IllegalStateException();
   13130             }
   13131 
   13132             @Override
   13133             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
   13134                     Bundle extras) throws RemoteException {
   13135                 Slog.d(TAG, "Install result for move: "
   13136                         + PackageManager.installStatusToString(returnCode, msg));
   13137 
   13138                 // We usually have a new package now after the install, but if
   13139                 // we failed we need to clear the pending flag on the original
   13140                 // package object.
   13141                 synchronized (mPackages) {
   13142                     final PackageParser.Package pkg = mPackages.get(packageName);
   13143                     if (pkg != null) {
   13144                         pkg.mOperationPending = false;
   13145                     }
   13146                 }
   13147 
   13148                 final int status = PackageManager.installStatusToPublicStatus(returnCode);
   13149                 switch (status) {
   13150                     case PackageInstaller.STATUS_SUCCESS:
   13151                         observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED);
   13152                         break;
   13153                     case PackageInstaller.STATUS_FAILURE_STORAGE:
   13154                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
   13155                         break;
   13156                     default:
   13157                         observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
   13158                         break;
   13159                 }
   13160             }
   13161         };
   13162 
   13163         // Treat a move like reinstalling an existing app, which ensures that we
   13164         // process everythign uniformly, like unpacking native libraries.
   13165         newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
   13166 
   13167         final Message msg = mHandler.obtainMessage(INIT_COPY);
   13168         final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
   13169         msg.obj = new InstallParams(origin, installObserver, newInstallFlags,
   13170                 installerPackageName, null, user, packageAbiOverride);
   13171         mHandler.sendMessage(msg);
   13172     }
   13173 
   13174     @Override
   13175     public boolean setInstallLocation(int loc) {
   13176         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
   13177                 null);
   13178         if (getInstallLocation() == loc) {
   13179             return true;
   13180         }
   13181         if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
   13182                 || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
   13183             android.provider.Settings.Global.putInt(mContext.getContentResolver(),
   13184                     android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
   13185             return true;
   13186         }
   13187         return false;
   13188    }
   13189 
   13190     @Override
   13191     public int getInstallLocation() {
   13192         return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
   13193                 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
   13194                 PackageHelper.APP_INSTALL_AUTO);
   13195     }
   13196 
   13197     /** Called by UserManagerService */
   13198     void cleanUpUserLILPw(UserManagerService userManager, int userHandle) {
   13199         mDirtyUsers.remove(userHandle);
   13200         mSettings.removeUserLPw(userHandle);
   13201         mPendingBroadcasts.remove(userHandle);
   13202         if (mInstaller != null) {
   13203             // Technically, we shouldn't be doing this with the package lock
   13204             // held.  However, this is very rare, and there is already so much
   13205             // other disk I/O going on, that we'll let it slide for now.
   13206             mInstaller.removeUserDataDirs(userHandle);
   13207         }
   13208         mUserNeedsBadging.delete(userHandle);
   13209         removeUnusedPackagesLILPw(userManager, userHandle);
   13210     }
   13211 
   13212     /**
   13213      * We're removing userHandle and would like to remove any downloaded packages
   13214      * that are no longer in use by any other user.
   13215      * @param userHandle the user being removed
   13216      */
   13217     private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) {
   13218         final boolean DEBUG_CLEAN_APKS = false;
   13219         int [] users = userManager.getUserIdsLPr();
   13220         Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
   13221         while (psit.hasNext()) {
   13222             PackageSetting ps = psit.next();
   13223             if (ps.pkg == null) {
   13224                 continue;
   13225             }
   13226             final String packageName = ps.pkg.packageName;
   13227             // Skip over if system app
   13228             if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   13229                 continue;
   13230             }
   13231             if (DEBUG_CLEAN_APKS) {
   13232                 Slog.i(TAG, "Checking package " + packageName);
   13233             }
   13234             boolean keep = false;
   13235             for (int i = 0; i < users.length; i++) {
   13236                 if (users[i] != userHandle && ps.getInstalled(users[i])) {
   13237                     keep = true;
   13238                     if (DEBUG_CLEAN_APKS) {
   13239                         Slog.i(TAG, "  Keeping package " + packageName + " for user "
   13240                                 + users[i]);
   13241                     }
   13242                     break;
   13243                 }
   13244             }
   13245             if (!keep) {
   13246                 if (DEBUG_CLEAN_APKS) {
   13247                     Slog.i(TAG, "  Removing package " + packageName);
   13248                 }
   13249                 mHandler.post(new Runnable() {
   13250                     public void run() {
   13251                         deletePackageX(packageName, userHandle, 0);
   13252                     } //end run
   13253                 });
   13254             }
   13255         }
   13256     }
   13257 
   13258     /** Called by UserManagerService */
   13259     void createNewUserLILPw(int userHandle, File path) {
   13260         if (mInstaller != null) {
   13261             mInstaller.createUserConfig(userHandle);
   13262             mSettings.createNewUserLILPw(this, mInstaller, userHandle, path);
   13263         }
   13264     }
   13265 
   13266     @Override
   13267     public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
   13268         mContext.enforceCallingOrSelfPermission(
   13269                 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
   13270                 "Only package verification agents can read the verifier device identity");
   13271 
   13272         synchronized (mPackages) {
   13273             return mSettings.getVerifierDeviceIdentityLPw();
   13274         }
   13275     }
   13276 
   13277     @Override
   13278     public void setPermissionEnforced(String permission, boolean enforced) {
   13279         mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null);
   13280         if (READ_EXTERNAL_STORAGE.equals(permission)) {
   13281             synchronized (mPackages) {
   13282                 if (mSettings.mReadExternalStorageEnforced == null
   13283                         || mSettings.mReadExternalStorageEnforced != enforced) {
   13284                     mSettings.mReadExternalStorageEnforced = enforced;
   13285                     mSettings.writeLPr();
   13286                 }
   13287             }
   13288             // kill any non-foreground processes so we restart them and
   13289             // grant/revoke the GID.
   13290             final IActivityManager am = ActivityManagerNative.getDefault();
   13291             if (am != null) {
   13292                 final long token = Binder.clearCallingIdentity();
   13293                 try {
   13294                     am.killProcessesBelowForeground("setPermissionEnforcement");
   13295                 } catch (RemoteException e) {
   13296                 } finally {
   13297                     Binder.restoreCallingIdentity(token);
   13298                 }
   13299             }
   13300         } else {
   13301             throw new IllegalArgumentException("No selective enforcement for " + permission);
   13302         }
   13303     }
   13304 
   13305     @Override
   13306     @Deprecated
   13307     public boolean isPermissionEnforced(String permission) {
   13308         return true;
   13309     }
   13310 
   13311     @Override
   13312     public boolean isStorageLow() {
   13313         final long token = Binder.clearCallingIdentity();
   13314         try {
   13315             final DeviceStorageMonitorInternal
   13316                     dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
   13317             if (dsm != null) {
   13318                 return dsm.isMemoryLow();
   13319             } else {
   13320                 return false;
   13321             }
   13322         } finally {
   13323             Binder.restoreCallingIdentity(token);
   13324         }
   13325     }
   13326 
   13327     @Override
   13328     public IPackageInstaller getPackageInstaller() {
   13329         return mInstallerService;
   13330     }
   13331 
   13332     private boolean userNeedsBadging(int userId) {
   13333         int index = mUserNeedsBadging.indexOfKey(userId);
   13334         if (index < 0) {
   13335             final UserInfo userInfo;
   13336             final long token = Binder.clearCallingIdentity();
   13337             try {
   13338                 userInfo = sUserManager.getUserInfo(userId);
   13339             } finally {
   13340                 Binder.restoreCallingIdentity(token);
   13341             }
   13342             final boolean b;
   13343             if (userInfo != null && userInfo.isManagedProfile()) {
   13344                 b = true;
   13345             } else {
   13346                 b = false;
   13347             }
   13348             mUserNeedsBadging.put(userId, b);
   13349             return b;
   13350         }
   13351         return mUserNeedsBadging.valueAt(index);
   13352     }
   13353 
   13354     @Override
   13355     public KeySet getKeySetByAlias(String packageName, String alias) {
   13356         if (packageName == null || alias == null) {
   13357             return null;
   13358         }
   13359         synchronized(mPackages) {
   13360             final PackageParser.Package pkg = mPackages.get(packageName);
   13361             if (pkg == null) {
   13362                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
   13363                 throw new IllegalArgumentException("Unknown package: " + packageName);
   13364             }
   13365             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   13366             return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
   13367         }
   13368     }
   13369 
   13370     @Override
   13371     public KeySet getSigningKeySet(String packageName) {
   13372         if (packageName == null) {
   13373             return null;
   13374         }
   13375         synchronized(mPackages) {
   13376             final PackageParser.Package pkg = mPackages.get(packageName);
   13377             if (pkg == null) {
   13378                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
   13379                 throw new IllegalArgumentException("Unknown package: " + packageName);
   13380             }
   13381             if (pkg.applicationInfo.uid != Binder.getCallingUid()
   13382                     && Process.SYSTEM_UID != Binder.getCallingUid()) {
   13383                 throw new SecurityException("May not access signing KeySet of other apps.");
   13384             }
   13385             KeySetManagerService ksms = mSettings.mKeySetManagerService;
   13386             return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
   13387         }
   13388     }
   13389 
   13390     @Override
   13391     public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
   13392         if (packageName == null || ks == null) {
   13393             return false;
   13394         }
   13395         synchronized(mPackages) {
   13396             final PackageParser.Package pkg = mPackages.get(packageName);
   13397             if (pkg == null) {
   13398                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
   13399                 throw new IllegalArgumentException("Unknown package: " + packageName);
   13400             }
   13401             IBinder ksh = ks.getToken();
   13402             if (ksh instanceof KeySetHandle) {
   13403                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
   13404                 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
   13405             }
   13406             return false;
   13407         }
   13408     }
   13409 
   13410     @Override
   13411     public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
   13412         if (packageName == null || ks == null) {
   13413             return false;
   13414         }
   13415         synchronized(mPackages) {
   13416             final PackageParser.Package pkg = mPackages.get(packageName);
   13417             if (pkg == null) {
   13418                 Slog.w(TAG, "KeySet requested for unknown package:" + packageName);
   13419                 throw new IllegalArgumentException("Unknown package: " + packageName);
   13420             }
   13421             IBinder ksh = ks.getToken();
   13422             if (ksh instanceof KeySetHandle) {
   13423                 KeySetManagerService ksms = mSettings.mKeySetManagerService;
   13424                 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
   13425             }
   13426             return false;
   13427         }
   13428     }
   13429 }
   13430