1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.pm; 18 19 import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS; 20 import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 21 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 25 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 26 import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 27 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 28 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 29 import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT; 30 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 31 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 32 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 33 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 34 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 35 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 36 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 37 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 38 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 39 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 40 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 41 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED; 42 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 43 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 44 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 45 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 46 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 47 import static android.content.pm.PackageParser.isApkFile; 48 import static android.os.Process.PACKAGE_INFO_GID; 49 import static android.os.Process.SYSTEM_UID; 50 import static android.system.OsConstants.O_CREAT; 51 import static android.system.OsConstants.O_RDWR; 52 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 53 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER; 54 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 55 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 56 import static com.android.internal.util.ArrayUtils.appendInt; 57 import static com.android.internal.util.ArrayUtils.removeInt; 58 59 import android.util.ArrayMap; 60 61 import com.android.internal.R; 62 import com.android.internal.app.IMediaContainerService; 63 import com.android.internal.app.ResolverActivity; 64 import com.android.internal.content.NativeLibraryHelper; 65 import com.android.internal.content.PackageHelper; 66 import com.android.internal.os.IParcelFileDescriptorFactory; 67 import com.android.internal.util.ArrayUtils; 68 import com.android.internal.util.FastPrintWriter; 69 import com.android.internal.util.FastXmlSerializer; 70 import com.android.internal.util.IndentingPrintWriter; 71 import com.android.server.EventLogTags; 72 import com.android.server.IntentResolver; 73 import com.android.server.LocalServices; 74 import com.android.server.ServiceThread; 75 import com.android.server.SystemConfig; 76 import com.android.server.Watchdog; 77 import com.android.server.pm.Settings.DatabaseVersion; 78 import com.android.server.storage.DeviceStorageMonitorInternal; 79 80 import org.xmlpull.v1.XmlSerializer; 81 82 import android.app.ActivityManager; 83 import android.app.ActivityManagerNative; 84 import android.app.AppGlobals; 85 import android.app.IActivityManager; 86 import android.app.admin.IDevicePolicyManager; 87 import android.app.backup.IBackupManager; 88 import android.app.usage.UsageStats; 89 import android.app.usage.UsageStatsManager; 90 import android.content.BroadcastReceiver; 91 import android.content.ComponentName; 92 import android.content.Context; 93 import android.content.IIntentReceiver; 94 import android.content.Intent; 95 import android.content.IntentFilter; 96 import android.content.IntentSender; 97 import android.content.IntentSender.SendIntentException; 98 import android.content.ServiceConnection; 99 import android.content.pm.ActivityInfo; 100 import android.content.pm.ApplicationInfo; 101 import android.content.pm.FeatureInfo; 102 import android.content.pm.IPackageDataObserver; 103 import android.content.pm.IPackageDeleteObserver; 104 import android.content.pm.IPackageDeleteObserver2; 105 import android.content.pm.IPackageInstallObserver2; 106 import android.content.pm.IPackageInstaller; 107 import android.content.pm.IPackageManager; 108 import android.content.pm.IPackageMoveObserver; 109 import android.content.pm.IPackageStatsObserver; 110 import android.content.pm.InstrumentationInfo; 111 import android.content.pm.KeySet; 112 import android.content.pm.ManifestDigest; 113 import android.content.pm.PackageCleanItem; 114 import android.content.pm.PackageInfo; 115 import android.content.pm.PackageInfoLite; 116 import android.content.pm.PackageInstaller; 117 import android.content.pm.PackageManager; 118 import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 119 import android.content.pm.PackageParser.ActivityIntentInfo; 120 import android.content.pm.PackageParser.PackageLite; 121 import android.content.pm.PackageParser.PackageParserException; 122 import android.content.pm.PackageParser; 123 import android.content.pm.PackageStats; 124 import android.content.pm.PackageUserState; 125 import android.content.pm.ParceledListSlice; 126 import android.content.pm.PermissionGroupInfo; 127 import android.content.pm.PermissionInfo; 128 import android.content.pm.ProviderInfo; 129 import android.content.pm.ResolveInfo; 130 import android.content.pm.ServiceInfo; 131 import android.content.pm.Signature; 132 import android.content.pm.UserInfo; 133 import android.content.pm.VerificationParams; 134 import android.content.pm.VerifierDeviceIdentity; 135 import android.content.pm.VerifierInfo; 136 import android.content.res.Resources; 137 import android.hardware.display.DisplayManager; 138 import android.net.Uri; 139 import android.os.Binder; 140 import android.os.Build; 141 import android.os.Bundle; 142 import android.os.Environment; 143 import android.os.Environment.UserEnvironment; 144 import android.os.storage.IMountService; 145 import android.os.storage.StorageManager; 146 import android.os.Debug; 147 import android.os.FileUtils; 148 import android.os.Handler; 149 import android.os.IBinder; 150 import android.os.Looper; 151 import android.os.Message; 152 import android.os.Parcel; 153 import android.os.ParcelFileDescriptor; 154 import android.os.Process; 155 import android.os.RemoteException; 156 import android.os.SELinux; 157 import android.os.ServiceManager; 158 import android.os.SystemClock; 159 import android.os.SystemProperties; 160 import android.os.UserHandle; 161 import android.os.UserManager; 162 import android.security.KeyStore; 163 import android.security.SystemKeyStore; 164 import android.system.ErrnoException; 165 import android.system.Os; 166 import android.system.StructStat; 167 import android.text.TextUtils; 168 import android.text.format.DateUtils; 169 import android.util.ArraySet; 170 import android.util.AtomicFile; 171 import android.util.DisplayMetrics; 172 import android.util.EventLog; 173 import android.util.ExceptionUtils; 174 import android.util.Log; 175 import android.util.LogPrinter; 176 import android.util.PrintStreamPrinter; 177 import android.util.Slog; 178 import android.util.SparseArray; 179 import android.util.SparseBooleanArray; 180 import android.view.Display; 181 182 import java.io.BufferedInputStream; 183 import java.io.BufferedOutputStream; 184 import java.io.BufferedReader; 185 import java.io.File; 186 import java.io.FileDescriptor; 187 import java.io.FileInputStream; 188 import java.io.FileNotFoundException; 189 import java.io.FileOutputStream; 190 import java.io.FileReader; 191 import java.io.FilenameFilter; 192 import java.io.IOException; 193 import java.io.InputStream; 194 import java.io.PrintWriter; 195 import java.nio.charset.StandardCharsets; 196 import java.security.NoSuchAlgorithmException; 197 import java.security.PublicKey; 198 import java.security.cert.CertificateEncodingException; 199 import java.security.cert.CertificateException; 200 import java.text.SimpleDateFormat; 201 import java.util.ArrayList; 202 import java.util.Arrays; 203 import java.util.Collection; 204 import java.util.Collections; 205 import java.util.Comparator; 206 import java.util.Date; 207 import java.util.Iterator; 208 import java.util.List; 209 import java.util.Map; 210 import java.util.Objects; 211 import java.util.Set; 212 import java.util.concurrent.atomic.AtomicBoolean; 213 import java.util.concurrent.atomic.AtomicLong; 214 215 import dalvik.system.DexFile; 216 import dalvik.system.StaleDexCacheError; 217 import dalvik.system.VMRuntime; 218 219 import libcore.io.IoUtils; 220 import libcore.util.EmptyArray; 221 222 /** 223 * Keep track of all those .apks everywhere. 224 * 225 * This is very central to the platform's security; please run the unit 226 * tests whenever making modifications here: 227 * 228 mmm frameworks/base/tests/AndroidTests 229 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 230 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 231 * 232 * {@hide} 233 */ 234 public class PackageManagerService extends IPackageManager.Stub { 235 static final String TAG = "PackageManager"; 236 static final boolean DEBUG_SETTINGS = false; 237 static final boolean DEBUG_PREFERRED = false; 238 static final boolean DEBUG_UPGRADE = false; 239 private static final boolean DEBUG_INSTALL = false; 240 private static final boolean DEBUG_REMOVE = false; 241 private static final boolean DEBUG_BROADCASTS = false; 242 private static final boolean DEBUG_SHOW_INFO = false; 243 private static final boolean DEBUG_PACKAGE_INFO = false; 244 private static final boolean DEBUG_INTENT_MATCHING = false; 245 private static final boolean DEBUG_PACKAGE_SCANNING = false; 246 private static final boolean DEBUG_VERIFY = false; 247 private static final boolean DEBUG_DEXOPT = false; 248 private static final boolean DEBUG_ABI_SELECTION = false; 249 250 private static final int RADIO_UID = Process.PHONE_UID; 251 private static final int LOG_UID = Process.LOG_UID; 252 private static final int NFC_UID = Process.NFC_UID; 253 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 254 private static final int SHELL_UID = Process.SHELL_UID; 255 256 // Cap the size of permission trees that 3rd party apps can define 257 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 258 259 // Suffix used during package installation when copying/moving 260 // package apks to install directory. 261 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 262 263 static final int SCAN_NO_DEX = 1<<1; 264 static final int SCAN_FORCE_DEX = 1<<2; 265 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 266 static final int SCAN_NEW_INSTALL = 1<<4; 267 static final int SCAN_NO_PATHS = 1<<5; 268 static final int SCAN_UPDATE_TIME = 1<<6; 269 static final int SCAN_DEFER_DEX = 1<<7; 270 static final int SCAN_BOOTING = 1<<8; 271 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 272 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 273 static final int SCAN_REPLACING = 1<<11; 274 275 static final int REMOVE_CHATTY = 1<<16; 276 277 /** 278 * Timeout (in milliseconds) after which the watchdog should declare that 279 * our handler thread is wedged. The usual default for such things is one 280 * minute but we sometimes do very lengthy I/O operations on this thread, 281 * such as installing multi-gigabyte applications, so ours needs to be longer. 282 */ 283 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 284 285 /** 286 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 287 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 288 * settings entry if available, otherwise we use the hardcoded default. If it's been 289 * more than this long since the last fstrim, we force one during the boot sequence. 290 * 291 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 292 * one gets run at the next available charging+idle time. This final mandatory 293 * no-fstrim check kicks in only of the other scheduling criteria is never met. 294 */ 295 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 296 297 /** 298 * Whether verification is enabled by default. 299 */ 300 private static final boolean DEFAULT_VERIFY_ENABLE = true; 301 302 /** 303 * The default maximum time to wait for the verification agent to return in 304 * milliseconds. 305 */ 306 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 307 308 /** 309 * The default response for package verification timeout. 310 * 311 * This can be either PackageManager.VERIFICATION_ALLOW or 312 * PackageManager.VERIFICATION_REJECT. 313 */ 314 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 315 316 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 317 318 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 319 DEFAULT_CONTAINER_PACKAGE, 320 "com.android.defcontainer.DefaultContainerService"); 321 322 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 323 324 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 325 326 private static String sPreferredInstructionSet; 327 328 final ServiceThread mHandlerThread; 329 330 private static final String IDMAP_PREFIX = "/data/resource-cache/"; 331 private static final String IDMAP_SUFFIX = "@idmap"; 332 333 final PackageHandler mHandler; 334 335 /** 336 * Messages for {@link #mHandler} that need to wait for system ready before 337 * being dispatched. 338 */ 339 private ArrayList<Message> mPostSystemReadyMessages; 340 341 final int mSdkVersion = Build.VERSION.SDK_INT; 342 343 final Context mContext; 344 final boolean mFactoryTest; 345 final boolean mOnlyCore; 346 final boolean mLazyDexOpt; 347 final long mDexOptLRUThresholdInMills; 348 final DisplayMetrics mMetrics; 349 final int mDefParseFlags; 350 final String[] mSeparateProcesses; 351 final boolean mIsUpgrade; 352 353 // This is where all application persistent data goes. 354 final File mAppDataDir; 355 356 // This is where all application persistent data goes for secondary users. 357 final File mUserAppDataDir; 358 359 /** The location for ASEC container files on internal storage. */ 360 final String mAsecInternalPath; 361 362 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 363 // LOCK HELD. Can be called with mInstallLock held. 364 final Installer mInstaller; 365 366 /** Directory where installed third-party apps stored */ 367 final File mAppInstallDir; 368 369 /** 370 * Directory to which applications installed internally have their 371 * 32 bit native libraries copied. 372 */ 373 private File mAppLib32InstallDir; 374 375 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 376 // apps. 377 final File mDrmAppPrivateInstallDir; 378 379 // ---------------------------------------------------------------- 380 381 // Lock for state used when installing and doing other long running 382 // operations. Methods that must be called with this lock held have 383 // the suffix "LI". 384 final Object mInstallLock = new Object(); 385 386 // ---------------------------------------------------------------- 387 388 // Keys are String (package name), values are Package. This also serves 389 // as the lock for the global state. Methods that must be called with 390 // this lock held have the prefix "LP". 391 final ArrayMap<String, PackageParser.Package> mPackages = 392 new ArrayMap<String, PackageParser.Package>(); 393 394 // Tracks available target package names -> overlay package paths. 395 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 396 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 397 398 final Settings mSettings; 399 boolean mRestoredSettings; 400 401 // System configuration read by SystemConfig. 402 final int[] mGlobalGids; 403 final SparseArray<ArraySet<String>> mSystemPermissions; 404 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 405 406 // If mac_permissions.xml was found for seinfo labeling. 407 boolean mFoundPolicyFile; 408 409 // If a recursive restorecon of /data/data/<pkg> is needed. 410 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 411 412 public static final class SharedLibraryEntry { 413 public final String path; 414 public final String apk; 415 SharedLibraryEntry(String _path, String _apk)416 SharedLibraryEntry(String _path, String _apk) { 417 path = _path; 418 apk = _apk; 419 } 420 } 421 422 // Currently known shared libraries. 423 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 424 new ArrayMap<String, SharedLibraryEntry>(); 425 426 // All available activities, for your resolving pleasure. 427 final ActivityIntentResolver mActivities = 428 new ActivityIntentResolver(); 429 430 // All available receivers, for your resolving pleasure. 431 final ActivityIntentResolver mReceivers = 432 new ActivityIntentResolver(); 433 434 // All available services, for your resolving pleasure. 435 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 436 437 // All available providers, for your resolving pleasure. 438 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 439 440 // Mapping from provider base names (first directory in content URI codePath) 441 // to the provider information. 442 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 443 new ArrayMap<String, PackageParser.Provider>(); 444 445 // Mapping from instrumentation class names to info about them. 446 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 447 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 448 449 // Mapping from permission names to info about them. 450 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 451 new ArrayMap<String, PackageParser.PermissionGroup>(); 452 453 // Packages whose data we have transfered into another package, thus 454 // should no longer exist. 455 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 456 457 // Broadcast actions that are only available to the system. 458 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 459 460 /** List of packages waiting for verification. */ 461 final SparseArray<PackageVerificationState> mPendingVerification 462 = new SparseArray<PackageVerificationState>(); 463 464 /** Set of packages associated with each app op permission. */ 465 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 466 467 final PackageInstallerService mInstallerService; 468 469 ArraySet<PackageParser.Package> mDeferredDexOpt = null; 470 471 // Cache of users who need badging. 472 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 473 474 /** Token for keys in mPendingVerification. */ 475 private int mPendingVerificationToken = 0; 476 477 volatile boolean mSystemReady; 478 volatile boolean mSafeMode; 479 volatile boolean mHasSystemUidErrors; 480 481 ApplicationInfo mAndroidApplication; 482 final ActivityInfo mResolveActivity = new ActivityInfo(); 483 final ResolveInfo mResolveInfo = new ResolveInfo(); 484 ComponentName mResolveComponentName; 485 PackageParser.Package mPlatformPackage; 486 ComponentName mCustomResolverComponentName; 487 488 boolean mResolverReplaced = false; 489 490 // Set of pending broadcasts for aggregating enable/disable of components. 491 static class PendingPackageBroadcasts { 492 // for each user id, a map of <package name -> components within that package> 493 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 494 PendingPackageBroadcasts()495 public PendingPackageBroadcasts() { 496 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 497 } 498 get(int userId, String packageName)499 public ArrayList<String> get(int userId, String packageName) { 500 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 501 return packages.get(packageName); 502 } 503 put(int userId, String packageName, ArrayList<String> components)504 public void put(int userId, String packageName, ArrayList<String> components) { 505 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 506 packages.put(packageName, components); 507 } 508 remove(int userId, String packageName)509 public void remove(int userId, String packageName) { 510 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 511 if (packages != null) { 512 packages.remove(packageName); 513 } 514 } 515 remove(int userId)516 public void remove(int userId) { 517 mUidMap.remove(userId); 518 } 519 userIdCount()520 public int userIdCount() { 521 return mUidMap.size(); 522 } 523 userIdAt(int n)524 public int userIdAt(int n) { 525 return mUidMap.keyAt(n); 526 } 527 packagesForUserId(int userId)528 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 529 return mUidMap.get(userId); 530 } 531 size()532 public int size() { 533 // total number of pending broadcast entries across all userIds 534 int num = 0; 535 for (int i = 0; i< mUidMap.size(); i++) { 536 num += mUidMap.valueAt(i).size(); 537 } 538 return num; 539 } 540 clear()541 public void clear() { 542 mUidMap.clear(); 543 } 544 getOrAllocate(int userId)545 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 546 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 547 if (map == null) { 548 map = new ArrayMap<String, ArrayList<String>>(); 549 mUidMap.put(userId, map); 550 } 551 return map; 552 } 553 } 554 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 555 556 // Service Connection to remote media container service to copy 557 // package uri's from external media onto secure containers 558 // or internal storage. 559 private IMediaContainerService mContainerService = null; 560 561 static final int SEND_PENDING_BROADCAST = 1; 562 static final int MCS_BOUND = 3; 563 static final int END_COPY = 4; 564 static final int INIT_COPY = 5; 565 static final int MCS_UNBIND = 6; 566 static final int START_CLEANING_PACKAGE = 7; 567 static final int FIND_INSTALL_LOC = 8; 568 static final int POST_INSTALL = 9; 569 static final int MCS_RECONNECT = 10; 570 static final int MCS_GIVE_UP = 11; 571 static final int UPDATED_MEDIA_STATUS = 12; 572 static final int WRITE_SETTINGS = 13; 573 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 574 static final int PACKAGE_VERIFIED = 15; 575 static final int CHECK_PENDING_VERIFICATION = 16; 576 577 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 578 579 // Delay time in millisecs 580 static final int BROADCAST_DELAY = 10 * 1000; 581 582 static UserManagerService sUserManager; 583 584 // Stores a list of users whose package restrictions file needs to be updated 585 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 586 587 final private DefaultContainerConnection mDefContainerConn = 588 new DefaultContainerConnection(); 589 class DefaultContainerConnection implements ServiceConnection { onServiceConnected(ComponentName name, IBinder service)590 public void onServiceConnected(ComponentName name, IBinder service) { 591 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 592 IMediaContainerService imcs = 593 IMediaContainerService.Stub.asInterface(service); 594 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 595 } 596 onServiceDisconnected(ComponentName name)597 public void onServiceDisconnected(ComponentName name) { 598 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 599 } 600 }; 601 602 // Recordkeeping of restore-after-install operations that are currently in flight 603 // between the Package Manager and the Backup Manager 604 class PostInstallData { 605 public InstallArgs args; 606 public PackageInstalledInfo res; 607 PostInstallData(InstallArgs _a, PackageInstalledInfo _r)608 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 609 args = _a; 610 res = _r; 611 } 612 }; 613 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 614 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 615 616 private final String mRequiredVerifierPackage; 617 618 private final PackageUsage mPackageUsage = new PackageUsage(); 619 620 private class PackageUsage { 621 private static final int WRITE_INTERVAL 622 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 623 624 private final Object mFileLock = new Object(); 625 private final AtomicLong mLastWritten = new AtomicLong(0); 626 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 627 628 private boolean mIsHistoricalPackageUsageAvailable = true; 629 isHistoricalPackageUsageAvailable()630 boolean isHistoricalPackageUsageAvailable() { 631 return mIsHistoricalPackageUsageAvailable; 632 } 633 write(boolean force)634 void write(boolean force) { 635 if (force) { 636 writeInternal(); 637 return; 638 } 639 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 640 && !DEBUG_DEXOPT) { 641 return; 642 } 643 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 644 new Thread("PackageUsage_DiskWriter") { 645 @Override 646 public void run() { 647 try { 648 writeInternal(); 649 } finally { 650 mBackgroundWriteRunning.set(false); 651 } 652 } 653 }.start(); 654 } 655 } 656 writeInternal()657 private void writeInternal() { 658 synchronized (mPackages) { 659 synchronized (mFileLock) { 660 AtomicFile file = getFile(); 661 FileOutputStream f = null; 662 try { 663 f = file.startWrite(); 664 BufferedOutputStream out = new BufferedOutputStream(f); 665 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 666 StringBuilder sb = new StringBuilder(); 667 for (PackageParser.Package pkg : mPackages.values()) { 668 if (pkg.mLastPackageUsageTimeInMills == 0) { 669 continue; 670 } 671 sb.setLength(0); 672 sb.append(pkg.packageName); 673 sb.append(' '); 674 sb.append((long)pkg.mLastPackageUsageTimeInMills); 675 sb.append('\n'); 676 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 677 } 678 out.flush(); 679 file.finishWrite(f); 680 } catch (IOException e) { 681 if (f != null) { 682 file.failWrite(f); 683 } 684 Log.e(TAG, "Failed to write package usage times", e); 685 } 686 } 687 } 688 mLastWritten.set(SystemClock.elapsedRealtime()); 689 } 690 readLP()691 void readLP() { 692 synchronized (mFileLock) { 693 AtomicFile file = getFile(); 694 BufferedInputStream in = null; 695 try { 696 in = new BufferedInputStream(file.openRead()); 697 StringBuffer sb = new StringBuffer(); 698 while (true) { 699 String packageName = readToken(in, sb, ' '); 700 if (packageName == null) { 701 break; 702 } 703 String timeInMillisString = readToken(in, sb, '\n'); 704 if (timeInMillisString == null) { 705 throw new IOException("Failed to find last usage time for package " 706 + packageName); 707 } 708 PackageParser.Package pkg = mPackages.get(packageName); 709 if (pkg == null) { 710 continue; 711 } 712 long timeInMillis; 713 try { 714 timeInMillis = Long.parseLong(timeInMillisString.toString()); 715 } catch (NumberFormatException e) { 716 throw new IOException("Failed to parse " + timeInMillisString 717 + " as a long.", e); 718 } 719 pkg.mLastPackageUsageTimeInMills = timeInMillis; 720 } 721 } catch (FileNotFoundException expected) { 722 mIsHistoricalPackageUsageAvailable = false; 723 } catch (IOException e) { 724 Log.w(TAG, "Failed to read package usage times", e); 725 } finally { 726 IoUtils.closeQuietly(in); 727 } 728 } 729 mLastWritten.set(SystemClock.elapsedRealtime()); 730 } 731 readToken(InputStream in, StringBuffer sb, char endOfToken)732 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 733 throws IOException { 734 sb.setLength(0); 735 while (true) { 736 int ch = in.read(); 737 if (ch == -1) { 738 if (sb.length() == 0) { 739 return null; 740 } 741 throw new IOException("Unexpected EOF"); 742 } 743 if (ch == endOfToken) { 744 return sb.toString(); 745 } 746 sb.append((char)ch); 747 } 748 } 749 getFile()750 private AtomicFile getFile() { 751 File dataDir = Environment.getDataDirectory(); 752 File systemDir = new File(dataDir, "system"); 753 File fname = new File(systemDir, "package-usage.list"); 754 return new AtomicFile(fname); 755 } 756 } 757 758 class PackageHandler extends Handler { 759 private boolean mBound = false; 760 final ArrayList<HandlerParams> mPendingInstalls = 761 new ArrayList<HandlerParams>(); 762 connectToService()763 private boolean connectToService() { 764 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 765 " DefaultContainerService"); 766 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 767 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 768 if (mContext.bindServiceAsUser(service, mDefContainerConn, 769 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 770 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 771 mBound = true; 772 return true; 773 } 774 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 775 return false; 776 } 777 disconnectService()778 private void disconnectService() { 779 mContainerService = null; 780 mBound = false; 781 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 782 mContext.unbindService(mDefContainerConn); 783 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 784 } 785 PackageHandler(Looper looper)786 PackageHandler(Looper looper) { 787 super(looper); 788 } 789 handleMessage(Message msg)790 public void handleMessage(Message msg) { 791 try { 792 doHandleMessage(msg); 793 } finally { 794 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 795 } 796 } 797 doHandleMessage(Message msg)798 void doHandleMessage(Message msg) { 799 switch (msg.what) { 800 case INIT_COPY: { 801 HandlerParams params = (HandlerParams) msg.obj; 802 int idx = mPendingInstalls.size(); 803 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 804 // If a bind was already initiated we dont really 805 // need to do anything. The pending install 806 // will be processed later on. 807 if (!mBound) { 808 // If this is the only one pending we might 809 // have to bind to the service again. 810 if (!connectToService()) { 811 Slog.e(TAG, "Failed to bind to media container service"); 812 params.serviceError(); 813 return; 814 } else { 815 // Once we bind to the service, the first 816 // pending request will be processed. 817 mPendingInstalls.add(idx, params); 818 } 819 } else { 820 mPendingInstalls.add(idx, params); 821 // Already bound to the service. Just make 822 // sure we trigger off processing the first request. 823 if (idx == 0) { 824 mHandler.sendEmptyMessage(MCS_BOUND); 825 } 826 } 827 break; 828 } 829 case MCS_BOUND: { 830 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 831 if (msg.obj != null) { 832 mContainerService = (IMediaContainerService) msg.obj; 833 } 834 if (mContainerService == null) { 835 // Something seriously wrong. Bail out 836 Slog.e(TAG, "Cannot bind to media container service"); 837 for (HandlerParams params : mPendingInstalls) { 838 // Indicate service bind error 839 params.serviceError(); 840 } 841 mPendingInstalls.clear(); 842 } else if (mPendingInstalls.size() > 0) { 843 HandlerParams params = mPendingInstalls.get(0); 844 if (params != null) { 845 if (params.startCopy()) { 846 // We are done... look for more work or to 847 // go idle. 848 if (DEBUG_SD_INSTALL) Log.i(TAG, 849 "Checking for more work or unbind..."); 850 // Delete pending install 851 if (mPendingInstalls.size() > 0) { 852 mPendingInstalls.remove(0); 853 } 854 if (mPendingInstalls.size() == 0) { 855 if (mBound) { 856 if (DEBUG_SD_INSTALL) Log.i(TAG, 857 "Posting delayed MCS_UNBIND"); 858 removeMessages(MCS_UNBIND); 859 Message ubmsg = obtainMessage(MCS_UNBIND); 860 // Unbind after a little delay, to avoid 861 // continual thrashing. 862 sendMessageDelayed(ubmsg, 10000); 863 } 864 } else { 865 // There are more pending requests in queue. 866 // Just post MCS_BOUND message to trigger processing 867 // of next pending install. 868 if (DEBUG_SD_INSTALL) Log.i(TAG, 869 "Posting MCS_BOUND for next work"); 870 mHandler.sendEmptyMessage(MCS_BOUND); 871 } 872 } 873 } 874 } else { 875 // Should never happen ideally. 876 Slog.w(TAG, "Empty queue"); 877 } 878 break; 879 } 880 case MCS_RECONNECT: { 881 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 882 if (mPendingInstalls.size() > 0) { 883 if (mBound) { 884 disconnectService(); 885 } 886 if (!connectToService()) { 887 Slog.e(TAG, "Failed to bind to media container service"); 888 for (HandlerParams params : mPendingInstalls) { 889 // Indicate service bind error 890 params.serviceError(); 891 } 892 mPendingInstalls.clear(); 893 } 894 } 895 break; 896 } 897 case MCS_UNBIND: { 898 // If there is no actual work left, then time to unbind. 899 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 900 901 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 902 if (mBound) { 903 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 904 905 disconnectService(); 906 } 907 } else if (mPendingInstalls.size() > 0) { 908 // There are more pending requests in queue. 909 // Just post MCS_BOUND message to trigger processing 910 // of next pending install. 911 mHandler.sendEmptyMessage(MCS_BOUND); 912 } 913 914 break; 915 } 916 case MCS_GIVE_UP: { 917 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 918 mPendingInstalls.remove(0); 919 break; 920 } 921 case SEND_PENDING_BROADCAST: { 922 String packages[]; 923 ArrayList<String> components[]; 924 int size = 0; 925 int uids[]; 926 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 927 synchronized (mPackages) { 928 if (mPendingBroadcasts == null) { 929 return; 930 } 931 size = mPendingBroadcasts.size(); 932 if (size <= 0) { 933 // Nothing to be done. Just return 934 return; 935 } 936 packages = new String[size]; 937 components = new ArrayList[size]; 938 uids = new int[size]; 939 int i = 0; // filling out the above arrays 940 941 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 942 int packageUserId = mPendingBroadcasts.userIdAt(n); 943 Iterator<Map.Entry<String, ArrayList<String>>> it 944 = mPendingBroadcasts.packagesForUserId(packageUserId) 945 .entrySet().iterator(); 946 while (it.hasNext() && i < size) { 947 Map.Entry<String, ArrayList<String>> ent = it.next(); 948 packages[i] = ent.getKey(); 949 components[i] = ent.getValue(); 950 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 951 uids[i] = (ps != null) 952 ? UserHandle.getUid(packageUserId, ps.appId) 953 : -1; 954 i++; 955 } 956 } 957 size = i; 958 mPendingBroadcasts.clear(); 959 } 960 // Send broadcasts 961 for (int i = 0; i < size; i++) { 962 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 963 } 964 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 965 break; 966 } 967 case START_CLEANING_PACKAGE: { 968 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 969 final String packageName = (String)msg.obj; 970 final int userId = msg.arg1; 971 final boolean andCode = msg.arg2 != 0; 972 synchronized (mPackages) { 973 if (userId == UserHandle.USER_ALL) { 974 int[] users = sUserManager.getUserIds(); 975 for (int user : users) { 976 mSettings.addPackageToCleanLPw( 977 new PackageCleanItem(user, packageName, andCode)); 978 } 979 } else { 980 mSettings.addPackageToCleanLPw( 981 new PackageCleanItem(userId, packageName, andCode)); 982 } 983 } 984 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 985 startCleaningPackages(); 986 } break; 987 case POST_INSTALL: { 988 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 989 PostInstallData data = mRunningInstalls.get(msg.arg1); 990 mRunningInstalls.delete(msg.arg1); 991 boolean deleteOld = false; 992 993 if (data != null) { 994 InstallArgs args = data.args; 995 PackageInstalledInfo res = data.res; 996 997 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 998 res.removedInfo.sendBroadcast(false, true, false); 999 Bundle extras = new Bundle(1); 1000 extras.putInt(Intent.EXTRA_UID, res.uid); 1001 // Determine the set of users who are adding this 1002 // package for the first time vs. those who are seeing 1003 // an update. 1004 int[] firstUsers; 1005 int[] updateUsers = new int[0]; 1006 if (res.origUsers == null || res.origUsers.length == 0) { 1007 firstUsers = res.newUsers; 1008 } else { 1009 firstUsers = new int[0]; 1010 for (int i=0; i<res.newUsers.length; i++) { 1011 int user = res.newUsers[i]; 1012 boolean isNew = true; 1013 for (int j=0; j<res.origUsers.length; j++) { 1014 if (res.origUsers[j] == user) { 1015 isNew = false; 1016 break; 1017 } 1018 } 1019 if (isNew) { 1020 int[] newFirst = new int[firstUsers.length+1]; 1021 System.arraycopy(firstUsers, 0, newFirst, 0, 1022 firstUsers.length); 1023 newFirst[firstUsers.length] = user; 1024 firstUsers = newFirst; 1025 } else { 1026 int[] newUpdate = new int[updateUsers.length+1]; 1027 System.arraycopy(updateUsers, 0, newUpdate, 0, 1028 updateUsers.length); 1029 newUpdate[updateUsers.length] = user; 1030 updateUsers = newUpdate; 1031 } 1032 } 1033 } 1034 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1035 res.pkg.applicationInfo.packageName, 1036 extras, null, null, firstUsers); 1037 final boolean update = res.removedInfo.removedPackage != null; 1038 if (update) { 1039 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1040 } 1041 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1042 res.pkg.applicationInfo.packageName, 1043 extras, null, null, updateUsers); 1044 if (update) { 1045 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1046 res.pkg.applicationInfo.packageName, 1047 extras, null, null, updateUsers); 1048 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1049 null, null, 1050 res.pkg.applicationInfo.packageName, null, updateUsers); 1051 1052 // treat asec-hosted packages like removable media on upgrade 1053 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) { 1054 if (DEBUG_INSTALL) { 1055 Slog.i(TAG, "upgrading pkg " + res.pkg 1056 + " is ASEC-hosted -> AVAILABLE"); 1057 } 1058 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1059 ArrayList<String> pkgList = new ArrayList<String>(1); 1060 pkgList.add(res.pkg.applicationInfo.packageName); 1061 sendResourcesChangedBroadcast(true, true, 1062 pkgList,uidArray, null); 1063 } 1064 } 1065 if (res.removedInfo.args != null) { 1066 // Remove the replaced package's older resources safely now 1067 deleteOld = true; 1068 } 1069 1070 // Log current value of "unknown sources" setting 1071 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1072 getUnknownSourcesSettings()); 1073 } 1074 // Force a gc to clear up things 1075 Runtime.getRuntime().gc(); 1076 // We delete after a gc for applications on sdcard. 1077 if (deleteOld) { 1078 synchronized (mInstallLock) { 1079 res.removedInfo.args.doPostDeleteLI(true); 1080 } 1081 } 1082 if (args.observer != null) { 1083 try { 1084 Bundle extras = extrasForInstallResult(res); 1085 args.observer.onPackageInstalled(res.name, res.returnCode, 1086 res.returnMsg, extras); 1087 } catch (RemoteException e) { 1088 Slog.i(TAG, "Observer no longer exists."); 1089 } 1090 } 1091 } else { 1092 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1093 } 1094 } break; 1095 case UPDATED_MEDIA_STATUS: { 1096 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1097 boolean reportStatus = msg.arg1 == 1; 1098 boolean doGc = msg.arg2 == 1; 1099 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1100 if (doGc) { 1101 // Force a gc to clear up stale containers. 1102 Runtime.getRuntime().gc(); 1103 } 1104 if (msg.obj != null) { 1105 @SuppressWarnings("unchecked") 1106 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1107 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1108 // Unload containers 1109 unloadAllContainers(args); 1110 } 1111 if (reportStatus) { 1112 try { 1113 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1114 PackageHelper.getMountService().finishMediaUpdate(); 1115 } catch (RemoteException e) { 1116 Log.e(TAG, "MountService not running?"); 1117 } 1118 } 1119 } break; 1120 case WRITE_SETTINGS: { 1121 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1122 synchronized (mPackages) { 1123 removeMessages(WRITE_SETTINGS); 1124 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1125 mSettings.writeLPr(); 1126 mDirtyUsers.clear(); 1127 } 1128 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1129 } break; 1130 case WRITE_PACKAGE_RESTRICTIONS: { 1131 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1132 synchronized (mPackages) { 1133 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1134 for (int userId : mDirtyUsers) { 1135 mSettings.writePackageRestrictionsLPr(userId); 1136 } 1137 mDirtyUsers.clear(); 1138 } 1139 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1140 } break; 1141 case CHECK_PENDING_VERIFICATION: { 1142 final int verificationId = msg.arg1; 1143 final PackageVerificationState state = mPendingVerification.get(verificationId); 1144 1145 if ((state != null) && !state.timeoutExtended()) { 1146 final InstallArgs args = state.getInstallArgs(); 1147 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1148 1149 Slog.i(TAG, "Verification timed out for " + originUri); 1150 mPendingVerification.remove(verificationId); 1151 1152 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1153 1154 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1155 Slog.i(TAG, "Continuing with installation of " + originUri); 1156 state.setVerifierResponse(Binder.getCallingUid(), 1157 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1158 broadcastPackageVerified(verificationId, originUri, 1159 PackageManager.VERIFICATION_ALLOW, 1160 state.getInstallArgs().getUser()); 1161 try { 1162 ret = args.copyApk(mContainerService, true); 1163 } catch (RemoteException e) { 1164 Slog.e(TAG, "Could not contact the ContainerService"); 1165 } 1166 } else { 1167 broadcastPackageVerified(verificationId, originUri, 1168 PackageManager.VERIFICATION_REJECT, 1169 state.getInstallArgs().getUser()); 1170 } 1171 1172 processPendingInstall(args, ret); 1173 mHandler.sendEmptyMessage(MCS_UNBIND); 1174 } 1175 break; 1176 } 1177 case PACKAGE_VERIFIED: { 1178 final int verificationId = msg.arg1; 1179 1180 final PackageVerificationState state = mPendingVerification.get(verificationId); 1181 if (state == null) { 1182 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1183 break; 1184 } 1185 1186 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1187 1188 state.setVerifierResponse(response.callerUid, response.code); 1189 1190 if (state.isVerificationComplete()) { 1191 mPendingVerification.remove(verificationId); 1192 1193 final InstallArgs args = state.getInstallArgs(); 1194 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1195 1196 int ret; 1197 if (state.isInstallAllowed()) { 1198 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1199 broadcastPackageVerified(verificationId, originUri, 1200 response.code, state.getInstallArgs().getUser()); 1201 try { 1202 ret = args.copyApk(mContainerService, true); 1203 } catch (RemoteException e) { 1204 Slog.e(TAG, "Could not contact the ContainerService"); 1205 } 1206 } else { 1207 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1208 } 1209 1210 processPendingInstall(args, ret); 1211 1212 mHandler.sendEmptyMessage(MCS_UNBIND); 1213 } 1214 1215 break; 1216 } 1217 } 1218 } 1219 } 1220 extrasForInstallResult(PackageInstalledInfo res)1221 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1222 Bundle extras = null; 1223 switch (res.returnCode) { 1224 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1225 extras = new Bundle(); 1226 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1227 res.origPermission); 1228 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1229 res.origPackage); 1230 break; 1231 } 1232 } 1233 return extras; 1234 } 1235 scheduleWriteSettingsLocked()1236 void scheduleWriteSettingsLocked() { 1237 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1238 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1239 } 1240 } 1241 scheduleWritePackageRestrictionsLocked(int userId)1242 void scheduleWritePackageRestrictionsLocked(int userId) { 1243 if (!sUserManager.exists(userId)) return; 1244 mDirtyUsers.add(userId); 1245 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1246 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1247 } 1248 } 1249 main(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1250 public static final PackageManagerService main(Context context, Installer installer, 1251 boolean factoryTest, boolean onlyCore) { 1252 PackageManagerService m = new PackageManagerService(context, installer, 1253 factoryTest, onlyCore); 1254 ServiceManager.addService("package", m); 1255 return m; 1256 } 1257 splitString(String str, char sep)1258 static String[] splitString(String str, char sep) { 1259 int count = 1; 1260 int i = 0; 1261 while ((i=str.indexOf(sep, i)) >= 0) { 1262 count++; 1263 i++; 1264 } 1265 1266 String[] res = new String[count]; 1267 i=0; 1268 count = 0; 1269 int lastI=0; 1270 while ((i=str.indexOf(sep, i)) >= 0) { 1271 res[count] = str.substring(lastI, i); 1272 count++; 1273 i++; 1274 lastI = i; 1275 } 1276 res[count] = str.substring(lastI, str.length()); 1277 return res; 1278 } 1279 getDefaultDisplayMetrics(Context context, DisplayMetrics metrics)1280 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1281 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1282 Context.DISPLAY_SERVICE); 1283 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1284 } 1285 PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1286 public PackageManagerService(Context context, Installer installer, 1287 boolean factoryTest, boolean onlyCore) { 1288 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1289 SystemClock.uptimeMillis()); 1290 1291 if (mSdkVersion <= 0) { 1292 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1293 } 1294 1295 mContext = context; 1296 mFactoryTest = factoryTest; 1297 mOnlyCore = onlyCore; 1298 mLazyDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1299 mMetrics = new DisplayMetrics(); 1300 mSettings = new Settings(context); 1301 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1302 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1303 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1304 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1305 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1306 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1307 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1308 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1309 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1310 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1311 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1312 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1313 1314 // TODO: add a property to control this? 1315 long dexOptLRUThresholdInMinutes; 1316 if (mLazyDexOpt) { 1317 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 1318 } else { 1319 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 1320 } 1321 mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 1322 1323 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1324 if (separateProcesses != null && separateProcesses.length() > 0) { 1325 if ("*".equals(separateProcesses)) { 1326 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1327 mSeparateProcesses = null; 1328 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1329 } else { 1330 mDefParseFlags = 0; 1331 mSeparateProcesses = separateProcesses.split(","); 1332 Slog.w(TAG, "Running with debug.separate_processes: " 1333 + separateProcesses); 1334 } 1335 } else { 1336 mDefParseFlags = 0; 1337 mSeparateProcesses = null; 1338 } 1339 1340 mInstaller = installer; 1341 1342 getDefaultDisplayMetrics(context, mMetrics); 1343 1344 SystemConfig systemConfig = SystemConfig.getInstance(); 1345 mGlobalGids = systemConfig.getGlobalGids(); 1346 mSystemPermissions = systemConfig.getSystemPermissions(); 1347 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1348 1349 synchronized (mInstallLock) { 1350 // writer 1351 synchronized (mPackages) { 1352 mHandlerThread = new ServiceThread(TAG, 1353 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1354 mHandlerThread.start(); 1355 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1356 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1357 1358 File dataDir = Environment.getDataDirectory(); 1359 mAppDataDir = new File(dataDir, "data"); 1360 mAppInstallDir = new File(dataDir, "app"); 1361 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1362 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1363 mUserAppDataDir = new File(dataDir, "user"); 1364 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1365 1366 sUserManager = new UserManagerService(context, this, 1367 mInstallLock, mPackages); 1368 1369 // Propagate permission configuration in to package manager. 1370 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1371 = systemConfig.getPermissions(); 1372 for (int i=0; i<permConfig.size(); i++) { 1373 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1374 BasePermission bp = mSettings.mPermissions.get(perm.name); 1375 if (bp == null) { 1376 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1377 mSettings.mPermissions.put(perm.name, bp); 1378 } 1379 if (perm.gids != null) { 1380 bp.gids = appendInts(bp.gids, perm.gids); 1381 } 1382 } 1383 1384 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1385 for (int i=0; i<libConfig.size(); i++) { 1386 mSharedLibraries.put(libConfig.keyAt(i), 1387 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1388 } 1389 1390 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1391 1392 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1393 mSdkVersion, mOnlyCore); 1394 1395 String customResolverActivity = Resources.getSystem().getString( 1396 R.string.config_customResolverActivity); 1397 if (TextUtils.isEmpty(customResolverActivity)) { 1398 customResolverActivity = null; 1399 } else { 1400 mCustomResolverComponentName = ComponentName.unflattenFromString( 1401 customResolverActivity); 1402 } 1403 1404 long startTime = SystemClock.uptimeMillis(); 1405 1406 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1407 startTime); 1408 1409 // Set flag to monitor and not change apk file paths when 1410 // scanning install directories. 1411 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; 1412 1413 final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); 1414 1415 /** 1416 * Add everything in the in the boot class path to the 1417 * list of process files because dexopt will have been run 1418 * if necessary during zygote startup. 1419 */ 1420 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 1421 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 1422 1423 if (bootClassPath != null) { 1424 String[] bootClassPathElements = splitString(bootClassPath, ':'); 1425 for (String element : bootClassPathElements) { 1426 alreadyDexOpted.add(element); 1427 } 1428 } else { 1429 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1430 } 1431 1432 if (systemServerClassPath != null) { 1433 String[] systemServerClassPathElements = splitString(systemServerClassPath, ':'); 1434 for (String element : systemServerClassPathElements) { 1435 alreadyDexOpted.add(element); 1436 } 1437 } else { 1438 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 1439 } 1440 1441 final List<String> allInstructionSets = getAllInstructionSets(); 1442 final String[] dexCodeInstructionSets = 1443 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()])); 1444 1445 /** 1446 * Ensure all external libraries have had dexopt run on them. 1447 */ 1448 if (mSharedLibraries.size() > 0) { 1449 // NOTE: For now, we're compiling these system "shared libraries" 1450 // (and framework jars) into all available architectures. It's possible 1451 // to compile them only when we come across an app that uses them (there's 1452 // already logic for that in scanPackageLI) but that adds some complexity. 1453 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1454 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1455 final String lib = libEntry.path; 1456 if (lib == null) { 1457 continue; 1458 } 1459 1460 try { 1461 byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null, 1462 dexCodeInstructionSet, 1463 false); 1464 if (dexoptRequired != DexFile.UP_TO_DATE) { 1465 alreadyDexOpted.add(lib); 1466 1467 // The list of "shared libraries" we have at this point is 1468 if (dexoptRequired == DexFile.DEXOPT_NEEDED) { 1469 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1470 } else { 1471 mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1472 } 1473 } 1474 } catch (FileNotFoundException e) { 1475 Slog.w(TAG, "Library not found: " + lib); 1476 } catch (IOException e) { 1477 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1478 + e.getMessage()); 1479 } 1480 } 1481 } 1482 } 1483 1484 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1485 1486 // Gross hack for now: we know this file doesn't contain any 1487 // code, so don't dexopt it to avoid the resulting log spew. 1488 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 1489 1490 // Gross hack for now: we know this file is only part of 1491 // the boot class path for art, so don't dexopt it to 1492 // avoid the resulting log spew. 1493 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 1494 1495 /** 1496 * And there are a number of commands implemented in Java, which 1497 * we currently need to do the dexopt on so that they can be 1498 * run from a non-root shell. 1499 */ 1500 String[] frameworkFiles = frameworkDir.list(); 1501 if (frameworkFiles != null) { 1502 // TODO: We could compile these only for the most preferred ABI. We should 1503 // first double check that the dex files for these commands are not referenced 1504 // by other system apps. 1505 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1506 for (int i=0; i<frameworkFiles.length; i++) { 1507 File libPath = new File(frameworkDir, frameworkFiles[i]); 1508 String path = libPath.getPath(); 1509 // Skip the file if we already did it. 1510 if (alreadyDexOpted.contains(path)) { 1511 continue; 1512 } 1513 // Skip the file if it is not a type we want to dexopt. 1514 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 1515 continue; 1516 } 1517 try { 1518 byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null, 1519 dexCodeInstructionSet, 1520 false); 1521 if (dexoptRequired == DexFile.DEXOPT_NEEDED) { 1522 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1523 } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) { 1524 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1525 } 1526 } catch (FileNotFoundException e) { 1527 Slog.w(TAG, "Jar not found: " + path); 1528 } catch (IOException e) { 1529 Slog.w(TAG, "Exception reading jar: " + path, e); 1530 } 1531 } 1532 } 1533 } 1534 1535 // Collect vendor overlay packages. 1536 // (Do this before scanning any apps.) 1537 // For security and version matching reason, only consider 1538 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 1539 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 1540 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 1541 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 1542 1543 // Find base frameworks (resource packages without code). 1544 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 1545 | PackageParser.PARSE_IS_SYSTEM_DIR 1546 | PackageParser.PARSE_IS_PRIVILEGED, 1547 scanFlags | SCAN_NO_DEX, 0); 1548 1549 // Collected privileged system packages. 1550 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 1551 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 1552 | PackageParser.PARSE_IS_SYSTEM_DIR 1553 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 1554 1555 // Collect ordinary system packages. 1556 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 1557 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 1558 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1559 1560 // Collect all vendor packages. 1561 File vendorAppDir = new File("/vendor/app"); 1562 try { 1563 vendorAppDir = vendorAppDir.getCanonicalFile(); 1564 } catch (IOException e) { 1565 // failed to look up canonical path, continue with original one 1566 } 1567 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 1568 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1569 1570 // Collect all OEM packages. 1571 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 1572 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 1573 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 1574 1575 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 1576 mInstaller.moveFiles(); 1577 1578 // Prune any system packages that no longer exist. 1579 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 1580 final ArrayMap<String, File> expectingBetter = new ArrayMap<>(); 1581 if (!mOnlyCore) { 1582 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 1583 while (psit.hasNext()) { 1584 PackageSetting ps = psit.next(); 1585 1586 /* 1587 * If this is not a system app, it can't be a 1588 * disable system app. 1589 */ 1590 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1591 continue; 1592 } 1593 1594 /* 1595 * If the package is scanned, it's not erased. 1596 */ 1597 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 1598 if (scannedPkg != null) { 1599 /* 1600 * If the system app is both scanned and in the 1601 * disabled packages list, then it must have been 1602 * added via OTA. Remove it from the currently 1603 * scanned package so the previously user-installed 1604 * application can be scanned. 1605 */ 1606 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 1607 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 1608 + ps.name + "; removing system app. Last known codePath=" 1609 + ps.codePathString + ", installStatus=" + ps.installStatus 1610 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 1611 + scannedPkg.mVersionCode); 1612 removePackageLI(ps, true); 1613 expectingBetter.put(ps.name, ps.codePath); 1614 } 1615 1616 continue; 1617 } 1618 1619 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 1620 psit.remove(); 1621 logCriticalInfo(Log.WARN, "System package " + ps.name 1622 + " no longer exists; wiping its data"); 1623 removeDataDirsLI(ps.name); 1624 } else { 1625 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 1626 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 1627 possiblyDeletedUpdatedSystemApps.add(ps.name); 1628 } 1629 } 1630 } 1631 } 1632 1633 //look for any incomplete package installations 1634 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 1635 //clean up list 1636 for(int i = 0; i < deletePkgsList.size(); i++) { 1637 //clean up here 1638 cleanupInstallFailedPackage(deletePkgsList.get(i)); 1639 } 1640 //delete tmp files 1641 deleteTempPackageFiles(); 1642 1643 // Remove any shared userIDs that have no associated packages 1644 mSettings.pruneSharedUsersLPw(); 1645 1646 if (!mOnlyCore) { 1647 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 1648 SystemClock.uptimeMillis()); 1649 scanDirLI(mAppInstallDir, 0, scanFlags, 0); 1650 1651 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 1652 scanFlags, 0); 1653 1654 /** 1655 * Remove disable package settings for any updated system 1656 * apps that were removed via an OTA. If they're not a 1657 * previously-updated app, remove them completely. 1658 * Otherwise, just revoke their system-level permissions. 1659 */ 1660 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 1661 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 1662 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 1663 1664 String msg; 1665 if (deletedPkg == null) { 1666 msg = "Updated system package " + deletedAppName 1667 + " no longer exists; wiping its data"; 1668 removeDataDirsLI(deletedAppName); 1669 } else { 1670 msg = "Updated system app + " + deletedAppName 1671 + " no longer present; removing system privileges for " 1672 + deletedAppName; 1673 1674 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 1675 1676 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 1677 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 1678 } 1679 logCriticalInfo(Log.WARN, msg); 1680 } 1681 1682 /** 1683 * Make sure all system apps that we expected to appear on 1684 * the userdata partition actually showed up. If they never 1685 * appeared, crawl back and revive the system version. 1686 */ 1687 for (int i = 0; i < expectingBetter.size(); i++) { 1688 final String packageName = expectingBetter.keyAt(i); 1689 if (!mPackages.containsKey(packageName)) { 1690 final File scanFile = expectingBetter.valueAt(i); 1691 1692 logCriticalInfo(Log.WARN, "Expected better " + packageName 1693 + " but never showed up; reverting to system"); 1694 1695 final int reparseFlags; 1696 if (FileUtils.contains(privilegedAppDir, scanFile)) { 1697 reparseFlags = PackageParser.PARSE_IS_SYSTEM 1698 | PackageParser.PARSE_IS_SYSTEM_DIR 1699 | PackageParser.PARSE_IS_PRIVILEGED; 1700 } else if (FileUtils.contains(systemAppDir, scanFile)) { 1701 reparseFlags = PackageParser.PARSE_IS_SYSTEM 1702 | PackageParser.PARSE_IS_SYSTEM_DIR; 1703 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 1704 reparseFlags = PackageParser.PARSE_IS_SYSTEM 1705 | PackageParser.PARSE_IS_SYSTEM_DIR; 1706 } else if (FileUtils.contains(oemAppDir, scanFile)) { 1707 reparseFlags = PackageParser.PARSE_IS_SYSTEM 1708 | PackageParser.PARSE_IS_SYSTEM_DIR; 1709 } else { 1710 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 1711 continue; 1712 } 1713 1714 mSettings.enableSystemPackageLPw(packageName); 1715 1716 try { 1717 scanPackageLI(scanFile, reparseFlags, scanFlags, 0, null); 1718 } catch (PackageManagerException e) { 1719 Slog.e(TAG, "Failed to parse original system package: " 1720 + e.getMessage()); 1721 } 1722 } 1723 } 1724 } 1725 1726 // Now that we know all of the shared libraries, update all clients to have 1727 // the correct library paths. 1728 updateAllSharedLibrariesLPw(); 1729 1730 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 1731 // NOTE: We ignore potential failures here during a system scan (like 1732 // the rest of the commands above) because there's precious little we 1733 // can do about it. A settings error is reported, though. 1734 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 1735 false /* force dexopt */, false /* defer dexopt */); 1736 } 1737 1738 // Now that we know all the packages we are keeping, 1739 // read and update their last usage times. 1740 mPackageUsage.readLP(); 1741 1742 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 1743 SystemClock.uptimeMillis()); 1744 Slog.i(TAG, "Time to scan packages: " 1745 + ((SystemClock.uptimeMillis()-startTime)/1000f) 1746 + " seconds"); 1747 1748 // If the platform SDK has changed since the last time we booted, 1749 // we need to re-grant app permission to catch any new ones that 1750 // appear. This is really a hack, and means that apps can in some 1751 // cases get permissions that the user didn't initially explicitly 1752 // allow... it would be nice to have some better way to handle 1753 // this situation. 1754 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 1755 != mSdkVersion; 1756 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 1757 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 1758 + "; regranting permissions for internal storage"); 1759 mSettings.mInternalSdkPlatform = mSdkVersion; 1760 1761 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 1762 | (regrantPermissions 1763 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 1764 : 0)); 1765 1766 // If this is the first boot, and it is a normal boot, then 1767 // we need to initialize the default preferred apps. 1768 if (!mRestoredSettings && !onlyCore) { 1769 mSettings.readDefaultPreferredAppsLPw(this, 0); 1770 } 1771 1772 // If this is first boot after an OTA, and a normal boot, then 1773 // we need to clear code cache directories. 1774 mIsUpgrade = !Build.FINGERPRINT.equals(mSettings.mFingerprint); 1775 if (mIsUpgrade && !onlyCore) { 1776 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 1777 for (String pkgName : mSettings.mPackages.keySet()) { 1778 deleteCodeCacheDirsLI(pkgName); 1779 } 1780 mSettings.mFingerprint = Build.FINGERPRINT; 1781 } 1782 1783 // All the changes are done during package scanning. 1784 mSettings.updateInternalDatabaseVersion(); 1785 1786 // can downgrade to reader 1787 mSettings.writeLPr(); 1788 1789 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 1790 SystemClock.uptimeMillis()); 1791 1792 1793 mRequiredVerifierPackage = getRequiredVerifierLPr(); 1794 } // synchronized (mPackages) 1795 } // synchronized (mInstallLock) 1796 1797 mInstallerService = new PackageInstallerService(context, this, mAppInstallDir); 1798 1799 // Now after opening every single application zip, make sure they 1800 // are all flushed. Not really needed, but keeps things nice and 1801 // tidy. 1802 Runtime.getRuntime().gc(); 1803 } 1804 1805 @Override isFirstBoot()1806 public boolean isFirstBoot() { 1807 return !mRestoredSettings; 1808 } 1809 1810 @Override isOnlyCoreApps()1811 public boolean isOnlyCoreApps() { 1812 return mOnlyCore; 1813 } 1814 1815 @Override isUpgrade()1816 public boolean isUpgrade() { 1817 return mIsUpgrade; 1818 } 1819 getRequiredVerifierLPr()1820 private String getRequiredVerifierLPr() { 1821 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 1822 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 1823 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 1824 1825 String requiredVerifier = null; 1826 1827 final int N = receivers.size(); 1828 for (int i = 0; i < N; i++) { 1829 final ResolveInfo info = receivers.get(i); 1830 1831 if (info.activityInfo == null) { 1832 continue; 1833 } 1834 1835 final String packageName = info.activityInfo.packageName; 1836 1837 final PackageSetting ps = mSettings.mPackages.get(packageName); 1838 if (ps == null) { 1839 continue; 1840 } 1841 1842 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1843 if (!gp.grantedPermissions 1844 .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) { 1845 continue; 1846 } 1847 1848 if (requiredVerifier != null) { 1849 throw new RuntimeException("There can be only one required verifier"); 1850 } 1851 1852 requiredVerifier = packageName; 1853 } 1854 1855 return requiredVerifier; 1856 } 1857 1858 @Override onTransact(int code, Parcel data, Parcel reply, int flags)1859 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1860 throws RemoteException { 1861 try { 1862 return super.onTransact(code, data, reply, flags); 1863 } catch (RuntimeException e) { 1864 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 1865 Slog.wtf(TAG, "Package Manager Crash", e); 1866 } 1867 throw e; 1868 } 1869 } 1870 cleanupInstallFailedPackage(PackageSetting ps)1871 void cleanupInstallFailedPackage(PackageSetting ps) { 1872 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 1873 1874 removeDataDirsLI(ps.name); 1875 if (ps.codePath != null) { 1876 if (ps.codePath.isDirectory()) { 1877 FileUtils.deleteContents(ps.codePath); 1878 } 1879 ps.codePath.delete(); 1880 } 1881 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 1882 if (ps.resourcePath.isDirectory()) { 1883 FileUtils.deleteContents(ps.resourcePath); 1884 } 1885 ps.resourcePath.delete(); 1886 } 1887 mSettings.removePackageLPw(ps.name); 1888 } 1889 appendInts(int[] cur, int[] add)1890 static int[] appendInts(int[] cur, int[] add) { 1891 if (add == null) return cur; 1892 if (cur == null) return add; 1893 final int N = add.length; 1894 for (int i=0; i<N; i++) { 1895 cur = appendInt(cur, add[i]); 1896 } 1897 return cur; 1898 } 1899 removeInts(int[] cur, int[] rem)1900 static int[] removeInts(int[] cur, int[] rem) { 1901 if (rem == null) return cur; 1902 if (cur == null) return cur; 1903 final int N = rem.length; 1904 for (int i=0; i<N; i++) { 1905 cur = removeInt(cur, rem[i]); 1906 } 1907 return cur; 1908 } 1909 generatePackageInfo(PackageParser.Package p, int flags, int userId)1910 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 1911 if (!sUserManager.exists(userId)) return null; 1912 final PackageSetting ps = (PackageSetting) p.mExtras; 1913 if (ps == null) { 1914 return null; 1915 } 1916 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1917 final PackageUserState state = ps.readUserState(userId); 1918 return PackageParser.generatePackageInfo(p, gp.gids, flags, 1919 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions, 1920 state, userId); 1921 } 1922 1923 @Override isPackageAvailable(String packageName, int userId)1924 public boolean isPackageAvailable(String packageName, int userId) { 1925 if (!sUserManager.exists(userId)) return false; 1926 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); 1927 synchronized (mPackages) { 1928 PackageParser.Package p = mPackages.get(packageName); 1929 if (p != null) { 1930 final PackageSetting ps = (PackageSetting) p.mExtras; 1931 if (ps != null) { 1932 final PackageUserState state = ps.readUserState(userId); 1933 if (state != null) { 1934 return PackageParser.isAvailable(state); 1935 } 1936 } 1937 } 1938 } 1939 return false; 1940 } 1941 1942 @Override getPackageInfo(String packageName, int flags, int userId)1943 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 1944 if (!sUserManager.exists(userId)) return null; 1945 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); 1946 // reader 1947 synchronized (mPackages) { 1948 PackageParser.Package p = mPackages.get(packageName); 1949 if (DEBUG_PACKAGE_INFO) 1950 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 1951 if (p != null) { 1952 return generatePackageInfo(p, flags, userId); 1953 } 1954 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 1955 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 1956 } 1957 } 1958 return null; 1959 } 1960 1961 @Override currentToCanonicalPackageNames(String[] names)1962 public String[] currentToCanonicalPackageNames(String[] names) { 1963 String[] out = new String[names.length]; 1964 // reader 1965 synchronized (mPackages) { 1966 for (int i=names.length-1; i>=0; i--) { 1967 PackageSetting ps = mSettings.mPackages.get(names[i]); 1968 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 1969 } 1970 } 1971 return out; 1972 } 1973 1974 @Override canonicalToCurrentPackageNames(String[] names)1975 public String[] canonicalToCurrentPackageNames(String[] names) { 1976 String[] out = new String[names.length]; 1977 // reader 1978 synchronized (mPackages) { 1979 for (int i=names.length-1; i>=0; i--) { 1980 String cur = mSettings.mRenamedPackages.get(names[i]); 1981 out[i] = cur != null ? cur : names[i]; 1982 } 1983 } 1984 return out; 1985 } 1986 1987 @Override getPackageUid(String packageName, int userId)1988 public int getPackageUid(String packageName, int userId) { 1989 if (!sUserManager.exists(userId)) return -1; 1990 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); 1991 // reader 1992 synchronized (mPackages) { 1993 PackageParser.Package p = mPackages.get(packageName); 1994 if(p != null) { 1995 return UserHandle.getUid(userId, p.applicationInfo.uid); 1996 } 1997 PackageSetting ps = mSettings.mPackages.get(packageName); 1998 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 1999 return -1; 2000 } 2001 p = ps.pkg; 2002 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 2003 } 2004 } 2005 2006 @Override getPackageGids(String packageName)2007 public int[] getPackageGids(String packageName) { 2008 // reader 2009 synchronized (mPackages) { 2010 PackageParser.Package p = mPackages.get(packageName); 2011 if (DEBUG_PACKAGE_INFO) 2012 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 2013 if (p != null) { 2014 final PackageSetting ps = (PackageSetting)p.mExtras; 2015 return ps.getGids(); 2016 } 2017 } 2018 // stupid thing to indicate an error. 2019 return new int[0]; 2020 } 2021 generatePermissionInfo( BasePermission bp, int flags)2022 static final PermissionInfo generatePermissionInfo( 2023 BasePermission bp, int flags) { 2024 if (bp.perm != null) { 2025 return PackageParser.generatePermissionInfo(bp.perm, flags); 2026 } 2027 PermissionInfo pi = new PermissionInfo(); 2028 pi.name = bp.name; 2029 pi.packageName = bp.sourcePackage; 2030 pi.nonLocalizedLabel = bp.name; 2031 pi.protectionLevel = bp.protectionLevel; 2032 return pi; 2033 } 2034 2035 @Override getPermissionInfo(String name, int flags)2036 public PermissionInfo getPermissionInfo(String name, int flags) { 2037 // reader 2038 synchronized (mPackages) { 2039 final BasePermission p = mSettings.mPermissions.get(name); 2040 if (p != null) { 2041 return generatePermissionInfo(p, flags); 2042 } 2043 return null; 2044 } 2045 } 2046 2047 @Override queryPermissionsByGroup(String group, int flags)2048 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2049 // reader 2050 synchronized (mPackages) { 2051 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2052 for (BasePermission p : mSettings.mPermissions.values()) { 2053 if (group == null) { 2054 if (p.perm == null || p.perm.info.group == null) { 2055 out.add(generatePermissionInfo(p, flags)); 2056 } 2057 } else { 2058 if (p.perm != null && group.equals(p.perm.info.group)) { 2059 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2060 } 2061 } 2062 } 2063 2064 if (out.size() > 0) { 2065 return out; 2066 } 2067 return mPermissionGroups.containsKey(group) ? out : null; 2068 } 2069 } 2070 2071 @Override getPermissionGroupInfo(String name, int flags)2072 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2073 // reader 2074 synchronized (mPackages) { 2075 return PackageParser.generatePermissionGroupInfo( 2076 mPermissionGroups.get(name), flags); 2077 } 2078 } 2079 2080 @Override getAllPermissionGroups(int flags)2081 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2082 // reader 2083 synchronized (mPackages) { 2084 final int N = mPermissionGroups.size(); 2085 ArrayList<PermissionGroupInfo> out 2086 = new ArrayList<PermissionGroupInfo>(N); 2087 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2088 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2089 } 2090 return out; 2091 } 2092 } 2093 generateApplicationInfoFromSettingsLPw(String packageName, int flags, int userId)2094 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2095 int userId) { 2096 if (!sUserManager.exists(userId)) return null; 2097 PackageSetting ps = mSettings.mPackages.get(packageName); 2098 if (ps != null) { 2099 if (ps.pkg == null) { 2100 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2101 flags, userId); 2102 if (pInfo != null) { 2103 return pInfo.applicationInfo; 2104 } 2105 return null; 2106 } 2107 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2108 ps.readUserState(userId), userId); 2109 } 2110 return null; 2111 } 2112 generatePackageInfoFromSettingsLPw(String packageName, int flags, int userId)2113 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2114 int userId) { 2115 if (!sUserManager.exists(userId)) return null; 2116 PackageSetting ps = mSettings.mPackages.get(packageName); 2117 if (ps != null) { 2118 PackageParser.Package pkg = ps.pkg; 2119 if (pkg == null) { 2120 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2121 return null; 2122 } 2123 // Only data remains, so we aren't worried about code paths 2124 pkg = new PackageParser.Package(packageName); 2125 pkg.applicationInfo.packageName = packageName; 2126 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2127 pkg.applicationInfo.dataDir = 2128 getDataPathForPackage(packageName, 0).getPath(); 2129 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2130 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2131 } 2132 return generatePackageInfo(pkg, flags, userId); 2133 } 2134 return null; 2135 } 2136 2137 @Override getApplicationInfo(String packageName, int flags, int userId)2138 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2139 if (!sUserManager.exists(userId)) return null; 2140 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); 2141 // writer 2142 synchronized (mPackages) { 2143 PackageParser.Package p = mPackages.get(packageName); 2144 if (DEBUG_PACKAGE_INFO) Log.v( 2145 TAG, "getApplicationInfo " + packageName 2146 + ": " + p); 2147 if (p != null) { 2148 PackageSetting ps = mSettings.mPackages.get(packageName); 2149 if (ps == null) return null; 2150 // Note: isEnabledLP() does not apply here - always return info 2151 return PackageParser.generateApplicationInfo( 2152 p, flags, ps.readUserState(userId), userId); 2153 } 2154 if ("android".equals(packageName)||"system".equals(packageName)) { 2155 return mAndroidApplication; 2156 } 2157 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2158 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2159 } 2160 } 2161 return null; 2162 } 2163 2164 2165 @Override freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer)2166 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) { 2167 mContext.enforceCallingOrSelfPermission( 2168 android.Manifest.permission.CLEAR_APP_CACHE, null); 2169 // Queue up an async operation since clearing cache may take a little while. 2170 mHandler.post(new Runnable() { 2171 public void run() { 2172 mHandler.removeCallbacks(this); 2173 int retCode = -1; 2174 synchronized (mInstallLock) { 2175 retCode = mInstaller.freeCache(freeStorageSize); 2176 if (retCode < 0) { 2177 Slog.w(TAG, "Couldn't clear application caches"); 2178 } 2179 } 2180 if (observer != null) { 2181 try { 2182 observer.onRemoveCompleted(null, (retCode >= 0)); 2183 } catch (RemoteException e) { 2184 Slog.w(TAG, "RemoveException when invoking call back"); 2185 } 2186 } 2187 } 2188 }); 2189 } 2190 2191 @Override freeStorage(final long freeStorageSize, final IntentSender pi)2192 public void freeStorage(final long freeStorageSize, final IntentSender pi) { 2193 mContext.enforceCallingOrSelfPermission( 2194 android.Manifest.permission.CLEAR_APP_CACHE, null); 2195 // Queue up an async operation since clearing cache may take a little while. 2196 mHandler.post(new Runnable() { 2197 public void run() { 2198 mHandler.removeCallbacks(this); 2199 int retCode = -1; 2200 synchronized (mInstallLock) { 2201 retCode = mInstaller.freeCache(freeStorageSize); 2202 if (retCode < 0) { 2203 Slog.w(TAG, "Couldn't clear application caches"); 2204 } 2205 } 2206 if(pi != null) { 2207 try { 2208 // Callback via pending intent 2209 int code = (retCode >= 0) ? 1 : 0; 2210 pi.sendIntent(null, code, null, 2211 null, null); 2212 } catch (SendIntentException e1) { 2213 Slog.i(TAG, "Failed to send pending intent"); 2214 } 2215 } 2216 } 2217 }); 2218 } 2219 freeStorage(long freeStorageSize)2220 void freeStorage(long freeStorageSize) throws IOException { 2221 synchronized (mInstallLock) { 2222 if (mInstaller.freeCache(freeStorageSize) < 0) { 2223 throw new IOException("Failed to free enough space"); 2224 } 2225 } 2226 } 2227 2228 @Override getActivityInfo(ComponentName component, int flags, int userId)2229 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2230 if (!sUserManager.exists(userId)) return null; 2231 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); 2232 synchronized (mPackages) { 2233 PackageParser.Activity a = mActivities.mActivities.get(component); 2234 2235 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2236 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2237 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2238 if (ps == null) return null; 2239 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2240 userId); 2241 } 2242 if (mResolveComponentName.equals(component)) { 2243 return PackageParser.generateActivityInfo(mResolveActivity, flags, 2244 new PackageUserState(), userId); 2245 } 2246 } 2247 return null; 2248 } 2249 2250 @Override activitySupportsIntent(ComponentName component, Intent intent, String resolvedType)2251 public boolean activitySupportsIntent(ComponentName component, Intent intent, 2252 String resolvedType) { 2253 synchronized (mPackages) { 2254 PackageParser.Activity a = mActivities.mActivities.get(component); 2255 if (a == null) { 2256 return false; 2257 } 2258 for (int i=0; i<a.intents.size(); i++) { 2259 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 2260 intent.getData(), intent.getCategories(), TAG) >= 0) { 2261 return true; 2262 } 2263 } 2264 return false; 2265 } 2266 } 2267 2268 @Override getReceiverInfo(ComponentName component, int flags, int userId)2269 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 2270 if (!sUserManager.exists(userId)) return null; 2271 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); 2272 synchronized (mPackages) { 2273 PackageParser.Activity a = mReceivers.mActivities.get(component); 2274 if (DEBUG_PACKAGE_INFO) Log.v( 2275 TAG, "getReceiverInfo " + component + ": " + a); 2276 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2277 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2278 if (ps == null) return null; 2279 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2280 userId); 2281 } 2282 } 2283 return null; 2284 } 2285 2286 @Override getServiceInfo(ComponentName component, int flags, int userId)2287 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 2288 if (!sUserManager.exists(userId)) return null; 2289 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); 2290 synchronized (mPackages) { 2291 PackageParser.Service s = mServices.mServices.get(component); 2292 if (DEBUG_PACKAGE_INFO) Log.v( 2293 TAG, "getServiceInfo " + component + ": " + s); 2294 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 2295 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2296 if (ps == null) return null; 2297 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 2298 userId); 2299 } 2300 } 2301 return null; 2302 } 2303 2304 @Override getProviderInfo(ComponentName component, int flags, int userId)2305 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 2306 if (!sUserManager.exists(userId)) return null; 2307 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); 2308 synchronized (mPackages) { 2309 PackageParser.Provider p = mProviders.mProviders.get(component); 2310 if (DEBUG_PACKAGE_INFO) Log.v( 2311 TAG, "getProviderInfo " + component + ": " + p); 2312 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 2313 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2314 if (ps == null) return null; 2315 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 2316 userId); 2317 } 2318 } 2319 return null; 2320 } 2321 2322 @Override getSystemSharedLibraryNames()2323 public String[] getSystemSharedLibraryNames() { 2324 Set<String> libSet; 2325 synchronized (mPackages) { 2326 libSet = mSharedLibraries.keySet(); 2327 int size = libSet.size(); 2328 if (size > 0) { 2329 String[] libs = new String[size]; 2330 libSet.toArray(libs); 2331 return libs; 2332 } 2333 } 2334 return null; 2335 } 2336 2337 @Override getSystemAvailableFeatures()2338 public FeatureInfo[] getSystemAvailableFeatures() { 2339 Collection<FeatureInfo> featSet; 2340 synchronized (mPackages) { 2341 featSet = mAvailableFeatures.values(); 2342 int size = featSet.size(); 2343 if (size > 0) { 2344 FeatureInfo[] features = new FeatureInfo[size+1]; 2345 featSet.toArray(features); 2346 FeatureInfo fi = new FeatureInfo(); 2347 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 2348 FeatureInfo.GL_ES_VERSION_UNDEFINED); 2349 features[size] = fi; 2350 return features; 2351 } 2352 } 2353 return null; 2354 } 2355 2356 @Override hasSystemFeature(String name)2357 public boolean hasSystemFeature(String name) { 2358 synchronized (mPackages) { 2359 return mAvailableFeatures.containsKey(name); 2360 } 2361 } 2362 checkValidCaller(int uid, int userId)2363 private void checkValidCaller(int uid, int userId) { 2364 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 2365 return; 2366 2367 throw new SecurityException("Caller uid=" + uid 2368 + " is not privileged to communicate with user=" + userId); 2369 } 2370 2371 @Override checkPermission(String permName, String pkgName)2372 public int checkPermission(String permName, String pkgName) { 2373 synchronized (mPackages) { 2374 PackageParser.Package p = mPackages.get(pkgName); 2375 if (p != null && p.mExtras != null) { 2376 PackageSetting ps = (PackageSetting)p.mExtras; 2377 if (ps.sharedUser != null) { 2378 if (ps.sharedUser.grantedPermissions.contains(permName)) { 2379 return PackageManager.PERMISSION_GRANTED; 2380 } 2381 } else if (ps.grantedPermissions.contains(permName)) { 2382 return PackageManager.PERMISSION_GRANTED; 2383 } 2384 } 2385 } 2386 return PackageManager.PERMISSION_DENIED; 2387 } 2388 2389 @Override checkUidPermission(String permName, int uid)2390 public int checkUidPermission(String permName, int uid) { 2391 synchronized (mPackages) { 2392 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2393 if (obj != null) { 2394 GrantedPermissions gp = (GrantedPermissions)obj; 2395 if (gp.grantedPermissions.contains(permName)) { 2396 return PackageManager.PERMISSION_GRANTED; 2397 } 2398 } else { 2399 ArraySet<String> perms = mSystemPermissions.get(uid); 2400 if (perms != null && perms.contains(permName)) { 2401 return PackageManager.PERMISSION_GRANTED; 2402 } 2403 } 2404 } 2405 return PackageManager.PERMISSION_DENIED; 2406 } 2407 2408 /** 2409 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 2410 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 2411 * @param checkShell TODO(yamasani): 2412 * @param message the message to log on security exception 2413 */ enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message)2414 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 2415 boolean checkShell, String message) { 2416 if (userId < 0) { 2417 throw new IllegalArgumentException("Invalid userId " + userId); 2418 } 2419 if (checkShell) { 2420 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 2421 } 2422 if (userId == UserHandle.getUserId(callingUid)) return; 2423 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2424 if (requireFullPermission) { 2425 mContext.enforceCallingOrSelfPermission( 2426 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2427 } else { 2428 try { 2429 mContext.enforceCallingOrSelfPermission( 2430 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2431 } catch (SecurityException se) { 2432 mContext.enforceCallingOrSelfPermission( 2433 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 2434 } 2435 } 2436 } 2437 } 2438 enforceShellRestriction(String restriction, int callingUid, int userHandle)2439 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 2440 if (callingUid == Process.SHELL_UID) { 2441 if (userHandle >= 0 2442 && sUserManager.hasUserRestriction(restriction, userHandle)) { 2443 throw new SecurityException("Shell does not have permission to access user " 2444 + userHandle); 2445 } else if (userHandle < 0) { 2446 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 2447 + Debug.getCallers(3)); 2448 } 2449 } 2450 } 2451 findPermissionTreeLP(String permName)2452 private BasePermission findPermissionTreeLP(String permName) { 2453 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 2454 if (permName.startsWith(bp.name) && 2455 permName.length() > bp.name.length() && 2456 permName.charAt(bp.name.length()) == '.') { 2457 return bp; 2458 } 2459 } 2460 return null; 2461 } 2462 checkPermissionTreeLP(String permName)2463 private BasePermission checkPermissionTreeLP(String permName) { 2464 if (permName != null) { 2465 BasePermission bp = findPermissionTreeLP(permName); 2466 if (bp != null) { 2467 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 2468 return bp; 2469 } 2470 throw new SecurityException("Calling uid " 2471 + Binder.getCallingUid() 2472 + " is not allowed to add to permission tree " 2473 + bp.name + " owned by uid " + bp.uid); 2474 } 2475 } 2476 throw new SecurityException("No permission tree found for " + permName); 2477 } 2478 compareStrings(CharSequence s1, CharSequence s2)2479 static boolean compareStrings(CharSequence s1, CharSequence s2) { 2480 if (s1 == null) { 2481 return s2 == null; 2482 } 2483 if (s2 == null) { 2484 return false; 2485 } 2486 if (s1.getClass() != s2.getClass()) { 2487 return false; 2488 } 2489 return s1.equals(s2); 2490 } 2491 comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2)2492 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 2493 if (pi1.icon != pi2.icon) return false; 2494 if (pi1.logo != pi2.logo) return false; 2495 if (pi1.protectionLevel != pi2.protectionLevel) return false; 2496 if (!compareStrings(pi1.name, pi2.name)) return false; 2497 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 2498 // We'll take care of setting this one. 2499 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 2500 // These are not currently stored in settings. 2501 //if (!compareStrings(pi1.group, pi2.group)) return false; 2502 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 2503 //if (pi1.labelRes != pi2.labelRes) return false; 2504 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 2505 return true; 2506 } 2507 permissionInfoFootprint(PermissionInfo info)2508 int permissionInfoFootprint(PermissionInfo info) { 2509 int size = info.name.length(); 2510 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 2511 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 2512 return size; 2513 } 2514 calculateCurrentPermissionFootprintLocked(BasePermission tree)2515 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 2516 int size = 0; 2517 for (BasePermission perm : mSettings.mPermissions.values()) { 2518 if (perm.uid == tree.uid) { 2519 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 2520 } 2521 } 2522 return size; 2523 } 2524 enforcePermissionCapLocked(PermissionInfo info, BasePermission tree)2525 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 2526 // We calculate the max size of permissions defined by this uid and throw 2527 // if that plus the size of 'info' would exceed our stated maximum. 2528 if (tree.uid != Process.SYSTEM_UID) { 2529 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 2530 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 2531 throw new SecurityException("Permission tree size cap exceeded"); 2532 } 2533 } 2534 } 2535 addPermissionLocked(PermissionInfo info, boolean async)2536 boolean addPermissionLocked(PermissionInfo info, boolean async) { 2537 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 2538 throw new SecurityException("Label must be specified in permission"); 2539 } 2540 BasePermission tree = checkPermissionTreeLP(info.name); 2541 BasePermission bp = mSettings.mPermissions.get(info.name); 2542 boolean added = bp == null; 2543 boolean changed = true; 2544 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 2545 if (added) { 2546 enforcePermissionCapLocked(info, tree); 2547 bp = new BasePermission(info.name, tree.sourcePackage, 2548 BasePermission.TYPE_DYNAMIC); 2549 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 2550 throw new SecurityException( 2551 "Not allowed to modify non-dynamic permission " 2552 + info.name); 2553 } else { 2554 if (bp.protectionLevel == fixedLevel 2555 && bp.perm.owner.equals(tree.perm.owner) 2556 && bp.uid == tree.uid 2557 && comparePermissionInfos(bp.perm.info, info)) { 2558 changed = false; 2559 } 2560 } 2561 bp.protectionLevel = fixedLevel; 2562 info = new PermissionInfo(info); 2563 info.protectionLevel = fixedLevel; 2564 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 2565 bp.perm.info.packageName = tree.perm.info.packageName; 2566 bp.uid = tree.uid; 2567 if (added) { 2568 mSettings.mPermissions.put(info.name, bp); 2569 } 2570 if (changed) { 2571 if (!async) { 2572 mSettings.writeLPr(); 2573 } else { 2574 scheduleWriteSettingsLocked(); 2575 } 2576 } 2577 return added; 2578 } 2579 2580 @Override addPermission(PermissionInfo info)2581 public boolean addPermission(PermissionInfo info) { 2582 synchronized (mPackages) { 2583 return addPermissionLocked(info, false); 2584 } 2585 } 2586 2587 @Override addPermissionAsync(PermissionInfo info)2588 public boolean addPermissionAsync(PermissionInfo info) { 2589 synchronized (mPackages) { 2590 return addPermissionLocked(info, true); 2591 } 2592 } 2593 2594 @Override removePermission(String name)2595 public void removePermission(String name) { 2596 synchronized (mPackages) { 2597 checkPermissionTreeLP(name); 2598 BasePermission bp = mSettings.mPermissions.get(name); 2599 if (bp != null) { 2600 if (bp.type != BasePermission.TYPE_DYNAMIC) { 2601 throw new SecurityException( 2602 "Not allowed to modify non-dynamic permission " 2603 + name); 2604 } 2605 mSettings.mPermissions.remove(name); 2606 mSettings.writeLPr(); 2607 } 2608 } 2609 } 2610 checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp)2611 private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) { 2612 int index = pkg.requestedPermissions.indexOf(bp.name); 2613 if (index == -1) { 2614 throw new SecurityException("Package " + pkg.packageName 2615 + " has not requested permission " + bp.name); 2616 } 2617 boolean isNormal = 2618 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) 2619 == PermissionInfo.PROTECTION_NORMAL); 2620 boolean isDangerous = 2621 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) 2622 == PermissionInfo.PROTECTION_DANGEROUS); 2623 boolean isDevelopment = 2624 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0); 2625 2626 if (!isNormal && !isDangerous && !isDevelopment) { 2627 throw new SecurityException("Permission " + bp.name 2628 + " is not a changeable permission type"); 2629 } 2630 2631 if (isNormal || isDangerous) { 2632 if (pkg.requestedPermissionsRequired.get(index)) { 2633 throw new SecurityException("Can't change " + bp.name 2634 + ". It is required by the application"); 2635 } 2636 } 2637 } 2638 2639 @Override grantPermission(String packageName, String permissionName)2640 public void grantPermission(String packageName, String permissionName) { 2641 mContext.enforceCallingOrSelfPermission( 2642 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); 2643 synchronized (mPackages) { 2644 final PackageParser.Package pkg = mPackages.get(packageName); 2645 if (pkg == null) { 2646 throw new IllegalArgumentException("Unknown package: " + packageName); 2647 } 2648 final BasePermission bp = mSettings.mPermissions.get(permissionName); 2649 if (bp == null) { 2650 throw new IllegalArgumentException("Unknown permission: " + permissionName); 2651 } 2652 2653 checkGrantRevokePermissions(pkg, bp); 2654 2655 final PackageSetting ps = (PackageSetting) pkg.mExtras; 2656 if (ps == null) { 2657 return; 2658 } 2659 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps; 2660 if (gp.grantedPermissions.add(permissionName)) { 2661 if (ps.haveGids) { 2662 gp.gids = appendInts(gp.gids, bp.gids); 2663 } 2664 mSettings.writeLPr(); 2665 } 2666 } 2667 } 2668 2669 @Override revokePermission(String packageName, String permissionName)2670 public void revokePermission(String packageName, String permissionName) { 2671 int changedAppId = -1; 2672 2673 synchronized (mPackages) { 2674 final PackageParser.Package pkg = mPackages.get(packageName); 2675 if (pkg == null) { 2676 throw new IllegalArgumentException("Unknown package: " + packageName); 2677 } 2678 if (pkg.applicationInfo.uid != Binder.getCallingUid()) { 2679 mContext.enforceCallingOrSelfPermission( 2680 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); 2681 } 2682 final BasePermission bp = mSettings.mPermissions.get(permissionName); 2683 if (bp == null) { 2684 throw new IllegalArgumentException("Unknown permission: " + permissionName); 2685 } 2686 2687 checkGrantRevokePermissions(pkg, bp); 2688 2689 final PackageSetting ps = (PackageSetting) pkg.mExtras; 2690 if (ps == null) { 2691 return; 2692 } 2693 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps; 2694 if (gp.grantedPermissions.remove(permissionName)) { 2695 gp.grantedPermissions.remove(permissionName); 2696 if (ps.haveGids) { 2697 gp.gids = removeInts(gp.gids, bp.gids); 2698 } 2699 mSettings.writeLPr(); 2700 changedAppId = ps.appId; 2701 } 2702 } 2703 2704 if (changedAppId >= 0) { 2705 // We changed the perm on someone, kill its processes. 2706 IActivityManager am = ActivityManagerNative.getDefault(); 2707 if (am != null) { 2708 final int callingUserId = UserHandle.getCallingUserId(); 2709 final long ident = Binder.clearCallingIdentity(); 2710 try { 2711 //XXX we should only revoke for the calling user's app permissions, 2712 // but for now we impact all users. 2713 //am.killUid(UserHandle.getUid(callingUserId, changedAppId), 2714 // "revoke " + permissionName); 2715 int[] users = sUserManager.getUserIds(); 2716 for (int user : users) { 2717 am.killUid(UserHandle.getUid(user, changedAppId), 2718 "revoke " + permissionName); 2719 } 2720 } catch (RemoteException e) { 2721 } finally { 2722 Binder.restoreCallingIdentity(ident); 2723 } 2724 } 2725 } 2726 } 2727 2728 @Override isProtectedBroadcast(String actionName)2729 public boolean isProtectedBroadcast(String actionName) { 2730 synchronized (mPackages) { 2731 return mProtectedBroadcasts.contains(actionName); 2732 } 2733 } 2734 2735 @Override checkSignatures(String pkg1, String pkg2)2736 public int checkSignatures(String pkg1, String pkg2) { 2737 synchronized (mPackages) { 2738 final PackageParser.Package p1 = mPackages.get(pkg1); 2739 final PackageParser.Package p2 = mPackages.get(pkg2); 2740 if (p1 == null || p1.mExtras == null 2741 || p2 == null || p2.mExtras == null) { 2742 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2743 } 2744 return compareSignatures(p1.mSignatures, p2.mSignatures); 2745 } 2746 } 2747 2748 @Override checkUidSignatures(int uid1, int uid2)2749 public int checkUidSignatures(int uid1, int uid2) { 2750 // Map to base uids. 2751 uid1 = UserHandle.getAppId(uid1); 2752 uid2 = UserHandle.getAppId(uid2); 2753 // reader 2754 synchronized (mPackages) { 2755 Signature[] s1; 2756 Signature[] s2; 2757 Object obj = mSettings.getUserIdLPr(uid1); 2758 if (obj != null) { 2759 if (obj instanceof SharedUserSetting) { 2760 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 2761 } else if (obj instanceof PackageSetting) { 2762 s1 = ((PackageSetting)obj).signatures.mSignatures; 2763 } else { 2764 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2765 } 2766 } else { 2767 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2768 } 2769 obj = mSettings.getUserIdLPr(uid2); 2770 if (obj != null) { 2771 if (obj instanceof SharedUserSetting) { 2772 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 2773 } else if (obj instanceof PackageSetting) { 2774 s2 = ((PackageSetting)obj).signatures.mSignatures; 2775 } else { 2776 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2777 } 2778 } else { 2779 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2780 } 2781 return compareSignatures(s1, s2); 2782 } 2783 } 2784 2785 /** 2786 * Compares two sets of signatures. Returns: 2787 * <br /> 2788 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 2789 * <br /> 2790 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 2791 * <br /> 2792 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 2793 * <br /> 2794 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 2795 * <br /> 2796 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 2797 */ compareSignatures(Signature[] s1, Signature[] s2)2798 static int compareSignatures(Signature[] s1, Signature[] s2) { 2799 if (s1 == null) { 2800 return s2 == null 2801 ? PackageManager.SIGNATURE_NEITHER_SIGNED 2802 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 2803 } 2804 2805 if (s2 == null) { 2806 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 2807 } 2808 2809 if (s1.length != s2.length) { 2810 return PackageManager.SIGNATURE_NO_MATCH; 2811 } 2812 2813 // Since both signature sets are of size 1, we can compare without HashSets. 2814 if (s1.length == 1) { 2815 return s1[0].equals(s2[0]) ? 2816 PackageManager.SIGNATURE_MATCH : 2817 PackageManager.SIGNATURE_NO_MATCH; 2818 } 2819 2820 ArraySet<Signature> set1 = new ArraySet<Signature>(); 2821 for (Signature sig : s1) { 2822 set1.add(sig); 2823 } 2824 ArraySet<Signature> set2 = new ArraySet<Signature>(); 2825 for (Signature sig : s2) { 2826 set2.add(sig); 2827 } 2828 // Make sure s2 contains all signatures in s1. 2829 if (set1.equals(set2)) { 2830 return PackageManager.SIGNATURE_MATCH; 2831 } 2832 return PackageManager.SIGNATURE_NO_MATCH; 2833 } 2834 2835 /** 2836 * If the database version for this type of package (internal storage or 2837 * external storage) is less than the version where package signatures 2838 * were updated, return true. 2839 */ isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg)2840 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 2841 return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan( 2842 DatabaseVersion.SIGNATURE_END_ENTITY)) 2843 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan( 2844 DatabaseVersion.SIGNATURE_END_ENTITY)); 2845 } 2846 2847 /** 2848 * Used for backward compatibility to make sure any packages with 2849 * certificate chains get upgraded to the new style. {@code existingSigs} 2850 * will be in the old format (since they were stored on disk from before the 2851 * system upgrade) and {@code scannedSigs} will be in the newer format. 2852 */ compareSignaturesCompat(PackageSignatures existingSigs, PackageParser.Package scannedPkg)2853 private int compareSignaturesCompat(PackageSignatures existingSigs, 2854 PackageParser.Package scannedPkg) { 2855 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 2856 return PackageManager.SIGNATURE_NO_MATCH; 2857 } 2858 2859 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 2860 for (Signature sig : existingSigs.mSignatures) { 2861 existingSet.add(sig); 2862 } 2863 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 2864 for (Signature sig : scannedPkg.mSignatures) { 2865 try { 2866 Signature[] chainSignatures = sig.getChainSignatures(); 2867 for (Signature chainSig : chainSignatures) { 2868 scannedCompatSet.add(chainSig); 2869 } 2870 } catch (CertificateEncodingException e) { 2871 scannedCompatSet.add(sig); 2872 } 2873 } 2874 /* 2875 * Make sure the expanded scanned set contains all signatures in the 2876 * existing one. 2877 */ 2878 if (scannedCompatSet.equals(existingSet)) { 2879 // Migrate the old signatures to the new scheme. 2880 existingSigs.assignSignatures(scannedPkg.mSignatures); 2881 // The new KeySets will be re-added later in the scanning process. 2882 synchronized (mPackages) { 2883 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 2884 } 2885 return PackageManager.SIGNATURE_MATCH; 2886 } 2887 return PackageManager.SIGNATURE_NO_MATCH; 2888 } 2889 isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg)2890 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 2891 if (isExternal(scannedPkg)) { 2892 return mSettings.isExternalDatabaseVersionOlderThan( 2893 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 2894 } else { 2895 return mSettings.isInternalDatabaseVersionOlderThan( 2896 DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); 2897 } 2898 } 2899 compareSignaturesRecover(PackageSignatures existingSigs, PackageParser.Package scannedPkg)2900 private int compareSignaturesRecover(PackageSignatures existingSigs, 2901 PackageParser.Package scannedPkg) { 2902 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 2903 return PackageManager.SIGNATURE_NO_MATCH; 2904 } 2905 2906 String msg = null; 2907 try { 2908 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 2909 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 2910 + scannedPkg.packageName); 2911 return PackageManager.SIGNATURE_MATCH; 2912 } 2913 } catch (CertificateException e) { 2914 msg = e.getMessage(); 2915 } 2916 2917 logCriticalInfo(Log.INFO, 2918 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 2919 return PackageManager.SIGNATURE_NO_MATCH; 2920 } 2921 2922 @Override getPackagesForUid(int uid)2923 public String[] getPackagesForUid(int uid) { 2924 uid = UserHandle.getAppId(uid); 2925 // reader 2926 synchronized (mPackages) { 2927 Object obj = mSettings.getUserIdLPr(uid); 2928 if (obj instanceof SharedUserSetting) { 2929 final SharedUserSetting sus = (SharedUserSetting) obj; 2930 final int N = sus.packages.size(); 2931 final String[] res = new String[N]; 2932 final Iterator<PackageSetting> it = sus.packages.iterator(); 2933 int i = 0; 2934 while (it.hasNext()) { 2935 res[i++] = it.next().name; 2936 } 2937 return res; 2938 } else if (obj instanceof PackageSetting) { 2939 final PackageSetting ps = (PackageSetting) obj; 2940 return new String[] { ps.name }; 2941 } 2942 } 2943 return null; 2944 } 2945 2946 @Override getNameForUid(int uid)2947 public String getNameForUid(int uid) { 2948 // reader 2949 synchronized (mPackages) { 2950 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2951 if (obj instanceof SharedUserSetting) { 2952 final SharedUserSetting sus = (SharedUserSetting) obj; 2953 return sus.name + ":" + sus.userId; 2954 } else if (obj instanceof PackageSetting) { 2955 final PackageSetting ps = (PackageSetting) obj; 2956 return ps.name; 2957 } 2958 } 2959 return null; 2960 } 2961 2962 @Override getUidForSharedUser(String sharedUserName)2963 public int getUidForSharedUser(String sharedUserName) { 2964 if(sharedUserName == null) { 2965 return -1; 2966 } 2967 // reader 2968 synchronized (mPackages) { 2969 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false); 2970 if (suid == null) { 2971 return -1; 2972 } 2973 return suid.userId; 2974 } 2975 } 2976 2977 @Override getFlagsForUid(int uid)2978 public int getFlagsForUid(int uid) { 2979 synchronized (mPackages) { 2980 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2981 if (obj instanceof SharedUserSetting) { 2982 final SharedUserSetting sus = (SharedUserSetting) obj; 2983 return sus.pkgFlags; 2984 } else if (obj instanceof PackageSetting) { 2985 final PackageSetting ps = (PackageSetting) obj; 2986 return ps.pkgFlags; 2987 } 2988 } 2989 return 0; 2990 } 2991 2992 @Override isUidPrivileged(int uid)2993 public boolean isUidPrivileged(int uid) { 2994 uid = UserHandle.getAppId(uid); 2995 // reader 2996 synchronized (mPackages) { 2997 Object obj = mSettings.getUserIdLPr(uid); 2998 if (obj instanceof SharedUserSetting) { 2999 final SharedUserSetting sus = (SharedUserSetting) obj; 3000 final Iterator<PackageSetting> it = sus.packages.iterator(); 3001 while (it.hasNext()) { 3002 if (it.next().isPrivileged()) { 3003 return true; 3004 } 3005 } 3006 } else if (obj instanceof PackageSetting) { 3007 final PackageSetting ps = (PackageSetting) obj; 3008 return ps.isPrivileged(); 3009 } 3010 } 3011 return false; 3012 } 3013 3014 @Override getAppOpPermissionPackages(String permissionName)3015 public String[] getAppOpPermissionPackages(String permissionName) { 3016 synchronized (mPackages) { 3017 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 3018 if (pkgs == null) { 3019 return null; 3020 } 3021 return pkgs.toArray(new String[pkgs.size()]); 3022 } 3023 } 3024 3025 @Override resolveIntent(Intent intent, String resolvedType, int flags, int userId)3026 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 3027 int flags, int userId) { 3028 if (!sUserManager.exists(userId)) return null; 3029 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); 3030 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3031 return chooseBestActivity(intent, resolvedType, flags, query, userId); 3032 } 3033 3034 @Override setLastChosenActivity(Intent intent, String resolvedType, int flags, IntentFilter filter, int match, ComponentName activity)3035 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 3036 IntentFilter filter, int match, ComponentName activity) { 3037 final int userId = UserHandle.getCallingUserId(); 3038 if (DEBUG_PREFERRED) { 3039 Log.v(TAG, "setLastChosenActivity intent=" + intent 3040 + " resolvedType=" + resolvedType 3041 + " flags=" + flags 3042 + " filter=" + filter 3043 + " match=" + match 3044 + " activity=" + activity); 3045 filter.dump(new PrintStreamPrinter(System.out), " "); 3046 } 3047 intent.setComponent(null); 3048 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3049 // Find any earlier preferred or last chosen entries and nuke them 3050 findPreferredActivity(intent, resolvedType, 3051 flags, query, 0, false, true, false, userId); 3052 // Add the new activity as the last chosen for this filter 3053 addPreferredActivityInternal(filter, match, null, activity, false, userId, 3054 "Setting last chosen"); 3055 } 3056 3057 @Override getLastChosenActivity(Intent intent, String resolvedType, int flags)3058 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 3059 final int userId = UserHandle.getCallingUserId(); 3060 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 3061 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 3062 return findPreferredActivity(intent, resolvedType, flags, query, 0, 3063 false, false, false, userId); 3064 } 3065 chooseBestActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int userId)3066 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 3067 int flags, List<ResolveInfo> query, int userId) { 3068 if (query != null) { 3069 final int N = query.size(); 3070 if (N == 1) { 3071 return query.get(0); 3072 } else if (N > 1) { 3073 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3074 // If there is more than one activity with the same priority, 3075 // then let the user decide between them. 3076 ResolveInfo r0 = query.get(0); 3077 ResolveInfo r1 = query.get(1); 3078 if (DEBUG_INTENT_MATCHING || debug) { 3079 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 3080 + r1.activityInfo.name + "=" + r1.priority); 3081 } 3082 // If the first activity has a higher priority, or a different 3083 // default, then it is always desireable to pick it. 3084 if (r0.priority != r1.priority 3085 || r0.preferredOrder != r1.preferredOrder 3086 || r0.isDefault != r1.isDefault) { 3087 return query.get(0); 3088 } 3089 // If we have saved a preference for a preferred activity for 3090 // this Intent, use that. 3091 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 3092 flags, query, r0.priority, true, false, debug, userId); 3093 if (ri != null) { 3094 return ri; 3095 } 3096 if (userId != 0) { 3097 ri = new ResolveInfo(mResolveInfo); 3098 ri.activityInfo = new ActivityInfo(ri.activityInfo); 3099 ri.activityInfo.applicationInfo = new ApplicationInfo( 3100 ri.activityInfo.applicationInfo); 3101 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 3102 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 3103 return ri; 3104 } 3105 return mResolveInfo; 3106 } 3107 } 3108 return null; 3109 } 3110 findPersistentPreferredActivityLP(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, boolean debug, int userId)3111 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 3112 int flags, List<ResolveInfo> query, boolean debug, int userId) { 3113 final int N = query.size(); 3114 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 3115 .get(userId); 3116 // Get the list of persistent preferred activities that handle the intent 3117 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 3118 List<PersistentPreferredActivity> pprefs = ppir != null 3119 ? ppir.queryIntent(intent, resolvedType, 3120 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3121 : null; 3122 if (pprefs != null && pprefs.size() > 0) { 3123 final int M = pprefs.size(); 3124 for (int i=0; i<M; i++) { 3125 final PersistentPreferredActivity ppa = pprefs.get(i); 3126 if (DEBUG_PREFERRED || debug) { 3127 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 3128 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 3129 + "\n component=" + ppa.mComponent); 3130 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3131 } 3132 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 3133 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3134 if (DEBUG_PREFERRED || debug) { 3135 Slog.v(TAG, "Found persistent preferred activity:"); 3136 if (ai != null) { 3137 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3138 } else { 3139 Slog.v(TAG, " null"); 3140 } 3141 } 3142 if (ai == null) { 3143 // This previously registered persistent preferred activity 3144 // component is no longer known. Ignore it and do NOT remove it. 3145 continue; 3146 } 3147 for (int j=0; j<N; j++) { 3148 final ResolveInfo ri = query.get(j); 3149 if (!ri.activityInfo.applicationInfo.packageName 3150 .equals(ai.applicationInfo.packageName)) { 3151 continue; 3152 } 3153 if (!ri.activityInfo.name.equals(ai.name)) { 3154 continue; 3155 } 3156 // Found a persistent preference that can handle the intent. 3157 if (DEBUG_PREFERRED || debug) { 3158 Slog.v(TAG, "Returning persistent preferred activity: " + 3159 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3160 } 3161 return ri; 3162 } 3163 } 3164 } 3165 return null; 3166 } 3167 findPreferredActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int priority, boolean always, boolean removeMatches, boolean debug, int userId)3168 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 3169 List<ResolveInfo> query, int priority, boolean always, 3170 boolean removeMatches, boolean debug, int userId) { 3171 if (!sUserManager.exists(userId)) return null; 3172 // writer 3173 synchronized (mPackages) { 3174 if (intent.getSelector() != null) { 3175 intent = intent.getSelector(); 3176 } 3177 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 3178 3179 // Try to find a matching persistent preferred activity. 3180 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 3181 debug, userId); 3182 3183 // If a persistent preferred activity matched, use it. 3184 if (pri != null) { 3185 return pri; 3186 } 3187 3188 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 3189 // Get the list of preferred activities that handle the intent 3190 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 3191 List<PreferredActivity> prefs = pir != null 3192 ? pir.queryIntent(intent, resolvedType, 3193 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3194 : null; 3195 if (prefs != null && prefs.size() > 0) { 3196 boolean changed = false; 3197 try { 3198 // First figure out how good the original match set is. 3199 // We will only allow preferred activities that came 3200 // from the same match quality. 3201 int match = 0; 3202 3203 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 3204 3205 final int N = query.size(); 3206 for (int j=0; j<N; j++) { 3207 final ResolveInfo ri = query.get(j); 3208 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 3209 + ": 0x" + Integer.toHexString(match)); 3210 if (ri.match > match) { 3211 match = ri.match; 3212 } 3213 } 3214 3215 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 3216 + Integer.toHexString(match)); 3217 3218 match &= IntentFilter.MATCH_CATEGORY_MASK; 3219 final int M = prefs.size(); 3220 for (int i=0; i<M; i++) { 3221 final PreferredActivity pa = prefs.get(i); 3222 if (DEBUG_PREFERRED || debug) { 3223 Slog.v(TAG, "Checking PreferredActivity ds=" 3224 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 3225 + "\n component=" + pa.mPref.mComponent); 3226 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3227 } 3228 if (pa.mPref.mMatch != match) { 3229 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 3230 + Integer.toHexString(pa.mPref.mMatch)); 3231 continue; 3232 } 3233 // If it's not an "always" type preferred activity and that's what we're 3234 // looking for, skip it. 3235 if (always && !pa.mPref.mAlways) { 3236 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 3237 continue; 3238 } 3239 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 3240 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3241 if (DEBUG_PREFERRED || debug) { 3242 Slog.v(TAG, "Found preferred activity:"); 3243 if (ai != null) { 3244 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3245 } else { 3246 Slog.v(TAG, " null"); 3247 } 3248 } 3249 if (ai == null) { 3250 // This previously registered preferred activity 3251 // component is no longer known. Most likely an update 3252 // to the app was installed and in the new version this 3253 // component no longer exists. Clean it up by removing 3254 // it from the preferred activities list, and skip it. 3255 Slog.w(TAG, "Removing dangling preferred activity: " 3256 + pa.mPref.mComponent); 3257 pir.removeFilter(pa); 3258 changed = true; 3259 continue; 3260 } 3261 for (int j=0; j<N; j++) { 3262 final ResolveInfo ri = query.get(j); 3263 if (!ri.activityInfo.applicationInfo.packageName 3264 .equals(ai.applicationInfo.packageName)) { 3265 continue; 3266 } 3267 if (!ri.activityInfo.name.equals(ai.name)) { 3268 continue; 3269 } 3270 3271 if (removeMatches) { 3272 pir.removeFilter(pa); 3273 changed = true; 3274 if (DEBUG_PREFERRED) { 3275 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 3276 } 3277 break; 3278 } 3279 3280 // Okay we found a previously set preferred or last chosen app. 3281 // If the result set is different from when this 3282 // was created, we need to clear it and re-ask the 3283 // user their preference, if we're looking for an "always" type entry. 3284 if (always && !pa.mPref.sameSet(query)) { 3285 Slog.i(TAG, "Result set changed, dropping preferred activity for " 3286 + intent + " type " + resolvedType); 3287 if (DEBUG_PREFERRED) { 3288 Slog.v(TAG, "Removing preferred activity since set changed " 3289 + pa.mPref.mComponent); 3290 } 3291 pir.removeFilter(pa); 3292 // Re-add the filter as a "last chosen" entry (!always) 3293 PreferredActivity lastChosen = new PreferredActivity( 3294 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 3295 pir.addFilter(lastChosen); 3296 changed = true; 3297 return null; 3298 } 3299 3300 // Yay! Either the set matched or we're looking for the last chosen 3301 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 3302 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3303 return ri; 3304 } 3305 } 3306 } finally { 3307 if (changed) { 3308 if (DEBUG_PREFERRED) { 3309 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 3310 } 3311 scheduleWritePackageRestrictionsLocked(userId); 3312 } 3313 } 3314 } 3315 } 3316 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 3317 return null; 3318 } 3319 3320 /* 3321 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 3322 */ 3323 @Override canForwardTo(Intent intent, String resolvedType, int sourceUserId, int targetUserId)3324 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 3325 int targetUserId) { 3326 mContext.enforceCallingOrSelfPermission( 3327 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 3328 List<CrossProfileIntentFilter> matches = 3329 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 3330 if (matches != null) { 3331 int size = matches.size(); 3332 for (int i = 0; i < size; i++) { 3333 if (matches.get(i).getTargetUserId() == targetUserId) return true; 3334 } 3335 } 3336 return false; 3337 } 3338 getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId)3339 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 3340 String resolvedType, int userId) { 3341 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 3342 if (resolver != null) { 3343 return resolver.queryIntent(intent, resolvedType, false, userId); 3344 } 3345 return null; 3346 } 3347 3348 @Override queryIntentActivities(Intent intent, String resolvedType, int flags, int userId)3349 public List<ResolveInfo> queryIntentActivities(Intent intent, 3350 String resolvedType, int flags, int userId) { 3351 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3352 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); 3353 ComponentName comp = intent.getComponent(); 3354 if (comp == null) { 3355 if (intent.getSelector() != null) { 3356 intent = intent.getSelector(); 3357 comp = intent.getComponent(); 3358 } 3359 } 3360 3361 if (comp != null) { 3362 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3363 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 3364 if (ai != null) { 3365 final ResolveInfo ri = new ResolveInfo(); 3366 ri.activityInfo = ai; 3367 list.add(ri); 3368 } 3369 return list; 3370 } 3371 3372 // reader 3373 synchronized (mPackages) { 3374 final String pkgName = intent.getPackage(); 3375 if (pkgName == null) { 3376 List<CrossProfileIntentFilter> matchingFilters = 3377 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 3378 // Check for results that need to skip the current profile. 3379 ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 3380 resolvedType, flags, userId); 3381 if (resolveInfo != null) { 3382 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 3383 result.add(resolveInfo); 3384 return result; 3385 } 3386 // Check for cross profile results. 3387 resolveInfo = queryCrossProfileIntents( 3388 matchingFilters, intent, resolvedType, flags, userId); 3389 3390 // Check for results in the current profile. 3391 List<ResolveInfo> result = mActivities.queryIntent( 3392 intent, resolvedType, flags, userId); 3393 if (resolveInfo != null) { 3394 result.add(resolveInfo); 3395 Collections.sort(result, mResolvePrioritySorter); 3396 } 3397 return result; 3398 } 3399 final PackageParser.Package pkg = mPackages.get(pkgName); 3400 if (pkg != null) { 3401 return mActivities.queryIntentForPackage(intent, resolvedType, flags, 3402 pkg.activities, userId); 3403 } 3404 return new ArrayList<ResolveInfo>(); 3405 } 3406 } 3407 querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)3408 private ResolveInfo querySkipCurrentProfileIntents( 3409 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 3410 int flags, int sourceUserId) { 3411 if (matchingFilters != null) { 3412 int size = matchingFilters.size(); 3413 for (int i = 0; i < size; i ++) { 3414 CrossProfileIntentFilter filter = matchingFilters.get(i); 3415 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 3416 // Checking if there are activities in the target user that can handle the 3417 // intent. 3418 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 3419 flags, sourceUserId); 3420 if (resolveInfo != null) { 3421 return resolveInfo; 3422 } 3423 } 3424 } 3425 } 3426 return null; 3427 } 3428 3429 // Return matching ResolveInfo if any for skip current profile intent filters. queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)3430 private ResolveInfo queryCrossProfileIntents( 3431 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 3432 int flags, int sourceUserId) { 3433 if (matchingFilters != null) { 3434 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 3435 // match the same intent. For performance reasons, it is better not to 3436 // run queryIntent twice for the same userId 3437 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 3438 int size = matchingFilters.size(); 3439 for (int i = 0; i < size; i++) { 3440 CrossProfileIntentFilter filter = matchingFilters.get(i); 3441 int targetUserId = filter.getTargetUserId(); 3442 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 3443 && !alreadyTriedUserIds.get(targetUserId)) { 3444 // Checking if there are activities in the target user that can handle the 3445 // intent. 3446 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 3447 flags, sourceUserId); 3448 if (resolveInfo != null) return resolveInfo; 3449 alreadyTriedUserIds.put(targetUserId, true); 3450 } 3451 } 3452 } 3453 return null; 3454 } 3455 checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, String resolvedType, int flags, int sourceUserId)3456 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, 3457 String resolvedType, int flags, int sourceUserId) { 3458 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 3459 resolvedType, flags, filter.getTargetUserId()); 3460 if (resultTargetUser != null && !resultTargetUser.isEmpty()) { 3461 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); 3462 } 3463 return null; 3464 } 3465 createForwardingResolveInfo(IntentFilter filter, int sourceUserId, int targetUserId)3466 private ResolveInfo createForwardingResolveInfo(IntentFilter filter, 3467 int sourceUserId, int targetUserId) { 3468 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 3469 String className; 3470 if (targetUserId == UserHandle.USER_OWNER) { 3471 className = FORWARD_INTENT_TO_USER_OWNER; 3472 } else { 3473 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 3474 } 3475 ComponentName forwardingActivityComponentName = new ComponentName( 3476 mAndroidApplication.packageName, className); 3477 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 3478 sourceUserId); 3479 if (targetUserId == UserHandle.USER_OWNER) { 3480 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER; 3481 forwardingResolveInfo.noResourceId = true; 3482 } 3483 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 3484 forwardingResolveInfo.priority = 0; 3485 forwardingResolveInfo.preferredOrder = 0; 3486 forwardingResolveInfo.match = 0; 3487 forwardingResolveInfo.isDefault = true; 3488 forwardingResolveInfo.filter = filter; 3489 forwardingResolveInfo.targetUserId = targetUserId; 3490 return forwardingResolveInfo; 3491 } 3492 3493 @Override queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)3494 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 3495 Intent[] specifics, String[] specificTypes, Intent intent, 3496 String resolvedType, int flags, int userId) { 3497 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3498 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 3499 false, "query intent activity options"); 3500 final String resultsAction = intent.getAction(); 3501 3502 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 3503 | PackageManager.GET_RESOLVED_FILTER, userId); 3504 3505 if (DEBUG_INTENT_MATCHING) { 3506 Log.v(TAG, "Query " + intent + ": " + results); 3507 } 3508 3509 int specificsPos = 0; 3510 int N; 3511 3512 // todo: note that the algorithm used here is O(N^2). This 3513 // isn't a problem in our current environment, but if we start running 3514 // into situations where we have more than 5 or 10 matches then this 3515 // should probably be changed to something smarter... 3516 3517 // First we go through and resolve each of the specific items 3518 // that were supplied, taking care of removing any corresponding 3519 // duplicate items in the generic resolve list. 3520 if (specifics != null) { 3521 for (int i=0; i<specifics.length; i++) { 3522 final Intent sintent = specifics[i]; 3523 if (sintent == null) { 3524 continue; 3525 } 3526 3527 if (DEBUG_INTENT_MATCHING) { 3528 Log.v(TAG, "Specific #" + i + ": " + sintent); 3529 } 3530 3531 String action = sintent.getAction(); 3532 if (resultsAction != null && resultsAction.equals(action)) { 3533 // If this action was explicitly requested, then don't 3534 // remove things that have it. 3535 action = null; 3536 } 3537 3538 ResolveInfo ri = null; 3539 ActivityInfo ai = null; 3540 3541 ComponentName comp = sintent.getComponent(); 3542 if (comp == null) { 3543 ri = resolveIntent( 3544 sintent, 3545 specificTypes != null ? specificTypes[i] : null, 3546 flags, userId); 3547 if (ri == null) { 3548 continue; 3549 } 3550 if (ri == mResolveInfo) { 3551 // ACK! Must do something better with this. 3552 } 3553 ai = ri.activityInfo; 3554 comp = new ComponentName(ai.applicationInfo.packageName, 3555 ai.name); 3556 } else { 3557 ai = getActivityInfo(comp, flags, userId); 3558 if (ai == null) { 3559 continue; 3560 } 3561 } 3562 3563 // Look for any generic query activities that are duplicates 3564 // of this specific one, and remove them from the results. 3565 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 3566 N = results.size(); 3567 int j; 3568 for (j=specificsPos; j<N; j++) { 3569 ResolveInfo sri = results.get(j); 3570 if ((sri.activityInfo.name.equals(comp.getClassName()) 3571 && sri.activityInfo.applicationInfo.packageName.equals( 3572 comp.getPackageName())) 3573 || (action != null && sri.filter.matchAction(action))) { 3574 results.remove(j); 3575 if (DEBUG_INTENT_MATCHING) Log.v( 3576 TAG, "Removing duplicate item from " + j 3577 + " due to specific " + specificsPos); 3578 if (ri == null) { 3579 ri = sri; 3580 } 3581 j--; 3582 N--; 3583 } 3584 } 3585 3586 // Add this specific item to its proper place. 3587 if (ri == null) { 3588 ri = new ResolveInfo(); 3589 ri.activityInfo = ai; 3590 } 3591 results.add(specificsPos, ri); 3592 ri.specificIndex = i; 3593 specificsPos++; 3594 } 3595 } 3596 3597 // Now we go through the remaining generic results and remove any 3598 // duplicate actions that are found here. 3599 N = results.size(); 3600 for (int i=specificsPos; i<N-1; i++) { 3601 final ResolveInfo rii = results.get(i); 3602 if (rii.filter == null) { 3603 continue; 3604 } 3605 3606 // Iterate over all of the actions of this result's intent 3607 // filter... typically this should be just one. 3608 final Iterator<String> it = rii.filter.actionsIterator(); 3609 if (it == null) { 3610 continue; 3611 } 3612 while (it.hasNext()) { 3613 final String action = it.next(); 3614 if (resultsAction != null && resultsAction.equals(action)) { 3615 // If this action was explicitly requested, then don't 3616 // remove things that have it. 3617 continue; 3618 } 3619 for (int j=i+1; j<N; j++) { 3620 final ResolveInfo rij = results.get(j); 3621 if (rij.filter != null && rij.filter.hasAction(action)) { 3622 results.remove(j); 3623 if (DEBUG_INTENT_MATCHING) Log.v( 3624 TAG, "Removing duplicate item from " + j 3625 + " due to action " + action + " at " + i); 3626 j--; 3627 N--; 3628 } 3629 } 3630 } 3631 3632 // If the caller didn't request filter information, drop it now 3633 // so we don't have to marshall/unmarshall it. 3634 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 3635 rii.filter = null; 3636 } 3637 } 3638 3639 // Filter out the caller activity if so requested. 3640 if (caller != null) { 3641 N = results.size(); 3642 for (int i=0; i<N; i++) { 3643 ActivityInfo ainfo = results.get(i).activityInfo; 3644 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 3645 && caller.getClassName().equals(ainfo.name)) { 3646 results.remove(i); 3647 break; 3648 } 3649 } 3650 } 3651 3652 // If the caller didn't request filter information, 3653 // drop them now so we don't have to 3654 // marshall/unmarshall it. 3655 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 3656 N = results.size(); 3657 for (int i=0; i<N; i++) { 3658 results.get(i).filter = null; 3659 } 3660 } 3661 3662 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 3663 return results; 3664 } 3665 3666 @Override queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)3667 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 3668 int userId) { 3669 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3670 ComponentName comp = intent.getComponent(); 3671 if (comp == null) { 3672 if (intent.getSelector() != null) { 3673 intent = intent.getSelector(); 3674 comp = intent.getComponent(); 3675 } 3676 } 3677 if (comp != null) { 3678 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3679 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 3680 if (ai != null) { 3681 ResolveInfo ri = new ResolveInfo(); 3682 ri.activityInfo = ai; 3683 list.add(ri); 3684 } 3685 return list; 3686 } 3687 3688 // reader 3689 synchronized (mPackages) { 3690 String pkgName = intent.getPackage(); 3691 if (pkgName == null) { 3692 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 3693 } 3694 final PackageParser.Package pkg = mPackages.get(pkgName); 3695 if (pkg != null) { 3696 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 3697 userId); 3698 } 3699 return null; 3700 } 3701 } 3702 3703 @Override resolveService(Intent intent, String resolvedType, int flags, int userId)3704 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 3705 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 3706 if (!sUserManager.exists(userId)) return null; 3707 if (query != null) { 3708 if (query.size() >= 1) { 3709 // If there is more than one service with the same priority, 3710 // just arbitrarily pick the first one. 3711 return query.get(0); 3712 } 3713 } 3714 return null; 3715 } 3716 3717 @Override queryIntentServices(Intent intent, String resolvedType, int flags, int userId)3718 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 3719 int userId) { 3720 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3721 ComponentName comp = intent.getComponent(); 3722 if (comp == null) { 3723 if (intent.getSelector() != null) { 3724 intent = intent.getSelector(); 3725 comp = intent.getComponent(); 3726 } 3727 } 3728 if (comp != null) { 3729 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3730 final ServiceInfo si = getServiceInfo(comp, flags, userId); 3731 if (si != null) { 3732 final ResolveInfo ri = new ResolveInfo(); 3733 ri.serviceInfo = si; 3734 list.add(ri); 3735 } 3736 return list; 3737 } 3738 3739 // reader 3740 synchronized (mPackages) { 3741 String pkgName = intent.getPackage(); 3742 if (pkgName == null) { 3743 return mServices.queryIntent(intent, resolvedType, flags, userId); 3744 } 3745 final PackageParser.Package pkg = mPackages.get(pkgName); 3746 if (pkg != null) { 3747 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 3748 userId); 3749 } 3750 return null; 3751 } 3752 } 3753 3754 @Override queryIntentContentProviders( Intent intent, String resolvedType, int flags, int userId)3755 public List<ResolveInfo> queryIntentContentProviders( 3756 Intent intent, String resolvedType, int flags, int userId) { 3757 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3758 ComponentName comp = intent.getComponent(); 3759 if (comp == null) { 3760 if (intent.getSelector() != null) { 3761 intent = intent.getSelector(); 3762 comp = intent.getComponent(); 3763 } 3764 } 3765 if (comp != null) { 3766 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3767 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 3768 if (pi != null) { 3769 final ResolveInfo ri = new ResolveInfo(); 3770 ri.providerInfo = pi; 3771 list.add(ri); 3772 } 3773 return list; 3774 } 3775 3776 // reader 3777 synchronized (mPackages) { 3778 String pkgName = intent.getPackage(); 3779 if (pkgName == null) { 3780 return mProviders.queryIntent(intent, resolvedType, flags, userId); 3781 } 3782 final PackageParser.Package pkg = mPackages.get(pkgName); 3783 if (pkg != null) { 3784 return mProviders.queryIntentForPackage( 3785 intent, resolvedType, flags, pkg.providers, userId); 3786 } 3787 return null; 3788 } 3789 } 3790 3791 @Override getInstalledPackages(int flags, int userId)3792 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 3793 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3794 3795 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); 3796 3797 // writer 3798 synchronized (mPackages) { 3799 ArrayList<PackageInfo> list; 3800 if (listUninstalled) { 3801 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 3802 for (PackageSetting ps : mSettings.mPackages.values()) { 3803 PackageInfo pi; 3804 if (ps.pkg != null) { 3805 pi = generatePackageInfo(ps.pkg, flags, userId); 3806 } else { 3807 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 3808 } 3809 if (pi != null) { 3810 list.add(pi); 3811 } 3812 } 3813 } else { 3814 list = new ArrayList<PackageInfo>(mPackages.size()); 3815 for (PackageParser.Package p : mPackages.values()) { 3816 PackageInfo pi = generatePackageInfo(p, flags, userId); 3817 if (pi != null) { 3818 list.add(pi); 3819 } 3820 } 3821 } 3822 3823 return new ParceledListSlice<PackageInfo>(list); 3824 } 3825 } 3826 addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)3827 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 3828 String[] permissions, boolean[] tmp, int flags, int userId) { 3829 int numMatch = 0; 3830 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 3831 for (int i=0; i<permissions.length; i++) { 3832 if (gp.grantedPermissions.contains(permissions[i])) { 3833 tmp[i] = true; 3834 numMatch++; 3835 } else { 3836 tmp[i] = false; 3837 } 3838 } 3839 if (numMatch == 0) { 3840 return; 3841 } 3842 PackageInfo pi; 3843 if (ps.pkg != null) { 3844 pi = generatePackageInfo(ps.pkg, flags, userId); 3845 } else { 3846 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 3847 } 3848 // The above might return null in cases of uninstalled apps or install-state 3849 // skew across users/profiles. 3850 if (pi != null) { 3851 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 3852 if (numMatch == permissions.length) { 3853 pi.requestedPermissions = permissions; 3854 } else { 3855 pi.requestedPermissions = new String[numMatch]; 3856 numMatch = 0; 3857 for (int i=0; i<permissions.length; i++) { 3858 if (tmp[i]) { 3859 pi.requestedPermissions[numMatch] = permissions[i]; 3860 numMatch++; 3861 } 3862 } 3863 } 3864 } 3865 list.add(pi); 3866 } 3867 } 3868 3869 @Override getPackagesHoldingPermissions( String[] permissions, int flags, int userId)3870 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 3871 String[] permissions, 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<PackageInfo> list = new ArrayList<PackageInfo>(); 3878 boolean[] tmpBools = new boolean[permissions.length]; 3879 if (listUninstalled) { 3880 for (PackageSetting ps : mSettings.mPackages.values()) { 3881 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 3882 } 3883 } else { 3884 for (PackageParser.Package pkg : mPackages.values()) { 3885 PackageSetting ps = (PackageSetting)pkg.mExtras; 3886 if (ps != null) { 3887 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 3888 userId); 3889 } 3890 } 3891 } 3892 3893 return new ParceledListSlice<PackageInfo>(list); 3894 } 3895 } 3896 3897 @Override getInstalledApplications(int flags, int userId)3898 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 3899 if (!sUserManager.exists(userId)) return null; 3900 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3901 3902 // writer 3903 synchronized (mPackages) { 3904 ArrayList<ApplicationInfo> list; 3905 if (listUninstalled) { 3906 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 3907 for (PackageSetting ps : mSettings.mPackages.values()) { 3908 ApplicationInfo ai; 3909 if (ps.pkg != null) { 3910 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 3911 ps.readUserState(userId), userId); 3912 } else { 3913 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 3914 } 3915 if (ai != null) { 3916 list.add(ai); 3917 } 3918 } 3919 } else { 3920 list = new ArrayList<ApplicationInfo>(mPackages.size()); 3921 for (PackageParser.Package p : mPackages.values()) { 3922 if (p.mExtras != null) { 3923 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 3924 ((PackageSetting)p.mExtras).readUserState(userId), userId); 3925 if (ai != null) { 3926 list.add(ai); 3927 } 3928 } 3929 } 3930 } 3931 3932 return new ParceledListSlice<ApplicationInfo>(list); 3933 } 3934 } 3935 getPersistentApplications(int flags)3936 public List<ApplicationInfo> getPersistentApplications(int flags) { 3937 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 3938 3939 // reader 3940 synchronized (mPackages) { 3941 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 3942 final int userId = UserHandle.getCallingUserId(); 3943 while (i.hasNext()) { 3944 final PackageParser.Package p = i.next(); 3945 if (p.applicationInfo != null 3946 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 3947 && (!mSafeMode || isSystemApp(p))) { 3948 PackageSetting ps = mSettings.mPackages.get(p.packageName); 3949 if (ps != null) { 3950 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 3951 ps.readUserState(userId), userId); 3952 if (ai != null) { 3953 finalList.add(ai); 3954 } 3955 } 3956 } 3957 } 3958 } 3959 3960 return finalList; 3961 } 3962 3963 @Override resolveContentProvider(String name, int flags, int userId)3964 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 3965 if (!sUserManager.exists(userId)) return null; 3966 // reader 3967 synchronized (mPackages) { 3968 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 3969 PackageSetting ps = provider != null 3970 ? mSettings.mPackages.get(provider.owner.packageName) 3971 : null; 3972 return ps != null 3973 && mSettings.isEnabledLPr(provider.info, flags, userId) 3974 && (!mSafeMode || (provider.info.applicationInfo.flags 3975 &ApplicationInfo.FLAG_SYSTEM) != 0) 3976 ? PackageParser.generateProviderInfo(provider, flags, 3977 ps.readUserState(userId), userId) 3978 : null; 3979 } 3980 } 3981 3982 /** 3983 * @deprecated 3984 */ 3985 @Deprecated querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)3986 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 3987 // reader 3988 synchronized (mPackages) { 3989 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 3990 .entrySet().iterator(); 3991 final int userId = UserHandle.getCallingUserId(); 3992 while (i.hasNext()) { 3993 Map.Entry<String, PackageParser.Provider> entry = i.next(); 3994 PackageParser.Provider p = entry.getValue(); 3995 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 3996 3997 if (ps != null && p.syncable 3998 && (!mSafeMode || (p.info.applicationInfo.flags 3999 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 4000 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 4001 ps.readUserState(userId), userId); 4002 if (info != null) { 4003 outNames.add(entry.getKey()); 4004 outInfo.add(info); 4005 } 4006 } 4007 } 4008 } 4009 } 4010 4011 @Override queryContentProviders(String processName, int uid, int flags)4012 public List<ProviderInfo> queryContentProviders(String processName, 4013 int uid, int flags) { 4014 ArrayList<ProviderInfo> finalList = null; 4015 // reader 4016 synchronized (mPackages) { 4017 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 4018 final int userId = processName != null ? 4019 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 4020 while (i.hasNext()) { 4021 final PackageParser.Provider p = i.next(); 4022 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 4023 if (ps != null && p.info.authority != null 4024 && (processName == null 4025 || (p.info.processName.equals(processName) 4026 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 4027 && mSettings.isEnabledLPr(p.info, flags, userId) 4028 && (!mSafeMode 4029 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 4030 if (finalList == null) { 4031 finalList = new ArrayList<ProviderInfo>(3); 4032 } 4033 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 4034 ps.readUserState(userId), userId); 4035 if (info != null) { 4036 finalList.add(info); 4037 } 4038 } 4039 } 4040 } 4041 4042 if (finalList != null) { 4043 Collections.sort(finalList, mProviderInitOrderSorter); 4044 } 4045 4046 return finalList; 4047 } 4048 4049 @Override getInstrumentationInfo(ComponentName name, int flags)4050 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 4051 int flags) { 4052 // reader 4053 synchronized (mPackages) { 4054 final PackageParser.Instrumentation i = mInstrumentation.get(name); 4055 return PackageParser.generateInstrumentationInfo(i, flags); 4056 } 4057 } 4058 4059 @Override queryInstrumentation(String targetPackage, int flags)4060 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 4061 int flags) { 4062 ArrayList<InstrumentationInfo> finalList = 4063 new ArrayList<InstrumentationInfo>(); 4064 4065 // reader 4066 synchronized (mPackages) { 4067 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 4068 while (i.hasNext()) { 4069 final PackageParser.Instrumentation p = i.next(); 4070 if (targetPackage == null 4071 || targetPackage.equals(p.info.targetPackage)) { 4072 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 4073 flags); 4074 if (ii != null) { 4075 finalList.add(ii); 4076 } 4077 } 4078 } 4079 } 4080 4081 return finalList; 4082 } 4083 createIdmapsForPackageLI(PackageParser.Package pkg)4084 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 4085 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 4086 if (overlays == null) { 4087 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 4088 return; 4089 } 4090 for (PackageParser.Package opkg : overlays.values()) { 4091 // Not much to do if idmap fails: we already logged the error 4092 // and we certainly don't want to abort installation of pkg simply 4093 // because an overlay didn't fit properly. For these reasons, 4094 // ignore the return value of createIdmapForPackagePairLI. 4095 createIdmapForPackagePairLI(pkg, opkg); 4096 } 4097 } 4098 createIdmapForPackagePairLI(PackageParser.Package pkg, PackageParser.Package opkg)4099 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 4100 PackageParser.Package opkg) { 4101 if (!opkg.mTrustedOverlay) { 4102 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 4103 opkg.baseCodePath + ": overlay not trusted"); 4104 return false; 4105 } 4106 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 4107 if (overlaySet == null) { 4108 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 4109 opkg.baseCodePath + " but target package has no known overlays"); 4110 return false; 4111 } 4112 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4113 // TODO: generate idmap for split APKs 4114 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 4115 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 4116 + opkg.baseCodePath); 4117 return false; 4118 } 4119 PackageParser.Package[] overlayArray = 4120 overlaySet.values().toArray(new PackageParser.Package[0]); 4121 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 4122 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 4123 return p1.mOverlayPriority - p2.mOverlayPriority; 4124 } 4125 }; 4126 Arrays.sort(overlayArray, cmp); 4127 4128 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 4129 int i = 0; 4130 for (PackageParser.Package p : overlayArray) { 4131 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 4132 } 4133 return true; 4134 } 4135 scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime)4136 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 4137 final File[] files = dir.listFiles(); 4138 if (ArrayUtils.isEmpty(files)) { 4139 Log.d(TAG, "No files in app dir " + dir); 4140 return; 4141 } 4142 4143 if (DEBUG_PACKAGE_SCANNING) { 4144 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 4145 + " flags=0x" + Integer.toHexString(parseFlags)); 4146 } 4147 4148 for (File file : files) { 4149 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 4150 && !PackageInstallerService.isStageName(file.getName()); 4151 if (!isPackage) { 4152 // Ignore entries which are not packages 4153 continue; 4154 } 4155 try { 4156 scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 4157 scanFlags, currentTime, null); 4158 } catch (PackageManagerException e) { 4159 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 4160 4161 // Delete invalid userdata apps 4162 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 4163 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 4164 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 4165 if (file.isDirectory()) { 4166 FileUtils.deleteContents(file); 4167 } 4168 file.delete(); 4169 } 4170 } 4171 } 4172 } 4173 getSettingsProblemFile()4174 private static File getSettingsProblemFile() { 4175 File dataDir = Environment.getDataDirectory(); 4176 File systemDir = new File(dataDir, "system"); 4177 File fname = new File(systemDir, "uiderrors.txt"); 4178 return fname; 4179 } 4180 reportSettingsProblem(int priority, String msg)4181 static void reportSettingsProblem(int priority, String msg) { 4182 logCriticalInfo(priority, msg); 4183 } 4184 logCriticalInfo(int priority, String msg)4185 static void logCriticalInfo(int priority, String msg) { 4186 Slog.println(priority, TAG, msg); 4187 EventLogTags.writePmCriticalInfo(msg); 4188 try { 4189 File fname = getSettingsProblemFile(); 4190 FileOutputStream out = new FileOutputStream(fname, true); 4191 PrintWriter pw = new FastPrintWriter(out); 4192 SimpleDateFormat formatter = new SimpleDateFormat(); 4193 String dateString = formatter.format(new Date(System.currentTimeMillis())); 4194 pw.println(dateString + ": " + msg); 4195 pw.close(); 4196 FileUtils.setPermissions( 4197 fname.toString(), 4198 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 4199 -1, -1); 4200 } catch (java.io.IOException e) { 4201 } 4202 } 4203 collectCertificatesLI(PackageParser pp, PackageSetting ps, PackageParser.Package pkg, File srcFile, int parseFlags)4204 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 4205 PackageParser.Package pkg, File srcFile, int parseFlags) 4206 throws PackageManagerException { 4207 if (ps != null 4208 && ps.codePath.equals(srcFile) 4209 && ps.timeStamp == srcFile.lastModified() 4210 && !isCompatSignatureUpdateNeeded(pkg) 4211 && !isRecoverSignatureUpdateNeeded(pkg)) { 4212 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 4213 if (ps.signatures.mSignatures != null 4214 && ps.signatures.mSignatures.length != 0 4215 && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) { 4216 // Optimization: reuse the existing cached certificates 4217 // if the package appears to be unchanged. 4218 pkg.mSignatures = ps.signatures.mSignatures; 4219 KeySetManagerService ksms = mSettings.mKeySetManagerService; 4220 synchronized (mPackages) { 4221 pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 4222 } 4223 return; 4224 } 4225 4226 Slog.w(TAG, "PackageSetting for " + ps.name 4227 + " is missing signatures. Collecting certs again to recover them."); 4228 } else { 4229 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 4230 } 4231 4232 try { 4233 pp.collectCertificates(pkg, parseFlags); 4234 pp.collectManifestDigest(pkg); 4235 } catch (PackageParserException e) { 4236 throw PackageManagerException.from(e); 4237 } 4238 } 4239 4240 /* 4241 * Scan a package and return the newly parsed package. 4242 * Returns null in case of errors and the error code is stored in mLastScanError 4243 */ scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)4244 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 4245 long currentTime, UserHandle user) throws PackageManagerException { 4246 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 4247 parseFlags |= mDefParseFlags; 4248 PackageParser pp = new PackageParser(); 4249 pp.setSeparateProcesses(mSeparateProcesses); 4250 pp.setOnlyCoreApps(mOnlyCore); 4251 pp.setDisplayMetrics(mMetrics); 4252 4253 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 4254 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 4255 } 4256 4257 final PackageParser.Package pkg; 4258 try { 4259 pkg = pp.parsePackage(scanFile, parseFlags); 4260 } catch (PackageParserException e) { 4261 throw PackageManagerException.from(e); 4262 } 4263 4264 PackageSetting ps = null; 4265 PackageSetting updatedPkg; 4266 // reader 4267 synchronized (mPackages) { 4268 // Look to see if we already know about this package. 4269 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 4270 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 4271 // This package has been renamed to its original name. Let's 4272 // use that. 4273 ps = mSettings.peekPackageLPr(oldName); 4274 } 4275 // If there was no original package, see one for the real package name. 4276 if (ps == null) { 4277 ps = mSettings.peekPackageLPr(pkg.packageName); 4278 } 4279 // Check to see if this package could be hiding/updating a system 4280 // package. Must look for it either under the original or real 4281 // package name depending on our state. 4282 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 4283 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 4284 } 4285 boolean updatedPkgBetter = false; 4286 // First check if this is a system package that may involve an update 4287 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 4288 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 4289 // it needs to drop FLAG_PRIVILEGED. 4290 if (locationIsPrivileged(scanFile)) { 4291 updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED; 4292 } else { 4293 updatedPkg.pkgFlags &= ~ApplicationInfo.FLAG_PRIVILEGED; 4294 } 4295 4296 if (ps != null && !ps.codePath.equals(scanFile)) { 4297 // The path has changed from what was last scanned... check the 4298 // version of the new path against what we have stored to determine 4299 // what to do. 4300 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 4301 if (pkg.mVersionCode <= ps.versionCode) { 4302 // The system package has been updated and the code path does not match 4303 // Ignore entry. Skip it. 4304 Slog.i(TAG, "Package " + ps.name + " at " + scanFile 4305 + " ignored: updated version " + ps.versionCode 4306 + " better than this " + pkg.mVersionCode); 4307 if (!updatedPkg.codePath.equals(scanFile)) { 4308 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 4309 + ps.name + " changing from " + updatedPkg.codePathString 4310 + " to " + scanFile); 4311 updatedPkg.codePath = scanFile; 4312 updatedPkg.codePathString = scanFile.toString(); 4313 } 4314 updatedPkg.pkg = pkg; 4315 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null); 4316 } else { 4317 // The current app on the system partition is better than 4318 // what we have updated to on the data partition; switch 4319 // back to the system partition version. 4320 // At this point, its safely assumed that package installation for 4321 // apps in system partition will go through. If not there won't be a working 4322 // version of the app 4323 // writer 4324 synchronized (mPackages) { 4325 // Just remove the loaded entries from package lists. 4326 mPackages.remove(ps.name); 4327 } 4328 4329 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 4330 + " reverting from " + ps.codePathString 4331 + ": new version " + pkg.mVersionCode 4332 + " better than installed " + ps.versionCode); 4333 4334 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 4335 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 4336 getAppDexInstructionSets(ps)); 4337 synchronized (mInstallLock) { 4338 args.cleanUpResourcesLI(); 4339 } 4340 synchronized (mPackages) { 4341 mSettings.enableSystemPackageLPw(ps.name); 4342 } 4343 updatedPkgBetter = true; 4344 } 4345 } 4346 } 4347 4348 if (updatedPkg != null) { 4349 // An updated system app will not have the PARSE_IS_SYSTEM flag set 4350 // initially 4351 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 4352 4353 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 4354 // flag set initially 4355 if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) { 4356 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 4357 } 4358 } 4359 4360 // Verify certificates against what was last scanned 4361 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 4362 4363 /* 4364 * A new system app appeared, but we already had a non-system one of the 4365 * same name installed earlier. 4366 */ 4367 boolean shouldHideSystemApp = false; 4368 if (updatedPkg == null && ps != null 4369 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 4370 /* 4371 * Check to make sure the signatures match first. If they don't, 4372 * wipe the installed application and its data. 4373 */ 4374 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 4375 != PackageManager.SIGNATURE_MATCH) { 4376 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 4377 + " signatures don't match existing userdata copy; removing"); 4378 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 4379 ps = null; 4380 } else { 4381 /* 4382 * If the newly-added system app is an older version than the 4383 * already installed version, hide it. It will be scanned later 4384 * and re-added like an update. 4385 */ 4386 if (pkg.mVersionCode <= ps.versionCode) { 4387 shouldHideSystemApp = true; 4388 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 4389 + " but new version " + pkg.mVersionCode + " better than installed " 4390 + ps.versionCode + "; hiding system"); 4391 } else { 4392 /* 4393 * The newly found system app is a newer version that the 4394 * one previously installed. Simply remove the 4395 * already-installed application and replace it with our own 4396 * while keeping the application data. 4397 */ 4398 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 4399 + " reverting from " + ps.codePathString + ": new version " 4400 + pkg.mVersionCode + " better than installed " + ps.versionCode); 4401 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 4402 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 4403 getAppDexInstructionSets(ps)); 4404 synchronized (mInstallLock) { 4405 args.cleanUpResourcesLI(); 4406 } 4407 } 4408 } 4409 } 4410 4411 // The apk is forward locked (not public) if its code and resources 4412 // are kept in different files. (except for app in either system or 4413 // vendor path). 4414 // TODO grab this value from PackageSettings 4415 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 4416 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 4417 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 4418 } 4419 } 4420 4421 // TODO: extend to support forward-locked splits 4422 String resourcePath = null; 4423 String baseResourcePath = null; 4424 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 4425 if (ps != null && ps.resourcePathString != null) { 4426 resourcePath = ps.resourcePathString; 4427 baseResourcePath = ps.resourcePathString; 4428 } else { 4429 // Should not happen at all. Just log an error. 4430 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 4431 } 4432 } else { 4433 resourcePath = pkg.codePath; 4434 baseResourcePath = pkg.baseCodePath; 4435 } 4436 4437 // Set application objects path explicitly. 4438 pkg.applicationInfo.setCodePath(pkg.codePath); 4439 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 4440 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 4441 pkg.applicationInfo.setResourcePath(resourcePath); 4442 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 4443 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 4444 4445 // Note that we invoke the following method only if we are about to unpack an application 4446 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 4447 | SCAN_UPDATE_SIGNATURE, currentTime, user); 4448 4449 /* 4450 * If the system app should be overridden by a previously installed 4451 * data, hide the system app now and let the /data/app scan pick it up 4452 * again. 4453 */ 4454 if (shouldHideSystemApp) { 4455 synchronized (mPackages) { 4456 /* 4457 * We have to grant systems permissions before we hide, because 4458 * grantPermissions will assume the package update is trying to 4459 * expand its permissions. 4460 */ 4461 grantPermissionsLPw(pkg, true, pkg.packageName); 4462 mSettings.disableSystemPackageLPw(pkg.packageName); 4463 } 4464 } 4465 4466 return scannedPkg; 4467 } 4468 fixProcessName(String defProcessName, String processName, int uid)4469 private static String fixProcessName(String defProcessName, 4470 String processName, int uid) { 4471 if (processName == null) { 4472 return defProcessName; 4473 } 4474 return processName; 4475 } 4476 verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)4477 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 4478 throws PackageManagerException { 4479 if (pkgSetting.signatures.mSignatures != null) { 4480 // Already existing package. Make sure signatures match 4481 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 4482 == PackageManager.SIGNATURE_MATCH; 4483 if (!match) { 4484 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 4485 == PackageManager.SIGNATURE_MATCH; 4486 } 4487 if (!match) { 4488 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 4489 == PackageManager.SIGNATURE_MATCH; 4490 } 4491 if (!match) { 4492 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 4493 + pkg.packageName + " signatures do not match the " 4494 + "previously installed version; ignoring!"); 4495 } 4496 } 4497 4498 // Check for shared user signatures 4499 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 4500 // Already existing package. Make sure signatures match 4501 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 4502 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 4503 if (!match) { 4504 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 4505 == PackageManager.SIGNATURE_MATCH; 4506 } 4507 if (!match) { 4508 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 4509 == PackageManager.SIGNATURE_MATCH; 4510 } 4511 if (!match) { 4512 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 4513 "Package " + pkg.packageName 4514 + " has no signatures that match those in shared user " 4515 + pkgSetting.sharedUser.name + "; ignoring!"); 4516 } 4517 } 4518 } 4519 4520 /** 4521 * Enforces that only the system UID or root's UID can call a method exposed 4522 * via Binder. 4523 * 4524 * @param message used as message if SecurityException is thrown 4525 * @throws SecurityException if the caller is not system or root 4526 */ enforceSystemOrRoot(String message)4527 private static final void enforceSystemOrRoot(String message) { 4528 final int uid = Binder.getCallingUid(); 4529 if (uid != Process.SYSTEM_UID && uid != 0) { 4530 throw new SecurityException(message); 4531 } 4532 } 4533 4534 @Override performBootDexOpt()4535 public void performBootDexOpt() { 4536 enforceSystemOrRoot("Only the system can request dexopt be performed"); 4537 4538 // Before everything else, see whether we need to fstrim. 4539 try { 4540 IMountService ms = PackageHelper.getMountService(); 4541 if (ms != null) { 4542 final boolean isUpgrade = isUpgrade(); 4543 boolean doTrim = isUpgrade; 4544 if (doTrim) { 4545 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 4546 } else { 4547 final long interval = android.provider.Settings.Global.getLong( 4548 mContext.getContentResolver(), 4549 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 4550 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 4551 if (interval > 0) { 4552 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 4553 if (timeSinceLast > interval) { 4554 doTrim = true; 4555 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 4556 + "; running immediately"); 4557 } 4558 } 4559 } 4560 if (doTrim) { 4561 if (!isFirstBoot()) { 4562 try { 4563 ActivityManagerNative.getDefault().showBootMessage( 4564 mContext.getResources().getString( 4565 R.string.android_upgrading_fstrim), true); 4566 } catch (RemoteException e) { 4567 } 4568 } 4569 ms.runMaintenance(); 4570 } 4571 } else { 4572 Slog.e(TAG, "Mount service unavailable!"); 4573 } 4574 } catch (RemoteException e) { 4575 // Can't happen; MountService is local 4576 } 4577 4578 final ArraySet<PackageParser.Package> pkgs; 4579 synchronized (mPackages) { 4580 pkgs = mDeferredDexOpt; 4581 mDeferredDexOpt = null; 4582 } 4583 4584 if (pkgs != null) { 4585 // Sort apps by importance for dexopt ordering. Important apps are given more priority 4586 // in case the device runs out of space. 4587 ArrayList<PackageParser.Package> sortedPkgs = new ArrayList<PackageParser.Package>(); 4588 // Give priority to core apps. 4589 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 4590 PackageParser.Package pkg = it.next(); 4591 if (pkg.coreApp) { 4592 if (DEBUG_DEXOPT) { 4593 Log.i(TAG, "Adding core app " + sortedPkgs.size() + ": " + pkg.packageName); 4594 } 4595 sortedPkgs.add(pkg); 4596 it.remove(); 4597 } 4598 } 4599 // Give priority to system apps that listen for pre boot complete. 4600 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 4601 ArraySet<String> pkgNames = getPackageNamesForIntent(intent); 4602 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 4603 PackageParser.Package pkg = it.next(); 4604 if (pkgNames.contains(pkg.packageName)) { 4605 if (DEBUG_DEXOPT) { 4606 Log.i(TAG, "Adding pre boot system app " + sortedPkgs.size() + ": " + pkg.packageName); 4607 } 4608 sortedPkgs.add(pkg); 4609 it.remove(); 4610 } 4611 } 4612 // Give priority to system apps. 4613 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 4614 PackageParser.Package pkg = it.next(); 4615 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { 4616 if (DEBUG_DEXOPT) { 4617 Log.i(TAG, "Adding system app " + sortedPkgs.size() + ": " + pkg.packageName); 4618 } 4619 sortedPkgs.add(pkg); 4620 it.remove(); 4621 } 4622 } 4623 // Give priority to updated system apps. 4624 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 4625 PackageParser.Package pkg = it.next(); 4626 if (isUpdatedSystemApp(pkg)) { 4627 if (DEBUG_DEXOPT) { 4628 Log.i(TAG, "Adding updated system app " + sortedPkgs.size() + ": " + pkg.packageName); 4629 } 4630 sortedPkgs.add(pkg); 4631 it.remove(); 4632 } 4633 } 4634 // Give priority to apps that listen for boot complete. 4635 intent = new Intent(Intent.ACTION_BOOT_COMPLETED); 4636 pkgNames = getPackageNamesForIntent(intent); 4637 for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { 4638 PackageParser.Package pkg = it.next(); 4639 if (pkgNames.contains(pkg.packageName)) { 4640 if (DEBUG_DEXOPT) { 4641 Log.i(TAG, "Adding boot app " + sortedPkgs.size() + ": " + pkg.packageName); 4642 } 4643 sortedPkgs.add(pkg); 4644 it.remove(); 4645 } 4646 } 4647 // Filter out packages that aren't recently used. 4648 filterRecentlyUsedApps(pkgs); 4649 // Add all remaining apps. 4650 for (PackageParser.Package pkg : pkgs) { 4651 if (DEBUG_DEXOPT) { 4652 Log.i(TAG, "Adding app " + sortedPkgs.size() + ": " + pkg.packageName); 4653 } 4654 sortedPkgs.add(pkg); 4655 } 4656 4657 // If we want to be lazy, filter everything that wasn't recently used. 4658 if (mLazyDexOpt) { 4659 filterRecentlyUsedApps(sortedPkgs); 4660 } 4661 4662 int i = 0; 4663 int total = sortedPkgs.size(); 4664 File dataDir = Environment.getDataDirectory(); 4665 long lowThreshold = StorageManager.from(mContext).getStorageLowBytes(dataDir); 4666 if (lowThreshold == 0) { 4667 throw new IllegalStateException("Invalid low memory threshold"); 4668 } 4669 for (PackageParser.Package pkg : sortedPkgs) { 4670 long usableSpace = dataDir.getUsableSpace(); 4671 if (usableSpace < lowThreshold) { 4672 Log.w(TAG, "Not running dexopt on remaining apps due to low memory: " + usableSpace); 4673 break; 4674 } 4675 performBootDexOpt(pkg, ++i, total); 4676 } 4677 } 4678 } 4679 filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs)4680 private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs) { 4681 // Filter out packages that aren't recently used. 4682 // 4683 // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which 4684 // should do a full dexopt. 4685 if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 4686 int total = pkgs.size(); 4687 int skipped = 0; 4688 long now = System.currentTimeMillis(); 4689 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 4690 PackageParser.Package pkg = i.next(); 4691 long then = pkg.mLastPackageUsageTimeInMills; 4692 if (then + mDexOptLRUThresholdInMills < now) { 4693 if (DEBUG_DEXOPT) { 4694 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 4695 ((then == 0) ? "never" : new Date(then))); 4696 } 4697 i.remove(); 4698 skipped++; 4699 } 4700 } 4701 if (DEBUG_DEXOPT) { 4702 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 4703 } 4704 } 4705 } 4706 getPackageNamesForIntent(Intent intent)4707 private ArraySet<String> getPackageNamesForIntent(Intent intent) { 4708 List<ResolveInfo> ris = null; 4709 try { 4710 ris = AppGlobals.getPackageManager().queryIntentReceivers( 4711 intent, null, 0, UserHandle.USER_OWNER); 4712 } catch (RemoteException e) { 4713 } 4714 ArraySet<String> pkgNames = new ArraySet<String>(); 4715 if (ris != null) { 4716 for (ResolveInfo ri : ris) { 4717 pkgNames.add(ri.activityInfo.packageName); 4718 } 4719 } 4720 return pkgNames; 4721 } 4722 performBootDexOpt(PackageParser.Package pkg, int curr, int total)4723 private void performBootDexOpt(PackageParser.Package pkg, int curr, int total) { 4724 if (DEBUG_DEXOPT) { 4725 Log.i(TAG, "Optimizing app " + curr + " of " + total + ": " + pkg.packageName); 4726 } 4727 if (!isFirstBoot()) { 4728 try { 4729 ActivityManagerNative.getDefault().showBootMessage( 4730 mContext.getResources().getString(R.string.android_upgrading_apk, 4731 curr, total), true); 4732 } catch (RemoteException e) { 4733 } 4734 } 4735 PackageParser.Package p = pkg; 4736 synchronized (mInstallLock) { 4737 performDexOptLI(p, null /* instruction sets */, false /* force dex */, 4738 false /* defer */, true /* include dependencies */); 4739 } 4740 } 4741 4742 @Override performDexOptIfNeeded(String packageName, String instructionSet)4743 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 4744 return performDexOpt(packageName, instructionSet, false); 4745 } 4746 getPrimaryInstructionSet(ApplicationInfo info)4747 private static String getPrimaryInstructionSet(ApplicationInfo info) { 4748 if (info.primaryCpuAbi == null) { 4749 return getPreferredInstructionSet(); 4750 } 4751 4752 return VMRuntime.getInstructionSet(info.primaryCpuAbi); 4753 } 4754 performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt)4755 public boolean performDexOpt(String packageName, String instructionSet, boolean backgroundDexopt) { 4756 boolean dexopt = mLazyDexOpt || backgroundDexopt; 4757 boolean updateUsage = !backgroundDexopt; // Don't update usage if this is just a backgroundDexopt 4758 if (!dexopt && !updateUsage) { 4759 // We aren't going to dexopt or update usage, so bail early. 4760 return false; 4761 } 4762 PackageParser.Package p; 4763 final String targetInstructionSet; 4764 synchronized (mPackages) { 4765 p = mPackages.get(packageName); 4766 if (p == null) { 4767 return false; 4768 } 4769 if (updateUsage) { 4770 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 4771 } 4772 mPackageUsage.write(false); 4773 if (!dexopt) { 4774 // We aren't going to dexopt, so bail early. 4775 return false; 4776 } 4777 4778 targetInstructionSet = instructionSet != null ? instructionSet : 4779 getPrimaryInstructionSet(p.applicationInfo); 4780 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 4781 return false; 4782 } 4783 } 4784 4785 synchronized (mInstallLock) { 4786 final String[] instructionSets = new String[] { targetInstructionSet }; 4787 return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */, 4788 true /* include dependencies */) == DEX_OPT_PERFORMED; 4789 } 4790 } 4791 getPackagesThatNeedDexOpt()4792 public ArraySet<String> getPackagesThatNeedDexOpt() { 4793 ArraySet<String> pkgs = null; 4794 synchronized (mPackages) { 4795 for (PackageParser.Package p : mPackages.values()) { 4796 if (DEBUG_DEXOPT) { 4797 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 4798 } 4799 if (!p.mDexOptPerformed.isEmpty()) { 4800 continue; 4801 } 4802 if (pkgs == null) { 4803 pkgs = new ArraySet<String>(); 4804 } 4805 pkgs.add(p.packageName); 4806 } 4807 } 4808 return pkgs; 4809 } 4810 shutdown()4811 public void shutdown() { 4812 mPackageUsage.write(true); 4813 } 4814 performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets, boolean forceDex, boolean defer, ArraySet<String> done)4815 private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets, 4816 boolean forceDex, boolean defer, ArraySet<String> done) { 4817 for (int i=0; i<libs.size(); i++) { 4818 PackageParser.Package libPkg; 4819 String libName; 4820 synchronized (mPackages) { 4821 libName = libs.get(i); 4822 SharedLibraryEntry lib = mSharedLibraries.get(libName); 4823 if (lib != null && lib.apk != null) { 4824 libPkg = mPackages.get(lib.apk); 4825 } else { 4826 libPkg = null; 4827 } 4828 } 4829 if (libPkg != null && !done.contains(libName)) { 4830 performDexOptLI(libPkg, instructionSets, forceDex, defer, done); 4831 } 4832 } 4833 } 4834 4835 static final int DEX_OPT_SKIPPED = 0; 4836 static final int DEX_OPT_PERFORMED = 1; 4837 static final int DEX_OPT_DEFERRED = 2; 4838 static final int DEX_OPT_FAILED = -1; 4839 performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets, boolean forceDex, boolean defer, ArraySet<String> done)4840 private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets, 4841 boolean forceDex, boolean defer, ArraySet<String> done) { 4842 final String[] instructionSets = targetInstructionSets != null ? 4843 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); 4844 4845 if (done != null) { 4846 done.add(pkg.packageName); 4847 if (pkg.usesLibraries != null) { 4848 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done); 4849 } 4850 if (pkg.usesOptionalLibraries != null) { 4851 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done); 4852 } 4853 } 4854 4855 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) { 4856 return DEX_OPT_SKIPPED; 4857 } 4858 4859 final boolean vmSafeMode = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0; 4860 4861 final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly(); 4862 boolean performedDexOpt = false; 4863 // There are three basic cases here: 4864 // 1.) we need to dexopt, either because we are forced or it is needed 4865 // 2.) we are defering a needed dexopt 4866 // 3.) we are skipping an unneeded dexopt 4867 final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 4868 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 4869 if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) { 4870 continue; 4871 } 4872 4873 for (String path : paths) { 4874 try { 4875 // This will return DEXOPT_NEEDED if we either cannot find any odex file for this 4876 // patckage or the one we find does not match the image checksum (i.e. it was 4877 // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a 4878 // odex file and it matches the checksum of the image but not its base address, 4879 // meaning we need to move it. 4880 final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path, 4881 pkg.packageName, dexCodeInstructionSet, defer); 4882 if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) { 4883 Log.i(TAG, "Running dexopt on: " + path + " pkg=" 4884 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet 4885 + " vmSafeMode=" + vmSafeMode); 4886 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4887 final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg), 4888 pkg.packageName, dexCodeInstructionSet, vmSafeMode); 4889 4890 if (ret < 0) { 4891 // Don't bother running dexopt again if we failed, it will probably 4892 // just result in an error again. Also, don't bother dexopting for other 4893 // paths & ISAs. 4894 return DEX_OPT_FAILED; 4895 } 4896 4897 performedDexOpt = true; 4898 } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) { 4899 Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName); 4900 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4901 final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg), 4902 pkg.packageName, dexCodeInstructionSet); 4903 4904 if (ret < 0) { 4905 // Don't bother running patchoat again if we failed, it will probably 4906 // just result in an error again. Also, don't bother dexopting for other 4907 // paths & ISAs. 4908 return DEX_OPT_FAILED; 4909 } 4910 4911 performedDexOpt = true; 4912 } 4913 4914 // We're deciding to defer a needed dexopt. Don't bother dexopting for other 4915 // paths and instruction sets. We'll deal with them all together when we process 4916 // our list of deferred dexopts. 4917 if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) { 4918 if (mDeferredDexOpt == null) { 4919 mDeferredDexOpt = new ArraySet<PackageParser.Package>(); 4920 } 4921 mDeferredDexOpt.add(pkg); 4922 return DEX_OPT_DEFERRED; 4923 } 4924 } catch (FileNotFoundException e) { 4925 Slog.w(TAG, "Apk not found for dexopt: " + path); 4926 return DEX_OPT_FAILED; 4927 } catch (IOException e) { 4928 Slog.w(TAG, "IOException reading apk: " + path, e); 4929 return DEX_OPT_FAILED; 4930 } catch (StaleDexCacheError e) { 4931 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e); 4932 return DEX_OPT_FAILED; 4933 } catch (Exception e) { 4934 Slog.w(TAG, "Exception when doing dexopt : ", e); 4935 return DEX_OPT_FAILED; 4936 } 4937 } 4938 4939 // At this point we haven't failed dexopt and we haven't deferred dexopt. We must 4940 // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us 4941 // it isn't required. We therefore mark that this package doesn't need dexopt unless 4942 // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped 4943 // it. 4944 pkg.mDexOptPerformed.add(dexCodeInstructionSet); 4945 } 4946 4947 // If we've gotten here, we're sure that no error occurred and that we haven't 4948 // deferred dex-opt. We've either dex-opted one more paths or instruction sets or 4949 // we've skipped all of them because they are up to date. In both cases this 4950 // package doesn't need dexopt any longer. 4951 return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED; 4952 } 4953 getAppDexInstructionSets(ApplicationInfo info)4954 private static String[] getAppDexInstructionSets(ApplicationInfo info) { 4955 if (info.primaryCpuAbi != null) { 4956 if (info.secondaryCpuAbi != null) { 4957 return new String[] { 4958 VMRuntime.getInstructionSet(info.primaryCpuAbi), 4959 VMRuntime.getInstructionSet(info.secondaryCpuAbi) }; 4960 } else { 4961 return new String[] { 4962 VMRuntime.getInstructionSet(info.primaryCpuAbi) }; 4963 } 4964 } 4965 4966 return new String[] { getPreferredInstructionSet() }; 4967 } 4968 getAppDexInstructionSets(PackageSetting ps)4969 private static String[] getAppDexInstructionSets(PackageSetting ps) { 4970 if (ps.primaryCpuAbiString != null) { 4971 if (ps.secondaryCpuAbiString != null) { 4972 return new String[] { 4973 VMRuntime.getInstructionSet(ps.primaryCpuAbiString), 4974 VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) }; 4975 } else { 4976 return new String[] { 4977 VMRuntime.getInstructionSet(ps.primaryCpuAbiString) }; 4978 } 4979 } 4980 4981 return new String[] { getPreferredInstructionSet() }; 4982 } 4983 getPreferredInstructionSet()4984 private static String getPreferredInstructionSet() { 4985 if (sPreferredInstructionSet == null) { 4986 sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]); 4987 } 4988 4989 return sPreferredInstructionSet; 4990 } 4991 getAllInstructionSets()4992 private static List<String> getAllInstructionSets() { 4993 final String[] allAbis = Build.SUPPORTED_ABIS; 4994 final List<String> allInstructionSets = new ArrayList<String>(allAbis.length); 4995 4996 for (String abi : allAbis) { 4997 final String instructionSet = VMRuntime.getInstructionSet(abi); 4998 if (!allInstructionSets.contains(instructionSet)) { 4999 allInstructionSets.add(instructionSet); 5000 } 5001 } 5002 5003 return allInstructionSets; 5004 } 5005 5006 /** 5007 * Returns the instruction set that should be used to compile dex code. In the presence of 5008 * a native bridge this might be different than the one shared libraries use. 5009 */ getDexCodeInstructionSet(String sharedLibraryIsa)5010 private static String getDexCodeInstructionSet(String sharedLibraryIsa) { 5011 String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa); 5012 return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa); 5013 } 5014 getDexCodeInstructionSets(String[] instructionSets)5015 private static String[] getDexCodeInstructionSets(String[] instructionSets) { 5016 ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length); 5017 for (String instructionSet : instructionSets) { 5018 dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet)); 5019 } 5020 return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]); 5021 } 5022 5023 /** 5024 * Returns deduplicated list of supported instructions for dex code. 5025 */ getAllDexCodeInstructionSets()5026 public static String[] getAllDexCodeInstructionSets() { 5027 String[] supportedInstructionSets = new String[Build.SUPPORTED_ABIS.length]; 5028 for (int i = 0; i < supportedInstructionSets.length; i++) { 5029 String abi = Build.SUPPORTED_ABIS[i]; 5030 supportedInstructionSets[i] = VMRuntime.getInstructionSet(abi); 5031 } 5032 return getDexCodeInstructionSets(supportedInstructionSets); 5033 } 5034 5035 @Override forceDexOpt(String packageName)5036 public void forceDexOpt(String packageName) { 5037 enforceSystemOrRoot("forceDexOpt"); 5038 5039 PackageParser.Package pkg; 5040 synchronized (mPackages) { 5041 pkg = mPackages.get(packageName); 5042 if (pkg == null) { 5043 throw new IllegalArgumentException("Missing package: " + packageName); 5044 } 5045 } 5046 5047 synchronized (mInstallLock) { 5048 final String[] instructionSets = new String[] { 5049 getPrimaryInstructionSet(pkg.applicationInfo) }; 5050 final int res = performDexOptLI(pkg, instructionSets, true, false, true); 5051 if (res != DEX_OPT_PERFORMED) { 5052 throw new IllegalStateException("Failed to dexopt: " + res); 5053 } 5054 } 5055 } 5056 performDexOptLI(PackageParser.Package pkg, String[] instructionSets, boolean forceDex, boolean defer, boolean inclDependencies)5057 private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets, 5058 boolean forceDex, boolean defer, boolean inclDependencies) { 5059 ArraySet<String> done; 5060 if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) { 5061 done = new ArraySet<String>(); 5062 done.add(pkg.packageName); 5063 } else { 5064 done = null; 5065 } 5066 return performDexOptLI(pkg, instructionSets, forceDex, defer, done); 5067 } 5068 verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)5069 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 5070 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 5071 Slog.w(TAG, "Unable to update from " + oldPkg.name 5072 + " to " + newPkg.packageName 5073 + ": old package not in system partition"); 5074 return false; 5075 } else if (mPackages.get(oldPkg.name) != null) { 5076 Slog.w(TAG, "Unable to update from " + oldPkg.name 5077 + " to " + newPkg.packageName 5078 + ": old package still exists"); 5079 return false; 5080 } 5081 return true; 5082 } 5083 getDataPathForUser(int userId)5084 File getDataPathForUser(int userId) { 5085 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId); 5086 } 5087 getDataPathForPackage(String packageName, int userId)5088 private File getDataPathForPackage(String packageName, int userId) { 5089 /* 5090 * Until we fully support multiple users, return the directory we 5091 * previously would have. The PackageManagerTests will need to be 5092 * revised when this is changed back.. 5093 */ 5094 if (userId == 0) { 5095 return new File(mAppDataDir, packageName); 5096 } else { 5097 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId 5098 + File.separator + packageName); 5099 } 5100 } 5101 createDataDirsLI(String packageName, int uid, String seinfo)5102 private int createDataDirsLI(String packageName, int uid, String seinfo) { 5103 int[] users = sUserManager.getUserIds(); 5104 int res = mInstaller.install(packageName, uid, uid, seinfo); 5105 if (res < 0) { 5106 return res; 5107 } 5108 for (int user : users) { 5109 if (user != 0) { 5110 res = mInstaller.createUserData(packageName, 5111 UserHandle.getUid(user, uid), user, seinfo); 5112 if (res < 0) { 5113 return res; 5114 } 5115 } 5116 } 5117 return res; 5118 } 5119 removeDataDirsLI(String packageName)5120 private int removeDataDirsLI(String packageName) { 5121 int[] users = sUserManager.getUserIds(); 5122 int res = 0; 5123 for (int user : users) { 5124 int resInner = mInstaller.remove(packageName, user); 5125 if (resInner < 0) { 5126 res = resInner; 5127 } 5128 } 5129 5130 return res; 5131 } 5132 deleteCodeCacheDirsLI(String packageName)5133 private int deleteCodeCacheDirsLI(String packageName) { 5134 int[] users = sUserManager.getUserIds(); 5135 int res = 0; 5136 for (int user : users) { 5137 int resInner = mInstaller.deleteCodeCacheFiles(packageName, user); 5138 if (resInner < 0) { 5139 res = resInner; 5140 } 5141 } 5142 return res; 5143 } 5144 addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, PackageParser.Package changingLib)5145 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 5146 PackageParser.Package changingLib) { 5147 if (file.path != null) { 5148 usesLibraryFiles.add(file.path); 5149 return; 5150 } 5151 PackageParser.Package p = mPackages.get(file.apk); 5152 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 5153 // If we are doing this while in the middle of updating a library apk, 5154 // then we need to make sure to use that new apk for determining the 5155 // dependencies here. (We haven't yet finished committing the new apk 5156 // to the package manager state.) 5157 if (p == null || p.packageName.equals(changingLib.packageName)) { 5158 p = changingLib; 5159 } 5160 } 5161 if (p != null) { 5162 usesLibraryFiles.addAll(p.getAllCodePaths()); 5163 } 5164 } 5165 updateSharedLibrariesLPw(PackageParser.Package pkg, PackageParser.Package changingLib)5166 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 5167 PackageParser.Package changingLib) throws PackageManagerException { 5168 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 5169 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 5170 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 5171 for (int i=0; i<N; i++) { 5172 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 5173 if (file == null) { 5174 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 5175 "Package " + pkg.packageName + " requires unavailable shared library " 5176 + pkg.usesLibraries.get(i) + "; failing!"); 5177 } 5178 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5179 } 5180 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 5181 for (int i=0; i<N; i++) { 5182 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 5183 if (file == null) { 5184 Slog.w(TAG, "Package " + pkg.packageName 5185 + " desires unavailable shared library " 5186 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 5187 } else { 5188 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 5189 } 5190 } 5191 N = usesLibraryFiles.size(); 5192 if (N > 0) { 5193 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 5194 } else { 5195 pkg.usesLibraryFiles = null; 5196 } 5197 } 5198 } 5199 hasString(List<String> list, List<String> which)5200 private static boolean hasString(List<String> list, List<String> which) { 5201 if (list == null) { 5202 return false; 5203 } 5204 for (int i=list.size()-1; i>=0; i--) { 5205 for (int j=which.size()-1; j>=0; j--) { 5206 if (which.get(j).equals(list.get(i))) { 5207 return true; 5208 } 5209 } 5210 } 5211 return false; 5212 } 5213 updateAllSharedLibrariesLPw()5214 private void updateAllSharedLibrariesLPw() { 5215 for (PackageParser.Package pkg : mPackages.values()) { 5216 try { 5217 updateSharedLibrariesLPw(pkg, null); 5218 } catch (PackageManagerException e) { 5219 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5220 } 5221 } 5222 } 5223 updateAllSharedLibrariesLPw( PackageParser.Package changingPkg)5224 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 5225 PackageParser.Package changingPkg) { 5226 ArrayList<PackageParser.Package> res = null; 5227 for (PackageParser.Package pkg : mPackages.values()) { 5228 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 5229 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 5230 if (res == null) { 5231 res = new ArrayList<PackageParser.Package>(); 5232 } 5233 res.add(pkg); 5234 try { 5235 updateSharedLibrariesLPw(pkg, changingPkg); 5236 } catch (PackageManagerException e) { 5237 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 5238 } 5239 } 5240 } 5241 return res; 5242 } 5243 5244 /** 5245 * Derive the value of the {@code cpuAbiOverride} based on the provided 5246 * value and an optional stored value from the package settings. 5247 */ deriveAbiOverride(String abiOverride, PackageSetting settings)5248 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 5249 String cpuAbiOverride = null; 5250 5251 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 5252 cpuAbiOverride = null; 5253 } else if (abiOverride != null) { 5254 cpuAbiOverride = abiOverride; 5255 } else if (settings != null) { 5256 cpuAbiOverride = settings.cpuAbiOverrideString; 5257 } 5258 5259 return cpuAbiOverride; 5260 } 5261 scanPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)5262 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 5263 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5264 boolean success = false; 5265 try { 5266 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 5267 currentTime, user); 5268 success = true; 5269 return res; 5270 } finally { 5271 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5272 removeDataDirsLI(pkg.packageName); 5273 } 5274 } 5275 } 5276 scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, int scanFlags, long currentTime, UserHandle user)5277 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 5278 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 5279 final File scanFile = new File(pkg.codePath); 5280 if (pkg.applicationInfo.getCodePath() == null || 5281 pkg.applicationInfo.getResourcePath() == null) { 5282 // Bail out. The resource and code paths haven't been set. 5283 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 5284 "Code and resource paths haven't been set correctly"); 5285 } 5286 5287 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5288 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 5289 } else { 5290 // Only allow system apps to be flagged as core apps. 5291 pkg.coreApp = false; 5292 } 5293 5294 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 5295 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED; 5296 } 5297 5298 if (mCustomResolverComponentName != null && 5299 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 5300 setUpCustomResolverActivity(pkg); 5301 } 5302 5303 if (pkg.packageName.equals("android")) { 5304 synchronized (mPackages) { 5305 if (mAndroidApplication != null) { 5306 Slog.w(TAG, "*************************************************"); 5307 Slog.w(TAG, "Core android package being redefined. Skipping."); 5308 Slog.w(TAG, " file=" + scanFile); 5309 Slog.w(TAG, "*************************************************"); 5310 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5311 "Core android package being redefined. Skipping."); 5312 } 5313 5314 // Set up information for our fall-back user intent resolution activity. 5315 mPlatformPackage = pkg; 5316 pkg.mVersionCode = mSdkVersion; 5317 mAndroidApplication = pkg.applicationInfo; 5318 5319 if (!mResolverReplaced) { 5320 mResolveActivity.applicationInfo = mAndroidApplication; 5321 mResolveActivity.name = ResolverActivity.class.getName(); 5322 mResolveActivity.packageName = mAndroidApplication.packageName; 5323 mResolveActivity.processName = "system:ui"; 5324 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 5325 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 5326 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 5327 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 5328 mResolveActivity.exported = true; 5329 mResolveActivity.enabled = true; 5330 mResolveInfo.activityInfo = mResolveActivity; 5331 mResolveInfo.priority = 0; 5332 mResolveInfo.preferredOrder = 0; 5333 mResolveInfo.match = 0; 5334 mResolveComponentName = new ComponentName( 5335 mAndroidApplication.packageName, mResolveActivity.name); 5336 } 5337 } 5338 } 5339 5340 if (DEBUG_PACKAGE_SCANNING) { 5341 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5342 Log.d(TAG, "Scanning package " + pkg.packageName); 5343 } 5344 5345 if (mPackages.containsKey(pkg.packageName) 5346 || mSharedLibraries.containsKey(pkg.packageName)) { 5347 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5348 "Application package " + pkg.packageName 5349 + " already installed. Skipping duplicate."); 5350 } 5351 5352 // Initialize package source and resource directories 5353 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 5354 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 5355 5356 SharedUserSetting suid = null; 5357 PackageSetting pkgSetting = null; 5358 5359 if (!isSystemApp(pkg)) { 5360 // Only system apps can use these features. 5361 pkg.mOriginalPackages = null; 5362 pkg.mRealPackage = null; 5363 pkg.mAdoptPermissions = null; 5364 } 5365 5366 // writer 5367 synchronized (mPackages) { 5368 if (pkg.mSharedUserId != null) { 5369 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true); 5370 if (suid == null) { 5371 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5372 "Creating application package " + pkg.packageName 5373 + " for shared user failed"); 5374 } 5375 if (DEBUG_PACKAGE_SCANNING) { 5376 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5377 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 5378 + "): packages=" + suid.packages); 5379 } 5380 } 5381 5382 // Check if we are renaming from an original package name. 5383 PackageSetting origPackage = null; 5384 String realName = null; 5385 if (pkg.mOriginalPackages != null) { 5386 // This package may need to be renamed to a previously 5387 // installed name. Let's check on that... 5388 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 5389 if (pkg.mOriginalPackages.contains(renamed)) { 5390 // This package had originally been installed as the 5391 // original name, and we have already taken care of 5392 // transitioning to the new one. Just update the new 5393 // one to continue using the old name. 5394 realName = pkg.mRealPackage; 5395 if (!pkg.packageName.equals(renamed)) { 5396 // Callers into this function may have already taken 5397 // care of renaming the package; only do it here if 5398 // it is not already done. 5399 pkg.setPackageName(renamed); 5400 } 5401 5402 } else { 5403 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 5404 if ((origPackage = mSettings.peekPackageLPr( 5405 pkg.mOriginalPackages.get(i))) != null) { 5406 // We do have the package already installed under its 5407 // original name... should we use it? 5408 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 5409 // New package is not compatible with original. 5410 origPackage = null; 5411 continue; 5412 } else if (origPackage.sharedUser != null) { 5413 // Make sure uid is compatible between packages. 5414 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 5415 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 5416 + " to " + pkg.packageName + ": old uid " 5417 + origPackage.sharedUser.name 5418 + " differs from " + pkg.mSharedUserId); 5419 origPackage = null; 5420 continue; 5421 } 5422 } else { 5423 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 5424 + pkg.packageName + " to old name " + origPackage.name); 5425 } 5426 break; 5427 } 5428 } 5429 } 5430 } 5431 5432 if (mTransferedPackages.contains(pkg.packageName)) { 5433 Slog.w(TAG, "Package " + pkg.packageName 5434 + " was transferred to another, but its .apk remains"); 5435 } 5436 5437 // Just create the setting, don't add it yet. For already existing packages 5438 // the PkgSetting exists already and doesn't have to be created. 5439 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 5440 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 5441 pkg.applicationInfo.primaryCpuAbi, 5442 pkg.applicationInfo.secondaryCpuAbi, 5443 pkg.applicationInfo.flags, user, false); 5444 if (pkgSetting == null) { 5445 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5446 "Creating application package " + pkg.packageName + " failed"); 5447 } 5448 5449 if (pkgSetting.origPackage != null) { 5450 // If we are first transitioning from an original package, 5451 // fix up the new package's name now. We need to do this after 5452 // looking up the package under its new name, so getPackageLP 5453 // can take care of fiddling things correctly. 5454 pkg.setPackageName(origPackage.name); 5455 5456 // File a report about this. 5457 String msg = "New package " + pkgSetting.realName 5458 + " renamed to replace old package " + pkgSetting.name; 5459 reportSettingsProblem(Log.WARN, msg); 5460 5461 // Make a note of it. 5462 mTransferedPackages.add(origPackage.name); 5463 5464 // No longer need to retain this. 5465 pkgSetting.origPackage = null; 5466 } 5467 5468 if (realName != null) { 5469 // Make a note of it. 5470 mTransferedPackages.add(pkg.packageName); 5471 } 5472 5473 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 5474 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 5475 } 5476 5477 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5478 // Check all shared libraries and map to their actual file path. 5479 // We only do this here for apps not on a system dir, because those 5480 // are the only ones that can fail an install due to this. We 5481 // will take care of the system apps by updating all of their 5482 // library paths after the scan is done. 5483 updateSharedLibrariesLPw(pkg, null); 5484 } 5485 5486 if (mFoundPolicyFile) { 5487 SELinuxMMAC.assignSeinfoValue(pkg); 5488 } 5489 5490 pkg.applicationInfo.uid = pkgSetting.appId; 5491 pkg.mExtras = pkgSetting; 5492 if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) { 5493 try { 5494 verifySignaturesLP(pkgSetting, pkg); 5495 // We just determined the app is signed correctly, so bring 5496 // over the latest parsed certs. 5497 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5498 } catch (PackageManagerException e) { 5499 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5500 throw e; 5501 } 5502 // The signature has changed, but this package is in the system 5503 // image... let's recover! 5504 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5505 // However... if this package is part of a shared user, but it 5506 // doesn't match the signature of the shared user, let's fail. 5507 // What this means is that you can't change the signatures 5508 // associated with an overall shared user, which doesn't seem all 5509 // that unreasonable. 5510 if (pkgSetting.sharedUser != null) { 5511 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5512 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 5513 throw new PackageManagerException( 5514 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 5515 "Signature mismatch for shared user : " 5516 + pkgSetting.sharedUser); 5517 } 5518 } 5519 // File a report about this. 5520 String msg = "System package " + pkg.packageName 5521 + " signature changed; retaining data."; 5522 reportSettingsProblem(Log.WARN, msg); 5523 } 5524 } else { 5525 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) { 5526 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5527 + pkg.packageName + " upgrade keys do not match the " 5528 + "previously installed version"); 5529 } else { 5530 // We just determined the app is signed correctly, so bring 5531 // over the latest parsed certs. 5532 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5533 } 5534 } 5535 // Verify that this new package doesn't have any content providers 5536 // that conflict with existing packages. Only do this if the 5537 // package isn't already installed, since we don't want to break 5538 // things that are installed. 5539 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 5540 final int N = pkg.providers.size(); 5541 int i; 5542 for (i=0; i<N; i++) { 5543 PackageParser.Provider p = pkg.providers.get(i); 5544 if (p.info.authority != null) { 5545 String names[] = p.info.authority.split(";"); 5546 for (int j = 0; j < names.length; j++) { 5547 if (mProvidersByAuthority.containsKey(names[j])) { 5548 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 5549 final String otherPackageName = 5550 ((other != null && other.getComponentName() != null) ? 5551 other.getComponentName().getPackageName() : "?"); 5552 throw new PackageManagerException( 5553 INSTALL_FAILED_CONFLICTING_PROVIDER, 5554 "Can't install because provider name " + names[j] 5555 + " (in package " + pkg.applicationInfo.packageName 5556 + ") is already used by " + otherPackageName); 5557 } 5558 } 5559 } 5560 } 5561 } 5562 5563 if (pkg.mAdoptPermissions != null) { 5564 // This package wants to adopt ownership of permissions from 5565 // another package. 5566 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 5567 final String origName = pkg.mAdoptPermissions.get(i); 5568 final PackageSetting orig = mSettings.peekPackageLPr(origName); 5569 if (orig != null) { 5570 if (verifyPackageUpdateLPr(orig, pkg)) { 5571 Slog.i(TAG, "Adopting permissions from " + origName + " to " 5572 + pkg.packageName); 5573 mSettings.transferPermissionsLPw(origName, pkg.packageName); 5574 } 5575 } 5576 } 5577 } 5578 } 5579 5580 final String pkgName = pkg.packageName; 5581 5582 final long scanFileTime = scanFile.lastModified(); 5583 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 5584 pkg.applicationInfo.processName = fixProcessName( 5585 pkg.applicationInfo.packageName, 5586 pkg.applicationInfo.processName, 5587 pkg.applicationInfo.uid); 5588 5589 File dataPath; 5590 if (mPlatformPackage == pkg) { 5591 // The system package is special. 5592 dataPath = new File(Environment.getDataDirectory(), "system"); 5593 5594 pkg.applicationInfo.dataDir = dataPath.getPath(); 5595 5596 } else { 5597 // This is a normal package, need to make its data directory. 5598 dataPath = getDataPathForPackage(pkg.packageName, 0); 5599 5600 boolean uidError = false; 5601 if (dataPath.exists()) { 5602 int currentUid = 0; 5603 try { 5604 StructStat stat = Os.stat(dataPath.getPath()); 5605 currentUid = stat.st_uid; 5606 } catch (ErrnoException e) { 5607 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 5608 } 5609 5610 // If we have mismatched owners for the data path, we have a problem. 5611 if (currentUid != pkg.applicationInfo.uid) { 5612 boolean recovered = false; 5613 if (currentUid == 0) { 5614 // The directory somehow became owned by root. Wow. 5615 // This is probably because the system was stopped while 5616 // installd was in the middle of messing with its libs 5617 // directory. Ask installd to fix that. 5618 int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid, 5619 pkg.applicationInfo.uid); 5620 if (ret >= 0) { 5621 recovered = true; 5622 String msg = "Package " + pkg.packageName 5623 + " unexpectedly changed to uid 0; recovered to " + 5624 + pkg.applicationInfo.uid; 5625 reportSettingsProblem(Log.WARN, msg); 5626 } 5627 } 5628 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 5629 || (scanFlags&SCAN_BOOTING) != 0)) { 5630 // If this is a system app, we can at least delete its 5631 // current data so the application will still work. 5632 int ret = removeDataDirsLI(pkgName); 5633 if (ret >= 0) { 5634 // TODO: Kill the processes first 5635 // Old data gone! 5636 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 5637 ? "System package " : "Third party package "; 5638 String msg = prefix + pkg.packageName 5639 + " has changed from uid: " 5640 + currentUid + " to " 5641 + pkg.applicationInfo.uid + "; old data erased"; 5642 reportSettingsProblem(Log.WARN, msg); 5643 recovered = true; 5644 5645 // And now re-install the app. 5646 ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 5647 pkg.applicationInfo.seinfo); 5648 if (ret == -1) { 5649 // Ack should not happen! 5650 msg = prefix + pkg.packageName 5651 + " could not have data directory re-created after delete."; 5652 reportSettingsProblem(Log.WARN, msg); 5653 throw new PackageManagerException( 5654 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 5655 } 5656 } 5657 if (!recovered) { 5658 mHasSystemUidErrors = true; 5659 } 5660 } else if (!recovered) { 5661 // If we allow this install to proceed, we will be broken. 5662 // Abort, abort! 5663 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 5664 "scanPackageLI"); 5665 } 5666 if (!recovered) { 5667 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 5668 + pkg.applicationInfo.uid + "/fs_" 5669 + currentUid; 5670 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 5671 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 5672 String msg = "Package " + pkg.packageName 5673 + " has mismatched uid: " 5674 + currentUid + " on disk, " 5675 + pkg.applicationInfo.uid + " in settings"; 5676 // writer 5677 synchronized (mPackages) { 5678 mSettings.mReadMessages.append(msg); 5679 mSettings.mReadMessages.append('\n'); 5680 uidError = true; 5681 if (!pkgSetting.uidError) { 5682 reportSettingsProblem(Log.ERROR, msg); 5683 } 5684 } 5685 } 5686 } 5687 pkg.applicationInfo.dataDir = dataPath.getPath(); 5688 if (mShouldRestoreconData) { 5689 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 5690 mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo, 5691 pkg.applicationInfo.uid); 5692 } 5693 } else { 5694 if (DEBUG_PACKAGE_SCANNING) { 5695 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5696 Log.v(TAG, "Want this data dir: " + dataPath); 5697 } 5698 //invoke installer to do the actual installation 5699 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 5700 pkg.applicationInfo.seinfo); 5701 if (ret < 0) { 5702 // Error from installer 5703 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5704 "Unable to create data dirs [errorCode=" + ret + "]"); 5705 } 5706 5707 if (dataPath.exists()) { 5708 pkg.applicationInfo.dataDir = dataPath.getPath(); 5709 } else { 5710 Slog.w(TAG, "Unable to create data directory: " + dataPath); 5711 pkg.applicationInfo.dataDir = null; 5712 } 5713 } 5714 5715 pkgSetting.uidError = uidError; 5716 } 5717 5718 final String path = scanFile.getPath(); 5719 final String codePath = pkg.applicationInfo.getCodePath(); 5720 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 5721 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { 5722 setBundledAppAbisAndRoots(pkg, pkgSetting); 5723 5724 // If we haven't found any native libraries for the app, check if it has 5725 // renderscript code. We'll need to force the app to 32 bit if it has 5726 // renderscript bitcode. 5727 if (pkg.applicationInfo.primaryCpuAbi == null 5728 && pkg.applicationInfo.secondaryCpuAbi == null 5729 && Build.SUPPORTED_64_BIT_ABIS.length > 0) { 5730 NativeLibraryHelper.Handle handle = null; 5731 try { 5732 handle = NativeLibraryHelper.Handle.create(scanFile); 5733 if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 5734 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 5735 } 5736 } catch (IOException ioe) { 5737 Slog.w(TAG, "Error scanning system app : " + ioe); 5738 } finally { 5739 IoUtils.closeQuietly(handle); 5740 } 5741 } 5742 5743 setNativeLibraryPaths(pkg); 5744 } else { 5745 // TODO: We can probably be smarter about this stuff. For installed apps, 5746 // we can calculate this information at install time once and for all. For 5747 // system apps, we can probably assume that this information doesn't change 5748 // after the first boot scan. As things stand, we do lots of unnecessary work. 5749 5750 // Give ourselves some initial paths; we'll come back for another 5751 // pass once we've determined ABI below. 5752 setNativeLibraryPaths(pkg); 5753 5754 final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg); 5755 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 5756 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 5757 5758 NativeLibraryHelper.Handle handle = null; 5759 try { 5760 handle = NativeLibraryHelper.Handle.create(scanFile); 5761 // TODO(multiArch): This can be null for apps that didn't go through the 5762 // usual installation process. We can calculate it again, like we 5763 // do during install time. 5764 // 5765 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 5766 // unnecessary. 5767 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 5768 5769 // Null out the abis so that they can be recalculated. 5770 pkg.applicationInfo.primaryCpuAbi = null; 5771 pkg.applicationInfo.secondaryCpuAbi = null; 5772 if (isMultiArch(pkg.applicationInfo)) { 5773 // Warn if we've set an abiOverride for multi-lib packages.. 5774 // By definition, we need to copy both 32 and 64 bit libraries for 5775 // such packages. 5776 if (pkg.cpuAbiOverride != null 5777 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 5778 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 5779 } 5780 5781 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 5782 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 5783 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 5784 if (isAsec) { 5785 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 5786 } else { 5787 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 5788 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 5789 useIsaSpecificSubdirs); 5790 } 5791 } 5792 5793 maybeThrowExceptionForMultiArchCopy( 5794 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 5795 5796 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 5797 if (isAsec) { 5798 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 5799 } else { 5800 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 5801 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 5802 useIsaSpecificSubdirs); 5803 } 5804 } 5805 5806 maybeThrowExceptionForMultiArchCopy( 5807 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 5808 5809 if (abi64 >= 0) { 5810 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 5811 } 5812 5813 if (abi32 >= 0) { 5814 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 5815 if (abi64 >= 0) { 5816 pkg.applicationInfo.secondaryCpuAbi = abi; 5817 } else { 5818 pkg.applicationInfo.primaryCpuAbi = abi; 5819 } 5820 } 5821 } else { 5822 String[] abiList = (cpuAbiOverride != null) ? 5823 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 5824 5825 // Enable gross and lame hacks for apps that are built with old 5826 // SDK tools. We must scan their APKs for renderscript bitcode and 5827 // not launch them if it's present. Don't bother checking on devices 5828 // that don't have 64 bit support. 5829 boolean needsRenderScriptOverride = false; 5830 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 5831 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 5832 abiList = Build.SUPPORTED_32_BIT_ABIS; 5833 needsRenderScriptOverride = true; 5834 } 5835 5836 final int copyRet; 5837 if (isAsec) { 5838 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 5839 } else { 5840 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 5841 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 5842 } 5843 5844 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 5845 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 5846 "Error unpackaging native libs for app, errorCode=" + copyRet); 5847 } 5848 5849 if (copyRet >= 0) { 5850 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 5851 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 5852 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 5853 } else if (needsRenderScriptOverride) { 5854 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 5855 } 5856 } 5857 } catch (IOException ioe) { 5858 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 5859 } finally { 5860 IoUtils.closeQuietly(handle); 5861 } 5862 5863 // Now that we've calculated the ABIs and determined if it's an internal app, 5864 // we will go ahead and populate the nativeLibraryPath. 5865 setNativeLibraryPaths(pkg); 5866 5867 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 5868 final int[] userIds = sUserManager.getUserIds(); 5869 synchronized (mInstallLock) { 5870 // Create a native library symlink only if we have native libraries 5871 // and if the native libraries are 32 bit libraries. We do not provide 5872 // this symlink for 64 bit libraries. 5873 if (pkg.applicationInfo.primaryCpuAbi != null && 5874 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 5875 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 5876 for (int userId : userIds) { 5877 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) { 5878 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 5879 "Failed linking native library dir (user=" + userId + ")"); 5880 } 5881 } 5882 } 5883 } 5884 } 5885 5886 // This is a special case for the "system" package, where the ABI is 5887 // dictated by the zygote configuration (and init.rc). We should keep track 5888 // of this ABI so that we can deal with "normal" applications that run under 5889 // the same UID correctly. 5890 if (mPlatformPackage == pkg) { 5891 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 5892 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 5893 } 5894 5895 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 5896 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 5897 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 5898 // Copy the derived override back to the parsed package, so that we can 5899 // update the package settings accordingly. 5900 pkg.cpuAbiOverride = cpuAbiOverride; 5901 5902 if (DEBUG_ABI_SELECTION) { 5903 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 5904 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 5905 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 5906 } 5907 5908 // Push the derived path down into PackageSettings so we know what to 5909 // clean up at uninstall time. 5910 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 5911 5912 if (DEBUG_ABI_SELECTION) { 5913 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 5914 " primary=" + pkg.applicationInfo.primaryCpuAbi + 5915 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 5916 } 5917 5918 if ((scanFlags&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 5919 // We don't do this here during boot because we can do it all 5920 // at once after scanning all existing packages. 5921 // 5922 // We also do this *before* we perform dexopt on this package, so that 5923 // we can avoid redundant dexopts, and also to make sure we've got the 5924 // code and package path correct. 5925 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 5926 pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0); 5927 } 5928 5929 if ((scanFlags & SCAN_NO_DEX) == 0) { 5930 if (performDexOptLI(pkg, null /* instruction sets */, forceDex, 5931 (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) { 5932 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 5933 } 5934 } 5935 5936 if (mFactoryTest && pkg.requestedPermissions.contains( 5937 android.Manifest.permission.FACTORY_TEST)) { 5938 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 5939 } 5940 5941 ArrayList<PackageParser.Package> clientLibPkgs = null; 5942 5943 // writer 5944 synchronized (mPackages) { 5945 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 5946 // Only system apps can add new shared libraries. 5947 if (pkg.libraryNames != null) { 5948 for (int i=0; i<pkg.libraryNames.size(); i++) { 5949 String name = pkg.libraryNames.get(i); 5950 boolean allowed = false; 5951 if (isUpdatedSystemApp(pkg)) { 5952 // New library entries can only be added through the 5953 // system image. This is important to get rid of a lot 5954 // of nasty edge cases: for example if we allowed a non- 5955 // system update of the app to add a library, then uninstalling 5956 // the update would make the library go away, and assumptions 5957 // we made such as through app install filtering would now 5958 // have allowed apps on the device which aren't compatible 5959 // with it. Better to just have the restriction here, be 5960 // conservative, and create many fewer cases that can negatively 5961 // impact the user experience. 5962 final PackageSetting sysPs = mSettings 5963 .getDisabledSystemPkgLPr(pkg.packageName); 5964 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 5965 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 5966 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 5967 allowed = true; 5968 allowed = true; 5969 break; 5970 } 5971 } 5972 } 5973 } else { 5974 allowed = true; 5975 } 5976 if (allowed) { 5977 if (!mSharedLibraries.containsKey(name)) { 5978 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 5979 } else if (!name.equals(pkg.packageName)) { 5980 Slog.w(TAG, "Package " + pkg.packageName + " library " 5981 + name + " already exists; skipping"); 5982 } 5983 } else { 5984 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 5985 + name + " that is not declared on system image; skipping"); 5986 } 5987 } 5988 if ((scanFlags&SCAN_BOOTING) == 0) { 5989 // If we are not booting, we need to update any applications 5990 // that are clients of our shared library. If we are booting, 5991 // this will all be done once the scan is complete. 5992 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 5993 } 5994 } 5995 } 5996 } 5997 5998 // We also need to dexopt any apps that are dependent on this library. Note that 5999 // if these fail, we should abort the install since installing the library will 6000 // result in some apps being broken. 6001 if (clientLibPkgs != null) { 6002 if ((scanFlags & SCAN_NO_DEX) == 0) { 6003 for (int i = 0; i < clientLibPkgs.size(); i++) { 6004 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6005 if (performDexOptLI(clientPkg, null /* instruction sets */, forceDex, 6006 (scanFlags & SCAN_DEFER_DEX) != 0, false) == DEX_OPT_FAILED) { 6007 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 6008 "scanPackageLI failed to dexopt clientLibPkgs"); 6009 } 6010 } 6011 } 6012 } 6013 6014 // Request the ActivityManager to kill the process(only for existing packages) 6015 // so that we do not end up in a confused state while the user is still using the older 6016 // version of the application while the new one gets installed. 6017 if ((scanFlags & SCAN_REPLACING) != 0) { 6018 killApplication(pkg.applicationInfo.packageName, 6019 pkg.applicationInfo.uid, "update pkg"); 6020 } 6021 6022 // Also need to kill any apps that are dependent on the library. 6023 if (clientLibPkgs != null) { 6024 for (int i=0; i<clientLibPkgs.size(); i++) { 6025 PackageParser.Package clientPkg = clientLibPkgs.get(i); 6026 killApplication(clientPkg.applicationInfo.packageName, 6027 clientPkg.applicationInfo.uid, "update lib"); 6028 } 6029 } 6030 6031 // writer 6032 synchronized (mPackages) { 6033 // We don't expect installation to fail beyond this point 6034 6035 // Add the new setting to mSettings 6036 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 6037 // Add the new setting to mPackages 6038 mPackages.put(pkg.applicationInfo.packageName, pkg); 6039 // Make sure we don't accidentally delete its data. 6040 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 6041 while (iter.hasNext()) { 6042 PackageCleanItem item = iter.next(); 6043 if (pkgName.equals(item.packageName)) { 6044 iter.remove(); 6045 } 6046 } 6047 6048 // Take care of first install / last update times. 6049 if (currentTime != 0) { 6050 if (pkgSetting.firstInstallTime == 0) { 6051 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 6052 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 6053 pkgSetting.lastUpdateTime = currentTime; 6054 } 6055 } else if (pkgSetting.firstInstallTime == 0) { 6056 // We need *something*. Take time time stamp of the file. 6057 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 6058 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 6059 if (scanFileTime != pkgSetting.timeStamp) { 6060 // A package on the system image has changed; consider this 6061 // to be an update. 6062 pkgSetting.lastUpdateTime = scanFileTime; 6063 } 6064 } 6065 6066 // Add the package's KeySets to the global KeySetManagerService 6067 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6068 try { 6069 // Old KeySetData no longer valid. 6070 ksms.removeAppKeySetDataLPw(pkg.packageName); 6071 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys); 6072 if (pkg.mKeySetMapping != null) { 6073 for (Map.Entry<String, ArraySet<PublicKey>> entry : 6074 pkg.mKeySetMapping.entrySet()) { 6075 if (entry.getValue() != null) { 6076 ksms.addDefinedKeySetToPackageLPw(pkg.packageName, 6077 entry.getValue(), entry.getKey()); 6078 } 6079 } 6080 if (pkg.mUpgradeKeySets != null) { 6081 for (String upgradeAlias : pkg.mUpgradeKeySets) { 6082 ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias); 6083 } 6084 } 6085 } 6086 } catch (NullPointerException e) { 6087 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e); 6088 } catch (IllegalArgumentException e) { 6089 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e); 6090 } 6091 6092 int N = pkg.providers.size(); 6093 StringBuilder r = null; 6094 int i; 6095 for (i=0; i<N; i++) { 6096 PackageParser.Provider p = pkg.providers.get(i); 6097 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 6098 p.info.processName, pkg.applicationInfo.uid); 6099 mProviders.addProvider(p); 6100 p.syncable = p.info.isSyncable; 6101 if (p.info.authority != null) { 6102 String names[] = p.info.authority.split(";"); 6103 p.info.authority = null; 6104 for (int j = 0; j < names.length; j++) { 6105 if (j == 1 && p.syncable) { 6106 // We only want the first authority for a provider to possibly be 6107 // syncable, so if we already added this provider using a different 6108 // authority clear the syncable flag. We copy the provider before 6109 // changing it because the mProviders object contains a reference 6110 // to a provider that we don't want to change. 6111 // Only do this for the second authority since the resulting provider 6112 // object can be the same for all future authorities for this provider. 6113 p = new PackageParser.Provider(p); 6114 p.syncable = false; 6115 } 6116 if (!mProvidersByAuthority.containsKey(names[j])) { 6117 mProvidersByAuthority.put(names[j], p); 6118 if (p.info.authority == null) { 6119 p.info.authority = names[j]; 6120 } else { 6121 p.info.authority = p.info.authority + ";" + names[j]; 6122 } 6123 if (DEBUG_PACKAGE_SCANNING) { 6124 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 6125 Log.d(TAG, "Registered content provider: " + names[j] 6126 + ", className = " + p.info.name + ", isSyncable = " 6127 + p.info.isSyncable); 6128 } 6129 } else { 6130 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 6131 Slog.w(TAG, "Skipping provider name " + names[j] + 6132 " (in package " + pkg.applicationInfo.packageName + 6133 "): name already used by " 6134 + ((other != null && other.getComponentName() != null) 6135 ? other.getComponentName().getPackageName() : "?")); 6136 } 6137 } 6138 } 6139 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6140 if (r == null) { 6141 r = new StringBuilder(256); 6142 } else { 6143 r.append(' '); 6144 } 6145 r.append(p.info.name); 6146 } 6147 } 6148 if (r != null) { 6149 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 6150 } 6151 6152 N = pkg.services.size(); 6153 r = null; 6154 for (i=0; i<N; i++) { 6155 PackageParser.Service s = pkg.services.get(i); 6156 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 6157 s.info.processName, pkg.applicationInfo.uid); 6158 mServices.addService(s); 6159 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6160 if (r == null) { 6161 r = new StringBuilder(256); 6162 } else { 6163 r.append(' '); 6164 } 6165 r.append(s.info.name); 6166 } 6167 } 6168 if (r != null) { 6169 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 6170 } 6171 6172 N = pkg.receivers.size(); 6173 r = null; 6174 for (i=0; i<N; i++) { 6175 PackageParser.Activity a = pkg.receivers.get(i); 6176 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6177 a.info.processName, pkg.applicationInfo.uid); 6178 mReceivers.addActivity(a, "receiver"); 6179 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6180 if (r == null) { 6181 r = new StringBuilder(256); 6182 } else { 6183 r.append(' '); 6184 } 6185 r.append(a.info.name); 6186 } 6187 } 6188 if (r != null) { 6189 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 6190 } 6191 6192 N = pkg.activities.size(); 6193 r = null; 6194 for (i=0; i<N; i++) { 6195 PackageParser.Activity a = pkg.activities.get(i); 6196 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 6197 a.info.processName, pkg.applicationInfo.uid); 6198 mActivities.addActivity(a, "activity"); 6199 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6200 if (r == null) { 6201 r = new StringBuilder(256); 6202 } else { 6203 r.append(' '); 6204 } 6205 r.append(a.info.name); 6206 } 6207 } 6208 if (r != null) { 6209 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 6210 } 6211 6212 N = pkg.permissionGroups.size(); 6213 r = null; 6214 for (i=0; i<N; i++) { 6215 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 6216 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 6217 if (cur == null) { 6218 mPermissionGroups.put(pg.info.name, pg); 6219 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6220 if (r == null) { 6221 r = new StringBuilder(256); 6222 } else { 6223 r.append(' '); 6224 } 6225 r.append(pg.info.name); 6226 } 6227 } else { 6228 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 6229 + pg.info.packageName + " ignored: original from " 6230 + cur.info.packageName); 6231 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6232 if (r == null) { 6233 r = new StringBuilder(256); 6234 } else { 6235 r.append(' '); 6236 } 6237 r.append("DUP:"); 6238 r.append(pg.info.name); 6239 } 6240 } 6241 } 6242 if (r != null) { 6243 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 6244 } 6245 6246 N = pkg.permissions.size(); 6247 r = null; 6248 for (i=0; i<N; i++) { 6249 PackageParser.Permission p = pkg.permissions.get(i); 6250 ArrayMap<String, BasePermission> permissionMap = 6251 p.tree ? mSettings.mPermissionTrees 6252 : mSettings.mPermissions; 6253 p.group = mPermissionGroups.get(p.info.group); 6254 if (p.info.group == null || p.group != null) { 6255 BasePermission bp = permissionMap.get(p.info.name); 6256 6257 // Allow system apps to redefine non-system permissions 6258 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 6259 final boolean currentOwnerIsSystem = (bp.perm != null 6260 && isSystemApp(bp.perm.owner)); 6261 if (isSystemApp(p.owner)) { 6262 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 6263 // It's a built-in permission and no owner, take ownership now 6264 bp.packageSetting = pkgSetting; 6265 bp.perm = p; 6266 bp.uid = pkg.applicationInfo.uid; 6267 bp.sourcePackage = p.info.packageName; 6268 } else if (!currentOwnerIsSystem) { 6269 String msg = "New decl " + p.owner + " of permission " 6270 + p.info.name + " is system; overriding " + bp.sourcePackage; 6271 reportSettingsProblem(Log.WARN, msg); 6272 bp = null; 6273 } 6274 } 6275 } 6276 6277 if (bp == null) { 6278 bp = new BasePermission(p.info.name, p.info.packageName, 6279 BasePermission.TYPE_NORMAL); 6280 permissionMap.put(p.info.name, bp); 6281 } 6282 6283 if (bp.perm == null) { 6284 if (bp.sourcePackage == null 6285 || bp.sourcePackage.equals(p.info.packageName)) { 6286 BasePermission tree = findPermissionTreeLP(p.info.name); 6287 if (tree == null 6288 || tree.sourcePackage.equals(p.info.packageName)) { 6289 bp.packageSetting = pkgSetting; 6290 bp.perm = p; 6291 bp.uid = pkg.applicationInfo.uid; 6292 bp.sourcePackage = p.info.packageName; 6293 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6294 if (r == null) { 6295 r = new StringBuilder(256); 6296 } else { 6297 r.append(' '); 6298 } 6299 r.append(p.info.name); 6300 } 6301 } else { 6302 Slog.w(TAG, "Permission " + p.info.name + " from package " 6303 + p.info.packageName + " ignored: base tree " 6304 + tree.name + " is from package " 6305 + tree.sourcePackage); 6306 } 6307 } else { 6308 Slog.w(TAG, "Permission " + p.info.name + " from package " 6309 + p.info.packageName + " ignored: original from " 6310 + bp.sourcePackage); 6311 } 6312 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6313 if (r == null) { 6314 r = new StringBuilder(256); 6315 } else { 6316 r.append(' '); 6317 } 6318 r.append("DUP:"); 6319 r.append(p.info.name); 6320 } 6321 if (bp.perm == p) { 6322 bp.protectionLevel = p.info.protectionLevel; 6323 } 6324 } else { 6325 Slog.w(TAG, "Permission " + p.info.name + " from package " 6326 + p.info.packageName + " ignored: no group " 6327 + p.group); 6328 } 6329 } 6330 if (r != null) { 6331 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 6332 } 6333 6334 N = pkg.instrumentation.size(); 6335 r = null; 6336 for (i=0; i<N; i++) { 6337 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 6338 a.info.packageName = pkg.applicationInfo.packageName; 6339 a.info.sourceDir = pkg.applicationInfo.sourceDir; 6340 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 6341 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 6342 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 6343 a.info.dataDir = pkg.applicationInfo.dataDir; 6344 6345 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 6346 // need other information about the application, like the ABI and what not ? 6347 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 6348 mInstrumentation.put(a.getComponentName(), a); 6349 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6350 if (r == null) { 6351 r = new StringBuilder(256); 6352 } else { 6353 r.append(' '); 6354 } 6355 r.append(a.info.name); 6356 } 6357 } 6358 if (r != null) { 6359 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 6360 } 6361 6362 if (pkg.protectedBroadcasts != null) { 6363 N = pkg.protectedBroadcasts.size(); 6364 for (i=0; i<N; i++) { 6365 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 6366 } 6367 } 6368 6369 pkgSetting.setTimeStamp(scanFileTime); 6370 6371 // Create idmap files for pairs of (packages, overlay packages). 6372 // Note: "android", ie framework-res.apk, is handled by native layers. 6373 if (pkg.mOverlayTarget != null) { 6374 // This is an overlay package. 6375 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 6376 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 6377 mOverlays.put(pkg.mOverlayTarget, 6378 new ArrayMap<String, PackageParser.Package>()); 6379 } 6380 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 6381 map.put(pkg.packageName, pkg); 6382 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 6383 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 6384 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6385 "scanPackageLI failed to createIdmap"); 6386 } 6387 } 6388 } else if (mOverlays.containsKey(pkg.packageName) && 6389 !pkg.packageName.equals("android")) { 6390 // This is a regular package, with one or more known overlay packages. 6391 createIdmapsForPackageLI(pkg); 6392 } 6393 } 6394 6395 return pkg; 6396 } 6397 6398 /** 6399 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 6400 * i.e, so that all packages can be run inside a single process if required. 6401 * 6402 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 6403 * this function will either try and make the ABI for all packages in {@code packagesForUser} 6404 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 6405 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 6406 * updating a package that belongs to a shared user. 6407 * 6408 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 6409 * adds unnecessary complexity. 6410 */ adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt)6411 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 6412 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { 6413 String requiredInstructionSet = null; 6414 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 6415 requiredInstructionSet = VMRuntime.getInstructionSet( 6416 scannedPackage.applicationInfo.primaryCpuAbi); 6417 } 6418 6419 PackageSetting requirer = null; 6420 for (PackageSetting ps : packagesForUser) { 6421 // If packagesForUser contains scannedPackage, we skip it. This will happen 6422 // when scannedPackage is an update of an existing package. Without this check, 6423 // we will never be able to change the ABI of any package belonging to a shared 6424 // user, even if it's compatible with other packages. 6425 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6426 if (ps.primaryCpuAbiString == null) { 6427 continue; 6428 } 6429 6430 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 6431 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 6432 // We have a mismatch between instruction sets (say arm vs arm64) warn about 6433 // this but there's not much we can do. 6434 String errorMessage = "Instruction set mismatch, " 6435 + ((requirer == null) ? "[caller]" : requirer) 6436 + " requires " + requiredInstructionSet + " whereas " + ps 6437 + " requires " + instructionSet; 6438 Slog.w(TAG, errorMessage); 6439 } 6440 6441 if (requiredInstructionSet == null) { 6442 requiredInstructionSet = instructionSet; 6443 requirer = ps; 6444 } 6445 } 6446 } 6447 6448 if (requiredInstructionSet != null) { 6449 String adjustedAbi; 6450 if (requirer != null) { 6451 // requirer != null implies that either scannedPackage was null or that scannedPackage 6452 // did not require an ABI, in which case we have to adjust scannedPackage to match 6453 // the ABI of the set (which is the same as requirer's ABI) 6454 adjustedAbi = requirer.primaryCpuAbiString; 6455 if (scannedPackage != null) { 6456 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 6457 } 6458 } else { 6459 // requirer == null implies that we're updating all ABIs in the set to 6460 // match scannedPackage. 6461 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 6462 } 6463 6464 for (PackageSetting ps : packagesForUser) { 6465 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6466 if (ps.primaryCpuAbiString != null) { 6467 continue; 6468 } 6469 6470 ps.primaryCpuAbiString = adjustedAbi; 6471 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 6472 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 6473 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 6474 6475 if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt, 6476 deferDexOpt, true) == DEX_OPT_FAILED) { 6477 ps.primaryCpuAbiString = null; 6478 ps.pkg.applicationInfo.primaryCpuAbi = null; 6479 return; 6480 } else { 6481 mInstaller.rmdex(ps.codePathString, 6482 getDexCodeInstructionSet(getPreferredInstructionSet())); 6483 } 6484 } 6485 } 6486 } 6487 } 6488 } 6489 setUpCustomResolverActivity(PackageParser.Package pkg)6490 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 6491 synchronized (mPackages) { 6492 mResolverReplaced = true; 6493 // Set up information for custom user intent resolution activity. 6494 mResolveActivity.applicationInfo = pkg.applicationInfo; 6495 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 6496 mResolveActivity.packageName = pkg.applicationInfo.packageName; 6497 mResolveActivity.processName = pkg.applicationInfo.packageName; 6498 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 6499 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 6500 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 6501 mResolveActivity.theme = 0; 6502 mResolveActivity.exported = true; 6503 mResolveActivity.enabled = true; 6504 mResolveInfo.activityInfo = mResolveActivity; 6505 mResolveInfo.priority = 0; 6506 mResolveInfo.preferredOrder = 0; 6507 mResolveInfo.match = 0; 6508 mResolveComponentName = mCustomResolverComponentName; 6509 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 6510 mResolveComponentName); 6511 } 6512 } 6513 calculateBundledApkRoot(final String codePathString)6514 private static String calculateBundledApkRoot(final String codePathString) { 6515 final File codePath = new File(codePathString); 6516 final File codeRoot; 6517 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 6518 codeRoot = Environment.getRootDirectory(); 6519 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 6520 codeRoot = Environment.getOemDirectory(); 6521 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 6522 codeRoot = Environment.getVendorDirectory(); 6523 } else { 6524 // Unrecognized code path; take its top real segment as the apk root: 6525 // e.g. /something/app/blah.apk => /something 6526 try { 6527 File f = codePath.getCanonicalFile(); 6528 File parent = f.getParentFile(); // non-null because codePath is a file 6529 File tmp; 6530 while ((tmp = parent.getParentFile()) != null) { 6531 f = parent; 6532 parent = tmp; 6533 } 6534 codeRoot = f; 6535 Slog.w(TAG, "Unrecognized code path " 6536 + codePath + " - using " + codeRoot); 6537 } catch (IOException e) { 6538 // Can't canonicalize the code path -- shenanigans? 6539 Slog.w(TAG, "Can't canonicalize code path " + codePath); 6540 return Environment.getRootDirectory().getPath(); 6541 } 6542 } 6543 return codeRoot.getPath(); 6544 } 6545 6546 /** 6547 * Derive and set the location of native libraries for the given package, 6548 * which varies depending on where and how the package was installed. 6549 */ setNativeLibraryPaths(PackageParser.Package pkg)6550 private void setNativeLibraryPaths(PackageParser.Package pkg) { 6551 final ApplicationInfo info = pkg.applicationInfo; 6552 final String codePath = pkg.codePath; 6553 final File codeFile = new File(codePath); 6554 final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info); 6555 final boolean asecApp = isForwardLocked(info) || isExternal(info); 6556 6557 info.nativeLibraryRootDir = null; 6558 info.nativeLibraryRootRequiresIsa = false; 6559 info.nativeLibraryDir = null; 6560 info.secondaryNativeLibraryDir = null; 6561 6562 if (isApkFile(codeFile)) { 6563 // Monolithic install 6564 if (bundledApp) { 6565 // If "/system/lib64/apkname" exists, assume that is the per-package 6566 // native library directory to use; otherwise use "/system/lib/apkname". 6567 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 6568 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 6569 getPrimaryInstructionSet(info)); 6570 6571 // This is a bundled system app so choose the path based on the ABI. 6572 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 6573 // is just the default path. 6574 final String apkName = deriveCodePathName(codePath); 6575 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 6576 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 6577 apkName).getAbsolutePath(); 6578 6579 if (info.secondaryCpuAbi != null) { 6580 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 6581 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 6582 secondaryLibDir, apkName).getAbsolutePath(); 6583 } 6584 } else if (asecApp) { 6585 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 6586 .getAbsolutePath(); 6587 } else { 6588 final String apkName = deriveCodePathName(codePath); 6589 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 6590 .getAbsolutePath(); 6591 } 6592 6593 info.nativeLibraryRootRequiresIsa = false; 6594 info.nativeLibraryDir = info.nativeLibraryRootDir; 6595 } else { 6596 // Cluster install 6597 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 6598 info.nativeLibraryRootRequiresIsa = true; 6599 6600 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 6601 getPrimaryInstructionSet(info)).getAbsolutePath(); 6602 6603 if (info.secondaryCpuAbi != null) { 6604 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 6605 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 6606 } 6607 } 6608 } 6609 6610 /** 6611 * Calculate the abis and roots for a bundled app. These can uniquely 6612 * be determined from the contents of the system partition, i.e whether 6613 * it contains 64 or 32 bit shared libraries etc. We do not validate any 6614 * of this information, and instead assume that the system was built 6615 * sensibly. 6616 */ setBundledAppAbisAndRoots(PackageParser.Package pkg, PackageSetting pkgSetting)6617 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 6618 PackageSetting pkgSetting) { 6619 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 6620 6621 // If "/system/lib64/apkname" exists, assume that is the per-package 6622 // native library directory to use; otherwise use "/system/lib/apkname". 6623 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 6624 setBundledAppAbi(pkg, apkRoot, apkName); 6625 // pkgSetting might be null during rescan following uninstall of updates 6626 // to a bundled app, so accommodate that possibility. The settings in 6627 // that case will be established later from the parsed package. 6628 // 6629 // If the settings aren't null, sync them up with what we've just derived. 6630 // note that apkRoot isn't stored in the package settings. 6631 if (pkgSetting != null) { 6632 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 6633 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 6634 } 6635 } 6636 6637 /** 6638 * Deduces the ABI of a bundled app and sets the relevant fields on the 6639 * parsed pkg object. 6640 * 6641 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 6642 * under which system libraries are installed. 6643 * @param apkName the name of the installed package. 6644 */ setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName)6645 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 6646 final File codeFile = new File(pkg.codePath); 6647 6648 final boolean has64BitLibs; 6649 final boolean has32BitLibs; 6650 if (isApkFile(codeFile)) { 6651 // Monolithic install 6652 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 6653 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 6654 } else { 6655 // Cluster install 6656 final File rootDir = new File(codeFile, LIB_DIR_NAME); 6657 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 6658 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 6659 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 6660 has64BitLibs = (new File(rootDir, isa)).exists(); 6661 } else { 6662 has64BitLibs = false; 6663 } 6664 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 6665 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 6666 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 6667 has32BitLibs = (new File(rootDir, isa)).exists(); 6668 } else { 6669 has32BitLibs = false; 6670 } 6671 } 6672 6673 if (has64BitLibs && !has32BitLibs) { 6674 // The package has 64 bit libs, but not 32 bit libs. Its primary 6675 // ABI should be 64 bit. We can safely assume here that the bundled 6676 // native libraries correspond to the most preferred ABI in the list. 6677 6678 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 6679 pkg.applicationInfo.secondaryCpuAbi = null; 6680 } else if (has32BitLibs && !has64BitLibs) { 6681 // The package has 32 bit libs but not 64 bit libs. Its primary 6682 // ABI should be 32 bit. 6683 6684 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6685 pkg.applicationInfo.secondaryCpuAbi = null; 6686 } else if (has32BitLibs && has64BitLibs) { 6687 // The application has both 64 and 32 bit bundled libraries. We check 6688 // here that the app declares multiArch support, and warn if it doesn't. 6689 // 6690 // We will be lenient here and record both ABIs. The primary will be the 6691 // ABI that's higher on the list, i.e, a device that's configured to prefer 6692 // 64 bit apps will see a 64 bit primary ABI, 6693 6694 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 6695 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 6696 } 6697 6698 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 6699 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 6700 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6701 } else { 6702 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6703 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 6704 } 6705 } else { 6706 pkg.applicationInfo.primaryCpuAbi = null; 6707 pkg.applicationInfo.secondaryCpuAbi = null; 6708 } 6709 } 6710 killApplication(String pkgName, int appId, String reason)6711 private void killApplication(String pkgName, int appId, String reason) { 6712 // Request the ActivityManager to kill the process(only for existing packages) 6713 // so that we do not end up in a confused state while the user is still using the older 6714 // version of the application while the new one gets installed. 6715 IActivityManager am = ActivityManagerNative.getDefault(); 6716 if (am != null) { 6717 try { 6718 am.killApplicationWithAppId(pkgName, appId, reason); 6719 } catch (RemoteException e) { 6720 } 6721 } 6722 } 6723 removePackageLI(PackageSetting ps, boolean chatty)6724 void removePackageLI(PackageSetting ps, boolean chatty) { 6725 if (DEBUG_INSTALL) { 6726 if (chatty) 6727 Log.d(TAG, "Removing package " + ps.name); 6728 } 6729 6730 // writer 6731 synchronized (mPackages) { 6732 mPackages.remove(ps.name); 6733 final PackageParser.Package pkg = ps.pkg; 6734 if (pkg != null) { 6735 cleanPackageDataStructuresLILPw(pkg, chatty); 6736 } 6737 } 6738 } 6739 removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)6740 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 6741 if (DEBUG_INSTALL) { 6742 if (chatty) 6743 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 6744 } 6745 6746 // writer 6747 synchronized (mPackages) { 6748 mPackages.remove(pkg.applicationInfo.packageName); 6749 cleanPackageDataStructuresLILPw(pkg, chatty); 6750 } 6751 } 6752 cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)6753 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 6754 int N = pkg.providers.size(); 6755 StringBuilder r = null; 6756 int i; 6757 for (i=0; i<N; i++) { 6758 PackageParser.Provider p = pkg.providers.get(i); 6759 mProviders.removeProvider(p); 6760 if (p.info.authority == null) { 6761 6762 /* There was another ContentProvider with this authority when 6763 * this app was installed so this authority is null, 6764 * Ignore it as we don't have to unregister the provider. 6765 */ 6766 continue; 6767 } 6768 String names[] = p.info.authority.split(";"); 6769 for (int j = 0; j < names.length; j++) { 6770 if (mProvidersByAuthority.get(names[j]) == p) { 6771 mProvidersByAuthority.remove(names[j]); 6772 if (DEBUG_REMOVE) { 6773 if (chatty) 6774 Log.d(TAG, "Unregistered content provider: " + names[j] 6775 + ", className = " + p.info.name + ", isSyncable = " 6776 + p.info.isSyncable); 6777 } 6778 } 6779 } 6780 if (DEBUG_REMOVE && chatty) { 6781 if (r == null) { 6782 r = new StringBuilder(256); 6783 } else { 6784 r.append(' '); 6785 } 6786 r.append(p.info.name); 6787 } 6788 } 6789 if (r != null) { 6790 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 6791 } 6792 6793 N = pkg.services.size(); 6794 r = null; 6795 for (i=0; i<N; i++) { 6796 PackageParser.Service s = pkg.services.get(i); 6797 mServices.removeService(s); 6798 if (chatty) { 6799 if (r == null) { 6800 r = new StringBuilder(256); 6801 } else { 6802 r.append(' '); 6803 } 6804 r.append(s.info.name); 6805 } 6806 } 6807 if (r != null) { 6808 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 6809 } 6810 6811 N = pkg.receivers.size(); 6812 r = null; 6813 for (i=0; i<N; i++) { 6814 PackageParser.Activity a = pkg.receivers.get(i); 6815 mReceivers.removeActivity(a, "receiver"); 6816 if (DEBUG_REMOVE && chatty) { 6817 if (r == null) { 6818 r = new StringBuilder(256); 6819 } else { 6820 r.append(' '); 6821 } 6822 r.append(a.info.name); 6823 } 6824 } 6825 if (r != null) { 6826 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 6827 } 6828 6829 N = pkg.activities.size(); 6830 r = null; 6831 for (i=0; i<N; i++) { 6832 PackageParser.Activity a = pkg.activities.get(i); 6833 mActivities.removeActivity(a, "activity"); 6834 if (DEBUG_REMOVE && chatty) { 6835 if (r == null) { 6836 r = new StringBuilder(256); 6837 } else { 6838 r.append(' '); 6839 } 6840 r.append(a.info.name); 6841 } 6842 } 6843 if (r != null) { 6844 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 6845 } 6846 6847 N = pkg.permissions.size(); 6848 r = null; 6849 for (i=0; i<N; i++) { 6850 PackageParser.Permission p = pkg.permissions.get(i); 6851 BasePermission bp = mSettings.mPermissions.get(p.info.name); 6852 if (bp == null) { 6853 bp = mSettings.mPermissionTrees.get(p.info.name); 6854 } 6855 if (bp != null && bp.perm == p) { 6856 bp.perm = null; 6857 if (DEBUG_REMOVE && chatty) { 6858 if (r == null) { 6859 r = new StringBuilder(256); 6860 } else { 6861 r.append(' '); 6862 } 6863 r.append(p.info.name); 6864 } 6865 } 6866 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 6867 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 6868 if (appOpPerms != null) { 6869 appOpPerms.remove(pkg.packageName); 6870 } 6871 } 6872 } 6873 if (r != null) { 6874 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 6875 } 6876 6877 N = pkg.requestedPermissions.size(); 6878 r = null; 6879 for (i=0; i<N; i++) { 6880 String perm = pkg.requestedPermissions.get(i); 6881 BasePermission bp = mSettings.mPermissions.get(perm); 6882 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 6883 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 6884 if (appOpPerms != null) { 6885 appOpPerms.remove(pkg.packageName); 6886 if (appOpPerms.isEmpty()) { 6887 mAppOpPermissionPackages.remove(perm); 6888 } 6889 } 6890 } 6891 } 6892 if (r != null) { 6893 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 6894 } 6895 6896 N = pkg.instrumentation.size(); 6897 r = null; 6898 for (i=0; i<N; i++) { 6899 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 6900 mInstrumentation.remove(a.getComponentName()); 6901 if (DEBUG_REMOVE && chatty) { 6902 if (r == null) { 6903 r = new StringBuilder(256); 6904 } else { 6905 r.append(' '); 6906 } 6907 r.append(a.info.name); 6908 } 6909 } 6910 if (r != null) { 6911 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 6912 } 6913 6914 r = null; 6915 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6916 // Only system apps can hold shared libraries. 6917 if (pkg.libraryNames != null) { 6918 for (i=0; i<pkg.libraryNames.size(); i++) { 6919 String name = pkg.libraryNames.get(i); 6920 SharedLibraryEntry cur = mSharedLibraries.get(name); 6921 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 6922 mSharedLibraries.remove(name); 6923 if (DEBUG_REMOVE && chatty) { 6924 if (r == null) { 6925 r = new StringBuilder(256); 6926 } else { 6927 r.append(' '); 6928 } 6929 r.append(name); 6930 } 6931 } 6932 } 6933 } 6934 } 6935 if (r != null) { 6936 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 6937 } 6938 } 6939 hasPermission(PackageParser.Package pkgInfo, String perm)6940 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 6941 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 6942 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 6943 return true; 6944 } 6945 } 6946 return false; 6947 } 6948 6949 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 6950 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 6951 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 6952 updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags)6953 private void updatePermissionsLPw(String changingPkg, 6954 PackageParser.Package pkgInfo, int flags) { 6955 // Make sure there are no dangling permission trees. 6956 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 6957 while (it.hasNext()) { 6958 final BasePermission bp = it.next(); 6959 if (bp.packageSetting == null) { 6960 // We may not yet have parsed the package, so just see if 6961 // we still know about its settings. 6962 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 6963 } 6964 if (bp.packageSetting == null) { 6965 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 6966 + " from package " + bp.sourcePackage); 6967 it.remove(); 6968 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 6969 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 6970 Slog.i(TAG, "Removing old permission tree: " + bp.name 6971 + " from package " + bp.sourcePackage); 6972 flags |= UPDATE_PERMISSIONS_ALL; 6973 it.remove(); 6974 } 6975 } 6976 } 6977 6978 // Make sure all dynamic permissions have been assigned to a package, 6979 // and make sure there are no dangling permissions. 6980 it = mSettings.mPermissions.values().iterator(); 6981 while (it.hasNext()) { 6982 final BasePermission bp = it.next(); 6983 if (bp.type == BasePermission.TYPE_DYNAMIC) { 6984 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 6985 + bp.name + " pkg=" + bp.sourcePackage 6986 + " info=" + bp.pendingInfo); 6987 if (bp.packageSetting == null && bp.pendingInfo != null) { 6988 final BasePermission tree = findPermissionTreeLP(bp.name); 6989 if (tree != null && tree.perm != null) { 6990 bp.packageSetting = tree.packageSetting; 6991 bp.perm = new PackageParser.Permission(tree.perm.owner, 6992 new PermissionInfo(bp.pendingInfo)); 6993 bp.perm.info.packageName = tree.perm.info.packageName; 6994 bp.perm.info.name = bp.name; 6995 bp.uid = tree.uid; 6996 } 6997 } 6998 } 6999 if (bp.packageSetting == null) { 7000 // We may not yet have parsed the package, so just see if 7001 // we still know about its settings. 7002 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 7003 } 7004 if (bp.packageSetting == null) { 7005 Slog.w(TAG, "Removing dangling permission: " + bp.name 7006 + " from package " + bp.sourcePackage); 7007 it.remove(); 7008 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 7009 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 7010 Slog.i(TAG, "Removing old permission: " + bp.name 7011 + " from package " + bp.sourcePackage); 7012 flags |= UPDATE_PERMISSIONS_ALL; 7013 it.remove(); 7014 } 7015 } 7016 } 7017 7018 // Now update the permissions for all packages, in particular 7019 // replace the granted permissions of the system packages. 7020 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 7021 for (PackageParser.Package pkg : mPackages.values()) { 7022 if (pkg != pkgInfo) { 7023 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0, 7024 changingPkg); 7025 } 7026 } 7027 } 7028 7029 if (pkgInfo != null) { 7030 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0, changingPkg); 7031 } 7032 } 7033 grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest)7034 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 7035 String packageOfInterest) { 7036 final PackageSetting ps = (PackageSetting) pkg.mExtras; 7037 if (ps == null) { 7038 return; 7039 } 7040 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 7041 ArraySet<String> origPermissions = gp.grantedPermissions; 7042 boolean changedPermission = false; 7043 7044 if (replace) { 7045 ps.permissionsFixed = false; 7046 if (gp == ps) { 7047 origPermissions = new ArraySet<String>(gp.grantedPermissions); 7048 gp.grantedPermissions.clear(); 7049 gp.gids = mGlobalGids; 7050 } 7051 } 7052 7053 if (gp.gids == null) { 7054 gp.gids = mGlobalGids; 7055 } 7056 7057 final int N = pkg.requestedPermissions.size(); 7058 for (int i=0; i<N; i++) { 7059 final String name = pkg.requestedPermissions.get(i); 7060 final boolean required = pkg.requestedPermissionsRequired.get(i); 7061 final BasePermission bp = mSettings.mPermissions.get(name); 7062 if (DEBUG_INSTALL) { 7063 if (gp != ps) { 7064 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 7065 } 7066 } 7067 7068 if (bp == null || bp.packageSetting == null) { 7069 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7070 Slog.w(TAG, "Unknown permission " + name 7071 + " in package " + pkg.packageName); 7072 } 7073 continue; 7074 } 7075 7076 final String perm = bp.name; 7077 boolean allowed; 7078 boolean allowedSig = false; 7079 if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 7080 // Keep track of app op permissions. 7081 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 7082 if (pkgs == null) { 7083 pkgs = new ArraySet<>(); 7084 mAppOpPermissionPackages.put(bp.name, pkgs); 7085 } 7086 pkgs.add(pkg.packageName); 7087 } 7088 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 7089 if (level == PermissionInfo.PROTECTION_NORMAL 7090 || level == PermissionInfo.PROTECTION_DANGEROUS) { 7091 // We grant a normal or dangerous permission if any of the following 7092 // are true: 7093 // 1) The permission is required 7094 // 2) The permission is optional, but was granted in the past 7095 // 3) The permission is optional, but was requested by an 7096 // app in /system (not /data) 7097 // 7098 // Otherwise, reject the permission. 7099 allowed = (required || origPermissions.contains(perm) 7100 || (isSystemApp(ps) && !isUpdatedSystemApp(ps))); 7101 } else if (bp.packageSetting == null) { 7102 // This permission is invalid; skip it. 7103 allowed = false; 7104 } else if (level == PermissionInfo.PROTECTION_SIGNATURE) { 7105 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions); 7106 if (allowed) { 7107 allowedSig = true; 7108 } 7109 } else { 7110 allowed = false; 7111 } 7112 if (DEBUG_INSTALL) { 7113 if (gp != ps) { 7114 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 7115 } 7116 } 7117 if (allowed) { 7118 if (!isSystemApp(ps) && ps.permissionsFixed) { 7119 // If this is an existing, non-system package, then 7120 // we can't add any new permissions to it. 7121 if (!allowedSig && !gp.grantedPermissions.contains(perm)) { 7122 // Except... if this is a permission that was added 7123 // to the platform (note: need to only do this when 7124 // updating the platform). 7125 allowed = isNewPlatformPermissionForPackage(perm, pkg); 7126 } 7127 } 7128 if (allowed) { 7129 if (!gp.grantedPermissions.contains(perm)) { 7130 changedPermission = true; 7131 gp.grantedPermissions.add(perm); 7132 gp.gids = appendInts(gp.gids, bp.gids); 7133 } else if (!ps.haveGids) { 7134 gp.gids = appendInts(gp.gids, bp.gids); 7135 } 7136 } else { 7137 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7138 Slog.w(TAG, "Not granting permission " + perm 7139 + " to package " + pkg.packageName 7140 + " because it was previously installed without"); 7141 } 7142 } 7143 } else { 7144 if (gp.grantedPermissions.remove(perm)) { 7145 changedPermission = true; 7146 gp.gids = removeInts(gp.gids, bp.gids); 7147 Slog.i(TAG, "Un-granting permission " + perm 7148 + " from package " + pkg.packageName 7149 + " (protectionLevel=" + bp.protectionLevel 7150 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7151 + ")"); 7152 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 7153 // Don't print warning for app op permissions, since it is fine for them 7154 // not to be granted, there is a UI for the user to decide. 7155 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 7156 Slog.w(TAG, "Not granting permission " + perm 7157 + " to package " + pkg.packageName 7158 + " (protectionLevel=" + bp.protectionLevel 7159 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 7160 + ")"); 7161 } 7162 } 7163 } 7164 } 7165 7166 if ((changedPermission || replace) && !ps.permissionsFixed && 7167 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 7168 // This is the first that we have heard about this package, so the 7169 // permissions we have now selected are fixed until explicitly 7170 // changed. 7171 ps.permissionsFixed = true; 7172 } 7173 ps.haveGids = true; 7174 } 7175 isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)7176 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 7177 boolean allowed = false; 7178 final int NP = PackageParser.NEW_PERMISSIONS.length; 7179 for (int ip=0; ip<NP; ip++) { 7180 final PackageParser.NewPermissionInfo npi 7181 = PackageParser.NEW_PERMISSIONS[ip]; 7182 if (npi.name.equals(perm) 7183 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 7184 allowed = true; 7185 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 7186 + pkg.packageName); 7187 break; 7188 } 7189 } 7190 return allowed; 7191 } 7192 grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, ArraySet<String> origPermissions)7193 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 7194 BasePermission bp, ArraySet<String> origPermissions) { 7195 boolean allowed; 7196 allowed = (compareSignatures( 7197 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 7198 == PackageManager.SIGNATURE_MATCH) 7199 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 7200 == PackageManager.SIGNATURE_MATCH); 7201 if (!allowed && (bp.protectionLevel 7202 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) { 7203 if (isSystemApp(pkg)) { 7204 // For updated system applications, a system permission 7205 // is granted only if it had been defined by the original application. 7206 if (isUpdatedSystemApp(pkg)) { 7207 final PackageSetting sysPs = mSettings 7208 .getDisabledSystemPkgLPr(pkg.packageName); 7209 final GrantedPermissions origGp = sysPs.sharedUser != null 7210 ? sysPs.sharedUser : sysPs; 7211 7212 if (origGp.grantedPermissions.contains(perm)) { 7213 // If the original was granted this permission, we take 7214 // that grant decision as read and propagate it to the 7215 // update. 7216 if (sysPs.isPrivileged()) { 7217 allowed = true; 7218 } 7219 } else { 7220 // The system apk may have been updated with an older 7221 // version of the one on the data partition, but which 7222 // granted a new system permission that it didn't have 7223 // before. In this case we do want to allow the app to 7224 // now get the new permission if the ancestral apk is 7225 // privileged to get it. 7226 if (sysPs.pkg != null && sysPs.isPrivileged()) { 7227 for (int j=0; 7228 j<sysPs.pkg.requestedPermissions.size(); j++) { 7229 if (perm.equals( 7230 sysPs.pkg.requestedPermissions.get(j))) { 7231 allowed = true; 7232 break; 7233 } 7234 } 7235 } 7236 } 7237 } else { 7238 allowed = isPrivilegedApp(pkg); 7239 } 7240 } 7241 } 7242 if (!allowed && (bp.protectionLevel 7243 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 7244 // For development permissions, a development permission 7245 // is granted only if it was already granted. 7246 allowed = origPermissions.contains(perm); 7247 } 7248 return allowed; 7249 } 7250 7251 final class ActivityIntentResolver 7252 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)7253 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7254 boolean defaultOnly, int userId) { 7255 if (!sUserManager.exists(userId)) return null; 7256 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7257 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7258 } 7259 queryIntent(Intent intent, String resolvedType, int flags, int userId)7260 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7261 int userId) { 7262 if (!sUserManager.exists(userId)) return null; 7263 mFlags = flags; 7264 return super.queryIntent(intent, resolvedType, 7265 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7266 } 7267 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities, int userId)7268 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7269 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 7270 if (!sUserManager.exists(userId)) return null; 7271 if (packageActivities == null) { 7272 return null; 7273 } 7274 mFlags = flags; 7275 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 7276 final int N = packageActivities.size(); 7277 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 7278 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 7279 7280 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 7281 for (int i = 0; i < N; ++i) { 7282 intentFilters = packageActivities.get(i).intents; 7283 if (intentFilters != null && intentFilters.size() > 0) { 7284 PackageParser.ActivityIntentInfo[] array = 7285 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 7286 intentFilters.toArray(array); 7287 listCut.add(array); 7288 } 7289 } 7290 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7291 } 7292 addActivity(PackageParser.Activity a, String type)7293 public final void addActivity(PackageParser.Activity a, String type) { 7294 final boolean systemApp = isSystemApp(a.info.applicationInfo); 7295 mActivities.put(a.getComponentName(), a); 7296 if (DEBUG_SHOW_INFO) 7297 Log.v( 7298 TAG, " " + type + " " + 7299 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 7300 if (DEBUG_SHOW_INFO) 7301 Log.v(TAG, " Class=" + a.info.name); 7302 final int NI = a.intents.size(); 7303 for (int j=0; j<NI; j++) { 7304 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7305 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 7306 intent.setPriority(0); 7307 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 7308 + a.className + " with priority > 0, forcing to 0"); 7309 } 7310 if (DEBUG_SHOW_INFO) { 7311 Log.v(TAG, " IntentFilter:"); 7312 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7313 } 7314 if (!intent.debugCheck()) { 7315 Log.w(TAG, "==> For Activity " + a.info.name); 7316 } 7317 addFilter(intent); 7318 } 7319 } 7320 removeActivity(PackageParser.Activity a, String type)7321 public final void removeActivity(PackageParser.Activity a, String type) { 7322 mActivities.remove(a.getComponentName()); 7323 if (DEBUG_SHOW_INFO) { 7324 Log.v(TAG, " " + type + " " 7325 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 7326 : a.info.name) + ":"); 7327 Log.v(TAG, " Class=" + a.info.name); 7328 } 7329 final int NI = a.intents.size(); 7330 for (int j=0; j<NI; j++) { 7331 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7332 if (DEBUG_SHOW_INFO) { 7333 Log.v(TAG, " IntentFilter:"); 7334 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7335 } 7336 removeFilter(intent); 7337 } 7338 } 7339 7340 @Override allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)7341 protected boolean allowFilterResult( 7342 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 7343 ActivityInfo filterAi = filter.activity.info; 7344 for (int i=dest.size()-1; i>=0; i--) { 7345 ActivityInfo destAi = dest.get(i).activityInfo; 7346 if (destAi.name == filterAi.name 7347 && destAi.packageName == filterAi.packageName) { 7348 return false; 7349 } 7350 } 7351 return true; 7352 } 7353 7354 @Override newArray(int size)7355 protected ActivityIntentInfo[] newArray(int size) { 7356 return new ActivityIntentInfo[size]; 7357 } 7358 7359 @Override isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)7360 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 7361 if (!sUserManager.exists(userId)) return true; 7362 PackageParser.Package p = filter.activity.owner; 7363 if (p != null) { 7364 PackageSetting ps = (PackageSetting)p.mExtras; 7365 if (ps != null) { 7366 // System apps are never considered stopped for purposes of 7367 // filtering, because there may be no way for the user to 7368 // actually re-launch them. 7369 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 7370 && ps.getStopped(userId); 7371 } 7372 } 7373 return false; 7374 } 7375 7376 @Override isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)7377 protected boolean isPackageForFilter(String packageName, 7378 PackageParser.ActivityIntentInfo info) { 7379 return packageName.equals(info.activity.owner.packageName); 7380 } 7381 7382 @Override newResult(PackageParser.ActivityIntentInfo info, int match, int userId)7383 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 7384 int match, int userId) { 7385 if (!sUserManager.exists(userId)) return null; 7386 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 7387 return null; 7388 } 7389 final PackageParser.Activity activity = info.activity; 7390 if (mSafeMode && (activity.info.applicationInfo.flags 7391 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7392 return null; 7393 } 7394 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 7395 if (ps == null) { 7396 return null; 7397 } 7398 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 7399 ps.readUserState(userId), userId); 7400 if (ai == null) { 7401 return null; 7402 } 7403 final ResolveInfo res = new ResolveInfo(); 7404 res.activityInfo = ai; 7405 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 7406 res.filter = info; 7407 } 7408 res.priority = info.getPriority(); 7409 res.preferredOrder = activity.owner.mPreferredOrder; 7410 //System.out.println("Result: " + res.activityInfo.className + 7411 // " = " + res.priority); 7412 res.match = match; 7413 res.isDefault = info.hasDefault; 7414 res.labelRes = info.labelRes; 7415 res.nonLocalizedLabel = info.nonLocalizedLabel; 7416 if (userNeedsBadging(userId)) { 7417 res.noResourceId = true; 7418 } else { 7419 res.icon = info.icon; 7420 } 7421 res.system = isSystemApp(res.activityInfo.applicationInfo); 7422 return res; 7423 } 7424 7425 @Override sortResults(List<ResolveInfo> results)7426 protected void sortResults(List<ResolveInfo> results) { 7427 Collections.sort(results, mResolvePrioritySorter); 7428 } 7429 7430 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)7431 protected void dumpFilter(PrintWriter out, String prefix, 7432 PackageParser.ActivityIntentInfo filter) { 7433 out.print(prefix); out.print( 7434 Integer.toHexString(System.identityHashCode(filter.activity))); 7435 out.print(' '); 7436 filter.activity.printComponentShortName(out); 7437 out.print(" filter "); 7438 out.println(Integer.toHexString(System.identityHashCode(filter))); 7439 } 7440 7441 @Override filterToLabel(PackageParser.ActivityIntentInfo filter)7442 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 7443 return filter.activity; 7444 } 7445 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)7446 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 7447 PackageParser.Activity activity = (PackageParser.Activity)label; 7448 out.print(prefix); out.print( 7449 Integer.toHexString(System.identityHashCode(activity))); 7450 out.print(' '); 7451 activity.printComponentShortName(out); 7452 if (count > 1) { 7453 out.print(" ("); out.print(count); out.print(" filters)"); 7454 } 7455 out.println(); 7456 } 7457 7458 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 7459 // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 7460 // final List<ResolveInfo> retList = Lists.newArrayList(); 7461 // while (i.hasNext()) { 7462 // final ResolveInfo resolveInfo = i.next(); 7463 // if (isEnabledLP(resolveInfo.activityInfo)) { 7464 // retList.add(resolveInfo); 7465 // } 7466 // } 7467 // return retList; 7468 // } 7469 7470 // Keys are String (activity class name), values are Activity. 7471 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 7472 = new ArrayMap<ComponentName, PackageParser.Activity>(); 7473 private int mFlags; 7474 } 7475 7476 private final class ServiceIntentResolver 7477 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)7478 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7479 boolean defaultOnly, int userId) { 7480 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7481 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7482 } 7483 queryIntent(Intent intent, String resolvedType, int flags, int userId)7484 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7485 int userId) { 7486 if (!sUserManager.exists(userId)) return null; 7487 mFlags = flags; 7488 return super.queryIntent(intent, resolvedType, 7489 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7490 } 7491 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices, int userId)7492 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7493 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 7494 if (!sUserManager.exists(userId)) return null; 7495 if (packageServices == null) { 7496 return null; 7497 } 7498 mFlags = flags; 7499 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 7500 final int N = packageServices.size(); 7501 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 7502 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 7503 7504 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 7505 for (int i = 0; i < N; ++i) { 7506 intentFilters = packageServices.get(i).intents; 7507 if (intentFilters != null && intentFilters.size() > 0) { 7508 PackageParser.ServiceIntentInfo[] array = 7509 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 7510 intentFilters.toArray(array); 7511 listCut.add(array); 7512 } 7513 } 7514 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7515 } 7516 addService(PackageParser.Service s)7517 public final void addService(PackageParser.Service s) { 7518 mServices.put(s.getComponentName(), s); 7519 if (DEBUG_SHOW_INFO) { 7520 Log.v(TAG, " " 7521 + (s.info.nonLocalizedLabel != null 7522 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 7523 Log.v(TAG, " Class=" + s.info.name); 7524 } 7525 final int NI = s.intents.size(); 7526 int j; 7527 for (j=0; j<NI; j++) { 7528 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 7529 if (DEBUG_SHOW_INFO) { 7530 Log.v(TAG, " IntentFilter:"); 7531 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7532 } 7533 if (!intent.debugCheck()) { 7534 Log.w(TAG, "==> For Service " + s.info.name); 7535 } 7536 addFilter(intent); 7537 } 7538 } 7539 removeService(PackageParser.Service s)7540 public final void removeService(PackageParser.Service s) { 7541 mServices.remove(s.getComponentName()); 7542 if (DEBUG_SHOW_INFO) { 7543 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 7544 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 7545 Log.v(TAG, " Class=" + s.info.name); 7546 } 7547 final int NI = s.intents.size(); 7548 int j; 7549 for (j=0; j<NI; j++) { 7550 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 7551 if (DEBUG_SHOW_INFO) { 7552 Log.v(TAG, " IntentFilter:"); 7553 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7554 } 7555 removeFilter(intent); 7556 } 7557 } 7558 7559 @Override allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)7560 protected boolean allowFilterResult( 7561 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 7562 ServiceInfo filterSi = filter.service.info; 7563 for (int i=dest.size()-1; i>=0; i--) { 7564 ServiceInfo destAi = dest.get(i).serviceInfo; 7565 if (destAi.name == filterSi.name 7566 && destAi.packageName == filterSi.packageName) { 7567 return false; 7568 } 7569 } 7570 return true; 7571 } 7572 7573 @Override newArray(int size)7574 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 7575 return new PackageParser.ServiceIntentInfo[size]; 7576 } 7577 7578 @Override isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)7579 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 7580 if (!sUserManager.exists(userId)) return true; 7581 PackageParser.Package p = filter.service.owner; 7582 if (p != null) { 7583 PackageSetting ps = (PackageSetting)p.mExtras; 7584 if (ps != null) { 7585 // System apps are never considered stopped for purposes of 7586 // filtering, because there may be no way for the user to 7587 // actually re-launch them. 7588 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 7589 && ps.getStopped(userId); 7590 } 7591 } 7592 return false; 7593 } 7594 7595 @Override isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)7596 protected boolean isPackageForFilter(String packageName, 7597 PackageParser.ServiceIntentInfo info) { 7598 return packageName.equals(info.service.owner.packageName); 7599 } 7600 7601 @Override newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)7602 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 7603 int match, int userId) { 7604 if (!sUserManager.exists(userId)) return null; 7605 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 7606 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 7607 return null; 7608 } 7609 final PackageParser.Service service = info.service; 7610 if (mSafeMode && (service.info.applicationInfo.flags 7611 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7612 return null; 7613 } 7614 PackageSetting ps = (PackageSetting) service.owner.mExtras; 7615 if (ps == null) { 7616 return null; 7617 } 7618 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 7619 ps.readUserState(userId), userId); 7620 if (si == null) { 7621 return null; 7622 } 7623 final ResolveInfo res = new ResolveInfo(); 7624 res.serviceInfo = si; 7625 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 7626 res.filter = filter; 7627 } 7628 res.priority = info.getPriority(); 7629 res.preferredOrder = service.owner.mPreferredOrder; 7630 //System.out.println("Result: " + res.activityInfo.className + 7631 // " = " + res.priority); 7632 res.match = match; 7633 res.isDefault = info.hasDefault; 7634 res.labelRes = info.labelRes; 7635 res.nonLocalizedLabel = info.nonLocalizedLabel; 7636 res.icon = info.icon; 7637 res.system = isSystemApp(res.serviceInfo.applicationInfo); 7638 return res; 7639 } 7640 7641 @Override sortResults(List<ResolveInfo> results)7642 protected void sortResults(List<ResolveInfo> results) { 7643 Collections.sort(results, mResolvePrioritySorter); 7644 } 7645 7646 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)7647 protected void dumpFilter(PrintWriter out, String prefix, 7648 PackageParser.ServiceIntentInfo filter) { 7649 out.print(prefix); out.print( 7650 Integer.toHexString(System.identityHashCode(filter.service))); 7651 out.print(' '); 7652 filter.service.printComponentShortName(out); 7653 out.print(" filter "); 7654 out.println(Integer.toHexString(System.identityHashCode(filter))); 7655 } 7656 7657 @Override filterToLabel(PackageParser.ServiceIntentInfo filter)7658 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 7659 return filter.service; 7660 } 7661 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)7662 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 7663 PackageParser.Service service = (PackageParser.Service)label; 7664 out.print(prefix); out.print( 7665 Integer.toHexString(System.identityHashCode(service))); 7666 out.print(' '); 7667 service.printComponentShortName(out); 7668 if (count > 1) { 7669 out.print(" ("); out.print(count); out.print(" filters)"); 7670 } 7671 out.println(); 7672 } 7673 7674 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 7675 // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 7676 // final List<ResolveInfo> retList = Lists.newArrayList(); 7677 // while (i.hasNext()) { 7678 // final ResolveInfo resolveInfo = (ResolveInfo) i; 7679 // if (isEnabledLP(resolveInfo.serviceInfo)) { 7680 // retList.add(resolveInfo); 7681 // } 7682 // } 7683 // return retList; 7684 // } 7685 7686 // Keys are String (activity class name), values are Activity. 7687 private final ArrayMap<ComponentName, PackageParser.Service> mServices 7688 = new ArrayMap<ComponentName, PackageParser.Service>(); 7689 private int mFlags; 7690 }; 7691 7692 private final class ProviderIntentResolver 7693 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)7694 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7695 boolean defaultOnly, int userId) { 7696 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7697 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7698 } 7699 queryIntent(Intent intent, String resolvedType, int flags, int userId)7700 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7701 int userId) { 7702 if (!sUserManager.exists(userId)) 7703 return null; 7704 mFlags = flags; 7705 return super.queryIntent(intent, resolvedType, 7706 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7707 } 7708 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Provider> packageProviders, int userId)7709 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7710 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 7711 if (!sUserManager.exists(userId)) 7712 return null; 7713 if (packageProviders == null) { 7714 return null; 7715 } 7716 mFlags = flags; 7717 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 7718 final int N = packageProviders.size(); 7719 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 7720 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 7721 7722 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 7723 for (int i = 0; i < N; ++i) { 7724 intentFilters = packageProviders.get(i).intents; 7725 if (intentFilters != null && intentFilters.size() > 0) { 7726 PackageParser.ProviderIntentInfo[] array = 7727 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 7728 intentFilters.toArray(array); 7729 listCut.add(array); 7730 } 7731 } 7732 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7733 } 7734 addProvider(PackageParser.Provider p)7735 public final void addProvider(PackageParser.Provider p) { 7736 if (mProviders.containsKey(p.getComponentName())) { 7737 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 7738 return; 7739 } 7740 7741 mProviders.put(p.getComponentName(), p); 7742 if (DEBUG_SHOW_INFO) { 7743 Log.v(TAG, " " 7744 + (p.info.nonLocalizedLabel != null 7745 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 7746 Log.v(TAG, " Class=" + p.info.name); 7747 } 7748 final int NI = p.intents.size(); 7749 int j; 7750 for (j = 0; j < NI; j++) { 7751 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 7752 if (DEBUG_SHOW_INFO) { 7753 Log.v(TAG, " IntentFilter:"); 7754 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7755 } 7756 if (!intent.debugCheck()) { 7757 Log.w(TAG, "==> For Provider " + p.info.name); 7758 } 7759 addFilter(intent); 7760 } 7761 } 7762 removeProvider(PackageParser.Provider p)7763 public final void removeProvider(PackageParser.Provider p) { 7764 mProviders.remove(p.getComponentName()); 7765 if (DEBUG_SHOW_INFO) { 7766 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 7767 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 7768 Log.v(TAG, " Class=" + p.info.name); 7769 } 7770 final int NI = p.intents.size(); 7771 int j; 7772 for (j = 0; j < NI; j++) { 7773 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 7774 if (DEBUG_SHOW_INFO) { 7775 Log.v(TAG, " IntentFilter:"); 7776 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7777 } 7778 removeFilter(intent); 7779 } 7780 } 7781 7782 @Override allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)7783 protected boolean allowFilterResult( 7784 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 7785 ProviderInfo filterPi = filter.provider.info; 7786 for (int i = dest.size() - 1; i >= 0; i--) { 7787 ProviderInfo destPi = dest.get(i).providerInfo; 7788 if (destPi.name == filterPi.name 7789 && destPi.packageName == filterPi.packageName) { 7790 return false; 7791 } 7792 } 7793 return true; 7794 } 7795 7796 @Override newArray(int size)7797 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 7798 return new PackageParser.ProviderIntentInfo[size]; 7799 } 7800 7801 @Override isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)7802 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 7803 if (!sUserManager.exists(userId)) 7804 return true; 7805 PackageParser.Package p = filter.provider.owner; 7806 if (p != null) { 7807 PackageSetting ps = (PackageSetting) p.mExtras; 7808 if (ps != null) { 7809 // System apps are never considered stopped for purposes of 7810 // filtering, because there may be no way for the user to 7811 // actually re-launch them. 7812 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 7813 && ps.getStopped(userId); 7814 } 7815 } 7816 return false; 7817 } 7818 7819 @Override isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)7820 protected boolean isPackageForFilter(String packageName, 7821 PackageParser.ProviderIntentInfo info) { 7822 return packageName.equals(info.provider.owner.packageName); 7823 } 7824 7825 @Override newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)7826 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 7827 int match, int userId) { 7828 if (!sUserManager.exists(userId)) 7829 return null; 7830 final PackageParser.ProviderIntentInfo info = filter; 7831 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 7832 return null; 7833 } 7834 final PackageParser.Provider provider = info.provider; 7835 if (mSafeMode && (provider.info.applicationInfo.flags 7836 & ApplicationInfo.FLAG_SYSTEM) == 0) { 7837 return null; 7838 } 7839 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 7840 if (ps == null) { 7841 return null; 7842 } 7843 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 7844 ps.readUserState(userId), userId); 7845 if (pi == null) { 7846 return null; 7847 } 7848 final ResolveInfo res = new ResolveInfo(); 7849 res.providerInfo = pi; 7850 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 7851 res.filter = filter; 7852 } 7853 res.priority = info.getPriority(); 7854 res.preferredOrder = provider.owner.mPreferredOrder; 7855 res.match = match; 7856 res.isDefault = info.hasDefault; 7857 res.labelRes = info.labelRes; 7858 res.nonLocalizedLabel = info.nonLocalizedLabel; 7859 res.icon = info.icon; 7860 res.system = isSystemApp(res.providerInfo.applicationInfo); 7861 return res; 7862 } 7863 7864 @Override sortResults(List<ResolveInfo> results)7865 protected void sortResults(List<ResolveInfo> results) { 7866 Collections.sort(results, mResolvePrioritySorter); 7867 } 7868 7869 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)7870 protected void dumpFilter(PrintWriter out, String prefix, 7871 PackageParser.ProviderIntentInfo filter) { 7872 out.print(prefix); 7873 out.print( 7874 Integer.toHexString(System.identityHashCode(filter.provider))); 7875 out.print(' '); 7876 filter.provider.printComponentShortName(out); 7877 out.print(" filter "); 7878 out.println(Integer.toHexString(System.identityHashCode(filter))); 7879 } 7880 7881 @Override filterToLabel(PackageParser.ProviderIntentInfo filter)7882 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 7883 return filter.provider; 7884 } 7885 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)7886 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 7887 PackageParser.Provider provider = (PackageParser.Provider)label; 7888 out.print(prefix); out.print( 7889 Integer.toHexString(System.identityHashCode(provider))); 7890 out.print(' '); 7891 provider.printComponentShortName(out); 7892 if (count > 1) { 7893 out.print(" ("); out.print(count); out.print(" filters)"); 7894 } 7895 out.println(); 7896 } 7897 7898 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 7899 = new ArrayMap<ComponentName, PackageParser.Provider>(); 7900 private int mFlags; 7901 }; 7902 7903 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 7904 new Comparator<ResolveInfo>() { 7905 public int compare(ResolveInfo r1, ResolveInfo r2) { 7906 int v1 = r1.priority; 7907 int v2 = r2.priority; 7908 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 7909 if (v1 != v2) { 7910 return (v1 > v2) ? -1 : 1; 7911 } 7912 v1 = r1.preferredOrder; 7913 v2 = r2.preferredOrder; 7914 if (v1 != v2) { 7915 return (v1 > v2) ? -1 : 1; 7916 } 7917 if (r1.isDefault != r2.isDefault) { 7918 return r1.isDefault ? -1 : 1; 7919 } 7920 v1 = r1.match; 7921 v2 = r2.match; 7922 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 7923 if (v1 != v2) { 7924 return (v1 > v2) ? -1 : 1; 7925 } 7926 if (r1.system != r2.system) { 7927 return r1.system ? -1 : 1; 7928 } 7929 return 0; 7930 } 7931 }; 7932 7933 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 7934 new Comparator<ProviderInfo>() { 7935 public int compare(ProviderInfo p1, ProviderInfo p2) { 7936 final int v1 = p1.initOrder; 7937 final int v2 = p2.initOrder; 7938 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 7939 } 7940 }; 7941 sendPackageBroadcast(String action, String pkg, Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, int[] userIds)7942 static final void sendPackageBroadcast(String action, String pkg, 7943 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, 7944 int[] userIds) { 7945 IActivityManager am = ActivityManagerNative.getDefault(); 7946 if (am != null) { 7947 try { 7948 if (userIds == null) { 7949 userIds = am.getRunningUserIds(); 7950 } 7951 for (int id : userIds) { 7952 final Intent intent = new Intent(action, 7953 pkg != null ? Uri.fromParts("package", pkg, null) : null); 7954 if (extras != null) { 7955 intent.putExtras(extras); 7956 } 7957 if (targetPkg != null) { 7958 intent.setPackage(targetPkg); 7959 } 7960 // Modify the UID when posting to other users 7961 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 7962 if (uid > 0 && UserHandle.getUserId(uid) != id) { 7963 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 7964 intent.putExtra(Intent.EXTRA_UID, uid); 7965 } 7966 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 7967 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 7968 if (DEBUG_BROADCASTS) { 7969 RuntimeException here = new RuntimeException("here"); 7970 here.fillInStackTrace(); 7971 Slog.d(TAG, "Sending to user " + id + ": " 7972 + intent.toShortString(false, true, false, false) 7973 + " " + intent.getExtras(), here); 7974 } 7975 am.broadcastIntent(null, intent, null, finishedReceiver, 7976 0, null, null, null, android.app.AppOpsManager.OP_NONE, 7977 finishedReceiver != null, false, id); 7978 } 7979 } catch (RemoteException ex) { 7980 } 7981 } 7982 } 7983 7984 /** 7985 * Check if the external storage media is available. This is true if there 7986 * is a mounted external storage medium or if the external storage is 7987 * emulated. 7988 */ isExternalMediaAvailable()7989 private boolean isExternalMediaAvailable() { 7990 return mMediaMounted || Environment.isExternalStorageEmulated(); 7991 } 7992 7993 @Override nextPackageToClean(PackageCleanItem lastPackage)7994 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 7995 // writer 7996 synchronized (mPackages) { 7997 if (!isExternalMediaAvailable()) { 7998 // If the external storage is no longer mounted at this point, 7999 // the caller may not have been able to delete all of this 8000 // packages files and can not delete any more. Bail. 8001 return null; 8002 } 8003 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 8004 if (lastPackage != null) { 8005 pkgs.remove(lastPackage); 8006 } 8007 if (pkgs.size() > 0) { 8008 return pkgs.get(0); 8009 } 8010 } 8011 return null; 8012 } 8013 schedulePackageCleaning(String packageName, int userId, boolean andCode)8014 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 8015 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 8016 userId, andCode ? 1 : 0, packageName); 8017 if (mSystemReady) { 8018 msg.sendToTarget(); 8019 } else { 8020 if (mPostSystemReadyMessages == null) { 8021 mPostSystemReadyMessages = new ArrayList<>(); 8022 } 8023 mPostSystemReadyMessages.add(msg); 8024 } 8025 } 8026 startCleaningPackages()8027 void startCleaningPackages() { 8028 // reader 8029 synchronized (mPackages) { 8030 if (!isExternalMediaAvailable()) { 8031 return; 8032 } 8033 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 8034 return; 8035 } 8036 } 8037 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 8038 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 8039 IActivityManager am = ActivityManagerNative.getDefault(); 8040 if (am != null) { 8041 try { 8042 am.startService(null, intent, null, UserHandle.USER_OWNER); 8043 } catch (RemoteException e) { 8044 } 8045 } 8046 } 8047 8048 @Override installPackage(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride)8049 public void installPackage(String originPath, IPackageInstallObserver2 observer, 8050 int installFlags, String installerPackageName, VerificationParams verificationParams, 8051 String packageAbiOverride) { 8052 installPackageAsUser(originPath, observer, installFlags, installerPackageName, verificationParams, 8053 packageAbiOverride, UserHandle.getCallingUserId()); 8054 } 8055 8056 @Override installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, String packageAbiOverride, int userId)8057 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 8058 int installFlags, String installerPackageName, VerificationParams verificationParams, 8059 String packageAbiOverride, int userId) { 8060 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 8061 8062 final int callingUid = Binder.getCallingUid(); 8063 enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); 8064 8065 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8066 try { 8067 if (observer != null) { 8068 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 8069 } 8070 } catch (RemoteException re) { 8071 } 8072 return; 8073 } 8074 8075 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 8076 installFlags |= PackageManager.INSTALL_FROM_ADB; 8077 8078 } else { 8079 // Caller holds INSTALL_PACKAGES permission, so we're less strict 8080 // about installerPackageName. 8081 8082 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 8083 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 8084 } 8085 8086 UserHandle user; 8087 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 8088 user = UserHandle.ALL; 8089 } else { 8090 user = new UserHandle(userId); 8091 } 8092 8093 verificationParams.setInstallerUid(callingUid); 8094 8095 final File originFile = new File(originPath); 8096 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 8097 8098 final Message msg = mHandler.obtainMessage(INIT_COPY); 8099 msg.obj = new InstallParams(origin, observer, installFlags, 8100 installerPackageName, verificationParams, user, packageAbiOverride); 8101 mHandler.sendMessage(msg); 8102 } 8103 installStage(String packageName, File stagedDir, String stagedCid, IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, String installerPackageName, int installerUid, UserHandle user)8104 void installStage(String packageName, File stagedDir, String stagedCid, 8105 IPackageInstallObserver2 observer, PackageInstaller.SessionParams params, 8106 String installerPackageName, int installerUid, UserHandle user) { 8107 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, 8108 params.referrerUri, installerUid, null); 8109 8110 final OriginInfo origin; 8111 if (stagedDir != null) { 8112 origin = OriginInfo.fromStagedFile(stagedDir); 8113 } else { 8114 origin = OriginInfo.fromStagedContainer(stagedCid); 8115 } 8116 8117 final Message msg = mHandler.obtainMessage(INIT_COPY); 8118 msg.obj = new InstallParams(origin, observer, params.installFlags, 8119 installerPackageName, verifParams, user, params.abiOverride); 8120 mHandler.sendMessage(msg); 8121 } 8122 sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId)8123 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 8124 Bundle extras = new Bundle(1); 8125 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 8126 8127 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 8128 packageName, extras, null, null, new int[] {userId}); 8129 try { 8130 IActivityManager am = ActivityManagerNative.getDefault(); 8131 final boolean isSystem = 8132 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 8133 if (isSystem && am.isUserRunning(userId, false)) { 8134 // The just-installed/enabled app is bundled on the system, so presumed 8135 // to be able to run automatically without needing an explicit launch. 8136 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 8137 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 8138 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 8139 .setPackage(packageName); 8140 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 8141 android.app.AppOpsManager.OP_NONE, false, false, userId); 8142 } 8143 } catch (RemoteException e) { 8144 // shouldn't happen 8145 Slog.w(TAG, "Unable to bootstrap installed package", e); 8146 } 8147 } 8148 8149 @Override setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)8150 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 8151 int userId) { 8152 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 8153 PackageSetting pkgSetting; 8154 final int uid = Binder.getCallingUid(); 8155 enforceCrossUserPermission(uid, userId, true, true, 8156 "setApplicationHiddenSetting for user " + userId); 8157 8158 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 8159 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 8160 return false; 8161 } 8162 8163 long callingId = Binder.clearCallingIdentity(); 8164 try { 8165 boolean sendAdded = false; 8166 boolean sendRemoved = false; 8167 // writer 8168 synchronized (mPackages) { 8169 pkgSetting = mSettings.mPackages.get(packageName); 8170 if (pkgSetting == null) { 8171 return false; 8172 } 8173 if (pkgSetting.getHidden(userId) != hidden) { 8174 pkgSetting.setHidden(hidden, userId); 8175 mSettings.writePackageRestrictionsLPr(userId); 8176 if (hidden) { 8177 sendRemoved = true; 8178 } else { 8179 sendAdded = true; 8180 } 8181 } 8182 } 8183 if (sendAdded) { 8184 sendPackageAddedForUser(packageName, pkgSetting, userId); 8185 return true; 8186 } 8187 if (sendRemoved) { 8188 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 8189 "hiding pkg"); 8190 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 8191 } 8192 } finally { 8193 Binder.restoreCallingIdentity(callingId); 8194 } 8195 return false; 8196 } 8197 sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)8198 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 8199 int userId) { 8200 final PackageRemovedInfo info = new PackageRemovedInfo(); 8201 info.removedPackage = packageName; 8202 info.removedUsers = new int[] {userId}; 8203 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 8204 info.sendBroadcast(false, false, false); 8205 } 8206 8207 /** 8208 * Returns true if application is not found or there was an error. Otherwise it returns 8209 * the hidden state of the package for the given user. 8210 */ 8211 @Override getApplicationHiddenSettingAsUser(String packageName, int userId)8212 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 8213 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 8214 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 8215 false, "getApplicationHidden for user " + userId); 8216 PackageSetting pkgSetting; 8217 long callingId = Binder.clearCallingIdentity(); 8218 try { 8219 // writer 8220 synchronized (mPackages) { 8221 pkgSetting = mSettings.mPackages.get(packageName); 8222 if (pkgSetting == null) { 8223 return true; 8224 } 8225 return pkgSetting.getHidden(userId); 8226 } 8227 } finally { 8228 Binder.restoreCallingIdentity(callingId); 8229 } 8230 } 8231 8232 /** 8233 * @hide 8234 */ 8235 @Override installExistingPackageAsUser(String packageName, int userId)8236 public int installExistingPackageAsUser(String packageName, int userId) { 8237 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 8238 null); 8239 PackageSetting pkgSetting; 8240 final int uid = Binder.getCallingUid(); 8241 enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " 8242 + userId); 8243 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 8244 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 8245 } 8246 8247 long callingId = Binder.clearCallingIdentity(); 8248 try { 8249 boolean sendAdded = false; 8250 Bundle extras = new Bundle(1); 8251 8252 // writer 8253 synchronized (mPackages) { 8254 pkgSetting = mSettings.mPackages.get(packageName); 8255 if (pkgSetting == null) { 8256 return PackageManager.INSTALL_FAILED_INVALID_URI; 8257 } 8258 if (!pkgSetting.getInstalled(userId)) { 8259 pkgSetting.setInstalled(true, userId); 8260 pkgSetting.setHidden(false, userId); 8261 mSettings.writePackageRestrictionsLPr(userId); 8262 sendAdded = true; 8263 } 8264 } 8265 8266 if (sendAdded) { 8267 sendPackageAddedForUser(packageName, pkgSetting, userId); 8268 } 8269 } finally { 8270 Binder.restoreCallingIdentity(callingId); 8271 } 8272 8273 return PackageManager.INSTALL_SUCCEEDED; 8274 } 8275 isUserRestricted(int userId, String restrictionKey)8276 boolean isUserRestricted(int userId, String restrictionKey) { 8277 Bundle restrictions = sUserManager.getUserRestrictions(userId); 8278 if (restrictions.getBoolean(restrictionKey, false)) { 8279 Log.w(TAG, "User is restricted: " + restrictionKey); 8280 return true; 8281 } 8282 return false; 8283 } 8284 8285 @Override verifyPendingInstall(int id, int verificationCode)8286 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 8287 mContext.enforceCallingOrSelfPermission( 8288 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8289 "Only package verification agents can verify applications"); 8290 8291 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8292 final PackageVerificationResponse response = new PackageVerificationResponse( 8293 verificationCode, Binder.getCallingUid()); 8294 msg.arg1 = id; 8295 msg.obj = response; 8296 mHandler.sendMessage(msg); 8297 } 8298 8299 @Override extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)8300 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 8301 long millisecondsToDelay) { 8302 mContext.enforceCallingOrSelfPermission( 8303 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8304 "Only package verification agents can extend verification timeouts"); 8305 8306 final PackageVerificationState state = mPendingVerification.get(id); 8307 final PackageVerificationResponse response = new PackageVerificationResponse( 8308 verificationCodeAtTimeout, Binder.getCallingUid()); 8309 8310 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 8311 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 8312 } 8313 if (millisecondsToDelay < 0) { 8314 millisecondsToDelay = 0; 8315 } 8316 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 8317 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 8318 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 8319 } 8320 8321 if ((state != null) && !state.timeoutExtended()) { 8322 state.extendTimeout(); 8323 8324 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8325 msg.arg1 = id; 8326 msg.obj = response; 8327 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 8328 } 8329 } 8330 broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, UserHandle user)8331 private void broadcastPackageVerified(int verificationId, Uri packageUri, 8332 int verificationCode, UserHandle user) { 8333 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 8334 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 8335 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 8336 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 8337 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 8338 8339 mContext.sendBroadcastAsUser(intent, user, 8340 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 8341 } 8342 matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)8343 private ComponentName matchComponentForVerifier(String packageName, 8344 List<ResolveInfo> receivers) { 8345 ActivityInfo targetReceiver = null; 8346 8347 final int NR = receivers.size(); 8348 for (int i = 0; i < NR; i++) { 8349 final ResolveInfo info = receivers.get(i); 8350 if (info.activityInfo == null) { 8351 continue; 8352 } 8353 8354 if (packageName.equals(info.activityInfo.packageName)) { 8355 targetReceiver = info.activityInfo; 8356 break; 8357 } 8358 } 8359 8360 if (targetReceiver == null) { 8361 return null; 8362 } 8363 8364 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 8365 } 8366 matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)8367 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 8368 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 8369 if (pkgInfo.verifiers.length == 0) { 8370 return null; 8371 } 8372 8373 final int N = pkgInfo.verifiers.length; 8374 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 8375 for (int i = 0; i < N; i++) { 8376 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 8377 8378 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 8379 receivers); 8380 if (comp == null) { 8381 continue; 8382 } 8383 8384 final int verifierUid = getUidForVerifier(verifierInfo); 8385 if (verifierUid == -1) { 8386 continue; 8387 } 8388 8389 if (DEBUG_VERIFY) { 8390 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 8391 + " with the correct signature"); 8392 } 8393 sufficientVerifiers.add(comp); 8394 verificationState.addSufficientVerifier(verifierUid); 8395 } 8396 8397 return sufficientVerifiers; 8398 } 8399 getUidForVerifier(VerifierInfo verifierInfo)8400 private int getUidForVerifier(VerifierInfo verifierInfo) { 8401 synchronized (mPackages) { 8402 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 8403 if (pkg == null) { 8404 return -1; 8405 } else if (pkg.mSignatures.length != 1) { 8406 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8407 + " has more than one signature; ignoring"); 8408 return -1; 8409 } 8410 8411 /* 8412 * If the public key of the package's signature does not match 8413 * our expected public key, then this is a different package and 8414 * we should skip. 8415 */ 8416 8417 final byte[] expectedPublicKey; 8418 try { 8419 final Signature verifierSig = pkg.mSignatures[0]; 8420 final PublicKey publicKey = verifierSig.getPublicKey(); 8421 expectedPublicKey = publicKey.getEncoded(); 8422 } catch (CertificateException e) { 8423 return -1; 8424 } 8425 8426 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 8427 8428 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 8429 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8430 + " does not have the expected public key; ignoring"); 8431 return -1; 8432 } 8433 8434 return pkg.applicationInfo.uid; 8435 } 8436 } 8437 8438 @Override finishPackageInstall(int token)8439 public void finishPackageInstall(int token) { 8440 enforceSystemOrRoot("Only the system is allowed to finish installs"); 8441 8442 if (DEBUG_INSTALL) { 8443 Slog.v(TAG, "BM finishing package install for " + token); 8444 } 8445 8446 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 8447 mHandler.sendMessage(msg); 8448 } 8449 8450 /** 8451 * Get the verification agent timeout. 8452 * 8453 * @return verification timeout in milliseconds 8454 */ getVerificationTimeout()8455 private long getVerificationTimeout() { 8456 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 8457 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 8458 DEFAULT_VERIFICATION_TIMEOUT); 8459 } 8460 8461 /** 8462 * Get the default verification agent response code. 8463 * 8464 * @return default verification response code 8465 */ getDefaultVerificationResponse()8466 private int getDefaultVerificationResponse() { 8467 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8468 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 8469 DEFAULT_VERIFICATION_RESPONSE); 8470 } 8471 8472 /** 8473 * Check whether or not package verification has been enabled. 8474 * 8475 * @return true if verification should be performed 8476 */ isVerificationEnabled(int userId, int installFlags)8477 private boolean isVerificationEnabled(int userId, int installFlags) { 8478 if (!DEFAULT_VERIFY_ENABLE) { 8479 return false; 8480 } 8481 8482 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 8483 8484 // Check if installing from ADB 8485 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 8486 // Do not run verification in a test harness environment 8487 if (ActivityManager.isRunningInTestHarness()) { 8488 return false; 8489 } 8490 if (ensureVerifyAppsEnabled) { 8491 return true; 8492 } 8493 // Check if the developer does not want package verification for ADB installs 8494 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8495 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 8496 return false; 8497 } 8498 } 8499 8500 if (ensureVerifyAppsEnabled) { 8501 return true; 8502 } 8503 8504 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8505 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 8506 } 8507 8508 /** 8509 * Get the "allow unknown sources" setting. 8510 * 8511 * @return the current "allow unknown sources" setting 8512 */ getUnknownSourcesSettings()8513 private int getUnknownSourcesSettings() { 8514 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8515 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 8516 -1); 8517 } 8518 8519 @Override setInstallerPackageName(String targetPackage, String installerPackageName)8520 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 8521 final int uid = Binder.getCallingUid(); 8522 // writer 8523 synchronized (mPackages) { 8524 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 8525 if (targetPackageSetting == null) { 8526 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 8527 } 8528 8529 PackageSetting installerPackageSetting; 8530 if (installerPackageName != null) { 8531 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 8532 if (installerPackageSetting == null) { 8533 throw new IllegalArgumentException("Unknown installer package: " 8534 + installerPackageName); 8535 } 8536 } else { 8537 installerPackageSetting = null; 8538 } 8539 8540 Signature[] callerSignature; 8541 Object obj = mSettings.getUserIdLPr(uid); 8542 if (obj != null) { 8543 if (obj instanceof SharedUserSetting) { 8544 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 8545 } else if (obj instanceof PackageSetting) { 8546 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 8547 } else { 8548 throw new SecurityException("Bad object " + obj + " for uid " + uid); 8549 } 8550 } else { 8551 throw new SecurityException("Unknown calling uid " + uid); 8552 } 8553 8554 // Verify: can't set installerPackageName to a package that is 8555 // not signed with the same cert as the caller. 8556 if (installerPackageSetting != null) { 8557 if (compareSignatures(callerSignature, 8558 installerPackageSetting.signatures.mSignatures) 8559 != PackageManager.SIGNATURE_MATCH) { 8560 throw new SecurityException( 8561 "Caller does not have same cert as new installer package " 8562 + installerPackageName); 8563 } 8564 } 8565 8566 // Verify: if target already has an installer package, it must 8567 // be signed with the same cert as the caller. 8568 if (targetPackageSetting.installerPackageName != null) { 8569 PackageSetting setting = mSettings.mPackages.get( 8570 targetPackageSetting.installerPackageName); 8571 // If the currently set package isn't valid, then it's always 8572 // okay to change it. 8573 if (setting != null) { 8574 if (compareSignatures(callerSignature, 8575 setting.signatures.mSignatures) 8576 != PackageManager.SIGNATURE_MATCH) { 8577 throw new SecurityException( 8578 "Caller does not have same cert as old installer package " 8579 + targetPackageSetting.installerPackageName); 8580 } 8581 } 8582 } 8583 8584 // Okay! 8585 targetPackageSetting.installerPackageName = installerPackageName; 8586 scheduleWriteSettingsLocked(); 8587 } 8588 } 8589 processPendingInstall(final InstallArgs args, final int currentStatus)8590 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 8591 // Queue up an async operation since the package installation may take a little while. 8592 mHandler.post(new Runnable() { 8593 public void run() { 8594 mHandler.removeCallbacks(this); 8595 // Result object to be returned 8596 PackageInstalledInfo res = new PackageInstalledInfo(); 8597 res.returnCode = currentStatus; 8598 res.uid = -1; 8599 res.pkg = null; 8600 res.removedInfo = new PackageRemovedInfo(); 8601 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 8602 args.doPreInstall(res.returnCode); 8603 synchronized (mInstallLock) { 8604 installPackageLI(args, res); 8605 } 8606 args.doPostInstall(res.returnCode, res.uid); 8607 } 8608 8609 // A restore should be performed at this point if (a) the install 8610 // succeeded, (b) the operation is not an update, and (c) the new 8611 // package has not opted out of backup participation. 8612 final boolean update = res.removedInfo.removedPackage != null; 8613 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 8614 boolean doRestore = !update 8615 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 8616 8617 // Set up the post-install work request bookkeeping. This will be used 8618 // and cleaned up by the post-install event handling regardless of whether 8619 // there's a restore pass performed. Token values are >= 1. 8620 int token; 8621 if (mNextInstallToken < 0) mNextInstallToken = 1; 8622 token = mNextInstallToken++; 8623 8624 PostInstallData data = new PostInstallData(args, res); 8625 mRunningInstalls.put(token, data); 8626 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 8627 8628 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 8629 // Pass responsibility to the Backup Manager. It will perform a 8630 // restore if appropriate, then pass responsibility back to the 8631 // Package Manager to run the post-install observer callbacks 8632 // and broadcasts. 8633 IBackupManager bm = IBackupManager.Stub.asInterface( 8634 ServiceManager.getService(Context.BACKUP_SERVICE)); 8635 if (bm != null) { 8636 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 8637 + " to BM for possible restore"); 8638 try { 8639 if (bm.isBackupServiceActive(UserHandle.USER_OWNER)) { 8640 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 8641 } else { 8642 doRestore = false; 8643 } 8644 } catch (RemoteException e) { 8645 // can't happen; the backup manager is local 8646 } catch (Exception e) { 8647 Slog.e(TAG, "Exception trying to enqueue restore", e); 8648 doRestore = false; 8649 } 8650 } else { 8651 Slog.e(TAG, "Backup Manager not found!"); 8652 doRestore = false; 8653 } 8654 } 8655 8656 if (!doRestore) { 8657 // No restore possible, or the Backup Manager was mysteriously not 8658 // available -- just fire the post-install work request directly. 8659 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 8660 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 8661 mHandler.sendMessage(msg); 8662 } 8663 } 8664 }); 8665 } 8666 8667 private abstract class HandlerParams { 8668 private static final int MAX_RETRIES = 4; 8669 8670 /** 8671 * Number of times startCopy() has been attempted and had a non-fatal 8672 * error. 8673 */ 8674 private int mRetries = 0; 8675 8676 /** User handle for the user requesting the information or installation. */ 8677 private final UserHandle mUser; 8678 HandlerParams(UserHandle user)8679 HandlerParams(UserHandle user) { 8680 mUser = user; 8681 } 8682 getUser()8683 UserHandle getUser() { 8684 return mUser; 8685 } 8686 startCopy()8687 final boolean startCopy() { 8688 boolean res; 8689 try { 8690 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 8691 8692 if (++mRetries > MAX_RETRIES) { 8693 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 8694 mHandler.sendEmptyMessage(MCS_GIVE_UP); 8695 handleServiceError(); 8696 return false; 8697 } else { 8698 handleStartCopy(); 8699 res = true; 8700 } 8701 } catch (RemoteException e) { 8702 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 8703 mHandler.sendEmptyMessage(MCS_RECONNECT); 8704 res = false; 8705 } 8706 handleReturnCode(); 8707 return res; 8708 } 8709 serviceError()8710 final void serviceError() { 8711 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 8712 handleServiceError(); 8713 handleReturnCode(); 8714 } 8715 handleStartCopy()8716 abstract void handleStartCopy() throws RemoteException; handleServiceError()8717 abstract void handleServiceError(); handleReturnCode()8718 abstract void handleReturnCode(); 8719 } 8720 8721 class MeasureParams extends HandlerParams { 8722 private final PackageStats mStats; 8723 private boolean mSuccess; 8724 8725 private final IPackageStatsObserver mObserver; 8726 MeasureParams(PackageStats stats, IPackageStatsObserver observer)8727 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 8728 super(new UserHandle(stats.userHandle)); 8729 mObserver = observer; 8730 mStats = stats; 8731 } 8732 8733 @Override toString()8734 public String toString() { 8735 return "MeasureParams{" 8736 + Integer.toHexString(System.identityHashCode(this)) 8737 + " " + mStats.packageName + "}"; 8738 } 8739 8740 @Override handleStartCopy()8741 void handleStartCopy() throws RemoteException { 8742 synchronized (mInstallLock) { 8743 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 8744 } 8745 8746 if (mSuccess) { 8747 final boolean mounted; 8748 if (Environment.isExternalStorageEmulated()) { 8749 mounted = true; 8750 } else { 8751 final String status = Environment.getExternalStorageState(); 8752 mounted = (Environment.MEDIA_MOUNTED.equals(status) 8753 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 8754 } 8755 8756 if (mounted) { 8757 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 8758 8759 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 8760 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 8761 8762 mStats.externalDataSize = calculateDirectorySize(mContainerService, 8763 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 8764 8765 // Always subtract cache size, since it's a subdirectory 8766 mStats.externalDataSize -= mStats.externalCacheSize; 8767 8768 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 8769 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 8770 8771 mStats.externalObbSize = calculateDirectorySize(mContainerService, 8772 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 8773 } 8774 } 8775 } 8776 8777 @Override handleReturnCode()8778 void handleReturnCode() { 8779 if (mObserver != null) { 8780 try { 8781 mObserver.onGetStatsCompleted(mStats, mSuccess); 8782 } catch (RemoteException e) { 8783 Slog.i(TAG, "Observer no longer exists."); 8784 } 8785 } 8786 } 8787 8788 @Override handleServiceError()8789 void handleServiceError() { 8790 Slog.e(TAG, "Could not measure application " + mStats.packageName 8791 + " external storage"); 8792 } 8793 } 8794 calculateDirectorySize(IMediaContainerService mcs, File[] paths)8795 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 8796 throws RemoteException { 8797 long result = 0; 8798 for (File path : paths) { 8799 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 8800 } 8801 return result; 8802 } 8803 clearDirectory(IMediaContainerService mcs, File[] paths)8804 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 8805 for (File path : paths) { 8806 try { 8807 mcs.clearDirectory(path.getAbsolutePath()); 8808 } catch (RemoteException e) { 8809 } 8810 } 8811 } 8812 8813 static class OriginInfo { 8814 /** 8815 * Location where install is coming from, before it has been 8816 * copied/renamed into place. This could be a single monolithic APK 8817 * file, or a cluster directory. This location may be untrusted. 8818 */ 8819 final File file; 8820 final String cid; 8821 8822 /** 8823 * Flag indicating that {@link #file} or {@link #cid} has already been 8824 * staged, meaning downstream users don't need to defensively copy the 8825 * contents. 8826 */ 8827 final boolean staged; 8828 8829 /** 8830 * Flag indicating that {@link #file} or {@link #cid} is an already 8831 * installed app that is being moved. 8832 */ 8833 final boolean existing; 8834 8835 final String resolvedPath; 8836 final File resolvedFile; 8837 fromNothing()8838 static OriginInfo fromNothing() { 8839 return new OriginInfo(null, null, false, false); 8840 } 8841 fromUntrustedFile(File file)8842 static OriginInfo fromUntrustedFile(File file) { 8843 return new OriginInfo(file, null, false, false); 8844 } 8845 fromExistingFile(File file)8846 static OriginInfo fromExistingFile(File file) { 8847 return new OriginInfo(file, null, false, true); 8848 } 8849 fromStagedFile(File file)8850 static OriginInfo fromStagedFile(File file) { 8851 return new OriginInfo(file, null, true, false); 8852 } 8853 fromStagedContainer(String cid)8854 static OriginInfo fromStagedContainer(String cid) { 8855 return new OriginInfo(null, cid, true, false); 8856 } 8857 OriginInfo(File file, String cid, boolean staged, boolean existing)8858 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 8859 this.file = file; 8860 this.cid = cid; 8861 this.staged = staged; 8862 this.existing = existing; 8863 8864 if (cid != null) { 8865 resolvedPath = PackageHelper.getSdDir(cid); 8866 resolvedFile = new File(resolvedPath); 8867 } else if (file != null) { 8868 resolvedPath = file.getAbsolutePath(); 8869 resolvedFile = file; 8870 } else { 8871 resolvedPath = null; 8872 resolvedFile = null; 8873 } 8874 } 8875 } 8876 8877 class InstallParams extends HandlerParams { 8878 final OriginInfo origin; 8879 final IPackageInstallObserver2 observer; 8880 int installFlags; 8881 final String installerPackageName; 8882 final VerificationParams verificationParams; 8883 private InstallArgs mArgs; 8884 private int mRet; 8885 final String packageAbiOverride; 8886 InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, VerificationParams verificationParams, UserHandle user, String packageAbiOverride)8887 InstallParams(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, 8888 String installerPackageName, VerificationParams verificationParams, UserHandle user, 8889 String packageAbiOverride) { 8890 super(user); 8891 this.origin = origin; 8892 this.observer = observer; 8893 this.installFlags = installFlags; 8894 this.installerPackageName = installerPackageName; 8895 this.verificationParams = verificationParams; 8896 this.packageAbiOverride = packageAbiOverride; 8897 } 8898 8899 @Override toString()8900 public String toString() { 8901 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 8902 + " file=" + origin.file + " cid=" + origin.cid + "}"; 8903 } 8904 getManifestDigest()8905 public ManifestDigest getManifestDigest() { 8906 if (verificationParams == null) { 8907 return null; 8908 } 8909 return verificationParams.getManifestDigest(); 8910 } 8911 installLocationPolicy(PackageInfoLite pkgLite)8912 private int installLocationPolicy(PackageInfoLite pkgLite) { 8913 String packageName = pkgLite.packageName; 8914 int installLocation = pkgLite.installLocation; 8915 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 8916 // reader 8917 synchronized (mPackages) { 8918 PackageParser.Package pkg = mPackages.get(packageName); 8919 if (pkg != null) { 8920 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 8921 // Check for downgrading. 8922 if ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 8923 try { 8924 checkDowngrade(pkg, pkgLite); 8925 } catch (PackageManagerException e) { 8926 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 8927 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 8928 } 8929 } 8930 // Check for updated system application. 8931 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8932 if (onSd) { 8933 Slog.w(TAG, "Cannot install update to system app on sdcard"); 8934 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 8935 } 8936 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8937 } else { 8938 if (onSd) { 8939 // Install flag overrides everything. 8940 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8941 } 8942 // If current upgrade specifies particular preference 8943 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 8944 // Application explicitly specified internal. 8945 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8946 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 8947 // App explictly prefers external. Let policy decide 8948 } else { 8949 // Prefer previous location 8950 if (isExternal(pkg)) { 8951 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8952 } 8953 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8954 } 8955 } 8956 } else { 8957 // Invalid install. Return error code 8958 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 8959 } 8960 } 8961 } 8962 // All the special cases have been taken care of. 8963 // Return result based on recommended install location. 8964 if (onSd) { 8965 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8966 } 8967 return pkgLite.recommendedInstallLocation; 8968 } 8969 8970 /* 8971 * Invoke remote method to get package information and install 8972 * location values. Override install location based on default 8973 * policy if needed and then create install arguments based 8974 * on the install location. 8975 */ handleStartCopy()8976 public void handleStartCopy() throws RemoteException { 8977 int ret = PackageManager.INSTALL_SUCCEEDED; 8978 8979 // If we're already staged, we've firmly committed to an install location 8980 if (origin.staged) { 8981 if (origin.file != null) { 8982 installFlags |= PackageManager.INSTALL_INTERNAL; 8983 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 8984 } else if (origin.cid != null) { 8985 installFlags |= PackageManager.INSTALL_EXTERNAL; 8986 installFlags &= ~PackageManager.INSTALL_INTERNAL; 8987 } else { 8988 throw new IllegalStateException("Invalid stage location"); 8989 } 8990 } 8991 8992 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 8993 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 8994 8995 PackageInfoLite pkgLite = null; 8996 8997 if (onInt && onSd) { 8998 // Check if both bits are set. 8999 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 9000 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9001 } else { 9002 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 9003 packageAbiOverride); 9004 9005 /* 9006 * If we have too little free space, try to free cache 9007 * before giving up. 9008 */ 9009 if (!origin.staged && pkgLite.recommendedInstallLocation 9010 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9011 // TODO: focus freeing disk space on the target device 9012 final StorageManager storage = StorageManager.from(mContext); 9013 final long lowThreshold = storage.getStorageLowBytes( 9014 Environment.getDataDirectory()); 9015 9016 final long sizeBytes = mContainerService.calculateInstalledSize( 9017 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 9018 9019 if (mInstaller.freeCache(sizeBytes + lowThreshold) >= 0) { 9020 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 9021 installFlags, packageAbiOverride); 9022 } 9023 9024 /* 9025 * The cache free must have deleted the file we 9026 * downloaded to install. 9027 * 9028 * TODO: fix the "freeCache" call to not delete 9029 * the file we care about. 9030 */ 9031 if (pkgLite.recommendedInstallLocation 9032 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9033 pkgLite.recommendedInstallLocation 9034 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 9035 } 9036 } 9037 } 9038 9039 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9040 int loc = pkgLite.recommendedInstallLocation; 9041 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 9042 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9043 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 9044 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 9045 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 9046 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9047 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 9048 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 9049 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 9050 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 9051 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 9052 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 9053 } else { 9054 // Override with defaults if needed. 9055 loc = installLocationPolicy(pkgLite); 9056 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 9057 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 9058 } else if (!onSd && !onInt) { 9059 // Override install location with flags 9060 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 9061 // Set the flag to install on external media. 9062 installFlags |= PackageManager.INSTALL_EXTERNAL; 9063 installFlags &= ~PackageManager.INSTALL_INTERNAL; 9064 } else { 9065 // Make sure the flag for installing on external 9066 // media is unset 9067 installFlags |= PackageManager.INSTALL_INTERNAL; 9068 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 9069 } 9070 } 9071 } 9072 } 9073 9074 final InstallArgs args = createInstallArgs(this); 9075 mArgs = args; 9076 9077 if (ret == PackageManager.INSTALL_SUCCEEDED) { 9078 /* 9079 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 9080 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 9081 */ 9082 int userIdentifier = getUser().getIdentifier(); 9083 if (userIdentifier == UserHandle.USER_ALL 9084 && ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0)) { 9085 userIdentifier = UserHandle.USER_OWNER; 9086 } 9087 9088 /* 9089 * Determine if we have any installed package verifiers. If we 9090 * do, then we'll defer to them to verify the packages. 9091 */ 9092 final int requiredUid = mRequiredVerifierPackage == null ? -1 9093 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 9094 if (!origin.existing && requiredUid != -1 9095 && isVerificationEnabled(userIdentifier, installFlags)) { 9096 final Intent verification = new Intent( 9097 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 9098 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9099 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 9100 PACKAGE_MIME_TYPE); 9101 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 9102 9103 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 9104 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 9105 0 /* TODO: Which userId? */); 9106 9107 if (DEBUG_VERIFY) { 9108 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 9109 + verification.toString() + " with " + pkgLite.verifiers.length 9110 + " optional verifiers"); 9111 } 9112 9113 final int verificationId = mPendingVerificationToken++; 9114 9115 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 9116 9117 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 9118 installerPackageName); 9119 9120 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 9121 installFlags); 9122 9123 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 9124 pkgLite.packageName); 9125 9126 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 9127 pkgLite.versionCode); 9128 9129 if (verificationParams != null) { 9130 if (verificationParams.getVerificationURI() != null) { 9131 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 9132 verificationParams.getVerificationURI()); 9133 } 9134 if (verificationParams.getOriginatingURI() != null) { 9135 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 9136 verificationParams.getOriginatingURI()); 9137 } 9138 if (verificationParams.getReferrer() != null) { 9139 verification.putExtra(Intent.EXTRA_REFERRER, 9140 verificationParams.getReferrer()); 9141 } 9142 if (verificationParams.getOriginatingUid() >= 0) { 9143 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 9144 verificationParams.getOriginatingUid()); 9145 } 9146 if (verificationParams.getInstallerUid() >= 0) { 9147 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 9148 verificationParams.getInstallerUid()); 9149 } 9150 } 9151 9152 final PackageVerificationState verificationState = new PackageVerificationState( 9153 requiredUid, args); 9154 9155 mPendingVerification.append(verificationId, verificationState); 9156 9157 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 9158 receivers, verificationState); 9159 9160 /* 9161 * If any sufficient verifiers were listed in the package 9162 * manifest, attempt to ask them. 9163 */ 9164 if (sufficientVerifiers != null) { 9165 final int N = sufficientVerifiers.size(); 9166 if (N == 0) { 9167 Slog.i(TAG, "Additional verifiers required, but none installed."); 9168 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 9169 } else { 9170 for (int i = 0; i < N; i++) { 9171 final ComponentName verifierComponent = sufficientVerifiers.get(i); 9172 9173 final Intent sufficientIntent = new Intent(verification); 9174 sufficientIntent.setComponent(verifierComponent); 9175 9176 mContext.sendBroadcastAsUser(sufficientIntent, getUser()); 9177 } 9178 } 9179 } 9180 9181 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 9182 mRequiredVerifierPackage, receivers); 9183 if (ret == PackageManager.INSTALL_SUCCEEDED 9184 && mRequiredVerifierPackage != null) { 9185 /* 9186 * Send the intent to the required verification agent, 9187 * but only start the verification timeout after the 9188 * target BroadcastReceivers have run. 9189 */ 9190 verification.setComponent(requiredVerifierComponent); 9191 mContext.sendOrderedBroadcastAsUser(verification, getUser(), 9192 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 9193 new BroadcastReceiver() { 9194 @Override 9195 public void onReceive(Context context, Intent intent) { 9196 final Message msg = mHandler 9197 .obtainMessage(CHECK_PENDING_VERIFICATION); 9198 msg.arg1 = verificationId; 9199 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 9200 } 9201 }, null, 0, null, null); 9202 9203 /* 9204 * We don't want the copy to proceed until verification 9205 * succeeds, so null out this field. 9206 */ 9207 mArgs = null; 9208 } 9209 } else { 9210 /* 9211 * No package verification is enabled, so immediately start 9212 * the remote call to initiate copy using temporary file. 9213 */ 9214 ret = args.copyApk(mContainerService, true); 9215 } 9216 } 9217 9218 mRet = ret; 9219 } 9220 9221 @Override handleReturnCode()9222 void handleReturnCode() { 9223 // If mArgs is null, then MCS couldn't be reached. When it 9224 // reconnects, it will try again to install. At that point, this 9225 // will succeed. 9226 if (mArgs != null) { 9227 processPendingInstall(mArgs, mRet); 9228 } 9229 } 9230 9231 @Override handleServiceError()9232 void handleServiceError() { 9233 mArgs = createInstallArgs(this); 9234 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 9235 } 9236 isForwardLocked()9237 public boolean isForwardLocked() { 9238 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9239 } 9240 } 9241 9242 /** 9243 * Used during creation of InstallArgs 9244 * 9245 * @param installFlags package installation flags 9246 * @return true if should be installed on external storage 9247 */ installOnSd(int installFlags)9248 private static boolean installOnSd(int installFlags) { 9249 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 9250 return false; 9251 } 9252 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 9253 return true; 9254 } 9255 return false; 9256 } 9257 9258 /** 9259 * Used during creation of InstallArgs 9260 * 9261 * @param installFlags package installation flags 9262 * @return true if should be installed as forward locked 9263 */ installForwardLocked(int installFlags)9264 private static boolean installForwardLocked(int installFlags) { 9265 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9266 } 9267 createInstallArgs(InstallParams params)9268 private InstallArgs createInstallArgs(InstallParams params) { 9269 if (installOnSd(params.installFlags) || params.isForwardLocked()) { 9270 return new AsecInstallArgs(params); 9271 } else { 9272 return new FileInstallArgs(params); 9273 } 9274 } 9275 9276 /** 9277 * Create args that describe an existing installed package. Typically used 9278 * when cleaning up old installs, or used as a move source. 9279 */ createInstallArgsForExisting(int installFlags, String codePath, String resourcePath, String nativeLibraryRoot, String[] instructionSets)9280 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 9281 String resourcePath, String nativeLibraryRoot, String[] instructionSets) { 9282 final boolean isInAsec; 9283 if (installOnSd(installFlags)) { 9284 /* Apps on SD card are always in ASEC containers. */ 9285 isInAsec = true; 9286 } else if (installForwardLocked(installFlags) 9287 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 9288 /* 9289 * Forward-locked apps are only in ASEC containers if they're the 9290 * new style 9291 */ 9292 isInAsec = true; 9293 } else { 9294 isInAsec = false; 9295 } 9296 9297 if (isInAsec) { 9298 return new AsecInstallArgs(codePath, instructionSets, 9299 installOnSd(installFlags), installForwardLocked(installFlags)); 9300 } else { 9301 return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot, 9302 instructionSets); 9303 } 9304 } 9305 9306 static abstract class InstallArgs { 9307 /** @see InstallParams#origin */ 9308 final OriginInfo origin; 9309 9310 final IPackageInstallObserver2 observer; 9311 // Always refers to PackageManager flags only 9312 final int installFlags; 9313 final String installerPackageName; 9314 final ManifestDigest manifestDigest; 9315 final UserHandle user; 9316 final String abiOverride; 9317 9318 // The list of instruction sets supported by this app. This is currently 9319 // only used during the rmdex() phase to clean up resources. We can get rid of this 9320 // if we move dex files under the common app path. 9321 /* nullable */ String[] instructionSets; 9322 InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, ManifestDigest manifestDigest, UserHandle user, String[] instructionSets, String abiOverride)9323 InstallArgs(OriginInfo origin, IPackageInstallObserver2 observer, int installFlags, 9324 String installerPackageName, ManifestDigest manifestDigest, UserHandle user, 9325 String[] instructionSets, String abiOverride) { 9326 this.origin = origin; 9327 this.installFlags = installFlags; 9328 this.observer = observer; 9329 this.installerPackageName = installerPackageName; 9330 this.manifestDigest = manifestDigest; 9331 this.user = user; 9332 this.instructionSets = instructionSets; 9333 this.abiOverride = abiOverride; 9334 } 9335 copyApk(IMediaContainerService imcs, boolean temp)9336 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; doPreInstall(int status)9337 abstract int doPreInstall(int status); 9338 9339 /** 9340 * Rename package into final resting place. All paths on the given 9341 * scanned package should be updated to reflect the rename. 9342 */ doRename(int status, PackageParser.Package pkg, String oldCodePath)9343 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); doPostInstall(int status, int uid)9344 abstract int doPostInstall(int status, int uid); 9345 9346 /** @see PackageSettingBase#codePathString */ getCodePath()9347 abstract String getCodePath(); 9348 /** @see PackageSettingBase#resourcePathString */ getResourcePath()9349 abstract String getResourcePath(); getLegacyNativeLibraryPath()9350 abstract String getLegacyNativeLibraryPath(); 9351 9352 // Need installer lock especially for dex file removal. cleanUpResourcesLI()9353 abstract void cleanUpResourcesLI(); doPostDeleteLI(boolean delete)9354 abstract boolean doPostDeleteLI(boolean delete); checkFreeStorage(IMediaContainerService imcs)9355 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 9356 9357 /** 9358 * Called before the source arguments are copied. This is used mostly 9359 * for MoveParams when it needs to read the source file to put it in the 9360 * destination. 9361 */ doPreCopy()9362 int doPreCopy() { 9363 return PackageManager.INSTALL_SUCCEEDED; 9364 } 9365 9366 /** 9367 * Called after the source arguments are copied. This is used mostly for 9368 * MoveParams when it needs to read the source file to put it in the 9369 * destination. 9370 * 9371 * @return 9372 */ doPostCopy(int uid)9373 int doPostCopy(int uid) { 9374 return PackageManager.INSTALL_SUCCEEDED; 9375 } 9376 isFwdLocked()9377 protected boolean isFwdLocked() { 9378 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9379 } 9380 isExternal()9381 protected boolean isExternal() { 9382 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 9383 } 9384 getUser()9385 UserHandle getUser() { 9386 return user; 9387 } 9388 } 9389 9390 /** 9391 * Logic to handle installation of non-ASEC applications, including copying 9392 * and renaming logic. 9393 */ 9394 class FileInstallArgs extends InstallArgs { 9395 private File codeFile; 9396 private File resourceFile; 9397 private File legacyNativeLibraryPath; 9398 9399 // Example topology: 9400 // /data/app/com.example/base.apk 9401 // /data/app/com.example/split_foo.apk 9402 // /data/app/com.example/lib/arm/libfoo.so 9403 // /data/app/com.example/lib/arm64/libfoo.so 9404 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 9405 9406 /** New install */ FileInstallArgs(InstallParams params)9407 FileInstallArgs(InstallParams params) { 9408 super(params.origin, params.observer, params.installFlags, 9409 params.installerPackageName, params.getManifestDigest(), params.getUser(), 9410 null /* instruction sets */, params.packageAbiOverride); 9411 if (isFwdLocked()) { 9412 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 9413 } 9414 } 9415 9416 /** Existing install */ FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath, String[] instructionSets)9417 FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath, 9418 String[] instructionSets) { 9419 super(OriginInfo.fromNothing(), null, 0, null, null, null, instructionSets, null); 9420 this.codeFile = (codePath != null) ? new File(codePath) : null; 9421 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 9422 this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ? 9423 new File(legacyNativeLibraryPath) : null; 9424 } 9425 checkFreeStorage(IMediaContainerService imcs)9426 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 9427 final long sizeBytes = imcs.calculateInstalledSize(origin.file.getAbsolutePath(), 9428 isFwdLocked(), abiOverride); 9429 9430 final StorageManager storage = StorageManager.from(mContext); 9431 return (sizeBytes <= storage.getStorageBytesUntilLow(Environment.getDataDirectory())); 9432 } 9433 copyApk(IMediaContainerService imcs, boolean temp)9434 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 9435 if (origin.staged) { 9436 Slog.d(TAG, origin.file + " already staged; skipping copy"); 9437 codeFile = origin.file; 9438 resourceFile = origin.file; 9439 return PackageManager.INSTALL_SUCCEEDED; 9440 } 9441 9442 try { 9443 final File tempDir = mInstallerService.allocateInternalStageDirLegacy(); 9444 codeFile = tempDir; 9445 resourceFile = tempDir; 9446 } catch (IOException e) { 9447 Slog.w(TAG, "Failed to create copy file: " + e); 9448 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9449 } 9450 9451 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 9452 @Override 9453 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 9454 if (!FileUtils.isValidExtFilename(name)) { 9455 throw new IllegalArgumentException("Invalid filename: " + name); 9456 } 9457 try { 9458 final File file = new File(codeFile, name); 9459 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 9460 O_RDWR | O_CREAT, 0644); 9461 Os.chmod(file.getAbsolutePath(), 0644); 9462 return new ParcelFileDescriptor(fd); 9463 } catch (ErrnoException e) { 9464 throw new RemoteException("Failed to open: " + e.getMessage()); 9465 } 9466 } 9467 }; 9468 9469 int ret = PackageManager.INSTALL_SUCCEEDED; 9470 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 9471 if (ret != PackageManager.INSTALL_SUCCEEDED) { 9472 Slog.e(TAG, "Failed to copy package"); 9473 return ret; 9474 } 9475 9476 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 9477 NativeLibraryHelper.Handle handle = null; 9478 try { 9479 handle = NativeLibraryHelper.Handle.create(codeFile); 9480 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 9481 abiOverride); 9482 } catch (IOException e) { 9483 Slog.e(TAG, "Copying native libraries failed", e); 9484 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 9485 } finally { 9486 IoUtils.closeQuietly(handle); 9487 } 9488 9489 return ret; 9490 } 9491 doPreInstall(int status)9492 int doPreInstall(int status) { 9493 if (status != PackageManager.INSTALL_SUCCEEDED) { 9494 cleanUp(); 9495 } 9496 return status; 9497 } 9498 doRename(int status, PackageParser.Package pkg, String oldCodePath)9499 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 9500 if (status != PackageManager.INSTALL_SUCCEEDED) { 9501 cleanUp(); 9502 return false; 9503 } else { 9504 final File beforeCodeFile = codeFile; 9505 final File afterCodeFile = getNextCodePath(pkg.packageName); 9506 9507 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 9508 try { 9509 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 9510 } catch (ErrnoException e) { 9511 Slog.d(TAG, "Failed to rename", e); 9512 return false; 9513 } 9514 9515 if (!SELinux.restoreconRecursive(afterCodeFile)) { 9516 Slog.d(TAG, "Failed to restorecon"); 9517 return false; 9518 } 9519 9520 // Reflect the rename internally 9521 codeFile = afterCodeFile; 9522 resourceFile = afterCodeFile; 9523 9524 // Reflect the rename in scanned details 9525 pkg.codePath = afterCodeFile.getAbsolutePath(); 9526 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 9527 pkg.baseCodePath); 9528 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 9529 pkg.splitCodePaths); 9530 9531 // Reflect the rename in app info 9532 pkg.applicationInfo.setCodePath(pkg.codePath); 9533 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 9534 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 9535 pkg.applicationInfo.setResourcePath(pkg.codePath); 9536 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 9537 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 9538 9539 return true; 9540 } 9541 } 9542 doPostInstall(int status, int uid)9543 int doPostInstall(int status, int uid) { 9544 if (status != PackageManager.INSTALL_SUCCEEDED) { 9545 cleanUp(); 9546 } 9547 return status; 9548 } 9549 9550 @Override getCodePath()9551 String getCodePath() { 9552 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 9553 } 9554 9555 @Override getResourcePath()9556 String getResourcePath() { 9557 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 9558 } 9559 9560 @Override getLegacyNativeLibraryPath()9561 String getLegacyNativeLibraryPath() { 9562 return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null; 9563 } 9564 cleanUp()9565 private boolean cleanUp() { 9566 if (codeFile == null || !codeFile.exists()) { 9567 return false; 9568 } 9569 9570 if (codeFile.isDirectory()) { 9571 FileUtils.deleteContents(codeFile); 9572 } 9573 codeFile.delete(); 9574 9575 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 9576 resourceFile.delete(); 9577 } 9578 9579 if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) { 9580 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) { 9581 Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath); 9582 } 9583 legacyNativeLibraryPath.delete(); 9584 } 9585 9586 return true; 9587 } 9588 cleanUpResourcesLI()9589 void cleanUpResourcesLI() { 9590 // Try enumerating all code paths before deleting 9591 List<String> allCodePaths = Collections.EMPTY_LIST; 9592 if (codeFile != null && codeFile.exists()) { 9593 try { 9594 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 9595 allCodePaths = pkg.getAllCodePaths(); 9596 } catch (PackageParserException e) { 9597 // Ignored; we tried our best 9598 } 9599 } 9600 9601 cleanUp(); 9602 9603 if (!allCodePaths.isEmpty()) { 9604 if (instructionSets == null) { 9605 throw new IllegalStateException("instructionSet == null"); 9606 } 9607 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 9608 for (String codePath : allCodePaths) { 9609 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 9610 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 9611 if (retCode < 0) { 9612 Slog.w(TAG, "Couldn't remove dex file for package: " 9613 + " at location " + codePath + ", retcode=" + retCode); 9614 // we don't consider this to be a failure of the core package deletion 9615 } 9616 } 9617 } 9618 } 9619 } 9620 doPostDeleteLI(boolean delete)9621 boolean doPostDeleteLI(boolean delete) { 9622 // XXX err, shouldn't we respect the delete flag? 9623 cleanUpResourcesLI(); 9624 return true; 9625 } 9626 } 9627 isAsecExternal(String cid)9628 private boolean isAsecExternal(String cid) { 9629 final String asecPath = PackageHelper.getSdFilesystem(cid); 9630 return !asecPath.startsWith(mAsecInternalPath); 9631 } 9632 maybeThrowExceptionForMultiArchCopy(String message, int copyRet)9633 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 9634 PackageManagerException { 9635 if (copyRet < 0) { 9636 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 9637 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 9638 throw new PackageManagerException(copyRet, message); 9639 } 9640 } 9641 } 9642 9643 /** 9644 * Extract the MountService "container ID" from the full code path of an 9645 * .apk. 9646 */ cidFromCodePath(String fullCodePath)9647 static String cidFromCodePath(String fullCodePath) { 9648 int eidx = fullCodePath.lastIndexOf("/"); 9649 String subStr1 = fullCodePath.substring(0, eidx); 9650 int sidx = subStr1.lastIndexOf("/"); 9651 return subStr1.substring(sidx+1, eidx); 9652 } 9653 9654 /** 9655 * Logic to handle installation of ASEC applications, including copying and 9656 * renaming logic. 9657 */ 9658 class AsecInstallArgs extends InstallArgs { 9659 static final String RES_FILE_NAME = "pkg.apk"; 9660 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 9661 9662 String cid; 9663 String packagePath; 9664 String resourcePath; 9665 String legacyNativeLibraryDir; 9666 9667 /** New install */ AsecInstallArgs(InstallParams params)9668 AsecInstallArgs(InstallParams params) { 9669 super(params.origin, params.observer, params.installFlags, 9670 params.installerPackageName, params.getManifestDigest(), 9671 params.getUser(), null /* instruction sets */, 9672 params.packageAbiOverride); 9673 } 9674 9675 /** Existing install */ AsecInstallArgs(String fullCodePath, String[] instructionSets, boolean isExternal, boolean isForwardLocked)9676 AsecInstallArgs(String fullCodePath, String[] instructionSets, 9677 boolean isExternal, boolean isForwardLocked) { 9678 super(OriginInfo.fromNothing(), null, (isExternal ? INSTALL_EXTERNAL : 0) 9679 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 9680 instructionSets, null); 9681 // Hackily pretend we're still looking at a full code path 9682 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 9683 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 9684 } 9685 9686 // Extract cid from fullCodePath 9687 int eidx = fullCodePath.lastIndexOf("/"); 9688 String subStr1 = fullCodePath.substring(0, eidx); 9689 int sidx = subStr1.lastIndexOf("/"); 9690 cid = subStr1.substring(sidx+1, eidx); 9691 setMountPath(subStr1); 9692 } 9693 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked)9694 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 9695 super(OriginInfo.fromNothing(), null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 9696 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 9697 instructionSets, null); 9698 this.cid = cid; 9699 setMountPath(PackageHelper.getSdDir(cid)); 9700 } 9701 createCopyFile()9702 void createCopyFile() { 9703 cid = mInstallerService.allocateExternalStageCidLegacy(); 9704 } 9705 checkFreeStorage(IMediaContainerService imcs)9706 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 9707 final long sizeBytes = imcs.calculateInstalledSize(packagePath, isFwdLocked(), 9708 abiOverride); 9709 9710 final File target; 9711 if (isExternal()) { 9712 target = new UserEnvironment(UserHandle.USER_OWNER).getExternalStorageDirectory(); 9713 } else { 9714 target = Environment.getDataDirectory(); 9715 } 9716 9717 final StorageManager storage = StorageManager.from(mContext); 9718 return (sizeBytes <= storage.getStorageBytesUntilLow(target)); 9719 } 9720 copyApk(IMediaContainerService imcs, boolean temp)9721 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 9722 if (origin.staged) { 9723 Slog.d(TAG, origin.cid + " already staged; skipping copy"); 9724 cid = origin.cid; 9725 setMountPath(PackageHelper.getSdDir(cid)); 9726 return PackageManager.INSTALL_SUCCEEDED; 9727 } 9728 9729 if (temp) { 9730 createCopyFile(); 9731 } else { 9732 /* 9733 * Pre-emptively destroy the container since it's destroyed if 9734 * copying fails due to it existing anyway. 9735 */ 9736 PackageHelper.destroySdDir(cid); 9737 } 9738 9739 final String newMountPath = imcs.copyPackageToContainer( 9740 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternal(), 9741 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 9742 9743 if (newMountPath != null) { 9744 setMountPath(newMountPath); 9745 return PackageManager.INSTALL_SUCCEEDED; 9746 } else { 9747 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9748 } 9749 } 9750 9751 @Override getCodePath()9752 String getCodePath() { 9753 return packagePath; 9754 } 9755 9756 @Override getResourcePath()9757 String getResourcePath() { 9758 return resourcePath; 9759 } 9760 9761 @Override getLegacyNativeLibraryPath()9762 String getLegacyNativeLibraryPath() { 9763 return legacyNativeLibraryDir; 9764 } 9765 doPreInstall(int status)9766 int doPreInstall(int status) { 9767 if (status != PackageManager.INSTALL_SUCCEEDED) { 9768 // Destroy container 9769 PackageHelper.destroySdDir(cid); 9770 } else { 9771 boolean mounted = PackageHelper.isContainerMounted(cid); 9772 if (!mounted) { 9773 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 9774 Process.SYSTEM_UID); 9775 if (newMountPath != null) { 9776 setMountPath(newMountPath); 9777 } else { 9778 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9779 } 9780 } 9781 } 9782 return status; 9783 } 9784 doRename(int status, PackageParser.Package pkg, String oldCodePath)9785 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 9786 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 9787 String newMountPath = null; 9788 if (PackageHelper.isContainerMounted(cid)) { 9789 // Unmount the container 9790 if (!PackageHelper.unMountSdDir(cid)) { 9791 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 9792 return false; 9793 } 9794 } 9795 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 9796 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 9797 " which might be stale. Will try to clean up."); 9798 // Clean up the stale container and proceed to recreate. 9799 if (!PackageHelper.destroySdDir(newCacheId)) { 9800 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 9801 return false; 9802 } 9803 // Successfully cleaned up stale container. Try to rename again. 9804 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 9805 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 9806 + " inspite of cleaning it up."); 9807 return false; 9808 } 9809 } 9810 if (!PackageHelper.isContainerMounted(newCacheId)) { 9811 Slog.w(TAG, "Mounting container " + newCacheId); 9812 newMountPath = PackageHelper.mountSdDir(newCacheId, 9813 getEncryptKey(), Process.SYSTEM_UID); 9814 } else { 9815 newMountPath = PackageHelper.getSdDir(newCacheId); 9816 } 9817 if (newMountPath == null) { 9818 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 9819 return false; 9820 } 9821 Log.i(TAG, "Succesfully renamed " + cid + 9822 " to " + newCacheId + 9823 " at new path: " + newMountPath); 9824 cid = newCacheId; 9825 9826 final File beforeCodeFile = new File(packagePath); 9827 setMountPath(newMountPath); 9828 final File afterCodeFile = new File(packagePath); 9829 9830 // Reflect the rename in scanned details 9831 pkg.codePath = afterCodeFile.getAbsolutePath(); 9832 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 9833 pkg.baseCodePath); 9834 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 9835 pkg.splitCodePaths); 9836 9837 // Reflect the rename in app info 9838 pkg.applicationInfo.setCodePath(pkg.codePath); 9839 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 9840 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 9841 pkg.applicationInfo.setResourcePath(pkg.codePath); 9842 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 9843 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 9844 9845 return true; 9846 } 9847 setMountPath(String mountPath)9848 private void setMountPath(String mountPath) { 9849 final File mountFile = new File(mountPath); 9850 9851 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 9852 if (monolithicFile.exists()) { 9853 packagePath = monolithicFile.getAbsolutePath(); 9854 if (isFwdLocked()) { 9855 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 9856 } else { 9857 resourcePath = packagePath; 9858 } 9859 } else { 9860 packagePath = mountFile.getAbsolutePath(); 9861 resourcePath = packagePath; 9862 } 9863 9864 legacyNativeLibraryDir = new File(mountFile, LIB_DIR_NAME).getAbsolutePath(); 9865 } 9866 doPostInstall(int status, int uid)9867 int doPostInstall(int status, int uid) { 9868 if (status != PackageManager.INSTALL_SUCCEEDED) { 9869 cleanUp(); 9870 } else { 9871 final int groupOwner; 9872 final String protectedFile; 9873 if (isFwdLocked()) { 9874 groupOwner = UserHandle.getSharedAppGid(uid); 9875 protectedFile = RES_FILE_NAME; 9876 } else { 9877 groupOwner = -1; 9878 protectedFile = null; 9879 } 9880 9881 if (uid < Process.FIRST_APPLICATION_UID 9882 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 9883 Slog.e(TAG, "Failed to finalize " + cid); 9884 PackageHelper.destroySdDir(cid); 9885 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9886 } 9887 9888 boolean mounted = PackageHelper.isContainerMounted(cid); 9889 if (!mounted) { 9890 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 9891 } 9892 } 9893 return status; 9894 } 9895 cleanUp()9896 private void cleanUp() { 9897 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 9898 9899 // Destroy secure container 9900 PackageHelper.destroySdDir(cid); 9901 } 9902 getAllCodePaths()9903 private List<String> getAllCodePaths() { 9904 final File codeFile = new File(getCodePath()); 9905 if (codeFile != null && codeFile.exists()) { 9906 try { 9907 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 9908 return pkg.getAllCodePaths(); 9909 } catch (PackageParserException e) { 9910 // Ignored; we tried our best 9911 } 9912 } 9913 return Collections.EMPTY_LIST; 9914 } 9915 cleanUpResourcesLI()9916 void cleanUpResourcesLI() { 9917 // Enumerate all code paths before deleting 9918 cleanUpResourcesLI(getAllCodePaths()); 9919 } 9920 cleanUpResourcesLI(List<String> allCodePaths)9921 private void cleanUpResourcesLI(List<String> allCodePaths) { 9922 cleanUp(); 9923 9924 if (!allCodePaths.isEmpty()) { 9925 if (instructionSets == null) { 9926 throw new IllegalStateException("instructionSet == null"); 9927 } 9928 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 9929 for (String codePath : allCodePaths) { 9930 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 9931 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 9932 if (retCode < 0) { 9933 Slog.w(TAG, "Couldn't remove dex file for package: " 9934 + " at location " + codePath + ", retcode=" + retCode); 9935 // we don't consider this to be a failure of the core package deletion 9936 } 9937 } 9938 } 9939 } 9940 } 9941 matchContainer(String app)9942 boolean matchContainer(String app) { 9943 if (cid.startsWith(app)) { 9944 return true; 9945 } 9946 return false; 9947 } 9948 getPackageName()9949 String getPackageName() { 9950 return getAsecPackageName(cid); 9951 } 9952 doPostDeleteLI(boolean delete)9953 boolean doPostDeleteLI(boolean delete) { 9954 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 9955 final List<String> allCodePaths = getAllCodePaths(); 9956 boolean mounted = PackageHelper.isContainerMounted(cid); 9957 if (mounted) { 9958 // Unmount first 9959 if (PackageHelper.unMountSdDir(cid)) { 9960 mounted = false; 9961 } 9962 } 9963 if (!mounted && delete) { 9964 cleanUpResourcesLI(allCodePaths); 9965 } 9966 return !mounted; 9967 } 9968 9969 @Override doPreCopy()9970 int doPreCopy() { 9971 if (isFwdLocked()) { 9972 if (!PackageHelper.fixSdPermissions(cid, 9973 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 9974 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9975 } 9976 } 9977 9978 return PackageManager.INSTALL_SUCCEEDED; 9979 } 9980 9981 @Override doPostCopy(int uid)9982 int doPostCopy(int uid) { 9983 if (isFwdLocked()) { 9984 if (uid < Process.FIRST_APPLICATION_UID 9985 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 9986 RES_FILE_NAME)) { 9987 Slog.e(TAG, "Failed to finalize " + cid); 9988 PackageHelper.destroySdDir(cid); 9989 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9990 } 9991 } 9992 9993 return PackageManager.INSTALL_SUCCEEDED; 9994 } 9995 } 9996 getAsecPackageName(String packageCid)9997 static String getAsecPackageName(String packageCid) { 9998 int idx = packageCid.lastIndexOf("-"); 9999 if (idx == -1) { 10000 return packageCid; 10001 } 10002 return packageCid.substring(0, idx); 10003 } 10004 10005 // Utility method used to create code paths based on package name and available index. getNextCodePath(String oldCodePath, String prefix, String suffix)10006 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 10007 String idxStr = ""; 10008 int idx = 1; 10009 // Fall back to default value of idx=1 if prefix is not 10010 // part of oldCodePath 10011 if (oldCodePath != null) { 10012 String subStr = oldCodePath; 10013 // Drop the suffix right away 10014 if (suffix != null && subStr.endsWith(suffix)) { 10015 subStr = subStr.substring(0, subStr.length() - suffix.length()); 10016 } 10017 // If oldCodePath already contains prefix find out the 10018 // ending index to either increment or decrement. 10019 int sidx = subStr.lastIndexOf(prefix); 10020 if (sidx != -1) { 10021 subStr = subStr.substring(sidx + prefix.length()); 10022 if (subStr != null) { 10023 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 10024 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 10025 } 10026 try { 10027 idx = Integer.parseInt(subStr); 10028 if (idx <= 1) { 10029 idx++; 10030 } else { 10031 idx--; 10032 } 10033 } catch(NumberFormatException e) { 10034 } 10035 } 10036 } 10037 } 10038 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 10039 return prefix + idxStr; 10040 } 10041 getNextCodePath(String packageName)10042 private File getNextCodePath(String packageName) { 10043 int suffix = 1; 10044 File result; 10045 do { 10046 result = new File(mAppInstallDir, packageName + "-" + suffix); 10047 suffix++; 10048 } while (result.exists()); 10049 return result; 10050 } 10051 10052 // Utility method used to ignore ADD/REMOVE events 10053 // by directory observer. ignoreCodePath(String fullPathStr)10054 private static boolean ignoreCodePath(String fullPathStr) { 10055 String apkName = deriveCodePathName(fullPathStr); 10056 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX); 10057 if (idx != -1 && ((idx+1) < apkName.length())) { 10058 // Make sure the package ends with a numeral 10059 String version = apkName.substring(idx+1); 10060 try { 10061 Integer.parseInt(version); 10062 return true; 10063 } catch (NumberFormatException e) {} 10064 } 10065 return false; 10066 } 10067 10068 // Utility method that returns the relative package path with respect 10069 // to the installation directory. Like say for /data/data/com.test-1.apk 10070 // string com.test-1 is returned. deriveCodePathName(String codePath)10071 static String deriveCodePathName(String codePath) { 10072 if (codePath == null) { 10073 return null; 10074 } 10075 final File codeFile = new File(codePath); 10076 final String name = codeFile.getName(); 10077 if (codeFile.isDirectory()) { 10078 return name; 10079 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 10080 final int lastDot = name.lastIndexOf('.'); 10081 return name.substring(0, lastDot); 10082 } else { 10083 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 10084 return null; 10085 } 10086 } 10087 10088 class PackageInstalledInfo { 10089 String name; 10090 int uid; 10091 // The set of users that originally had this package installed. 10092 int[] origUsers; 10093 // The set of users that now have this package installed. 10094 int[] newUsers; 10095 PackageParser.Package pkg; 10096 int returnCode; 10097 String returnMsg; 10098 PackageRemovedInfo removedInfo; 10099 setError(int code, String msg)10100 public void setError(int code, String msg) { 10101 returnCode = code; 10102 returnMsg = msg; 10103 Slog.w(TAG, msg); 10104 } 10105 setError(String msg, PackageParserException e)10106 public void setError(String msg, PackageParserException e) { 10107 returnCode = e.error; 10108 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 10109 Slog.w(TAG, msg, e); 10110 } 10111 setError(String msg, PackageManagerException e)10112 public void setError(String msg, PackageManagerException e) { 10113 returnCode = e.error; 10114 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 10115 Slog.w(TAG, msg, e); 10116 } 10117 10118 // In some error cases we want to convey more info back to the observer 10119 String origPackage; 10120 String origPermission; 10121 } 10122 10123 /* 10124 * Install a non-existing package. 10125 */ installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, String installerPackageName, PackageInstalledInfo res)10126 private void installNewPackageLI(PackageParser.Package pkg, 10127 int parseFlags, int scanFlags, UserHandle user, 10128 String installerPackageName, PackageInstalledInfo res) { 10129 // Remember this for later, in case we need to rollback this install 10130 String pkgName = pkg.packageName; 10131 10132 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 10133 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists(); 10134 synchronized(mPackages) { 10135 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 10136 // A package with the same name is already installed, though 10137 // it has been renamed to an older name. The package we 10138 // are trying to install should be installed as an update to 10139 // the existing one, but that has not been requested, so bail. 10140 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 10141 + " without first uninstalling package running as " 10142 + mSettings.mRenamedPackages.get(pkgName)); 10143 return; 10144 } 10145 if (mPackages.containsKey(pkgName)) { 10146 // Don't allow installation over an existing package with the same name. 10147 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 10148 + " without first uninstalling."); 10149 return; 10150 } 10151 } 10152 10153 try { 10154 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 10155 System.currentTimeMillis(), user); 10156 10157 updateSettingsLI(newPackage, installerPackageName, null, null, res); 10158 // delete the partially installed application. the data directory will have to be 10159 // restored if it was already existing 10160 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10161 // remove package from internal structures. Note that we want deletePackageX to 10162 // delete the package data and cache directories that it created in 10163 // scanPackageLocked, unless those directories existed before we even tried to 10164 // install. 10165 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 10166 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 10167 res.removedInfo, true); 10168 } 10169 10170 } catch (PackageManagerException e) { 10171 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10172 } 10173 } 10174 checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg)10175 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 10176 // Upgrade keysets are being used. Determine if new package has a superset of the 10177 // required keys. 10178 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 10179 KeySetManagerService ksms = mSettings.mKeySetManagerService; 10180 for (int i = 0; i < upgradeKeySets.length; i++) { 10181 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 10182 if (newPkg.mSigningKeys.containsAll(upgradeSet)) { 10183 return true; 10184 } 10185 } 10186 return false; 10187 } 10188 replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, String installerPackageName, PackageInstalledInfo res)10189 private void replacePackageLI(PackageParser.Package pkg, 10190 int parseFlags, int scanFlags, UserHandle user, 10191 String installerPackageName, PackageInstalledInfo res) { 10192 PackageParser.Package oldPackage; 10193 String pkgName = pkg.packageName; 10194 int[] allUsers; 10195 boolean[] perUserInstalled; 10196 10197 // First find the old package info and check signatures 10198 synchronized(mPackages) { 10199 oldPackage = mPackages.get(pkgName); 10200 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 10201 PackageSetting ps = mSettings.mPackages.get(pkgName); 10202 if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 10203 // default to original signature matching 10204 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 10205 != PackageManager.SIGNATURE_MATCH) { 10206 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10207 "New package has a different signature: " + pkgName); 10208 return; 10209 } 10210 } else { 10211 if(!checkUpgradeKeySetLP(ps, pkg)) { 10212 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 10213 "New package not signed by keys specified by upgrade-keysets: " 10214 + pkgName); 10215 return; 10216 } 10217 } 10218 10219 // In case of rollback, remember per-user/profile install state 10220 allUsers = sUserManager.getUserIds(); 10221 perUserInstalled = new boolean[allUsers.length]; 10222 for (int i = 0; i < allUsers.length; i++) { 10223 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 10224 } 10225 } 10226 10227 boolean sysPkg = (isSystemApp(oldPackage)); 10228 if (sysPkg) { 10229 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 10230 user, allUsers, perUserInstalled, installerPackageName, res); 10231 } else { 10232 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 10233 user, allUsers, perUserInstalled, installerPackageName, res); 10234 } 10235 } 10236 replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, PackageInstalledInfo res)10237 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 10238 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 10239 int[] allUsers, boolean[] perUserInstalled, 10240 String installerPackageName, PackageInstalledInfo res) { 10241 String pkgName = deletedPackage.packageName; 10242 boolean deletedPkg = true; 10243 boolean updatedSettings = false; 10244 10245 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 10246 + deletedPackage); 10247 long origUpdateTime; 10248 if (pkg.mExtras != null) { 10249 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 10250 } else { 10251 origUpdateTime = 0; 10252 } 10253 10254 // First delete the existing package while retaining the data directory 10255 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 10256 res.removedInfo, true)) { 10257 // If the existing package wasn't successfully deleted 10258 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 10259 deletedPkg = false; 10260 } else { 10261 // Successfully deleted the old package; proceed with replace. 10262 10263 // If deleted package lived in a container, give users a chance to 10264 // relinquish resources before killing. 10265 if (isForwardLocked(deletedPackage) || isExternal(deletedPackage)) { 10266 if (DEBUG_INSTALL) { 10267 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 10268 } 10269 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 10270 final ArrayList<String> pkgList = new ArrayList<String>(1); 10271 pkgList.add(deletedPackage.applicationInfo.packageName); 10272 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 10273 } 10274 10275 deleteCodeCacheDirsLI(pkgName); 10276 try { 10277 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, 10278 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 10279 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); 10280 updatedSettings = true; 10281 } catch (PackageManagerException e) { 10282 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10283 } 10284 } 10285 10286 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10287 // remove package from internal structures. Note that we want deletePackageX to 10288 // delete the package data and cache directories that it created in 10289 // scanPackageLocked, unless those directories existed before we even tried to 10290 // install. 10291 if(updatedSettings) { 10292 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 10293 deletePackageLI( 10294 pkgName, null, true, allUsers, perUserInstalled, 10295 PackageManager.DELETE_KEEP_DATA, 10296 res.removedInfo, true); 10297 } 10298 // Since we failed to install the new package we need to restore the old 10299 // package that we deleted. 10300 if (deletedPkg) { 10301 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 10302 File restoreFile = new File(deletedPackage.codePath); 10303 // Parse old package 10304 boolean oldOnSd = isExternal(deletedPackage); 10305 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 10306 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) | 10307 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0); 10308 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 10309 try { 10310 scanPackageLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, null); 10311 } catch (PackageManagerException e) { 10312 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 10313 + e.getMessage()); 10314 return; 10315 } 10316 // Restore of old package succeeded. Update permissions. 10317 // writer 10318 synchronized (mPackages) { 10319 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 10320 UPDATE_PERMISSIONS_ALL); 10321 // can downgrade to reader 10322 mSettings.writeLPr(); 10323 } 10324 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 10325 } 10326 } 10327 } 10328 replaceSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, int[] allUsers, boolean[] perUserInstalled, String installerPackageName, PackageInstalledInfo res)10329 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 10330 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 10331 int[] allUsers, boolean[] perUserInstalled, 10332 String installerPackageName, PackageInstalledInfo res) { 10333 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 10334 + ", old=" + deletedPackage); 10335 boolean disabledSystem = false; 10336 boolean updatedSettings = false; 10337 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 10338 if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) { 10339 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 10340 } 10341 String packageName = deletedPackage.packageName; 10342 if (packageName == null) { 10343 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 10344 "Attempt to delete null packageName."); 10345 return; 10346 } 10347 PackageParser.Package oldPkg; 10348 PackageSetting oldPkgSetting; 10349 // reader 10350 synchronized (mPackages) { 10351 oldPkg = mPackages.get(packageName); 10352 oldPkgSetting = mSettings.mPackages.get(packageName); 10353 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 10354 (oldPkgSetting == null)) { 10355 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 10356 "Couldn't find package:" + packageName + " information"); 10357 return; 10358 } 10359 } 10360 10361 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); 10362 10363 res.removedInfo.uid = oldPkg.applicationInfo.uid; 10364 res.removedInfo.removedPackage = packageName; 10365 // Remove existing system package 10366 removePackageLI(oldPkgSetting, true); 10367 // writer 10368 synchronized (mPackages) { 10369 disabledSystem = mSettings.disableSystemPackageLPw(packageName); 10370 if (!disabledSystem && deletedPackage != null) { 10371 // We didn't need to disable the .apk as a current system package, 10372 // which means we are replacing another update that is already 10373 // installed. We need to make sure to delete the older one's .apk. 10374 res.removedInfo.args = createInstallArgsForExisting(0, 10375 deletedPackage.applicationInfo.getCodePath(), 10376 deletedPackage.applicationInfo.getResourcePath(), 10377 deletedPackage.applicationInfo.nativeLibraryRootDir, 10378 getAppDexInstructionSets(deletedPackage.applicationInfo)); 10379 } else { 10380 res.removedInfo.args = null; 10381 } 10382 } 10383 10384 // Successfully disabled the old package. Now proceed with re-installation 10385 deleteCodeCacheDirsLI(packageName); 10386 10387 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 10388 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 10389 10390 PackageParser.Package newPackage = null; 10391 try { 10392 newPackage = scanPackageLI(pkg, parseFlags, scanFlags, 0, user); 10393 if (newPackage.mExtras != null) { 10394 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 10395 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 10396 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 10397 10398 // is the update attempting to change shared user? that isn't going to work... 10399 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 10400 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 10401 "Forbidding shared user change from " + oldPkgSetting.sharedUser 10402 + " to " + newPkgSetting.sharedUser); 10403 updatedSettings = true; 10404 } 10405 } 10406 10407 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 10408 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); 10409 updatedSettings = true; 10410 } 10411 10412 } catch (PackageManagerException e) { 10413 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10414 } 10415 10416 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10417 // Re installation failed. Restore old information 10418 // Remove new pkg information 10419 if (newPackage != null) { 10420 removeInstalledPackageLI(newPackage, true); 10421 } 10422 // Add back the old system package 10423 try { 10424 scanPackageLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 10425 } catch (PackageManagerException e) { 10426 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 10427 } 10428 // Restore the old system information in Settings 10429 synchronized (mPackages) { 10430 if (disabledSystem) { 10431 mSettings.enableSystemPackageLPw(packageName); 10432 } 10433 if (updatedSettings) { 10434 mSettings.setInstallerPackageName(packageName, 10435 oldPkgSetting.installerPackageName); 10436 } 10437 mSettings.writeLPr(); 10438 } 10439 } 10440 } 10441 updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res)10442 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 10443 int[] allUsers, boolean[] perUserInstalled, 10444 PackageInstalledInfo res) { 10445 String pkgName = newPackage.packageName; 10446 synchronized (mPackages) { 10447 //write settings. the installStatus will be incomplete at this stage. 10448 //note that the new package setting would have already been 10449 //added to mPackages. It hasn't been persisted yet. 10450 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 10451 mSettings.writeLPr(); 10452 } 10453 10454 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 10455 10456 synchronized (mPackages) { 10457 updatePermissionsLPw(newPackage.packageName, newPackage, 10458 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 10459 ? UPDATE_PERMISSIONS_ALL : 0)); 10460 // For system-bundled packages, we assume that installing an upgraded version 10461 // of the package implies that the user actually wants to run that new code, 10462 // so we enable the package. 10463 if (isSystemApp(newPackage)) { 10464 // NB: implicit assumption that system package upgrades apply to all users 10465 if (DEBUG_INSTALL) { 10466 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 10467 } 10468 PackageSetting ps = mSettings.mPackages.get(pkgName); 10469 if (ps != null) { 10470 if (res.origUsers != null) { 10471 for (int userHandle : res.origUsers) { 10472 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 10473 userHandle, installerPackageName); 10474 } 10475 } 10476 // Also convey the prior install/uninstall state 10477 if (allUsers != null && perUserInstalled != null) { 10478 for (int i = 0; i < allUsers.length; i++) { 10479 if (DEBUG_INSTALL) { 10480 Slog.d(TAG, " user " + allUsers[i] 10481 + " => " + perUserInstalled[i]); 10482 } 10483 ps.setInstalled(perUserInstalled[i], allUsers[i]); 10484 } 10485 // these install state changes will be persisted in the 10486 // upcoming call to mSettings.writeLPr(). 10487 } 10488 } 10489 } 10490 res.name = pkgName; 10491 res.uid = newPackage.applicationInfo.uid; 10492 res.pkg = newPackage; 10493 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 10494 mSettings.setInstallerPackageName(pkgName, installerPackageName); 10495 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 10496 //to update install status 10497 mSettings.writeLPr(); 10498 } 10499 } 10500 installPackageLI(InstallArgs args, PackageInstalledInfo res)10501 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 10502 final int installFlags = args.installFlags; 10503 String installerPackageName = args.installerPackageName; 10504 File tmpPackageFile = new File(args.getCodePath()); 10505 boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 10506 boolean onSd = ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0); 10507 boolean replace = false; 10508 final int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE; 10509 // Result object to be returned 10510 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 10511 10512 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 10513 // Retrieve PackageSettings and parse package 10514 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 10515 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 10516 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0); 10517 PackageParser pp = new PackageParser(); 10518 pp.setSeparateProcesses(mSeparateProcesses); 10519 pp.setDisplayMetrics(mMetrics); 10520 10521 final PackageParser.Package pkg; 10522 try { 10523 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 10524 } catch (PackageParserException e) { 10525 res.setError("Failed parse during installPackageLI", e); 10526 return; 10527 } 10528 10529 // Mark that we have an install time CPU ABI override. 10530 pkg.cpuAbiOverride = args.abiOverride; 10531 10532 String pkgName = res.name = pkg.packageName; 10533 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 10534 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 10535 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 10536 return; 10537 } 10538 } 10539 10540 try { 10541 pp.collectCertificates(pkg, parseFlags); 10542 pp.collectManifestDigest(pkg); 10543 } catch (PackageParserException e) { 10544 res.setError("Failed collect during installPackageLI", e); 10545 return; 10546 } 10547 10548 /* If the installer passed in a manifest digest, compare it now. */ 10549 if (args.manifestDigest != null) { 10550 if (DEBUG_INSTALL) { 10551 final String parsedManifest = pkg.manifestDigest == null ? "null" 10552 : pkg.manifestDigest.toString(); 10553 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 10554 + parsedManifest); 10555 } 10556 10557 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 10558 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 10559 return; 10560 } 10561 } else if (DEBUG_INSTALL) { 10562 final String parsedManifest = pkg.manifestDigest == null 10563 ? "null" : pkg.manifestDigest.toString(); 10564 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 10565 } 10566 10567 // Get rid of all references to package scan path via parser. 10568 pp = null; 10569 String oldCodePath = null; 10570 boolean systemApp = false; 10571 synchronized (mPackages) { 10572 // Check if installing already existing package 10573 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 10574 String oldName = mSettings.mRenamedPackages.get(pkgName); 10575 if (pkg.mOriginalPackages != null 10576 && pkg.mOriginalPackages.contains(oldName) 10577 && mPackages.containsKey(oldName)) { 10578 // This package is derived from an original package, 10579 // and this device has been updating from that original 10580 // name. We must continue using the original name, so 10581 // rename the new package here. 10582 pkg.setPackageName(oldName); 10583 pkgName = pkg.packageName; 10584 replace = true; 10585 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 10586 + oldName + " pkgName=" + pkgName); 10587 } else if (mPackages.containsKey(pkgName)) { 10588 // This package, under its official name, already exists 10589 // on the device; we should replace it. 10590 replace = true; 10591 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 10592 } 10593 } 10594 10595 PackageSetting ps = mSettings.mPackages.get(pkgName); 10596 if (ps != null) { 10597 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 10598 10599 // Quick sanity check that we're signed correctly if updating; 10600 // we'll check this again later when scanning, but we want to 10601 // bail early here before tripping over redefined permissions. 10602 if (!ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 10603 try { 10604 verifySignaturesLP(ps, pkg); 10605 } catch (PackageManagerException e) { 10606 res.setError(e.error, e.getMessage()); 10607 return; 10608 } 10609 } else { 10610 if (!checkUpgradeKeySetLP(ps, pkg)) { 10611 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 10612 + pkg.packageName + " upgrade keys do not match the " 10613 + "previously installed version"); 10614 return; 10615 } 10616 } 10617 10618 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 10619 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 10620 systemApp = (ps.pkg.applicationInfo.flags & 10621 ApplicationInfo.FLAG_SYSTEM) != 0; 10622 } 10623 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 10624 } 10625 10626 // Check whether the newly-scanned package wants to define an already-defined perm 10627 int N = pkg.permissions.size(); 10628 for (int i = N-1; i >= 0; i--) { 10629 PackageParser.Permission perm = pkg.permissions.get(i); 10630 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 10631 if (bp != null) { 10632 // If the defining package is signed with our cert, it's okay. This 10633 // also includes the "updating the same package" case, of course. 10634 // "updating same package" could also involve key-rotation. 10635 final boolean sigsOk; 10636 if (!bp.sourcePackage.equals(pkg.packageName) 10637 || !(bp.packageSetting instanceof PackageSetting) 10638 || !bp.packageSetting.keySetData.isUsingUpgradeKeySets() 10639 || ((PackageSetting) bp.packageSetting).sharedUser != null) { 10640 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 10641 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 10642 } else { 10643 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 10644 } 10645 if (!sigsOk) { 10646 // If the owning package is the system itself, we log but allow 10647 // install to proceed; we fail the install on all other permission 10648 // redefinitions. 10649 if (!bp.sourcePackage.equals("android")) { 10650 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 10651 + pkg.packageName + " attempting to redeclare permission " 10652 + perm.info.name + " already owned by " + bp.sourcePackage); 10653 res.origPermission = perm.info.name; 10654 res.origPackage = bp.sourcePackage; 10655 return; 10656 } else { 10657 Slog.w(TAG, "Package " + pkg.packageName 10658 + " attempting to redeclare system permission " 10659 + perm.info.name + "; ignoring new declaration"); 10660 pkg.permissions.remove(i); 10661 } 10662 } 10663 } 10664 } 10665 10666 } 10667 10668 if (systemApp && onSd) { 10669 // Disable updates to system apps on sdcard 10670 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 10671 "Cannot install updates to system apps on sdcard"); 10672 return; 10673 } 10674 10675 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 10676 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 10677 return; 10678 } 10679 10680 if (replace) { 10681 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 10682 installerPackageName, res); 10683 } else { 10684 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 10685 args.user, installerPackageName, res); 10686 } 10687 synchronized (mPackages) { 10688 final PackageSetting ps = mSettings.mPackages.get(pkgName); 10689 if (ps != null) { 10690 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 10691 } 10692 } 10693 } 10694 isForwardLocked(PackageParser.Package pkg)10695 private static boolean isForwardLocked(PackageParser.Package pkg) { 10696 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 10697 } 10698 isForwardLocked(ApplicationInfo info)10699 private static boolean isForwardLocked(ApplicationInfo info) { 10700 return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 10701 } 10702 isForwardLocked(PackageSetting ps)10703 private boolean isForwardLocked(PackageSetting ps) { 10704 return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 10705 } 10706 isMultiArch(PackageSetting ps)10707 private static boolean isMultiArch(PackageSetting ps) { 10708 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 10709 } 10710 isMultiArch(ApplicationInfo info)10711 private static boolean isMultiArch(ApplicationInfo info) { 10712 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 10713 } 10714 isExternal(PackageParser.Package pkg)10715 private static boolean isExternal(PackageParser.Package pkg) { 10716 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 10717 } 10718 isExternal(PackageSetting ps)10719 private static boolean isExternal(PackageSetting ps) { 10720 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 10721 } 10722 isExternal(ApplicationInfo info)10723 private static boolean isExternal(ApplicationInfo info) { 10724 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 10725 } 10726 isSystemApp(PackageParser.Package pkg)10727 private static boolean isSystemApp(PackageParser.Package pkg) { 10728 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10729 } 10730 isPrivilegedApp(PackageParser.Package pkg)10731 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 10732 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0; 10733 } 10734 isSystemApp(ApplicationInfo info)10735 private static boolean isSystemApp(ApplicationInfo info) { 10736 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10737 } 10738 isSystemApp(PackageSetting ps)10739 private static boolean isSystemApp(PackageSetting ps) { 10740 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 10741 } 10742 isUpdatedSystemApp(PackageSetting ps)10743 private static boolean isUpdatedSystemApp(PackageSetting ps) { 10744 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 10745 } 10746 isUpdatedSystemApp(PackageParser.Package pkg)10747 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) { 10748 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 10749 } 10750 isUpdatedSystemApp(ApplicationInfo info)10751 private static boolean isUpdatedSystemApp(ApplicationInfo info) { 10752 return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 10753 } 10754 packageFlagsToInstallFlags(PackageSetting ps)10755 private int packageFlagsToInstallFlags(PackageSetting ps) { 10756 int installFlags = 0; 10757 if (isExternal(ps)) { 10758 installFlags |= PackageManager.INSTALL_EXTERNAL; 10759 } 10760 if (isForwardLocked(ps)) { 10761 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 10762 } 10763 return installFlags; 10764 } 10765 deleteTempPackageFiles()10766 private void deleteTempPackageFiles() { 10767 final FilenameFilter filter = new FilenameFilter() { 10768 public boolean accept(File dir, String name) { 10769 return name.startsWith("vmdl") && name.endsWith(".tmp"); 10770 } 10771 }; 10772 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 10773 file.delete(); 10774 } 10775 } 10776 10777 @Override deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, int flags)10778 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 10779 int flags) { 10780 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 10781 flags); 10782 } 10783 10784 @Override deletePackage(final String packageName, final IPackageDeleteObserver2 observer, final int userId, final int flags)10785 public void deletePackage(final String packageName, 10786 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 10787 mContext.enforceCallingOrSelfPermission( 10788 android.Manifest.permission.DELETE_PACKAGES, null); 10789 final int uid = Binder.getCallingUid(); 10790 if (UserHandle.getUserId(uid) != userId) { 10791 mContext.enforceCallingPermission( 10792 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10793 "deletePackage for user " + userId); 10794 } 10795 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 10796 try { 10797 observer.onPackageDeleted(packageName, 10798 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 10799 } catch (RemoteException re) { 10800 } 10801 return; 10802 } 10803 10804 boolean uninstallBlocked = false; 10805 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { 10806 int[] users = sUserManager.getUserIds(); 10807 for (int i = 0; i < users.length; ++i) { 10808 if (getBlockUninstallForUser(packageName, users[i])) { 10809 uninstallBlocked = true; 10810 break; 10811 } 10812 } 10813 } else { 10814 uninstallBlocked = getBlockUninstallForUser(packageName, userId); 10815 } 10816 if (uninstallBlocked) { 10817 try { 10818 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED, 10819 null); 10820 } catch (RemoteException re) { 10821 } 10822 return; 10823 } 10824 10825 if (DEBUG_REMOVE) { 10826 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 10827 } 10828 // Queue up an async operation since the package deletion may take a little while. 10829 mHandler.post(new Runnable() { 10830 public void run() { 10831 mHandler.removeCallbacks(this); 10832 final int returnCode = deletePackageX(packageName, userId, flags); 10833 if (observer != null) { 10834 try { 10835 observer.onPackageDeleted(packageName, returnCode, null); 10836 } catch (RemoteException e) { 10837 Log.i(TAG, "Observer no longer exists."); 10838 } //end catch 10839 } //end if 10840 } //end run 10841 }); 10842 } 10843 isPackageDeviceAdmin(String packageName, int userId)10844 private boolean isPackageDeviceAdmin(String packageName, int userId) { 10845 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 10846 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 10847 try { 10848 if (dpm != null) { 10849 if (dpm.isDeviceOwner(packageName)) { 10850 return true; 10851 } 10852 int[] users; 10853 if (userId == UserHandle.USER_ALL) { 10854 users = sUserManager.getUserIds(); 10855 } else { 10856 users = new int[]{userId}; 10857 } 10858 for (int i = 0; i < users.length; ++i) { 10859 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 10860 return true; 10861 } 10862 } 10863 } 10864 } catch (RemoteException e) { 10865 } 10866 return false; 10867 } 10868 10869 /** 10870 * This method is an internal method that could be get invoked either 10871 * to delete an installed package or to clean up a failed installation. 10872 * After deleting an installed package, a broadcast is sent to notify any 10873 * listeners that the package has been installed. For cleaning up a failed 10874 * installation, the broadcast is not necessary since the package's 10875 * installation wouldn't have sent the initial broadcast either 10876 * The key steps in deleting a package are 10877 * deleting the package information in internal structures like mPackages, 10878 * deleting the packages base directories through installd 10879 * updating mSettings to reflect current status 10880 * persisting settings for later use 10881 * sending a broadcast if necessary 10882 */ deletePackageX(String packageName, int userId, int flags)10883 private int deletePackageX(String packageName, int userId, int flags) { 10884 final PackageRemovedInfo info = new PackageRemovedInfo(); 10885 final boolean res; 10886 10887 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 10888 ? UserHandle.ALL : new UserHandle(userId); 10889 10890 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 10891 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 10892 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 10893 } 10894 10895 boolean removedForAllUsers = false; 10896 boolean systemUpdate = false; 10897 10898 // for the uninstall-updates case and restricted profiles, remember the per- 10899 // userhandle installed state 10900 int[] allUsers; 10901 boolean[] perUserInstalled; 10902 synchronized (mPackages) { 10903 PackageSetting ps = mSettings.mPackages.get(packageName); 10904 allUsers = sUserManager.getUserIds(); 10905 perUserInstalled = new boolean[allUsers.length]; 10906 for (int i = 0; i < allUsers.length; i++) { 10907 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 10908 } 10909 } 10910 10911 synchronized (mInstallLock) { 10912 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 10913 res = deletePackageLI(packageName, removeForUser, 10914 true, allUsers, perUserInstalled, 10915 flags | REMOVE_CHATTY, info, true); 10916 systemUpdate = info.isRemovedPackageSystemUpdate; 10917 if (res && !systemUpdate && mPackages.get(packageName) == null) { 10918 removedForAllUsers = true; 10919 } 10920 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 10921 + " removedForAllUsers=" + removedForAllUsers); 10922 } 10923 10924 if (res) { 10925 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 10926 10927 // If the removed package was a system update, the old system package 10928 // was re-enabled; we need to broadcast this information 10929 if (systemUpdate) { 10930 Bundle extras = new Bundle(1); 10931 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 10932 ? info.removedAppId : info.uid); 10933 extras.putBoolean(Intent.EXTRA_REPLACING, true); 10934 10935 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 10936 extras, null, null, null); 10937 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 10938 extras, null, null, null); 10939 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 10940 null, packageName, null, null); 10941 } 10942 } 10943 // Force a gc here. 10944 Runtime.getRuntime().gc(); 10945 // Delete the resources here after sending the broadcast to let 10946 // other processes clean up before deleting resources. 10947 if (info.args != null) { 10948 synchronized (mInstallLock) { 10949 info.args.doPostDeleteLI(true); 10950 } 10951 } 10952 10953 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 10954 } 10955 10956 static class PackageRemovedInfo { 10957 String removedPackage; 10958 int uid = -1; 10959 int removedAppId = -1; 10960 int[] removedUsers = null; 10961 boolean isRemovedPackageSystemUpdate = false; 10962 // Clean up resources deleted packages. 10963 InstallArgs args = null; 10964 sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers)10965 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 10966 Bundle extras = new Bundle(1); 10967 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 10968 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 10969 if (replacing) { 10970 extras.putBoolean(Intent.EXTRA_REPLACING, true); 10971 } 10972 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 10973 if (removedPackage != null) { 10974 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 10975 extras, null, null, removedUsers); 10976 if (fullRemove && !replacing) { 10977 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 10978 extras, null, null, removedUsers); 10979 } 10980 } 10981 if (removedAppId >= 0) { 10982 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 10983 removedUsers); 10984 } 10985 } 10986 } 10987 10988 /* 10989 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 10990 * flag is not set, the data directory is removed as well. 10991 * make sure this flag is set for partially installed apps. If not its meaningless to 10992 * delete a partially installed application. 10993 */ removePackageDataLI(PackageSetting ps, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, int flags, boolean writeSettings)10994 private void removePackageDataLI(PackageSetting ps, 10995 int[] allUserHandles, boolean[] perUserInstalled, 10996 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 10997 String packageName = ps.name; 10998 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 10999 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 11000 // Retrieve object to delete permissions for shared user later on 11001 final PackageSetting deletedPs; 11002 // reader 11003 synchronized (mPackages) { 11004 deletedPs = mSettings.mPackages.get(packageName); 11005 if (outInfo != null) { 11006 outInfo.removedPackage = packageName; 11007 outInfo.removedUsers = deletedPs != null 11008 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 11009 : null; 11010 } 11011 } 11012 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 11013 removeDataDirsLI(packageName); 11014 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 11015 } 11016 // writer 11017 synchronized (mPackages) { 11018 if (deletedPs != null) { 11019 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 11020 if (outInfo != null) { 11021 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 11022 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 11023 } 11024 if (deletedPs != null) { 11025 updatePermissionsLPw(deletedPs.name, null, 0); 11026 if (deletedPs.sharedUser != null) { 11027 // remove permissions associated with package 11028 mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids); 11029 } 11030 } 11031 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 11032 } 11033 // make sure to preserve per-user disabled state if this removal was just 11034 // a downgrade of a system app to the factory package 11035 if (allUserHandles != null && perUserInstalled != null) { 11036 if (DEBUG_REMOVE) { 11037 Slog.d(TAG, "Propagating install state across downgrade"); 11038 } 11039 for (int i = 0; i < allUserHandles.length; i++) { 11040 if (DEBUG_REMOVE) { 11041 Slog.d(TAG, " user " + allUserHandles[i] 11042 + " => " + perUserInstalled[i]); 11043 } 11044 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 11045 } 11046 } 11047 } 11048 // can downgrade to reader 11049 if (writeSettings) { 11050 // Save settings now 11051 mSettings.writeLPr(); 11052 } 11053 } 11054 if (outInfo != null) { 11055 // A user ID was deleted here. Go through all users and remove it 11056 // from KeyStore. 11057 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 11058 } 11059 } 11060 locationIsPrivileged(File path)11061 static boolean locationIsPrivileged(File path) { 11062 try { 11063 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 11064 .getCanonicalPath(); 11065 return path.getCanonicalPath().startsWith(privilegedAppDir); 11066 } catch (IOException e) { 11067 Slog.e(TAG, "Unable to access code path " + path); 11068 } 11069 return false; 11070 } 11071 11072 /* 11073 * Tries to delete system package. 11074 */ deleteSystemPackageLI(PackageSetting newPs, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)11075 private boolean deleteSystemPackageLI(PackageSetting newPs, 11076 int[] allUserHandles, boolean[] perUserInstalled, 11077 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 11078 final boolean applyUserRestrictions 11079 = (allUserHandles != null) && (perUserInstalled != null); 11080 PackageSetting disabledPs = null; 11081 // Confirm if the system package has been updated 11082 // An updated system app can be deleted. This will also have to restore 11083 // the system pkg from system partition 11084 // reader 11085 synchronized (mPackages) { 11086 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 11087 } 11088 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 11089 + " disabledPs=" + disabledPs); 11090 if (disabledPs == null) { 11091 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 11092 return false; 11093 } else if (DEBUG_REMOVE) { 11094 Slog.d(TAG, "Deleting system pkg from data partition"); 11095 } 11096 if (DEBUG_REMOVE) { 11097 if (applyUserRestrictions) { 11098 Slog.d(TAG, "Remembering install states:"); 11099 for (int i = 0; i < allUserHandles.length; i++) { 11100 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 11101 } 11102 } 11103 } 11104 // Delete the updated package 11105 outInfo.isRemovedPackageSystemUpdate = true; 11106 if (disabledPs.versionCode < newPs.versionCode) { 11107 // Delete data for downgrades 11108 flags &= ~PackageManager.DELETE_KEEP_DATA; 11109 } else { 11110 // Preserve data by setting flag 11111 flags |= PackageManager.DELETE_KEEP_DATA; 11112 } 11113 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 11114 allUserHandles, perUserInstalled, outInfo, writeSettings); 11115 if (!ret) { 11116 return false; 11117 } 11118 // writer 11119 synchronized (mPackages) { 11120 // Reinstate the old system package 11121 mSettings.enableSystemPackageLPw(newPs.name); 11122 // Remove any native libraries from the upgraded package. 11123 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 11124 } 11125 // Install the system package 11126 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 11127 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 11128 if (locationIsPrivileged(disabledPs.codePath)) { 11129 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 11130 } 11131 11132 final PackageParser.Package newPkg; 11133 try { 11134 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 11135 } catch (PackageManagerException e) { 11136 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 11137 return false; 11138 } 11139 11140 // writer 11141 synchronized (mPackages) { 11142 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 11143 updatePermissionsLPw(newPkg.packageName, newPkg, 11144 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 11145 if (applyUserRestrictions) { 11146 if (DEBUG_REMOVE) { 11147 Slog.d(TAG, "Propagating install state across reinstall"); 11148 } 11149 for (int i = 0; i < allUserHandles.length; i++) { 11150 if (DEBUG_REMOVE) { 11151 Slog.d(TAG, " user " + allUserHandles[i] 11152 + " => " + perUserInstalled[i]); 11153 } 11154 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 11155 } 11156 // Regardless of writeSettings we need to ensure that this restriction 11157 // state propagation is persisted 11158 mSettings.writeAllUsersPackageRestrictionsLPr(); 11159 } 11160 // can downgrade to reader here 11161 if (writeSettings) { 11162 mSettings.writeLPr(); 11163 } 11164 } 11165 return true; 11166 } 11167 deleteInstalledPackageLI(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, boolean[] perUserInstalled, PackageRemovedInfo outInfo, boolean writeSettings)11168 private boolean deleteInstalledPackageLI(PackageSetting ps, 11169 boolean deleteCodeAndResources, int flags, 11170 int[] allUserHandles, boolean[] perUserInstalled, 11171 PackageRemovedInfo outInfo, boolean writeSettings) { 11172 if (outInfo != null) { 11173 outInfo.uid = ps.appId; 11174 } 11175 11176 // Delete package data from internal structures and also remove data if flag is set 11177 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 11178 11179 // Delete application code and resources 11180 if (deleteCodeAndResources && (outInfo != null)) { 11181 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 11182 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 11183 getAppDexInstructionSets(ps)); 11184 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 11185 } 11186 return true; 11187 } 11188 11189 @Override setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)11190 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 11191 int userId) { 11192 mContext.enforceCallingOrSelfPermission( 11193 android.Manifest.permission.DELETE_PACKAGES, null); 11194 synchronized (mPackages) { 11195 PackageSetting ps = mSettings.mPackages.get(packageName); 11196 if (ps == null) { 11197 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 11198 return false; 11199 } 11200 if (!ps.getInstalled(userId)) { 11201 // Can't block uninstall for an app that is not installed or enabled. 11202 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 11203 return false; 11204 } 11205 ps.setBlockUninstall(blockUninstall, userId); 11206 mSettings.writePackageRestrictionsLPr(userId); 11207 } 11208 return true; 11209 } 11210 11211 @Override getBlockUninstallForUser(String packageName, int userId)11212 public boolean getBlockUninstallForUser(String packageName, int userId) { 11213 synchronized (mPackages) { 11214 PackageSetting ps = mSettings.mPackages.get(packageName); 11215 if (ps == null) { 11216 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 11217 return false; 11218 } 11219 return ps.getBlockUninstall(userId); 11220 } 11221 } 11222 11223 /* 11224 * This method handles package deletion in general 11225 */ deletePackageLI(String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, int flags, PackageRemovedInfo outInfo, boolean writeSettings)11226 private boolean deletePackageLI(String packageName, UserHandle user, 11227 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 11228 int flags, PackageRemovedInfo outInfo, 11229 boolean writeSettings) { 11230 if (packageName == null) { 11231 Slog.w(TAG, "Attempt to delete null packageName."); 11232 return false; 11233 } 11234 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 11235 PackageSetting ps; 11236 boolean dataOnly = false; 11237 int removeUser = -1; 11238 int appId = -1; 11239 synchronized (mPackages) { 11240 ps = mSettings.mPackages.get(packageName); 11241 if (ps == null) { 11242 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 11243 return false; 11244 } 11245 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 11246 && user.getIdentifier() != UserHandle.USER_ALL) { 11247 // The caller is asking that the package only be deleted for a single 11248 // user. To do this, we just mark its uninstalled state and delete 11249 // its data. If this is a system app, we only allow this to happen if 11250 // they have set the special DELETE_SYSTEM_APP which requests different 11251 // semantics than normal for uninstalling system apps. 11252 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 11253 ps.setUserState(user.getIdentifier(), 11254 COMPONENT_ENABLED_STATE_DEFAULT, 11255 false, //installed 11256 true, //stopped 11257 true, //notLaunched 11258 false, //hidden 11259 null, null, null, 11260 false // blockUninstall 11261 ); 11262 if (!isSystemApp(ps)) { 11263 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 11264 // Other user still have this package installed, so all 11265 // we need to do is clear this user's data and save that 11266 // it is uninstalled. 11267 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 11268 removeUser = user.getIdentifier(); 11269 appId = ps.appId; 11270 mSettings.writePackageRestrictionsLPr(removeUser); 11271 } else { 11272 // We need to set it back to 'installed' so the uninstall 11273 // broadcasts will be sent correctly. 11274 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 11275 ps.setInstalled(true, user.getIdentifier()); 11276 } 11277 } else { 11278 // This is a system app, so we assume that the 11279 // other users still have this package installed, so all 11280 // we need to do is clear this user's data and save that 11281 // it is uninstalled. 11282 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 11283 removeUser = user.getIdentifier(); 11284 appId = ps.appId; 11285 mSettings.writePackageRestrictionsLPr(removeUser); 11286 } 11287 } 11288 } 11289 11290 if (removeUser >= 0) { 11291 // From above, we determined that we are deleting this only 11292 // for a single user. Continue the work here. 11293 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 11294 if (outInfo != null) { 11295 outInfo.removedPackage = packageName; 11296 outInfo.removedAppId = appId; 11297 outInfo.removedUsers = new int[] {removeUser}; 11298 } 11299 mInstaller.clearUserData(packageName, removeUser); 11300 removeKeystoreDataIfNeeded(removeUser, appId); 11301 schedulePackageCleaning(packageName, removeUser, false); 11302 return true; 11303 } 11304 11305 if (dataOnly) { 11306 // Delete application data first 11307 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 11308 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 11309 return true; 11310 } 11311 11312 boolean ret = false; 11313 if (isSystemApp(ps)) { 11314 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 11315 // When an updated system application is deleted we delete the existing resources as well and 11316 // fall back to existing code in system partition 11317 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 11318 flags, outInfo, writeSettings); 11319 } else { 11320 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 11321 // Kill application pre-emptively especially for apps on sd. 11322 killApplication(packageName, ps.appId, "uninstall pkg"); 11323 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 11324 allUserHandles, perUserInstalled, 11325 outInfo, writeSettings); 11326 } 11327 11328 return ret; 11329 } 11330 11331 private final class ClearStorageConnection implements ServiceConnection { 11332 IMediaContainerService mContainerService; 11333 11334 @Override onServiceConnected(ComponentName name, IBinder service)11335 public void onServiceConnected(ComponentName name, IBinder service) { 11336 synchronized (this) { 11337 mContainerService = IMediaContainerService.Stub.asInterface(service); 11338 notifyAll(); 11339 } 11340 } 11341 11342 @Override onServiceDisconnected(ComponentName name)11343 public void onServiceDisconnected(ComponentName name) { 11344 } 11345 } 11346 clearExternalStorageDataSync(String packageName, int userId, boolean allData)11347 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 11348 final boolean mounted; 11349 if (Environment.isExternalStorageEmulated()) { 11350 mounted = true; 11351 } else { 11352 final String status = Environment.getExternalStorageState(); 11353 11354 mounted = status.equals(Environment.MEDIA_MOUNTED) 11355 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 11356 } 11357 11358 if (!mounted) { 11359 return; 11360 } 11361 11362 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 11363 int[] users; 11364 if (userId == UserHandle.USER_ALL) { 11365 users = sUserManager.getUserIds(); 11366 } else { 11367 users = new int[] { userId }; 11368 } 11369 final ClearStorageConnection conn = new ClearStorageConnection(); 11370 if (mContext.bindServiceAsUser( 11371 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 11372 try { 11373 for (int curUser : users) { 11374 long timeout = SystemClock.uptimeMillis() + 5000; 11375 synchronized (conn) { 11376 long now = SystemClock.uptimeMillis(); 11377 while (conn.mContainerService == null && now < timeout) { 11378 try { 11379 conn.wait(timeout - now); 11380 } catch (InterruptedException e) { 11381 } 11382 } 11383 } 11384 if (conn.mContainerService == null) { 11385 return; 11386 } 11387 11388 final UserEnvironment userEnv = new UserEnvironment(curUser); 11389 clearDirectory(conn.mContainerService, 11390 userEnv.buildExternalStorageAppCacheDirs(packageName)); 11391 if (allData) { 11392 clearDirectory(conn.mContainerService, 11393 userEnv.buildExternalStorageAppDataDirs(packageName)); 11394 clearDirectory(conn.mContainerService, 11395 userEnv.buildExternalStorageAppMediaDirs(packageName)); 11396 } 11397 } 11398 } finally { 11399 mContext.unbindService(conn); 11400 } 11401 } 11402 } 11403 11404 @Override clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)11405 public void clearApplicationUserData(final String packageName, 11406 final IPackageDataObserver observer, final int userId) { 11407 mContext.enforceCallingOrSelfPermission( 11408 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 11409 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); 11410 // Queue up an async operation since the package deletion may take a little while. 11411 mHandler.post(new Runnable() { 11412 public void run() { 11413 mHandler.removeCallbacks(this); 11414 final boolean succeeded; 11415 synchronized (mInstallLock) { 11416 succeeded = clearApplicationUserDataLI(packageName, userId); 11417 } 11418 clearExternalStorageDataSync(packageName, userId, true); 11419 if (succeeded) { 11420 // invoke DeviceStorageMonitor's update method to clear any notifications 11421 DeviceStorageMonitorInternal 11422 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 11423 if (dsm != null) { 11424 dsm.checkMemory(); 11425 } 11426 } 11427 if(observer != null) { 11428 try { 11429 observer.onRemoveCompleted(packageName, succeeded); 11430 } catch (RemoteException e) { 11431 Log.i(TAG, "Observer no longer exists."); 11432 } 11433 } //end if observer 11434 } //end run 11435 }); 11436 } 11437 clearApplicationUserDataLI(String packageName, int userId)11438 private boolean clearApplicationUserDataLI(String packageName, int userId) { 11439 if (packageName == null) { 11440 Slog.w(TAG, "Attempt to delete null packageName."); 11441 return false; 11442 } 11443 11444 // Try finding details about the requested package 11445 PackageParser.Package pkg; 11446 synchronized (mPackages) { 11447 pkg = mPackages.get(packageName); 11448 if (pkg == null) { 11449 final PackageSetting ps = mSettings.mPackages.get(packageName); 11450 if (ps != null) { 11451 pkg = ps.pkg; 11452 } 11453 } 11454 } 11455 11456 if (pkg == null) { 11457 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 11458 } 11459 11460 // Always delete data directories for package, even if we found no other 11461 // record of app. This helps users recover from UID mismatches without 11462 // resorting to a full data wipe. 11463 int retCode = mInstaller.clearUserData(packageName, userId); 11464 if (retCode < 0) { 11465 Slog.w(TAG, "Couldn't remove cache files for package: " + packageName); 11466 return false; 11467 } 11468 11469 if (pkg == null) { 11470 return false; 11471 } 11472 11473 if (pkg != null && pkg.applicationInfo != null) { 11474 final int appId = pkg.applicationInfo.uid; 11475 removeKeystoreDataIfNeeded(userId, appId); 11476 } 11477 11478 // Create a native library symlink only if we have native libraries 11479 // and if the native libraries are 32 bit libraries. We do not provide 11480 // this symlink for 64 bit libraries. 11481 if (pkg != null && pkg.applicationInfo.primaryCpuAbi != null && 11482 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 11483 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 11484 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) { 11485 Slog.w(TAG, "Failed linking native library dir"); 11486 return false; 11487 } 11488 } 11489 11490 return true; 11491 } 11492 11493 /** 11494 * Remove entries from the keystore daemon. Will only remove it if the 11495 * {@code appId} is valid. 11496 */ removeKeystoreDataIfNeeded(int userId, int appId)11497 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 11498 if (appId < 0) { 11499 return; 11500 } 11501 11502 final KeyStore keyStore = KeyStore.getInstance(); 11503 if (keyStore != null) { 11504 if (userId == UserHandle.USER_ALL) { 11505 for (final int individual : sUserManager.getUserIds()) { 11506 keyStore.clearUid(UserHandle.getUid(individual, appId)); 11507 } 11508 } else { 11509 keyStore.clearUid(UserHandle.getUid(userId, appId)); 11510 } 11511 } else { 11512 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 11513 } 11514 } 11515 11516 @Override deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)11517 public void deleteApplicationCacheFiles(final String packageName, 11518 final IPackageDataObserver observer) { 11519 mContext.enforceCallingOrSelfPermission( 11520 android.Manifest.permission.DELETE_CACHE_FILES, null); 11521 // Queue up an async operation since the package deletion may take a little while. 11522 final int userId = UserHandle.getCallingUserId(); 11523 mHandler.post(new Runnable() { 11524 public void run() { 11525 mHandler.removeCallbacks(this); 11526 final boolean succeded; 11527 synchronized (mInstallLock) { 11528 succeded = deleteApplicationCacheFilesLI(packageName, userId); 11529 } 11530 clearExternalStorageDataSync(packageName, userId, false); 11531 if(observer != null) { 11532 try { 11533 observer.onRemoveCompleted(packageName, succeded); 11534 } catch (RemoteException e) { 11535 Log.i(TAG, "Observer no longer exists."); 11536 } 11537 } //end if observer 11538 } //end run 11539 }); 11540 } 11541 deleteApplicationCacheFilesLI(String packageName, int userId)11542 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 11543 if (packageName == null) { 11544 Slog.w(TAG, "Attempt to delete null packageName."); 11545 return false; 11546 } 11547 PackageParser.Package p; 11548 synchronized (mPackages) { 11549 p = mPackages.get(packageName); 11550 } 11551 if (p == null) { 11552 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 11553 return false; 11554 } 11555 final ApplicationInfo applicationInfo = p.applicationInfo; 11556 if (applicationInfo == null) { 11557 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 11558 return false; 11559 } 11560 int retCode = mInstaller.deleteCacheFiles(packageName, userId); 11561 if (retCode < 0) { 11562 Slog.w(TAG, "Couldn't remove cache files for package: " 11563 + packageName + " u" + userId); 11564 return false; 11565 } 11566 return true; 11567 } 11568 11569 @Override getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer)11570 public void getPackageSizeInfo(final String packageName, int userHandle, 11571 final IPackageStatsObserver observer) { 11572 mContext.enforceCallingOrSelfPermission( 11573 android.Manifest.permission.GET_PACKAGE_SIZE, null); 11574 if (packageName == null) { 11575 throw new IllegalArgumentException("Attempt to get size of null packageName"); 11576 } 11577 11578 PackageStats stats = new PackageStats(packageName, userHandle); 11579 11580 /* 11581 * Queue up an async operation since the package measurement may take a 11582 * little while. 11583 */ 11584 Message msg = mHandler.obtainMessage(INIT_COPY); 11585 msg.obj = new MeasureParams(stats, observer); 11586 mHandler.sendMessage(msg); 11587 } 11588 getPackageSizeInfoLI(String packageName, int userHandle, PackageStats pStats)11589 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 11590 PackageStats pStats) { 11591 if (packageName == null) { 11592 Slog.w(TAG, "Attempt to get size of null packageName."); 11593 return false; 11594 } 11595 PackageParser.Package p; 11596 boolean dataOnly = false; 11597 String libDirRoot = null; 11598 String asecPath = null; 11599 PackageSetting ps = null; 11600 synchronized (mPackages) { 11601 p = mPackages.get(packageName); 11602 ps = mSettings.mPackages.get(packageName); 11603 if(p == null) { 11604 dataOnly = true; 11605 if((ps == null) || (ps.pkg == null)) { 11606 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 11607 return false; 11608 } 11609 p = ps.pkg; 11610 } 11611 if (ps != null) { 11612 libDirRoot = ps.legacyNativeLibraryPathString; 11613 } 11614 if (p != null && (isExternal(p) || isForwardLocked(p))) { 11615 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 11616 if (secureContainerId != null) { 11617 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 11618 } 11619 } 11620 } 11621 String publicSrcDir = null; 11622 if(!dataOnly) { 11623 final ApplicationInfo applicationInfo = p.applicationInfo; 11624 if (applicationInfo == null) { 11625 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 11626 return false; 11627 } 11628 if (isForwardLocked(p)) { 11629 publicSrcDir = applicationInfo.getBaseResourcePath(); 11630 } 11631 } 11632 // TODO: extend to measure size of split APKs 11633 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 11634 // not just the first level. 11635 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 11636 // just the primary. 11637 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 11638 int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot, 11639 publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 11640 if (res < 0) { 11641 return false; 11642 } 11643 11644 // Fix-up for forward-locked applications in ASEC containers. 11645 if (!isExternal(p)) { 11646 pStats.codeSize += pStats.externalCodeSize; 11647 pStats.externalCodeSize = 0L; 11648 } 11649 11650 return true; 11651 } 11652 11653 11654 @Override addPackageToPreferred(String packageName)11655 public void addPackageToPreferred(String packageName) { 11656 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 11657 } 11658 11659 @Override removePackageFromPreferred(String packageName)11660 public void removePackageFromPreferred(String packageName) { 11661 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 11662 } 11663 11664 @Override getPreferredPackages(int flags)11665 public List<PackageInfo> getPreferredPackages(int flags) { 11666 return new ArrayList<PackageInfo>(); 11667 } 11668 getUidTargetSdkVersionLockedLPr(int uid)11669 private int getUidTargetSdkVersionLockedLPr(int uid) { 11670 Object obj = mSettings.getUserIdLPr(uid); 11671 if (obj instanceof SharedUserSetting) { 11672 final SharedUserSetting sus = (SharedUserSetting) obj; 11673 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 11674 final Iterator<PackageSetting> it = sus.packages.iterator(); 11675 while (it.hasNext()) { 11676 final PackageSetting ps = it.next(); 11677 if (ps.pkg != null) { 11678 int v = ps.pkg.applicationInfo.targetSdkVersion; 11679 if (v < vers) vers = v; 11680 } 11681 } 11682 return vers; 11683 } else if (obj instanceof PackageSetting) { 11684 final PackageSetting ps = (PackageSetting) obj; 11685 if (ps.pkg != null) { 11686 return ps.pkg.applicationInfo.targetSdkVersion; 11687 } 11688 } 11689 return Build.VERSION_CODES.CUR_DEVELOPMENT; 11690 } 11691 11692 @Override addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)11693 public void addPreferredActivity(IntentFilter filter, int match, 11694 ComponentName[] set, ComponentName activity, int userId) { 11695 addPreferredActivityInternal(filter, match, set, activity, true, userId, 11696 "Adding preferred"); 11697 } 11698 addPreferredActivityInternal(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname)11699 private void addPreferredActivityInternal(IntentFilter filter, int match, 11700 ComponentName[] set, ComponentName activity, boolean always, int userId, 11701 String opname) { 11702 // writer 11703 int callingUid = Binder.getCallingUid(); 11704 enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); 11705 if (filter.countActions() == 0) { 11706 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 11707 return; 11708 } 11709 synchronized (mPackages) { 11710 if (mContext.checkCallingOrSelfPermission( 11711 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 11712 != PackageManager.PERMISSION_GRANTED) { 11713 if (getUidTargetSdkVersionLockedLPr(callingUid) 11714 < Build.VERSION_CODES.FROYO) { 11715 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 11716 + callingUid); 11717 return; 11718 } 11719 mContext.enforceCallingOrSelfPermission( 11720 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11721 } 11722 11723 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 11724 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 11725 + userId + ":"); 11726 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 11727 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 11728 scheduleWritePackageRestrictionsLocked(userId); 11729 } 11730 } 11731 11732 @Override replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)11733 public void replacePreferredActivity(IntentFilter filter, int match, 11734 ComponentName[] set, ComponentName activity, int userId) { 11735 if (filter.countActions() != 1) { 11736 throw new IllegalArgumentException( 11737 "replacePreferredActivity expects filter to have only 1 action."); 11738 } 11739 if (filter.countDataAuthorities() != 0 11740 || filter.countDataPaths() != 0 11741 || filter.countDataSchemes() > 1 11742 || filter.countDataTypes() != 0) { 11743 throw new IllegalArgumentException( 11744 "replacePreferredActivity expects filter to have no data authorities, " + 11745 "paths, or types; and at most one scheme."); 11746 } 11747 11748 final int callingUid = Binder.getCallingUid(); 11749 enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); 11750 synchronized (mPackages) { 11751 if (mContext.checkCallingOrSelfPermission( 11752 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 11753 != PackageManager.PERMISSION_GRANTED) { 11754 if (getUidTargetSdkVersionLockedLPr(callingUid) 11755 < Build.VERSION_CODES.FROYO) { 11756 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 11757 + Binder.getCallingUid()); 11758 return; 11759 } 11760 mContext.enforceCallingOrSelfPermission( 11761 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11762 } 11763 11764 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 11765 if (pir != null) { 11766 // Get all of the existing entries that exactly match this filter. 11767 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 11768 if (existing != null && existing.size() == 1) { 11769 PreferredActivity cur = existing.get(0); 11770 if (DEBUG_PREFERRED) { 11771 Slog.i(TAG, "Checking replace of preferred:"); 11772 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 11773 if (!cur.mPref.mAlways) { 11774 Slog.i(TAG, " -- CUR; not mAlways!"); 11775 } else { 11776 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 11777 Slog.i(TAG, " -- CUR: mSet=" 11778 + Arrays.toString(cur.mPref.mSetComponents)); 11779 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 11780 Slog.i(TAG, " -- NEW: mMatch=" 11781 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 11782 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 11783 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 11784 } 11785 } 11786 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 11787 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 11788 && cur.mPref.sameSet(set)) { 11789 // Setting the preferred activity to what it happens to be already 11790 if (DEBUG_PREFERRED) { 11791 Slog.i(TAG, "Replacing with same preferred activity " 11792 + cur.mPref.mShortComponent + " for user " 11793 + userId + ":"); 11794 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 11795 } 11796 return; 11797 } 11798 } 11799 11800 if (existing != null) { 11801 if (DEBUG_PREFERRED) { 11802 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 11803 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 11804 } 11805 for (int i = 0; i < existing.size(); i++) { 11806 PreferredActivity pa = existing.get(i); 11807 if (DEBUG_PREFERRED) { 11808 Slog.i(TAG, "Removing existing preferred activity " 11809 + pa.mPref.mComponent + ":"); 11810 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 11811 } 11812 pir.removeFilter(pa); 11813 } 11814 } 11815 } 11816 addPreferredActivityInternal(filter, match, set, activity, true, userId, 11817 "Replacing preferred"); 11818 } 11819 } 11820 11821 @Override clearPackagePreferredActivities(String packageName)11822 public void clearPackagePreferredActivities(String packageName) { 11823 final int uid = Binder.getCallingUid(); 11824 // writer 11825 synchronized (mPackages) { 11826 PackageParser.Package pkg = mPackages.get(packageName); 11827 if (pkg == null || pkg.applicationInfo.uid != uid) { 11828 if (mContext.checkCallingOrSelfPermission( 11829 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 11830 != PackageManager.PERMISSION_GRANTED) { 11831 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 11832 < Build.VERSION_CODES.FROYO) { 11833 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 11834 + Binder.getCallingUid()); 11835 return; 11836 } 11837 mContext.enforceCallingOrSelfPermission( 11838 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11839 } 11840 } 11841 11842 int user = UserHandle.getCallingUserId(); 11843 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 11844 scheduleWritePackageRestrictionsLocked(user); 11845 } 11846 } 11847 } 11848 11849 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ clearPackagePreferredActivitiesLPw(String packageName, int userId)11850 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 11851 ArrayList<PreferredActivity> removed = null; 11852 boolean changed = false; 11853 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 11854 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 11855 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 11856 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 11857 continue; 11858 } 11859 Iterator<PreferredActivity> it = pir.filterIterator(); 11860 while (it.hasNext()) { 11861 PreferredActivity pa = it.next(); 11862 // Mark entry for removal only if it matches the package name 11863 // and the entry is of type "always". 11864 if (packageName == null || 11865 (pa.mPref.mComponent.getPackageName().equals(packageName) 11866 && pa.mPref.mAlways)) { 11867 if (removed == null) { 11868 removed = new ArrayList<PreferredActivity>(); 11869 } 11870 removed.add(pa); 11871 } 11872 } 11873 if (removed != null) { 11874 for (int j=0; j<removed.size(); j++) { 11875 PreferredActivity pa = removed.get(j); 11876 pir.removeFilter(pa); 11877 } 11878 changed = true; 11879 } 11880 } 11881 return changed; 11882 } 11883 11884 @Override resetPreferredActivities(int userId)11885 public void resetPreferredActivities(int userId) { 11886 /* TODO: Actually use userId. Why is it being passed in? */ 11887 mContext.enforceCallingOrSelfPermission( 11888 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11889 // writer 11890 synchronized (mPackages) { 11891 int user = UserHandle.getCallingUserId(); 11892 clearPackagePreferredActivitiesLPw(null, user); 11893 mSettings.readDefaultPreferredAppsLPw(this, user); 11894 scheduleWritePackageRestrictionsLocked(user); 11895 } 11896 } 11897 11898 @Override getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)11899 public int getPreferredActivities(List<IntentFilter> outFilters, 11900 List<ComponentName> outActivities, String packageName) { 11901 11902 int num = 0; 11903 final int userId = UserHandle.getCallingUserId(); 11904 // reader 11905 synchronized (mPackages) { 11906 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 11907 if (pir != null) { 11908 final Iterator<PreferredActivity> it = pir.filterIterator(); 11909 while (it.hasNext()) { 11910 final PreferredActivity pa = it.next(); 11911 if (packageName == null 11912 || (pa.mPref.mComponent.getPackageName().equals(packageName) 11913 && pa.mPref.mAlways)) { 11914 if (outFilters != null) { 11915 outFilters.add(new IntentFilter(pa)); 11916 } 11917 if (outActivities != null) { 11918 outActivities.add(pa.mPref.mComponent); 11919 } 11920 } 11921 } 11922 } 11923 } 11924 11925 return num; 11926 } 11927 11928 @Override addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)11929 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 11930 int userId) { 11931 int callingUid = Binder.getCallingUid(); 11932 if (callingUid != Process.SYSTEM_UID) { 11933 throw new SecurityException( 11934 "addPersistentPreferredActivity can only be run by the system"); 11935 } 11936 if (filter.countActions() == 0) { 11937 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 11938 return; 11939 } 11940 synchronized (mPackages) { 11941 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 11942 " :"); 11943 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 11944 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 11945 new PersistentPreferredActivity(filter, activity)); 11946 scheduleWritePackageRestrictionsLocked(userId); 11947 } 11948 } 11949 11950 @Override clearPackagePersistentPreferredActivities(String packageName, int userId)11951 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 11952 int callingUid = Binder.getCallingUid(); 11953 if (callingUid != Process.SYSTEM_UID) { 11954 throw new SecurityException( 11955 "clearPackagePersistentPreferredActivities can only be run by the system"); 11956 } 11957 ArrayList<PersistentPreferredActivity> removed = null; 11958 boolean changed = false; 11959 synchronized (mPackages) { 11960 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 11961 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 11962 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 11963 .valueAt(i); 11964 if (userId != thisUserId) { 11965 continue; 11966 } 11967 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 11968 while (it.hasNext()) { 11969 PersistentPreferredActivity ppa = it.next(); 11970 // Mark entry for removal only if it matches the package name. 11971 if (ppa.mComponent.getPackageName().equals(packageName)) { 11972 if (removed == null) { 11973 removed = new ArrayList<PersistentPreferredActivity>(); 11974 } 11975 removed.add(ppa); 11976 } 11977 } 11978 if (removed != null) { 11979 for (int j=0; j<removed.size(); j++) { 11980 PersistentPreferredActivity ppa = removed.get(j); 11981 ppir.removeFilter(ppa); 11982 } 11983 changed = true; 11984 } 11985 } 11986 11987 if (changed) { 11988 scheduleWritePackageRestrictionsLocked(userId); 11989 } 11990 } 11991 } 11992 11993 @Override addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int ownerUserId, int sourceUserId, int targetUserId, int flags)11994 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 11995 int ownerUserId, int sourceUserId, int targetUserId, int flags) { 11996 mContext.enforceCallingOrSelfPermission( 11997 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 11998 int callingUid = Binder.getCallingUid(); 11999 enforceOwnerRights(ownerPackage, ownerUserId, callingUid); 12000 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 12001 if (intentFilter.countActions() == 0) { 12002 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 12003 return; 12004 } 12005 synchronized (mPackages) { 12006 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 12007 ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags); 12008 CrossProfileIntentResolver resolver = 12009 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 12010 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 12011 // We have all those whose filter is equal. Now checking if the rest is equal as well. 12012 if (existing != null) { 12013 int size = existing.size(); 12014 for (int i = 0; i < size; i++) { 12015 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 12016 return; 12017 } 12018 } 12019 } 12020 resolver.addFilter(newFilter); 12021 scheduleWritePackageRestrictionsLocked(sourceUserId); 12022 } 12023 } 12024 12025 @Override clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, int ownerUserId)12026 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, 12027 int ownerUserId) { 12028 mContext.enforceCallingOrSelfPermission( 12029 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 12030 int callingUid = Binder.getCallingUid(); 12031 enforceOwnerRights(ownerPackage, ownerUserId, callingUid); 12032 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 12033 int callingUserId = UserHandle.getUserId(callingUid); 12034 synchronized (mPackages) { 12035 CrossProfileIntentResolver resolver = 12036 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 12037 ArraySet<CrossProfileIntentFilter> set = 12038 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 12039 for (CrossProfileIntentFilter filter : set) { 12040 if (filter.getOwnerPackage().equals(ownerPackage) 12041 && filter.getOwnerUserId() == callingUserId) { 12042 resolver.removeFilter(filter); 12043 } 12044 } 12045 scheduleWritePackageRestrictionsLocked(sourceUserId); 12046 } 12047 } 12048 12049 // Enforcing that callingUid is owning pkg on userId enforceOwnerRights(String pkg, int userId, int callingUid)12050 private void enforceOwnerRights(String pkg, int userId, int callingUid) { 12051 // The system owns everything. 12052 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 12053 return; 12054 } 12055 int callingUserId = UserHandle.getUserId(callingUid); 12056 if (callingUserId != userId) { 12057 throw new SecurityException("calling uid " + callingUid 12058 + " pretends to own " + pkg + " on user " + userId + " but belongs to user " 12059 + callingUserId); 12060 } 12061 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 12062 if (pi == null) { 12063 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 12064 + callingUserId); 12065 } 12066 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 12067 throw new SecurityException("Calling uid " + callingUid 12068 + " does not own package " + pkg); 12069 } 12070 } 12071 12072 @Override getHomeActivities(List<ResolveInfo> allHomeCandidates)12073 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 12074 Intent intent = new Intent(Intent.ACTION_MAIN); 12075 intent.addCategory(Intent.CATEGORY_HOME); 12076 12077 final int callingUserId = UserHandle.getCallingUserId(); 12078 List<ResolveInfo> list = queryIntentActivities(intent, null, 12079 PackageManager.GET_META_DATA, callingUserId); 12080 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 12081 true, false, false, callingUserId); 12082 12083 allHomeCandidates.clear(); 12084 if (list != null) { 12085 for (ResolveInfo ri : list) { 12086 allHomeCandidates.add(ri); 12087 } 12088 } 12089 return (preferred == null || preferred.activityInfo == null) 12090 ? null 12091 : new ComponentName(preferred.activityInfo.packageName, 12092 preferred.activityInfo.name); 12093 } 12094 12095 @Override setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage)12096 public void setApplicationEnabledSetting(String appPackageName, 12097 int newState, int flags, int userId, String callingPackage) { 12098 if (!sUserManager.exists(userId)) return; 12099 if (callingPackage == null) { 12100 callingPackage = Integer.toString(Binder.getCallingUid()); 12101 } 12102 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 12103 } 12104 12105 @Override setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId)12106 public void setComponentEnabledSetting(ComponentName componentName, 12107 int newState, int flags, int userId) { 12108 if (!sUserManager.exists(userId)) return; 12109 setEnabledSetting(componentName.getPackageName(), 12110 componentName.getClassName(), newState, flags, userId, null); 12111 } 12112 setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage)12113 private void setEnabledSetting(final String packageName, String className, int newState, 12114 final int flags, int userId, String callingPackage) { 12115 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 12116 || newState == COMPONENT_ENABLED_STATE_ENABLED 12117 || newState == COMPONENT_ENABLED_STATE_DISABLED 12118 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 12119 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 12120 throw new IllegalArgumentException("Invalid new component state: " 12121 + newState); 12122 } 12123 PackageSetting pkgSetting; 12124 final int uid = Binder.getCallingUid(); 12125 final int permission = mContext.checkCallingOrSelfPermission( 12126 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 12127 enforceCrossUserPermission(uid, userId, false, true, "set enabled"); 12128 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 12129 boolean sendNow = false; 12130 boolean isApp = (className == null); 12131 String componentName = isApp ? packageName : className; 12132 int packageUid = -1; 12133 ArrayList<String> components; 12134 12135 // writer 12136 synchronized (mPackages) { 12137 pkgSetting = mSettings.mPackages.get(packageName); 12138 if (pkgSetting == null) { 12139 if (className == null) { 12140 throw new IllegalArgumentException( 12141 "Unknown package: " + packageName); 12142 } 12143 throw new IllegalArgumentException( 12144 "Unknown component: " + packageName 12145 + "/" + className); 12146 } 12147 // Allow root and verify that userId is not being specified by a different user 12148 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 12149 throw new SecurityException( 12150 "Permission Denial: attempt to change component state from pid=" 12151 + Binder.getCallingPid() 12152 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 12153 } 12154 if (className == null) { 12155 // We're dealing with an application/package level state change 12156 if (pkgSetting.getEnabled(userId) == newState) { 12157 // Nothing to do 12158 return; 12159 } 12160 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 12161 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 12162 // Don't care about who enables an app. 12163 callingPackage = null; 12164 } 12165 pkgSetting.setEnabled(newState, userId, callingPackage); 12166 // pkgSetting.pkg.mSetEnabled = newState; 12167 } else { 12168 // We're dealing with a component level state change 12169 // First, verify that this is a valid class name. 12170 PackageParser.Package pkg = pkgSetting.pkg; 12171 if (pkg == null || !pkg.hasComponentClassName(className)) { 12172 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 12173 throw new IllegalArgumentException("Component class " + className 12174 + " does not exist in " + packageName); 12175 } else { 12176 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 12177 + className + " does not exist in " + packageName); 12178 } 12179 } 12180 switch (newState) { 12181 case COMPONENT_ENABLED_STATE_ENABLED: 12182 if (!pkgSetting.enableComponentLPw(className, userId)) { 12183 return; 12184 } 12185 break; 12186 case COMPONENT_ENABLED_STATE_DISABLED: 12187 if (!pkgSetting.disableComponentLPw(className, userId)) { 12188 return; 12189 } 12190 break; 12191 case COMPONENT_ENABLED_STATE_DEFAULT: 12192 if (!pkgSetting.restoreComponentLPw(className, userId)) { 12193 return; 12194 } 12195 break; 12196 default: 12197 Slog.e(TAG, "Invalid new component state: " + newState); 12198 return; 12199 } 12200 } 12201 mSettings.writePackageRestrictionsLPr(userId); 12202 components = mPendingBroadcasts.get(userId, packageName); 12203 final boolean newPackage = components == null; 12204 if (newPackage) { 12205 components = new ArrayList<String>(); 12206 } 12207 if (!components.contains(componentName)) { 12208 components.add(componentName); 12209 } 12210 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 12211 sendNow = true; 12212 // Purge entry from pending broadcast list if another one exists already 12213 // since we are sending one right away. 12214 mPendingBroadcasts.remove(userId, packageName); 12215 } else { 12216 if (newPackage) { 12217 mPendingBroadcasts.put(userId, packageName, components); 12218 } 12219 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 12220 // Schedule a message 12221 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 12222 } 12223 } 12224 } 12225 12226 long callingId = Binder.clearCallingIdentity(); 12227 try { 12228 if (sendNow) { 12229 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 12230 sendPackageChangedBroadcast(packageName, 12231 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 12232 } 12233 } finally { 12234 Binder.restoreCallingIdentity(callingId); 12235 } 12236 } 12237 sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)12238 private void sendPackageChangedBroadcast(String packageName, 12239 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 12240 if (DEBUG_INSTALL) 12241 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 12242 + componentNames); 12243 Bundle extras = new Bundle(4); 12244 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 12245 String nameList[] = new String[componentNames.size()]; 12246 componentNames.toArray(nameList); 12247 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 12248 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 12249 extras.putInt(Intent.EXTRA_UID, packageUid); 12250 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 12251 new int[] {UserHandle.getUserId(packageUid)}); 12252 } 12253 12254 @Override setPackageStoppedState(String packageName, boolean stopped, int userId)12255 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 12256 if (!sUserManager.exists(userId)) return; 12257 final int uid = Binder.getCallingUid(); 12258 final int permission = mContext.checkCallingOrSelfPermission( 12259 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 12260 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 12261 enforceCrossUserPermission(uid, userId, true, true, "stop package"); 12262 // writer 12263 synchronized (mPackages) { 12264 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, 12265 uid, userId)) { 12266 scheduleWritePackageRestrictionsLocked(userId); 12267 } 12268 } 12269 } 12270 12271 @Override getInstallerPackageName(String packageName)12272 public String getInstallerPackageName(String packageName) { 12273 // reader 12274 synchronized (mPackages) { 12275 return mSettings.getInstallerPackageNameLPr(packageName); 12276 } 12277 } 12278 12279 @Override getApplicationEnabledSetting(String packageName, int userId)12280 public int getApplicationEnabledSetting(String packageName, int userId) { 12281 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 12282 int uid = Binder.getCallingUid(); 12283 enforceCrossUserPermission(uid, userId, false, false, "get enabled"); 12284 // reader 12285 synchronized (mPackages) { 12286 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 12287 } 12288 } 12289 12290 @Override getComponentEnabledSetting(ComponentName componentName, int userId)12291 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 12292 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 12293 int uid = Binder.getCallingUid(); 12294 enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); 12295 // reader 12296 synchronized (mPackages) { 12297 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 12298 } 12299 } 12300 12301 @Override enterSafeMode()12302 public void enterSafeMode() { 12303 enforceSystemOrRoot("Only the system can request entering safe mode"); 12304 12305 if (!mSystemReady) { 12306 mSafeMode = true; 12307 } 12308 } 12309 12310 @Override systemReady()12311 public void systemReady() { 12312 mSystemReady = true; 12313 12314 // Read the compatibilty setting when the system is ready. 12315 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 12316 mContext.getContentResolver(), 12317 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 12318 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 12319 if (DEBUG_SETTINGS) { 12320 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 12321 } 12322 12323 synchronized (mPackages) { 12324 // Verify that all of the preferred activity components actually 12325 // exist. It is possible for applications to be updated and at 12326 // that point remove a previously declared activity component that 12327 // had been set as a preferred activity. We try to clean this up 12328 // the next time we encounter that preferred activity, but it is 12329 // possible for the user flow to never be able to return to that 12330 // situation so here we do a sanity check to make sure we haven't 12331 // left any junk around. 12332 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 12333 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 12334 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 12335 removed.clear(); 12336 for (PreferredActivity pa : pir.filterSet()) { 12337 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 12338 removed.add(pa); 12339 } 12340 } 12341 if (removed.size() > 0) { 12342 for (int r=0; r<removed.size(); r++) { 12343 PreferredActivity pa = removed.get(r); 12344 Slog.w(TAG, "Removing dangling preferred activity: " 12345 + pa.mPref.mComponent); 12346 pir.removeFilter(pa); 12347 } 12348 mSettings.writePackageRestrictionsLPr( 12349 mSettings.mPreferredActivities.keyAt(i)); 12350 } 12351 } 12352 } 12353 sUserManager.systemReady(); 12354 12355 // Kick off any messages waiting for system ready 12356 if (mPostSystemReadyMessages != null) { 12357 for (Message msg : mPostSystemReadyMessages) { 12358 msg.sendToTarget(); 12359 } 12360 mPostSystemReadyMessages = null; 12361 } 12362 } 12363 12364 @Override isSafeMode()12365 public boolean isSafeMode() { 12366 return mSafeMode; 12367 } 12368 12369 @Override hasSystemUidErrors()12370 public boolean hasSystemUidErrors() { 12371 return mHasSystemUidErrors; 12372 } 12373 arrayToString(int[] array)12374 static String arrayToString(int[] array) { 12375 StringBuffer buf = new StringBuffer(128); 12376 buf.append('['); 12377 if (array != null) { 12378 for (int i=0; i<array.length; i++) { 12379 if (i > 0) buf.append(", "); 12380 buf.append(array[i]); 12381 } 12382 } 12383 buf.append(']'); 12384 return buf.toString(); 12385 } 12386 12387 static class DumpState { 12388 public static final int DUMP_LIBS = 1 << 0; 12389 public static final int DUMP_FEATURES = 1 << 1; 12390 public static final int DUMP_RESOLVERS = 1 << 2; 12391 public static final int DUMP_PERMISSIONS = 1 << 3; 12392 public static final int DUMP_PACKAGES = 1 << 4; 12393 public static final int DUMP_SHARED_USERS = 1 << 5; 12394 public static final int DUMP_MESSAGES = 1 << 6; 12395 public static final int DUMP_PROVIDERS = 1 << 7; 12396 public static final int DUMP_VERIFIERS = 1 << 8; 12397 public static final int DUMP_PREFERRED = 1 << 9; 12398 public static final int DUMP_PREFERRED_XML = 1 << 10; 12399 public static final int DUMP_KEYSETS = 1 << 11; 12400 public static final int DUMP_VERSION = 1 << 12; 12401 public static final int DUMP_INSTALLS = 1 << 13; 12402 12403 public static final int OPTION_SHOW_FILTERS = 1 << 0; 12404 12405 private int mTypes; 12406 12407 private int mOptions; 12408 12409 private boolean mTitlePrinted; 12410 12411 private SharedUserSetting mSharedUser; 12412 isDumping(int type)12413 public boolean isDumping(int type) { 12414 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 12415 return true; 12416 } 12417 12418 return (mTypes & type) != 0; 12419 } 12420 setDump(int type)12421 public void setDump(int type) { 12422 mTypes |= type; 12423 } 12424 isOptionEnabled(int option)12425 public boolean isOptionEnabled(int option) { 12426 return (mOptions & option) != 0; 12427 } 12428 setOptionEnabled(int option)12429 public void setOptionEnabled(int option) { 12430 mOptions |= option; 12431 } 12432 onTitlePrinted()12433 public boolean onTitlePrinted() { 12434 final boolean printed = mTitlePrinted; 12435 mTitlePrinted = true; 12436 return printed; 12437 } 12438 getTitlePrinted()12439 public boolean getTitlePrinted() { 12440 return mTitlePrinted; 12441 } 12442 setTitlePrinted(boolean enabled)12443 public void setTitlePrinted(boolean enabled) { 12444 mTitlePrinted = enabled; 12445 } 12446 getSharedUser()12447 public SharedUserSetting getSharedUser() { 12448 return mSharedUser; 12449 } 12450 setSharedUser(SharedUserSetting user)12451 public void setSharedUser(SharedUserSetting user) { 12452 mSharedUser = user; 12453 } 12454 } 12455 12456 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)12457 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12458 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 12459 != PackageManager.PERMISSION_GRANTED) { 12460 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12461 + Binder.getCallingPid() 12462 + ", uid=" + Binder.getCallingUid() 12463 + " without permission " 12464 + android.Manifest.permission.DUMP); 12465 return; 12466 } 12467 12468 DumpState dumpState = new DumpState(); 12469 boolean fullPreferred = false; 12470 boolean checkin = false; 12471 12472 String packageName = null; 12473 12474 int opti = 0; 12475 while (opti < args.length) { 12476 String opt = args[opti]; 12477 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12478 break; 12479 } 12480 opti++; 12481 12482 if ("-a".equals(opt)) { 12483 // Right now we only know how to print all. 12484 } else if ("-h".equals(opt)) { 12485 pw.println("Package manager dump options:"); 12486 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 12487 pw.println(" --checkin: dump for a checkin"); 12488 pw.println(" -f: print details of intent filters"); 12489 pw.println(" -h: print this help"); 12490 pw.println(" cmd may be one of:"); 12491 pw.println(" l[ibraries]: list known shared libraries"); 12492 pw.println(" f[ibraries]: list device features"); 12493 pw.println(" k[eysets]: print known keysets"); 12494 pw.println(" r[esolvers]: dump intent resolvers"); 12495 pw.println(" perm[issions]: dump permissions"); 12496 pw.println(" pref[erred]: print preferred package settings"); 12497 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 12498 pw.println(" prov[iders]: dump content providers"); 12499 pw.println(" p[ackages]: dump installed packages"); 12500 pw.println(" s[hared-users]: dump shared user IDs"); 12501 pw.println(" m[essages]: print collected runtime messages"); 12502 pw.println(" v[erifiers]: print package verifier info"); 12503 pw.println(" version: print database version info"); 12504 pw.println(" write: write current settings now"); 12505 pw.println(" <package.name>: info about given package"); 12506 pw.println(" installs: details about install sessions"); 12507 return; 12508 } else if ("--checkin".equals(opt)) { 12509 checkin = true; 12510 } else if ("-f".equals(opt)) { 12511 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 12512 } else { 12513 pw.println("Unknown argument: " + opt + "; use -h for help"); 12514 } 12515 } 12516 12517 // Is the caller requesting to dump a particular piece of data? 12518 if (opti < args.length) { 12519 String cmd = args[opti]; 12520 opti++; 12521 // Is this a package name? 12522 if ("android".equals(cmd) || cmd.contains(".")) { 12523 packageName = cmd; 12524 // When dumping a single package, we always dump all of its 12525 // filter information since the amount of data will be reasonable. 12526 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 12527 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 12528 dumpState.setDump(DumpState.DUMP_LIBS); 12529 } else if ("f".equals(cmd) || "features".equals(cmd)) { 12530 dumpState.setDump(DumpState.DUMP_FEATURES); 12531 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 12532 dumpState.setDump(DumpState.DUMP_RESOLVERS); 12533 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 12534 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 12535 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 12536 dumpState.setDump(DumpState.DUMP_PREFERRED); 12537 } else if ("preferred-xml".equals(cmd)) { 12538 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 12539 if (opti < args.length && "--full".equals(args[opti])) { 12540 fullPreferred = true; 12541 opti++; 12542 } 12543 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 12544 dumpState.setDump(DumpState.DUMP_PACKAGES); 12545 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 12546 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 12547 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 12548 dumpState.setDump(DumpState.DUMP_PROVIDERS); 12549 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 12550 dumpState.setDump(DumpState.DUMP_MESSAGES); 12551 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 12552 dumpState.setDump(DumpState.DUMP_VERIFIERS); 12553 } else if ("version".equals(cmd)) { 12554 dumpState.setDump(DumpState.DUMP_VERSION); 12555 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 12556 dumpState.setDump(DumpState.DUMP_KEYSETS); 12557 } else if ("installs".equals(cmd)) { 12558 dumpState.setDump(DumpState.DUMP_INSTALLS); 12559 } else if ("write".equals(cmd)) { 12560 synchronized (mPackages) { 12561 mSettings.writeLPr(); 12562 pw.println("Settings written."); 12563 return; 12564 } 12565 } 12566 } 12567 12568 if (checkin) { 12569 pw.println("vers,1"); 12570 } 12571 12572 // reader 12573 synchronized (mPackages) { 12574 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 12575 if (!checkin) { 12576 if (dumpState.onTitlePrinted()) 12577 pw.println(); 12578 pw.println("Database versions:"); 12579 pw.print(" SDK Version:"); 12580 pw.print(" internal="); 12581 pw.print(mSettings.mInternalSdkPlatform); 12582 pw.print(" external="); 12583 pw.println(mSettings.mExternalSdkPlatform); 12584 pw.print(" DB Version:"); 12585 pw.print(" internal="); 12586 pw.print(mSettings.mInternalDatabaseVersion); 12587 pw.print(" external="); 12588 pw.println(mSettings.mExternalDatabaseVersion); 12589 } 12590 } 12591 12592 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 12593 if (!checkin) { 12594 if (dumpState.onTitlePrinted()) 12595 pw.println(); 12596 pw.println("Verifiers:"); 12597 pw.print(" Required: "); 12598 pw.print(mRequiredVerifierPackage); 12599 pw.print(" (uid="); 12600 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 12601 pw.println(")"); 12602 } else if (mRequiredVerifierPackage != null) { 12603 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 12604 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 12605 } 12606 } 12607 12608 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 12609 boolean printedHeader = false; 12610 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 12611 while (it.hasNext()) { 12612 String name = it.next(); 12613 SharedLibraryEntry ent = mSharedLibraries.get(name); 12614 if (!checkin) { 12615 if (!printedHeader) { 12616 if (dumpState.onTitlePrinted()) 12617 pw.println(); 12618 pw.println("Libraries:"); 12619 printedHeader = true; 12620 } 12621 pw.print(" "); 12622 } else { 12623 pw.print("lib,"); 12624 } 12625 pw.print(name); 12626 if (!checkin) { 12627 pw.print(" -> "); 12628 } 12629 if (ent.path != null) { 12630 if (!checkin) { 12631 pw.print("(jar) "); 12632 pw.print(ent.path); 12633 } else { 12634 pw.print(",jar,"); 12635 pw.print(ent.path); 12636 } 12637 } else { 12638 if (!checkin) { 12639 pw.print("(apk) "); 12640 pw.print(ent.apk); 12641 } else { 12642 pw.print(",apk,"); 12643 pw.print(ent.apk); 12644 } 12645 } 12646 pw.println(); 12647 } 12648 } 12649 12650 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 12651 if (dumpState.onTitlePrinted()) 12652 pw.println(); 12653 if (!checkin) { 12654 pw.println("Features:"); 12655 } 12656 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 12657 while (it.hasNext()) { 12658 String name = it.next(); 12659 if (!checkin) { 12660 pw.print(" "); 12661 } else { 12662 pw.print("feat,"); 12663 } 12664 pw.println(name); 12665 } 12666 } 12667 12668 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 12669 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 12670 : "Activity Resolver Table:", " ", packageName, 12671 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 12672 dumpState.setTitlePrinted(true); 12673 } 12674 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 12675 : "Receiver Resolver Table:", " ", packageName, 12676 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 12677 dumpState.setTitlePrinted(true); 12678 } 12679 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 12680 : "Service Resolver Table:", " ", packageName, 12681 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 12682 dumpState.setTitlePrinted(true); 12683 } 12684 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 12685 : "Provider Resolver Table:", " ", packageName, 12686 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 12687 dumpState.setTitlePrinted(true); 12688 } 12689 } 12690 12691 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 12692 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 12693 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 12694 int user = mSettings.mPreferredActivities.keyAt(i); 12695 if (pir.dump(pw, 12696 dumpState.getTitlePrinted() 12697 ? "\nPreferred Activities User " + user + ":" 12698 : "Preferred Activities User " + user + ":", " ", 12699 packageName, true, false)) { 12700 dumpState.setTitlePrinted(true); 12701 } 12702 } 12703 } 12704 12705 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 12706 pw.flush(); 12707 FileOutputStream fout = new FileOutputStream(fd); 12708 BufferedOutputStream str = new BufferedOutputStream(fout); 12709 XmlSerializer serializer = new FastXmlSerializer(); 12710 try { 12711 serializer.setOutput(str, "utf-8"); 12712 serializer.startDocument(null, true); 12713 serializer.setFeature( 12714 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 12715 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 12716 serializer.endDocument(); 12717 serializer.flush(); 12718 } catch (IllegalArgumentException e) { 12719 pw.println("Failed writing: " + e); 12720 } catch (IllegalStateException e) { 12721 pw.println("Failed writing: " + e); 12722 } catch (IOException e) { 12723 pw.println("Failed writing: " + e); 12724 } 12725 } 12726 12727 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 12728 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 12729 if (packageName == null) { 12730 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 12731 if (iperm == 0) { 12732 if (dumpState.onTitlePrinted()) 12733 pw.println(); 12734 pw.println("AppOp Permissions:"); 12735 } 12736 pw.print(" AppOp Permission "); 12737 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 12738 pw.println(":"); 12739 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 12740 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 12741 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 12742 } 12743 } 12744 } 12745 } 12746 12747 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 12748 boolean printedSomething = false; 12749 for (PackageParser.Provider p : mProviders.mProviders.values()) { 12750 if (packageName != null && !packageName.equals(p.info.packageName)) { 12751 continue; 12752 } 12753 if (!printedSomething) { 12754 if (dumpState.onTitlePrinted()) 12755 pw.println(); 12756 pw.println("Registered ContentProviders:"); 12757 printedSomething = true; 12758 } 12759 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 12760 pw.print(" "); pw.println(p.toString()); 12761 } 12762 printedSomething = false; 12763 for (Map.Entry<String, PackageParser.Provider> entry : 12764 mProvidersByAuthority.entrySet()) { 12765 PackageParser.Provider p = entry.getValue(); 12766 if (packageName != null && !packageName.equals(p.info.packageName)) { 12767 continue; 12768 } 12769 if (!printedSomething) { 12770 if (dumpState.onTitlePrinted()) 12771 pw.println(); 12772 pw.println("ContentProvider Authorities:"); 12773 printedSomething = true; 12774 } 12775 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 12776 pw.print(" "); pw.println(p.toString()); 12777 if (p.info != null && p.info.applicationInfo != null) { 12778 final String appInfo = p.info.applicationInfo.toString(); 12779 pw.print(" applicationInfo="); pw.println(appInfo); 12780 } 12781 } 12782 } 12783 12784 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 12785 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 12786 } 12787 12788 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 12789 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin); 12790 } 12791 12792 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 12793 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState, checkin); 12794 } 12795 12796 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 12797 // XXX should handle packageName != null by dumping only install data that 12798 // the given package is involved with. 12799 if (dumpState.onTitlePrinted()) pw.println(); 12800 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 12801 } 12802 12803 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 12804 if (dumpState.onTitlePrinted()) pw.println(); 12805 mSettings.dumpReadMessagesLPr(pw, dumpState); 12806 12807 pw.println(); 12808 pw.println("Package warning messages:"); 12809 BufferedReader in = null; 12810 String line = null; 12811 try { 12812 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 12813 while ((line = in.readLine()) != null) { 12814 if (line.contains("ignored: updated version")) continue; 12815 pw.println(line); 12816 } 12817 } catch (IOException ignored) { 12818 } finally { 12819 IoUtils.closeQuietly(in); 12820 } 12821 } 12822 12823 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 12824 BufferedReader in = null; 12825 String line = null; 12826 try { 12827 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 12828 while ((line = in.readLine()) != null) { 12829 if (line.contains("ignored: updated version")) continue; 12830 pw.print("msg,"); 12831 pw.println(line); 12832 } 12833 } catch (IOException ignored) { 12834 } finally { 12835 IoUtils.closeQuietly(in); 12836 } 12837 } 12838 } 12839 } 12840 12841 // ------- apps on sdcard specific code ------- 12842 static final boolean DEBUG_SD_INSTALL = false; 12843 12844 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 12845 12846 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 12847 12848 private boolean mMediaMounted = false; 12849 getEncryptKey()12850 static String getEncryptKey() { 12851 try { 12852 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 12853 SD_ENCRYPTION_KEYSTORE_NAME); 12854 if (sdEncKey == null) { 12855 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 12856 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 12857 if (sdEncKey == null) { 12858 Slog.e(TAG, "Failed to create encryption keys"); 12859 return null; 12860 } 12861 } 12862 return sdEncKey; 12863 } catch (NoSuchAlgorithmException nsae) { 12864 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 12865 return null; 12866 } catch (IOException ioe) { 12867 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 12868 return null; 12869 } 12870 } 12871 12872 /* 12873 * Update media status on PackageManager. 12874 */ 12875 @Override updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)12876 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 12877 int callingUid = Binder.getCallingUid(); 12878 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12879 throw new SecurityException("Media status can only be updated by the system"); 12880 } 12881 // reader; this apparently protects mMediaMounted, but should probably 12882 // be a different lock in that case. 12883 synchronized (mPackages) { 12884 Log.i(TAG, "Updating external media status from " 12885 + (mMediaMounted ? "mounted" : "unmounted") + " to " 12886 + (mediaStatus ? "mounted" : "unmounted")); 12887 if (DEBUG_SD_INSTALL) 12888 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 12889 + ", mMediaMounted=" + mMediaMounted); 12890 if (mediaStatus == mMediaMounted) { 12891 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 12892 : 0, -1); 12893 mHandler.sendMessage(msg); 12894 return; 12895 } 12896 mMediaMounted = mediaStatus; 12897 } 12898 // Queue up an async operation since the package installation may take a 12899 // little while. 12900 mHandler.post(new Runnable() { 12901 public void run() { 12902 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 12903 } 12904 }); 12905 } 12906 12907 /** 12908 * Called by MountService when the initial ASECs to scan are available. 12909 * Should block until all the ASEC containers are finished being scanned. 12910 */ scanAvailableAsecs()12911 public void scanAvailableAsecs() { 12912 updateExternalMediaStatusInner(true, false, false); 12913 if (mShouldRestoreconData) { 12914 SELinuxMMAC.setRestoreconDone(); 12915 mShouldRestoreconData = false; 12916 } 12917 } 12918 12919 /* 12920 * Collect information of applications on external media, map them against 12921 * existing containers and update information based on current mount status. 12922 * Please note that we always have to report status if reportStatus has been 12923 * set to true especially when unloading packages. 12924 */ updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)12925 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 12926 boolean externalStorage) { 12927 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 12928 int[] uidArr = EmptyArray.INT; 12929 12930 final String[] list = PackageHelper.getSecureContainerList(); 12931 if (ArrayUtils.isEmpty(list)) { 12932 Log.i(TAG, "No secure containers found"); 12933 } else { 12934 // Process list of secure containers and categorize them 12935 // as active or stale based on their package internal state. 12936 12937 // reader 12938 synchronized (mPackages) { 12939 for (String cid : list) { 12940 // Leave stages untouched for now; installer service owns them 12941 if (PackageInstallerService.isStageName(cid)) continue; 12942 12943 if (DEBUG_SD_INSTALL) 12944 Log.i(TAG, "Processing container " + cid); 12945 String pkgName = getAsecPackageName(cid); 12946 if (pkgName == null) { 12947 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 12948 continue; 12949 } 12950 if (DEBUG_SD_INSTALL) 12951 Log.i(TAG, "Looking for pkg : " + pkgName); 12952 12953 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12954 if (ps == null) { 12955 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 12956 continue; 12957 } 12958 12959 /* 12960 * Skip packages that are not external if we're unmounting 12961 * external storage. 12962 */ 12963 if (externalStorage && !isMounted && !isExternal(ps)) { 12964 continue; 12965 } 12966 12967 final AsecInstallArgs args = new AsecInstallArgs(cid, 12968 getAppDexInstructionSets(ps), isForwardLocked(ps)); 12969 // The package status is changed only if the code path 12970 // matches between settings and the container id. 12971 if (ps.codePathString != null 12972 && ps.codePathString.startsWith(args.getCodePath())) { 12973 if (DEBUG_SD_INSTALL) { 12974 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 12975 + " at code path: " + ps.codePathString); 12976 } 12977 12978 // We do have a valid package installed on sdcard 12979 processCids.put(args, ps.codePathString); 12980 final int uid = ps.appId; 12981 if (uid != -1) { 12982 uidArr = ArrayUtils.appendInt(uidArr, uid); 12983 } 12984 } else { 12985 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 12986 + ps.codePathString); 12987 } 12988 } 12989 } 12990 12991 Arrays.sort(uidArr); 12992 } 12993 12994 // Process packages with valid entries. 12995 if (isMounted) { 12996 if (DEBUG_SD_INSTALL) 12997 Log.i(TAG, "Loading packages"); 12998 loadMediaPackages(processCids, uidArr); 12999 startCleaningPackages(); 13000 mInstallerService.onSecureContainersAvailable(); 13001 } else { 13002 if (DEBUG_SD_INSTALL) 13003 Log.i(TAG, "Unloading packages"); 13004 unloadMediaPackages(processCids, uidArr, reportStatus); 13005 } 13006 } 13007 sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)13008 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 13009 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 13010 int size = pkgList.size(); 13011 if (size > 0) { 13012 // Send broadcasts here 13013 Bundle extras = new Bundle(); 13014 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList 13015 .toArray(new String[size])); 13016 if (uidArr != null) { 13017 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 13018 } 13019 if (replacing) { 13020 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 13021 } 13022 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 13023 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 13024 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 13025 } 13026 } 13027 13028 /* 13029 * Look at potentially valid container ids from processCids If package 13030 * information doesn't match the one on record or package scanning fails, 13031 * the cid is added to list of removeCids. We currently don't delete stale 13032 * containers. 13033 */ loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr)13034 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr) { 13035 ArrayList<String> pkgList = new ArrayList<String>(); 13036 Set<AsecInstallArgs> keys = processCids.keySet(); 13037 13038 for (AsecInstallArgs args : keys) { 13039 String codePath = processCids.get(args); 13040 if (DEBUG_SD_INSTALL) 13041 Log.i(TAG, "Loading container : " + args.cid); 13042 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13043 try { 13044 // Make sure there are no container errors first. 13045 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 13046 Slog.e(TAG, "Failed to mount cid : " + args.cid 13047 + " when installing from sdcard"); 13048 continue; 13049 } 13050 // Check code path here. 13051 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 13052 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 13053 + " does not match one in settings " + codePath); 13054 continue; 13055 } 13056 // Parse package 13057 int parseFlags = mDefParseFlags; 13058 if (args.isExternal()) { 13059 parseFlags |= PackageParser.PARSE_ON_SDCARD; 13060 } 13061 if (args.isFwdLocked()) { 13062 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 13063 } 13064 13065 synchronized (mInstallLock) { 13066 PackageParser.Package pkg = null; 13067 try { 13068 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null); 13069 } catch (PackageManagerException e) { 13070 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 13071 } 13072 // Scan the package 13073 if (pkg != null) { 13074 /* 13075 * TODO why is the lock being held? doPostInstall is 13076 * called in other places without the lock. This needs 13077 * to be straightened out. 13078 */ 13079 // writer 13080 synchronized (mPackages) { 13081 retCode = PackageManager.INSTALL_SUCCEEDED; 13082 pkgList.add(pkg.packageName); 13083 // Post process args 13084 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 13085 pkg.applicationInfo.uid); 13086 } 13087 } else { 13088 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 13089 } 13090 } 13091 13092 } finally { 13093 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 13094 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 13095 } 13096 } 13097 } 13098 // writer 13099 synchronized (mPackages) { 13100 // If the platform SDK has changed since the last time we booted, 13101 // we need to re-grant app permission to catch any new ones that 13102 // appear. This is really a hack, and means that apps can in some 13103 // cases get permissions that the user didn't initially explicitly 13104 // allow... it would be nice to have some better way to handle 13105 // this situation. 13106 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 13107 if (regrantPermissions) 13108 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 13109 + mSdkVersion + "; regranting permissions for external storage"); 13110 mSettings.mExternalSdkPlatform = mSdkVersion; 13111 13112 // Make sure group IDs have been assigned, and any permission 13113 // changes in other apps are accounted for 13114 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 13115 | (regrantPermissions 13116 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 13117 : 0)); 13118 13119 mSettings.updateExternalDatabaseVersion(); 13120 13121 // can downgrade to reader 13122 // Persist settings 13123 mSettings.writeLPr(); 13124 } 13125 // Send a broadcast to let everyone know we are done processing 13126 if (pkgList.size() > 0) { 13127 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 13128 } 13129 } 13130 13131 /* 13132 * Utility method to unload a list of specified containers 13133 */ unloadAllContainers(Set<AsecInstallArgs> cidArgs)13134 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 13135 // Just unmount all valid containers. 13136 for (AsecInstallArgs arg : cidArgs) { 13137 synchronized (mInstallLock) { 13138 arg.doPostDeleteLI(false); 13139 } 13140 } 13141 } 13142 13143 /* 13144 * Unload packages mounted on external media. This involves deleting package 13145 * data from internal structures, sending broadcasts about diabled packages, 13146 * gc'ing to free up references, unmounting all secure containers 13147 * corresponding to packages on external media, and posting a 13148 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 13149 * that we always have to post this message if status has been requested no 13150 * matter what. 13151 */ unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)13152 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 13153 final boolean reportStatus) { 13154 if (DEBUG_SD_INSTALL) 13155 Log.i(TAG, "unloading media packages"); 13156 ArrayList<String> pkgList = new ArrayList<String>(); 13157 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 13158 final Set<AsecInstallArgs> keys = processCids.keySet(); 13159 for (AsecInstallArgs args : keys) { 13160 String pkgName = args.getPackageName(); 13161 if (DEBUG_SD_INSTALL) 13162 Log.i(TAG, "Trying to unload pkg : " + pkgName); 13163 // Delete package internally 13164 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 13165 synchronized (mInstallLock) { 13166 boolean res = deletePackageLI(pkgName, null, false, null, null, 13167 PackageManager.DELETE_KEEP_DATA, outInfo, false); 13168 if (res) { 13169 pkgList.add(pkgName); 13170 } else { 13171 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 13172 failedList.add(args); 13173 } 13174 } 13175 } 13176 13177 // reader 13178 synchronized (mPackages) { 13179 // We didn't update the settings after removing each package; 13180 // write them now for all packages. 13181 mSettings.writeLPr(); 13182 } 13183 13184 // We have to absolutely send UPDATED_MEDIA_STATUS only 13185 // after confirming that all the receivers processed the ordered 13186 // broadcast when packages get disabled, force a gc to clean things up. 13187 // and unload all the containers. 13188 if (pkgList.size() > 0) { 13189 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 13190 new IIntentReceiver.Stub() { 13191 public void performReceive(Intent intent, int resultCode, String data, 13192 Bundle extras, boolean ordered, boolean sticky, 13193 int sendingUser) throws RemoteException { 13194 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 13195 reportStatus ? 1 : 0, 1, keys); 13196 mHandler.sendMessage(msg); 13197 } 13198 }); 13199 } else { 13200 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 13201 keys); 13202 mHandler.sendMessage(msg); 13203 } 13204 } 13205 13206 /** Binder call */ 13207 @Override movePackage(final String packageName, final IPackageMoveObserver observer, final int flags)13208 public void movePackage(final String packageName, final IPackageMoveObserver observer, 13209 final int flags) { 13210 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 13211 UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 13212 int returnCode = PackageManager.MOVE_SUCCEEDED; 13213 int currInstallFlags = 0; 13214 int newInstallFlags = 0; 13215 13216 File codeFile = null; 13217 String installerPackageName = null; 13218 String packageAbiOverride = null; 13219 13220 // reader 13221 synchronized (mPackages) { 13222 final PackageParser.Package pkg = mPackages.get(packageName); 13223 final PackageSetting ps = mSettings.mPackages.get(packageName); 13224 if (pkg == null || ps == null) { 13225 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 13226 } else { 13227 // Disable moving fwd locked apps and system packages 13228 if (pkg.applicationInfo != null && isSystemApp(pkg)) { 13229 Slog.w(TAG, "Cannot move system application"); 13230 returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 13231 } else if (pkg.mOperationPending) { 13232 Slog.w(TAG, "Attempt to move package which has pending operations"); 13233 returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING; 13234 } else { 13235 // Find install location first 13236 if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 13237 && (flags & PackageManager.MOVE_INTERNAL) != 0) { 13238 Slog.w(TAG, "Ambigous flags specified for move location."); 13239 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 13240 } else { 13241 newInstallFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 13242 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL; 13243 currInstallFlags = isExternal(pkg) 13244 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL; 13245 13246 if (newInstallFlags == currInstallFlags) { 13247 Slog.w(TAG, "No move required. Trying to move to same location"); 13248 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 13249 } else { 13250 if (isForwardLocked(pkg)) { 13251 currInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK; 13252 newInstallFlags |= PackageManager.INSTALL_FORWARD_LOCK; 13253 } 13254 } 13255 } 13256 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 13257 pkg.mOperationPending = true; 13258 } 13259 } 13260 13261 codeFile = new File(pkg.codePath); 13262 installerPackageName = ps.installerPackageName; 13263 packageAbiOverride = ps.cpuAbiOverrideString; 13264 } 13265 } 13266 13267 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 13268 try { 13269 observer.packageMoved(packageName, returnCode); 13270 } catch (RemoteException ignored) { 13271 } 13272 return; 13273 } 13274 13275 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 13276 @Override 13277 public void onUserActionRequired(Intent intent) throws RemoteException { 13278 throw new IllegalStateException(); 13279 } 13280 13281 @Override 13282 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 13283 Bundle extras) throws RemoteException { 13284 Slog.d(TAG, "Install result for move: " 13285 + PackageManager.installStatusToString(returnCode, msg)); 13286 13287 // We usually have a new package now after the install, but if 13288 // we failed we need to clear the pending flag on the original 13289 // package object. 13290 synchronized (mPackages) { 13291 final PackageParser.Package pkg = mPackages.get(packageName); 13292 if (pkg != null) { 13293 pkg.mOperationPending = false; 13294 } 13295 } 13296 13297 final int status = PackageManager.installStatusToPublicStatus(returnCode); 13298 switch (status) { 13299 case PackageInstaller.STATUS_SUCCESS: 13300 observer.packageMoved(packageName, PackageManager.MOVE_SUCCEEDED); 13301 break; 13302 case PackageInstaller.STATUS_FAILURE_STORAGE: 13303 observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 13304 break; 13305 default: 13306 observer.packageMoved(packageName, PackageManager.MOVE_FAILED_INTERNAL_ERROR); 13307 break; 13308 } 13309 } 13310 }; 13311 13312 // Treat a move like reinstalling an existing app, which ensures that we 13313 // process everythign uniformly, like unpacking native libraries. 13314 newInstallFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 13315 13316 final Message msg = mHandler.obtainMessage(INIT_COPY); 13317 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 13318 msg.obj = new InstallParams(origin, installObserver, newInstallFlags, 13319 installerPackageName, null, user, packageAbiOverride); 13320 mHandler.sendMessage(msg); 13321 } 13322 13323 @Override setInstallLocation(int loc)13324 public boolean setInstallLocation(int loc) { 13325 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 13326 null); 13327 if (getInstallLocation() == loc) { 13328 return true; 13329 } 13330 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 13331 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 13332 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 13333 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 13334 return true; 13335 } 13336 return false; 13337 } 13338 13339 @Override getInstallLocation()13340 public int getInstallLocation() { 13341 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13342 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 13343 PackageHelper.APP_INSTALL_AUTO); 13344 } 13345 13346 /** Called by UserManagerService */ cleanUpUserLILPw(UserManagerService userManager, int userHandle)13347 void cleanUpUserLILPw(UserManagerService userManager, int userHandle) { 13348 mDirtyUsers.remove(userHandle); 13349 mSettings.removeUserLPw(userHandle); 13350 mPendingBroadcasts.remove(userHandle); 13351 if (mInstaller != null) { 13352 // Technically, we shouldn't be doing this with the package lock 13353 // held. However, this is very rare, and there is already so much 13354 // other disk I/O going on, that we'll let it slide for now. 13355 mInstaller.removeUserDataDirs(userHandle); 13356 } 13357 mUserNeedsBadging.delete(userHandle); 13358 removeUnusedPackagesLILPw(userManager, userHandle); 13359 } 13360 13361 /** 13362 * We're removing userHandle and would like to remove any downloaded packages 13363 * that are no longer in use by any other user. 13364 * @param userHandle the user being removed 13365 */ removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle)13366 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 13367 final boolean DEBUG_CLEAN_APKS = false; 13368 int [] users = userManager.getUserIdsLPr(); 13369 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 13370 while (psit.hasNext()) { 13371 PackageSetting ps = psit.next(); 13372 if (ps.pkg == null) { 13373 continue; 13374 } 13375 final String packageName = ps.pkg.packageName; 13376 // Skip over if system app 13377 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 13378 continue; 13379 } 13380 if (DEBUG_CLEAN_APKS) { 13381 Slog.i(TAG, "Checking package " + packageName); 13382 } 13383 boolean keep = false; 13384 for (int i = 0; i < users.length; i++) { 13385 if (users[i] != userHandle && ps.getInstalled(users[i])) { 13386 keep = true; 13387 if (DEBUG_CLEAN_APKS) { 13388 Slog.i(TAG, " Keeping package " + packageName + " for user " 13389 + users[i]); 13390 } 13391 break; 13392 } 13393 } 13394 if (!keep) { 13395 if (DEBUG_CLEAN_APKS) { 13396 Slog.i(TAG, " Removing package " + packageName); 13397 } 13398 mHandler.post(new Runnable() { 13399 public void run() { 13400 deletePackageX(packageName, userHandle, 0); 13401 } //end run 13402 }); 13403 } 13404 } 13405 } 13406 13407 /** Called by UserManagerService */ createNewUserLILPw(int userHandle, File path)13408 void createNewUserLILPw(int userHandle, File path) { 13409 if (mInstaller != null) { 13410 mInstaller.createUserConfig(userHandle); 13411 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path); 13412 } 13413 } 13414 13415 @Override getVerifierDeviceIdentity()13416 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 13417 mContext.enforceCallingOrSelfPermission( 13418 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13419 "Only package verification agents can read the verifier device identity"); 13420 13421 synchronized (mPackages) { 13422 return mSettings.getVerifierDeviceIdentityLPw(); 13423 } 13424 } 13425 13426 @Override setPermissionEnforced(String permission, boolean enforced)13427 public void setPermissionEnforced(String permission, boolean enforced) { 13428 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); 13429 if (READ_EXTERNAL_STORAGE.equals(permission)) { 13430 synchronized (mPackages) { 13431 if (mSettings.mReadExternalStorageEnforced == null 13432 || mSettings.mReadExternalStorageEnforced != enforced) { 13433 mSettings.mReadExternalStorageEnforced = enforced; 13434 mSettings.writeLPr(); 13435 } 13436 } 13437 // kill any non-foreground processes so we restart them and 13438 // grant/revoke the GID. 13439 final IActivityManager am = ActivityManagerNative.getDefault(); 13440 if (am != null) { 13441 final long token = Binder.clearCallingIdentity(); 13442 try { 13443 am.killProcessesBelowForeground("setPermissionEnforcement"); 13444 } catch (RemoteException e) { 13445 } finally { 13446 Binder.restoreCallingIdentity(token); 13447 } 13448 } 13449 } else { 13450 throw new IllegalArgumentException("No selective enforcement for " + permission); 13451 } 13452 } 13453 13454 @Override 13455 @Deprecated isPermissionEnforced(String permission)13456 public boolean isPermissionEnforced(String permission) { 13457 return true; 13458 } 13459 13460 @Override isStorageLow()13461 public boolean isStorageLow() { 13462 final long token = Binder.clearCallingIdentity(); 13463 try { 13464 final DeviceStorageMonitorInternal 13465 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 13466 if (dsm != null) { 13467 return dsm.isMemoryLow(); 13468 } else { 13469 return false; 13470 } 13471 } finally { 13472 Binder.restoreCallingIdentity(token); 13473 } 13474 } 13475 13476 @Override getPackageInstaller()13477 public IPackageInstaller getPackageInstaller() { 13478 return mInstallerService; 13479 } 13480 userNeedsBadging(int userId)13481 private boolean userNeedsBadging(int userId) { 13482 int index = mUserNeedsBadging.indexOfKey(userId); 13483 if (index < 0) { 13484 final UserInfo userInfo; 13485 final long token = Binder.clearCallingIdentity(); 13486 try { 13487 userInfo = sUserManager.getUserInfo(userId); 13488 } finally { 13489 Binder.restoreCallingIdentity(token); 13490 } 13491 final boolean b; 13492 if (userInfo != null && userInfo.isManagedProfile()) { 13493 b = true; 13494 } else { 13495 b = false; 13496 } 13497 mUserNeedsBadging.put(userId, b); 13498 return b; 13499 } 13500 return mUserNeedsBadging.valueAt(index); 13501 } 13502 13503 @Override getKeySetByAlias(String packageName, String alias)13504 public KeySet getKeySetByAlias(String packageName, String alias) { 13505 if (packageName == null || alias == null) { 13506 return null; 13507 } 13508 synchronized(mPackages) { 13509 final PackageParser.Package pkg = mPackages.get(packageName); 13510 if (pkg == null) { 13511 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 13512 throw new IllegalArgumentException("Unknown package: " + packageName); 13513 } 13514 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13515 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 13516 } 13517 } 13518 13519 @Override getSigningKeySet(String packageName)13520 public KeySet getSigningKeySet(String packageName) { 13521 if (packageName == null) { 13522 return null; 13523 } 13524 synchronized(mPackages) { 13525 final PackageParser.Package pkg = mPackages.get(packageName); 13526 if (pkg == null) { 13527 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 13528 throw new IllegalArgumentException("Unknown package: " + packageName); 13529 } 13530 if (pkg.applicationInfo.uid != Binder.getCallingUid() 13531 && Process.SYSTEM_UID != Binder.getCallingUid()) { 13532 throw new SecurityException("May not access signing KeySet of other apps."); 13533 } 13534 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13535 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 13536 } 13537 } 13538 13539 @Override isPackageSignedByKeySet(String packageName, KeySet ks)13540 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 13541 if (packageName == null || ks == null) { 13542 return false; 13543 } 13544 synchronized(mPackages) { 13545 final PackageParser.Package pkg = mPackages.get(packageName); 13546 if (pkg == null) { 13547 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 13548 throw new IllegalArgumentException("Unknown package: " + packageName); 13549 } 13550 IBinder ksh = ks.getToken(); 13551 if (ksh instanceof KeySetHandle) { 13552 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13553 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 13554 } 13555 return false; 13556 } 13557 } 13558 13559 @Override isPackageSignedByKeySetExactly(String packageName, KeySet ks)13560 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 13561 if (packageName == null || ks == null) { 13562 return false; 13563 } 13564 synchronized(mPackages) { 13565 final PackageParser.Package pkg = mPackages.get(packageName); 13566 if (pkg == null) { 13567 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 13568 throw new IllegalArgumentException("Unknown package: " + packageName); 13569 } 13570 IBinder ksh = ks.getToken(); 13571 if (ksh instanceof KeySetHandle) { 13572 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13573 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 13574 } 13575 return false; 13576 } 13577 } 13578 getUsageStatsIfNoPackageUsageInfo()13579 public void getUsageStatsIfNoPackageUsageInfo() { 13580 if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { 13581 UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 13582 if (usm == null) { 13583 throw new IllegalStateException("UsageStatsManager must be initialized"); 13584 } 13585 long now = System.currentTimeMillis(); 13586 Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); 13587 for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { 13588 String packageName = entry.getKey(); 13589 PackageParser.Package pkg = mPackages.get(packageName); 13590 if (pkg == null) { 13591 continue; 13592 } 13593 UsageStats usage = entry.getValue(); 13594 pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); 13595 mPackageUsage.mIsHistoricalPackageUsageAvailable = true; 13596 } 13597 } 13598 } 13599 13600 /** 13601 * Check and throw if the given before/after packages would be considered a 13602 * downgrade. 13603 */ checkDowngrade(PackageParser.Package before, PackageInfoLite after)13604 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 13605 throws PackageManagerException { 13606 if (after.versionCode < before.mVersionCode) { 13607 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 13608 "Update version code " + after.versionCode + " is older than current " 13609 + before.mVersionCode); 13610 } else if (after.versionCode == before.mVersionCode) { 13611 if (after.baseRevisionCode < before.baseRevisionCode) { 13612 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 13613 "Update base revision code " + after.baseRevisionCode 13614 + " is older than current " + before.baseRevisionCode); 13615 } 13616 13617 if (!ArrayUtils.isEmpty(after.splitNames)) { 13618 for (int i = 0; i < after.splitNames.length; i++) { 13619 final String splitName = after.splitNames[i]; 13620 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 13621 if (j != -1) { 13622 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 13623 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 13624 "Update split " + splitName + " revision code " 13625 + after.splitRevisionCodes[i] + " is older than current " 13626 + before.splitRevisionCodes[j]); 13627 } 13628 } 13629 } 13630 } 13631 } 13632 } 13633 } 13634