PackageManagerService.java revision c6f22499f3046684d7175e10ca42cce1492cd36f
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 17package com.android.server.pm; 18 19import static android.Manifest.permission.GRANT_REVOKE_PERMISSIONS; 20import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 21import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 26import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 27import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 28import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 29import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT; 30import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 31import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 32import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 33import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 34import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 35import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 36import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 37import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 38import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 39import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 40import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 41import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED; 42import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 43import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 44import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 45import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 46import static android.content.pm.PackageParser.isApkFile; 47import static android.os.Process.PACKAGE_INFO_GID; 48import static android.os.Process.SYSTEM_UID; 49import static android.system.OsConstants.O_CREAT; 50import static android.system.OsConstants.O_RDWR; 51import static android.system.OsConstants.S_IRGRP; 52import static android.system.OsConstants.S_IROTH; 53import static android.system.OsConstants.S_IRWXU; 54import static android.system.OsConstants.S_IXGRP; 55import static android.system.OsConstants.S_IXOTH; 56import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 57import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER; 58import static com.android.internal.util.ArrayUtils.appendInt; 59import static com.android.internal.util.ArrayUtils.removeInt; 60 61import android.util.ArrayMap; 62 63import com.android.internal.R; 64import com.android.internal.app.IMediaContainerService; 65import com.android.internal.app.ResolverActivity; 66import com.android.internal.content.NativeLibraryHelper; 67import com.android.internal.content.PackageHelper; 68import com.android.internal.os.IParcelFileDescriptorFactory; 69import com.android.internal.util.ArrayUtils; 70import com.android.internal.util.FastPrintWriter; 71import com.android.internal.util.FastXmlSerializer; 72import com.android.internal.util.IndentingPrintWriter; 73import com.android.internal.util.Preconditions; 74import com.android.server.EventLogTags; 75import com.android.server.IntentResolver; 76import com.android.server.LocalServices; 77import com.android.server.ServiceThread; 78import com.android.server.SystemConfig; 79import com.android.server.Watchdog; 80import com.android.server.pm.Settings.DatabaseVersion; 81import com.android.server.storage.DeviceStorageMonitorInternal; 82 83import org.xmlpull.v1.XmlSerializer; 84 85import android.app.ActivityManager; 86import android.app.ActivityManagerNative; 87import android.app.IActivityManager; 88import android.app.admin.IDevicePolicyManager; 89import android.app.backup.IBackupManager; 90import android.content.BroadcastReceiver; 91import android.content.ComponentName; 92import android.content.Context; 93import android.content.IIntentReceiver; 94import android.content.Intent; 95import android.content.IntentFilter; 96import android.content.IntentSender; 97import android.content.IntentSender.SendIntentException; 98import android.content.ServiceConnection; 99import android.content.pm.ActivityInfo; 100import android.content.pm.ApplicationInfo; 101import android.content.pm.FeatureInfo; 102import android.content.pm.IPackageDataObserver; 103import android.content.pm.IPackageDeleteObserver; 104import android.content.pm.IPackageDeleteObserver2; 105import android.content.pm.IPackageInstallObserver2; 106import android.content.pm.IPackageInstaller; 107import android.content.pm.IPackageManager; 108import android.content.pm.IPackageMoveObserver; 109import android.content.pm.IPackageStatsObserver; 110import android.content.pm.InstallSessionParams; 111import android.content.pm.InstrumentationInfo; 112import android.content.pm.KeySet; 113import android.content.pm.ManifestDigest; 114import android.content.pm.PackageCleanItem; 115import android.content.pm.PackageInfo; 116import android.content.pm.PackageInfoLite; 117import android.content.pm.PackageManager; 118import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 119import android.content.pm.PackageParser.ActivityIntentInfo; 120import android.content.pm.PackageParser.PackageLite; 121import android.content.pm.PackageParser.PackageParserException; 122import android.content.pm.PackageParser; 123import android.content.pm.PackageStats; 124import android.content.pm.PackageUserState; 125import android.content.pm.ParceledListSlice; 126import android.content.pm.PermissionGroupInfo; 127import android.content.pm.PermissionInfo; 128import android.content.pm.ProviderInfo; 129import android.content.pm.ResolveInfo; 130import android.content.pm.ServiceInfo; 131import android.content.pm.Signature; 132import android.content.pm.UserInfo; 133import android.content.pm.VerificationParams; 134import android.content.pm.VerifierDeviceIdentity; 135import android.content.pm.VerifierInfo; 136import android.content.res.Resources; 137import android.hardware.display.DisplayManager; 138import android.net.Uri; 139import android.os.Binder; 140import android.os.Build; 141import android.os.Bundle; 142import android.os.Environment; 143import android.os.Environment.UserEnvironment; 144import android.os.FileUtils; 145import android.os.Handler; 146import android.os.IBinder; 147import android.os.Looper; 148import android.os.Message; 149import android.os.Parcel; 150import android.os.ParcelFileDescriptor; 151import android.os.Process; 152import android.os.RemoteException; 153import android.os.SELinux; 154import android.os.ServiceManager; 155import android.os.SystemClock; 156import android.os.SystemProperties; 157import android.os.UserHandle; 158import android.os.UserManager; 159import android.security.KeyStore; 160import android.security.SystemKeyStore; 161import android.system.ErrnoException; 162import android.system.Os; 163import android.system.StructStat; 164import android.text.TextUtils; 165import android.util.ArraySet; 166import android.util.AtomicFile; 167import android.util.DisplayMetrics; 168import android.util.EventLog; 169import android.util.ExceptionUtils; 170import android.util.Log; 171import android.util.LogPrinter; 172import android.util.PrintStreamPrinter; 173import android.util.Slog; 174import android.util.SparseArray; 175import android.util.SparseBooleanArray; 176import android.view.Display; 177 178import java.io.BufferedInputStream; 179import java.io.BufferedOutputStream; 180import java.io.File; 181import java.io.FileDescriptor; 182import java.io.FileInputStream; 183import java.io.FileNotFoundException; 184import java.io.FileOutputStream; 185import java.io.FilenameFilter; 186import java.io.IOException; 187import java.io.InputStream; 188import java.io.PrintWriter; 189import java.nio.charset.StandardCharsets; 190import java.security.NoSuchAlgorithmException; 191import java.security.PublicKey; 192import java.security.cert.CertificateEncodingException; 193import java.security.cert.CertificateException; 194import java.text.SimpleDateFormat; 195import java.util.ArrayList; 196import java.util.Arrays; 197import java.util.Collection; 198import java.util.Collections; 199import java.util.Comparator; 200import java.util.Date; 201import java.util.HashMap; 202import java.util.HashSet; 203import java.util.Iterator; 204import java.util.List; 205import java.util.Map; 206import java.util.Set; 207import java.util.concurrent.atomic.AtomicBoolean; 208import java.util.concurrent.atomic.AtomicLong; 209 210import dalvik.system.DexFile; 211import dalvik.system.StaleDexCacheError; 212import dalvik.system.VMRuntime; 213 214import libcore.io.IoUtils; 215 216/** 217 * Keep track of all those .apks everywhere. 218 * 219 * This is very central to the platform's security; please run the unit 220 * tests whenever making modifications here: 221 * 222mmm frameworks/base/tests/AndroidTests 223adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 224adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 225 * 226 * {@hide} 227 */ 228public class PackageManagerService extends IPackageManager.Stub { 229 static final String TAG = "PackageManager"; 230 static final boolean DEBUG_SETTINGS = false; 231 static final boolean DEBUG_PREFERRED = false; 232 static final boolean DEBUG_UPGRADE = false; 233 private static final boolean DEBUG_INSTALL = false; 234 private static final boolean DEBUG_REMOVE = false; 235 private static final boolean DEBUG_BROADCASTS = false; 236 private static final boolean DEBUG_SHOW_INFO = false; 237 private static final boolean DEBUG_PACKAGE_INFO = false; 238 private static final boolean DEBUG_INTENT_MATCHING = false; 239 private static final boolean DEBUG_PACKAGE_SCANNING = false; 240 private static final boolean DEBUG_VERIFY = false; 241 private static final boolean DEBUG_DEXOPT = false; 242 private static final boolean DEBUG_ABI_SELECTION = false; 243 244 private static final int RADIO_UID = Process.PHONE_UID; 245 private static final int LOG_UID = Process.LOG_UID; 246 private static final int NFC_UID = Process.NFC_UID; 247 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 248 private static final int SHELL_UID = Process.SHELL_UID; 249 250 // Cap the size of permission trees that 3rd party apps can define 251 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 252 253 // Suffix used during package installation when copying/moving 254 // package apks to install directory. 255 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 256 257 static final int SCAN_MONITOR = 1<<0; 258 static final int SCAN_NO_DEX = 1<<1; 259 static final int SCAN_FORCE_DEX = 1<<2; 260 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 261 static final int SCAN_NEW_INSTALL = 1<<4; 262 static final int SCAN_NO_PATHS = 1<<5; 263 static final int SCAN_UPDATE_TIME = 1<<6; 264 static final int SCAN_DEFER_DEX = 1<<7; 265 static final int SCAN_BOOTING = 1<<8; 266 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 267 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 268 269 static final int REMOVE_CHATTY = 1<<16; 270 271 /** 272 * Timeout (in milliseconds) after which the watchdog should declare that 273 * our handler thread is wedged. The usual default for such things is one 274 * minute but we sometimes do very lengthy I/O operations on this thread, 275 * such as installing multi-gigabyte applications, so ours needs to be longer. 276 */ 277 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 278 279 /** 280 * Whether verification is enabled by default. 281 */ 282 private static final boolean DEFAULT_VERIFY_ENABLE = true; 283 284 /** 285 * The default maximum time to wait for the verification agent to return in 286 * milliseconds. 287 */ 288 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 289 290 /** 291 * The default response for package verification timeout. 292 * 293 * This can be either PackageManager.VERIFICATION_ALLOW or 294 * PackageManager.VERIFICATION_REJECT. 295 */ 296 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 297 298 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 299 300 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 301 DEFAULT_CONTAINER_PACKAGE, 302 "com.android.defcontainer.DefaultContainerService"); 303 304 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 305 306 private static final String LIB_DIR_NAME = "lib"; 307 private static final String LIB64_DIR_NAME = "lib64"; 308 309 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 310 311 static final String mTempContainerPrefix = "smdl2tmp"; 312 313 private static String sPreferredInstructionSet; 314 315 final ServiceThread mHandlerThread; 316 317 private static final String IDMAP_PREFIX = "/data/resource-cache/"; 318 private static final String IDMAP_SUFFIX = "@idmap"; 319 320 final PackageHandler mHandler; 321 322 final int mSdkVersion = Build.VERSION.SDK_INT; 323 324 final Context mContext; 325 final boolean mFactoryTest; 326 final boolean mOnlyCore; 327 final DisplayMetrics mMetrics; 328 final int mDefParseFlags; 329 final String[] mSeparateProcesses; 330 331 // This is where all application persistent data goes. 332 final File mAppDataDir; 333 334 // This is where all application persistent data goes for secondary users. 335 final File mUserAppDataDir; 336 337 /** The location for ASEC container files on internal storage. */ 338 final String mAsecInternalPath; 339 340 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 341 // LOCK HELD. Can be called with mInstallLock held. 342 final Installer mInstaller; 343 344 /** Directory where installed third-party apps stored */ 345 final File mAppInstallDir; 346 347 /** 348 * Directory to which applications installed internally have their 349 * 32 bit native libraries copied. 350 */ 351 private File mAppLib32InstallDir; 352 353 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 354 // apps. 355 final File mDrmAppPrivateInstallDir; 356 357 // ---------------------------------------------------------------- 358 359 // Lock for state used when installing and doing other long running 360 // operations. Methods that must be called with this lock held have 361 // the suffix "LI". 362 final Object mInstallLock = new Object(); 363 364 // These are the directories in the 3rd party applications installed dir 365 // that we have currently loaded packages from. Keys are the application's 366 // installed zip file (absolute codePath), and values are Package. 367 final HashMap<String, PackageParser.Package> mAppDirs = 368 new HashMap<String, PackageParser.Package>(); 369 370 // ---------------------------------------------------------------- 371 372 // Keys are String (package name), values are Package. This also serves 373 // as the lock for the global state. Methods that must be called with 374 // this lock held have the prefix "LP". 375 final HashMap<String, PackageParser.Package> mPackages = 376 new HashMap<String, PackageParser.Package>(); 377 378 // Tracks available target package names -> overlay package paths. 379 final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays = 380 new HashMap<String, HashMap<String, PackageParser.Package>>(); 381 382 final Settings mSettings; 383 boolean mRestoredSettings; 384 385 // System configuration read by SystemConfig. 386 final int[] mGlobalGids; 387 final SparseArray<HashSet<String>> mSystemPermissions; 388 final HashMap<String, FeatureInfo> mAvailableFeatures; 389 390 // If mac_permissions.xml was found for seinfo labeling. 391 boolean mFoundPolicyFile; 392 393 // If a recursive restorecon of /data/data/<pkg> is needed. 394 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 395 396 public static final class SharedLibraryEntry { 397 public final String path; 398 public final String apk; 399 400 SharedLibraryEntry(String _path, String _apk) { 401 path = _path; 402 apk = _apk; 403 } 404 } 405 406 // Currently known shared libraries. 407 final HashMap<String, SharedLibraryEntry> mSharedLibraries = 408 new HashMap<String, SharedLibraryEntry>(); 409 410 // All available activities, for your resolving pleasure. 411 final ActivityIntentResolver mActivities = 412 new ActivityIntentResolver(); 413 414 // All available receivers, for your resolving pleasure. 415 final ActivityIntentResolver mReceivers = 416 new ActivityIntentResolver(); 417 418 // All available services, for your resolving pleasure. 419 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 420 421 // All available providers, for your resolving pleasure. 422 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 423 424 // Mapping from provider base names (first directory in content URI codePath) 425 // to the provider information. 426 final HashMap<String, PackageParser.Provider> mProvidersByAuthority = 427 new HashMap<String, PackageParser.Provider>(); 428 429 // Mapping from instrumentation class names to info about them. 430 final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 431 new HashMap<ComponentName, PackageParser.Instrumentation>(); 432 433 // Mapping from permission names to info about them. 434 final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups = 435 new HashMap<String, PackageParser.PermissionGroup>(); 436 437 // Packages whose data we have transfered into another package, thus 438 // should no longer exist. 439 final HashSet<String> mTransferedPackages = new HashSet<String>(); 440 441 // Broadcast actions that are only available to the system. 442 final HashSet<String> mProtectedBroadcasts = new HashSet<String>(); 443 444 /** List of packages waiting for verification. */ 445 final SparseArray<PackageVerificationState> mPendingVerification 446 = new SparseArray<PackageVerificationState>(); 447 448 /** Set of packages associated with each app op permission. */ 449 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 450 451 final PackageInstallerService mInstallerService; 452 453 HashSet<PackageParser.Package> mDeferredDexOpt = null; 454 455 // Cache of users who need badging. 456 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 457 458 /** Token for keys in mPendingVerification. */ 459 private int mPendingVerificationToken = 0; 460 461 boolean mSystemReady; 462 boolean mSafeMode; 463 boolean mHasSystemUidErrors; 464 465 ApplicationInfo mAndroidApplication; 466 final ActivityInfo mResolveActivity = new ActivityInfo(); 467 final ResolveInfo mResolveInfo = new ResolveInfo(); 468 ComponentName mResolveComponentName; 469 PackageParser.Package mPlatformPackage; 470 ComponentName mCustomResolverComponentName; 471 472 boolean mResolverReplaced = false; 473 474 // Set of pending broadcasts for aggregating enable/disable of components. 475 static class PendingPackageBroadcasts { 476 // for each user id, a map of <package name -> components within that package> 477 final SparseArray<HashMap<String, ArrayList<String>>> mUidMap; 478 479 public PendingPackageBroadcasts() { 480 mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2); 481 } 482 483 public ArrayList<String> get(int userId, String packageName) { 484 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId); 485 return packages.get(packageName); 486 } 487 488 public void put(int userId, String packageName, ArrayList<String> components) { 489 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId); 490 packages.put(packageName, components); 491 } 492 493 public void remove(int userId, String packageName) { 494 HashMap<String, ArrayList<String>> packages = mUidMap.get(userId); 495 if (packages != null) { 496 packages.remove(packageName); 497 } 498 } 499 500 public void remove(int userId) { 501 mUidMap.remove(userId); 502 } 503 504 public int userIdCount() { 505 return mUidMap.size(); 506 } 507 508 public int userIdAt(int n) { 509 return mUidMap.keyAt(n); 510 } 511 512 public HashMap<String, ArrayList<String>> packagesForUserId(int userId) { 513 return mUidMap.get(userId); 514 } 515 516 public int size() { 517 // total number of pending broadcast entries across all userIds 518 int num = 0; 519 for (int i = 0; i< mUidMap.size(); i++) { 520 num += mUidMap.valueAt(i).size(); 521 } 522 return num; 523 } 524 525 public void clear() { 526 mUidMap.clear(); 527 } 528 529 private HashMap<String, ArrayList<String>> getOrAllocate(int userId) { 530 HashMap<String, ArrayList<String>> map = mUidMap.get(userId); 531 if (map == null) { 532 map = new HashMap<String, ArrayList<String>>(); 533 mUidMap.put(userId, map); 534 } 535 return map; 536 } 537 } 538 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 539 540 // Service Connection to remote media container service to copy 541 // package uri's from external media onto secure containers 542 // or internal storage. 543 private IMediaContainerService mContainerService = null; 544 545 static final int SEND_PENDING_BROADCAST = 1; 546 static final int MCS_BOUND = 3; 547 static final int END_COPY = 4; 548 static final int INIT_COPY = 5; 549 static final int MCS_UNBIND = 6; 550 static final int START_CLEANING_PACKAGE = 7; 551 static final int FIND_INSTALL_LOC = 8; 552 static final int POST_INSTALL = 9; 553 static final int MCS_RECONNECT = 10; 554 static final int MCS_GIVE_UP = 11; 555 static final int UPDATED_MEDIA_STATUS = 12; 556 static final int WRITE_SETTINGS = 13; 557 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 558 static final int PACKAGE_VERIFIED = 15; 559 static final int CHECK_PENDING_VERIFICATION = 16; 560 561 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 562 563 // Delay time in millisecs 564 static final int BROADCAST_DELAY = 10 * 1000; 565 566 static UserManagerService sUserManager; 567 568 // Stores a list of users whose package restrictions file needs to be updated 569 private HashSet<Integer> mDirtyUsers = new HashSet<Integer>(); 570 571 final private DefaultContainerConnection mDefContainerConn = 572 new DefaultContainerConnection(); 573 class DefaultContainerConnection implements ServiceConnection { 574 public void onServiceConnected(ComponentName name, IBinder service) { 575 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 576 IMediaContainerService imcs = 577 IMediaContainerService.Stub.asInterface(service); 578 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 579 } 580 581 public void onServiceDisconnected(ComponentName name) { 582 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 583 } 584 }; 585 586 // Recordkeeping of restore-after-install operations that are currently in flight 587 // between the Package Manager and the Backup Manager 588 class PostInstallData { 589 public InstallArgs args; 590 public PackageInstalledInfo res; 591 592 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 593 args = _a; 594 res = _r; 595 } 596 }; 597 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 598 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 599 600 private final String mRequiredVerifierPackage; 601 602 private final PackageUsage mPackageUsage = new PackageUsage(); 603 604 private class PackageUsage { 605 private static final int WRITE_INTERVAL 606 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 607 608 private final Object mFileLock = new Object(); 609 private final AtomicLong mLastWritten = new AtomicLong(0); 610 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 611 612 private boolean mIsHistoricalPackageUsageAvailable = true; 613 614 boolean isHistoricalPackageUsageAvailable() { 615 return mIsHistoricalPackageUsageAvailable; 616 } 617 618 void write(boolean force) { 619 if (force) { 620 writeInternal(); 621 return; 622 } 623 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 624 && !DEBUG_DEXOPT) { 625 return; 626 } 627 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 628 new Thread("PackageUsage_DiskWriter") { 629 @Override 630 public void run() { 631 try { 632 writeInternal(); 633 } finally { 634 mBackgroundWriteRunning.set(false); 635 } 636 } 637 }.start(); 638 } 639 } 640 641 private void writeInternal() { 642 synchronized (mPackages) { 643 synchronized (mFileLock) { 644 AtomicFile file = getFile(); 645 FileOutputStream f = null; 646 try { 647 f = file.startWrite(); 648 BufferedOutputStream out = new BufferedOutputStream(f); 649 FileUtils.setPermissions(file.getBaseFile().getPath(), 0660, SYSTEM_UID, PACKAGE_INFO_GID); 650 StringBuilder sb = new StringBuilder(); 651 for (PackageParser.Package pkg : mPackages.values()) { 652 if (pkg.mLastPackageUsageTimeInMills == 0) { 653 continue; 654 } 655 sb.setLength(0); 656 sb.append(pkg.packageName); 657 sb.append(' '); 658 sb.append((long)pkg.mLastPackageUsageTimeInMills); 659 sb.append('\n'); 660 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 661 } 662 out.flush(); 663 file.finishWrite(f); 664 } catch (IOException e) { 665 if (f != null) { 666 file.failWrite(f); 667 } 668 Log.e(TAG, "Failed to write package usage times", e); 669 } 670 } 671 } 672 mLastWritten.set(SystemClock.elapsedRealtime()); 673 } 674 675 void readLP() { 676 synchronized (mFileLock) { 677 AtomicFile file = getFile(); 678 BufferedInputStream in = null; 679 try { 680 in = new BufferedInputStream(file.openRead()); 681 StringBuffer sb = new StringBuffer(); 682 while (true) { 683 String packageName = readToken(in, sb, ' '); 684 if (packageName == null) { 685 break; 686 } 687 String timeInMillisString = readToken(in, sb, '\n'); 688 if (timeInMillisString == null) { 689 throw new IOException("Failed to find last usage time for package " 690 + packageName); 691 } 692 PackageParser.Package pkg = mPackages.get(packageName); 693 if (pkg == null) { 694 continue; 695 } 696 long timeInMillis; 697 try { 698 timeInMillis = Long.parseLong(timeInMillisString.toString()); 699 } catch (NumberFormatException e) { 700 throw new IOException("Failed to parse " + timeInMillisString 701 + " as a long.", e); 702 } 703 pkg.mLastPackageUsageTimeInMills = timeInMillis; 704 } 705 } catch (FileNotFoundException expected) { 706 mIsHistoricalPackageUsageAvailable = false; 707 } catch (IOException e) { 708 Log.w(TAG, "Failed to read package usage times", e); 709 } finally { 710 IoUtils.closeQuietly(in); 711 } 712 } 713 mLastWritten.set(SystemClock.elapsedRealtime()); 714 } 715 716 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 717 throws IOException { 718 sb.setLength(0); 719 while (true) { 720 int ch = in.read(); 721 if (ch == -1) { 722 if (sb.length() == 0) { 723 return null; 724 } 725 throw new IOException("Unexpected EOF"); 726 } 727 if (ch == endOfToken) { 728 return sb.toString(); 729 } 730 sb.append((char)ch); 731 } 732 } 733 734 private AtomicFile getFile() { 735 File dataDir = Environment.getDataDirectory(); 736 File systemDir = new File(dataDir, "system"); 737 File fname = new File(systemDir, "package-usage.list"); 738 return new AtomicFile(fname); 739 } 740 } 741 742 class PackageHandler extends Handler { 743 private boolean mBound = false; 744 final ArrayList<HandlerParams> mPendingInstalls = 745 new ArrayList<HandlerParams>(); 746 747 private boolean connectToService() { 748 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 749 " DefaultContainerService"); 750 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 751 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 752 if (mContext.bindServiceAsUser(service, mDefContainerConn, 753 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 754 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 755 mBound = true; 756 return true; 757 } 758 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 759 return false; 760 } 761 762 private void disconnectService() { 763 mContainerService = null; 764 mBound = false; 765 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 766 mContext.unbindService(mDefContainerConn); 767 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 768 } 769 770 PackageHandler(Looper looper) { 771 super(looper); 772 } 773 774 public void handleMessage(Message msg) { 775 try { 776 doHandleMessage(msg); 777 } finally { 778 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 779 } 780 } 781 782 void doHandleMessage(Message msg) { 783 switch (msg.what) { 784 case INIT_COPY: { 785 HandlerParams params = (HandlerParams) msg.obj; 786 int idx = mPendingInstalls.size(); 787 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 788 // If a bind was already initiated we dont really 789 // need to do anything. The pending install 790 // will be processed later on. 791 if (!mBound) { 792 // If this is the only one pending we might 793 // have to bind to the service again. 794 if (!connectToService()) { 795 Slog.e(TAG, "Failed to bind to media container service"); 796 params.serviceError(); 797 return; 798 } else { 799 // Once we bind to the service, the first 800 // pending request will be processed. 801 mPendingInstalls.add(idx, params); 802 } 803 } else { 804 mPendingInstalls.add(idx, params); 805 // Already bound to the service. Just make 806 // sure we trigger off processing the first request. 807 if (idx == 0) { 808 mHandler.sendEmptyMessage(MCS_BOUND); 809 } 810 } 811 break; 812 } 813 case MCS_BOUND: { 814 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 815 if (msg.obj != null) { 816 mContainerService = (IMediaContainerService) msg.obj; 817 } 818 if (mContainerService == null) { 819 // Something seriously wrong. Bail out 820 Slog.e(TAG, "Cannot bind to media container service"); 821 for (HandlerParams params : mPendingInstalls) { 822 // Indicate service bind error 823 params.serviceError(); 824 } 825 mPendingInstalls.clear(); 826 } else if (mPendingInstalls.size() > 0) { 827 HandlerParams params = mPendingInstalls.get(0); 828 if (params != null) { 829 if (params.startCopy()) { 830 // We are done... look for more work or to 831 // go idle. 832 if (DEBUG_SD_INSTALL) Log.i(TAG, 833 "Checking for more work or unbind..."); 834 // Delete pending install 835 if (mPendingInstalls.size() > 0) { 836 mPendingInstalls.remove(0); 837 } 838 if (mPendingInstalls.size() == 0) { 839 if (mBound) { 840 if (DEBUG_SD_INSTALL) Log.i(TAG, 841 "Posting delayed MCS_UNBIND"); 842 removeMessages(MCS_UNBIND); 843 Message ubmsg = obtainMessage(MCS_UNBIND); 844 // Unbind after a little delay, to avoid 845 // continual thrashing. 846 sendMessageDelayed(ubmsg, 10000); 847 } 848 } else { 849 // There are more pending requests in queue. 850 // Just post MCS_BOUND message to trigger processing 851 // of next pending install. 852 if (DEBUG_SD_INSTALL) Log.i(TAG, 853 "Posting MCS_BOUND for next work"); 854 mHandler.sendEmptyMessage(MCS_BOUND); 855 } 856 } 857 } 858 } else { 859 // Should never happen ideally. 860 Slog.w(TAG, "Empty queue"); 861 } 862 break; 863 } 864 case MCS_RECONNECT: { 865 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 866 if (mPendingInstalls.size() > 0) { 867 if (mBound) { 868 disconnectService(); 869 } 870 if (!connectToService()) { 871 Slog.e(TAG, "Failed to bind to media container service"); 872 for (HandlerParams params : mPendingInstalls) { 873 // Indicate service bind error 874 params.serviceError(); 875 } 876 mPendingInstalls.clear(); 877 } 878 } 879 break; 880 } 881 case MCS_UNBIND: { 882 // If there is no actual work left, then time to unbind. 883 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 884 885 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 886 if (mBound) { 887 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 888 889 disconnectService(); 890 } 891 } else if (mPendingInstalls.size() > 0) { 892 // There are more pending requests in queue. 893 // Just post MCS_BOUND message to trigger processing 894 // of next pending install. 895 mHandler.sendEmptyMessage(MCS_BOUND); 896 } 897 898 break; 899 } 900 case MCS_GIVE_UP: { 901 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 902 mPendingInstalls.remove(0); 903 break; 904 } 905 case SEND_PENDING_BROADCAST: { 906 String packages[]; 907 ArrayList<String> components[]; 908 int size = 0; 909 int uids[]; 910 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 911 synchronized (mPackages) { 912 if (mPendingBroadcasts == null) { 913 return; 914 } 915 size = mPendingBroadcasts.size(); 916 if (size <= 0) { 917 // Nothing to be done. Just return 918 return; 919 } 920 packages = new String[size]; 921 components = new ArrayList[size]; 922 uids = new int[size]; 923 int i = 0; // filling out the above arrays 924 925 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 926 int packageUserId = mPendingBroadcasts.userIdAt(n); 927 Iterator<Map.Entry<String, ArrayList<String>>> it 928 = mPendingBroadcasts.packagesForUserId(packageUserId) 929 .entrySet().iterator(); 930 while (it.hasNext() && i < size) { 931 Map.Entry<String, ArrayList<String>> ent = it.next(); 932 packages[i] = ent.getKey(); 933 components[i] = ent.getValue(); 934 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 935 uids[i] = (ps != null) 936 ? UserHandle.getUid(packageUserId, ps.appId) 937 : -1; 938 i++; 939 } 940 } 941 size = i; 942 mPendingBroadcasts.clear(); 943 } 944 // Send broadcasts 945 for (int i = 0; i < size; i++) { 946 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 947 } 948 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 949 break; 950 } 951 case START_CLEANING_PACKAGE: { 952 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 953 final String packageName = (String)msg.obj; 954 final int userId = msg.arg1; 955 final boolean andCode = msg.arg2 != 0; 956 synchronized (mPackages) { 957 if (userId == UserHandle.USER_ALL) { 958 int[] users = sUserManager.getUserIds(); 959 for (int user : users) { 960 mSettings.addPackageToCleanLPw( 961 new PackageCleanItem(user, packageName, andCode)); 962 } 963 } else { 964 mSettings.addPackageToCleanLPw( 965 new PackageCleanItem(userId, packageName, andCode)); 966 } 967 } 968 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 969 startCleaningPackages(); 970 } break; 971 case POST_INSTALL: { 972 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 973 PostInstallData data = mRunningInstalls.get(msg.arg1); 974 mRunningInstalls.delete(msg.arg1); 975 boolean deleteOld = false; 976 977 if (data != null) { 978 InstallArgs args = data.args; 979 PackageInstalledInfo res = data.res; 980 981 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 982 res.removedInfo.sendBroadcast(false, true, false); 983 Bundle extras = new Bundle(1); 984 extras.putInt(Intent.EXTRA_UID, res.uid); 985 // Determine the set of users who are adding this 986 // package for the first time vs. those who are seeing 987 // an update. 988 int[] firstUsers; 989 int[] updateUsers = new int[0]; 990 if (res.origUsers == null || res.origUsers.length == 0) { 991 firstUsers = res.newUsers; 992 } else { 993 firstUsers = new int[0]; 994 for (int i=0; i<res.newUsers.length; i++) { 995 int user = res.newUsers[i]; 996 boolean isNew = true; 997 for (int j=0; j<res.origUsers.length; j++) { 998 if (res.origUsers[j] == user) { 999 isNew = false; 1000 break; 1001 } 1002 } 1003 if (isNew) { 1004 int[] newFirst = new int[firstUsers.length+1]; 1005 System.arraycopy(firstUsers, 0, newFirst, 0, 1006 firstUsers.length); 1007 newFirst[firstUsers.length] = user; 1008 firstUsers = newFirst; 1009 } else { 1010 int[] newUpdate = new int[updateUsers.length+1]; 1011 System.arraycopy(updateUsers, 0, newUpdate, 0, 1012 updateUsers.length); 1013 newUpdate[updateUsers.length] = user; 1014 updateUsers = newUpdate; 1015 } 1016 } 1017 } 1018 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1019 res.pkg.applicationInfo.packageName, 1020 extras, null, null, firstUsers); 1021 final boolean update = res.removedInfo.removedPackage != null; 1022 if (update) { 1023 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1024 } 1025 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1026 res.pkg.applicationInfo.packageName, 1027 extras, null, null, updateUsers); 1028 if (update) { 1029 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1030 res.pkg.applicationInfo.packageName, 1031 extras, null, null, updateUsers); 1032 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1033 null, null, 1034 res.pkg.applicationInfo.packageName, null, updateUsers); 1035 1036 // treat asec-hosted packages like removable media on upgrade 1037 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) { 1038 if (DEBUG_INSTALL) { 1039 Slog.i(TAG, "upgrading pkg " + res.pkg 1040 + " is ASEC-hosted -> AVAILABLE"); 1041 } 1042 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1043 ArrayList<String> pkgList = new ArrayList<String>(1); 1044 pkgList.add(res.pkg.applicationInfo.packageName); 1045 sendResourcesChangedBroadcast(true, true, 1046 pkgList,uidArray, null); 1047 } 1048 } 1049 if (res.removedInfo.args != null) { 1050 // Remove the replaced package's older resources safely now 1051 deleteOld = true; 1052 } 1053 1054 // Log current value of "unknown sources" setting 1055 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1056 getUnknownSourcesSettings()); 1057 } 1058 // Force a gc to clear up things 1059 Runtime.getRuntime().gc(); 1060 // We delete after a gc for applications on sdcard. 1061 if (deleteOld) { 1062 synchronized (mInstallLock) { 1063 res.removedInfo.args.doPostDeleteLI(true); 1064 } 1065 } 1066 if (args.observer != null) { 1067 try { 1068 Bundle extras = extrasForInstallResult(res); 1069 args.observer.onPackageInstalled(res.name, res.returnCode, 1070 res.returnMsg, extras); 1071 } catch (RemoteException e) { 1072 Slog.i(TAG, "Observer no longer exists."); 1073 } 1074 } 1075 } else { 1076 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1077 } 1078 } break; 1079 case UPDATED_MEDIA_STATUS: { 1080 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1081 boolean reportStatus = msg.arg1 == 1; 1082 boolean doGc = msg.arg2 == 1; 1083 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1084 if (doGc) { 1085 // Force a gc to clear up stale containers. 1086 Runtime.getRuntime().gc(); 1087 } 1088 if (msg.obj != null) { 1089 @SuppressWarnings("unchecked") 1090 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1091 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1092 // Unload containers 1093 unloadAllContainers(args); 1094 } 1095 if (reportStatus) { 1096 try { 1097 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1098 PackageHelper.getMountService().finishMediaUpdate(); 1099 } catch (RemoteException e) { 1100 Log.e(TAG, "MountService not running?"); 1101 } 1102 } 1103 } break; 1104 case WRITE_SETTINGS: { 1105 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1106 synchronized (mPackages) { 1107 removeMessages(WRITE_SETTINGS); 1108 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1109 mSettings.writeLPr(); 1110 mDirtyUsers.clear(); 1111 } 1112 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1113 } break; 1114 case WRITE_PACKAGE_RESTRICTIONS: { 1115 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1116 synchronized (mPackages) { 1117 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1118 for (int userId : mDirtyUsers) { 1119 mSettings.writePackageRestrictionsLPr(userId); 1120 } 1121 mDirtyUsers.clear(); 1122 } 1123 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1124 } break; 1125 case CHECK_PENDING_VERIFICATION: { 1126 final int verificationId = msg.arg1; 1127 final PackageVerificationState state = mPendingVerification.get(verificationId); 1128 1129 if ((state != null) && !state.timeoutExtended()) { 1130 final InstallArgs args = state.getInstallArgs(); 1131 final Uri originUri = Uri.fromFile(args.originFile); 1132 1133 Slog.i(TAG, "Verification timed out for " + originUri); 1134 mPendingVerification.remove(verificationId); 1135 1136 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1137 1138 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1139 Slog.i(TAG, "Continuing with installation of " + originUri); 1140 state.setVerifierResponse(Binder.getCallingUid(), 1141 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1142 broadcastPackageVerified(verificationId, originUri, 1143 PackageManager.VERIFICATION_ALLOW, 1144 state.getInstallArgs().getUser()); 1145 try { 1146 ret = args.copyApk(mContainerService, true); 1147 } catch (RemoteException e) { 1148 Slog.e(TAG, "Could not contact the ContainerService"); 1149 } 1150 } else { 1151 broadcastPackageVerified(verificationId, originUri, 1152 PackageManager.VERIFICATION_REJECT, 1153 state.getInstallArgs().getUser()); 1154 } 1155 1156 processPendingInstall(args, ret); 1157 mHandler.sendEmptyMessage(MCS_UNBIND); 1158 } 1159 break; 1160 } 1161 case PACKAGE_VERIFIED: { 1162 final int verificationId = msg.arg1; 1163 1164 final PackageVerificationState state = mPendingVerification.get(verificationId); 1165 if (state == null) { 1166 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1167 break; 1168 } 1169 1170 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1171 1172 state.setVerifierResponse(response.callerUid, response.code); 1173 1174 if (state.isVerificationComplete()) { 1175 mPendingVerification.remove(verificationId); 1176 1177 final InstallArgs args = state.getInstallArgs(); 1178 final Uri originUri = Uri.fromFile(args.originFile); 1179 1180 int ret; 1181 if (state.isInstallAllowed()) { 1182 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1183 broadcastPackageVerified(verificationId, originUri, 1184 response.code, state.getInstallArgs().getUser()); 1185 try { 1186 ret = args.copyApk(mContainerService, true); 1187 } catch (RemoteException e) { 1188 Slog.e(TAG, "Could not contact the ContainerService"); 1189 } 1190 } else { 1191 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1192 } 1193 1194 processPendingInstall(args, ret); 1195 1196 mHandler.sendEmptyMessage(MCS_UNBIND); 1197 } 1198 1199 break; 1200 } 1201 } 1202 } 1203 } 1204 1205 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1206 Bundle extras = null; 1207 switch (res.returnCode) { 1208 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1209 extras = new Bundle(); 1210 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1211 res.origPermission); 1212 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1213 res.origPackage); 1214 break; 1215 } 1216 } 1217 return extras; 1218 } 1219 1220 void scheduleWriteSettingsLocked() { 1221 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1222 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1223 } 1224 } 1225 1226 void scheduleWritePackageRestrictionsLocked(int userId) { 1227 if (!sUserManager.exists(userId)) return; 1228 mDirtyUsers.add(userId); 1229 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1230 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1231 } 1232 } 1233 1234 public static final PackageManagerService main(Context context, Installer installer, 1235 boolean factoryTest, boolean onlyCore) { 1236 PackageManagerService m = new PackageManagerService(context, installer, 1237 factoryTest, onlyCore); 1238 ServiceManager.addService("package", m); 1239 return m; 1240 } 1241 1242 static String[] splitString(String str, char sep) { 1243 int count = 1; 1244 int i = 0; 1245 while ((i=str.indexOf(sep, i)) >= 0) { 1246 count++; 1247 i++; 1248 } 1249 1250 String[] res = new String[count]; 1251 i=0; 1252 count = 0; 1253 int lastI=0; 1254 while ((i=str.indexOf(sep, i)) >= 0) { 1255 res[count] = str.substring(lastI, i); 1256 count++; 1257 i++; 1258 lastI = i; 1259 } 1260 res[count] = str.substring(lastI, str.length()); 1261 return res; 1262 } 1263 1264 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1265 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1266 Context.DISPLAY_SERVICE); 1267 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1268 } 1269 1270 public PackageManagerService(Context context, Installer installer, 1271 boolean factoryTest, boolean onlyCore) { 1272 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1273 SystemClock.uptimeMillis()); 1274 1275 if (mSdkVersion <= 0) { 1276 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1277 } 1278 1279 mContext = context; 1280 mFactoryTest = factoryTest; 1281 mOnlyCore = onlyCore; 1282 mMetrics = new DisplayMetrics(); 1283 mSettings = new Settings(context); 1284 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1285 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1286 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1287 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1288 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1289 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1290 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1291 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1292 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1293 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1294 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1295 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1296 1297 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1298 if (separateProcesses != null && separateProcesses.length() > 0) { 1299 if ("*".equals(separateProcesses)) { 1300 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1301 mSeparateProcesses = null; 1302 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1303 } else { 1304 mDefParseFlags = 0; 1305 mSeparateProcesses = separateProcesses.split(","); 1306 Slog.w(TAG, "Running with debug.separate_processes: " 1307 + separateProcesses); 1308 } 1309 } else { 1310 mDefParseFlags = 0; 1311 mSeparateProcesses = null; 1312 } 1313 1314 mInstaller = installer; 1315 1316 getDefaultDisplayMetrics(context, mMetrics); 1317 1318 SystemConfig systemConfig = SystemConfig.getInstance(); 1319 mGlobalGids = systemConfig.getGlobalGids(); 1320 mSystemPermissions = systemConfig.getSystemPermissions(); 1321 mAvailableFeatures = systemConfig.getAvailableFeatures(); 1322 1323 synchronized (mInstallLock) { 1324 // writer 1325 synchronized (mPackages) { 1326 mHandlerThread = new ServiceThread(TAG, 1327 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1328 mHandlerThread.start(); 1329 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1330 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1331 1332 File dataDir = Environment.getDataDirectory(); 1333 mAppDataDir = new File(dataDir, "data"); 1334 mAppInstallDir = new File(dataDir, "app"); 1335 mAppLib32InstallDir = new File(dataDir, "app-lib"); 1336 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1337 mUserAppDataDir = new File(dataDir, "user"); 1338 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1339 1340 sUserManager = new UserManagerService(context, this, 1341 mInstallLock, mPackages); 1342 1343 // Propagate permission configuration in to package manager. 1344 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 1345 = systemConfig.getPermissions(); 1346 for (int i=0; i<permConfig.size(); i++) { 1347 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 1348 BasePermission bp = mSettings.mPermissions.get(perm.name); 1349 if (bp == null) { 1350 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 1351 mSettings.mPermissions.put(perm.name, bp); 1352 } 1353 if (perm.gids != null) { 1354 bp.gids = appendInts(bp.gids, perm.gids); 1355 } 1356 } 1357 1358 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 1359 for (int i=0; i<libConfig.size(); i++) { 1360 mSharedLibraries.put(libConfig.keyAt(i), 1361 new SharedLibraryEntry(libConfig.valueAt(i), null)); 1362 } 1363 1364 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1365 1366 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1367 mSdkVersion, mOnlyCore); 1368 1369 String customResolverActivity = Resources.getSystem().getString( 1370 R.string.config_customResolverActivity); 1371 if (TextUtils.isEmpty(customResolverActivity)) { 1372 customResolverActivity = null; 1373 } else { 1374 mCustomResolverComponentName = ComponentName.unflattenFromString( 1375 customResolverActivity); 1376 } 1377 1378 long startTime = SystemClock.uptimeMillis(); 1379 1380 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1381 startTime); 1382 1383 // Set flag to monitor and not change apk file paths when 1384 // scanning install directories. 1385 int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; 1386 1387 final HashSet<String> alreadyDexOpted = new HashSet<String>(); 1388 1389 /** 1390 * Add everything in the in the boot class path to the 1391 * list of process files because dexopt will have been run 1392 * if necessary during zygote startup. 1393 */ 1394 String bootClassPath = System.getProperty("java.boot.class.path"); 1395 if (bootClassPath != null) { 1396 String[] paths = splitString(bootClassPath, ':'); 1397 for (int i=0; i<paths.length; i++) { 1398 alreadyDexOpted.add(paths[i]); 1399 } 1400 } else { 1401 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1402 } 1403 1404 boolean didDexOptLibraryOrTool = false; 1405 1406 final List<String> allInstructionSets = getAllInstructionSets(); 1407 final String[] dexCodeInstructionSets = 1408 getDexCodeInstructionSets(allInstructionSets.toArray(new String[allInstructionSets.size()])); 1409 1410 /** 1411 * Ensure all external libraries have had dexopt run on them. 1412 */ 1413 if (mSharedLibraries.size() > 0) { 1414 // NOTE: For now, we're compiling these system "shared libraries" 1415 // (and framework jars) into all available architectures. It's possible 1416 // to compile them only when we come across an app that uses them (there's 1417 // already logic for that in scanPackageLI) but that adds some complexity. 1418 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1419 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1420 final String lib = libEntry.path; 1421 if (lib == null) { 1422 continue; 1423 } 1424 1425 try { 1426 byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null, 1427 dexCodeInstructionSet, 1428 false); 1429 if (dexoptRequired != DexFile.UP_TO_DATE) { 1430 alreadyDexOpted.add(lib); 1431 1432 // The list of "shared libraries" we have at this point is 1433 if (dexoptRequired == DexFile.DEXOPT_NEEDED) { 1434 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1435 } else { 1436 mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1437 } 1438 didDexOptLibraryOrTool = true; 1439 } 1440 } catch (FileNotFoundException e) { 1441 Slog.w(TAG, "Library not found: " + lib); 1442 } catch (IOException e) { 1443 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1444 + e.getMessage()); 1445 } 1446 } 1447 } 1448 } 1449 1450 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1451 1452 // Gross hack for now: we know this file doesn't contain any 1453 // code, so don't dexopt it to avoid the resulting log spew. 1454 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 1455 1456 // Gross hack for now: we know this file is only part of 1457 // the boot class path for art, so don't dexopt it to 1458 // avoid the resulting log spew. 1459 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 1460 1461 /** 1462 * And there are a number of commands implemented in Java, which 1463 * we currently need to do the dexopt on so that they can be 1464 * run from a non-root shell. 1465 */ 1466 String[] frameworkFiles = frameworkDir.list(); 1467 if (frameworkFiles != null) { 1468 // TODO: We could compile these only for the most preferred ABI. We should 1469 // first double check that the dex files for these commands are not referenced 1470 // by other system apps. 1471 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1472 for (int i=0; i<frameworkFiles.length; i++) { 1473 File libPath = new File(frameworkDir, frameworkFiles[i]); 1474 String path = libPath.getPath(); 1475 // Skip the file if we already did it. 1476 if (alreadyDexOpted.contains(path)) { 1477 continue; 1478 } 1479 // Skip the file if it is not a type we want to dexopt. 1480 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 1481 continue; 1482 } 1483 try { 1484 byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null, 1485 dexCodeInstructionSet, 1486 false); 1487 if (dexoptRequired == DexFile.DEXOPT_NEEDED) { 1488 mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1489 didDexOptLibraryOrTool = true; 1490 } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) { 1491 mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet); 1492 didDexOptLibraryOrTool = true; 1493 } 1494 } catch (FileNotFoundException e) { 1495 Slog.w(TAG, "Jar not found: " + path); 1496 } catch (IOException e) { 1497 Slog.w(TAG, "Exception reading jar: " + path, e); 1498 } 1499 } 1500 } 1501 } 1502 1503 if (didDexOptLibraryOrTool) { 1504 // If we dexopted a library or tool, then something on the system has 1505 // changed. Consider this significant, and wipe away all other 1506 // existing dexopt files to ensure we don't leave any dangling around. 1507 // 1508 // TODO: This should be revisited because it isn't as good an indicator 1509 // as it used to be. It used to include the boot classpath but at some point 1510 // DexFile.isDexOptNeeded started returning false for the boot 1511 // class path files in all cases. It is very possible in a 1512 // small maintenance release update that the library and tool 1513 // jars may be unchanged but APK could be removed resulting in 1514 // unused dalvik-cache files. 1515 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 1516 mInstaller.pruneDexCache(dexCodeInstructionSet); 1517 } 1518 1519 // Additionally, delete all dex files from the root directory 1520 // since there shouldn't be any there anyway, unless we're upgrading 1521 // from an older OS version or a build that contained the "old" style 1522 // flat scheme. 1523 mInstaller.pruneDexCache("."); 1524 } 1525 1526 // Collect vendor overlay packages. 1527 // (Do this before scanning any apps.) 1528 // For security and version matching reason, only consider 1529 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 1530 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 1531 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 1532 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode | SCAN_TRUSTED_OVERLAY, 0); 1533 1534 // Find base frameworks (resource packages without code). 1535 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 1536 | PackageParser.PARSE_IS_SYSTEM_DIR 1537 | PackageParser.PARSE_IS_PRIVILEGED, 1538 scanMode | SCAN_NO_DEX, 0); 1539 1540 // Collected privileged system packages. 1541 File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 1542 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 1543 | PackageParser.PARSE_IS_SYSTEM_DIR 1544 | PackageParser.PARSE_IS_PRIVILEGED, scanMode, 0); 1545 1546 // Collect ordinary system packages. 1547 File systemAppDir = new File(Environment.getRootDirectory(), "app"); 1548 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 1549 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 1550 1551 // Collect all vendor packages. 1552 File vendorAppDir = new File("/vendor/app"); 1553 try { 1554 vendorAppDir = vendorAppDir.getCanonicalFile(); 1555 } catch (IOException e) { 1556 // failed to look up canonical path, continue with original one 1557 } 1558 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 1559 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 1560 1561 // Collect all OEM packages. 1562 File oemAppDir = new File(Environment.getOemDirectory(), "app"); 1563 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 1564 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 1565 1566 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 1567 mInstaller.moveFiles(); 1568 1569 // Prune any system packages that no longer exist. 1570 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 1571 if (!mOnlyCore) { 1572 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 1573 while (psit.hasNext()) { 1574 PackageSetting ps = psit.next(); 1575 1576 /* 1577 * If this is not a system app, it can't be a 1578 * disable system app. 1579 */ 1580 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1581 continue; 1582 } 1583 1584 /* 1585 * If the package is scanned, it's not erased. 1586 */ 1587 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 1588 if (scannedPkg != null) { 1589 /* 1590 * If the system app is both scanned and in the 1591 * disabled packages list, then it must have been 1592 * added via OTA. Remove it from the currently 1593 * scanned package so the previously user-installed 1594 * application can be scanned. 1595 */ 1596 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 1597 Slog.i(TAG, "Expecting better updatd system app for " + ps.name 1598 + "; removing system app"); 1599 removePackageLI(ps, true); 1600 } 1601 1602 continue; 1603 } 1604 1605 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 1606 psit.remove(); 1607 String msg = "System package " + ps.name 1608 + " no longer exists; wiping its data"; 1609 reportSettingsProblem(Log.WARN, msg); 1610 removeDataDirsLI(ps.name); 1611 } else { 1612 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 1613 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 1614 possiblyDeletedUpdatedSystemApps.add(ps.name); 1615 } 1616 } 1617 } 1618 } 1619 1620 //look for any incomplete package installations 1621 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 1622 //clean up list 1623 for(int i = 0; i < deletePkgsList.size(); i++) { 1624 //clean up here 1625 cleanupInstallFailedPackage(deletePkgsList.get(i)); 1626 } 1627 //delete tmp files 1628 deleteTempPackageFiles(); 1629 1630 // Remove any shared userIDs that have no associated packages 1631 mSettings.pruneSharedUsersLPw(); 1632 1633 if (!mOnlyCore) { 1634 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 1635 SystemClock.uptimeMillis()); 1636 scanDirLI(mAppInstallDir, 0, scanMode, 0); 1637 1638 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 1639 scanMode, 0); 1640 1641 /** 1642 * Remove disable package settings for any updated system 1643 * apps that were removed via an OTA. If they're not a 1644 * previously-updated app, remove them completely. 1645 * Otherwise, just revoke their system-level permissions. 1646 */ 1647 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 1648 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 1649 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 1650 1651 String msg; 1652 if (deletedPkg == null) { 1653 msg = "Updated system package " + deletedAppName 1654 + " no longer exists; wiping its data"; 1655 removeDataDirsLI(deletedAppName); 1656 } else { 1657 msg = "Updated system app + " + deletedAppName 1658 + " no longer present; removing system privileges for " 1659 + deletedAppName; 1660 1661 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 1662 1663 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 1664 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 1665 } 1666 reportSettingsProblem(Log.WARN, msg); 1667 } 1668 } 1669 1670 // Now that we know all of the shared libraries, update all clients to have 1671 // the correct library paths. 1672 updateAllSharedLibrariesLPw(); 1673 1674 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 1675 // NOTE: We ignore potential failures here during a system scan (like 1676 // the rest of the commands above) because there's precious little we 1677 // can do about it. A settings error is reported, though. 1678 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 1679 false /* force dexopt */, false /* defer dexopt */); 1680 } 1681 1682 // Now that we know all the packages we are keeping, 1683 // read and update their last usage times. 1684 mPackageUsage.readLP(); 1685 1686 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 1687 SystemClock.uptimeMillis()); 1688 Slog.i(TAG, "Time to scan packages: " 1689 + ((SystemClock.uptimeMillis()-startTime)/1000f) 1690 + " seconds"); 1691 1692 // If the platform SDK has changed since the last time we booted, 1693 // we need to re-grant app permission to catch any new ones that 1694 // appear. This is really a hack, and means that apps can in some 1695 // cases get permissions that the user didn't initially explicitly 1696 // allow... it would be nice to have some better way to handle 1697 // this situation. 1698 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 1699 != mSdkVersion; 1700 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 1701 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 1702 + "; regranting permissions for internal storage"); 1703 mSettings.mInternalSdkPlatform = mSdkVersion; 1704 1705 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 1706 | (regrantPermissions 1707 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 1708 : 0)); 1709 1710 // If this is the first boot, and it is a normal boot, then 1711 // we need to initialize the default preferred apps. 1712 if (!mRestoredSettings && !onlyCore) { 1713 mSettings.readDefaultPreferredAppsLPw(this, 0); 1714 } 1715 1716 // If this is first boot after an OTA, and a normal boot, then 1717 // we need to clear code cache directories. 1718 if (!Build.FINGERPRINT.equals(mSettings.mFingerprint) && !onlyCore) { 1719 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 1720 for (String pkgName : mSettings.mPackages.keySet()) { 1721 deleteCodeCacheDirsLI(pkgName); 1722 } 1723 mSettings.mFingerprint = Build.FINGERPRINT; 1724 } 1725 1726 // All the changes are done during package scanning. 1727 mSettings.updateInternalDatabaseVersion(); 1728 1729 // can downgrade to reader 1730 mSettings.writeLPr(); 1731 1732 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 1733 SystemClock.uptimeMillis()); 1734 1735 1736 mRequiredVerifierPackage = getRequiredVerifierLPr(); 1737 } // synchronized (mPackages) 1738 } // synchronized (mInstallLock) 1739 1740 mInstallerService = new PackageInstallerService(context, this, mAppInstallDir); 1741 1742 // Now after opening every single application zip, make sure they 1743 // are all flushed. Not really needed, but keeps things nice and 1744 // tidy. 1745 Runtime.getRuntime().gc(); 1746 } 1747 1748 @Override 1749 public boolean isFirstBoot() { 1750 return !mRestoredSettings; 1751 } 1752 1753 @Override 1754 public boolean isOnlyCoreApps() { 1755 return mOnlyCore; 1756 } 1757 1758 private String getRequiredVerifierLPr() { 1759 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 1760 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 1761 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 1762 1763 String requiredVerifier = null; 1764 1765 final int N = receivers.size(); 1766 for (int i = 0; i < N; i++) { 1767 final ResolveInfo info = receivers.get(i); 1768 1769 if (info.activityInfo == null) { 1770 continue; 1771 } 1772 1773 final String packageName = info.activityInfo.packageName; 1774 1775 final PackageSetting ps = mSettings.mPackages.get(packageName); 1776 if (ps == null) { 1777 continue; 1778 } 1779 1780 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1781 if (!gp.grantedPermissions 1782 .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) { 1783 continue; 1784 } 1785 1786 if (requiredVerifier != null) { 1787 throw new RuntimeException("There can be only one required verifier"); 1788 } 1789 1790 requiredVerifier = packageName; 1791 } 1792 1793 return requiredVerifier; 1794 } 1795 1796 @Override 1797 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1798 throws RemoteException { 1799 try { 1800 return super.onTransact(code, data, reply, flags); 1801 } catch (RuntimeException e) { 1802 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 1803 Slog.wtf(TAG, "Package Manager Crash", e); 1804 } 1805 throw e; 1806 } 1807 } 1808 1809 void cleanupInstallFailedPackage(PackageSetting ps) { 1810 Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name); 1811 removeDataDirsLI(ps.name); 1812 1813 // TODO: try cleaning up codePath directory contents first, since it 1814 // might be a cluster 1815 1816 if (ps.codePath != null) { 1817 if (!ps.codePath.delete()) { 1818 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath); 1819 } 1820 } 1821 if (ps.resourcePath != null) { 1822 if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) { 1823 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath); 1824 } 1825 } 1826 mSettings.removePackageLPw(ps.name); 1827 } 1828 1829 static int[] appendInts(int[] cur, int[] add) { 1830 if (add == null) return cur; 1831 if (cur == null) return add; 1832 final int N = add.length; 1833 for (int i=0; i<N; i++) { 1834 cur = appendInt(cur, add[i]); 1835 } 1836 return cur; 1837 } 1838 1839 static int[] removeInts(int[] cur, int[] rem) { 1840 if (rem == null) return cur; 1841 if (cur == null) return cur; 1842 final int N = rem.length; 1843 for (int i=0; i<N; i++) { 1844 cur = removeInt(cur, rem[i]); 1845 } 1846 return cur; 1847 } 1848 1849 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 1850 if (!sUserManager.exists(userId)) return null; 1851 final PackageSetting ps = (PackageSetting) p.mExtras; 1852 if (ps == null) { 1853 return null; 1854 } 1855 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1856 final PackageUserState state = ps.readUserState(userId); 1857 return PackageParser.generatePackageInfo(p, gp.gids, flags, 1858 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions, 1859 state, userId); 1860 } 1861 1862 @Override 1863 public boolean isPackageAvailable(String packageName, int userId) { 1864 if (!sUserManager.exists(userId)) return false; 1865 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available"); 1866 synchronized (mPackages) { 1867 PackageParser.Package p = mPackages.get(packageName); 1868 if (p != null) { 1869 final PackageSetting ps = (PackageSetting) p.mExtras; 1870 if (ps != null) { 1871 final PackageUserState state = ps.readUserState(userId); 1872 if (state != null) { 1873 return PackageParser.isAvailable(state); 1874 } 1875 } 1876 } 1877 } 1878 return false; 1879 } 1880 1881 @Override 1882 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 1883 if (!sUserManager.exists(userId)) return null; 1884 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info"); 1885 // reader 1886 synchronized (mPackages) { 1887 PackageParser.Package p = mPackages.get(packageName); 1888 if (DEBUG_PACKAGE_INFO) 1889 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 1890 if (p != null) { 1891 return generatePackageInfo(p, flags, userId); 1892 } 1893 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 1894 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 1895 } 1896 } 1897 return null; 1898 } 1899 1900 @Override 1901 public String[] currentToCanonicalPackageNames(String[] names) { 1902 String[] out = new String[names.length]; 1903 // reader 1904 synchronized (mPackages) { 1905 for (int i=names.length-1; i>=0; i--) { 1906 PackageSetting ps = mSettings.mPackages.get(names[i]); 1907 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 1908 } 1909 } 1910 return out; 1911 } 1912 1913 @Override 1914 public String[] canonicalToCurrentPackageNames(String[] names) { 1915 String[] out = new String[names.length]; 1916 // reader 1917 synchronized (mPackages) { 1918 for (int i=names.length-1; i>=0; i--) { 1919 String cur = mSettings.mRenamedPackages.get(names[i]); 1920 out[i] = cur != null ? cur : names[i]; 1921 } 1922 } 1923 return out; 1924 } 1925 1926 @Override 1927 public int getPackageUid(String packageName, int userId) { 1928 if (!sUserManager.exists(userId)) return -1; 1929 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid"); 1930 // reader 1931 synchronized (mPackages) { 1932 PackageParser.Package p = mPackages.get(packageName); 1933 if(p != null) { 1934 return UserHandle.getUid(userId, p.applicationInfo.uid); 1935 } 1936 PackageSetting ps = mSettings.mPackages.get(packageName); 1937 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 1938 return -1; 1939 } 1940 p = ps.pkg; 1941 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 1942 } 1943 } 1944 1945 @Override 1946 public int[] getPackageGids(String packageName) { 1947 // reader 1948 synchronized (mPackages) { 1949 PackageParser.Package p = mPackages.get(packageName); 1950 if (DEBUG_PACKAGE_INFO) 1951 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 1952 if (p != null) { 1953 final PackageSetting ps = (PackageSetting)p.mExtras; 1954 return ps.getGids(); 1955 } 1956 } 1957 // stupid thing to indicate an error. 1958 return new int[0]; 1959 } 1960 1961 static final PermissionInfo generatePermissionInfo( 1962 BasePermission bp, int flags) { 1963 if (bp.perm != null) { 1964 return PackageParser.generatePermissionInfo(bp.perm, flags); 1965 } 1966 PermissionInfo pi = new PermissionInfo(); 1967 pi.name = bp.name; 1968 pi.packageName = bp.sourcePackage; 1969 pi.nonLocalizedLabel = bp.name; 1970 pi.protectionLevel = bp.protectionLevel; 1971 return pi; 1972 } 1973 1974 @Override 1975 public PermissionInfo getPermissionInfo(String name, int flags) { 1976 // reader 1977 synchronized (mPackages) { 1978 final BasePermission p = mSettings.mPermissions.get(name); 1979 if (p != null) { 1980 return generatePermissionInfo(p, flags); 1981 } 1982 return null; 1983 } 1984 } 1985 1986 @Override 1987 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 1988 // reader 1989 synchronized (mPackages) { 1990 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 1991 for (BasePermission p : mSettings.mPermissions.values()) { 1992 if (group == null) { 1993 if (p.perm == null || p.perm.info.group == null) { 1994 out.add(generatePermissionInfo(p, flags)); 1995 } 1996 } else { 1997 if (p.perm != null && group.equals(p.perm.info.group)) { 1998 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 1999 } 2000 } 2001 } 2002 2003 if (out.size() > 0) { 2004 return out; 2005 } 2006 return mPermissionGroups.containsKey(group) ? out : null; 2007 } 2008 } 2009 2010 @Override 2011 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2012 // reader 2013 synchronized (mPackages) { 2014 return PackageParser.generatePermissionGroupInfo( 2015 mPermissionGroups.get(name), flags); 2016 } 2017 } 2018 2019 @Override 2020 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2021 // reader 2022 synchronized (mPackages) { 2023 final int N = mPermissionGroups.size(); 2024 ArrayList<PermissionGroupInfo> out 2025 = new ArrayList<PermissionGroupInfo>(N); 2026 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2027 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2028 } 2029 return out; 2030 } 2031 } 2032 2033 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2034 int userId) { 2035 if (!sUserManager.exists(userId)) return null; 2036 PackageSetting ps = mSettings.mPackages.get(packageName); 2037 if (ps != null) { 2038 if (ps.pkg == null) { 2039 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2040 flags, userId); 2041 if (pInfo != null) { 2042 return pInfo.applicationInfo; 2043 } 2044 return null; 2045 } 2046 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2047 ps.readUserState(userId), userId); 2048 } 2049 return null; 2050 } 2051 2052 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2053 int userId) { 2054 if (!sUserManager.exists(userId)) return null; 2055 PackageSetting ps = mSettings.mPackages.get(packageName); 2056 if (ps != null) { 2057 PackageParser.Package pkg = ps.pkg; 2058 if (pkg == null) { 2059 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2060 return null; 2061 } 2062 // Only data remains, so we aren't worried about code paths 2063 pkg = new PackageParser.Package(packageName); 2064 pkg.applicationInfo.packageName = packageName; 2065 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2066 pkg.applicationInfo.dataDir = 2067 getDataPathForPackage(packageName, 0).getPath(); 2068 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 2069 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 2070 } 2071 return generatePackageInfo(pkg, flags, userId); 2072 } 2073 return null; 2074 } 2075 2076 @Override 2077 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2078 if (!sUserManager.exists(userId)) return null; 2079 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info"); 2080 // writer 2081 synchronized (mPackages) { 2082 PackageParser.Package p = mPackages.get(packageName); 2083 if (DEBUG_PACKAGE_INFO) Log.v( 2084 TAG, "getApplicationInfo " + packageName 2085 + ": " + p); 2086 if (p != null) { 2087 PackageSetting ps = mSettings.mPackages.get(packageName); 2088 if (ps == null) return null; 2089 // Note: isEnabledLP() does not apply here - always return info 2090 return PackageParser.generateApplicationInfo( 2091 p, flags, ps.readUserState(userId), userId); 2092 } 2093 if ("android".equals(packageName)||"system".equals(packageName)) { 2094 return mAndroidApplication; 2095 } 2096 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2097 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2098 } 2099 } 2100 return null; 2101 } 2102 2103 2104 @Override 2105 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) { 2106 mContext.enforceCallingOrSelfPermission( 2107 android.Manifest.permission.CLEAR_APP_CACHE, null); 2108 // Queue up an async operation since clearing cache may take a little while. 2109 mHandler.post(new Runnable() { 2110 public void run() { 2111 mHandler.removeCallbacks(this); 2112 int retCode = -1; 2113 synchronized (mInstallLock) { 2114 retCode = mInstaller.freeCache(freeStorageSize); 2115 if (retCode < 0) { 2116 Slog.w(TAG, "Couldn't clear application caches"); 2117 } 2118 } 2119 if (observer != null) { 2120 try { 2121 observer.onRemoveCompleted(null, (retCode >= 0)); 2122 } catch (RemoteException e) { 2123 Slog.w(TAG, "RemoveException when invoking call back"); 2124 } 2125 } 2126 } 2127 }); 2128 } 2129 2130 @Override 2131 public void freeStorage(final long freeStorageSize, final IntentSender pi) { 2132 mContext.enforceCallingOrSelfPermission( 2133 android.Manifest.permission.CLEAR_APP_CACHE, null); 2134 // Queue up an async operation since clearing cache may take a little while. 2135 mHandler.post(new Runnable() { 2136 public void run() { 2137 mHandler.removeCallbacks(this); 2138 int retCode = -1; 2139 synchronized (mInstallLock) { 2140 retCode = mInstaller.freeCache(freeStorageSize); 2141 if (retCode < 0) { 2142 Slog.w(TAG, "Couldn't clear application caches"); 2143 } 2144 } 2145 if(pi != null) { 2146 try { 2147 // Callback via pending intent 2148 int code = (retCode >= 0) ? 1 : 0; 2149 pi.sendIntent(null, code, null, 2150 null, null); 2151 } catch (SendIntentException e1) { 2152 Slog.i(TAG, "Failed to send pending intent"); 2153 } 2154 } 2155 } 2156 }); 2157 } 2158 2159 void freeStorage(long freeStorageSize) throws IOException { 2160 synchronized (mInstallLock) { 2161 if (mInstaller.freeCache(freeStorageSize) < 0) { 2162 throw new IOException("Failed to free enough space"); 2163 } 2164 } 2165 } 2166 2167 @Override 2168 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2169 if (!sUserManager.exists(userId)) return null; 2170 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info"); 2171 synchronized (mPackages) { 2172 PackageParser.Activity a = mActivities.mActivities.get(component); 2173 2174 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2175 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2176 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2177 if (ps == null) return null; 2178 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2179 userId); 2180 } 2181 if (mResolveComponentName.equals(component)) { 2182 return mResolveActivity; 2183 } 2184 } 2185 return null; 2186 } 2187 2188 @Override 2189 public boolean activitySupportsIntent(ComponentName component, Intent intent, 2190 String resolvedType) { 2191 synchronized (mPackages) { 2192 PackageParser.Activity a = mActivities.mActivities.get(component); 2193 if (a == null) { 2194 return false; 2195 } 2196 for (int i=0; i<a.intents.size(); i++) { 2197 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 2198 intent.getData(), intent.getCategories(), TAG) >= 0) { 2199 return true; 2200 } 2201 } 2202 return false; 2203 } 2204 } 2205 2206 @Override 2207 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 2208 if (!sUserManager.exists(userId)) return null; 2209 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info"); 2210 synchronized (mPackages) { 2211 PackageParser.Activity a = mReceivers.mActivities.get(component); 2212 if (DEBUG_PACKAGE_INFO) Log.v( 2213 TAG, "getReceiverInfo " + component + ": " + a); 2214 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2215 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2216 if (ps == null) return null; 2217 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2218 userId); 2219 } 2220 } 2221 return null; 2222 } 2223 2224 @Override 2225 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 2226 if (!sUserManager.exists(userId)) return null; 2227 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info"); 2228 synchronized (mPackages) { 2229 PackageParser.Service s = mServices.mServices.get(component); 2230 if (DEBUG_PACKAGE_INFO) Log.v( 2231 TAG, "getServiceInfo " + component + ": " + s); 2232 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 2233 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2234 if (ps == null) return null; 2235 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 2236 userId); 2237 } 2238 } 2239 return null; 2240 } 2241 2242 @Override 2243 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 2244 if (!sUserManager.exists(userId)) return null; 2245 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info"); 2246 synchronized (mPackages) { 2247 PackageParser.Provider p = mProviders.mProviders.get(component); 2248 if (DEBUG_PACKAGE_INFO) Log.v( 2249 TAG, "getProviderInfo " + component + ": " + p); 2250 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 2251 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2252 if (ps == null) return null; 2253 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 2254 userId); 2255 } 2256 } 2257 return null; 2258 } 2259 2260 @Override 2261 public String[] getSystemSharedLibraryNames() { 2262 Set<String> libSet; 2263 synchronized (mPackages) { 2264 libSet = mSharedLibraries.keySet(); 2265 int size = libSet.size(); 2266 if (size > 0) { 2267 String[] libs = new String[size]; 2268 libSet.toArray(libs); 2269 return libs; 2270 } 2271 } 2272 return null; 2273 } 2274 2275 @Override 2276 public FeatureInfo[] getSystemAvailableFeatures() { 2277 Collection<FeatureInfo> featSet; 2278 synchronized (mPackages) { 2279 featSet = mAvailableFeatures.values(); 2280 int size = featSet.size(); 2281 if (size > 0) { 2282 FeatureInfo[] features = new FeatureInfo[size+1]; 2283 featSet.toArray(features); 2284 FeatureInfo fi = new FeatureInfo(); 2285 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 2286 FeatureInfo.GL_ES_VERSION_UNDEFINED); 2287 features[size] = fi; 2288 return features; 2289 } 2290 } 2291 return null; 2292 } 2293 2294 @Override 2295 public boolean hasSystemFeature(String name) { 2296 synchronized (mPackages) { 2297 return mAvailableFeatures.containsKey(name); 2298 } 2299 } 2300 2301 private void checkValidCaller(int uid, int userId) { 2302 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 2303 return; 2304 2305 throw new SecurityException("Caller uid=" + uid 2306 + " is not privileged to communicate with user=" + userId); 2307 } 2308 2309 @Override 2310 public int checkPermission(String permName, String pkgName) { 2311 synchronized (mPackages) { 2312 PackageParser.Package p = mPackages.get(pkgName); 2313 if (p != null && p.mExtras != null) { 2314 PackageSetting ps = (PackageSetting)p.mExtras; 2315 if (ps.sharedUser != null) { 2316 if (ps.sharedUser.grantedPermissions.contains(permName)) { 2317 return PackageManager.PERMISSION_GRANTED; 2318 } 2319 } else if (ps.grantedPermissions.contains(permName)) { 2320 return PackageManager.PERMISSION_GRANTED; 2321 } 2322 } 2323 } 2324 return PackageManager.PERMISSION_DENIED; 2325 } 2326 2327 @Override 2328 public int checkUidPermission(String permName, int uid) { 2329 synchronized (mPackages) { 2330 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2331 if (obj != null) { 2332 GrantedPermissions gp = (GrantedPermissions)obj; 2333 if (gp.grantedPermissions.contains(permName)) { 2334 return PackageManager.PERMISSION_GRANTED; 2335 } 2336 } else { 2337 HashSet<String> perms = mSystemPermissions.get(uid); 2338 if (perms != null && perms.contains(permName)) { 2339 return PackageManager.PERMISSION_GRANTED; 2340 } 2341 } 2342 } 2343 return PackageManager.PERMISSION_DENIED; 2344 } 2345 2346 /** 2347 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 2348 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 2349 * @param message the message to log on security exception 2350 */ 2351 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 2352 String message) { 2353 if (userId < 0) { 2354 throw new IllegalArgumentException("Invalid userId " + userId); 2355 } 2356 if (userId == UserHandle.getUserId(callingUid)) return; 2357 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2358 if (requireFullPermission) { 2359 mContext.enforceCallingOrSelfPermission( 2360 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2361 } else { 2362 try { 2363 mContext.enforceCallingOrSelfPermission( 2364 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2365 } catch (SecurityException se) { 2366 mContext.enforceCallingOrSelfPermission( 2367 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 2368 } 2369 } 2370 } 2371 } 2372 2373 private BasePermission findPermissionTreeLP(String permName) { 2374 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 2375 if (permName.startsWith(bp.name) && 2376 permName.length() > bp.name.length() && 2377 permName.charAt(bp.name.length()) == '.') { 2378 return bp; 2379 } 2380 } 2381 return null; 2382 } 2383 2384 private BasePermission checkPermissionTreeLP(String permName) { 2385 if (permName != null) { 2386 BasePermission bp = findPermissionTreeLP(permName); 2387 if (bp != null) { 2388 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 2389 return bp; 2390 } 2391 throw new SecurityException("Calling uid " 2392 + Binder.getCallingUid() 2393 + " is not allowed to add to permission tree " 2394 + bp.name + " owned by uid " + bp.uid); 2395 } 2396 } 2397 throw new SecurityException("No permission tree found for " + permName); 2398 } 2399 2400 static boolean compareStrings(CharSequence s1, CharSequence s2) { 2401 if (s1 == null) { 2402 return s2 == null; 2403 } 2404 if (s2 == null) { 2405 return false; 2406 } 2407 if (s1.getClass() != s2.getClass()) { 2408 return false; 2409 } 2410 return s1.equals(s2); 2411 } 2412 2413 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 2414 if (pi1.icon != pi2.icon) return false; 2415 if (pi1.logo != pi2.logo) return false; 2416 if (pi1.protectionLevel != pi2.protectionLevel) return false; 2417 if (!compareStrings(pi1.name, pi2.name)) return false; 2418 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 2419 // We'll take care of setting this one. 2420 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 2421 // These are not currently stored in settings. 2422 //if (!compareStrings(pi1.group, pi2.group)) return false; 2423 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 2424 //if (pi1.labelRes != pi2.labelRes) return false; 2425 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 2426 return true; 2427 } 2428 2429 int permissionInfoFootprint(PermissionInfo info) { 2430 int size = info.name.length(); 2431 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 2432 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 2433 return size; 2434 } 2435 2436 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 2437 int size = 0; 2438 for (BasePermission perm : mSettings.mPermissions.values()) { 2439 if (perm.uid == tree.uid) { 2440 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 2441 } 2442 } 2443 return size; 2444 } 2445 2446 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 2447 // We calculate the max size of permissions defined by this uid and throw 2448 // if that plus the size of 'info' would exceed our stated maximum. 2449 if (tree.uid != Process.SYSTEM_UID) { 2450 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 2451 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 2452 throw new SecurityException("Permission tree size cap exceeded"); 2453 } 2454 } 2455 } 2456 2457 boolean addPermissionLocked(PermissionInfo info, boolean async) { 2458 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 2459 throw new SecurityException("Label must be specified in permission"); 2460 } 2461 BasePermission tree = checkPermissionTreeLP(info.name); 2462 BasePermission bp = mSettings.mPermissions.get(info.name); 2463 boolean added = bp == null; 2464 boolean changed = true; 2465 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 2466 if (added) { 2467 enforcePermissionCapLocked(info, tree); 2468 bp = new BasePermission(info.name, tree.sourcePackage, 2469 BasePermission.TYPE_DYNAMIC); 2470 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 2471 throw new SecurityException( 2472 "Not allowed to modify non-dynamic permission " 2473 + info.name); 2474 } else { 2475 if (bp.protectionLevel == fixedLevel 2476 && bp.perm.owner.equals(tree.perm.owner) 2477 && bp.uid == tree.uid 2478 && comparePermissionInfos(bp.perm.info, info)) { 2479 changed = false; 2480 } 2481 } 2482 bp.protectionLevel = fixedLevel; 2483 info = new PermissionInfo(info); 2484 info.protectionLevel = fixedLevel; 2485 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 2486 bp.perm.info.packageName = tree.perm.info.packageName; 2487 bp.uid = tree.uid; 2488 if (added) { 2489 mSettings.mPermissions.put(info.name, bp); 2490 } 2491 if (changed) { 2492 if (!async) { 2493 mSettings.writeLPr(); 2494 } else { 2495 scheduleWriteSettingsLocked(); 2496 } 2497 } 2498 return added; 2499 } 2500 2501 @Override 2502 public boolean addPermission(PermissionInfo info) { 2503 synchronized (mPackages) { 2504 return addPermissionLocked(info, false); 2505 } 2506 } 2507 2508 @Override 2509 public boolean addPermissionAsync(PermissionInfo info) { 2510 synchronized (mPackages) { 2511 return addPermissionLocked(info, true); 2512 } 2513 } 2514 2515 @Override 2516 public void removePermission(String name) { 2517 synchronized (mPackages) { 2518 checkPermissionTreeLP(name); 2519 BasePermission bp = mSettings.mPermissions.get(name); 2520 if (bp != null) { 2521 if (bp.type != BasePermission.TYPE_DYNAMIC) { 2522 throw new SecurityException( 2523 "Not allowed to modify non-dynamic permission " 2524 + name); 2525 } 2526 mSettings.mPermissions.remove(name); 2527 mSettings.writeLPr(); 2528 } 2529 } 2530 } 2531 2532 private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) { 2533 int index = pkg.requestedPermissions.indexOf(bp.name); 2534 if (index == -1) { 2535 throw new SecurityException("Package " + pkg.packageName 2536 + " has not requested permission " + bp.name); 2537 } 2538 boolean isNormal = 2539 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) 2540 == PermissionInfo.PROTECTION_NORMAL); 2541 boolean isDangerous = 2542 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) 2543 == PermissionInfo.PROTECTION_DANGEROUS); 2544 boolean isDevelopment = 2545 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0); 2546 2547 if (!isNormal && !isDangerous && !isDevelopment) { 2548 throw new SecurityException("Permission " + bp.name 2549 + " is not a changeable permission type"); 2550 } 2551 2552 if (isNormal || isDangerous) { 2553 if (pkg.requestedPermissionsRequired.get(index)) { 2554 throw new SecurityException("Can't change " + bp.name 2555 + ". It is required by the application"); 2556 } 2557 } 2558 } 2559 2560 @Override 2561 public void grantPermission(String packageName, String permissionName) { 2562 mContext.enforceCallingOrSelfPermission( 2563 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); 2564 synchronized (mPackages) { 2565 final PackageParser.Package pkg = mPackages.get(packageName); 2566 if (pkg == null) { 2567 throw new IllegalArgumentException("Unknown package: " + packageName); 2568 } 2569 final BasePermission bp = mSettings.mPermissions.get(permissionName); 2570 if (bp == null) { 2571 throw new IllegalArgumentException("Unknown permission: " + permissionName); 2572 } 2573 2574 checkGrantRevokePermissions(pkg, bp); 2575 2576 final PackageSetting ps = (PackageSetting) pkg.mExtras; 2577 if (ps == null) { 2578 return; 2579 } 2580 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps; 2581 if (gp.grantedPermissions.add(permissionName)) { 2582 if (ps.haveGids) { 2583 gp.gids = appendInts(gp.gids, bp.gids); 2584 } 2585 mSettings.writeLPr(); 2586 } 2587 } 2588 } 2589 2590 @Override 2591 public void revokePermission(String packageName, String permissionName) { 2592 int changedAppId = -1; 2593 2594 synchronized (mPackages) { 2595 final PackageParser.Package pkg = mPackages.get(packageName); 2596 if (pkg == null) { 2597 throw new IllegalArgumentException("Unknown package: " + packageName); 2598 } 2599 if (pkg.applicationInfo.uid != Binder.getCallingUid()) { 2600 mContext.enforceCallingOrSelfPermission( 2601 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); 2602 } 2603 final BasePermission bp = mSettings.mPermissions.get(permissionName); 2604 if (bp == null) { 2605 throw new IllegalArgumentException("Unknown permission: " + permissionName); 2606 } 2607 2608 checkGrantRevokePermissions(pkg, bp); 2609 2610 final PackageSetting ps = (PackageSetting) pkg.mExtras; 2611 if (ps == null) { 2612 return; 2613 } 2614 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps; 2615 if (gp.grantedPermissions.remove(permissionName)) { 2616 gp.grantedPermissions.remove(permissionName); 2617 if (ps.haveGids) { 2618 gp.gids = removeInts(gp.gids, bp.gids); 2619 } 2620 mSettings.writeLPr(); 2621 changedAppId = ps.appId; 2622 } 2623 } 2624 2625 if (changedAppId >= 0) { 2626 // We changed the perm on someone, kill its processes. 2627 IActivityManager am = ActivityManagerNative.getDefault(); 2628 if (am != null) { 2629 final int callingUserId = UserHandle.getCallingUserId(); 2630 final long ident = Binder.clearCallingIdentity(); 2631 try { 2632 //XXX we should only revoke for the calling user's app permissions, 2633 // but for now we impact all users. 2634 //am.killUid(UserHandle.getUid(callingUserId, changedAppId), 2635 // "revoke " + permissionName); 2636 int[] users = sUserManager.getUserIds(); 2637 for (int user : users) { 2638 am.killUid(UserHandle.getUid(user, changedAppId), 2639 "revoke " + permissionName); 2640 } 2641 } catch (RemoteException e) { 2642 } finally { 2643 Binder.restoreCallingIdentity(ident); 2644 } 2645 } 2646 } 2647 } 2648 2649 @Override 2650 public boolean isProtectedBroadcast(String actionName) { 2651 synchronized (mPackages) { 2652 return mProtectedBroadcasts.contains(actionName); 2653 } 2654 } 2655 2656 @Override 2657 public int checkSignatures(String pkg1, String pkg2) { 2658 synchronized (mPackages) { 2659 final PackageParser.Package p1 = mPackages.get(pkg1); 2660 final PackageParser.Package p2 = mPackages.get(pkg2); 2661 if (p1 == null || p1.mExtras == null 2662 || p2 == null || p2.mExtras == null) { 2663 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2664 } 2665 return compareSignatures(p1.mSignatures, p2.mSignatures); 2666 } 2667 } 2668 2669 @Override 2670 public int checkUidSignatures(int uid1, int uid2) { 2671 // Map to base uids. 2672 uid1 = UserHandle.getAppId(uid1); 2673 uid2 = UserHandle.getAppId(uid2); 2674 // reader 2675 synchronized (mPackages) { 2676 Signature[] s1; 2677 Signature[] s2; 2678 Object obj = mSettings.getUserIdLPr(uid1); 2679 if (obj != null) { 2680 if (obj instanceof SharedUserSetting) { 2681 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 2682 } else if (obj instanceof PackageSetting) { 2683 s1 = ((PackageSetting)obj).signatures.mSignatures; 2684 } else { 2685 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2686 } 2687 } else { 2688 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2689 } 2690 obj = mSettings.getUserIdLPr(uid2); 2691 if (obj != null) { 2692 if (obj instanceof SharedUserSetting) { 2693 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 2694 } else if (obj instanceof PackageSetting) { 2695 s2 = ((PackageSetting)obj).signatures.mSignatures; 2696 } else { 2697 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2698 } 2699 } else { 2700 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2701 } 2702 return compareSignatures(s1, s2); 2703 } 2704 } 2705 2706 /** 2707 * Compares two sets of signatures. Returns: 2708 * <br /> 2709 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 2710 * <br /> 2711 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 2712 * <br /> 2713 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 2714 * <br /> 2715 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 2716 * <br /> 2717 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 2718 */ 2719 static int compareSignatures(Signature[] s1, Signature[] s2) { 2720 if (s1 == null) { 2721 return s2 == null 2722 ? PackageManager.SIGNATURE_NEITHER_SIGNED 2723 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 2724 } 2725 2726 if (s2 == null) { 2727 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 2728 } 2729 2730 if (s1.length != s2.length) { 2731 return PackageManager.SIGNATURE_NO_MATCH; 2732 } 2733 2734 // Since both signature sets are of size 1, we can compare without HashSets. 2735 if (s1.length == 1) { 2736 return s1[0].equals(s2[0]) ? 2737 PackageManager.SIGNATURE_MATCH : 2738 PackageManager.SIGNATURE_NO_MATCH; 2739 } 2740 2741 HashSet<Signature> set1 = new HashSet<Signature>(); 2742 for (Signature sig : s1) { 2743 set1.add(sig); 2744 } 2745 HashSet<Signature> set2 = new HashSet<Signature>(); 2746 for (Signature sig : s2) { 2747 set2.add(sig); 2748 } 2749 // Make sure s2 contains all signatures in s1. 2750 if (set1.equals(set2)) { 2751 return PackageManager.SIGNATURE_MATCH; 2752 } 2753 return PackageManager.SIGNATURE_NO_MATCH; 2754 } 2755 2756 /** 2757 * If the database version for this type of package (internal storage or 2758 * external storage) is less than the version where package signatures 2759 * were updated, return true. 2760 */ 2761 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 2762 return (isExternal(scannedPkg) && mSettings.isExternalDatabaseVersionOlderThan( 2763 DatabaseVersion.SIGNATURE_END_ENTITY)) 2764 || (!isExternal(scannedPkg) && mSettings.isInternalDatabaseVersionOlderThan( 2765 DatabaseVersion.SIGNATURE_END_ENTITY)); 2766 } 2767 2768 /** 2769 * Used for backward compatibility to make sure any packages with 2770 * certificate chains get upgraded to the new style. {@code existingSigs} 2771 * will be in the old format (since they were stored on disk from before the 2772 * system upgrade) and {@code scannedSigs} will be in the newer format. 2773 */ 2774 private int compareSignaturesCompat(PackageSignatures existingSigs, 2775 PackageParser.Package scannedPkg) { 2776 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 2777 return PackageManager.SIGNATURE_NO_MATCH; 2778 } 2779 2780 HashSet<Signature> existingSet = new HashSet<Signature>(); 2781 for (Signature sig : existingSigs.mSignatures) { 2782 existingSet.add(sig); 2783 } 2784 HashSet<Signature> scannedCompatSet = new HashSet<Signature>(); 2785 for (Signature sig : scannedPkg.mSignatures) { 2786 try { 2787 Signature[] chainSignatures = sig.getChainSignatures(); 2788 for (Signature chainSig : chainSignatures) { 2789 scannedCompatSet.add(chainSig); 2790 } 2791 } catch (CertificateEncodingException e) { 2792 scannedCompatSet.add(sig); 2793 } 2794 } 2795 /* 2796 * Make sure the expanded scanned set contains all signatures in the 2797 * existing one. 2798 */ 2799 if (scannedCompatSet.equals(existingSet)) { 2800 // Migrate the old signatures to the new scheme. 2801 existingSigs.assignSignatures(scannedPkg.mSignatures); 2802 // The new KeySets will be re-added later in the scanning process. 2803 synchronized (mPackages) { 2804 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 2805 } 2806 return PackageManager.SIGNATURE_MATCH; 2807 } 2808 return PackageManager.SIGNATURE_NO_MATCH; 2809 } 2810 2811 @Override 2812 public String[] getPackagesForUid(int uid) { 2813 uid = UserHandle.getAppId(uid); 2814 // reader 2815 synchronized (mPackages) { 2816 Object obj = mSettings.getUserIdLPr(uid); 2817 if (obj instanceof SharedUserSetting) { 2818 final SharedUserSetting sus = (SharedUserSetting) obj; 2819 final int N = sus.packages.size(); 2820 final String[] res = new String[N]; 2821 final Iterator<PackageSetting> it = sus.packages.iterator(); 2822 int i = 0; 2823 while (it.hasNext()) { 2824 res[i++] = it.next().name; 2825 } 2826 return res; 2827 } else if (obj instanceof PackageSetting) { 2828 final PackageSetting ps = (PackageSetting) obj; 2829 return new String[] { ps.name }; 2830 } 2831 } 2832 return null; 2833 } 2834 2835 @Override 2836 public String getNameForUid(int uid) { 2837 // reader 2838 synchronized (mPackages) { 2839 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2840 if (obj instanceof SharedUserSetting) { 2841 final SharedUserSetting sus = (SharedUserSetting) obj; 2842 return sus.name + ":" + sus.userId; 2843 } else if (obj instanceof PackageSetting) { 2844 final PackageSetting ps = (PackageSetting) obj; 2845 return ps.name; 2846 } 2847 } 2848 return null; 2849 } 2850 2851 @Override 2852 public int getUidForSharedUser(String sharedUserName) { 2853 if(sharedUserName == null) { 2854 return -1; 2855 } 2856 // reader 2857 synchronized (mPackages) { 2858 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false); 2859 if (suid == null) { 2860 return -1; 2861 } 2862 return suid.userId; 2863 } 2864 } 2865 2866 @Override 2867 public int getFlagsForUid(int uid) { 2868 synchronized (mPackages) { 2869 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2870 if (obj instanceof SharedUserSetting) { 2871 final SharedUserSetting sus = (SharedUserSetting) obj; 2872 return sus.pkgFlags; 2873 } else if (obj instanceof PackageSetting) { 2874 final PackageSetting ps = (PackageSetting) obj; 2875 return ps.pkgFlags; 2876 } 2877 } 2878 return 0; 2879 } 2880 2881 @Override 2882 public String[] getAppOpPermissionPackages(String permissionName) { 2883 synchronized (mPackages) { 2884 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 2885 if (pkgs == null) { 2886 return null; 2887 } 2888 return pkgs.toArray(new String[pkgs.size()]); 2889 } 2890 } 2891 2892 @Override 2893 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 2894 int flags, int userId) { 2895 if (!sUserManager.exists(userId)) return null; 2896 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent"); 2897 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2898 return chooseBestActivity(intent, resolvedType, flags, query, userId); 2899 } 2900 2901 @Override 2902 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 2903 IntentFilter filter, int match, ComponentName activity) { 2904 final int userId = UserHandle.getCallingUserId(); 2905 if (DEBUG_PREFERRED) { 2906 Log.v(TAG, "setLastChosenActivity intent=" + intent 2907 + " resolvedType=" + resolvedType 2908 + " flags=" + flags 2909 + " filter=" + filter 2910 + " match=" + match 2911 + " activity=" + activity); 2912 filter.dump(new PrintStreamPrinter(System.out), " "); 2913 } 2914 intent.setComponent(null); 2915 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2916 // Find any earlier preferred or last chosen entries and nuke them 2917 findPreferredActivity(intent, resolvedType, 2918 flags, query, 0, false, true, false, userId); 2919 // Add the new activity as the last chosen for this filter 2920 addPreferredActivityInternal(filter, match, null, activity, false, userId); 2921 } 2922 2923 @Override 2924 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 2925 final int userId = UserHandle.getCallingUserId(); 2926 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 2927 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2928 return findPreferredActivity(intent, resolvedType, flags, query, 0, 2929 false, false, false, userId); 2930 } 2931 2932 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 2933 int flags, List<ResolveInfo> query, int userId) { 2934 if (query != null) { 2935 final int N = query.size(); 2936 if (N == 1) { 2937 return query.get(0); 2938 } else if (N > 1) { 2939 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 2940 // If there is more than one activity with the same priority, 2941 // then let the user decide between them. 2942 ResolveInfo r0 = query.get(0); 2943 ResolveInfo r1 = query.get(1); 2944 if (DEBUG_INTENT_MATCHING || debug) { 2945 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 2946 + r1.activityInfo.name + "=" + r1.priority); 2947 } 2948 // If the first activity has a higher priority, or a different 2949 // default, then it is always desireable to pick it. 2950 if (r0.priority != r1.priority 2951 || r0.preferredOrder != r1.preferredOrder 2952 || r0.isDefault != r1.isDefault) { 2953 return query.get(0); 2954 } 2955 // If we have saved a preference for a preferred activity for 2956 // this Intent, use that. 2957 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 2958 flags, query, r0.priority, true, false, debug, userId); 2959 if (ri != null) { 2960 return ri; 2961 } 2962 if (userId != 0) { 2963 ri = new ResolveInfo(mResolveInfo); 2964 ri.activityInfo = new ActivityInfo(ri.activityInfo); 2965 ri.activityInfo.applicationInfo = new ApplicationInfo( 2966 ri.activityInfo.applicationInfo); 2967 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 2968 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 2969 return ri; 2970 } 2971 return mResolveInfo; 2972 } 2973 } 2974 return null; 2975 } 2976 2977 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 2978 int flags, List<ResolveInfo> query, boolean debug, int userId) { 2979 final int N = query.size(); 2980 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 2981 .get(userId); 2982 // Get the list of persistent preferred activities that handle the intent 2983 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 2984 List<PersistentPreferredActivity> pprefs = ppir != null 2985 ? ppir.queryIntent(intent, resolvedType, 2986 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 2987 : null; 2988 if (pprefs != null && pprefs.size() > 0) { 2989 final int M = pprefs.size(); 2990 for (int i=0; i<M; i++) { 2991 final PersistentPreferredActivity ppa = pprefs.get(i); 2992 if (DEBUG_PREFERRED || debug) { 2993 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 2994 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 2995 + "\n component=" + ppa.mComponent); 2996 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 2997 } 2998 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 2999 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3000 if (DEBUG_PREFERRED || debug) { 3001 Slog.v(TAG, "Found persistent preferred activity:"); 3002 if (ai != null) { 3003 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3004 } else { 3005 Slog.v(TAG, " null"); 3006 } 3007 } 3008 if (ai == null) { 3009 // This previously registered persistent preferred activity 3010 // component is no longer known. Ignore it and do NOT remove it. 3011 continue; 3012 } 3013 for (int j=0; j<N; j++) { 3014 final ResolveInfo ri = query.get(j); 3015 if (!ri.activityInfo.applicationInfo.packageName 3016 .equals(ai.applicationInfo.packageName)) { 3017 continue; 3018 } 3019 if (!ri.activityInfo.name.equals(ai.name)) { 3020 continue; 3021 } 3022 // Found a persistent preference that can handle the intent. 3023 if (DEBUG_PREFERRED || debug) { 3024 Slog.v(TAG, "Returning persistent preferred activity: " + 3025 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3026 } 3027 return ri; 3028 } 3029 } 3030 } 3031 return null; 3032 } 3033 3034 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 3035 List<ResolveInfo> query, int priority, boolean always, 3036 boolean removeMatches, boolean debug, int userId) { 3037 if (!sUserManager.exists(userId)) return null; 3038 // writer 3039 synchronized (mPackages) { 3040 if (intent.getSelector() != null) { 3041 intent = intent.getSelector(); 3042 } 3043 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 3044 3045 // Try to find a matching persistent preferred activity. 3046 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 3047 debug, userId); 3048 3049 // If a persistent preferred activity matched, use it. 3050 if (pri != null) { 3051 return pri; 3052 } 3053 3054 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 3055 // Get the list of preferred activities that handle the intent 3056 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 3057 List<PreferredActivity> prefs = pir != null 3058 ? pir.queryIntent(intent, resolvedType, 3059 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3060 : null; 3061 if (prefs != null && prefs.size() > 0) { 3062 // First figure out how good the original match set is. 3063 // We will only allow preferred activities that came 3064 // from the same match quality. 3065 int match = 0; 3066 3067 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 3068 3069 final int N = query.size(); 3070 for (int j=0; j<N; j++) { 3071 final ResolveInfo ri = query.get(j); 3072 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 3073 + ": 0x" + Integer.toHexString(match)); 3074 if (ri.match > match) { 3075 match = ri.match; 3076 } 3077 } 3078 3079 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 3080 + Integer.toHexString(match)); 3081 3082 match &= IntentFilter.MATCH_CATEGORY_MASK; 3083 final int M = prefs.size(); 3084 for (int i=0; i<M; i++) { 3085 final PreferredActivity pa = prefs.get(i); 3086 if (DEBUG_PREFERRED || debug) { 3087 Slog.v(TAG, "Checking PreferredActivity ds=" 3088 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 3089 + "\n component=" + pa.mPref.mComponent); 3090 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3091 } 3092 if (pa.mPref.mMatch != match) { 3093 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 3094 + Integer.toHexString(pa.mPref.mMatch)); 3095 continue; 3096 } 3097 // If it's not an "always" type preferred activity and that's what we're 3098 // looking for, skip it. 3099 if (always && !pa.mPref.mAlways) { 3100 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 3101 continue; 3102 } 3103 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 3104 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3105 if (DEBUG_PREFERRED || debug) { 3106 Slog.v(TAG, "Found preferred activity:"); 3107 if (ai != null) { 3108 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3109 } else { 3110 Slog.v(TAG, " null"); 3111 } 3112 } 3113 if (ai == null) { 3114 // This previously registered preferred activity 3115 // component is no longer known. Most likely an update 3116 // to the app was installed and in the new version this 3117 // component no longer exists. Clean it up by removing 3118 // it from the preferred activities list, and skip it. 3119 Slog.w(TAG, "Removing dangling preferred activity: " 3120 + pa.mPref.mComponent); 3121 pir.removeFilter(pa); 3122 continue; 3123 } 3124 for (int j=0; j<N; j++) { 3125 final ResolveInfo ri = query.get(j); 3126 if (!ri.activityInfo.applicationInfo.packageName 3127 .equals(ai.applicationInfo.packageName)) { 3128 continue; 3129 } 3130 if (!ri.activityInfo.name.equals(ai.name)) { 3131 continue; 3132 } 3133 3134 if (removeMatches) { 3135 pir.removeFilter(pa); 3136 if (DEBUG_PREFERRED) { 3137 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 3138 } 3139 break; 3140 } 3141 3142 // Okay we found a previously set preferred or last chosen app. 3143 // If the result set is different from when this 3144 // was created, we need to clear it and re-ask the 3145 // user their preference, if we're looking for an "always" type entry. 3146 if (always && !pa.mPref.sameSet(query, priority)) { 3147 Slog.i(TAG, "Result set changed, dropping preferred activity for " 3148 + intent + " type " + resolvedType); 3149 if (DEBUG_PREFERRED) { 3150 Slog.v(TAG, "Removing preferred activity since set changed " 3151 + pa.mPref.mComponent); 3152 } 3153 pir.removeFilter(pa); 3154 // Re-add the filter as a "last chosen" entry (!always) 3155 PreferredActivity lastChosen = new PreferredActivity( 3156 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 3157 pir.addFilter(lastChosen); 3158 mSettings.writePackageRestrictionsLPr(userId); 3159 return null; 3160 } 3161 3162 // Yay! Either the set matched or we're looking for the last chosen 3163 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 3164 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3165 mSettings.writePackageRestrictionsLPr(userId); 3166 return ri; 3167 } 3168 } 3169 } 3170 mSettings.writePackageRestrictionsLPr(userId); 3171 } 3172 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 3173 return null; 3174 } 3175 3176 /* 3177 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 3178 */ 3179 @Override 3180 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 3181 int targetUserId) { 3182 mContext.enforceCallingOrSelfPermission( 3183 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 3184 List<CrossProfileIntentFilter> matches = 3185 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 3186 if (matches != null) { 3187 int size = matches.size(); 3188 for (int i = 0; i < size; i++) { 3189 if (matches.get(i).getTargetUserId() == targetUserId) return true; 3190 } 3191 } 3192 3193 ArrayList<String> packageNames = null; 3194 SparseArray<ArrayList<String>> fromSource = 3195 mSettings.mCrossProfilePackageInfo.get(sourceUserId); 3196 if (fromSource != null) { 3197 packageNames = fromSource.get(targetUserId); 3198 } 3199 if (packageNames.contains(intent.getPackage())) { 3200 return true; 3201 } 3202 // We need the package name, so we try to resolve with the loosest flags possible 3203 List<ResolveInfo> resolveInfos = mActivities.queryIntent( 3204 intent, resolvedType, PackageManager.GET_UNINSTALLED_PACKAGES, targetUserId); 3205 int count = resolveInfos.size(); 3206 for (int i = 0; i < count; i++) { 3207 ResolveInfo resolveInfo = resolveInfos.get(i); 3208 if (packageNames.contains(resolveInfo.activityInfo.packageName)) { 3209 return true; 3210 } 3211 } 3212 return false; 3213 } 3214 3215 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 3216 String resolvedType, int userId) { 3217 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 3218 if (resolver != null) { 3219 return resolver.queryIntent(intent, resolvedType, false, userId); 3220 } 3221 return null; 3222 } 3223 3224 @Override 3225 public List<ResolveInfo> queryIntentActivities(Intent intent, 3226 String resolvedType, int flags, int userId) { 3227 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3228 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities"); 3229 ComponentName comp = intent.getComponent(); 3230 if (comp == null) { 3231 if (intent.getSelector() != null) { 3232 intent = intent.getSelector(); 3233 comp = intent.getComponent(); 3234 } 3235 } 3236 3237 if (comp != null) { 3238 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3239 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 3240 if (ai != null) { 3241 final ResolveInfo ri = new ResolveInfo(); 3242 ri.activityInfo = ai; 3243 list.add(ri); 3244 } 3245 return list; 3246 } 3247 3248 // reader 3249 synchronized (mPackages) { 3250 final String pkgName = intent.getPackage(); 3251 boolean queryCrossProfile = (flags & PackageManager.NO_CROSS_PROFILE) == 0; 3252 if (pkgName == null) { 3253 ResolveInfo resolveInfo = null; 3254 if (queryCrossProfile) { 3255 // Check if the intent needs to be forwarded to another user for this package 3256 ArrayList<ResolveInfo> crossProfileResult = 3257 queryIntentActivitiesCrossProfilePackage( 3258 intent, resolvedType, flags, userId); 3259 if (!crossProfileResult.isEmpty()) { 3260 // Skip the current profile 3261 return crossProfileResult; 3262 } 3263 List<CrossProfileIntentFilter> matchingFilters = 3264 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 3265 // Check for results that need to skip the current profile. 3266 resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 3267 resolvedType, flags, userId); 3268 if (resolveInfo != null) { 3269 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 3270 result.add(resolveInfo); 3271 return result; 3272 } 3273 // Check for cross profile results. 3274 resolveInfo = queryCrossProfileIntents( 3275 matchingFilters, intent, resolvedType, flags, userId); 3276 } 3277 // Check for results in the current profile. 3278 List<ResolveInfo> result = mActivities.queryIntent( 3279 intent, resolvedType, flags, userId); 3280 if (resolveInfo != null) { 3281 result.add(resolveInfo); 3282 } 3283 return result; 3284 } 3285 final PackageParser.Package pkg = mPackages.get(pkgName); 3286 if (pkg != null) { 3287 if (queryCrossProfile) { 3288 ArrayList<ResolveInfo> crossProfileResult = 3289 queryIntentActivitiesCrossProfilePackage( 3290 intent, resolvedType, flags, userId, pkg, pkgName); 3291 if (!crossProfileResult.isEmpty()) { 3292 // Skip the current profile 3293 return crossProfileResult; 3294 } 3295 } 3296 return mActivities.queryIntentForPackage(intent, resolvedType, flags, 3297 pkg.activities, userId); 3298 } 3299 return new ArrayList<ResolveInfo>(); 3300 } 3301 } 3302 3303 private ResolveInfo querySkipCurrentProfileIntents( 3304 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 3305 int flags, int sourceUserId) { 3306 if (matchingFilters != null) { 3307 int size = matchingFilters.size(); 3308 for (int i = 0; i < size; i ++) { 3309 CrossProfileIntentFilter filter = matchingFilters.get(i); 3310 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 3311 // Checking if there are activities in the target user that can handle the 3312 // intent. 3313 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 3314 flags, sourceUserId); 3315 if (resolveInfo != null) { 3316 return resolveInfo; 3317 } 3318 } 3319 } 3320 } 3321 return null; 3322 } 3323 3324 private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage( 3325 Intent intent, String resolvedType, int flags, int userId) { 3326 ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>(); 3327 SparseArray<ArrayList<String>> sourceForwardingInfo = 3328 mSettings.mCrossProfilePackageInfo.get(userId); 3329 if (sourceForwardingInfo != null) { 3330 int NI = sourceForwardingInfo.size(); 3331 for (int i = 0; i < NI; i++) { 3332 int targetUserId = sourceForwardingInfo.keyAt(i); 3333 ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i); 3334 List<ResolveInfo> resolveInfos = mActivities.queryIntent( 3335 intent, resolvedType, flags, targetUserId); 3336 int NJ = resolveInfos.size(); 3337 for (int j = 0; j < NJ; j++) { 3338 ResolveInfo resolveInfo = resolveInfos.get(j); 3339 if (packageNames.contains(resolveInfo.activityInfo.packageName)) { 3340 matchingResolveInfos.add(createForwardingResolveInfo( 3341 resolveInfo.filter, userId, targetUserId)); 3342 } 3343 } 3344 } 3345 } 3346 return matchingResolveInfos; 3347 } 3348 3349 private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage( 3350 Intent intent, String resolvedType, int flags, int userId, PackageParser.Package pkg, 3351 String packageName) { 3352 ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>(); 3353 SparseArray<ArrayList<String>> sourceForwardingInfo = 3354 mSettings.mCrossProfilePackageInfo.get(userId); 3355 if (sourceForwardingInfo != null) { 3356 int NI = sourceForwardingInfo.size(); 3357 for (int i = 0; i < NI; i++) { 3358 int targetUserId = sourceForwardingInfo.keyAt(i); 3359 if (sourceForwardingInfo.valueAt(i).contains(packageName)) { 3360 List<ResolveInfo> resolveInfos = mActivities.queryIntentForPackage( 3361 intent, resolvedType, flags, pkg.activities, targetUserId); 3362 int NJ = resolveInfos.size(); 3363 for (int j = 0; j < NJ; j++) { 3364 ResolveInfo resolveInfo = resolveInfos.get(j); 3365 matchingResolveInfos.add(createForwardingResolveInfo( 3366 resolveInfo.filter, userId, targetUserId)); 3367 } 3368 } 3369 } 3370 } 3371 return matchingResolveInfos; 3372 } 3373 3374 // Return matching ResolveInfo if any for skip current profile intent filters. 3375 private ResolveInfo queryCrossProfileIntents( 3376 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 3377 int flags, int sourceUserId) { 3378 if (matchingFilters != null) { 3379 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 3380 // match the same intent. For performance reasons, it is better not to 3381 // run queryIntent twice for the same userId 3382 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 3383 int size = matchingFilters.size(); 3384 for (int i = 0; i < size; i++) { 3385 CrossProfileIntentFilter filter = matchingFilters.get(i); 3386 int targetUserId = filter.getTargetUserId(); 3387 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0 3388 && !alreadyTriedUserIds.get(targetUserId)) { 3389 // Checking if there are activities in the target user that can handle the 3390 // intent. 3391 ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, 3392 flags, sourceUserId); 3393 if (resolveInfo != null) return resolveInfo; 3394 alreadyTriedUserIds.put(targetUserId, true); 3395 } 3396 } 3397 } 3398 return null; 3399 } 3400 3401 private ResolveInfo checkTargetCanHandle(CrossProfileIntentFilter filter, Intent intent, 3402 String resolvedType, int flags, int sourceUserId) { 3403 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 3404 resolvedType, flags, filter.getTargetUserId()); 3405 if (resultTargetUser != null && !resultTargetUser.isEmpty()) { 3406 return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); 3407 } 3408 return null; 3409 } 3410 3411 private ResolveInfo createForwardingResolveInfo(IntentFilter filter, 3412 int sourceUserId, int targetUserId) { 3413 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 3414 String className; 3415 if (targetUserId == UserHandle.USER_OWNER) { 3416 className = FORWARD_INTENT_TO_USER_OWNER; 3417 } else { 3418 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 3419 } 3420 ComponentName forwardingActivityComponentName = new ComponentName( 3421 mAndroidApplication.packageName, className); 3422 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 3423 sourceUserId); 3424 if (targetUserId == UserHandle.USER_OWNER) { 3425 forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER; 3426 forwardingResolveInfo.noResourceId = true; 3427 } 3428 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 3429 forwardingResolveInfo.priority = 0; 3430 forwardingResolveInfo.preferredOrder = 0; 3431 forwardingResolveInfo.match = 0; 3432 forwardingResolveInfo.isDefault = true; 3433 forwardingResolveInfo.filter = filter; 3434 forwardingResolveInfo.targetUserId = targetUserId; 3435 return forwardingResolveInfo; 3436 } 3437 3438 @Override 3439 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 3440 Intent[] specifics, String[] specificTypes, Intent intent, 3441 String resolvedType, int flags, int userId) { 3442 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3443 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 3444 "query intent activity options"); 3445 final String resultsAction = intent.getAction(); 3446 3447 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 3448 | PackageManager.GET_RESOLVED_FILTER, userId); 3449 3450 if (DEBUG_INTENT_MATCHING) { 3451 Log.v(TAG, "Query " + intent + ": " + results); 3452 } 3453 3454 int specificsPos = 0; 3455 int N; 3456 3457 // todo: note that the algorithm used here is O(N^2). This 3458 // isn't a problem in our current environment, but if we start running 3459 // into situations where we have more than 5 or 10 matches then this 3460 // should probably be changed to something smarter... 3461 3462 // First we go through and resolve each of the specific items 3463 // that were supplied, taking care of removing any corresponding 3464 // duplicate items in the generic resolve list. 3465 if (specifics != null) { 3466 for (int i=0; i<specifics.length; i++) { 3467 final Intent sintent = specifics[i]; 3468 if (sintent == null) { 3469 continue; 3470 } 3471 3472 if (DEBUG_INTENT_MATCHING) { 3473 Log.v(TAG, "Specific #" + i + ": " + sintent); 3474 } 3475 3476 String action = sintent.getAction(); 3477 if (resultsAction != null && resultsAction.equals(action)) { 3478 // If this action was explicitly requested, then don't 3479 // remove things that have it. 3480 action = null; 3481 } 3482 3483 ResolveInfo ri = null; 3484 ActivityInfo ai = null; 3485 3486 ComponentName comp = sintent.getComponent(); 3487 if (comp == null) { 3488 ri = resolveIntent( 3489 sintent, 3490 specificTypes != null ? specificTypes[i] : null, 3491 flags, userId); 3492 if (ri == null) { 3493 continue; 3494 } 3495 if (ri == mResolveInfo) { 3496 // ACK! Must do something better with this. 3497 } 3498 ai = ri.activityInfo; 3499 comp = new ComponentName(ai.applicationInfo.packageName, 3500 ai.name); 3501 } else { 3502 ai = getActivityInfo(comp, flags, userId); 3503 if (ai == null) { 3504 continue; 3505 } 3506 } 3507 3508 // Look for any generic query activities that are duplicates 3509 // of this specific one, and remove them from the results. 3510 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 3511 N = results.size(); 3512 int j; 3513 for (j=specificsPos; j<N; j++) { 3514 ResolveInfo sri = results.get(j); 3515 if ((sri.activityInfo.name.equals(comp.getClassName()) 3516 && sri.activityInfo.applicationInfo.packageName.equals( 3517 comp.getPackageName())) 3518 || (action != null && sri.filter.matchAction(action))) { 3519 results.remove(j); 3520 if (DEBUG_INTENT_MATCHING) Log.v( 3521 TAG, "Removing duplicate item from " + j 3522 + " due to specific " + specificsPos); 3523 if (ri == null) { 3524 ri = sri; 3525 } 3526 j--; 3527 N--; 3528 } 3529 } 3530 3531 // Add this specific item to its proper place. 3532 if (ri == null) { 3533 ri = new ResolveInfo(); 3534 ri.activityInfo = ai; 3535 } 3536 results.add(specificsPos, ri); 3537 ri.specificIndex = i; 3538 specificsPos++; 3539 } 3540 } 3541 3542 // Now we go through the remaining generic results and remove any 3543 // duplicate actions that are found here. 3544 N = results.size(); 3545 for (int i=specificsPos; i<N-1; i++) { 3546 final ResolveInfo rii = results.get(i); 3547 if (rii.filter == null) { 3548 continue; 3549 } 3550 3551 // Iterate over all of the actions of this result's intent 3552 // filter... typically this should be just one. 3553 final Iterator<String> it = rii.filter.actionsIterator(); 3554 if (it == null) { 3555 continue; 3556 } 3557 while (it.hasNext()) { 3558 final String action = it.next(); 3559 if (resultsAction != null && resultsAction.equals(action)) { 3560 // If this action was explicitly requested, then don't 3561 // remove things that have it. 3562 continue; 3563 } 3564 for (int j=i+1; j<N; j++) { 3565 final ResolveInfo rij = results.get(j); 3566 if (rij.filter != null && rij.filter.hasAction(action)) { 3567 results.remove(j); 3568 if (DEBUG_INTENT_MATCHING) Log.v( 3569 TAG, "Removing duplicate item from " + j 3570 + " due to action " + action + " at " + i); 3571 j--; 3572 N--; 3573 } 3574 } 3575 } 3576 3577 // If the caller didn't request filter information, drop it now 3578 // so we don't have to marshall/unmarshall it. 3579 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 3580 rii.filter = null; 3581 } 3582 } 3583 3584 // Filter out the caller activity if so requested. 3585 if (caller != null) { 3586 N = results.size(); 3587 for (int i=0; i<N; i++) { 3588 ActivityInfo ainfo = results.get(i).activityInfo; 3589 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 3590 && caller.getClassName().equals(ainfo.name)) { 3591 results.remove(i); 3592 break; 3593 } 3594 } 3595 } 3596 3597 // If the caller didn't request filter information, 3598 // drop them now so we don't have to 3599 // marshall/unmarshall it. 3600 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 3601 N = results.size(); 3602 for (int i=0; i<N; i++) { 3603 results.get(i).filter = null; 3604 } 3605 } 3606 3607 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 3608 return results; 3609 } 3610 3611 @Override 3612 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 3613 int userId) { 3614 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3615 ComponentName comp = intent.getComponent(); 3616 if (comp == null) { 3617 if (intent.getSelector() != null) { 3618 intent = intent.getSelector(); 3619 comp = intent.getComponent(); 3620 } 3621 } 3622 if (comp != null) { 3623 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3624 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 3625 if (ai != null) { 3626 ResolveInfo ri = new ResolveInfo(); 3627 ri.activityInfo = ai; 3628 list.add(ri); 3629 } 3630 return list; 3631 } 3632 3633 // reader 3634 synchronized (mPackages) { 3635 String pkgName = intent.getPackage(); 3636 if (pkgName == null) { 3637 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 3638 } 3639 final PackageParser.Package pkg = mPackages.get(pkgName); 3640 if (pkg != null) { 3641 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 3642 userId); 3643 } 3644 return null; 3645 } 3646 } 3647 3648 @Override 3649 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 3650 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 3651 if (!sUserManager.exists(userId)) return null; 3652 if (query != null) { 3653 if (query.size() >= 1) { 3654 // If there is more than one service with the same priority, 3655 // just arbitrarily pick the first one. 3656 return query.get(0); 3657 } 3658 } 3659 return null; 3660 } 3661 3662 @Override 3663 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 3664 int userId) { 3665 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3666 ComponentName comp = intent.getComponent(); 3667 if (comp == null) { 3668 if (intent.getSelector() != null) { 3669 intent = intent.getSelector(); 3670 comp = intent.getComponent(); 3671 } 3672 } 3673 if (comp != null) { 3674 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3675 final ServiceInfo si = getServiceInfo(comp, flags, userId); 3676 if (si != null) { 3677 final ResolveInfo ri = new ResolveInfo(); 3678 ri.serviceInfo = si; 3679 list.add(ri); 3680 } 3681 return list; 3682 } 3683 3684 // reader 3685 synchronized (mPackages) { 3686 String pkgName = intent.getPackage(); 3687 if (pkgName == null) { 3688 return mServices.queryIntent(intent, resolvedType, flags, userId); 3689 } 3690 final PackageParser.Package pkg = mPackages.get(pkgName); 3691 if (pkg != null) { 3692 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 3693 userId); 3694 } 3695 return null; 3696 } 3697 } 3698 3699 @Override 3700 public List<ResolveInfo> queryIntentContentProviders( 3701 Intent intent, String resolvedType, int flags, int userId) { 3702 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3703 ComponentName comp = intent.getComponent(); 3704 if (comp == null) { 3705 if (intent.getSelector() != null) { 3706 intent = intent.getSelector(); 3707 comp = intent.getComponent(); 3708 } 3709 } 3710 if (comp != null) { 3711 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3712 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 3713 if (pi != null) { 3714 final ResolveInfo ri = new ResolveInfo(); 3715 ri.providerInfo = pi; 3716 list.add(ri); 3717 } 3718 return list; 3719 } 3720 3721 // reader 3722 synchronized (mPackages) { 3723 String pkgName = intent.getPackage(); 3724 if (pkgName == null) { 3725 return mProviders.queryIntent(intent, resolvedType, flags, userId); 3726 } 3727 final PackageParser.Package pkg = mPackages.get(pkgName); 3728 if (pkg != null) { 3729 return mProviders.queryIntentForPackage( 3730 intent, resolvedType, flags, pkg.providers, userId); 3731 } 3732 return null; 3733 } 3734 } 3735 3736 @Override 3737 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 3738 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3739 3740 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages"); 3741 3742 // writer 3743 synchronized (mPackages) { 3744 ArrayList<PackageInfo> list; 3745 if (listUninstalled) { 3746 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 3747 for (PackageSetting ps : mSettings.mPackages.values()) { 3748 PackageInfo pi; 3749 if (ps.pkg != null) { 3750 pi = generatePackageInfo(ps.pkg, flags, userId); 3751 } else { 3752 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 3753 } 3754 if (pi != null) { 3755 list.add(pi); 3756 } 3757 } 3758 } else { 3759 list = new ArrayList<PackageInfo>(mPackages.size()); 3760 for (PackageParser.Package p : mPackages.values()) { 3761 PackageInfo pi = generatePackageInfo(p, flags, userId); 3762 if (pi != null) { 3763 list.add(pi); 3764 } 3765 } 3766 } 3767 3768 return new ParceledListSlice<PackageInfo>(list); 3769 } 3770 } 3771 3772 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 3773 String[] permissions, boolean[] tmp, int flags, int userId) { 3774 int numMatch = 0; 3775 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 3776 for (int i=0; i<permissions.length; i++) { 3777 if (gp.grantedPermissions.contains(permissions[i])) { 3778 tmp[i] = true; 3779 numMatch++; 3780 } else { 3781 tmp[i] = false; 3782 } 3783 } 3784 if (numMatch == 0) { 3785 return; 3786 } 3787 PackageInfo pi; 3788 if (ps.pkg != null) { 3789 pi = generatePackageInfo(ps.pkg, flags, userId); 3790 } else { 3791 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 3792 } 3793 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 3794 if (numMatch == permissions.length) { 3795 pi.requestedPermissions = permissions; 3796 } else { 3797 pi.requestedPermissions = new String[numMatch]; 3798 numMatch = 0; 3799 for (int i=0; i<permissions.length; i++) { 3800 if (tmp[i]) { 3801 pi.requestedPermissions[numMatch] = permissions[i]; 3802 numMatch++; 3803 } 3804 } 3805 } 3806 } 3807 list.add(pi); 3808 } 3809 3810 @Override 3811 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 3812 String[] permissions, int flags, int userId) { 3813 if (!sUserManager.exists(userId)) return null; 3814 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3815 3816 // writer 3817 synchronized (mPackages) { 3818 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 3819 boolean[] tmpBools = new boolean[permissions.length]; 3820 if (listUninstalled) { 3821 for (PackageSetting ps : mSettings.mPackages.values()) { 3822 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 3823 } 3824 } else { 3825 for (PackageParser.Package pkg : mPackages.values()) { 3826 PackageSetting ps = (PackageSetting)pkg.mExtras; 3827 if (ps != null) { 3828 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 3829 userId); 3830 } 3831 } 3832 } 3833 3834 return new ParceledListSlice<PackageInfo>(list); 3835 } 3836 } 3837 3838 @Override 3839 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 3840 if (!sUserManager.exists(userId)) return null; 3841 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3842 3843 // writer 3844 synchronized (mPackages) { 3845 ArrayList<ApplicationInfo> list; 3846 if (listUninstalled) { 3847 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 3848 for (PackageSetting ps : mSettings.mPackages.values()) { 3849 ApplicationInfo ai; 3850 if (ps.pkg != null) { 3851 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 3852 ps.readUserState(userId), userId); 3853 } else { 3854 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 3855 } 3856 if (ai != null) { 3857 list.add(ai); 3858 } 3859 } 3860 } else { 3861 list = new ArrayList<ApplicationInfo>(mPackages.size()); 3862 for (PackageParser.Package p : mPackages.values()) { 3863 if (p.mExtras != null) { 3864 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 3865 ((PackageSetting)p.mExtras).readUserState(userId), userId); 3866 if (ai != null) { 3867 list.add(ai); 3868 } 3869 } 3870 } 3871 } 3872 3873 return new ParceledListSlice<ApplicationInfo>(list); 3874 } 3875 } 3876 3877 public List<ApplicationInfo> getPersistentApplications(int flags) { 3878 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 3879 3880 // reader 3881 synchronized (mPackages) { 3882 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 3883 final int userId = UserHandle.getCallingUserId(); 3884 while (i.hasNext()) { 3885 final PackageParser.Package p = i.next(); 3886 if (p.applicationInfo != null 3887 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 3888 && (!mSafeMode || isSystemApp(p))) { 3889 PackageSetting ps = mSettings.mPackages.get(p.packageName); 3890 if (ps != null) { 3891 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 3892 ps.readUserState(userId), userId); 3893 if (ai != null) { 3894 finalList.add(ai); 3895 } 3896 } 3897 } 3898 } 3899 } 3900 3901 return finalList; 3902 } 3903 3904 @Override 3905 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 3906 if (!sUserManager.exists(userId)) return null; 3907 // reader 3908 synchronized (mPackages) { 3909 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 3910 PackageSetting ps = provider != null 3911 ? mSettings.mPackages.get(provider.owner.packageName) 3912 : null; 3913 return ps != null 3914 && mSettings.isEnabledLPr(provider.info, flags, userId) 3915 && (!mSafeMode || (provider.info.applicationInfo.flags 3916 &ApplicationInfo.FLAG_SYSTEM) != 0) 3917 ? PackageParser.generateProviderInfo(provider, flags, 3918 ps.readUserState(userId), userId) 3919 : null; 3920 } 3921 } 3922 3923 /** 3924 * @deprecated 3925 */ 3926 @Deprecated 3927 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 3928 // reader 3929 synchronized (mPackages) { 3930 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 3931 .entrySet().iterator(); 3932 final int userId = UserHandle.getCallingUserId(); 3933 while (i.hasNext()) { 3934 Map.Entry<String, PackageParser.Provider> entry = i.next(); 3935 PackageParser.Provider p = entry.getValue(); 3936 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 3937 3938 if (ps != null && p.syncable 3939 && (!mSafeMode || (p.info.applicationInfo.flags 3940 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 3941 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 3942 ps.readUserState(userId), userId); 3943 if (info != null) { 3944 outNames.add(entry.getKey()); 3945 outInfo.add(info); 3946 } 3947 } 3948 } 3949 } 3950 } 3951 3952 @Override 3953 public List<ProviderInfo> queryContentProviders(String processName, 3954 int uid, int flags) { 3955 ArrayList<ProviderInfo> finalList = null; 3956 // reader 3957 synchronized (mPackages) { 3958 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 3959 final int userId = processName != null ? 3960 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 3961 while (i.hasNext()) { 3962 final PackageParser.Provider p = i.next(); 3963 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 3964 if (ps != null && p.info.authority != null 3965 && (processName == null 3966 || (p.info.processName.equals(processName) 3967 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 3968 && mSettings.isEnabledLPr(p.info, flags, userId) 3969 && (!mSafeMode 3970 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 3971 if (finalList == null) { 3972 finalList = new ArrayList<ProviderInfo>(3); 3973 } 3974 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 3975 ps.readUserState(userId), userId); 3976 if (info != null) { 3977 finalList.add(info); 3978 } 3979 } 3980 } 3981 } 3982 3983 if (finalList != null) { 3984 Collections.sort(finalList, mProviderInitOrderSorter); 3985 } 3986 3987 return finalList; 3988 } 3989 3990 @Override 3991 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 3992 int flags) { 3993 // reader 3994 synchronized (mPackages) { 3995 final PackageParser.Instrumentation i = mInstrumentation.get(name); 3996 return PackageParser.generateInstrumentationInfo(i, flags); 3997 } 3998 } 3999 4000 @Override 4001 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 4002 int flags) { 4003 ArrayList<InstrumentationInfo> finalList = 4004 new ArrayList<InstrumentationInfo>(); 4005 4006 // reader 4007 synchronized (mPackages) { 4008 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 4009 while (i.hasNext()) { 4010 final PackageParser.Instrumentation p = i.next(); 4011 if (targetPackage == null 4012 || targetPackage.equals(p.info.targetPackage)) { 4013 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 4014 flags); 4015 if (ii != null) { 4016 finalList.add(ii); 4017 } 4018 } 4019 } 4020 } 4021 4022 return finalList; 4023 } 4024 4025 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 4026 HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 4027 if (overlays == null) { 4028 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 4029 return; 4030 } 4031 for (PackageParser.Package opkg : overlays.values()) { 4032 // Not much to do if idmap fails: we already logged the error 4033 // and we certainly don't want to abort installation of pkg simply 4034 // because an overlay didn't fit properly. For these reasons, 4035 // ignore the return value of createIdmapForPackagePairLI. 4036 createIdmapForPackagePairLI(pkg, opkg); 4037 } 4038 } 4039 4040 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 4041 PackageParser.Package opkg) { 4042 if (!opkg.mTrustedOverlay) { 4043 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 4044 opkg.baseCodePath + ": overlay not trusted"); 4045 return false; 4046 } 4047 HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 4048 if (overlaySet == null) { 4049 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 4050 opkg.baseCodePath + " but target package has no known overlays"); 4051 return false; 4052 } 4053 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4054 // TODO: generate idmap for split APKs 4055 if (mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid) != 0) { 4056 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 4057 + opkg.baseCodePath); 4058 return false; 4059 } 4060 PackageParser.Package[] overlayArray = 4061 overlaySet.values().toArray(new PackageParser.Package[0]); 4062 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 4063 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 4064 return p1.mOverlayPriority - p2.mOverlayPriority; 4065 } 4066 }; 4067 Arrays.sort(overlayArray, cmp); 4068 4069 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 4070 int i = 0; 4071 for (PackageParser.Package p : overlayArray) { 4072 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 4073 } 4074 return true; 4075 } 4076 4077 private void scanDirLI(File dir, int flags, int scanMode, long currentTime) { 4078 final File[] files = dir.listFiles(); 4079 if (ArrayUtils.isEmpty(files)) { 4080 Log.d(TAG, "No files in app dir " + dir); 4081 return; 4082 } 4083 4084 if (DEBUG_PACKAGE_SCANNING) { 4085 Log.d(TAG, "Scanning app dir " + dir + " scanMode=" + scanMode 4086 + " flags=0x" + Integer.toHexString(flags)); 4087 } 4088 4089 for (File file : files) { 4090 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 4091 && !PackageInstallerService.isStageFile(file); 4092 if (!isPackage) { 4093 // Ignore entries which are not apk's 4094 continue; 4095 } 4096 try { 4097 scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, 4098 null, null); 4099 } catch (PackageManagerException e) { 4100 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 4101 4102 // Don't mess around with apps in system partition. 4103 if ((flags & PackageParser.PARSE_IS_SYSTEM) == 0 && 4104 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 4105 // Delete the apk 4106 Slog.w(TAG, "Cleaning up failed install of " + file); 4107 file.delete(); 4108 } 4109 } 4110 } 4111 } 4112 4113 private static File getSettingsProblemFile() { 4114 File dataDir = Environment.getDataDirectory(); 4115 File systemDir = new File(dataDir, "system"); 4116 File fname = new File(systemDir, "uiderrors.txt"); 4117 return fname; 4118 } 4119 4120 static void reportSettingsProblem(int priority, String msg) { 4121 try { 4122 File fname = getSettingsProblemFile(); 4123 FileOutputStream out = new FileOutputStream(fname, true); 4124 PrintWriter pw = new FastPrintWriter(out); 4125 SimpleDateFormat formatter = new SimpleDateFormat(); 4126 String dateString = formatter.format(new Date(System.currentTimeMillis())); 4127 pw.println(dateString + ": " + msg); 4128 pw.close(); 4129 FileUtils.setPermissions( 4130 fname.toString(), 4131 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 4132 -1, -1); 4133 } catch (java.io.IOException e) { 4134 } 4135 Slog.println(priority, TAG, msg); 4136 } 4137 4138 private void collectCertificatesLI(PackageParser pp, PackageSetting ps, 4139 PackageParser.Package pkg, File srcFile, int parseFlags) 4140 throws PackageManagerException { 4141 if (ps != null 4142 && ps.codePath.equals(srcFile) 4143 && ps.timeStamp == srcFile.lastModified() 4144 && !isCompatSignatureUpdateNeeded(pkg)) { 4145 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 4146 if (ps.signatures.mSignatures != null 4147 && ps.signatures.mSignatures.length != 0 4148 && mSigningKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) { 4149 // Optimization: reuse the existing cached certificates 4150 // if the package appears to be unchanged. 4151 pkg.mSignatures = ps.signatures.mSignatures; 4152 KeySetManagerService ksms = mSettings.mKeySetManagerService; 4153 synchronized (mPackages) { 4154 pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 4155 } 4156 return; 4157 } 4158 4159 Slog.w(TAG, "PackageSetting for " + ps.name 4160 + " is missing signatures. Collecting certs again to recover them."); 4161 } else { 4162 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 4163 } 4164 4165 try { 4166 pp.collectCertificates(pkg, parseFlags); 4167 pp.collectManifestDigest(pkg); 4168 } catch (PackageParserException e) { 4169 throw new PackageManagerException(e.error, "Failed to collect certificates for " 4170 + pkg.packageName + ": " + e.getMessage()); 4171 } 4172 } 4173 4174 /* 4175 * Scan a package and return the newly parsed package. 4176 * Returns null in case of errors and the error code is stored in mLastScanError 4177 */ 4178 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanMode, 4179 long currentTime, UserHandle user, String abiOverride) throws PackageManagerException { 4180 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 4181 parseFlags |= mDefParseFlags; 4182 PackageParser pp = new PackageParser(); 4183 pp.setSeparateProcesses(mSeparateProcesses); 4184 pp.setOnlyCoreApps(mOnlyCore); 4185 pp.setDisplayMetrics(mMetrics); 4186 4187 if ((scanMode & SCAN_TRUSTED_OVERLAY) != 0) { 4188 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 4189 } 4190 4191 final PackageParser.Package pkg; 4192 try { 4193 pkg = pp.parsePackage(scanFile, parseFlags); 4194 } catch (PackageParserException e) { 4195 throw new PackageManagerException(e.error, 4196 "Failed to scan " + scanFile + ": " + e.getMessage()); 4197 } 4198 4199 PackageSetting ps = null; 4200 PackageSetting updatedPkg; 4201 // reader 4202 synchronized (mPackages) { 4203 // Look to see if we already know about this package. 4204 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 4205 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 4206 // This package has been renamed to its original name. Let's 4207 // use that. 4208 ps = mSettings.peekPackageLPr(oldName); 4209 } 4210 // If there was no original package, see one for the real package name. 4211 if (ps == null) { 4212 ps = mSettings.peekPackageLPr(pkg.packageName); 4213 } 4214 // Check to see if this package could be hiding/updating a system 4215 // package. Must look for it either under the original or real 4216 // package name depending on our state. 4217 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 4218 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 4219 } 4220 boolean updatedPkgBetter = false; 4221 // First check if this is a system package that may involve an update 4222 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 4223 if (ps != null && !ps.codePath.equals(scanFile)) { 4224 // The path has changed from what was last scanned... check the 4225 // version of the new path against what we have stored to determine 4226 // what to do. 4227 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 4228 if (pkg.mVersionCode < ps.versionCode) { 4229 // The system package has been updated and the code path does not match 4230 // Ignore entry. Skip it. 4231 Log.i(TAG, "Package " + ps.name + " at " + scanFile 4232 + " ignored: updated version " + ps.versionCode 4233 + " better than this " + pkg.mVersionCode); 4234 if (!updatedPkg.codePath.equals(scanFile)) { 4235 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 4236 + ps.name + " changing from " + updatedPkg.codePathString 4237 + " to " + scanFile); 4238 updatedPkg.codePath = scanFile; 4239 updatedPkg.codePathString = scanFile.toString(); 4240 // This is the point at which we know that the system-disk APK 4241 // for this package has moved during a reboot (e.g. due to an OTA), 4242 // so we need to reevaluate it for privilege policy. 4243 if (locationIsPrivileged(scanFile)) { 4244 updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED; 4245 } 4246 } 4247 updatedPkg.pkg = pkg; 4248 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, null); 4249 } else { 4250 // The current app on the system partition is better than 4251 // what we have updated to on the data partition; switch 4252 // back to the system partition version. 4253 // At this point, its safely assumed that package installation for 4254 // apps in system partition will go through. If not there won't be a working 4255 // version of the app 4256 // writer 4257 synchronized (mPackages) { 4258 // Just remove the loaded entries from package lists. 4259 mPackages.remove(ps.name); 4260 } 4261 Slog.w(TAG, "Package " + ps.name + " at " + scanFile 4262 + "reverting from " + ps.codePathString 4263 + ": new version " + pkg.mVersionCode 4264 + " better than installed " + ps.versionCode); 4265 4266 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 4267 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 4268 getAppDexInstructionSets(ps), isMultiArch(ps)); 4269 synchronized (mInstallLock) { 4270 args.cleanUpResourcesLI(); 4271 } 4272 synchronized (mPackages) { 4273 mSettings.enableSystemPackageLPw(ps.name); 4274 } 4275 updatedPkgBetter = true; 4276 } 4277 } 4278 } 4279 4280 if (updatedPkg != null) { 4281 // An updated system app will not have the PARSE_IS_SYSTEM flag set 4282 // initially 4283 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 4284 4285 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 4286 // flag set initially 4287 if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) { 4288 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 4289 } 4290 } 4291 4292 // Verify certificates against what was last scanned 4293 collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags); 4294 4295 /* 4296 * A new system app appeared, but we already had a non-system one of the 4297 * same name installed earlier. 4298 */ 4299 boolean shouldHideSystemApp = false; 4300 if (updatedPkg == null && ps != null 4301 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 4302 /* 4303 * Check to make sure the signatures match first. If they don't, 4304 * wipe the installed application and its data. 4305 */ 4306 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 4307 != PackageManager.SIGNATURE_MATCH) { 4308 if (DEBUG_INSTALL) Slog.d(TAG, "Signature mismatch!"); 4309 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 4310 ps = null; 4311 } else { 4312 /* 4313 * If the newly-added system app is an older version than the 4314 * already installed version, hide it. It will be scanned later 4315 * and re-added like an update. 4316 */ 4317 if (pkg.mVersionCode < ps.versionCode) { 4318 shouldHideSystemApp = true; 4319 } else { 4320 /* 4321 * The newly found system app is a newer version that the 4322 * one previously installed. Simply remove the 4323 * already-installed application and replace it with our own 4324 * while keeping the application data. 4325 */ 4326 Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from " 4327 + ps.codePathString + ": new version " + pkg.mVersionCode 4328 + " better than installed " + ps.versionCode); 4329 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 4330 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 4331 getAppDexInstructionSets(ps), isMultiArch(ps)); 4332 synchronized (mInstallLock) { 4333 args.cleanUpResourcesLI(); 4334 } 4335 } 4336 } 4337 } 4338 4339 // The apk is forward locked (not public) if its code and resources 4340 // are kept in different files. (except for app in either system or 4341 // vendor path). 4342 // TODO grab this value from PackageSettings 4343 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 4344 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 4345 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 4346 } 4347 } 4348 4349 // TODO: extend to support forward-locked splits 4350 String resourcePath = null; 4351 String baseResourcePath = null; 4352 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 4353 if (ps != null && ps.resourcePathString != null) { 4354 resourcePath = ps.resourcePathString; 4355 baseResourcePath = ps.resourcePathString; 4356 } else { 4357 // Should not happen at all. Just log an error. 4358 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 4359 } 4360 } else { 4361 resourcePath = pkg.codePath; 4362 baseResourcePath = pkg.baseCodePath; 4363 } 4364 4365 // Set application objects path explicitly. 4366 pkg.applicationInfo.setCodePath(pkg.codePath); 4367 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 4368 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 4369 pkg.applicationInfo.setResourcePath(resourcePath); 4370 pkg.applicationInfo.setBaseResourcePath(baseResourcePath); 4371 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 4372 4373 // Note that we invoke the following method only if we are about to unpack an application 4374 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode 4375 | SCAN_UPDATE_SIGNATURE, currentTime, user, abiOverride); 4376 4377 /* 4378 * If the system app should be overridden by a previously installed 4379 * data, hide the system app now and let the /data/app scan pick it up 4380 * again. 4381 */ 4382 if (shouldHideSystemApp) { 4383 synchronized (mPackages) { 4384 /* 4385 * We have to grant systems permissions before we hide, because 4386 * grantPermissions will assume the package update is trying to 4387 * expand its permissions. 4388 */ 4389 grantPermissionsLPw(pkg, true); 4390 mSettings.disableSystemPackageLPw(pkg.packageName); 4391 } 4392 } 4393 4394 return scannedPkg; 4395 } 4396 4397 private static String fixProcessName(String defProcessName, 4398 String processName, int uid) { 4399 if (processName == null) { 4400 return defProcessName; 4401 } 4402 return processName; 4403 } 4404 4405 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 4406 throws PackageManagerException { 4407 if (pkgSetting.signatures.mSignatures != null) { 4408 // Already existing package. Make sure signatures match 4409 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 4410 == PackageManager.SIGNATURE_MATCH; 4411 if (!match) { 4412 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 4413 == PackageManager.SIGNATURE_MATCH; 4414 } 4415 if (!match) { 4416 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 4417 + pkg.packageName + " signatures do not match the " 4418 + "previously installed version; ignoring!"); 4419 } 4420 } 4421 4422 // Check for shared user signatures 4423 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 4424 // Already existing package. Make sure signatures match 4425 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 4426 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 4427 if (!match) { 4428 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 4429 == PackageManager.SIGNATURE_MATCH; 4430 } 4431 if (!match) { 4432 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 4433 "Package " + pkg.packageName 4434 + " has no signatures that match those in shared user " 4435 + pkgSetting.sharedUser.name + "; ignoring!"); 4436 } 4437 } 4438 } 4439 4440 /** 4441 * Enforces that only the system UID or root's UID can call a method exposed 4442 * via Binder. 4443 * 4444 * @param message used as message if SecurityException is thrown 4445 * @throws SecurityException if the caller is not system or root 4446 */ 4447 private static final void enforceSystemOrRoot(String message) { 4448 final int uid = Binder.getCallingUid(); 4449 if (uid != Process.SYSTEM_UID && uid != 0) { 4450 throw new SecurityException(message); 4451 } 4452 } 4453 4454 @Override 4455 public void performBootDexOpt() { 4456 enforceSystemOrRoot("Only the system can request dexopt be performed"); 4457 4458 final HashSet<PackageParser.Package> pkgs; 4459 synchronized (mPackages) { 4460 pkgs = mDeferredDexOpt; 4461 mDeferredDexOpt = null; 4462 } 4463 4464 if (pkgs != null) { 4465 // Filter out packages that aren't recently used. 4466 // 4467 // The exception is first boot of a non-eng device, which 4468 // should do a full dexopt. 4469 boolean eng = "eng".equals(SystemProperties.get("ro.build.type")); 4470 if (eng || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { 4471 // TODO: add a property to control this? 4472 long dexOptLRUThresholdInMinutes; 4473 if (eng) { 4474 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 4475 } else { 4476 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 4477 } 4478 long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 4479 4480 int total = pkgs.size(); 4481 int skipped = 0; 4482 long now = System.currentTimeMillis(); 4483 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 4484 PackageParser.Package pkg = i.next(); 4485 long then = pkg.mLastPackageUsageTimeInMills; 4486 if (then + dexOptLRUThresholdInMills < now) { 4487 if (DEBUG_DEXOPT) { 4488 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 4489 ((then == 0) ? "never" : new Date(then))); 4490 } 4491 i.remove(); 4492 skipped++; 4493 } 4494 } 4495 if (DEBUG_DEXOPT) { 4496 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 4497 } 4498 } 4499 4500 int i = 0; 4501 for (PackageParser.Package pkg : pkgs) { 4502 i++; 4503 if (DEBUG_DEXOPT) { 4504 Log.i(TAG, "Optimizing app " + i + " of " + pkgs.size() 4505 + ": " + pkg.packageName); 4506 } 4507 if (!isFirstBoot()) { 4508 try { 4509 ActivityManagerNative.getDefault().showBootMessage( 4510 mContext.getResources().getString( 4511 R.string.android_upgrading_apk, 4512 i, pkgs.size()), true); 4513 } catch (RemoteException e) { 4514 } 4515 } 4516 PackageParser.Package p = pkg; 4517 synchronized (mInstallLock) { 4518 performDexOptLI(p, null /* instruction sets */, false /* force dex */, false /* defer */, 4519 true /* include dependencies */); 4520 } 4521 } 4522 } 4523 } 4524 4525 @Override 4526 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 4527 return performDexOpt(packageName, instructionSet, true); 4528 } 4529 4530 private static String getPrimaryInstructionSet(ApplicationInfo info) { 4531 if (info.primaryCpuAbi == null) { 4532 return getPreferredInstructionSet(); 4533 } 4534 4535 return VMRuntime.getInstructionSet(info.primaryCpuAbi); 4536 } 4537 4538 public boolean performDexOpt(String packageName, String instructionSet, boolean updateUsage) { 4539 PackageParser.Package p; 4540 final String targetInstructionSet; 4541 synchronized (mPackages) { 4542 p = mPackages.get(packageName); 4543 if (p == null) { 4544 return false; 4545 } 4546 if (updateUsage) { 4547 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 4548 } 4549 mPackageUsage.write(false); 4550 4551 targetInstructionSet = instructionSet != null ? instructionSet : 4552 getPrimaryInstructionSet(p.applicationInfo); 4553 if (p.mDexOptPerformed.contains(targetInstructionSet)) { 4554 return false; 4555 } 4556 } 4557 4558 synchronized (mInstallLock) { 4559 final String[] instructionSets = new String[] { targetInstructionSet }; 4560 return performDexOptLI(p, instructionSets, false /* force dex */, false /* defer */, 4561 true /* include dependencies */) == DEX_OPT_PERFORMED; 4562 } 4563 } 4564 4565 public HashSet<String> getPackagesThatNeedDexOpt() { 4566 HashSet<String> pkgs = null; 4567 synchronized (mPackages) { 4568 for (PackageParser.Package p : mPackages.values()) { 4569 if (DEBUG_DEXOPT) { 4570 Log.i(TAG, p.packageName + " mDexOptPerformed=" + p.mDexOptPerformed.toArray()); 4571 } 4572 if (!p.mDexOptPerformed.isEmpty()) { 4573 continue; 4574 } 4575 if (pkgs == null) { 4576 pkgs = new HashSet<String>(); 4577 } 4578 pkgs.add(p.packageName); 4579 } 4580 } 4581 return pkgs; 4582 } 4583 4584 public void shutdown() { 4585 mPackageUsage.write(true); 4586 } 4587 4588 private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets, 4589 boolean forceDex, boolean defer, HashSet<String> done) { 4590 for (int i=0; i<libs.size(); i++) { 4591 PackageParser.Package libPkg; 4592 String libName; 4593 synchronized (mPackages) { 4594 libName = libs.get(i); 4595 SharedLibraryEntry lib = mSharedLibraries.get(libName); 4596 if (lib != null && lib.apk != null) { 4597 libPkg = mPackages.get(lib.apk); 4598 } else { 4599 libPkg = null; 4600 } 4601 } 4602 if (libPkg != null && !done.contains(libName)) { 4603 performDexOptLI(libPkg, instructionSets, forceDex, defer, done); 4604 } 4605 } 4606 } 4607 4608 static final int DEX_OPT_SKIPPED = 0; 4609 static final int DEX_OPT_PERFORMED = 1; 4610 static final int DEX_OPT_DEFERRED = 2; 4611 static final int DEX_OPT_FAILED = -1; 4612 4613 private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets, 4614 boolean forceDex, boolean defer, HashSet<String> done) { 4615 final String[] instructionSets = targetInstructionSets != null ? 4616 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); 4617 4618 if (done != null) { 4619 done.add(pkg.packageName); 4620 if (pkg.usesLibraries != null) { 4621 performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done); 4622 } 4623 if (pkg.usesOptionalLibraries != null) { 4624 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, done); 4625 } 4626 } 4627 4628 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) { 4629 return DEX_OPT_SKIPPED; 4630 } 4631 4632 final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly(); 4633 boolean performedDexOpt = false; 4634 // There are three basic cases here: 4635 // 1.) we need to dexopt, either because we are forced or it is needed 4636 // 2.) we are defering a needed dexopt 4637 // 3.) we are skipping an unneeded dexopt 4638 final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 4639 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 4640 if (!forceDex && pkg.mDexOptPerformed.contains(dexCodeInstructionSet)) { 4641 continue; 4642 } 4643 4644 for (String path : paths) { 4645 try { 4646 // This will return DEXOPT_NEEDED if we either cannot find any odex file for this 4647 // patckage or the one we find does not match the image checksum (i.e. it was 4648 // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a 4649 // odex file and it matches the checksum of the image but not its base address, 4650 // meaning we need to move it. 4651 final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path, 4652 pkg.packageName, dexCodeInstructionSet, defer); 4653 if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) { 4654 Log.i(TAG, "Running dexopt on: " + path + " pkg=" 4655 + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet); 4656 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4657 final int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg), 4658 pkg.packageName, dexCodeInstructionSet); 4659 4660 if (ret < 0) { 4661 // Don't bother running dexopt again if we failed, it will probably 4662 // just result in an error again. Also, don't bother dexopting for other 4663 // paths & ISAs. 4664 return DEX_OPT_FAILED; 4665 } 4666 4667 performedDexOpt = true; 4668 } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) { 4669 Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName); 4670 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4671 final int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg), 4672 pkg.packageName, dexCodeInstructionSet); 4673 4674 if (ret < 0) { 4675 // Don't bother running patchoat again if we failed, it will probably 4676 // just result in an error again. Also, don't bother dexopting for other 4677 // paths & ISAs. 4678 return DEX_OPT_FAILED; 4679 } 4680 4681 performedDexOpt = true; 4682 } 4683 4684 // We're deciding to defer a needed dexopt. Don't bother dexopting for other 4685 // paths and instruction sets. We'll deal with them all together when we process 4686 // our list of deferred dexopts. 4687 if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) { 4688 if (mDeferredDexOpt == null) { 4689 mDeferredDexOpt = new HashSet<PackageParser.Package>(); 4690 } 4691 mDeferredDexOpt.add(pkg); 4692 return DEX_OPT_DEFERRED; 4693 } 4694 } catch (FileNotFoundException e) { 4695 Slog.w(TAG, "Apk not found for dexopt: " + path); 4696 return DEX_OPT_FAILED; 4697 } catch (IOException e) { 4698 Slog.w(TAG, "IOException reading apk: " + path, e); 4699 return DEX_OPT_FAILED; 4700 } catch (StaleDexCacheError e) { 4701 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e); 4702 return DEX_OPT_FAILED; 4703 } catch (Exception e) { 4704 Slog.w(TAG, "Exception when doing dexopt : ", e); 4705 return DEX_OPT_FAILED; 4706 } 4707 } 4708 4709 // At this point we haven't failed dexopt and we haven't deferred dexopt. We must 4710 // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us 4711 // it isn't required. We therefore mark that this package doesn't need dexopt unless 4712 // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped 4713 // it. 4714 pkg.mDexOptPerformed.add(dexCodeInstructionSet); 4715 } 4716 4717 // If we've gotten here, we're sure that no error occurred and that we haven't 4718 // deferred dex-opt. We've either dex-opted one more paths or instruction sets or 4719 // we've skipped all of them because they are up to date. In both cases this 4720 // package doesn't need dexopt any longer. 4721 return performedDexOpt ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED; 4722 } 4723 4724 private static String[] getAppDexInstructionSets(ApplicationInfo info) { 4725 if (info.primaryCpuAbi != null) { 4726 if (info.secondaryCpuAbi != null) { 4727 return new String[] { 4728 VMRuntime.getInstructionSet(info.primaryCpuAbi), 4729 VMRuntime.getInstructionSet(info.secondaryCpuAbi) }; 4730 } else { 4731 return new String[] { 4732 VMRuntime.getInstructionSet(info.primaryCpuAbi) }; 4733 } 4734 } 4735 4736 return new String[] { getPreferredInstructionSet() }; 4737 } 4738 4739 private static String[] getAppDexInstructionSets(PackageSetting ps) { 4740 if (ps.primaryCpuAbiString != null) { 4741 if (ps.secondaryCpuAbiString != null) { 4742 return new String[] { 4743 VMRuntime.getInstructionSet(ps.primaryCpuAbiString), 4744 VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) }; 4745 } else { 4746 return new String[] { 4747 VMRuntime.getInstructionSet(ps.primaryCpuAbiString) }; 4748 } 4749 } 4750 4751 return new String[] { getPreferredInstructionSet() }; 4752 } 4753 4754 private static String getPreferredInstructionSet() { 4755 if (sPreferredInstructionSet == null) { 4756 sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]); 4757 } 4758 4759 return sPreferredInstructionSet; 4760 } 4761 4762 private static List<String> getAllInstructionSets() { 4763 final String[] allAbis = Build.SUPPORTED_ABIS; 4764 final List<String> allInstructionSets = new ArrayList<String>(allAbis.length); 4765 4766 for (String abi : allAbis) { 4767 final String instructionSet = VMRuntime.getInstructionSet(abi); 4768 if (!allInstructionSets.contains(instructionSet)) { 4769 allInstructionSets.add(instructionSet); 4770 } 4771 } 4772 4773 return allInstructionSets; 4774 } 4775 4776 /** 4777 * Returns the instruction set that should be used to compile dex code. In the presence of 4778 * a native bridge this might be different than the one shared libraries use. 4779 */ 4780 private static String getDexCodeInstructionSet(String sharedLibraryIsa) { 4781 String dexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + sharedLibraryIsa); 4782 return (dexCodeIsa.isEmpty() ? sharedLibraryIsa : dexCodeIsa); 4783 } 4784 4785 private static String[] getDexCodeInstructionSets(String[] instructionSets) { 4786 HashSet<String> dexCodeInstructionSets = new HashSet<String>(instructionSets.length); 4787 for (String instructionSet : instructionSets) { 4788 dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet)); 4789 } 4790 return dexCodeInstructionSets.toArray(new String[dexCodeInstructionSets.size()]); 4791 } 4792 4793 @Override 4794 public void forceDexOpt(String packageName) { 4795 enforceSystemOrRoot("forceDexOpt"); 4796 4797 PackageParser.Package pkg; 4798 synchronized (mPackages) { 4799 pkg = mPackages.get(packageName); 4800 if (pkg == null) { 4801 throw new IllegalArgumentException("Missing package: " + packageName); 4802 } 4803 } 4804 4805 synchronized (mInstallLock) { 4806 final String[] instructionSets = new String[] { 4807 getPrimaryInstructionSet(pkg.applicationInfo) }; 4808 final int res = performDexOptLI(pkg, instructionSets, true, false, true); 4809 if (res != DEX_OPT_PERFORMED) { 4810 throw new IllegalStateException("Failed to dexopt: " + res); 4811 } 4812 } 4813 } 4814 4815 private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets, 4816 boolean forceDex, boolean defer, boolean inclDependencies) { 4817 HashSet<String> done; 4818 if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) { 4819 done = new HashSet<String>(); 4820 done.add(pkg.packageName); 4821 } else { 4822 done = null; 4823 } 4824 return performDexOptLI(pkg, instructionSets, forceDex, defer, done); 4825 } 4826 4827 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 4828 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 4829 Slog.w(TAG, "Unable to update from " + oldPkg.name 4830 + " to " + newPkg.packageName 4831 + ": old package not in system partition"); 4832 return false; 4833 } else if (mPackages.get(oldPkg.name) != null) { 4834 Slog.w(TAG, "Unable to update from " + oldPkg.name 4835 + " to " + newPkg.packageName 4836 + ": old package still exists"); 4837 return false; 4838 } 4839 return true; 4840 } 4841 4842 File getDataPathForUser(int userId) { 4843 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId); 4844 } 4845 4846 private File getDataPathForPackage(String packageName, int userId) { 4847 /* 4848 * Until we fully support multiple users, return the directory we 4849 * previously would have. The PackageManagerTests will need to be 4850 * revised when this is changed back.. 4851 */ 4852 if (userId == 0) { 4853 return new File(mAppDataDir, packageName); 4854 } else { 4855 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId 4856 + File.separator + packageName); 4857 } 4858 } 4859 4860 private int createDataDirsLI(String packageName, int uid, String seinfo) { 4861 int[] users = sUserManager.getUserIds(); 4862 int res = mInstaller.install(packageName, uid, uid, seinfo); 4863 if (res < 0) { 4864 return res; 4865 } 4866 for (int user : users) { 4867 if (user != 0) { 4868 res = mInstaller.createUserData(packageName, 4869 UserHandle.getUid(user, uid), user, seinfo); 4870 if (res < 0) { 4871 return res; 4872 } 4873 } 4874 } 4875 return res; 4876 } 4877 4878 private int removeDataDirsLI(String packageName) { 4879 int[] users = sUserManager.getUserIds(); 4880 int res = 0; 4881 for (int user : users) { 4882 int resInner = mInstaller.remove(packageName, user); 4883 if (resInner < 0) { 4884 res = resInner; 4885 } 4886 } 4887 4888 return res; 4889 } 4890 4891 private int deleteCodeCacheDirsLI(String packageName) { 4892 int[] users = sUserManager.getUserIds(); 4893 int res = 0; 4894 for (int user : users) { 4895 int resInner = mInstaller.deleteCodeCacheFiles(packageName, user); 4896 if (resInner < 0) { 4897 res = resInner; 4898 } 4899 } 4900 return res; 4901 } 4902 4903 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 4904 PackageParser.Package changingLib) { 4905 if (file.path != null) { 4906 usesLibraryFiles.add(file.path); 4907 return; 4908 } 4909 PackageParser.Package p = mPackages.get(file.apk); 4910 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 4911 // If we are doing this while in the middle of updating a library apk, 4912 // then we need to make sure to use that new apk for determining the 4913 // dependencies here. (We haven't yet finished committing the new apk 4914 // to the package manager state.) 4915 if (p == null || p.packageName.equals(changingLib.packageName)) { 4916 p = changingLib; 4917 } 4918 } 4919 if (p != null) { 4920 usesLibraryFiles.addAll(p.getAllCodePaths()); 4921 } 4922 } 4923 4924 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 4925 PackageParser.Package changingLib) throws PackageManagerException { 4926 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 4927 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 4928 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 4929 for (int i=0; i<N; i++) { 4930 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 4931 if (file == null) { 4932 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 4933 "Package " + pkg.packageName + " requires unavailable shared library " 4934 + pkg.usesLibraries.get(i) + "; failing!"); 4935 } 4936 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 4937 } 4938 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 4939 for (int i=0; i<N; i++) { 4940 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 4941 if (file == null) { 4942 Slog.w(TAG, "Package " + pkg.packageName 4943 + " desires unavailable shared library " 4944 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 4945 } else { 4946 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 4947 } 4948 } 4949 N = usesLibraryFiles.size(); 4950 if (N > 0) { 4951 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 4952 } else { 4953 pkg.usesLibraryFiles = null; 4954 } 4955 } 4956 } 4957 4958 private static boolean hasString(List<String> list, List<String> which) { 4959 if (list == null) { 4960 return false; 4961 } 4962 for (int i=list.size()-1; i>=0; i--) { 4963 for (int j=which.size()-1; j>=0; j--) { 4964 if (which.get(j).equals(list.get(i))) { 4965 return true; 4966 } 4967 } 4968 } 4969 return false; 4970 } 4971 4972 private void updateAllSharedLibrariesLPw() { 4973 for (PackageParser.Package pkg : mPackages.values()) { 4974 try { 4975 updateSharedLibrariesLPw(pkg, null); 4976 } catch (PackageManagerException e) { 4977 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 4978 } 4979 } 4980 } 4981 4982 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 4983 PackageParser.Package changingPkg) { 4984 ArrayList<PackageParser.Package> res = null; 4985 for (PackageParser.Package pkg : mPackages.values()) { 4986 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 4987 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 4988 if (res == null) { 4989 res = new ArrayList<PackageParser.Package>(); 4990 } 4991 res.add(pkg); 4992 try { 4993 updateSharedLibrariesLPw(pkg, changingPkg); 4994 } catch (PackageManagerException e) { 4995 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 4996 } 4997 } 4998 } 4999 return res; 5000 } 5001 5002 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 5003 int scanMode, long currentTime, UserHandle user, String abiOverride) 5004 throws PackageManagerException { 5005 final File scanFile = new File(pkg.codePath); 5006 if (pkg.applicationInfo.getCodePath() == null || 5007 pkg.applicationInfo.getResourcePath() == null) { 5008 // Bail out. The resource and code paths haven't been set. 5009 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 5010 "Code and resource paths haven't been set correctly"); 5011 } 5012 5013 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 5014 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 5015 } 5016 5017 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 5018 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED; 5019 } 5020 5021 if (mCustomResolverComponentName != null && 5022 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 5023 setUpCustomResolverActivity(pkg); 5024 } 5025 5026 if (pkg.packageName.equals("android")) { 5027 synchronized (mPackages) { 5028 if (mAndroidApplication != null) { 5029 Slog.w(TAG, "*************************************************"); 5030 Slog.w(TAG, "Core android package being redefined. Skipping."); 5031 Slog.w(TAG, " file=" + scanFile); 5032 Slog.w(TAG, "*************************************************"); 5033 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5034 "Core android package being redefined. Skipping."); 5035 } 5036 5037 // Set up information for our fall-back user intent resolution activity. 5038 mPlatformPackage = pkg; 5039 pkg.mVersionCode = mSdkVersion; 5040 mAndroidApplication = pkg.applicationInfo; 5041 5042 if (!mResolverReplaced) { 5043 mResolveActivity.applicationInfo = mAndroidApplication; 5044 mResolveActivity.name = ResolverActivity.class.getName(); 5045 mResolveActivity.packageName = mAndroidApplication.packageName; 5046 mResolveActivity.processName = "system:ui"; 5047 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 5048 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 5049 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 5050 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 5051 mResolveActivity.exported = true; 5052 mResolveActivity.enabled = true; 5053 mResolveInfo.activityInfo = mResolveActivity; 5054 mResolveInfo.priority = 0; 5055 mResolveInfo.preferredOrder = 0; 5056 mResolveInfo.match = 0; 5057 mResolveComponentName = new ComponentName( 5058 mAndroidApplication.packageName, mResolveActivity.name); 5059 } 5060 } 5061 } 5062 5063 if (DEBUG_PACKAGE_SCANNING) { 5064 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5065 Log.d(TAG, "Scanning package " + pkg.packageName); 5066 } 5067 5068 if (mPackages.containsKey(pkg.packageName) 5069 || mSharedLibraries.containsKey(pkg.packageName)) { 5070 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 5071 "Application package " + pkg.packageName 5072 + " already installed. Skipping duplicate."); 5073 } 5074 5075 // Initialize package source and resource directories 5076 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 5077 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 5078 5079 SharedUserSetting suid = null; 5080 PackageSetting pkgSetting = null; 5081 5082 if (!isSystemApp(pkg)) { 5083 // Only system apps can use these features. 5084 pkg.mOriginalPackages = null; 5085 pkg.mRealPackage = null; 5086 pkg.mAdoptPermissions = null; 5087 } 5088 5089 // writer 5090 synchronized (mPackages) { 5091 if (pkg.mSharedUserId != null) { 5092 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true); 5093 if (suid == null) { 5094 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5095 "Creating application package " + pkg.packageName 5096 + " for shared user failed"); 5097 } 5098 if (DEBUG_PACKAGE_SCANNING) { 5099 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5100 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 5101 + "): packages=" + suid.packages); 5102 } 5103 } 5104 5105 // Check if we are renaming from an original package name. 5106 PackageSetting origPackage = null; 5107 String realName = null; 5108 if (pkg.mOriginalPackages != null) { 5109 // This package may need to be renamed to a previously 5110 // installed name. Let's check on that... 5111 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 5112 if (pkg.mOriginalPackages.contains(renamed)) { 5113 // This package had originally been installed as the 5114 // original name, and we have already taken care of 5115 // transitioning to the new one. Just update the new 5116 // one to continue using the old name. 5117 realName = pkg.mRealPackage; 5118 if (!pkg.packageName.equals(renamed)) { 5119 // Callers into this function may have already taken 5120 // care of renaming the package; only do it here if 5121 // it is not already done. 5122 pkg.setPackageName(renamed); 5123 } 5124 5125 } else { 5126 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 5127 if ((origPackage = mSettings.peekPackageLPr( 5128 pkg.mOriginalPackages.get(i))) != null) { 5129 // We do have the package already installed under its 5130 // original name... should we use it? 5131 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 5132 // New package is not compatible with original. 5133 origPackage = null; 5134 continue; 5135 } else if (origPackage.sharedUser != null) { 5136 // Make sure uid is compatible between packages. 5137 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 5138 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 5139 + " to " + pkg.packageName + ": old uid " 5140 + origPackage.sharedUser.name 5141 + " differs from " + pkg.mSharedUserId); 5142 origPackage = null; 5143 continue; 5144 } 5145 } else { 5146 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 5147 + pkg.packageName + " to old name " + origPackage.name); 5148 } 5149 break; 5150 } 5151 } 5152 } 5153 } 5154 5155 if (mTransferedPackages.contains(pkg.packageName)) { 5156 Slog.w(TAG, "Package " + pkg.packageName 5157 + " was transferred to another, but its .apk remains"); 5158 } 5159 5160 // Just create the setting, don't add it yet. For already existing packages 5161 // the PkgSetting exists already and doesn't have to be created. 5162 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 5163 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 5164 pkg.applicationInfo.primaryCpuAbi, 5165 pkg.applicationInfo.secondaryCpuAbi, 5166 pkg.applicationInfo.flags, user, false); 5167 if (pkgSetting == null) { 5168 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5169 "Creating application package " + pkg.packageName + " failed"); 5170 } 5171 5172 if (pkgSetting.origPackage != null) { 5173 // If we are first transitioning from an original package, 5174 // fix up the new package's name now. We need to do this after 5175 // looking up the package under its new name, so getPackageLP 5176 // can take care of fiddling things correctly. 5177 pkg.setPackageName(origPackage.name); 5178 5179 // File a report about this. 5180 String msg = "New package " + pkgSetting.realName 5181 + " renamed to replace old package " + pkgSetting.name; 5182 reportSettingsProblem(Log.WARN, msg); 5183 5184 // Make a note of it. 5185 mTransferedPackages.add(origPackage.name); 5186 5187 // No longer need to retain this. 5188 pkgSetting.origPackage = null; 5189 } 5190 5191 if (realName != null) { 5192 // Make a note of it. 5193 mTransferedPackages.add(pkg.packageName); 5194 } 5195 5196 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 5197 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 5198 } 5199 5200 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5201 // Check all shared libraries and map to their actual file path. 5202 // We only do this here for apps not on a system dir, because those 5203 // are the only ones that can fail an install due to this. We 5204 // will take care of the system apps by updating all of their 5205 // library paths after the scan is done. 5206 updateSharedLibrariesLPw(pkg, null); 5207 } 5208 5209 if (mFoundPolicyFile) { 5210 SELinuxMMAC.assignSeinfoValue(pkg); 5211 } 5212 5213 pkg.applicationInfo.uid = pkgSetting.appId; 5214 pkg.mExtras = pkgSetting; 5215 if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) { 5216 try { 5217 verifySignaturesLP(pkgSetting, pkg); 5218 } catch (PackageManagerException e) { 5219 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 5220 throw e; 5221 } 5222 // The signature has changed, but this package is in the system 5223 // image... let's recover! 5224 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5225 // However... if this package is part of a shared user, but it 5226 // doesn't match the signature of the shared user, let's fail. 5227 // What this means is that you can't change the signatures 5228 // associated with an overall shared user, which doesn't seem all 5229 // that unreasonable. 5230 if (pkgSetting.sharedUser != null) { 5231 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 5232 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 5233 throw new PackageManagerException( 5234 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 5235 "Signature mismatch for shared user : " 5236 + pkgSetting.sharedUser); 5237 } 5238 } 5239 // File a report about this. 5240 String msg = "System package " + pkg.packageName 5241 + " signature changed; retaining data."; 5242 reportSettingsProblem(Log.WARN, msg); 5243 } 5244 } else { 5245 if (!checkUpgradeKeySetLP(pkgSetting, pkg)) { 5246 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 5247 + pkg.packageName + " upgrade keys do not match the " 5248 + "previously installed version"); 5249 } else { 5250 // signatures may have changed as result of upgrade 5251 pkgSetting.signatures.mSignatures = pkg.mSignatures; 5252 } 5253 } 5254 // Verify that this new package doesn't have any content providers 5255 // that conflict with existing packages. Only do this if the 5256 // package isn't already installed, since we don't want to break 5257 // things that are installed. 5258 if ((scanMode&SCAN_NEW_INSTALL) != 0) { 5259 final int N = pkg.providers.size(); 5260 int i; 5261 for (i=0; i<N; i++) { 5262 PackageParser.Provider p = pkg.providers.get(i); 5263 if (p.info.authority != null) { 5264 String names[] = p.info.authority.split(";"); 5265 for (int j = 0; j < names.length; j++) { 5266 if (mProvidersByAuthority.containsKey(names[j])) { 5267 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 5268 final String otherPackageName = 5269 ((other != null && other.getComponentName() != null) ? 5270 other.getComponentName().getPackageName() : "?"); 5271 throw new PackageManagerException( 5272 INSTALL_FAILED_CONFLICTING_PROVIDER, 5273 "Can't install because provider name " + names[j] 5274 + " (in package " + pkg.applicationInfo.packageName 5275 + ") is already used by " + otherPackageName); 5276 } 5277 } 5278 } 5279 } 5280 } 5281 5282 if (pkg.mAdoptPermissions != null) { 5283 // This package wants to adopt ownership of permissions from 5284 // another package. 5285 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 5286 final String origName = pkg.mAdoptPermissions.get(i); 5287 final PackageSetting orig = mSettings.peekPackageLPr(origName); 5288 if (orig != null) { 5289 if (verifyPackageUpdateLPr(orig, pkg)) { 5290 Slog.i(TAG, "Adopting permissions from " + origName + " to " 5291 + pkg.packageName); 5292 mSettings.transferPermissionsLPw(origName, pkg.packageName); 5293 } 5294 } 5295 } 5296 } 5297 } 5298 5299 final String pkgName = pkg.packageName; 5300 5301 final long scanFileTime = scanFile.lastModified(); 5302 final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0; 5303 pkg.applicationInfo.processName = fixProcessName( 5304 pkg.applicationInfo.packageName, 5305 pkg.applicationInfo.processName, 5306 pkg.applicationInfo.uid); 5307 5308 File dataPath; 5309 if (mPlatformPackage == pkg) { 5310 // The system package is special. 5311 dataPath = new File (Environment.getDataDirectory(), "system"); 5312 pkg.applicationInfo.dataDir = dataPath.getPath(); 5313 5314 } else { 5315 // This is a normal package, need to make its data directory. 5316 dataPath = getDataPathForPackage(pkg.packageName, 0); 5317 5318 boolean uidError = false; 5319 5320 if (dataPath.exists()) { 5321 int currentUid = 0; 5322 try { 5323 StructStat stat = Os.stat(dataPath.getPath()); 5324 currentUid = stat.st_uid; 5325 } catch (ErrnoException e) { 5326 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 5327 } 5328 5329 // If we have mismatched owners for the data path, we have a problem. 5330 if (currentUid != pkg.applicationInfo.uid) { 5331 boolean recovered = false; 5332 if (currentUid == 0) { 5333 // The directory somehow became owned by root. Wow. 5334 // This is probably because the system was stopped while 5335 // installd was in the middle of messing with its libs 5336 // directory. Ask installd to fix that. 5337 int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid, 5338 pkg.applicationInfo.uid); 5339 if (ret >= 0) { 5340 recovered = true; 5341 String msg = "Package " + pkg.packageName 5342 + " unexpectedly changed to uid 0; recovered to " + 5343 + pkg.applicationInfo.uid; 5344 reportSettingsProblem(Log.WARN, msg); 5345 } 5346 } 5347 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 5348 || (scanMode&SCAN_BOOTING) != 0)) { 5349 // If this is a system app, we can at least delete its 5350 // current data so the application will still work. 5351 int ret = removeDataDirsLI(pkgName); 5352 if (ret >= 0) { 5353 // TODO: Kill the processes first 5354 // Old data gone! 5355 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 5356 ? "System package " : "Third party package "; 5357 String msg = prefix + pkg.packageName 5358 + " has changed from uid: " 5359 + currentUid + " to " 5360 + pkg.applicationInfo.uid + "; old data erased"; 5361 reportSettingsProblem(Log.WARN, msg); 5362 recovered = true; 5363 5364 // And now re-install the app. 5365 ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 5366 pkg.applicationInfo.seinfo); 5367 if (ret == -1) { 5368 // Ack should not happen! 5369 msg = prefix + pkg.packageName 5370 + " could not have data directory re-created after delete."; 5371 reportSettingsProblem(Log.WARN, msg); 5372 throw new PackageManagerException( 5373 INSTALL_FAILED_INSUFFICIENT_STORAGE, msg); 5374 } 5375 } 5376 if (!recovered) { 5377 mHasSystemUidErrors = true; 5378 } 5379 } else if (!recovered) { 5380 // If we allow this install to proceed, we will be broken. 5381 // Abort, abort! 5382 throw new PackageManagerException(INSTALL_FAILED_UID_CHANGED, 5383 "scanPackageLI"); 5384 } 5385 if (!recovered) { 5386 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 5387 + pkg.applicationInfo.uid + "/fs_" 5388 + currentUid; 5389 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 5390 pkg.applicationInfo.nativeLibraryRootDir = pkg.applicationInfo.dataDir; 5391 String msg = "Package " + pkg.packageName 5392 + " has mismatched uid: " 5393 + currentUid + " on disk, " 5394 + pkg.applicationInfo.uid + " in settings"; 5395 // writer 5396 synchronized (mPackages) { 5397 mSettings.mReadMessages.append(msg); 5398 mSettings.mReadMessages.append('\n'); 5399 uidError = true; 5400 if (!pkgSetting.uidError) { 5401 reportSettingsProblem(Log.ERROR, msg); 5402 } 5403 } 5404 } 5405 } 5406 pkg.applicationInfo.dataDir = dataPath.getPath(); 5407 if (mShouldRestoreconData) { 5408 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 5409 mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo, 5410 pkg.applicationInfo.uid); 5411 } 5412 } else { 5413 if (DEBUG_PACKAGE_SCANNING) { 5414 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5415 Log.v(TAG, "Want this data dir: " + dataPath); 5416 } 5417 //invoke installer to do the actual installation 5418 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 5419 pkg.applicationInfo.seinfo); 5420 if (ret < 0) { 5421 // Error from installer 5422 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 5423 "Unable to create data dirs [errorCode=" + ret + "]"); 5424 } 5425 5426 if (dataPath.exists()) { 5427 pkg.applicationInfo.dataDir = dataPath.getPath(); 5428 } else { 5429 Slog.w(TAG, "Unable to create data directory: " + dataPath); 5430 pkg.applicationInfo.dataDir = null; 5431 } 5432 } 5433 5434 pkgSetting.uidError = uidError; 5435 } 5436 5437 final String path = scanFile.getPath(); 5438 final String codePath = pkg.applicationInfo.getCodePath(); 5439 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { 5440 // For the case where we had previously uninstalled an update, get rid 5441 // of any native binaries we might have unpackaged. Note that this assumes 5442 // that system app updates were not installed via ASEC. 5443 // 5444 // TODO(multiArch): Is this cleanup really necessary ? 5445 NativeLibraryHelper.removeNativeBinariesFromDirLI( 5446 new File(codePath, LIB_DIR_NAME), false /* delete dirs */); 5447 setBundledAppAbisAndRoots(pkg, pkgSetting); 5448 5449 // If we haven't found any native libraries for the app, check if it has 5450 // renderscript code. We'll need to force the app to 32 bit if it has 5451 // renderscript bitcode. 5452 if (pkg.applicationInfo.primaryCpuAbi == null 5453 && pkg.applicationInfo.secondaryCpuAbi == null 5454 && Build.SUPPORTED_64_BIT_ABIS.length > 0) { 5455 NativeLibraryHelper.Handle handle = null; 5456 try { 5457 handle = NativeLibraryHelper.Handle.create(scanFile); 5458 if (NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 5459 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 5460 } 5461 } catch (IOException ioe) { 5462 Slog.w(TAG, "Error scanning system app : " + ioe); 5463 } finally { 5464 IoUtils.closeQuietly(handle); 5465 } 5466 } 5467 5468 setNativeLibraryPaths(pkg); 5469 } else { 5470 // TODO: We can probably be smarter about this stuff. For installed apps, 5471 // we can calculate this information at install time once and for all. For 5472 // system apps, we can probably assume that this information doesn't change 5473 // after the first boot scan. As things stand, we do lots of unnecessary work. 5474 5475 // Give ourselves some initial paths; we'll come back for another 5476 // pass once we've determined ABI below. 5477 setNativeLibraryPaths(pkg); 5478 5479 final boolean isAsec = isForwardLocked(pkg) || isExternal(pkg); 5480 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 5481 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 5482 5483 NativeLibraryHelper.Handle handle = null; 5484 try { 5485 handle = NativeLibraryHelper.Handle.create(scanFile); 5486 // TODO(multiArch): This can be null for apps that didn't go through the 5487 // usual installation process. We can calculate it again, like we 5488 // do during install time. 5489 // 5490 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 5491 // unnecessary. 5492 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 5493 5494 // Null out the abis so that they can be recalculated. 5495 pkg.applicationInfo.primaryCpuAbi = null; 5496 pkg.applicationInfo.secondaryCpuAbi = null; 5497 if (isMultiArch(pkg.applicationInfo)) { 5498 // Warn if we've set an abiOverride for multi-lib packages.. 5499 // By definition, we need to copy both 32 and 64 bit libraries for 5500 // such packages. 5501 if (abiOverride != null) { 5502 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 5503 } 5504 5505 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 5506 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 5507 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 5508 if (isAsec) { 5509 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 5510 } else { 5511 abi32 = copyNativeLibrariesForInternalApp(handle, 5512 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, useIsaSpecificSubdirs); 5513 } 5514 } 5515 5516 maybeThrowExceptionForMultiArchCopy( 5517 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 5518 5519 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 5520 if (isAsec) { 5521 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 5522 } else { 5523 abi64 = copyNativeLibrariesForInternalApp(handle, 5524 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, useIsaSpecificSubdirs); 5525 } 5526 } 5527 5528 maybeThrowExceptionForMultiArchCopy( 5529 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 5530 5531 if (abi64 >= 0) { 5532 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 5533 } 5534 5535 if (abi32 >= 0) { 5536 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 5537 if (abi64 >= 0) { 5538 pkg.applicationInfo.secondaryCpuAbi = abi; 5539 } else { 5540 pkg.applicationInfo.primaryCpuAbi = abi; 5541 } 5542 } 5543 } else { 5544 String[] abiList = (abiOverride != null) ? 5545 new String[] { abiOverride } : Build.SUPPORTED_ABIS; 5546 5547 // Enable gross and lame hacks for apps that are built with old 5548 // SDK tools. We must scan their APKs for renderscript bitcode and 5549 // not launch them if it's present. Don't bother checking on devices 5550 // that don't have 64 bit support. 5551 boolean needsRenderScriptOverride = false; 5552 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && abiOverride == null && 5553 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 5554 abiList = Build.SUPPORTED_32_BIT_ABIS; 5555 needsRenderScriptOverride = true; 5556 } 5557 5558 final int copyRet; 5559 if (isAsec) { 5560 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 5561 } else { 5562 copyRet = copyNativeLibrariesForInternalApp(handle, nativeLibraryRoot, abiList, 5563 useIsaSpecificSubdirs); 5564 } 5565 5566 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 5567 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 5568 "Error unpackaging native libs for app, errorCode=" + copyRet); 5569 } 5570 5571 if (copyRet >= 0) { 5572 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 5573 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && abiOverride != null) { 5574 pkg.applicationInfo.primaryCpuAbi = abiOverride; 5575 } else if (needsRenderScriptOverride) { 5576 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 5577 } 5578 } 5579 } catch (IOException ioe) { 5580 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 5581 } finally { 5582 IoUtils.closeQuietly(handle); 5583 } 5584 5585 // Now that we've calculated the ABIs and determined if it's an internal app, 5586 // we will go ahead and populate the nativeLibraryPath. 5587 setNativeLibraryPaths(pkg); 5588 5589 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 5590 final int[] userIds = sUserManager.getUserIds(); 5591 synchronized (mInstallLock) { 5592 // Create a native library symlink only if we have native libraries 5593 // and if the native libraries are 32 bit libraries. We do not provide 5594 // this symlink for 64 bit libraries. 5595 if (pkg.applicationInfo.primaryCpuAbi != null && 5596 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 5597 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 5598 for (int userId : userIds) { 5599 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, nativeLibPath, userId) < 0) { 5600 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 5601 "Failed linking native library dir (user=" + userId + ")"); 5602 } 5603 } 5604 } 5605 } 5606 } 5607 5608 // This is a special case for the "system" package, where the ABI is 5609 // dictated by the zygote configuration (and init.rc). We should keep track 5610 // of this ABI so that we can deal with "normal" applications that run under 5611 // the same UID correctly. 5612 if (mPlatformPackage == pkg) { 5613 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 5614 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 5615 } 5616 5617 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 5618 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 5619 5620 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 5621 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 5622 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 5623 5624 // Push the derived path down into PackageSettings so we know what to 5625 // clean up at uninstall time. 5626 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 5627 5628 if (DEBUG_ABI_SELECTION) { 5629 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 5630 " primary=" + pkg.applicationInfo.primaryCpuAbi + 5631 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 5632 } 5633 5634 if ((scanMode&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 5635 // We don't do this here during boot because we can do it all 5636 // at once after scanning all existing packages. 5637 // 5638 // We also do this *before* we perform dexopt on this package, so that 5639 // we can avoid redundant dexopts, and also to make sure we've got the 5640 // code and package path correct. 5641 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 5642 pkg, forceDex, (scanMode & SCAN_DEFER_DEX) != 0); 5643 } 5644 5645 if ((scanMode&SCAN_NO_DEX) == 0) { 5646 if (performDexOptLI(pkg, null /* instruction sets */, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false) 5647 == DEX_OPT_FAILED) { 5648 if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5649 removeDataDirsLI(pkg.packageName); 5650 } 5651 5652 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); 5653 } 5654 } 5655 5656 if (mFactoryTest && pkg.requestedPermissions.contains( 5657 android.Manifest.permission.FACTORY_TEST)) { 5658 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 5659 } 5660 5661 ArrayList<PackageParser.Package> clientLibPkgs = null; 5662 5663 // writer 5664 synchronized (mPackages) { 5665 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 5666 // Only system apps can add new shared libraries. 5667 if (pkg.libraryNames != null) { 5668 for (int i=0; i<pkg.libraryNames.size(); i++) { 5669 String name = pkg.libraryNames.get(i); 5670 boolean allowed = false; 5671 if (isUpdatedSystemApp(pkg)) { 5672 // New library entries can only be added through the 5673 // system image. This is important to get rid of a lot 5674 // of nasty edge cases: for example if we allowed a non- 5675 // system update of the app to add a library, then uninstalling 5676 // the update would make the library go away, and assumptions 5677 // we made such as through app install filtering would now 5678 // have allowed apps on the device which aren't compatible 5679 // with it. Better to just have the restriction here, be 5680 // conservative, and create many fewer cases that can negatively 5681 // impact the user experience. 5682 final PackageSetting sysPs = mSettings 5683 .getDisabledSystemPkgLPr(pkg.packageName); 5684 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 5685 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 5686 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 5687 allowed = true; 5688 allowed = true; 5689 break; 5690 } 5691 } 5692 } 5693 } else { 5694 allowed = true; 5695 } 5696 if (allowed) { 5697 if (!mSharedLibraries.containsKey(name)) { 5698 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 5699 } else if (!name.equals(pkg.packageName)) { 5700 Slog.w(TAG, "Package " + pkg.packageName + " library " 5701 + name + " already exists; skipping"); 5702 } 5703 } else { 5704 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 5705 + name + " that is not declared on system image; skipping"); 5706 } 5707 } 5708 if ((scanMode&SCAN_BOOTING) == 0) { 5709 // If we are not booting, we need to update any applications 5710 // that are clients of our shared library. If we are booting, 5711 // this will all be done once the scan is complete. 5712 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 5713 } 5714 } 5715 } 5716 } 5717 5718 // We also need to dexopt any apps that are dependent on this library. Note that 5719 // if these fail, we should abort the install since installing the library will 5720 // result in some apps being broken. 5721 if (clientLibPkgs != null) { 5722 if ((scanMode&SCAN_NO_DEX) == 0) { 5723 for (int i=0; i<clientLibPkgs.size(); i++) { 5724 PackageParser.Package clientPkg = clientLibPkgs.get(i); 5725 if (performDexOptLI(clientPkg, null /* instruction sets */, 5726 forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false) 5727 == DEX_OPT_FAILED) { 5728 if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5729 removeDataDirsLI(pkg.packageName); 5730 } 5731 5732 throw new PackageManagerException(INSTALL_FAILED_DEXOPT, 5733 "scanPackageLI failed to dexopt clientLibPkgs"); 5734 } 5735 } 5736 } 5737 } 5738 5739 // Request the ActivityManager to kill the process(only for existing packages) 5740 // so that we do not end up in a confused state while the user is still using the older 5741 // version of the application while the new one gets installed. 5742 if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 5743 // If the package lives in an asec, tell everyone that the container is going 5744 // away so they can clean up any references to its resources (which would prevent 5745 // vold from being able to unmount the asec) 5746 if (isForwardLocked(pkg) || isExternal(pkg)) { 5747 if (DEBUG_INSTALL) { 5748 Slog.i(TAG, "upgrading pkg " + pkg + " is ASEC-hosted -> UNAVAILABLE"); 5749 } 5750 final int[] uidArray = new int[] { pkg.applicationInfo.uid }; 5751 final ArrayList<String> pkgList = new ArrayList<String>(1); 5752 pkgList.add(pkg.applicationInfo.packageName); 5753 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 5754 } 5755 5756 // Post the request that it be killed now that the going-away broadcast is en route 5757 killApplication(pkg.applicationInfo.packageName, 5758 pkg.applicationInfo.uid, "update pkg"); 5759 } 5760 5761 // Also need to kill any apps that are dependent on the library. 5762 if (clientLibPkgs != null) { 5763 for (int i=0; i<clientLibPkgs.size(); i++) { 5764 PackageParser.Package clientPkg = clientLibPkgs.get(i); 5765 killApplication(clientPkg.applicationInfo.packageName, 5766 clientPkg.applicationInfo.uid, "update lib"); 5767 } 5768 } 5769 5770 // writer 5771 synchronized (mPackages) { 5772 // We don't expect installation to fail beyond this point, 5773 if ((scanMode&SCAN_MONITOR) != 0) { 5774 mAppDirs.put(pkg.codePath, pkg); 5775 } 5776 // Add the new setting to mSettings 5777 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 5778 // Add the new setting to mPackages 5779 mPackages.put(pkg.applicationInfo.packageName, pkg); 5780 // Make sure we don't accidentally delete its data. 5781 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 5782 while (iter.hasNext()) { 5783 PackageCleanItem item = iter.next(); 5784 if (pkgName.equals(item.packageName)) { 5785 iter.remove(); 5786 } 5787 } 5788 5789 // Take care of first install / last update times. 5790 if (currentTime != 0) { 5791 if (pkgSetting.firstInstallTime == 0) { 5792 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 5793 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) { 5794 pkgSetting.lastUpdateTime = currentTime; 5795 } 5796 } else if (pkgSetting.firstInstallTime == 0) { 5797 // We need *something*. Take time time stamp of the file. 5798 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 5799 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 5800 if (scanFileTime != pkgSetting.timeStamp) { 5801 // A package on the system image has changed; consider this 5802 // to be an update. 5803 pkgSetting.lastUpdateTime = scanFileTime; 5804 } 5805 } 5806 5807 // Add the package's KeySets to the global KeySetManagerService 5808 KeySetManagerService ksms = mSettings.mKeySetManagerService; 5809 try { 5810 // Old KeySetData no longer valid. 5811 ksms.removeAppKeySetDataLPw(pkg.packageName); 5812 ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys); 5813 if (pkg.mKeySetMapping != null) { 5814 for (Map.Entry<String, ArraySet<PublicKey>> entry : 5815 pkg.mKeySetMapping.entrySet()) { 5816 if (entry.getValue() != null) { 5817 ksms.addDefinedKeySetToPackageLPw(pkg.packageName, 5818 entry.getValue(), entry.getKey()); 5819 } 5820 } 5821 if (pkg.mUpgradeKeySets != null) { 5822 for (String upgradeAlias : pkg.mUpgradeKeySets) { 5823 ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias); 5824 } 5825 } 5826 } 5827 } catch (NullPointerException e) { 5828 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e); 5829 } catch (IllegalArgumentException e) { 5830 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e); 5831 } 5832 5833 int N = pkg.providers.size(); 5834 StringBuilder r = null; 5835 int i; 5836 for (i=0; i<N; i++) { 5837 PackageParser.Provider p = pkg.providers.get(i); 5838 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 5839 p.info.processName, pkg.applicationInfo.uid); 5840 mProviders.addProvider(p); 5841 p.syncable = p.info.isSyncable; 5842 if (p.info.authority != null) { 5843 String names[] = p.info.authority.split(";"); 5844 p.info.authority = null; 5845 for (int j = 0; j < names.length; j++) { 5846 if (j == 1 && p.syncable) { 5847 // We only want the first authority for a provider to possibly be 5848 // syncable, so if we already added this provider using a different 5849 // authority clear the syncable flag. We copy the provider before 5850 // changing it because the mProviders object contains a reference 5851 // to a provider that we don't want to change. 5852 // Only do this for the second authority since the resulting provider 5853 // object can be the same for all future authorities for this provider. 5854 p = new PackageParser.Provider(p); 5855 p.syncable = false; 5856 } 5857 if (!mProvidersByAuthority.containsKey(names[j])) { 5858 mProvidersByAuthority.put(names[j], p); 5859 if (p.info.authority == null) { 5860 p.info.authority = names[j]; 5861 } else { 5862 p.info.authority = p.info.authority + ";" + names[j]; 5863 } 5864 if (DEBUG_PACKAGE_SCANNING) { 5865 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5866 Log.d(TAG, "Registered content provider: " + names[j] 5867 + ", className = " + p.info.name + ", isSyncable = " 5868 + p.info.isSyncable); 5869 } 5870 } else { 5871 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 5872 Slog.w(TAG, "Skipping provider name " + names[j] + 5873 " (in package " + pkg.applicationInfo.packageName + 5874 "): name already used by " 5875 + ((other != null && other.getComponentName() != null) 5876 ? other.getComponentName().getPackageName() : "?")); 5877 } 5878 } 5879 } 5880 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5881 if (r == null) { 5882 r = new StringBuilder(256); 5883 } else { 5884 r.append(' '); 5885 } 5886 r.append(p.info.name); 5887 } 5888 } 5889 if (r != null) { 5890 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 5891 } 5892 5893 N = pkg.services.size(); 5894 r = null; 5895 for (i=0; i<N; i++) { 5896 PackageParser.Service s = pkg.services.get(i); 5897 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 5898 s.info.processName, pkg.applicationInfo.uid); 5899 mServices.addService(s); 5900 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5901 if (r == null) { 5902 r = new StringBuilder(256); 5903 } else { 5904 r.append(' '); 5905 } 5906 r.append(s.info.name); 5907 } 5908 } 5909 if (r != null) { 5910 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 5911 } 5912 5913 N = pkg.receivers.size(); 5914 r = null; 5915 for (i=0; i<N; i++) { 5916 PackageParser.Activity a = pkg.receivers.get(i); 5917 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 5918 a.info.processName, pkg.applicationInfo.uid); 5919 mReceivers.addActivity(a, "receiver"); 5920 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5921 if (r == null) { 5922 r = new StringBuilder(256); 5923 } else { 5924 r.append(' '); 5925 } 5926 r.append(a.info.name); 5927 } 5928 } 5929 if (r != null) { 5930 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 5931 } 5932 5933 N = pkg.activities.size(); 5934 r = null; 5935 for (i=0; i<N; i++) { 5936 PackageParser.Activity a = pkg.activities.get(i); 5937 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 5938 a.info.processName, pkg.applicationInfo.uid); 5939 mActivities.addActivity(a, "activity"); 5940 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5941 if (r == null) { 5942 r = new StringBuilder(256); 5943 } else { 5944 r.append(' '); 5945 } 5946 r.append(a.info.name); 5947 } 5948 } 5949 if (r != null) { 5950 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 5951 } 5952 5953 N = pkg.permissionGroups.size(); 5954 r = null; 5955 for (i=0; i<N; i++) { 5956 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 5957 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 5958 if (cur == null) { 5959 mPermissionGroups.put(pg.info.name, pg); 5960 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5961 if (r == null) { 5962 r = new StringBuilder(256); 5963 } else { 5964 r.append(' '); 5965 } 5966 r.append(pg.info.name); 5967 } 5968 } else { 5969 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 5970 + pg.info.packageName + " ignored: original from " 5971 + cur.info.packageName); 5972 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5973 if (r == null) { 5974 r = new StringBuilder(256); 5975 } else { 5976 r.append(' '); 5977 } 5978 r.append("DUP:"); 5979 r.append(pg.info.name); 5980 } 5981 } 5982 } 5983 if (r != null) { 5984 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 5985 } 5986 5987 N = pkg.permissions.size(); 5988 r = null; 5989 for (i=0; i<N; i++) { 5990 PackageParser.Permission p = pkg.permissions.get(i); 5991 HashMap<String, BasePermission> permissionMap = 5992 p.tree ? mSettings.mPermissionTrees 5993 : mSettings.mPermissions; 5994 p.group = mPermissionGroups.get(p.info.group); 5995 if (p.info.group == null || p.group != null) { 5996 BasePermission bp = permissionMap.get(p.info.name); 5997 if (bp == null) { 5998 bp = new BasePermission(p.info.name, p.info.packageName, 5999 BasePermission.TYPE_NORMAL); 6000 permissionMap.put(p.info.name, bp); 6001 } 6002 if (bp.perm == null) { 6003 if (bp.sourcePackage != null 6004 && !bp.sourcePackage.equals(p.info.packageName)) { 6005 // If this is a permission that was formerly defined by a non-system 6006 // app, but is now defined by a system app (following an upgrade), 6007 // discard the previous declaration and consider the system's to be 6008 // canonical. 6009 if (isSystemApp(p.owner)) { 6010 String msg = "New decl " + p.owner + " of permission " 6011 + p.info.name + " is system"; 6012 reportSettingsProblem(Log.WARN, msg); 6013 bp.sourcePackage = null; 6014 } 6015 } 6016 if (bp.sourcePackage == null 6017 || bp.sourcePackage.equals(p.info.packageName)) { 6018 BasePermission tree = findPermissionTreeLP(p.info.name); 6019 if (tree == null 6020 || tree.sourcePackage.equals(p.info.packageName)) { 6021 bp.packageSetting = pkgSetting; 6022 bp.perm = p; 6023 bp.uid = pkg.applicationInfo.uid; 6024 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6025 if (r == null) { 6026 r = new StringBuilder(256); 6027 } else { 6028 r.append(' '); 6029 } 6030 r.append(p.info.name); 6031 } 6032 } else { 6033 Slog.w(TAG, "Permission " + p.info.name + " from package " 6034 + p.info.packageName + " ignored: base tree " 6035 + tree.name + " is from package " 6036 + tree.sourcePackage); 6037 } 6038 } else { 6039 Slog.w(TAG, "Permission " + p.info.name + " from package " 6040 + p.info.packageName + " ignored: original from " 6041 + bp.sourcePackage); 6042 } 6043 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6044 if (r == null) { 6045 r = new StringBuilder(256); 6046 } else { 6047 r.append(' '); 6048 } 6049 r.append("DUP:"); 6050 r.append(p.info.name); 6051 } 6052 if (bp.perm == p) { 6053 bp.protectionLevel = p.info.protectionLevel; 6054 } 6055 } else { 6056 Slog.w(TAG, "Permission " + p.info.name + " from package " 6057 + p.info.packageName + " ignored: no group " 6058 + p.group); 6059 } 6060 } 6061 if (r != null) { 6062 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 6063 } 6064 6065 N = pkg.instrumentation.size(); 6066 r = null; 6067 for (i=0; i<N; i++) { 6068 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 6069 a.info.packageName = pkg.applicationInfo.packageName; 6070 a.info.sourceDir = pkg.applicationInfo.sourceDir; 6071 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 6072 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 6073 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 6074 a.info.dataDir = pkg.applicationInfo.dataDir; 6075 6076 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 6077 // need other information about the application, like the ABI and what not ? 6078 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 6079 mInstrumentation.put(a.getComponentName(), a); 6080 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 6081 if (r == null) { 6082 r = new StringBuilder(256); 6083 } else { 6084 r.append(' '); 6085 } 6086 r.append(a.info.name); 6087 } 6088 } 6089 if (r != null) { 6090 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 6091 } 6092 6093 if (pkg.protectedBroadcasts != null) { 6094 N = pkg.protectedBroadcasts.size(); 6095 for (i=0; i<N; i++) { 6096 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 6097 } 6098 } 6099 6100 pkgSetting.setTimeStamp(scanFileTime); 6101 6102 // Create idmap files for pairs of (packages, overlay packages). 6103 // Note: "android", ie framework-res.apk, is handled by native layers. 6104 if (pkg.mOverlayTarget != null) { 6105 // This is an overlay package. 6106 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 6107 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 6108 mOverlays.put(pkg.mOverlayTarget, 6109 new HashMap<String, PackageParser.Package>()); 6110 } 6111 HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 6112 map.put(pkg.packageName, pkg); 6113 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 6114 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 6115 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 6116 "scanPackageLI failed to createIdmap"); 6117 } 6118 } 6119 } else if (mOverlays.containsKey(pkg.packageName) && 6120 !pkg.packageName.equals("android")) { 6121 // This is a regular package, with one or more known overlay packages. 6122 createIdmapsForPackageLI(pkg); 6123 } 6124 } 6125 6126 return pkg; 6127 } 6128 6129 /** 6130 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 6131 * i.e, so that all packages can be run inside a single process if required. 6132 * 6133 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 6134 * this function will either try and make the ABI for all packages in {@code packagesForUser} 6135 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 6136 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 6137 * updating a package that belongs to a shared user. 6138 * 6139 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 6140 * adds unnecessary complexity. 6141 */ 6142 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 6143 PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { 6144 String requiredInstructionSet = null; 6145 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 6146 requiredInstructionSet = VMRuntime.getInstructionSet( 6147 scannedPackage.applicationInfo.primaryCpuAbi); 6148 } 6149 6150 PackageSetting requirer = null; 6151 for (PackageSetting ps : packagesForUser) { 6152 // If packagesForUser contains scannedPackage, we skip it. This will happen 6153 // when scannedPackage is an update of an existing package. Without this check, 6154 // we will never be able to change the ABI of any package belonging to a shared 6155 // user, even if it's compatible with other packages. 6156 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6157 if (ps.primaryCpuAbiString == null) { 6158 continue; 6159 } 6160 6161 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 6162 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 6163 // We have a mismatch between instruction sets (say arm vs arm64) warn about 6164 // this but there's not much we can do. 6165 String errorMessage = "Instruction set mismatch, " 6166 + ((requirer == null) ? "[caller]" : requirer) 6167 + " requires " + requiredInstructionSet + " whereas " + ps 6168 + " requires " + instructionSet; 6169 Slog.w(TAG, errorMessage); 6170 } 6171 6172 if (requiredInstructionSet == null) { 6173 requiredInstructionSet = instructionSet; 6174 requirer = ps; 6175 } 6176 } 6177 } 6178 6179 if (requiredInstructionSet != null) { 6180 String adjustedAbi; 6181 if (requirer != null) { 6182 // requirer != null implies that either scannedPackage was null or that scannedPackage 6183 // did not require an ABI, in which case we have to adjust scannedPackage to match 6184 // the ABI of the set (which is the same as requirer's ABI) 6185 adjustedAbi = requirer.primaryCpuAbiString; 6186 if (scannedPackage != null) { 6187 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 6188 } 6189 } else { 6190 // requirer == null implies that we're updating all ABIs in the set to 6191 // match scannedPackage. 6192 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 6193 } 6194 6195 for (PackageSetting ps : packagesForUser) { 6196 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 6197 if (ps.primaryCpuAbiString != null) { 6198 continue; 6199 } 6200 6201 ps.primaryCpuAbiString = adjustedAbi; 6202 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 6203 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 6204 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 6205 6206 if (performDexOptLI(ps.pkg, null /* instruction sets */, forceDexOpt, 6207 deferDexOpt, true) == DEX_OPT_FAILED) { 6208 ps.primaryCpuAbiString = null; 6209 ps.pkg.applicationInfo.primaryCpuAbi = null; 6210 return; 6211 } else { 6212 mInstaller.rmdex(ps.codePathString, 6213 getDexCodeInstructionSet(getPreferredInstructionSet())); 6214 } 6215 } 6216 } 6217 } 6218 } 6219 } 6220 6221 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 6222 synchronized (mPackages) { 6223 mResolverReplaced = true; 6224 // Set up information for custom user intent resolution activity. 6225 mResolveActivity.applicationInfo = pkg.applicationInfo; 6226 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 6227 mResolveActivity.packageName = pkg.applicationInfo.packageName; 6228 mResolveActivity.processName = null; 6229 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 6230 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 6231 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 6232 mResolveActivity.theme = 0; 6233 mResolveActivity.exported = true; 6234 mResolveActivity.enabled = true; 6235 mResolveInfo.activityInfo = mResolveActivity; 6236 mResolveInfo.priority = 0; 6237 mResolveInfo.preferredOrder = 0; 6238 mResolveInfo.match = 0; 6239 mResolveComponentName = mCustomResolverComponentName; 6240 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 6241 mResolveComponentName); 6242 } 6243 } 6244 6245 private static String calculateApkRoot(final String codePathString) { 6246 final File codePath = new File(codePathString); 6247 final File codeRoot; 6248 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 6249 codeRoot = Environment.getRootDirectory(); 6250 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 6251 codeRoot = Environment.getOemDirectory(); 6252 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 6253 codeRoot = Environment.getVendorDirectory(); 6254 } else { 6255 // Unrecognized code path; take its top real segment as the apk root: 6256 // e.g. /something/app/blah.apk => /something 6257 try { 6258 File f = codePath.getCanonicalFile(); 6259 File parent = f.getParentFile(); // non-null because codePath is a file 6260 File tmp; 6261 while ((tmp = parent.getParentFile()) != null) { 6262 f = parent; 6263 parent = tmp; 6264 } 6265 codeRoot = f; 6266 Slog.w(TAG, "Unrecognized code path " 6267 + codePath + " - using " + codeRoot); 6268 } catch (IOException e) { 6269 // Can't canonicalize the code path -- shenanigans? 6270 Slog.w(TAG, "Can't canonicalize code path " + codePath); 6271 return Environment.getRootDirectory().getPath(); 6272 } 6273 } 6274 return codeRoot.getPath(); 6275 } 6276 6277 /** 6278 * Derive and set the location of native libraries for the given package, 6279 * which varies depending on where and how the package was installed. 6280 */ 6281 private void setNativeLibraryPaths(PackageParser.Package pkg) { 6282 final ApplicationInfo info = pkg.applicationInfo; 6283 final String codePath = pkg.codePath; 6284 final File codeFile = new File(codePath); 6285 // If "/system/lib64/apkname" exists, assume that is the per-package 6286 // native library directory to use; otherwise use "/system/lib/apkname". 6287 final String apkRoot = calculateApkRoot(info.sourceDir); 6288 6289 final boolean bundledApp = isSystemApp(info) && !isUpdatedSystemApp(info); 6290 final boolean asecApp = isForwardLocked(info) || isExternal(info); 6291 6292 6293 info.nativeLibraryRootDir = null; 6294 info.nativeLibraryRootRequiresIsa = false; 6295 info.nativeLibraryDir = null; 6296 info.secondaryNativeLibraryDir = null; 6297 6298 if (isApkFile(codeFile)) { 6299 // Monolithic install 6300 if (bundledApp) { 6301 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 6302 getPrimaryInstructionSet(info)); 6303 6304 // This is a bundled system app so choose the path based on the ABI. 6305 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 6306 // is just the default path. 6307 final String apkName = deriveCodePathName(codePath); 6308 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 6309 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 6310 apkName).getAbsolutePath(); 6311 6312 if (info.secondaryCpuAbi != null) { 6313 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 6314 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 6315 secondaryLibDir, apkName).getAbsolutePath(); 6316 } 6317 } else if (asecApp) { 6318 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 6319 .getAbsolutePath(); 6320 } else { 6321 final String apkName = deriveCodePathName(codePath); 6322 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 6323 .getAbsolutePath(); 6324 } 6325 6326 info.nativeLibraryRootRequiresIsa = false; 6327 info.nativeLibraryDir = info.nativeLibraryRootDir; 6328 } else { 6329 // Cluster install 6330 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 6331 info.nativeLibraryRootRequiresIsa = true; 6332 6333 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 6334 getPrimaryInstructionSet(info)).getAbsolutePath(); 6335 6336 if (info.secondaryCpuAbi != null) { 6337 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 6338 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 6339 } 6340 } 6341 } 6342 6343 /** 6344 * Calculate the abis and roots for a bundled app. These can uniquely 6345 * be determined from the contents of the system partition, i.e whether 6346 * it contains 64 or 32 bit shared libraries etc. We do not validate any 6347 * of this information, and instead assume that the system was built 6348 * sensibly. 6349 */ 6350 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 6351 PackageSetting pkgSetting) { 6352 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 6353 6354 // If "/system/lib64/apkname" exists, assume that is the per-package 6355 // native library directory to use; otherwise use "/system/lib/apkname". 6356 final String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir); 6357 setBundledAppAbi(pkg, apkRoot, apkName); 6358 // pkgSetting might be null during rescan following uninstall of updates 6359 // to a bundled app, so accommodate that possibility. The settings in 6360 // that case will be established later from the parsed package. 6361 // 6362 // If the settings aren't null, sync them up with what we've just derived. 6363 // note that apkRoot isn't stored in the package settings. 6364 if (pkgSetting != null) { 6365 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 6366 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 6367 } 6368 } 6369 6370 /** 6371 * Deduces the ABI of a bundled app and sets the relevant fields on the 6372 * parsed pkg object. 6373 * 6374 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 6375 * under which system libraries are installed. 6376 * @param apkName the name of the installed package. 6377 */ 6378 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 6379 final File codeFile = new File(pkg.codePath); 6380 6381 final boolean has64BitLibs; 6382 final boolean has32BitLibs; 6383 if (isApkFile(codeFile)) { 6384 // Monolithic install 6385 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 6386 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 6387 } else { 6388 // Cluster install 6389 final File rootDir = new File(codeFile, LIB_DIR_NAME); 6390 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 6391 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 6392 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 6393 has64BitLibs = (new File(rootDir, isa)).exists(); 6394 } else { 6395 has64BitLibs = false; 6396 } 6397 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 6398 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 6399 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 6400 has32BitLibs = (new File(rootDir, isa)).exists(); 6401 } else { 6402 has32BitLibs = false; 6403 } 6404 } 6405 6406 if (has64BitLibs && !has32BitLibs) { 6407 // The package has 64 bit libs, but not 32 bit libs. Its primary 6408 // ABI should be 64 bit. We can safely assume here that the bundled 6409 // native libraries correspond to the most preferred ABI in the list. 6410 6411 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 6412 pkg.applicationInfo.secondaryCpuAbi = null; 6413 } else if (has32BitLibs && !has64BitLibs) { 6414 // The package has 32 bit libs but not 64 bit libs. Its primary 6415 // ABI should be 32 bit. 6416 6417 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6418 pkg.applicationInfo.secondaryCpuAbi = null; 6419 } else if (has32BitLibs && has64BitLibs) { 6420 // The application has both 64 and 32 bit bundled libraries. We check 6421 // here that the app declares multiArch support, and warn if it doesn't. 6422 // 6423 // We will be lenient here and record both ABIs. The primary will be the 6424 // ABI that's higher on the list, i.e, a device that's configured to prefer 6425 // 64 bit apps will see a 64 bit primary ABI, 6426 6427 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 6428 Slog.e(TAG, "Package: " + pkg + " has multiple bundled libs, but is not multiarch."); 6429 } 6430 6431 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 6432 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 6433 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6434 } else { 6435 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 6436 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 6437 } 6438 } else { 6439 pkg.applicationInfo.primaryCpuAbi = null; 6440 pkg.applicationInfo.secondaryCpuAbi = null; 6441 } 6442 } 6443 6444 private static void createNativeLibrarySubdir(File path) throws IOException { 6445 if (!path.isDirectory()) { 6446 path.delete(); 6447 6448 if (!path.mkdir()) { 6449 throw new IOException("Cannot create " + path.getPath()); 6450 } 6451 6452 try { 6453 Os.chmod(path.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 6454 } catch (ErrnoException e) { 6455 throw new IOException("Cannot chmod native library directory " 6456 + path.getPath(), e); 6457 } 6458 } else if (!SELinux.restorecon(path)) { 6459 throw new IOException("Cannot set SELinux context for " + path.getPath()); 6460 } 6461 } 6462 6463 private static int copyNativeLibrariesForInternalApp(NativeLibraryHelper.Handle handle, 6464 final File nativeLibraryRoot, String[] abiList, boolean useIsaSubdir) throws IOException { 6465 createNativeLibrarySubdir(nativeLibraryRoot); 6466 6467 /* 6468 * If this is an internal application or our nativeLibraryPath points to 6469 * the app-lib directory, unpack the libraries if necessary. 6470 */ 6471 int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList); 6472 if (abi >= 0) { 6473 /* 6474 * If we have a matching instruction set, construct a subdir under the native 6475 * library root that corresponds to this instruction set. 6476 */ 6477 final String instructionSet = VMRuntime.getInstructionSet(abiList[abi]); 6478 final File subDir; 6479 if (useIsaSubdir) { 6480 final File isaSubdir = new File(nativeLibraryRoot, instructionSet); 6481 createNativeLibrarySubdir(isaSubdir); 6482 subDir = isaSubdir; 6483 } else { 6484 subDir = nativeLibraryRoot; 6485 } 6486 6487 int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, subDir, abiList[abi]); 6488 if (copyRet != PackageManager.INSTALL_SUCCEEDED) { 6489 return copyRet; 6490 } 6491 } 6492 6493 return abi; 6494 } 6495 6496 private void killApplication(String pkgName, int appId, String reason) { 6497 // Request the ActivityManager to kill the process(only for existing packages) 6498 // so that we do not end up in a confused state while the user is still using the older 6499 // version of the application while the new one gets installed. 6500 IActivityManager am = ActivityManagerNative.getDefault(); 6501 if (am != null) { 6502 try { 6503 am.killApplicationWithAppId(pkgName, appId, reason); 6504 } catch (RemoteException e) { 6505 } 6506 } 6507 } 6508 6509 void removePackageLI(PackageSetting ps, boolean chatty) { 6510 if (DEBUG_INSTALL) { 6511 if (chatty) 6512 Log.d(TAG, "Removing package " + ps.name); 6513 } 6514 6515 // writer 6516 synchronized (mPackages) { 6517 mPackages.remove(ps.name); 6518 if (ps.codePathString != null) { 6519 mAppDirs.remove(ps.codePathString); 6520 } 6521 6522 final PackageParser.Package pkg = ps.pkg; 6523 if (pkg != null) { 6524 cleanPackageDataStructuresLILPw(pkg, chatty); 6525 } 6526 } 6527 } 6528 6529 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 6530 if (DEBUG_INSTALL) { 6531 if (chatty) 6532 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 6533 } 6534 6535 // writer 6536 synchronized (mPackages) { 6537 mPackages.remove(pkg.applicationInfo.packageName); 6538 if (pkg.codePath != null) { 6539 mAppDirs.remove(pkg.codePath); 6540 } 6541 cleanPackageDataStructuresLILPw(pkg, chatty); 6542 } 6543 } 6544 6545 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 6546 int N = pkg.providers.size(); 6547 StringBuilder r = null; 6548 int i; 6549 for (i=0; i<N; i++) { 6550 PackageParser.Provider p = pkg.providers.get(i); 6551 mProviders.removeProvider(p); 6552 if (p.info.authority == null) { 6553 6554 /* There was another ContentProvider with this authority when 6555 * this app was installed so this authority is null, 6556 * Ignore it as we don't have to unregister the provider. 6557 */ 6558 continue; 6559 } 6560 String names[] = p.info.authority.split(";"); 6561 for (int j = 0; j < names.length; j++) { 6562 if (mProvidersByAuthority.get(names[j]) == p) { 6563 mProvidersByAuthority.remove(names[j]); 6564 if (DEBUG_REMOVE) { 6565 if (chatty) 6566 Log.d(TAG, "Unregistered content provider: " + names[j] 6567 + ", className = " + p.info.name + ", isSyncable = " 6568 + p.info.isSyncable); 6569 } 6570 } 6571 } 6572 if (DEBUG_REMOVE && chatty) { 6573 if (r == null) { 6574 r = new StringBuilder(256); 6575 } else { 6576 r.append(' '); 6577 } 6578 r.append(p.info.name); 6579 } 6580 } 6581 if (r != null) { 6582 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 6583 } 6584 6585 N = pkg.services.size(); 6586 r = null; 6587 for (i=0; i<N; i++) { 6588 PackageParser.Service s = pkg.services.get(i); 6589 mServices.removeService(s); 6590 if (chatty) { 6591 if (r == null) { 6592 r = new StringBuilder(256); 6593 } else { 6594 r.append(' '); 6595 } 6596 r.append(s.info.name); 6597 } 6598 } 6599 if (r != null) { 6600 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 6601 } 6602 6603 N = pkg.receivers.size(); 6604 r = null; 6605 for (i=0; i<N; i++) { 6606 PackageParser.Activity a = pkg.receivers.get(i); 6607 mReceivers.removeActivity(a, "receiver"); 6608 if (DEBUG_REMOVE && chatty) { 6609 if (r == null) { 6610 r = new StringBuilder(256); 6611 } else { 6612 r.append(' '); 6613 } 6614 r.append(a.info.name); 6615 } 6616 } 6617 if (r != null) { 6618 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 6619 } 6620 6621 N = pkg.activities.size(); 6622 r = null; 6623 for (i=0; i<N; i++) { 6624 PackageParser.Activity a = pkg.activities.get(i); 6625 mActivities.removeActivity(a, "activity"); 6626 if (DEBUG_REMOVE && chatty) { 6627 if (r == null) { 6628 r = new StringBuilder(256); 6629 } else { 6630 r.append(' '); 6631 } 6632 r.append(a.info.name); 6633 } 6634 } 6635 if (r != null) { 6636 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 6637 } 6638 6639 N = pkg.permissions.size(); 6640 r = null; 6641 for (i=0; i<N; i++) { 6642 PackageParser.Permission p = pkg.permissions.get(i); 6643 BasePermission bp = mSettings.mPermissions.get(p.info.name); 6644 if (bp == null) { 6645 bp = mSettings.mPermissionTrees.get(p.info.name); 6646 } 6647 if (bp != null && bp.perm == p) { 6648 bp.perm = null; 6649 if (DEBUG_REMOVE && chatty) { 6650 if (r == null) { 6651 r = new StringBuilder(256); 6652 } else { 6653 r.append(' '); 6654 } 6655 r.append(p.info.name); 6656 } 6657 } 6658 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 6659 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(p.info.name); 6660 if (appOpPerms != null) { 6661 appOpPerms.remove(pkg.packageName); 6662 } 6663 } 6664 } 6665 if (r != null) { 6666 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 6667 } 6668 6669 N = pkg.requestedPermissions.size(); 6670 r = null; 6671 for (i=0; i<N; i++) { 6672 String perm = pkg.requestedPermissions.get(i); 6673 BasePermission bp = mSettings.mPermissions.get(perm); 6674 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 6675 ArraySet<String> appOpPerms = mAppOpPermissionPackages.get(perm); 6676 if (appOpPerms != null) { 6677 appOpPerms.remove(pkg.packageName); 6678 if (appOpPerms.isEmpty()) { 6679 mAppOpPermissionPackages.remove(perm); 6680 } 6681 } 6682 } 6683 } 6684 if (r != null) { 6685 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 6686 } 6687 6688 N = pkg.instrumentation.size(); 6689 r = null; 6690 for (i=0; i<N; i++) { 6691 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 6692 mInstrumentation.remove(a.getComponentName()); 6693 if (DEBUG_REMOVE && chatty) { 6694 if (r == null) { 6695 r = new StringBuilder(256); 6696 } else { 6697 r.append(' '); 6698 } 6699 r.append(a.info.name); 6700 } 6701 } 6702 if (r != null) { 6703 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 6704 } 6705 6706 r = null; 6707 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6708 // Only system apps can hold shared libraries. 6709 if (pkg.libraryNames != null) { 6710 for (i=0; i<pkg.libraryNames.size(); i++) { 6711 String name = pkg.libraryNames.get(i); 6712 SharedLibraryEntry cur = mSharedLibraries.get(name); 6713 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 6714 mSharedLibraries.remove(name); 6715 if (DEBUG_REMOVE && chatty) { 6716 if (r == null) { 6717 r = new StringBuilder(256); 6718 } else { 6719 r.append(' '); 6720 } 6721 r.append(name); 6722 } 6723 } 6724 } 6725 } 6726 } 6727 if (r != null) { 6728 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 6729 } 6730 } 6731 6732 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 6733 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 6734 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 6735 return true; 6736 } 6737 } 6738 return false; 6739 } 6740 6741 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 6742 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 6743 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 6744 6745 private void updatePermissionsLPw(String changingPkg, 6746 PackageParser.Package pkgInfo, int flags) { 6747 // Make sure there are no dangling permission trees. 6748 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 6749 while (it.hasNext()) { 6750 final BasePermission bp = it.next(); 6751 if (bp.packageSetting == null) { 6752 // We may not yet have parsed the package, so just see if 6753 // we still know about its settings. 6754 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 6755 } 6756 if (bp.packageSetting == null) { 6757 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 6758 + " from package " + bp.sourcePackage); 6759 it.remove(); 6760 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 6761 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 6762 Slog.i(TAG, "Removing old permission tree: " + bp.name 6763 + " from package " + bp.sourcePackage); 6764 flags |= UPDATE_PERMISSIONS_ALL; 6765 it.remove(); 6766 } 6767 } 6768 } 6769 6770 // Make sure all dynamic permissions have been assigned to a package, 6771 // and make sure there are no dangling permissions. 6772 it = mSettings.mPermissions.values().iterator(); 6773 while (it.hasNext()) { 6774 final BasePermission bp = it.next(); 6775 if (bp.type == BasePermission.TYPE_DYNAMIC) { 6776 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 6777 + bp.name + " pkg=" + bp.sourcePackage 6778 + " info=" + bp.pendingInfo); 6779 if (bp.packageSetting == null && bp.pendingInfo != null) { 6780 final BasePermission tree = findPermissionTreeLP(bp.name); 6781 if (tree != null && tree.perm != null) { 6782 bp.packageSetting = tree.packageSetting; 6783 bp.perm = new PackageParser.Permission(tree.perm.owner, 6784 new PermissionInfo(bp.pendingInfo)); 6785 bp.perm.info.packageName = tree.perm.info.packageName; 6786 bp.perm.info.name = bp.name; 6787 bp.uid = tree.uid; 6788 } 6789 } 6790 } 6791 if (bp.packageSetting == null) { 6792 // We may not yet have parsed the package, so just see if 6793 // we still know about its settings. 6794 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 6795 } 6796 if (bp.packageSetting == null) { 6797 Slog.w(TAG, "Removing dangling permission: " + bp.name 6798 + " from package " + bp.sourcePackage); 6799 it.remove(); 6800 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 6801 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 6802 Slog.i(TAG, "Removing old permission: " + bp.name 6803 + " from package " + bp.sourcePackage); 6804 flags |= UPDATE_PERMISSIONS_ALL; 6805 it.remove(); 6806 } 6807 } 6808 } 6809 6810 // Now update the permissions for all packages, in particular 6811 // replace the granted permissions of the system packages. 6812 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 6813 for (PackageParser.Package pkg : mPackages.values()) { 6814 if (pkg != pkgInfo) { 6815 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0); 6816 } 6817 } 6818 } 6819 6820 if (pkgInfo != null) { 6821 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0); 6822 } 6823 } 6824 6825 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) { 6826 final PackageSetting ps = (PackageSetting) pkg.mExtras; 6827 if (ps == null) { 6828 return; 6829 } 6830 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 6831 HashSet<String> origPermissions = gp.grantedPermissions; 6832 boolean changedPermission = false; 6833 6834 if (replace) { 6835 ps.permissionsFixed = false; 6836 if (gp == ps) { 6837 origPermissions = new HashSet<String>(gp.grantedPermissions); 6838 gp.grantedPermissions.clear(); 6839 gp.gids = mGlobalGids; 6840 } 6841 } 6842 6843 if (gp.gids == null) { 6844 gp.gids = mGlobalGids; 6845 } 6846 6847 final int N = pkg.requestedPermissions.size(); 6848 for (int i=0; i<N; i++) { 6849 final String name = pkg.requestedPermissions.get(i); 6850 final boolean required = pkg.requestedPermissionsRequired.get(i); 6851 final BasePermission bp = mSettings.mPermissions.get(name); 6852 if (DEBUG_INSTALL) { 6853 if (gp != ps) { 6854 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 6855 } 6856 } 6857 6858 if (bp == null || bp.packageSetting == null) { 6859 Slog.w(TAG, "Unknown permission " + name 6860 + " in package " + pkg.packageName); 6861 continue; 6862 } 6863 6864 final String perm = bp.name; 6865 boolean allowed; 6866 boolean allowedSig = false; 6867 if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 6868 // Keep track of app op permissions. 6869 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 6870 if (pkgs == null) { 6871 pkgs = new ArraySet<>(); 6872 mAppOpPermissionPackages.put(bp.name, pkgs); 6873 } 6874 pkgs.add(pkg.packageName); 6875 } 6876 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 6877 if (level == PermissionInfo.PROTECTION_NORMAL 6878 || level == PermissionInfo.PROTECTION_DANGEROUS) { 6879 // We grant a normal or dangerous permission if any of the following 6880 // are true: 6881 // 1) The permission is required 6882 // 2) The permission is optional, but was granted in the past 6883 // 3) The permission is optional, but was requested by an 6884 // app in /system (not /data) 6885 // 6886 // Otherwise, reject the permission. 6887 allowed = (required || origPermissions.contains(perm) 6888 || (isSystemApp(ps) && !isUpdatedSystemApp(ps))); 6889 } else if (bp.packageSetting == null) { 6890 // This permission is invalid; skip it. 6891 allowed = false; 6892 } else if (level == PermissionInfo.PROTECTION_SIGNATURE) { 6893 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions); 6894 if (allowed) { 6895 allowedSig = true; 6896 } 6897 } else { 6898 allowed = false; 6899 } 6900 if (DEBUG_INSTALL) { 6901 if (gp != ps) { 6902 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 6903 } 6904 } 6905 if (allowed) { 6906 if (!isSystemApp(ps) && ps.permissionsFixed) { 6907 // If this is an existing, non-system package, then 6908 // we can't add any new permissions to it. 6909 if (!allowedSig && !gp.grantedPermissions.contains(perm)) { 6910 // Except... if this is a permission that was added 6911 // to the platform (note: need to only do this when 6912 // updating the platform). 6913 allowed = isNewPlatformPermissionForPackage(perm, pkg); 6914 } 6915 } 6916 if (allowed) { 6917 if (!gp.grantedPermissions.contains(perm)) { 6918 changedPermission = true; 6919 gp.grantedPermissions.add(perm); 6920 gp.gids = appendInts(gp.gids, bp.gids); 6921 } else if (!ps.haveGids) { 6922 gp.gids = appendInts(gp.gids, bp.gids); 6923 } 6924 } else { 6925 Slog.w(TAG, "Not granting permission " + perm 6926 + " to package " + pkg.packageName 6927 + " because it was previously installed without"); 6928 } 6929 } else { 6930 if (gp.grantedPermissions.remove(perm)) { 6931 changedPermission = true; 6932 gp.gids = removeInts(gp.gids, bp.gids); 6933 Slog.i(TAG, "Un-granting permission " + perm 6934 + " from package " + pkg.packageName 6935 + " (protectionLevel=" + bp.protectionLevel 6936 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 6937 + ")"); 6938 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 6939 // Don't print warning for app op permissions, since it is fine for them 6940 // not to be granted, there is a UI for the user to decide. 6941 Slog.w(TAG, "Not granting permission " + perm 6942 + " to package " + pkg.packageName 6943 + " (protectionLevel=" + bp.protectionLevel 6944 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 6945 + ")"); 6946 } 6947 } 6948 } 6949 6950 if ((changedPermission || replace) && !ps.permissionsFixed && 6951 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 6952 // This is the first that we have heard about this package, so the 6953 // permissions we have now selected are fixed until explicitly 6954 // changed. 6955 ps.permissionsFixed = true; 6956 } 6957 ps.haveGids = true; 6958 } 6959 6960 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 6961 boolean allowed = false; 6962 final int NP = PackageParser.NEW_PERMISSIONS.length; 6963 for (int ip=0; ip<NP; ip++) { 6964 final PackageParser.NewPermissionInfo npi 6965 = PackageParser.NEW_PERMISSIONS[ip]; 6966 if (npi.name.equals(perm) 6967 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 6968 allowed = true; 6969 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 6970 + pkg.packageName); 6971 break; 6972 } 6973 } 6974 return allowed; 6975 } 6976 6977 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 6978 BasePermission bp, HashSet<String> origPermissions) { 6979 boolean allowed; 6980 allowed = (compareSignatures( 6981 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 6982 == PackageManager.SIGNATURE_MATCH) 6983 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 6984 == PackageManager.SIGNATURE_MATCH); 6985 if (!allowed && (bp.protectionLevel 6986 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) { 6987 if (isSystemApp(pkg)) { 6988 // For updated system applications, a system permission 6989 // is granted only if it had been defined by the original application. 6990 if (isUpdatedSystemApp(pkg)) { 6991 final PackageSetting sysPs = mSettings 6992 .getDisabledSystemPkgLPr(pkg.packageName); 6993 final GrantedPermissions origGp = sysPs.sharedUser != null 6994 ? sysPs.sharedUser : sysPs; 6995 6996 if (origGp.grantedPermissions.contains(perm)) { 6997 // If the original was granted this permission, we take 6998 // that grant decision as read and propagate it to the 6999 // update. 7000 allowed = true; 7001 } else { 7002 // The system apk may have been updated with an older 7003 // version of the one on the data partition, but which 7004 // granted a new system permission that it didn't have 7005 // before. In this case we do want to allow the app to 7006 // now get the new permission if the ancestral apk is 7007 // privileged to get it. 7008 if (sysPs.pkg != null && sysPs.isPrivileged()) { 7009 for (int j=0; 7010 j<sysPs.pkg.requestedPermissions.size(); j++) { 7011 if (perm.equals( 7012 sysPs.pkg.requestedPermissions.get(j))) { 7013 allowed = true; 7014 break; 7015 } 7016 } 7017 } 7018 } 7019 } else { 7020 allowed = isPrivilegedApp(pkg); 7021 } 7022 } 7023 } 7024 if (!allowed && (bp.protectionLevel 7025 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 7026 // For development permissions, a development permission 7027 // is granted only if it was already granted. 7028 allowed = origPermissions.contains(perm); 7029 } 7030 return allowed; 7031 } 7032 7033 final class ActivityIntentResolver 7034 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 7035 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7036 boolean defaultOnly, int userId) { 7037 if (!sUserManager.exists(userId)) return null; 7038 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7039 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7040 } 7041 7042 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7043 int userId) { 7044 if (!sUserManager.exists(userId)) return null; 7045 mFlags = flags; 7046 return super.queryIntent(intent, resolvedType, 7047 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7048 } 7049 7050 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7051 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 7052 if (!sUserManager.exists(userId)) return null; 7053 if (packageActivities == null) { 7054 return null; 7055 } 7056 mFlags = flags; 7057 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 7058 final int N = packageActivities.size(); 7059 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 7060 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 7061 7062 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 7063 for (int i = 0; i < N; ++i) { 7064 intentFilters = packageActivities.get(i).intents; 7065 if (intentFilters != null && intentFilters.size() > 0) { 7066 PackageParser.ActivityIntentInfo[] array = 7067 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 7068 intentFilters.toArray(array); 7069 listCut.add(array); 7070 } 7071 } 7072 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7073 } 7074 7075 public final void addActivity(PackageParser.Activity a, String type) { 7076 final boolean systemApp = isSystemApp(a.info.applicationInfo); 7077 mActivities.put(a.getComponentName(), a); 7078 if (DEBUG_SHOW_INFO) 7079 Log.v( 7080 TAG, " " + type + " " + 7081 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 7082 if (DEBUG_SHOW_INFO) 7083 Log.v(TAG, " Class=" + a.info.name); 7084 final int NI = a.intents.size(); 7085 for (int j=0; j<NI; j++) { 7086 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7087 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 7088 intent.setPriority(0); 7089 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 7090 + a.className + " with priority > 0, forcing to 0"); 7091 } 7092 if (DEBUG_SHOW_INFO) { 7093 Log.v(TAG, " IntentFilter:"); 7094 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7095 } 7096 if (!intent.debugCheck()) { 7097 Log.w(TAG, "==> For Activity " + a.info.name); 7098 } 7099 addFilter(intent); 7100 } 7101 } 7102 7103 public final void removeActivity(PackageParser.Activity a, String type) { 7104 mActivities.remove(a.getComponentName()); 7105 if (DEBUG_SHOW_INFO) { 7106 Log.v(TAG, " " + type + " " 7107 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 7108 : a.info.name) + ":"); 7109 Log.v(TAG, " Class=" + a.info.name); 7110 } 7111 final int NI = a.intents.size(); 7112 for (int j=0; j<NI; j++) { 7113 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 7114 if (DEBUG_SHOW_INFO) { 7115 Log.v(TAG, " IntentFilter:"); 7116 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7117 } 7118 removeFilter(intent); 7119 } 7120 } 7121 7122 @Override 7123 protected boolean allowFilterResult( 7124 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 7125 ActivityInfo filterAi = filter.activity.info; 7126 for (int i=dest.size()-1; i>=0; i--) { 7127 ActivityInfo destAi = dest.get(i).activityInfo; 7128 if (destAi.name == filterAi.name 7129 && destAi.packageName == filterAi.packageName) { 7130 return false; 7131 } 7132 } 7133 return true; 7134 } 7135 7136 @Override 7137 protected ActivityIntentInfo[] newArray(int size) { 7138 return new ActivityIntentInfo[size]; 7139 } 7140 7141 @Override 7142 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 7143 if (!sUserManager.exists(userId)) return true; 7144 PackageParser.Package p = filter.activity.owner; 7145 if (p != null) { 7146 PackageSetting ps = (PackageSetting)p.mExtras; 7147 if (ps != null) { 7148 // System apps are never considered stopped for purposes of 7149 // filtering, because there may be no way for the user to 7150 // actually re-launch them. 7151 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 7152 && ps.getStopped(userId); 7153 } 7154 } 7155 return false; 7156 } 7157 7158 @Override 7159 protected boolean isPackageForFilter(String packageName, 7160 PackageParser.ActivityIntentInfo info) { 7161 return packageName.equals(info.activity.owner.packageName); 7162 } 7163 7164 @Override 7165 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 7166 int match, int userId) { 7167 if (!sUserManager.exists(userId)) return null; 7168 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 7169 return null; 7170 } 7171 final PackageParser.Activity activity = info.activity; 7172 if (mSafeMode && (activity.info.applicationInfo.flags 7173 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7174 return null; 7175 } 7176 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 7177 if (ps == null) { 7178 return null; 7179 } 7180 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 7181 ps.readUserState(userId), userId); 7182 if (ai == null) { 7183 return null; 7184 } 7185 final ResolveInfo res = new ResolveInfo(); 7186 res.activityInfo = ai; 7187 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 7188 res.filter = info; 7189 } 7190 res.priority = info.getPriority(); 7191 res.preferredOrder = activity.owner.mPreferredOrder; 7192 //System.out.println("Result: " + res.activityInfo.className + 7193 // " = " + res.priority); 7194 res.match = match; 7195 res.isDefault = info.hasDefault; 7196 res.labelRes = info.labelRes; 7197 res.nonLocalizedLabel = info.nonLocalizedLabel; 7198 if (userNeedsBadging(userId)) { 7199 res.noResourceId = true; 7200 } else { 7201 res.icon = info.icon; 7202 } 7203 res.system = isSystemApp(res.activityInfo.applicationInfo); 7204 return res; 7205 } 7206 7207 @Override 7208 protected void sortResults(List<ResolveInfo> results) { 7209 Collections.sort(results, mResolvePrioritySorter); 7210 } 7211 7212 @Override 7213 protected void dumpFilter(PrintWriter out, String prefix, 7214 PackageParser.ActivityIntentInfo filter) { 7215 out.print(prefix); out.print( 7216 Integer.toHexString(System.identityHashCode(filter.activity))); 7217 out.print(' '); 7218 filter.activity.printComponentShortName(out); 7219 out.print(" filter "); 7220 out.println(Integer.toHexString(System.identityHashCode(filter))); 7221 } 7222 7223// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 7224// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 7225// final List<ResolveInfo> retList = Lists.newArrayList(); 7226// while (i.hasNext()) { 7227// final ResolveInfo resolveInfo = i.next(); 7228// if (isEnabledLP(resolveInfo.activityInfo)) { 7229// retList.add(resolveInfo); 7230// } 7231// } 7232// return retList; 7233// } 7234 7235 // Keys are String (activity class name), values are Activity. 7236 private final HashMap<ComponentName, PackageParser.Activity> mActivities 7237 = new HashMap<ComponentName, PackageParser.Activity>(); 7238 private int mFlags; 7239 } 7240 7241 private final class ServiceIntentResolver 7242 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 7243 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7244 boolean defaultOnly, int userId) { 7245 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7246 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7247 } 7248 7249 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7250 int userId) { 7251 if (!sUserManager.exists(userId)) return null; 7252 mFlags = flags; 7253 return super.queryIntent(intent, resolvedType, 7254 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7255 } 7256 7257 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7258 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 7259 if (!sUserManager.exists(userId)) return null; 7260 if (packageServices == null) { 7261 return null; 7262 } 7263 mFlags = flags; 7264 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 7265 final int N = packageServices.size(); 7266 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 7267 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 7268 7269 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 7270 for (int i = 0; i < N; ++i) { 7271 intentFilters = packageServices.get(i).intents; 7272 if (intentFilters != null && intentFilters.size() > 0) { 7273 PackageParser.ServiceIntentInfo[] array = 7274 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 7275 intentFilters.toArray(array); 7276 listCut.add(array); 7277 } 7278 } 7279 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7280 } 7281 7282 public final void addService(PackageParser.Service s) { 7283 mServices.put(s.getComponentName(), s); 7284 if (DEBUG_SHOW_INFO) { 7285 Log.v(TAG, " " 7286 + (s.info.nonLocalizedLabel != null 7287 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 7288 Log.v(TAG, " Class=" + s.info.name); 7289 } 7290 final int NI = s.intents.size(); 7291 int j; 7292 for (j=0; j<NI; j++) { 7293 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 7294 if (DEBUG_SHOW_INFO) { 7295 Log.v(TAG, " IntentFilter:"); 7296 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7297 } 7298 if (!intent.debugCheck()) { 7299 Log.w(TAG, "==> For Service " + s.info.name); 7300 } 7301 addFilter(intent); 7302 } 7303 } 7304 7305 public final void removeService(PackageParser.Service s) { 7306 mServices.remove(s.getComponentName()); 7307 if (DEBUG_SHOW_INFO) { 7308 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 7309 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 7310 Log.v(TAG, " Class=" + s.info.name); 7311 } 7312 final int NI = s.intents.size(); 7313 int j; 7314 for (j=0; j<NI; j++) { 7315 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 7316 if (DEBUG_SHOW_INFO) { 7317 Log.v(TAG, " IntentFilter:"); 7318 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7319 } 7320 removeFilter(intent); 7321 } 7322 } 7323 7324 @Override 7325 protected boolean allowFilterResult( 7326 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 7327 ServiceInfo filterSi = filter.service.info; 7328 for (int i=dest.size()-1; i>=0; i--) { 7329 ServiceInfo destAi = dest.get(i).serviceInfo; 7330 if (destAi.name == filterSi.name 7331 && destAi.packageName == filterSi.packageName) { 7332 return false; 7333 } 7334 } 7335 return true; 7336 } 7337 7338 @Override 7339 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 7340 return new PackageParser.ServiceIntentInfo[size]; 7341 } 7342 7343 @Override 7344 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 7345 if (!sUserManager.exists(userId)) return true; 7346 PackageParser.Package p = filter.service.owner; 7347 if (p != null) { 7348 PackageSetting ps = (PackageSetting)p.mExtras; 7349 if (ps != null) { 7350 // System apps are never considered stopped for purposes of 7351 // filtering, because there may be no way for the user to 7352 // actually re-launch them. 7353 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 7354 && ps.getStopped(userId); 7355 } 7356 } 7357 return false; 7358 } 7359 7360 @Override 7361 protected boolean isPackageForFilter(String packageName, 7362 PackageParser.ServiceIntentInfo info) { 7363 return packageName.equals(info.service.owner.packageName); 7364 } 7365 7366 @Override 7367 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 7368 int match, int userId) { 7369 if (!sUserManager.exists(userId)) return null; 7370 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 7371 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 7372 return null; 7373 } 7374 final PackageParser.Service service = info.service; 7375 if (mSafeMode && (service.info.applicationInfo.flags 7376 &ApplicationInfo.FLAG_SYSTEM) == 0) { 7377 return null; 7378 } 7379 PackageSetting ps = (PackageSetting) service.owner.mExtras; 7380 if (ps == null) { 7381 return null; 7382 } 7383 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 7384 ps.readUserState(userId), userId); 7385 if (si == null) { 7386 return null; 7387 } 7388 final ResolveInfo res = new ResolveInfo(); 7389 res.serviceInfo = si; 7390 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 7391 res.filter = filter; 7392 } 7393 res.priority = info.getPriority(); 7394 res.preferredOrder = service.owner.mPreferredOrder; 7395 //System.out.println("Result: " + res.activityInfo.className + 7396 // " = " + res.priority); 7397 res.match = match; 7398 res.isDefault = info.hasDefault; 7399 res.labelRes = info.labelRes; 7400 res.nonLocalizedLabel = info.nonLocalizedLabel; 7401 res.icon = info.icon; 7402 res.system = isSystemApp(res.serviceInfo.applicationInfo); 7403 return res; 7404 } 7405 7406 @Override 7407 protected void sortResults(List<ResolveInfo> results) { 7408 Collections.sort(results, mResolvePrioritySorter); 7409 } 7410 7411 @Override 7412 protected void dumpFilter(PrintWriter out, String prefix, 7413 PackageParser.ServiceIntentInfo filter) { 7414 out.print(prefix); out.print( 7415 Integer.toHexString(System.identityHashCode(filter.service))); 7416 out.print(' '); 7417 filter.service.printComponentShortName(out); 7418 out.print(" filter "); 7419 out.println(Integer.toHexString(System.identityHashCode(filter))); 7420 } 7421 7422// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 7423// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 7424// final List<ResolveInfo> retList = Lists.newArrayList(); 7425// while (i.hasNext()) { 7426// final ResolveInfo resolveInfo = (ResolveInfo) i; 7427// if (isEnabledLP(resolveInfo.serviceInfo)) { 7428// retList.add(resolveInfo); 7429// } 7430// } 7431// return retList; 7432// } 7433 7434 // Keys are String (activity class name), values are Activity. 7435 private final HashMap<ComponentName, PackageParser.Service> mServices 7436 = new HashMap<ComponentName, PackageParser.Service>(); 7437 private int mFlags; 7438 }; 7439 7440 private final class ProviderIntentResolver 7441 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 7442 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 7443 boolean defaultOnly, int userId) { 7444 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 7445 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 7446 } 7447 7448 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 7449 int userId) { 7450 if (!sUserManager.exists(userId)) 7451 return null; 7452 mFlags = flags; 7453 return super.queryIntent(intent, resolvedType, 7454 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 7455 } 7456 7457 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 7458 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 7459 if (!sUserManager.exists(userId)) 7460 return null; 7461 if (packageProviders == null) { 7462 return null; 7463 } 7464 mFlags = flags; 7465 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 7466 final int N = packageProviders.size(); 7467 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 7468 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 7469 7470 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 7471 for (int i = 0; i < N; ++i) { 7472 intentFilters = packageProviders.get(i).intents; 7473 if (intentFilters != null && intentFilters.size() > 0) { 7474 PackageParser.ProviderIntentInfo[] array = 7475 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 7476 intentFilters.toArray(array); 7477 listCut.add(array); 7478 } 7479 } 7480 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 7481 } 7482 7483 public final void addProvider(PackageParser.Provider p) { 7484 if (mProviders.containsKey(p.getComponentName())) { 7485 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 7486 return; 7487 } 7488 7489 mProviders.put(p.getComponentName(), p); 7490 if (DEBUG_SHOW_INFO) { 7491 Log.v(TAG, " " 7492 + (p.info.nonLocalizedLabel != null 7493 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 7494 Log.v(TAG, " Class=" + p.info.name); 7495 } 7496 final int NI = p.intents.size(); 7497 int j; 7498 for (j = 0; j < NI; j++) { 7499 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 7500 if (DEBUG_SHOW_INFO) { 7501 Log.v(TAG, " IntentFilter:"); 7502 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7503 } 7504 if (!intent.debugCheck()) { 7505 Log.w(TAG, "==> For Provider " + p.info.name); 7506 } 7507 addFilter(intent); 7508 } 7509 } 7510 7511 public final void removeProvider(PackageParser.Provider p) { 7512 mProviders.remove(p.getComponentName()); 7513 if (DEBUG_SHOW_INFO) { 7514 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 7515 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 7516 Log.v(TAG, " Class=" + p.info.name); 7517 } 7518 final int NI = p.intents.size(); 7519 int j; 7520 for (j = 0; j < NI; j++) { 7521 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 7522 if (DEBUG_SHOW_INFO) { 7523 Log.v(TAG, " IntentFilter:"); 7524 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 7525 } 7526 removeFilter(intent); 7527 } 7528 } 7529 7530 @Override 7531 protected boolean allowFilterResult( 7532 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 7533 ProviderInfo filterPi = filter.provider.info; 7534 for (int i = dest.size() - 1; i >= 0; i--) { 7535 ProviderInfo destPi = dest.get(i).providerInfo; 7536 if (destPi.name == filterPi.name 7537 && destPi.packageName == filterPi.packageName) { 7538 return false; 7539 } 7540 } 7541 return true; 7542 } 7543 7544 @Override 7545 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 7546 return new PackageParser.ProviderIntentInfo[size]; 7547 } 7548 7549 @Override 7550 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 7551 if (!sUserManager.exists(userId)) 7552 return true; 7553 PackageParser.Package p = filter.provider.owner; 7554 if (p != null) { 7555 PackageSetting ps = (PackageSetting) p.mExtras; 7556 if (ps != null) { 7557 // System apps are never considered stopped for purposes of 7558 // filtering, because there may be no way for the user to 7559 // actually re-launch them. 7560 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 7561 && ps.getStopped(userId); 7562 } 7563 } 7564 return false; 7565 } 7566 7567 @Override 7568 protected boolean isPackageForFilter(String packageName, 7569 PackageParser.ProviderIntentInfo info) { 7570 return packageName.equals(info.provider.owner.packageName); 7571 } 7572 7573 @Override 7574 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 7575 int match, int userId) { 7576 if (!sUserManager.exists(userId)) 7577 return null; 7578 final PackageParser.ProviderIntentInfo info = filter; 7579 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 7580 return null; 7581 } 7582 final PackageParser.Provider provider = info.provider; 7583 if (mSafeMode && (provider.info.applicationInfo.flags 7584 & ApplicationInfo.FLAG_SYSTEM) == 0) { 7585 return null; 7586 } 7587 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 7588 if (ps == null) { 7589 return null; 7590 } 7591 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 7592 ps.readUserState(userId), userId); 7593 if (pi == null) { 7594 return null; 7595 } 7596 final ResolveInfo res = new ResolveInfo(); 7597 res.providerInfo = pi; 7598 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 7599 res.filter = filter; 7600 } 7601 res.priority = info.getPriority(); 7602 res.preferredOrder = provider.owner.mPreferredOrder; 7603 res.match = match; 7604 res.isDefault = info.hasDefault; 7605 res.labelRes = info.labelRes; 7606 res.nonLocalizedLabel = info.nonLocalizedLabel; 7607 res.icon = info.icon; 7608 res.system = isSystemApp(res.providerInfo.applicationInfo); 7609 return res; 7610 } 7611 7612 @Override 7613 protected void sortResults(List<ResolveInfo> results) { 7614 Collections.sort(results, mResolvePrioritySorter); 7615 } 7616 7617 @Override 7618 protected void dumpFilter(PrintWriter out, String prefix, 7619 PackageParser.ProviderIntentInfo filter) { 7620 out.print(prefix); 7621 out.print( 7622 Integer.toHexString(System.identityHashCode(filter.provider))); 7623 out.print(' '); 7624 filter.provider.printComponentShortName(out); 7625 out.print(" filter "); 7626 out.println(Integer.toHexString(System.identityHashCode(filter))); 7627 } 7628 7629 private final HashMap<ComponentName, PackageParser.Provider> mProviders 7630 = new HashMap<ComponentName, PackageParser.Provider>(); 7631 private int mFlags; 7632 }; 7633 7634 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 7635 new Comparator<ResolveInfo>() { 7636 public int compare(ResolveInfo r1, ResolveInfo r2) { 7637 int v1 = r1.priority; 7638 int v2 = r2.priority; 7639 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 7640 if (v1 != v2) { 7641 return (v1 > v2) ? -1 : 1; 7642 } 7643 v1 = r1.preferredOrder; 7644 v2 = r2.preferredOrder; 7645 if (v1 != v2) { 7646 return (v1 > v2) ? -1 : 1; 7647 } 7648 if (r1.isDefault != r2.isDefault) { 7649 return r1.isDefault ? -1 : 1; 7650 } 7651 v1 = r1.match; 7652 v2 = r2.match; 7653 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 7654 if (v1 != v2) { 7655 return (v1 > v2) ? -1 : 1; 7656 } 7657 if (r1.system != r2.system) { 7658 return r1.system ? -1 : 1; 7659 } 7660 return 0; 7661 } 7662 }; 7663 7664 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 7665 new Comparator<ProviderInfo>() { 7666 public int compare(ProviderInfo p1, ProviderInfo p2) { 7667 final int v1 = p1.initOrder; 7668 final int v2 = p2.initOrder; 7669 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 7670 } 7671 }; 7672 7673 static final void sendPackageBroadcast(String action, String pkg, 7674 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, 7675 int[] userIds) { 7676 IActivityManager am = ActivityManagerNative.getDefault(); 7677 if (am != null) { 7678 try { 7679 if (userIds == null) { 7680 userIds = am.getRunningUserIds(); 7681 } 7682 for (int id : userIds) { 7683 final Intent intent = new Intent(action, 7684 pkg != null ? Uri.fromParts("package", pkg, null) : null); 7685 if (extras != null) { 7686 intent.putExtras(extras); 7687 } 7688 if (targetPkg != null) { 7689 intent.setPackage(targetPkg); 7690 } 7691 // Modify the UID when posting to other users 7692 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 7693 if (uid > 0 && UserHandle.getUserId(uid) != id) { 7694 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 7695 intent.putExtra(Intent.EXTRA_UID, uid); 7696 } 7697 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 7698 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 7699 if (DEBUG_BROADCASTS) { 7700 RuntimeException here = new RuntimeException("here"); 7701 here.fillInStackTrace(); 7702 Slog.d(TAG, "Sending to user " + id + ": " 7703 + intent.toShortString(false, true, false, false) 7704 + " " + intent.getExtras(), here); 7705 } 7706 am.broadcastIntent(null, intent, null, finishedReceiver, 7707 0, null, null, null, android.app.AppOpsManager.OP_NONE, 7708 finishedReceiver != null, false, id); 7709 } 7710 } catch (RemoteException ex) { 7711 } 7712 } 7713 } 7714 7715 /** 7716 * Check if the external storage media is available. This is true if there 7717 * is a mounted external storage medium or if the external storage is 7718 * emulated. 7719 */ 7720 private boolean isExternalMediaAvailable() { 7721 return mMediaMounted || Environment.isExternalStorageEmulated(); 7722 } 7723 7724 @Override 7725 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 7726 // writer 7727 synchronized (mPackages) { 7728 if (!isExternalMediaAvailable()) { 7729 // If the external storage is no longer mounted at this point, 7730 // the caller may not have been able to delete all of this 7731 // packages files and can not delete any more. Bail. 7732 return null; 7733 } 7734 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 7735 if (lastPackage != null) { 7736 pkgs.remove(lastPackage); 7737 } 7738 if (pkgs.size() > 0) { 7739 return pkgs.get(0); 7740 } 7741 } 7742 return null; 7743 } 7744 7745 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 7746 if (false) { 7747 RuntimeException here = new RuntimeException("here"); 7748 here.fillInStackTrace(); 7749 Slog.d(TAG, "Schedule cleaning " + packageName + " user=" + userId 7750 + " andCode=" + andCode, here); 7751 } 7752 mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE, 7753 userId, andCode ? 1 : 0, packageName)); 7754 } 7755 7756 void startCleaningPackages() { 7757 // reader 7758 synchronized (mPackages) { 7759 if (!isExternalMediaAvailable()) { 7760 return; 7761 } 7762 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 7763 return; 7764 } 7765 } 7766 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 7767 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 7768 IActivityManager am = ActivityManagerNative.getDefault(); 7769 if (am != null) { 7770 try { 7771 am.startService(null, intent, null, UserHandle.USER_OWNER); 7772 } catch (RemoteException e) { 7773 } 7774 } 7775 } 7776 7777 @Override 7778 public void installPackage(String originPath, IPackageInstallObserver2 observer, int flags, 7779 String installerPackageName, VerificationParams verificationParams, 7780 String packageAbiOverride) { 7781 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 7782 null); 7783 7784 final File originFile = new File(originPath); 7785 final int uid = Binder.getCallingUid(); 7786 if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) { 7787 try { 7788 if (observer != null) { 7789 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 7790 } 7791 } catch (RemoteException re) { 7792 } 7793 return; 7794 } 7795 7796 UserHandle user; 7797 if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) { 7798 user = UserHandle.ALL; 7799 } else { 7800 user = new UserHandle(UserHandle.getUserId(uid)); 7801 } 7802 7803 final int filteredFlags; 7804 if (uid == Process.SHELL_UID || uid == 0) { 7805 if (DEBUG_INSTALL) { 7806 Slog.v(TAG, "Install from ADB"); 7807 } 7808 filteredFlags = flags | PackageManager.INSTALL_FROM_ADB; 7809 } else { 7810 filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB; 7811 } 7812 7813 verificationParams.setInstallerUid(uid); 7814 7815 final Message msg = mHandler.obtainMessage(INIT_COPY); 7816 msg.obj = new InstallParams(originFile, false, observer, filteredFlags, 7817 installerPackageName, verificationParams, user, packageAbiOverride); 7818 mHandler.sendMessage(msg); 7819 } 7820 7821 void installStage(String packageName, File stageDir, IPackageInstallObserver2 observer, 7822 InstallSessionParams params, String installerPackageName, int installerUid, 7823 UserHandle user) { 7824 final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, 7825 params.referrerUri, installerUid, null); 7826 7827 final Message msg = mHandler.obtainMessage(INIT_COPY); 7828 msg.obj = new InstallParams(stageDir, true, observer, params.installFlags, 7829 installerPackageName, verifParams, user, params.abiOverride); 7830 mHandler.sendMessage(msg); 7831 } 7832 7833 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 7834 Bundle extras = new Bundle(1); 7835 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 7836 7837 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 7838 packageName, extras, null, null, new int[] {userId}); 7839 try { 7840 IActivityManager am = ActivityManagerNative.getDefault(); 7841 final boolean isSystem = 7842 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 7843 if (isSystem && am.isUserRunning(userId, false)) { 7844 // The just-installed/enabled app is bundled on the system, so presumed 7845 // to be able to run automatically without needing an explicit launch. 7846 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 7847 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 7848 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 7849 .setPackage(packageName); 7850 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 7851 android.app.AppOpsManager.OP_NONE, false, false, userId); 7852 } 7853 } catch (RemoteException e) { 7854 // shouldn't happen 7855 Slog.w(TAG, "Unable to bootstrap installed package", e); 7856 } 7857 } 7858 7859 @Override 7860 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 7861 int userId) { 7862 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 7863 PackageSetting pkgSetting; 7864 final int uid = Binder.getCallingUid(); 7865 if (UserHandle.getUserId(uid) != userId) { 7866 mContext.enforceCallingOrSelfPermission( 7867 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 7868 "setApplicationHiddenSetting for user " + userId); 7869 } 7870 7871 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 7872 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 7873 return false; 7874 } 7875 7876 long callingId = Binder.clearCallingIdentity(); 7877 try { 7878 boolean sendAdded = false; 7879 boolean sendRemoved = false; 7880 // writer 7881 synchronized (mPackages) { 7882 pkgSetting = mSettings.mPackages.get(packageName); 7883 if (pkgSetting == null) { 7884 return false; 7885 } 7886 if (pkgSetting.getHidden(userId) != hidden) { 7887 pkgSetting.setHidden(hidden, userId); 7888 mSettings.writePackageRestrictionsLPr(userId); 7889 if (hidden) { 7890 sendRemoved = true; 7891 } else { 7892 sendAdded = true; 7893 } 7894 } 7895 } 7896 if (sendAdded) { 7897 sendPackageAddedForUser(packageName, pkgSetting, userId); 7898 return true; 7899 } 7900 if (sendRemoved) { 7901 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 7902 "hiding pkg"); 7903 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 7904 } 7905 } finally { 7906 Binder.restoreCallingIdentity(callingId); 7907 } 7908 return false; 7909 } 7910 7911 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 7912 int userId) { 7913 final PackageRemovedInfo info = new PackageRemovedInfo(); 7914 info.removedPackage = packageName; 7915 info.removedUsers = new int[] {userId}; 7916 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 7917 info.sendBroadcast(false, false, false); 7918 } 7919 7920 /** 7921 * Returns true if application is not found or there was an error. Otherwise it returns 7922 * the hidden state of the package for the given user. 7923 */ 7924 @Override 7925 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 7926 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 7927 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, 7928 "getApplicationHidden for user " + userId); 7929 PackageSetting pkgSetting; 7930 long callingId = Binder.clearCallingIdentity(); 7931 try { 7932 // writer 7933 synchronized (mPackages) { 7934 pkgSetting = mSettings.mPackages.get(packageName); 7935 if (pkgSetting == null) { 7936 return true; 7937 } 7938 return pkgSetting.getHidden(userId); 7939 } 7940 } finally { 7941 Binder.restoreCallingIdentity(callingId); 7942 } 7943 } 7944 7945 /** 7946 * @hide 7947 */ 7948 @Override 7949 public int installExistingPackageAsUser(String packageName, int userId) { 7950 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 7951 null); 7952 PackageSetting pkgSetting; 7953 final int uid = Binder.getCallingUid(); 7954 enforceCrossUserPermission(uid, userId, true, "installExistingPackage for user " + userId); 7955 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 7956 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 7957 } 7958 7959 long callingId = Binder.clearCallingIdentity(); 7960 try { 7961 boolean sendAdded = false; 7962 Bundle extras = new Bundle(1); 7963 7964 // writer 7965 synchronized (mPackages) { 7966 pkgSetting = mSettings.mPackages.get(packageName); 7967 if (pkgSetting == null) { 7968 return PackageManager.INSTALL_FAILED_INVALID_URI; 7969 } 7970 if (!pkgSetting.getInstalled(userId)) { 7971 pkgSetting.setInstalled(true, userId); 7972 pkgSetting.setHidden(false, userId); 7973 mSettings.writePackageRestrictionsLPr(userId); 7974 sendAdded = true; 7975 } 7976 } 7977 7978 if (sendAdded) { 7979 sendPackageAddedForUser(packageName, pkgSetting, userId); 7980 } 7981 } finally { 7982 Binder.restoreCallingIdentity(callingId); 7983 } 7984 7985 return PackageManager.INSTALL_SUCCEEDED; 7986 } 7987 7988 boolean isUserRestricted(int userId, String restrictionKey) { 7989 Bundle restrictions = sUserManager.getUserRestrictions(userId); 7990 if (restrictions.getBoolean(restrictionKey, false)) { 7991 Log.w(TAG, "User is restricted: " + restrictionKey); 7992 return true; 7993 } 7994 return false; 7995 } 7996 7997 @Override 7998 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 7999 mContext.enforceCallingOrSelfPermission( 8000 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8001 "Only package verification agents can verify applications"); 8002 8003 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8004 final PackageVerificationResponse response = new PackageVerificationResponse( 8005 verificationCode, Binder.getCallingUid()); 8006 msg.arg1 = id; 8007 msg.obj = response; 8008 mHandler.sendMessage(msg); 8009 } 8010 8011 @Override 8012 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 8013 long millisecondsToDelay) { 8014 mContext.enforceCallingOrSelfPermission( 8015 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8016 "Only package verification agents can extend verification timeouts"); 8017 8018 final PackageVerificationState state = mPendingVerification.get(id); 8019 final PackageVerificationResponse response = new PackageVerificationResponse( 8020 verificationCodeAtTimeout, Binder.getCallingUid()); 8021 8022 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 8023 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 8024 } 8025 if (millisecondsToDelay < 0) { 8026 millisecondsToDelay = 0; 8027 } 8028 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 8029 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 8030 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 8031 } 8032 8033 if ((state != null) && !state.timeoutExtended()) { 8034 state.extendTimeout(); 8035 8036 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 8037 msg.arg1 = id; 8038 msg.obj = response; 8039 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 8040 } 8041 } 8042 8043 private void broadcastPackageVerified(int verificationId, Uri packageUri, 8044 int verificationCode, UserHandle user) { 8045 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 8046 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 8047 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 8048 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 8049 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 8050 8051 mContext.sendBroadcastAsUser(intent, user, 8052 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 8053 } 8054 8055 private ComponentName matchComponentForVerifier(String packageName, 8056 List<ResolveInfo> receivers) { 8057 ActivityInfo targetReceiver = null; 8058 8059 final int NR = receivers.size(); 8060 for (int i = 0; i < NR; i++) { 8061 final ResolveInfo info = receivers.get(i); 8062 if (info.activityInfo == null) { 8063 continue; 8064 } 8065 8066 if (packageName.equals(info.activityInfo.packageName)) { 8067 targetReceiver = info.activityInfo; 8068 break; 8069 } 8070 } 8071 8072 if (targetReceiver == null) { 8073 return null; 8074 } 8075 8076 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 8077 } 8078 8079 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 8080 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 8081 if (pkgInfo.verifiers.length == 0) { 8082 return null; 8083 } 8084 8085 final int N = pkgInfo.verifiers.length; 8086 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 8087 for (int i = 0; i < N; i++) { 8088 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 8089 8090 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 8091 receivers); 8092 if (comp == null) { 8093 continue; 8094 } 8095 8096 final int verifierUid = getUidForVerifier(verifierInfo); 8097 if (verifierUid == -1) { 8098 continue; 8099 } 8100 8101 if (DEBUG_VERIFY) { 8102 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 8103 + " with the correct signature"); 8104 } 8105 sufficientVerifiers.add(comp); 8106 verificationState.addSufficientVerifier(verifierUid); 8107 } 8108 8109 return sufficientVerifiers; 8110 } 8111 8112 private int getUidForVerifier(VerifierInfo verifierInfo) { 8113 synchronized (mPackages) { 8114 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 8115 if (pkg == null) { 8116 return -1; 8117 } else if (pkg.mSignatures.length != 1) { 8118 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8119 + " has more than one signature; ignoring"); 8120 return -1; 8121 } 8122 8123 /* 8124 * If the public key of the package's signature does not match 8125 * our expected public key, then this is a different package and 8126 * we should skip. 8127 */ 8128 8129 final byte[] expectedPublicKey; 8130 try { 8131 final Signature verifierSig = pkg.mSignatures[0]; 8132 final PublicKey publicKey = verifierSig.getPublicKey(); 8133 expectedPublicKey = publicKey.getEncoded(); 8134 } catch (CertificateException e) { 8135 return -1; 8136 } 8137 8138 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 8139 8140 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 8141 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 8142 + " does not have the expected public key; ignoring"); 8143 return -1; 8144 } 8145 8146 return pkg.applicationInfo.uid; 8147 } 8148 } 8149 8150 @Override 8151 public void finishPackageInstall(int token) { 8152 enforceSystemOrRoot("Only the system is allowed to finish installs"); 8153 8154 if (DEBUG_INSTALL) { 8155 Slog.v(TAG, "BM finishing package install for " + token); 8156 } 8157 8158 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 8159 mHandler.sendMessage(msg); 8160 } 8161 8162 /** 8163 * Get the verification agent timeout. 8164 * 8165 * @return verification timeout in milliseconds 8166 */ 8167 private long getVerificationTimeout() { 8168 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 8169 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 8170 DEFAULT_VERIFICATION_TIMEOUT); 8171 } 8172 8173 /** 8174 * Get the default verification agent response code. 8175 * 8176 * @return default verification response code 8177 */ 8178 private int getDefaultVerificationResponse() { 8179 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8180 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 8181 DEFAULT_VERIFICATION_RESPONSE); 8182 } 8183 8184 /** 8185 * Check whether or not package verification has been enabled. 8186 * 8187 * @return true if verification should be performed 8188 */ 8189 private boolean isVerificationEnabled(int userId, int flags) { 8190 if (!DEFAULT_VERIFY_ENABLE) { 8191 return false; 8192 } 8193 8194 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 8195 8196 // Check if installing from ADB 8197 if ((flags & PackageManager.INSTALL_FROM_ADB) != 0) { 8198 // Do not run verification in a test harness environment 8199 if (ActivityManager.isRunningInTestHarness()) { 8200 return false; 8201 } 8202 if (ensureVerifyAppsEnabled) { 8203 return true; 8204 } 8205 // Check if the developer does not want package verification for ADB installs 8206 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8207 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 8208 return false; 8209 } 8210 } 8211 8212 if (ensureVerifyAppsEnabled) { 8213 return true; 8214 } 8215 8216 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8217 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 8218 } 8219 8220 /** 8221 * Get the "allow unknown sources" setting. 8222 * 8223 * @return the current "allow unknown sources" setting 8224 */ 8225 private int getUnknownSourcesSettings() { 8226 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 8227 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 8228 -1); 8229 } 8230 8231 @Override 8232 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 8233 final int uid = Binder.getCallingUid(); 8234 // writer 8235 synchronized (mPackages) { 8236 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 8237 if (targetPackageSetting == null) { 8238 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 8239 } 8240 8241 PackageSetting installerPackageSetting; 8242 if (installerPackageName != null) { 8243 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 8244 if (installerPackageSetting == null) { 8245 throw new IllegalArgumentException("Unknown installer package: " 8246 + installerPackageName); 8247 } 8248 } else { 8249 installerPackageSetting = null; 8250 } 8251 8252 Signature[] callerSignature; 8253 Object obj = mSettings.getUserIdLPr(uid); 8254 if (obj != null) { 8255 if (obj instanceof SharedUserSetting) { 8256 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 8257 } else if (obj instanceof PackageSetting) { 8258 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 8259 } else { 8260 throw new SecurityException("Bad object " + obj + " for uid " + uid); 8261 } 8262 } else { 8263 throw new SecurityException("Unknown calling uid " + uid); 8264 } 8265 8266 // Verify: can't set installerPackageName to a package that is 8267 // not signed with the same cert as the caller. 8268 if (installerPackageSetting != null) { 8269 if (compareSignatures(callerSignature, 8270 installerPackageSetting.signatures.mSignatures) 8271 != PackageManager.SIGNATURE_MATCH) { 8272 throw new SecurityException( 8273 "Caller does not have same cert as new installer package " 8274 + installerPackageName); 8275 } 8276 } 8277 8278 // Verify: if target already has an installer package, it must 8279 // be signed with the same cert as the caller. 8280 if (targetPackageSetting.installerPackageName != null) { 8281 PackageSetting setting = mSettings.mPackages.get( 8282 targetPackageSetting.installerPackageName); 8283 // If the currently set package isn't valid, then it's always 8284 // okay to change it. 8285 if (setting != null) { 8286 if (compareSignatures(callerSignature, 8287 setting.signatures.mSignatures) 8288 != PackageManager.SIGNATURE_MATCH) { 8289 throw new SecurityException( 8290 "Caller does not have same cert as old installer package " 8291 + targetPackageSetting.installerPackageName); 8292 } 8293 } 8294 } 8295 8296 // Okay! 8297 targetPackageSetting.installerPackageName = installerPackageName; 8298 scheduleWriteSettingsLocked(); 8299 } 8300 } 8301 8302 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 8303 // Queue up an async operation since the package installation may take a little while. 8304 mHandler.post(new Runnable() { 8305 public void run() { 8306 mHandler.removeCallbacks(this); 8307 // Result object to be returned 8308 PackageInstalledInfo res = new PackageInstalledInfo(); 8309 res.returnCode = currentStatus; 8310 res.uid = -1; 8311 res.pkg = null; 8312 res.removedInfo = new PackageRemovedInfo(); 8313 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 8314 args.doPreInstall(res.returnCode); 8315 synchronized (mInstallLock) { 8316 installPackageLI(args, true, res); 8317 } 8318 args.doPostInstall(res.returnCode, res.uid); 8319 } 8320 8321 // A restore should be performed at this point if (a) the install 8322 // succeeded, (b) the operation is not an update, and (c) the new 8323 // package has not opted out of backup participation. 8324 final boolean update = res.removedInfo.removedPackage != null; 8325 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 8326 boolean doRestore = !update 8327 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 8328 8329 // Set up the post-install work request bookkeeping. This will be used 8330 // and cleaned up by the post-install event handling regardless of whether 8331 // there's a restore pass performed. Token values are >= 1. 8332 int token; 8333 if (mNextInstallToken < 0) mNextInstallToken = 1; 8334 token = mNextInstallToken++; 8335 8336 PostInstallData data = new PostInstallData(args, res); 8337 mRunningInstalls.put(token, data); 8338 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 8339 8340 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 8341 // Pass responsibility to the Backup Manager. It will perform a 8342 // restore if appropriate, then pass responsibility back to the 8343 // Package Manager to run the post-install observer callbacks 8344 // and broadcasts. 8345 IBackupManager bm = IBackupManager.Stub.asInterface( 8346 ServiceManager.getService(Context.BACKUP_SERVICE)); 8347 if (bm != null) { 8348 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 8349 + " to BM for possible restore"); 8350 try { 8351 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 8352 } catch (RemoteException e) { 8353 // can't happen; the backup manager is local 8354 } catch (Exception e) { 8355 Slog.e(TAG, "Exception trying to enqueue restore", e); 8356 doRestore = false; 8357 } 8358 } else { 8359 Slog.e(TAG, "Backup Manager not found!"); 8360 doRestore = false; 8361 } 8362 } 8363 8364 if (!doRestore) { 8365 // No restore possible, or the Backup Manager was mysteriously not 8366 // available -- just fire the post-install work request directly. 8367 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 8368 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 8369 mHandler.sendMessage(msg); 8370 } 8371 } 8372 }); 8373 } 8374 8375 private abstract class HandlerParams { 8376 private static final int MAX_RETRIES = 4; 8377 8378 /** 8379 * Number of times startCopy() has been attempted and had a non-fatal 8380 * error. 8381 */ 8382 private int mRetries = 0; 8383 8384 /** User handle for the user requesting the information or installation. */ 8385 private final UserHandle mUser; 8386 8387 HandlerParams(UserHandle user) { 8388 mUser = user; 8389 } 8390 8391 UserHandle getUser() { 8392 return mUser; 8393 } 8394 8395 final boolean startCopy() { 8396 boolean res; 8397 try { 8398 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 8399 8400 if (++mRetries > MAX_RETRIES) { 8401 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 8402 mHandler.sendEmptyMessage(MCS_GIVE_UP); 8403 handleServiceError(); 8404 return false; 8405 } else { 8406 handleStartCopy(); 8407 res = true; 8408 } 8409 } catch (RemoteException e) { 8410 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 8411 mHandler.sendEmptyMessage(MCS_RECONNECT); 8412 res = false; 8413 } 8414 handleReturnCode(); 8415 return res; 8416 } 8417 8418 final void serviceError() { 8419 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 8420 handleServiceError(); 8421 handleReturnCode(); 8422 } 8423 8424 abstract void handleStartCopy() throws RemoteException; 8425 abstract void handleServiceError(); 8426 abstract void handleReturnCode(); 8427 } 8428 8429 class MeasureParams extends HandlerParams { 8430 private final PackageStats mStats; 8431 private boolean mSuccess; 8432 8433 private final IPackageStatsObserver mObserver; 8434 8435 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 8436 super(new UserHandle(stats.userHandle)); 8437 mObserver = observer; 8438 mStats = stats; 8439 } 8440 8441 @Override 8442 public String toString() { 8443 return "MeasureParams{" 8444 + Integer.toHexString(System.identityHashCode(this)) 8445 + " " + mStats.packageName + "}"; 8446 } 8447 8448 @Override 8449 void handleStartCopy() throws RemoteException { 8450 synchronized (mInstallLock) { 8451 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 8452 } 8453 8454 if (mSuccess) { 8455 final boolean mounted; 8456 if (Environment.isExternalStorageEmulated()) { 8457 mounted = true; 8458 } else { 8459 final String status = Environment.getExternalStorageState(); 8460 mounted = (Environment.MEDIA_MOUNTED.equals(status) 8461 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 8462 } 8463 8464 if (mounted) { 8465 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 8466 8467 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 8468 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 8469 8470 mStats.externalDataSize = calculateDirectorySize(mContainerService, 8471 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 8472 8473 // Always subtract cache size, since it's a subdirectory 8474 mStats.externalDataSize -= mStats.externalCacheSize; 8475 8476 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 8477 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 8478 8479 mStats.externalObbSize = calculateDirectorySize(mContainerService, 8480 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 8481 } 8482 } 8483 } 8484 8485 @Override 8486 void handleReturnCode() { 8487 if (mObserver != null) { 8488 try { 8489 mObserver.onGetStatsCompleted(mStats, mSuccess); 8490 } catch (RemoteException e) { 8491 Slog.i(TAG, "Observer no longer exists."); 8492 } 8493 } 8494 } 8495 8496 @Override 8497 void handleServiceError() { 8498 Slog.e(TAG, "Could not measure application " + mStats.packageName 8499 + " external storage"); 8500 } 8501 } 8502 8503 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 8504 throws RemoteException { 8505 long result = 0; 8506 for (File path : paths) { 8507 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 8508 } 8509 return result; 8510 } 8511 8512 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 8513 for (File path : paths) { 8514 try { 8515 mcs.clearDirectory(path.getAbsolutePath()); 8516 } catch (RemoteException e) { 8517 } 8518 } 8519 } 8520 8521 class InstallParams extends HandlerParams { 8522 /** 8523 * Location where install is coming from, before it has been 8524 * copied/renamed into place. This could be a single monolithic APK 8525 * file, or a cluster directory. This location may be untrusted. 8526 */ 8527 final File originFile; 8528 8529 /** 8530 * Flag indicating that {@link #originFile} has already been staged, 8531 * meaning downstream users don't need to defensively copy the contents. 8532 */ 8533 boolean originStaged; 8534 8535 final IPackageInstallObserver2 observer; 8536 int flags; 8537 final String installerPackageName; 8538 final VerificationParams verificationParams; 8539 private InstallArgs mArgs; 8540 private int mRet; 8541 final String packageAbiOverride; 8542 boolean multiArch; 8543 8544 InstallParams(File originFile, boolean originStaged, IPackageInstallObserver2 observer, 8545 int flags, String installerPackageName, VerificationParams verificationParams, 8546 UserHandle user, String packageAbiOverride) { 8547 super(user); 8548 this.originFile = Preconditions.checkNotNull(originFile); 8549 this.originStaged = originStaged; 8550 this.observer = observer; 8551 this.flags = flags; 8552 this.installerPackageName = installerPackageName; 8553 this.verificationParams = verificationParams; 8554 this.packageAbiOverride = packageAbiOverride; 8555 } 8556 8557 @Override 8558 public String toString() { 8559 return "InstallParams{" 8560 + Integer.toHexString(System.identityHashCode(this)) 8561 + " " + originFile + "}"; 8562 } 8563 8564 public ManifestDigest getManifestDigest() { 8565 if (verificationParams == null) { 8566 return null; 8567 } 8568 return verificationParams.getManifestDigest(); 8569 } 8570 8571 private int installLocationPolicy(PackageInfoLite pkgLite, int flags) { 8572 String packageName = pkgLite.packageName; 8573 int installLocation = pkgLite.installLocation; 8574 boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 8575 // reader 8576 synchronized (mPackages) { 8577 PackageParser.Package pkg = mPackages.get(packageName); 8578 if (pkg != null) { 8579 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 8580 // Check for downgrading. 8581 if ((flags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 8582 if (pkgLite.versionCode < pkg.mVersionCode) { 8583 Slog.w(TAG, "Can't install update of " + packageName 8584 + " update version " + pkgLite.versionCode 8585 + " is older than installed version " 8586 + pkg.mVersionCode); 8587 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 8588 } 8589 } 8590 // Check for updated system application. 8591 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 8592 if (onSd) { 8593 Slog.w(TAG, "Cannot install update to system app on sdcard"); 8594 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 8595 } 8596 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8597 } else { 8598 if (onSd) { 8599 // Install flag overrides everything. 8600 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8601 } 8602 // If current upgrade specifies particular preference 8603 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 8604 // Application explicitly specified internal. 8605 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8606 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 8607 // App explictly prefers external. Let policy decide 8608 } else { 8609 // Prefer previous location 8610 if (isExternal(pkg)) { 8611 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8612 } 8613 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8614 } 8615 } 8616 } else { 8617 // Invalid install. Return error code 8618 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 8619 } 8620 } 8621 } 8622 // All the special cases have been taken care of. 8623 // Return result based on recommended install location. 8624 if (onSd) { 8625 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8626 } 8627 return pkgLite.recommendedInstallLocation; 8628 } 8629 8630 private long getMemoryLowThreshold() { 8631 final DeviceStorageMonitorInternal 8632 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 8633 if (dsm == null) { 8634 return 0L; 8635 } 8636 return dsm.getMemoryLowThreshold(); 8637 } 8638 8639 /* 8640 * Invoke remote method to get package information and install 8641 * location values. Override install location based on default 8642 * policy if needed and then create install arguments based 8643 * on the install location. 8644 */ 8645 public void handleStartCopy() throws RemoteException { 8646 int ret = PackageManager.INSTALL_SUCCEEDED; 8647 final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 8648 final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0; 8649 PackageInfoLite pkgLite = null; 8650 8651 if (onInt && onSd) { 8652 // Check if both bits are set. 8653 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 8654 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 8655 } else { 8656 final long lowThreshold = getMemoryLowThreshold(); 8657 if (lowThreshold == 0L) { 8658 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 8659 } 8660 8661 // Remote call to find out default install location 8662 final String originPath = originFile.getAbsolutePath(); 8663 pkgLite = mContainerService.getMinimalPackageInfo(originPath, flags, lowThreshold, 8664 packageAbiOverride); 8665 // Keep track of whether this package is a multiArch package until 8666 // we perform a full scan of it. We need to do this because we might 8667 // end up extracting the package shared libraries before we perform 8668 // a full scan. 8669 multiArch = pkgLite.multiArch; 8670 8671 /* 8672 * If we have too little free space, try to free cache 8673 * before giving up. 8674 */ 8675 if (pkgLite.recommendedInstallLocation 8676 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 8677 final long size = mContainerService.calculateInstalledSize( 8678 originPath, isForwardLocked(), packageAbiOverride); 8679 if (mInstaller.freeCache(size + lowThreshold) >= 0) { 8680 pkgLite = mContainerService.getMinimalPackageInfo(originPath, flags, 8681 lowThreshold, packageAbiOverride); 8682 } 8683 /* 8684 * The cache free must have deleted the file we 8685 * downloaded to install. 8686 * 8687 * TODO: fix the "freeCache" call to not delete 8688 * the file we care about. 8689 */ 8690 if (pkgLite.recommendedInstallLocation 8691 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 8692 pkgLite.recommendedInstallLocation 8693 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 8694 } 8695 } 8696 } 8697 8698 if (ret == PackageManager.INSTALL_SUCCEEDED) { 8699 int loc = pkgLite.recommendedInstallLocation; 8700 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 8701 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 8702 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 8703 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 8704 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 8705 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8706 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 8707 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 8708 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 8709 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 8710 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 8711 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 8712 } else { 8713 // Override with defaults if needed. 8714 loc = installLocationPolicy(pkgLite, flags); 8715 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 8716 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 8717 } else if (!onSd && !onInt) { 8718 // Override install location with flags 8719 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 8720 // Set the flag to install on external media. 8721 flags |= PackageManager.INSTALL_EXTERNAL; 8722 flags &= ~PackageManager.INSTALL_INTERNAL; 8723 } else { 8724 // Make sure the flag for installing on external 8725 // media is unset 8726 flags |= PackageManager.INSTALL_INTERNAL; 8727 flags &= ~PackageManager.INSTALL_EXTERNAL; 8728 } 8729 } 8730 } 8731 } 8732 8733 final InstallArgs args = createInstallArgs(this); 8734 mArgs = args; 8735 8736 if (ret == PackageManager.INSTALL_SUCCEEDED) { 8737 /* 8738 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 8739 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 8740 */ 8741 int userIdentifier = getUser().getIdentifier(); 8742 if (userIdentifier == UserHandle.USER_ALL 8743 && ((flags & PackageManager.INSTALL_FROM_ADB) != 0)) { 8744 userIdentifier = UserHandle.USER_OWNER; 8745 } 8746 8747 /* 8748 * Determine if we have any installed package verifiers. If we 8749 * do, then we'll defer to them to verify the packages. 8750 */ 8751 final int requiredUid = mRequiredVerifierPackage == null ? -1 8752 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 8753 if (requiredUid != -1 && isVerificationEnabled(userIdentifier, flags)) { 8754 // TODO: send verifier the install session instead of uri 8755 final Intent verification = new Intent( 8756 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 8757 verification.setDataAndType(Uri.fromFile(originFile), PACKAGE_MIME_TYPE); 8758 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 8759 8760 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 8761 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 8762 0 /* TODO: Which userId? */); 8763 8764 if (DEBUG_VERIFY) { 8765 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 8766 + verification.toString() + " with " + pkgLite.verifiers.length 8767 + " optional verifiers"); 8768 } 8769 8770 final int verificationId = mPendingVerificationToken++; 8771 8772 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 8773 8774 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 8775 installerPackageName); 8776 8777 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags); 8778 8779 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 8780 pkgLite.packageName); 8781 8782 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 8783 pkgLite.versionCode); 8784 8785 if (verificationParams != null) { 8786 if (verificationParams.getVerificationURI() != null) { 8787 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 8788 verificationParams.getVerificationURI()); 8789 } 8790 if (verificationParams.getOriginatingURI() != null) { 8791 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 8792 verificationParams.getOriginatingURI()); 8793 } 8794 if (verificationParams.getReferrer() != null) { 8795 verification.putExtra(Intent.EXTRA_REFERRER, 8796 verificationParams.getReferrer()); 8797 } 8798 if (verificationParams.getOriginatingUid() >= 0) { 8799 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 8800 verificationParams.getOriginatingUid()); 8801 } 8802 if (verificationParams.getInstallerUid() >= 0) { 8803 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 8804 verificationParams.getInstallerUid()); 8805 } 8806 } 8807 8808 final PackageVerificationState verificationState = new PackageVerificationState( 8809 requiredUid, args); 8810 8811 mPendingVerification.append(verificationId, verificationState); 8812 8813 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 8814 receivers, verificationState); 8815 8816 /* 8817 * If any sufficient verifiers were listed in the package 8818 * manifest, attempt to ask them. 8819 */ 8820 if (sufficientVerifiers != null) { 8821 final int N = sufficientVerifiers.size(); 8822 if (N == 0) { 8823 Slog.i(TAG, "Additional verifiers required, but none installed."); 8824 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 8825 } else { 8826 for (int i = 0; i < N; i++) { 8827 final ComponentName verifierComponent = sufficientVerifiers.get(i); 8828 8829 final Intent sufficientIntent = new Intent(verification); 8830 sufficientIntent.setComponent(verifierComponent); 8831 8832 mContext.sendBroadcastAsUser(sufficientIntent, getUser()); 8833 } 8834 } 8835 } 8836 8837 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 8838 mRequiredVerifierPackage, receivers); 8839 if (ret == PackageManager.INSTALL_SUCCEEDED 8840 && mRequiredVerifierPackage != null) { 8841 /* 8842 * Send the intent to the required verification agent, 8843 * but only start the verification timeout after the 8844 * target BroadcastReceivers have run. 8845 */ 8846 verification.setComponent(requiredVerifierComponent); 8847 mContext.sendOrderedBroadcastAsUser(verification, getUser(), 8848 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8849 new BroadcastReceiver() { 8850 @Override 8851 public void onReceive(Context context, Intent intent) { 8852 final Message msg = mHandler 8853 .obtainMessage(CHECK_PENDING_VERIFICATION); 8854 msg.arg1 = verificationId; 8855 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 8856 } 8857 }, null, 0, null, null); 8858 8859 /* 8860 * We don't want the copy to proceed until verification 8861 * succeeds, so null out this field. 8862 */ 8863 mArgs = null; 8864 } 8865 } else { 8866 /* 8867 * No package verification is enabled, so immediately start 8868 * the remote call to initiate copy using temporary file. 8869 */ 8870 ret = args.copyApk(mContainerService, true); 8871 } 8872 } 8873 8874 mRet = ret; 8875 } 8876 8877 @Override 8878 void handleReturnCode() { 8879 // If mArgs is null, then MCS couldn't be reached. When it 8880 // reconnects, it will try again to install. At that point, this 8881 // will succeed. 8882 if (mArgs != null) { 8883 processPendingInstall(mArgs, mRet); 8884 } 8885 } 8886 8887 @Override 8888 void handleServiceError() { 8889 mArgs = createInstallArgs(this); 8890 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 8891 } 8892 8893 public boolean isForwardLocked() { 8894 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 8895 } 8896 } 8897 8898 /* 8899 * Utility class used in movePackage api. 8900 * srcArgs and targetArgs are not set for invalid flags and make 8901 * sure to do null checks when invoking methods on them. 8902 * We probably want to return ErrorPrams for both failed installs 8903 * and moves. 8904 */ 8905 class MoveParams extends HandlerParams { 8906 final IPackageMoveObserver observer; 8907 final int flags; 8908 final String packageName; 8909 final InstallArgs srcArgs; 8910 final InstallArgs targetArgs; 8911 int uid; 8912 int mRet; 8913 8914 MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, 8915 String packageName, String[] instructionSets, int uid, UserHandle user, 8916 boolean isMultiArch) { 8917 super(user); 8918 this.srcArgs = srcArgs; 8919 this.observer = observer; 8920 this.flags = flags; 8921 this.packageName = packageName; 8922 this.uid = uid; 8923 if (srcArgs != null) { 8924 final String codePath = srcArgs.getCodePath(); 8925 targetArgs = createInstallArgsForMoveTarget(codePath, flags, packageName, 8926 instructionSets, isMultiArch); 8927 } else { 8928 targetArgs = null; 8929 } 8930 } 8931 8932 @Override 8933 public String toString() { 8934 return "MoveParams{" 8935 + Integer.toHexString(System.identityHashCode(this)) 8936 + " " + packageName + "}"; 8937 } 8938 8939 public void handleStartCopy() throws RemoteException { 8940 mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8941 // Check for storage space on target medium 8942 if (!targetArgs.checkFreeStorage(mContainerService)) { 8943 Log.w(TAG, "Insufficient storage to install"); 8944 return; 8945 } 8946 8947 mRet = srcArgs.doPreCopy(); 8948 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8949 return; 8950 } 8951 8952 mRet = targetArgs.copyApk(mContainerService, false); 8953 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8954 srcArgs.doPostCopy(uid); 8955 return; 8956 } 8957 8958 mRet = srcArgs.doPostCopy(uid); 8959 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8960 return; 8961 } 8962 8963 mRet = targetArgs.doPreInstall(mRet); 8964 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8965 return; 8966 } 8967 8968 if (DEBUG_SD_INSTALL) { 8969 StringBuilder builder = new StringBuilder(); 8970 if (srcArgs != null) { 8971 builder.append("src: "); 8972 builder.append(srcArgs.getCodePath()); 8973 } 8974 if (targetArgs != null) { 8975 builder.append(" target : "); 8976 builder.append(targetArgs.getCodePath()); 8977 } 8978 Log.i(TAG, builder.toString()); 8979 } 8980 } 8981 8982 @Override 8983 void handleReturnCode() { 8984 targetArgs.doPostInstall(mRet, uid); 8985 int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 8986 if (mRet == PackageManager.INSTALL_SUCCEEDED) { 8987 currentStatus = PackageManager.MOVE_SUCCEEDED; 8988 } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){ 8989 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 8990 } 8991 processPendingMove(this, currentStatus); 8992 } 8993 8994 @Override 8995 void handleServiceError() { 8996 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 8997 } 8998 } 8999 9000 /** 9001 * Used during creation of InstallArgs 9002 * 9003 * @param flags package installation flags 9004 * @return true if should be installed on external storage 9005 */ 9006 private static boolean installOnSd(int flags) { 9007 if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { 9008 return false; 9009 } 9010 if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { 9011 return true; 9012 } 9013 return false; 9014 } 9015 9016 /** 9017 * Used during creation of InstallArgs 9018 * 9019 * @param flags package installation flags 9020 * @return true if should be installed as forward locked 9021 */ 9022 private static boolean installForwardLocked(int flags) { 9023 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9024 } 9025 9026 private InstallArgs createInstallArgs(InstallParams params) { 9027 // TODO: extend to support incoming zero-copy locations 9028 9029 if (installOnSd(params.flags) || params.isForwardLocked()) { 9030 return new AsecInstallArgs(params); 9031 } else { 9032 return new FileInstallArgs(params); 9033 } 9034 } 9035 9036 /** 9037 * Create args that describe an existing installed package. Typically used 9038 * when cleaning up old installs, or used as a move source. 9039 */ 9040 private InstallArgs createInstallArgsForExisting(int flags, String codePath, 9041 String resourcePath, String nativeLibraryRoot, String[] instructionSets, 9042 boolean isMultiArch) { 9043 final boolean isInAsec; 9044 if (installOnSd(flags)) { 9045 /* Apps on SD card are always in ASEC containers. */ 9046 isInAsec = true; 9047 } else if (installForwardLocked(flags) 9048 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 9049 /* 9050 * Forward-locked apps are only in ASEC containers if they're the 9051 * new style 9052 */ 9053 isInAsec = true; 9054 } else { 9055 isInAsec = false; 9056 } 9057 9058 if (isInAsec) { 9059 return new AsecInstallArgs(codePath, instructionSets, 9060 installOnSd(flags), installForwardLocked(flags), isMultiArch); 9061 } else { 9062 return new FileInstallArgs(codePath, resourcePath, nativeLibraryRoot, 9063 instructionSets, isMultiArch); 9064 } 9065 } 9066 9067 private InstallArgs createInstallArgsForMoveTarget(String codePath, int flags, String pkgName, 9068 String[] instructionSets, boolean isMultiArch) { 9069 final File codeFile = new File(codePath); 9070 if (installOnSd(flags) || installForwardLocked(flags)) { 9071 String cid = getNextCodePath(codePath, pkgName, "/" 9072 + AsecInstallArgs.RES_FILE_NAME); 9073 return new AsecInstallArgs(codeFile, cid, instructionSets, installOnSd(flags), 9074 installForwardLocked(flags), isMultiArch); 9075 } else { 9076 return new FileInstallArgs(codeFile, instructionSets, isMultiArch); 9077 } 9078 } 9079 9080 static abstract class InstallArgs { 9081 /** @see InstallParams#originFile */ 9082 final File originFile; 9083 /** @see InstallParams#originStaged */ 9084 final boolean originStaged; 9085 9086 // TODO: define inherit location 9087 9088 final IPackageInstallObserver2 observer; 9089 // Always refers to PackageManager flags only 9090 final int flags; 9091 final String installerPackageName; 9092 final ManifestDigest manifestDigest; 9093 final UserHandle user; 9094 final String abiOverride; 9095 final boolean multiArch; 9096 9097 // The list of instruction sets supported by this app. This is currently 9098 // only used during the rmdex() phase to clean up resources. We can get rid of this 9099 // if we move dex files under the common app path. 9100 /* nullable */ String[] instructionSets; 9101 9102 InstallArgs(File originFile, boolean originStaged, IPackageInstallObserver2 observer, 9103 int flags, String installerPackageName, ManifestDigest manifestDigest, 9104 UserHandle user, String[] instructionSets, 9105 String abiOverride, boolean multiArch) { 9106 this.originFile = originFile; 9107 this.originStaged = originStaged; 9108 this.flags = flags; 9109 this.observer = observer; 9110 this.installerPackageName = installerPackageName; 9111 this.manifestDigest = manifestDigest; 9112 this.user = user; 9113 this.instructionSets = instructionSets; 9114 this.abiOverride = abiOverride; 9115 this.multiArch = multiArch; 9116 } 9117 9118 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 9119 abstract int doPreInstall(int status); 9120 9121 /** 9122 * Rename package into final resting place. All paths on the given 9123 * scanned package should be updated to reflect the rename. 9124 */ 9125 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 9126 abstract int doPostInstall(int status, int uid); 9127 9128 /** @see PackageSettingBase#codePathString */ 9129 abstract String getCodePath(); 9130 /** @see PackageSettingBase#resourcePathString */ 9131 abstract String getResourcePath(); 9132 abstract String getLegacyNativeLibraryPath(); 9133 9134 // Need installer lock especially for dex file removal. 9135 abstract void cleanUpResourcesLI(); 9136 abstract boolean doPostDeleteLI(boolean delete); 9137 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 9138 9139 /** 9140 * Called before the source arguments are copied. This is used mostly 9141 * for MoveParams when it needs to read the source file to put it in the 9142 * destination. 9143 */ 9144 int doPreCopy() { 9145 return PackageManager.INSTALL_SUCCEEDED; 9146 } 9147 9148 /** 9149 * Called after the source arguments are copied. This is used mostly for 9150 * MoveParams when it needs to read the source file to put it in the 9151 * destination. 9152 * 9153 * @return 9154 */ 9155 int doPostCopy(int uid) { 9156 return PackageManager.INSTALL_SUCCEEDED; 9157 } 9158 9159 protected boolean isFwdLocked() { 9160 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 9161 } 9162 9163 UserHandle getUser() { 9164 return user; 9165 } 9166 } 9167 9168 /** 9169 * Logic to handle installation of non-ASEC applications, including copying 9170 * and renaming logic. 9171 */ 9172 class FileInstallArgs extends InstallArgs { 9173 private File codeFile; 9174 private File resourceFile; 9175 private File legacyNativeLibraryPath; 9176 9177 // Example topology: 9178 // /data/app/com.example/base.apk 9179 // /data/app/com.example/split_foo.apk 9180 // /data/app/com.example/lib/arm/libfoo.so 9181 // /data/app/com.example/lib/arm64/libfoo.so 9182 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 9183 9184 /** New install */ 9185 FileInstallArgs(InstallParams params) { 9186 super(params.originFile, params.originStaged, params.observer, params.flags, 9187 params.installerPackageName, params.getManifestDigest(), params.getUser(), 9188 null /* instruction sets */, params.packageAbiOverride, 9189 params.multiArch); 9190 if (isFwdLocked()) { 9191 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 9192 } 9193 } 9194 9195 /** Existing install */ 9196 FileInstallArgs(String codePath, String resourcePath, String legacyNativeLibraryPath, 9197 String[] instructionSets, boolean isMultiArch) { 9198 super(null, false, null, 0, null, null, null, instructionSets, null, isMultiArch); 9199 this.codeFile = (codePath != null) ? new File(codePath) : null; 9200 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 9201 this.legacyNativeLibraryPath = (legacyNativeLibraryPath != null) ? 9202 new File(legacyNativeLibraryPath) : null; 9203 } 9204 9205 /** New install from existing */ 9206 FileInstallArgs(File originFile, String[] instructionSets, boolean isMultiArch) { 9207 super(originFile, false, null, 0, null, null, null, instructionSets, null, 9208 isMultiArch); 9209 } 9210 9211 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 9212 final long lowThreshold; 9213 9214 final DeviceStorageMonitorInternal 9215 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 9216 if (dsm == null) { 9217 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 9218 lowThreshold = 0L; 9219 } else { 9220 if (dsm.isMemoryLow()) { 9221 Log.w(TAG, "Memory is reported as being too low; aborting package install"); 9222 return false; 9223 } 9224 9225 lowThreshold = dsm.getMemoryLowThreshold(); 9226 } 9227 9228 return imcs.checkInternalFreeStorage(originFile.getAbsolutePath(), isFwdLocked(), 9229 lowThreshold); 9230 } 9231 9232 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 9233 int ret = PackageManager.INSTALL_SUCCEEDED; 9234 9235 if (originStaged) { 9236 Slog.d(TAG, originFile + " already staged; skipping copy"); 9237 codeFile = originFile; 9238 resourceFile = originFile; 9239 } else { 9240 try { 9241 final File tempDir = mInstallerService.allocateSessionDir(); 9242 codeFile = tempDir; 9243 resourceFile = tempDir; 9244 } catch (IOException e) { 9245 Slog.w(TAG, "Failed to create copy file: " + e); 9246 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9247 } 9248 9249 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 9250 @Override 9251 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 9252 if (!FileUtils.isValidExtFilename(name)) { 9253 throw new IllegalArgumentException("Invalid filename: " + name); 9254 } 9255 try { 9256 final File file = new File(codeFile, name); 9257 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 9258 O_RDWR | O_CREAT, 0644); 9259 Os.chmod(file.getAbsolutePath(), 0644); 9260 return new ParcelFileDescriptor(fd); 9261 } catch (ErrnoException e) { 9262 throw new RemoteException("Failed to open: " + e.getMessage()); 9263 } 9264 } 9265 }; 9266 9267 ret = imcs.copyPackage(originFile.getAbsolutePath(), target); 9268 if (ret != PackageManager.INSTALL_SUCCEEDED) { 9269 Slog.e(TAG, "Failed to copy package"); 9270 return ret; 9271 } 9272 } 9273 9274 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 9275 NativeLibraryHelper.Handle handle = null; 9276 try { 9277 handle = NativeLibraryHelper.Handle.create(codeFile); 9278 if (multiArch) { 9279 // Warn if we've set an abiOverride for multi-lib packages.. 9280 // By definition, we need to copy both 32 and 64 bit libraries for 9281 // such packages. 9282 if (abiOverride != null) { 9283 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 9284 } 9285 9286 int copyRet = PackageManager.NO_NATIVE_LIBRARIES; 9287 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 9288 copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot, 9289 Build.SUPPORTED_32_BIT_ABIS, true /* use isa specific subdirs */); 9290 maybeThrowExceptionForMultiArchCopy("Failure copying 32 bit native libraries", copyRet); 9291 } 9292 9293 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 9294 copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot, 9295 Build.SUPPORTED_64_BIT_ABIS, true /* use isa specific subdirs */); 9296 maybeThrowExceptionForMultiArchCopy("Failure copying 64 bit native libraries", copyRet); 9297 } 9298 } else { 9299 String[] abiList = (abiOverride != null) ? 9300 new String[] { abiOverride } : Build.SUPPORTED_ABIS; 9301 9302 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && abiOverride == null && 9303 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 9304 abiList = Build.SUPPORTED_32_BIT_ABIS; 9305 } 9306 9307 int copyRet = copyNativeLibrariesForInternalApp(handle, libraryRoot, abiList, 9308 true /* use isa specific subdirs */); 9309 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 9310 Slog.w(TAG, "Failure copying native libraries [errorCode=" + copyRet + "]"); 9311 return copyRet; 9312 } 9313 } 9314 } catch (IOException e) { 9315 Slog.e(TAG, "Copying native libraries failed", e); 9316 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 9317 } catch (PackageManagerException pme) { 9318 Slog.e(TAG, "Copying native libraries failed", pme); 9319 ret = pme.error; 9320 } finally { 9321 IoUtils.closeQuietly(handle); 9322 } 9323 9324 return ret; 9325 } 9326 9327 int doPreInstall(int status) { 9328 if (status != PackageManager.INSTALL_SUCCEEDED) { 9329 cleanUp(); 9330 } 9331 return status; 9332 } 9333 9334 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 9335 if (status != PackageManager.INSTALL_SUCCEEDED) { 9336 cleanUp(); 9337 return false; 9338 } else { 9339 final File beforeCodeFile = codeFile; 9340 final File afterCodeFile = getNextCodePath(pkg.packageName); 9341 9342 Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 9343 try { 9344 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 9345 } catch (ErrnoException e) { 9346 Slog.d(TAG, "Failed to rename", e); 9347 return false; 9348 } 9349 9350 if (!SELinux.restoreconRecursive(afterCodeFile)) { 9351 Slog.d(TAG, "Failed to restorecon"); 9352 return false; 9353 } 9354 9355 // Reflect the rename internally 9356 codeFile = afterCodeFile; 9357 resourceFile = afterCodeFile; 9358 9359 // Reflect the rename in scanned details 9360 pkg.codePath = afterCodeFile.getAbsolutePath(); 9361 pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 9362 pkg.baseCodePath); 9363 pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile, 9364 pkg.splitCodePaths); 9365 9366 // Reflect the rename in app info 9367 pkg.applicationInfo.setCodePath(pkg.codePath); 9368 pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath); 9369 pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths); 9370 pkg.applicationInfo.setResourcePath(pkg.codePath); 9371 pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath); 9372 pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths); 9373 9374 return true; 9375 } 9376 } 9377 9378 int doPostInstall(int status, int uid) { 9379 if (status != PackageManager.INSTALL_SUCCEEDED) { 9380 cleanUp(); 9381 } 9382 return status; 9383 } 9384 9385 @Override 9386 String getCodePath() { 9387 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 9388 } 9389 9390 @Override 9391 String getResourcePath() { 9392 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 9393 } 9394 9395 @Override 9396 String getLegacyNativeLibraryPath() { 9397 return (legacyNativeLibraryPath != null) ? legacyNativeLibraryPath.getAbsolutePath() : null; 9398 } 9399 9400 private boolean cleanUp() { 9401 if (codeFile == null || !codeFile.exists()) { 9402 return false; 9403 } 9404 9405 if (codeFile.isDirectory()) { 9406 FileUtils.deleteContents(codeFile); 9407 } 9408 codeFile.delete(); 9409 9410 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 9411 resourceFile.delete(); 9412 } 9413 9414 if (legacyNativeLibraryPath != null && !FileUtils.contains(codeFile, legacyNativeLibraryPath)) { 9415 if (!FileUtils.deleteContents(legacyNativeLibraryPath)) { 9416 Slog.w(TAG, "Couldn't delete native library directory " + legacyNativeLibraryPath); 9417 } 9418 legacyNativeLibraryPath.delete(); 9419 } 9420 9421 return true; 9422 } 9423 9424 void cleanUpResourcesLI() { 9425 // Try enumerating all code paths before deleting 9426 List<String> allCodePaths = Collections.EMPTY_LIST; 9427 if (codeFile != null && codeFile.exists()) { 9428 try { 9429 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 9430 allCodePaths = pkg.getAllCodePaths(); 9431 } catch (PackageParserException e) { 9432 // Ignored; we tried our best 9433 } 9434 } 9435 9436 cleanUp(); 9437 9438 if (!allCodePaths.isEmpty()) { 9439 if (instructionSets == null) { 9440 throw new IllegalStateException("instructionSet == null"); 9441 } 9442 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 9443 for (String codePath : allCodePaths) { 9444 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 9445 int retCode = mInstaller.rmdex(codePath, dexCodeInstructionSet); 9446 if (retCode < 0) { 9447 Slog.w(TAG, "Couldn't remove dex file for package: " 9448 + " at location " + codePath + ", retcode=" + retCode); 9449 // we don't consider this to be a failure of the core package deletion 9450 } 9451 } 9452 } 9453 } 9454 } 9455 9456 boolean doPostDeleteLI(boolean delete) { 9457 // XXX err, shouldn't we respect the delete flag? 9458 cleanUpResourcesLI(); 9459 return true; 9460 } 9461 } 9462 9463 private boolean isAsecExternal(String cid) { 9464 final String asecPath = PackageHelper.getSdFilesystem(cid); 9465 return !asecPath.startsWith(mAsecInternalPath); 9466 } 9467 9468 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 9469 PackageManagerException { 9470 if (copyRet < 0) { 9471 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 9472 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 9473 throw new PackageManagerException(copyRet, message); 9474 } 9475 } 9476 } 9477 9478 /** 9479 * Extract the MountService "container ID" from the full code path of an 9480 * .apk. 9481 */ 9482 static String cidFromCodePath(String fullCodePath) { 9483 int eidx = fullCodePath.lastIndexOf("/"); 9484 String subStr1 = fullCodePath.substring(0, eidx); 9485 int sidx = subStr1.lastIndexOf("/"); 9486 return subStr1.substring(sidx+1, eidx); 9487 } 9488 9489 /** 9490 * Logic to handle installation of ASEC applications, including copying and 9491 * renaming logic. 9492 */ 9493 class AsecInstallArgs extends InstallArgs { 9494 // TODO: teach about handling cluster directories 9495 9496 static final String RES_FILE_NAME = "pkg.apk"; 9497 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 9498 9499 String cid; 9500 String packagePath; 9501 String resourcePath; 9502 String legacyNativeLibraryDir; 9503 9504 /** New install */ 9505 AsecInstallArgs(InstallParams params) { 9506 super(params.originFile, params.originStaged, params.observer, params.flags, 9507 params.installerPackageName, params.getManifestDigest(), 9508 params.getUser(), null /* instruction sets */, 9509 params.packageAbiOverride, params.multiArch); 9510 } 9511 9512 /** Existing install */ 9513 AsecInstallArgs(String fullCodePath, String[] instructionSets, 9514 boolean isExternal, boolean isForwardLocked, boolean isMultiArch) { 9515 super(null, false, null, (isExternal ? INSTALL_EXTERNAL : 0) 9516 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 9517 instructionSets, null, isMultiArch); 9518 // Extract cid from fullCodePath 9519 int eidx = fullCodePath.lastIndexOf("/"); 9520 String subStr1 = fullCodePath.substring(0, eidx); 9521 int sidx = subStr1.lastIndexOf("/"); 9522 cid = subStr1.substring(sidx+1, eidx); 9523 setCachePath(subStr1); 9524 } 9525 9526 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked, 9527 boolean isMultiArch) { 9528 super(null, false, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 9529 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 9530 instructionSets, null, isMultiArch); 9531 this.cid = cid; 9532 setCachePath(PackageHelper.getSdDir(cid)); 9533 } 9534 9535 /** New install from existing */ 9536 AsecInstallArgs(File originPackageFile, String cid, String[] instructionSets, 9537 boolean isExternal, boolean isForwardLocked, boolean isMultiArch) { 9538 super(originPackageFile, false, null, (isExternal ? INSTALL_EXTERNAL : 0) 9539 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 9540 instructionSets, null, isMultiArch); 9541 this.cid = cid; 9542 } 9543 9544 void createCopyFile() { 9545 cid = getTempContainerId(); 9546 } 9547 9548 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 9549 return imcs.checkExternalFreeStorage(originFile.getAbsolutePath(), isFwdLocked(), 9550 abiOverride); 9551 } 9552 9553 private final boolean isExternal() { 9554 return (flags & PackageManager.INSTALL_EXTERNAL) != 0; 9555 } 9556 9557 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 9558 if (temp) { 9559 createCopyFile(); 9560 } else { 9561 /* 9562 * Pre-emptively destroy the container since it's destroyed if 9563 * copying fails due to it existing anyway. 9564 */ 9565 PackageHelper.destroySdDir(cid); 9566 } 9567 9568 final String newCachePath = imcs.copyPackageToContainer( 9569 originFile.getAbsolutePath(), cid, getEncryptKey(), isExternal(), 9570 isFwdLocked(), abiOverride); 9571 9572 if (newCachePath != null) { 9573 setCachePath(newCachePath); 9574 return PackageManager.INSTALL_SUCCEEDED; 9575 } else { 9576 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9577 } 9578 } 9579 9580 @Override 9581 String getCodePath() { 9582 return packagePath; 9583 } 9584 9585 @Override 9586 String getResourcePath() { 9587 return resourcePath; 9588 } 9589 9590 @Override 9591 String getLegacyNativeLibraryPath() { 9592 return legacyNativeLibraryDir; 9593 } 9594 9595 int doPreInstall(int status) { 9596 if (status != PackageManager.INSTALL_SUCCEEDED) { 9597 // Destroy container 9598 PackageHelper.destroySdDir(cid); 9599 } else { 9600 boolean mounted = PackageHelper.isContainerMounted(cid); 9601 if (!mounted) { 9602 String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(), 9603 Process.SYSTEM_UID); 9604 if (newCachePath != null) { 9605 setCachePath(newCachePath); 9606 } else { 9607 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9608 } 9609 } 9610 } 9611 return status; 9612 } 9613 9614 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 9615 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 9616 String newCachePath = null; 9617 if (PackageHelper.isContainerMounted(cid)) { 9618 // Unmount the container 9619 if (!PackageHelper.unMountSdDir(cid)) { 9620 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 9621 return false; 9622 } 9623 } 9624 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 9625 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 9626 " which might be stale. Will try to clean up."); 9627 // Clean up the stale container and proceed to recreate. 9628 if (!PackageHelper.destroySdDir(newCacheId)) { 9629 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 9630 return false; 9631 } 9632 // Successfully cleaned up stale container. Try to rename again. 9633 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 9634 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 9635 + " inspite of cleaning it up."); 9636 return false; 9637 } 9638 } 9639 if (!PackageHelper.isContainerMounted(newCacheId)) { 9640 Slog.w(TAG, "Mounting container " + newCacheId); 9641 newCachePath = PackageHelper.mountSdDir(newCacheId, 9642 getEncryptKey(), Process.SYSTEM_UID); 9643 } else { 9644 newCachePath = PackageHelper.getSdDir(newCacheId); 9645 } 9646 if (newCachePath == null) { 9647 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 9648 return false; 9649 } 9650 Log.i(TAG, "Succesfully renamed " + cid + 9651 " to " + newCacheId + 9652 " at new path: " + newCachePath); 9653 cid = newCacheId; 9654 setCachePath(newCachePath); 9655 9656 // TODO: extend to support split APKs 9657 pkg.codePath = getCodePath(); 9658 pkg.baseCodePath = getCodePath(); 9659 pkg.splitCodePaths = null; 9660 9661 pkg.applicationInfo.setCodePath(getCodePath()); 9662 pkg.applicationInfo.setBaseCodePath(getCodePath()); 9663 pkg.applicationInfo.setSplitCodePaths(null); 9664 pkg.applicationInfo.setResourcePath(getResourcePath()); 9665 pkg.applicationInfo.setBaseResourcePath(getResourcePath()); 9666 pkg.applicationInfo.setSplitResourcePaths(null); 9667 9668 return true; 9669 } 9670 9671 private void setCachePath(String newCachePath) { 9672 File cachePath = new File(newCachePath); 9673 legacyNativeLibraryDir = new File(cachePath, LIB_DIR_NAME).getPath(); 9674 packagePath = new File(cachePath, RES_FILE_NAME).getPath(); 9675 9676 if (isFwdLocked()) { 9677 resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath(); 9678 } else { 9679 resourcePath = packagePath; 9680 } 9681 } 9682 9683 int doPostInstall(int status, int uid) { 9684 if (status != PackageManager.INSTALL_SUCCEEDED) { 9685 cleanUp(); 9686 } else { 9687 final int groupOwner; 9688 final String protectedFile; 9689 if (isFwdLocked()) { 9690 groupOwner = UserHandle.getSharedAppGid(uid); 9691 protectedFile = RES_FILE_NAME; 9692 } else { 9693 groupOwner = -1; 9694 protectedFile = null; 9695 } 9696 9697 if (uid < Process.FIRST_APPLICATION_UID 9698 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 9699 Slog.e(TAG, "Failed to finalize " + cid); 9700 PackageHelper.destroySdDir(cid); 9701 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9702 } 9703 9704 boolean mounted = PackageHelper.isContainerMounted(cid); 9705 if (!mounted) { 9706 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 9707 } 9708 } 9709 return status; 9710 } 9711 9712 private void cleanUp() { 9713 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 9714 9715 // Destroy secure container 9716 PackageHelper.destroySdDir(cid); 9717 } 9718 9719 void cleanUpResourcesLI() { 9720 String sourceFile = getCodePath(); 9721 // Remove dex file 9722 if (instructionSets == null) { 9723 throw new IllegalStateException("instructionSet == null"); 9724 } 9725 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 9726 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 9727 int retCode = mInstaller.rmdex(sourceFile, dexCodeInstructionSet); 9728 if (retCode < 0) { 9729 Slog.w(TAG, "Couldn't remove dex file for package: " 9730 + " at location " 9731 + sourceFile.toString() + ", retcode=" + retCode); 9732 // we don't consider this to be a failure of the core package deletion 9733 } 9734 } 9735 cleanUp(); 9736 } 9737 9738 boolean matchContainer(String app) { 9739 if (cid.startsWith(app)) { 9740 return true; 9741 } 9742 return false; 9743 } 9744 9745 String getPackageName() { 9746 return getAsecPackageName(cid); 9747 } 9748 9749 boolean doPostDeleteLI(boolean delete) { 9750 boolean ret = false; 9751 boolean mounted = PackageHelper.isContainerMounted(cid); 9752 if (mounted) { 9753 // Unmount first 9754 ret = PackageHelper.unMountSdDir(cid); 9755 } 9756 if (ret && delete) { 9757 cleanUpResourcesLI(); 9758 } 9759 return ret; 9760 } 9761 9762 @Override 9763 int doPreCopy() { 9764 if (isFwdLocked()) { 9765 if (!PackageHelper.fixSdPermissions(cid, 9766 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 9767 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9768 } 9769 } 9770 9771 return PackageManager.INSTALL_SUCCEEDED; 9772 } 9773 9774 @Override 9775 int doPostCopy(int uid) { 9776 if (isFwdLocked()) { 9777 if (uid < Process.FIRST_APPLICATION_UID 9778 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 9779 RES_FILE_NAME)) { 9780 Slog.e(TAG, "Failed to finalize " + cid); 9781 PackageHelper.destroySdDir(cid); 9782 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9783 } 9784 } 9785 9786 return PackageManager.INSTALL_SUCCEEDED; 9787 } 9788 } 9789 9790 static String getAsecPackageName(String packageCid) { 9791 int idx = packageCid.lastIndexOf("-"); 9792 if (idx == -1) { 9793 return packageCid; 9794 } 9795 return packageCid.substring(0, idx); 9796 } 9797 9798 // Utility method used to create code paths based on package name and available index. 9799 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 9800 String idxStr = ""; 9801 int idx = 1; 9802 // Fall back to default value of idx=1 if prefix is not 9803 // part of oldCodePath 9804 if (oldCodePath != null) { 9805 String subStr = oldCodePath; 9806 // Drop the suffix right away 9807 if (suffix != null && subStr.endsWith(suffix)) { 9808 subStr = subStr.substring(0, subStr.length() - suffix.length()); 9809 } 9810 // If oldCodePath already contains prefix find out the 9811 // ending index to either increment or decrement. 9812 int sidx = subStr.lastIndexOf(prefix); 9813 if (sidx != -1) { 9814 subStr = subStr.substring(sidx + prefix.length()); 9815 if (subStr != null) { 9816 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 9817 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 9818 } 9819 try { 9820 idx = Integer.parseInt(subStr); 9821 if (idx <= 1) { 9822 idx++; 9823 } else { 9824 idx--; 9825 } 9826 } catch(NumberFormatException e) { 9827 } 9828 } 9829 } 9830 } 9831 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 9832 return prefix + idxStr; 9833 } 9834 9835 private File getNextCodePath(String packageName) { 9836 int suffix = 1; 9837 File result; 9838 do { 9839 result = new File(mAppInstallDir, packageName + "-" + suffix); 9840 suffix++; 9841 } while (result.exists()); 9842 return result; 9843 } 9844 9845 // Utility method used to ignore ADD/REMOVE events 9846 // by directory observer. 9847 private static boolean ignoreCodePath(String fullPathStr) { 9848 String apkName = deriveCodePathName(fullPathStr); 9849 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX); 9850 if (idx != -1 && ((idx+1) < apkName.length())) { 9851 // Make sure the package ends with a numeral 9852 String version = apkName.substring(idx+1); 9853 try { 9854 Integer.parseInt(version); 9855 return true; 9856 } catch (NumberFormatException e) {} 9857 } 9858 return false; 9859 } 9860 9861 // Utility method that returns the relative package path with respect 9862 // to the installation directory. Like say for /data/data/com.test-1.apk 9863 // string com.test-1 is returned. 9864 static String deriveCodePathName(String codePath) { 9865 if (codePath == null) { 9866 return null; 9867 } 9868 final File codeFile = new File(codePath); 9869 final String name = codeFile.getName(); 9870 if (codeFile.isDirectory()) { 9871 return name; 9872 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 9873 final int lastDot = name.lastIndexOf('.'); 9874 return name.substring(0, lastDot); 9875 } else { 9876 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 9877 return null; 9878 } 9879 } 9880 9881 class PackageInstalledInfo { 9882 String name; 9883 int uid; 9884 // The set of users that originally had this package installed. 9885 int[] origUsers; 9886 // The set of users that now have this package installed. 9887 int[] newUsers; 9888 PackageParser.Package pkg; 9889 int returnCode; 9890 String returnMsg; 9891 PackageRemovedInfo removedInfo; 9892 9893 public void setError(int code, String msg) { 9894 returnCode = code; 9895 returnMsg = msg; 9896 Slog.w(TAG, msg); 9897 } 9898 9899 public void setError(String msg, PackageParserException e) { 9900 returnCode = e.error; 9901 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 9902 Slog.w(TAG, msg, e); 9903 } 9904 9905 public void setError(String msg, PackageManagerException e) { 9906 returnCode = e.error; 9907 returnMsg = ExceptionUtils.getCompleteMessage(msg, e); 9908 Slog.w(TAG, msg, e); 9909 } 9910 9911 // In some error cases we want to convey more info back to the observer 9912 String origPackage; 9913 String origPermission; 9914 } 9915 9916 /* 9917 * Install a non-existing package. 9918 */ 9919 private void installNewPackageLI(PackageParser.Package pkg, 9920 int parseFlags, int scanMode, UserHandle user, 9921 String installerPackageName, PackageInstalledInfo res, String abiOverride) { 9922 // Remember this for later, in case we need to rollback this install 9923 String pkgName = pkg.packageName; 9924 9925 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 9926 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists(); 9927 synchronized(mPackages) { 9928 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 9929 // A package with the same name is already installed, though 9930 // it has been renamed to an older name. The package we 9931 // are trying to install should be installed as an update to 9932 // the existing one, but that has not been requested, so bail. 9933 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 9934 + " without first uninstalling package running as " 9935 + mSettings.mRenamedPackages.get(pkgName)); 9936 return; 9937 } 9938 if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.codePath)) { 9939 // Don't allow installation over an existing package with the same name. 9940 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 9941 + " without first uninstalling."); 9942 return; 9943 } 9944 } 9945 9946 try { 9947 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode, 9948 System.currentTimeMillis(), user, abiOverride); 9949 9950 updateSettingsLI(newPackage, installerPackageName, null, null, res); 9951 // delete the partially installed application. the data directory will have to be 9952 // restored if it was already existing 9953 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 9954 // remove package from internal structures. Note that we want deletePackageX to 9955 // delete the package data and cache directories that it created in 9956 // scanPackageLocked, unless those directories existed before we even tried to 9957 // install. 9958 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 9959 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 9960 res.removedInfo, true); 9961 } 9962 9963 } catch (PackageManagerException e) { 9964 res.setError("Package couldn't be installed in " + pkg.codePath, e); 9965 } 9966 } 9967 9968 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 9969 // Upgrade keysets are being used. Determine if new package has a superset of the 9970 // required keys. 9971 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 9972 KeySetManagerService ksms = mSettings.mKeySetManagerService; 9973 for (int i = 0; i < upgradeKeySets.length; i++) { 9974 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 9975 if (newPkg.mSigningKeys.containsAll(upgradeSet)) { 9976 return true; 9977 } 9978 } 9979 return false; 9980 } 9981 9982 private void replacePackageLI(PackageParser.Package pkg, 9983 int parseFlags, int scanMode, UserHandle user, 9984 String installerPackageName, PackageInstalledInfo res, String abiOverride) { 9985 PackageParser.Package oldPackage; 9986 String pkgName = pkg.packageName; 9987 int[] allUsers; 9988 boolean[] perUserInstalled; 9989 9990 // First find the old package info and check signatures 9991 synchronized(mPackages) { 9992 oldPackage = mPackages.get(pkgName); 9993 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 9994 PackageSetting ps = mSettings.mPackages.get(pkgName); 9995 if (ps == null || !ps.keySetData.isUsingUpgradeKeySets() || ps.sharedUser != null) { 9996 // default to original signature matching 9997 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 9998 != PackageManager.SIGNATURE_MATCH) { 9999 res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 10000 "New package has a different signature: " + pkgName); 10001 return; 10002 } 10003 } else { 10004 if(!checkUpgradeKeySetLP(ps, pkg)) { 10005 res.setError(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 10006 "New package not signed by keys specified by upgrade-keysets: " 10007 + pkgName); 10008 return; 10009 } 10010 } 10011 10012 // In case of rollback, remember per-user/profile install state 10013 allUsers = sUserManager.getUserIds(); 10014 perUserInstalled = new boolean[allUsers.length]; 10015 for (int i = 0; i < allUsers.length; i++) { 10016 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 10017 } 10018 } 10019 10020 boolean sysPkg = (isSystemApp(oldPackage)); 10021 if (sysPkg) { 10022 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, 10023 user, allUsers, perUserInstalled, installerPackageName, res, 10024 abiOverride); 10025 } else { 10026 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, 10027 user, allUsers, perUserInstalled, installerPackageName, res, 10028 abiOverride); 10029 } 10030 } 10031 10032 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 10033 PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, 10034 int[] allUsers, boolean[] perUserInstalled, 10035 String installerPackageName, PackageInstalledInfo res, String abiOverride) { 10036 String pkgName = deletedPackage.packageName; 10037 boolean deletedPkg = true; 10038 boolean updatedSettings = false; 10039 10040 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 10041 + deletedPackage); 10042 long origUpdateTime; 10043 if (pkg.mExtras != null) { 10044 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 10045 } else { 10046 origUpdateTime = 0; 10047 } 10048 10049 // First delete the existing package while retaining the data directory 10050 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 10051 res.removedInfo, true)) { 10052 // If the existing package wasn't successfully deleted 10053 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 10054 deletedPkg = false; 10055 } else { 10056 // Successfully deleted the old package. Now proceed with re-installation 10057 deleteCodeCacheDirsLI(pkgName); 10058 try { 10059 final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, 10060 scanMode | SCAN_UPDATE_TIME, System.currentTimeMillis(), user, abiOverride); 10061 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); 10062 updatedSettings = true; 10063 } catch (PackageManagerException e) { 10064 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10065 } 10066 } 10067 10068 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10069 // remove package from internal structures. Note that we want deletePackageX to 10070 // delete the package data and cache directories that it created in 10071 // scanPackageLocked, unless those directories existed before we even tried to 10072 // install. 10073 if(updatedSettings) { 10074 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 10075 deletePackageLI( 10076 pkgName, null, true, allUsers, perUserInstalled, 10077 PackageManager.DELETE_KEEP_DATA, 10078 res.removedInfo, true); 10079 } 10080 // Since we failed to install the new package we need to restore the old 10081 // package that we deleted. 10082 if (deletedPkg) { 10083 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 10084 File restoreFile = new File(deletedPackage.codePath); 10085 // Parse old package 10086 boolean oldOnSd = isExternal(deletedPackage); 10087 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 10088 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) | 10089 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0); 10090 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE 10091 | SCAN_UPDATE_TIME; 10092 try { 10093 scanPackageLI(restoreFile, oldParseFlags, oldScanMode, origUpdateTime, null, 10094 null); 10095 } catch (PackageManagerException e) { 10096 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 10097 + e.getMessage()); 10098 return; 10099 } 10100 // Restore of old package succeeded. Update permissions. 10101 // writer 10102 synchronized (mPackages) { 10103 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 10104 UPDATE_PERMISSIONS_ALL); 10105 // can downgrade to reader 10106 mSettings.writeLPr(); 10107 } 10108 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 10109 } 10110 } 10111 } 10112 10113 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 10114 PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, 10115 int[] allUsers, boolean[] perUserInstalled, 10116 String installerPackageName, PackageInstalledInfo res, String abiOverride) { 10117 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 10118 + ", old=" + deletedPackage); 10119 boolean updatedSettings = false; 10120 parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING | 10121 PackageParser.PARSE_IS_SYSTEM; 10122 if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) { 10123 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 10124 } 10125 String packageName = deletedPackage.packageName; 10126 if (packageName == null) { 10127 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 10128 "Attempt to delete null packageName."); 10129 return; 10130 } 10131 PackageParser.Package oldPkg; 10132 PackageSetting oldPkgSetting; 10133 // reader 10134 synchronized (mPackages) { 10135 oldPkg = mPackages.get(packageName); 10136 oldPkgSetting = mSettings.mPackages.get(packageName); 10137 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 10138 (oldPkgSetting == null)) { 10139 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, 10140 "Couldn't find package:" + packageName + " information"); 10141 return; 10142 } 10143 } 10144 10145 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); 10146 10147 res.removedInfo.uid = oldPkg.applicationInfo.uid; 10148 res.removedInfo.removedPackage = packageName; 10149 // Remove existing system package 10150 removePackageLI(oldPkgSetting, true); 10151 // writer 10152 synchronized (mPackages) { 10153 if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) { 10154 // We didn't need to disable the .apk as a current system package, 10155 // which means we are replacing another update that is already 10156 // installed. We need to make sure to delete the older one's .apk. 10157 res.removedInfo.args = createInstallArgsForExisting(0, 10158 deletedPackage.applicationInfo.getCodePath(), 10159 deletedPackage.applicationInfo.getResourcePath(), 10160 deletedPackage.applicationInfo.nativeLibraryRootDir, 10161 getAppDexInstructionSets(deletedPackage.applicationInfo), 10162 isMultiArch(deletedPackage.applicationInfo)); 10163 } else { 10164 res.removedInfo.args = null; 10165 } 10166 } 10167 10168 // Successfully disabled the old package. Now proceed with re-installation 10169 deleteCodeCacheDirsLI(packageName); 10170 10171 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 10172 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 10173 10174 PackageParser.Package newPackage = null; 10175 try { 10176 newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user, abiOverride); 10177 if (newPackage.mExtras != null) { 10178 final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras; 10179 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 10180 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 10181 10182 // is the update attempting to change shared user? that isn't going to work... 10183 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 10184 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 10185 "Forbidding shared user change from " + oldPkgSetting.sharedUser 10186 + " to " + newPkgSetting.sharedUser); 10187 updatedSettings = true; 10188 } 10189 } 10190 10191 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 10192 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); 10193 updatedSettings = true; 10194 } 10195 10196 } catch (PackageManagerException e) { 10197 res.setError("Package couldn't be installed in " + pkg.codePath, e); 10198 } 10199 10200 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 10201 // Re installation failed. Restore old information 10202 // Remove new pkg information 10203 if (newPackage != null) { 10204 removeInstalledPackageLI(newPackage, true); 10205 } 10206 // Add back the old system package 10207 try { 10208 scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user, 10209 null); 10210 } catch (PackageManagerException e) { 10211 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 10212 } 10213 // Restore the old system information in Settings 10214 synchronized(mPackages) { 10215 if (updatedSettings) { 10216 mSettings.enableSystemPackageLPw(packageName); 10217 mSettings.setInstallerPackageName(packageName, 10218 oldPkgSetting.installerPackageName); 10219 } 10220 mSettings.writeLPr(); 10221 } 10222 } 10223 } 10224 10225 // Utility method used to move dex files during install. 10226 private int moveDexFilesLI(String oldCodePath, PackageParser.Package newPackage) { 10227 // TODO: extend to move split APK dex files 10228 if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 10229 final String[] instructionSets = getAppDexInstructionSets(newPackage.applicationInfo); 10230 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 10231 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 10232 int retCode = mInstaller.movedex(oldCodePath, newPackage.baseCodePath, 10233 dexCodeInstructionSet); 10234 if (retCode != 0) { 10235 /* 10236 * Programs may be lazily run through dexopt, so the 10237 * source may not exist. However, something seems to 10238 * have gone wrong, so note that dexopt needs to be 10239 * run again and remove the source file. In addition, 10240 * remove the target to make sure there isn't a stale 10241 * file from a previous version of the package. 10242 */ 10243 newPackage.mDexOptPerformed.clear(); 10244 mInstaller.rmdex(oldCodePath, dexCodeInstructionSet); 10245 mInstaller.rmdex(newPackage.baseCodePath, dexCodeInstructionSet); 10246 } 10247 } 10248 } 10249 return PackageManager.INSTALL_SUCCEEDED; 10250 } 10251 10252 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 10253 int[] allUsers, boolean[] perUserInstalled, 10254 PackageInstalledInfo res) { 10255 String pkgName = newPackage.packageName; 10256 synchronized (mPackages) { 10257 //write settings. the installStatus will be incomplete at this stage. 10258 //note that the new package setting would have already been 10259 //added to mPackages. It hasn't been persisted yet. 10260 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 10261 mSettings.writeLPr(); 10262 } 10263 10264 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 10265 10266 synchronized (mPackages) { 10267 updatePermissionsLPw(newPackage.packageName, newPackage, 10268 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 10269 ? UPDATE_PERMISSIONS_ALL : 0)); 10270 // For system-bundled packages, we assume that installing an upgraded version 10271 // of the package implies that the user actually wants to run that new code, 10272 // so we enable the package. 10273 if (isSystemApp(newPackage)) { 10274 // NB: implicit assumption that system package upgrades apply to all users 10275 if (DEBUG_INSTALL) { 10276 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 10277 } 10278 PackageSetting ps = mSettings.mPackages.get(pkgName); 10279 if (ps != null) { 10280 if (res.origUsers != null) { 10281 for (int userHandle : res.origUsers) { 10282 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 10283 userHandle, installerPackageName); 10284 } 10285 } 10286 // Also convey the prior install/uninstall state 10287 if (allUsers != null && perUserInstalled != null) { 10288 for (int i = 0; i < allUsers.length; i++) { 10289 if (DEBUG_INSTALL) { 10290 Slog.d(TAG, " user " + allUsers[i] 10291 + " => " + perUserInstalled[i]); 10292 } 10293 ps.setInstalled(perUserInstalled[i], allUsers[i]); 10294 } 10295 // these install state changes will be persisted in the 10296 // upcoming call to mSettings.writeLPr(). 10297 } 10298 } 10299 } 10300 res.name = pkgName; 10301 res.uid = newPackage.applicationInfo.uid; 10302 res.pkg = newPackage; 10303 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 10304 mSettings.setInstallerPackageName(pkgName, installerPackageName); 10305 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 10306 //to update install status 10307 mSettings.writeLPr(); 10308 } 10309 } 10310 10311 private void installPackageLI(InstallArgs args, boolean newInstall, PackageInstalledInfo res) { 10312 int pFlags = args.flags; 10313 String installerPackageName = args.installerPackageName; 10314 File tmpPackageFile = new File(args.getCodePath()); 10315 boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 10316 boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0); 10317 boolean replace = false; 10318 int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE 10319 | (newInstall ? SCAN_NEW_INSTALL : 0); 10320 // Result object to be returned 10321 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 10322 10323 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 10324 // Retrieve PackageSettings and parse package 10325 int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 10326 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 10327 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0); 10328 PackageParser pp = new PackageParser(); 10329 pp.setSeparateProcesses(mSeparateProcesses); 10330 pp.setDisplayMetrics(mMetrics); 10331 10332 final PackageParser.Package pkg; 10333 try { 10334 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 10335 } catch (PackageParserException e) { 10336 res.setError("Failed parse during installPackageLI", e); 10337 return; 10338 } 10339 10340 String pkgName = res.name = pkg.packageName; 10341 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 10342 if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) { 10343 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 10344 return; 10345 } 10346 } 10347 10348 try { 10349 pp.collectCertificates(pkg, parseFlags); 10350 pp.collectManifestDigest(pkg); 10351 } catch (PackageParserException e) { 10352 res.setError("Failed collect during installPackageLI", e); 10353 return; 10354 } 10355 10356 /* If the installer passed in a manifest digest, compare it now. */ 10357 if (args.manifestDigest != null) { 10358 if (DEBUG_INSTALL) { 10359 final String parsedManifest = pkg.manifestDigest == null ? "null" 10360 : pkg.manifestDigest.toString(); 10361 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 10362 + parsedManifest); 10363 } 10364 10365 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 10366 res.setError(INSTALL_FAILED_PACKAGE_CHANGED, "Manifest digest changed"); 10367 return; 10368 } 10369 } else if (DEBUG_INSTALL) { 10370 final String parsedManifest = pkg.manifestDigest == null 10371 ? "null" : pkg.manifestDigest.toString(); 10372 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 10373 } 10374 10375 // Get rid of all references to package scan path via parser. 10376 pp = null; 10377 String oldCodePath = null; 10378 boolean systemApp = false; 10379 synchronized (mPackages) { 10380 // Check whether the newly-scanned package wants to define an already-defined perm 10381 int N = pkg.permissions.size(); 10382 for (int i = N-1; i >= 0; i--) { 10383 PackageParser.Permission perm = pkg.permissions.get(i); 10384 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 10385 if (bp != null) { 10386 // If the defining package is signed with our cert, it's okay. This 10387 // also includes the "updating the same package" case, of course. 10388 if (compareSignatures(bp.packageSetting.signatures.mSignatures, 10389 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 10390 // If the owning package is the system itself, we log but allow 10391 // install to proceed; we fail the install on all other permission 10392 // redefinitions. 10393 if (!bp.sourcePackage.equals("android")) { 10394 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 10395 + pkg.packageName + " attempting to redeclare permission " 10396 + perm.info.name + " already owned by " + bp.sourcePackage); 10397 res.origPermission = perm.info.name; 10398 res.origPackage = bp.sourcePackage; 10399 return; 10400 } else { 10401 Slog.w(TAG, "Package " + pkg.packageName 10402 + " attempting to redeclare system permission " 10403 + perm.info.name + "; ignoring new declaration"); 10404 pkg.permissions.remove(i); 10405 } 10406 } 10407 } 10408 } 10409 10410 // Check if installing already existing package 10411 if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 10412 String oldName = mSettings.mRenamedPackages.get(pkgName); 10413 if (pkg.mOriginalPackages != null 10414 && pkg.mOriginalPackages.contains(oldName) 10415 && mPackages.containsKey(oldName)) { 10416 // This package is derived from an original package, 10417 // and this device has been updating from that original 10418 // name. We must continue using the original name, so 10419 // rename the new package here. 10420 pkg.setPackageName(oldName); 10421 pkgName = pkg.packageName; 10422 replace = true; 10423 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 10424 + oldName + " pkgName=" + pkgName); 10425 } else if (mPackages.containsKey(pkgName)) { 10426 // This package, under its official name, already exists 10427 // on the device; we should replace it. 10428 replace = true; 10429 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 10430 } 10431 } 10432 PackageSetting ps = mSettings.mPackages.get(pkgName); 10433 if (ps != null) { 10434 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 10435 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 10436 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 10437 systemApp = (ps.pkg.applicationInfo.flags & 10438 ApplicationInfo.FLAG_SYSTEM) != 0; 10439 } 10440 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 10441 } 10442 } 10443 10444 if (systemApp && onSd) { 10445 // Disable updates to system apps on sdcard 10446 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 10447 "Cannot install updates to system apps on sdcard"); 10448 return; 10449 } 10450 10451 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 10452 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 10453 return; 10454 } 10455 10456 if (replace) { 10457 replacePackageLI(pkg, parseFlags, scanMode, args.user, 10458 installerPackageName, res, args.abiOverride); 10459 } else { 10460 installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user, 10461 installerPackageName, res, args.abiOverride); 10462 } 10463 synchronized (mPackages) { 10464 final PackageSetting ps = mSettings.mPackages.get(pkgName); 10465 if (ps != null) { 10466 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 10467 } 10468 } 10469 } 10470 10471 private static boolean isForwardLocked(PackageParser.Package pkg) { 10472 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 10473 } 10474 10475 private static boolean isForwardLocked(ApplicationInfo info) { 10476 return (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 10477 } 10478 10479 private boolean isForwardLocked(PackageSetting ps) { 10480 return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 10481 } 10482 10483 private static boolean isMultiArch(PackageSetting ps) { 10484 return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0; 10485 } 10486 10487 private static boolean isMultiArch(ApplicationInfo info) { 10488 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 10489 } 10490 10491 private static boolean isExternal(PackageParser.Package pkg) { 10492 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 10493 } 10494 10495 private static boolean isExternal(PackageSetting ps) { 10496 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 10497 } 10498 10499 private static boolean isExternal(ApplicationInfo info) { 10500 return (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 10501 } 10502 10503 private static boolean isSystemApp(PackageParser.Package pkg) { 10504 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10505 } 10506 10507 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 10508 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0; 10509 } 10510 10511 private static boolean isSystemApp(ApplicationInfo info) { 10512 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10513 } 10514 10515 private static boolean isSystemApp(PackageSetting ps) { 10516 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 10517 } 10518 10519 private static boolean isUpdatedSystemApp(PackageSetting ps) { 10520 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 10521 } 10522 10523 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) { 10524 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 10525 } 10526 10527 private static boolean isUpdatedSystemApp(ApplicationInfo info) { 10528 return (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 10529 } 10530 10531 private int packageFlagsToInstallFlags(PackageSetting ps) { 10532 int installFlags = 0; 10533 if (isExternal(ps)) { 10534 installFlags |= PackageManager.INSTALL_EXTERNAL; 10535 } 10536 if (isForwardLocked(ps)) { 10537 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 10538 } 10539 return installFlags; 10540 } 10541 10542 private void deleteTempPackageFiles() { 10543 final FilenameFilter filter = new FilenameFilter() { 10544 public boolean accept(File dir, String name) { 10545 return name.startsWith("vmdl") && name.endsWith(".tmp"); 10546 } 10547 }; 10548 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 10549 file.delete(); 10550 } 10551 } 10552 10553 @Override 10554 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 10555 int flags) { 10556 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 10557 flags); 10558 } 10559 10560 @Override 10561 public void deletePackage(final String packageName, 10562 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 10563 mContext.enforceCallingOrSelfPermission( 10564 android.Manifest.permission.DELETE_PACKAGES, null); 10565 final int uid = Binder.getCallingUid(); 10566 if (UserHandle.getUserId(uid) != userId) { 10567 mContext.enforceCallingPermission( 10568 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10569 "deletePackage for user " + userId); 10570 } 10571 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 10572 try { 10573 observer.onPackageDeleted(packageName, 10574 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 10575 } catch (RemoteException re) { 10576 } 10577 return; 10578 } 10579 10580 boolean uninstallBlocked = false; 10581 if ((flags & PackageManager.DELETE_ALL_USERS) != 0) { 10582 int[] users = sUserManager.getUserIds(); 10583 for (int i = 0; i < users.length; ++i) { 10584 if (getBlockUninstallForUser(packageName, users[i])) { 10585 uninstallBlocked = true; 10586 break; 10587 } 10588 } 10589 } else { 10590 uninstallBlocked = getBlockUninstallForUser(packageName, userId); 10591 } 10592 if (uninstallBlocked) { 10593 try { 10594 observer.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_OWNER_BLOCKED, 10595 null); 10596 } catch (RemoteException re) { 10597 } 10598 return; 10599 } 10600 10601 if (DEBUG_REMOVE) { 10602 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 10603 } 10604 // Queue up an async operation since the package deletion may take a little while. 10605 mHandler.post(new Runnable() { 10606 public void run() { 10607 mHandler.removeCallbacks(this); 10608 final int returnCode = deletePackageX(packageName, userId, flags); 10609 if (observer != null) { 10610 try { 10611 observer.onPackageDeleted(packageName, returnCode, null); 10612 } catch (RemoteException e) { 10613 Log.i(TAG, "Observer no longer exists."); 10614 } //end catch 10615 } //end if 10616 } //end run 10617 }); 10618 } 10619 10620 private boolean isPackageDeviceAdmin(String packageName, int userId) { 10621 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 10622 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 10623 try { 10624 if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId) 10625 || dpm.isDeviceOwner(packageName))) { 10626 return true; 10627 } 10628 } catch (RemoteException e) { 10629 } 10630 return false; 10631 } 10632 10633 /** 10634 * This method is an internal method that could be get invoked either 10635 * to delete an installed package or to clean up a failed installation. 10636 * After deleting an installed package, a broadcast is sent to notify any 10637 * listeners that the package has been installed. For cleaning up a failed 10638 * installation, the broadcast is not necessary since the package's 10639 * installation wouldn't have sent the initial broadcast either 10640 * The key steps in deleting a package are 10641 * deleting the package information in internal structures like mPackages, 10642 * deleting the packages base directories through installd 10643 * updating mSettings to reflect current status 10644 * persisting settings for later use 10645 * sending a broadcast if necessary 10646 */ 10647 private int deletePackageX(String packageName, int userId, int flags) { 10648 final PackageRemovedInfo info = new PackageRemovedInfo(); 10649 final boolean res; 10650 10651 if (isPackageDeviceAdmin(packageName, userId)) { 10652 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 10653 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 10654 } 10655 10656 boolean removedForAllUsers = false; 10657 boolean systemUpdate = false; 10658 10659 // for the uninstall-updates case and restricted profiles, remember the per- 10660 // userhandle installed state 10661 int[] allUsers; 10662 boolean[] perUserInstalled; 10663 synchronized (mPackages) { 10664 PackageSetting ps = mSettings.mPackages.get(packageName); 10665 allUsers = sUserManager.getUserIds(); 10666 perUserInstalled = new boolean[allUsers.length]; 10667 for (int i = 0; i < allUsers.length; i++) { 10668 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 10669 } 10670 } 10671 10672 synchronized (mInstallLock) { 10673 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 10674 res = deletePackageLI(packageName, 10675 (flags & PackageManager.DELETE_ALL_USERS) != 0 10676 ? UserHandle.ALL : new UserHandle(userId), 10677 true, allUsers, perUserInstalled, 10678 flags | REMOVE_CHATTY, info, true); 10679 systemUpdate = info.isRemovedPackageSystemUpdate; 10680 if (res && !systemUpdate && mPackages.get(packageName) == null) { 10681 removedForAllUsers = true; 10682 } 10683 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 10684 + " removedForAllUsers=" + removedForAllUsers); 10685 } 10686 10687 if (res) { 10688 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 10689 10690 // If the removed package was a system update, the old system package 10691 // was re-enabled; we need to broadcast this information 10692 if (systemUpdate) { 10693 Bundle extras = new Bundle(1); 10694 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 10695 ? info.removedAppId : info.uid); 10696 extras.putBoolean(Intent.EXTRA_REPLACING, true); 10697 10698 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 10699 extras, null, null, null); 10700 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 10701 extras, null, null, null); 10702 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 10703 null, packageName, null, null); 10704 } 10705 } 10706 // Force a gc here. 10707 Runtime.getRuntime().gc(); 10708 // Delete the resources here after sending the broadcast to let 10709 // other processes clean up before deleting resources. 10710 if (info.args != null) { 10711 synchronized (mInstallLock) { 10712 info.args.doPostDeleteLI(true); 10713 } 10714 } 10715 10716 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 10717 } 10718 10719 static class PackageRemovedInfo { 10720 String removedPackage; 10721 int uid = -1; 10722 int removedAppId = -1; 10723 int[] removedUsers = null; 10724 boolean isRemovedPackageSystemUpdate = false; 10725 // Clean up resources deleted packages. 10726 InstallArgs args = null; 10727 10728 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 10729 Bundle extras = new Bundle(1); 10730 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 10731 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 10732 if (replacing) { 10733 extras.putBoolean(Intent.EXTRA_REPLACING, true); 10734 } 10735 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 10736 if (removedPackage != null) { 10737 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 10738 extras, null, null, removedUsers); 10739 if (fullRemove && !replacing) { 10740 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 10741 extras, null, null, removedUsers); 10742 } 10743 } 10744 if (removedAppId >= 0) { 10745 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 10746 removedUsers); 10747 } 10748 } 10749 } 10750 10751 /* 10752 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 10753 * flag is not set, the data directory is removed as well. 10754 * make sure this flag is set for partially installed apps. If not its meaningless to 10755 * delete a partially installed application. 10756 */ 10757 private void removePackageDataLI(PackageSetting ps, 10758 int[] allUserHandles, boolean[] perUserInstalled, 10759 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 10760 String packageName = ps.name; 10761 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 10762 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 10763 // Retrieve object to delete permissions for shared user later on 10764 final PackageSetting deletedPs; 10765 // reader 10766 synchronized (mPackages) { 10767 deletedPs = mSettings.mPackages.get(packageName); 10768 if (outInfo != null) { 10769 outInfo.removedPackage = packageName; 10770 outInfo.removedUsers = deletedPs != null 10771 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 10772 : null; 10773 } 10774 } 10775 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 10776 removeDataDirsLI(packageName); 10777 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 10778 } 10779 // writer 10780 synchronized (mPackages) { 10781 if (deletedPs != null) { 10782 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 10783 if (outInfo != null) { 10784 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 10785 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 10786 } 10787 if (deletedPs != null) { 10788 updatePermissionsLPw(deletedPs.name, null, 0); 10789 if (deletedPs.sharedUser != null) { 10790 // remove permissions associated with package 10791 mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids); 10792 } 10793 } 10794 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 10795 } 10796 // make sure to preserve per-user disabled state if this removal was just 10797 // a downgrade of a system app to the factory package 10798 if (allUserHandles != null && perUserInstalled != null) { 10799 if (DEBUG_REMOVE) { 10800 Slog.d(TAG, "Propagating install state across downgrade"); 10801 } 10802 for (int i = 0; i < allUserHandles.length; i++) { 10803 if (DEBUG_REMOVE) { 10804 Slog.d(TAG, " user " + allUserHandles[i] 10805 + " => " + perUserInstalled[i]); 10806 } 10807 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 10808 } 10809 } 10810 } 10811 // can downgrade to reader 10812 if (writeSettings) { 10813 // Save settings now 10814 mSettings.writeLPr(); 10815 } 10816 } 10817 if (outInfo != null) { 10818 // A user ID was deleted here. Go through all users and remove it 10819 // from KeyStore. 10820 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 10821 } 10822 } 10823 10824 static boolean locationIsPrivileged(File path) { 10825 try { 10826 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 10827 .getCanonicalPath(); 10828 return path.getCanonicalPath().startsWith(privilegedAppDir); 10829 } catch (IOException e) { 10830 Slog.e(TAG, "Unable to access code path " + path); 10831 } 10832 return false; 10833 } 10834 10835 /* 10836 * Tries to delete system package. 10837 */ 10838 private boolean deleteSystemPackageLI(PackageSetting newPs, 10839 int[] allUserHandles, boolean[] perUserInstalled, 10840 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 10841 final boolean applyUserRestrictions 10842 = (allUserHandles != null) && (perUserInstalled != null); 10843 PackageSetting disabledPs = null; 10844 // Confirm if the system package has been updated 10845 // An updated system app can be deleted. This will also have to restore 10846 // the system pkg from system partition 10847 // reader 10848 synchronized (mPackages) { 10849 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 10850 } 10851 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 10852 + " disabledPs=" + disabledPs); 10853 if (disabledPs == null) { 10854 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 10855 return false; 10856 } else if (DEBUG_REMOVE) { 10857 Slog.d(TAG, "Deleting system pkg from data partition"); 10858 } 10859 if (DEBUG_REMOVE) { 10860 if (applyUserRestrictions) { 10861 Slog.d(TAG, "Remembering install states:"); 10862 for (int i = 0; i < allUserHandles.length; i++) { 10863 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 10864 } 10865 } 10866 } 10867 // Delete the updated package 10868 outInfo.isRemovedPackageSystemUpdate = true; 10869 if (disabledPs.versionCode < newPs.versionCode) { 10870 // Delete data for downgrades 10871 flags &= ~PackageManager.DELETE_KEEP_DATA; 10872 } else { 10873 // Preserve data by setting flag 10874 flags |= PackageManager.DELETE_KEEP_DATA; 10875 } 10876 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 10877 allUserHandles, perUserInstalled, outInfo, writeSettings); 10878 if (!ret) { 10879 return false; 10880 } 10881 // writer 10882 synchronized (mPackages) { 10883 // Reinstate the old system package 10884 mSettings.enableSystemPackageLPw(newPs.name); 10885 // Remove any native libraries from the upgraded package. 10886 NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString); 10887 } 10888 // Install the system package 10889 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 10890 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 10891 if (locationIsPrivileged(disabledPs.codePath)) { 10892 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 10893 } 10894 10895 final PackageParser.Package newPkg; 10896 try { 10897 newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, 10898 null, null); 10899 } catch (PackageManagerException e) { 10900 Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage()); 10901 return false; 10902 } 10903 10904 // writer 10905 synchronized (mPackages) { 10906 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 10907 updatePermissionsLPw(newPkg.packageName, newPkg, 10908 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 10909 if (applyUserRestrictions) { 10910 if (DEBUG_REMOVE) { 10911 Slog.d(TAG, "Propagating install state across reinstall"); 10912 } 10913 for (int i = 0; i < allUserHandles.length; i++) { 10914 if (DEBUG_REMOVE) { 10915 Slog.d(TAG, " user " + allUserHandles[i] 10916 + " => " + perUserInstalled[i]); 10917 } 10918 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 10919 } 10920 // Regardless of writeSettings we need to ensure that this restriction 10921 // state propagation is persisted 10922 mSettings.writeAllUsersPackageRestrictionsLPr(); 10923 } 10924 // can downgrade to reader here 10925 if (writeSettings) { 10926 mSettings.writeLPr(); 10927 } 10928 } 10929 return true; 10930 } 10931 10932 private boolean deleteInstalledPackageLI(PackageSetting ps, 10933 boolean deleteCodeAndResources, int flags, 10934 int[] allUserHandles, boolean[] perUserInstalled, 10935 PackageRemovedInfo outInfo, boolean writeSettings) { 10936 if (outInfo != null) { 10937 outInfo.uid = ps.appId; 10938 } 10939 10940 // Delete package data from internal structures and also remove data if flag is set 10941 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 10942 10943 // Delete application code and resources 10944 if (deleteCodeAndResources && (outInfo != null)) { 10945 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 10946 ps.codePathString, ps.resourcePathString, ps.legacyNativeLibraryPathString, 10947 getAppDexInstructionSets(ps), isMultiArch(ps)); 10948 } 10949 return true; 10950 } 10951 10952 @Override 10953 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 10954 int userId) { 10955 mContext.enforceCallingOrSelfPermission( 10956 android.Manifest.permission.DELETE_PACKAGES, null); 10957 synchronized (mPackages) { 10958 PackageSetting ps = mSettings.mPackages.get(packageName); 10959 if (ps == null) { 10960 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 10961 return false; 10962 } 10963 if (!ps.getInstalled(userId)) { 10964 // Can't block uninstall for an app that is not installed or enabled. 10965 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 10966 return false; 10967 } 10968 ps.setBlockUninstall(blockUninstall, userId); 10969 mSettings.writePackageRestrictionsLPr(userId); 10970 } 10971 return true; 10972 } 10973 10974 @Override 10975 public boolean getBlockUninstallForUser(String packageName, int userId) { 10976 synchronized (mPackages) { 10977 PackageSetting ps = mSettings.mPackages.get(packageName); 10978 if (ps == null) { 10979 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 10980 return false; 10981 } 10982 return ps.getBlockUninstall(userId); 10983 } 10984 } 10985 10986 /* 10987 * This method handles package deletion in general 10988 */ 10989 private boolean deletePackageLI(String packageName, UserHandle user, 10990 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 10991 int flags, PackageRemovedInfo outInfo, 10992 boolean writeSettings) { 10993 if (packageName == null) { 10994 Slog.w(TAG, "Attempt to delete null packageName."); 10995 return false; 10996 } 10997 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 10998 PackageSetting ps; 10999 boolean dataOnly = false; 11000 int removeUser = -1; 11001 int appId = -1; 11002 synchronized (mPackages) { 11003 ps = mSettings.mPackages.get(packageName); 11004 if (ps == null) { 11005 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 11006 return false; 11007 } 11008 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 11009 && user.getIdentifier() != UserHandle.USER_ALL) { 11010 // The caller is asking that the package only be deleted for a single 11011 // user. To do this, we just mark its uninstalled state and delete 11012 // its data. If this is a system app, we only allow this to happen if 11013 // they have set the special DELETE_SYSTEM_APP which requests different 11014 // semantics than normal for uninstalling system apps. 11015 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 11016 ps.setUserState(user.getIdentifier(), 11017 COMPONENT_ENABLED_STATE_DEFAULT, 11018 false, //installed 11019 true, //stopped 11020 true, //notLaunched 11021 false, //hidden 11022 null, null, null, 11023 false // blockUninstall 11024 ); 11025 if (!isSystemApp(ps)) { 11026 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 11027 // Other user still have this package installed, so all 11028 // we need to do is clear this user's data and save that 11029 // it is uninstalled. 11030 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 11031 removeUser = user.getIdentifier(); 11032 appId = ps.appId; 11033 mSettings.writePackageRestrictionsLPr(removeUser); 11034 } else { 11035 // We need to set it back to 'installed' so the uninstall 11036 // broadcasts will be sent correctly. 11037 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 11038 ps.setInstalled(true, user.getIdentifier()); 11039 } 11040 } else { 11041 // This is a system app, so we assume that the 11042 // other users still have this package installed, so all 11043 // we need to do is clear this user's data and save that 11044 // it is uninstalled. 11045 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 11046 removeUser = user.getIdentifier(); 11047 appId = ps.appId; 11048 mSettings.writePackageRestrictionsLPr(removeUser); 11049 } 11050 } 11051 } 11052 11053 if (removeUser >= 0) { 11054 // From above, we determined that we are deleting this only 11055 // for a single user. Continue the work here. 11056 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 11057 if (outInfo != null) { 11058 outInfo.removedPackage = packageName; 11059 outInfo.removedAppId = appId; 11060 outInfo.removedUsers = new int[] {removeUser}; 11061 } 11062 mInstaller.clearUserData(packageName, removeUser); 11063 removeKeystoreDataIfNeeded(removeUser, appId); 11064 schedulePackageCleaning(packageName, removeUser, false); 11065 return true; 11066 } 11067 11068 if (dataOnly) { 11069 // Delete application data first 11070 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 11071 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 11072 return true; 11073 } 11074 11075 boolean ret = false; 11076 if (isSystemApp(ps)) { 11077 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 11078 // When an updated system application is deleted we delete the existing resources as well and 11079 // fall back to existing code in system partition 11080 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 11081 flags, outInfo, writeSettings); 11082 } else { 11083 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 11084 // Kill application pre-emptively especially for apps on sd. 11085 killApplication(packageName, ps.appId, "uninstall pkg"); 11086 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 11087 allUserHandles, perUserInstalled, 11088 outInfo, writeSettings); 11089 } 11090 11091 return ret; 11092 } 11093 11094 private final class ClearStorageConnection implements ServiceConnection { 11095 IMediaContainerService mContainerService; 11096 11097 @Override 11098 public void onServiceConnected(ComponentName name, IBinder service) { 11099 synchronized (this) { 11100 mContainerService = IMediaContainerService.Stub.asInterface(service); 11101 notifyAll(); 11102 } 11103 } 11104 11105 @Override 11106 public void onServiceDisconnected(ComponentName name) { 11107 } 11108 } 11109 11110 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 11111 final boolean mounted; 11112 if (Environment.isExternalStorageEmulated()) { 11113 mounted = true; 11114 } else { 11115 final String status = Environment.getExternalStorageState(); 11116 11117 mounted = status.equals(Environment.MEDIA_MOUNTED) 11118 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 11119 } 11120 11121 if (!mounted) { 11122 return; 11123 } 11124 11125 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 11126 int[] users; 11127 if (userId == UserHandle.USER_ALL) { 11128 users = sUserManager.getUserIds(); 11129 } else { 11130 users = new int[] { userId }; 11131 } 11132 final ClearStorageConnection conn = new ClearStorageConnection(); 11133 if (mContext.bindServiceAsUser( 11134 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 11135 try { 11136 for (int curUser : users) { 11137 long timeout = SystemClock.uptimeMillis() + 5000; 11138 synchronized (conn) { 11139 long now = SystemClock.uptimeMillis(); 11140 while (conn.mContainerService == null && now < timeout) { 11141 try { 11142 conn.wait(timeout - now); 11143 } catch (InterruptedException e) { 11144 } 11145 } 11146 } 11147 if (conn.mContainerService == null) { 11148 return; 11149 } 11150 11151 final UserEnvironment userEnv = new UserEnvironment(curUser); 11152 clearDirectory(conn.mContainerService, 11153 userEnv.buildExternalStorageAppCacheDirs(packageName)); 11154 if (allData) { 11155 clearDirectory(conn.mContainerService, 11156 userEnv.buildExternalStorageAppDataDirs(packageName)); 11157 clearDirectory(conn.mContainerService, 11158 userEnv.buildExternalStorageAppMediaDirs(packageName)); 11159 } 11160 } 11161 } finally { 11162 mContext.unbindService(conn); 11163 } 11164 } 11165 } 11166 11167 @Override 11168 public void clearApplicationUserData(final String packageName, 11169 final IPackageDataObserver observer, final int userId) { 11170 mContext.enforceCallingOrSelfPermission( 11171 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 11172 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data"); 11173 // Queue up an async operation since the package deletion may take a little while. 11174 mHandler.post(new Runnable() { 11175 public void run() { 11176 mHandler.removeCallbacks(this); 11177 final boolean succeeded; 11178 synchronized (mInstallLock) { 11179 succeeded = clearApplicationUserDataLI(packageName, userId); 11180 } 11181 clearExternalStorageDataSync(packageName, userId, true); 11182 if (succeeded) { 11183 // invoke DeviceStorageMonitor's update method to clear any notifications 11184 DeviceStorageMonitorInternal 11185 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 11186 if (dsm != null) { 11187 dsm.checkMemory(); 11188 } 11189 } 11190 if(observer != null) { 11191 try { 11192 observer.onRemoveCompleted(packageName, succeeded); 11193 } catch (RemoteException e) { 11194 Log.i(TAG, "Observer no longer exists."); 11195 } 11196 } //end if observer 11197 } //end run 11198 }); 11199 } 11200 11201 private boolean clearApplicationUserDataLI(String packageName, int userId) { 11202 if (packageName == null) { 11203 Slog.w(TAG, "Attempt to delete null packageName."); 11204 return false; 11205 } 11206 PackageParser.Package p; 11207 boolean dataOnly = false; 11208 final int appId; 11209 synchronized (mPackages) { 11210 p = mPackages.get(packageName); 11211 if (p == null) { 11212 dataOnly = true; 11213 PackageSetting ps = mSettings.mPackages.get(packageName); 11214 if ((ps == null) || (ps.pkg == null)) { 11215 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 11216 return false; 11217 } 11218 p = ps.pkg; 11219 } 11220 if (!dataOnly) { 11221 // need to check this only for fully installed applications 11222 if (p == null) { 11223 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 11224 return false; 11225 } 11226 final ApplicationInfo applicationInfo = p.applicationInfo; 11227 if (applicationInfo == null) { 11228 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 11229 return false; 11230 } 11231 } 11232 if (p != null && p.applicationInfo != null) { 11233 appId = p.applicationInfo.uid; 11234 } else { 11235 appId = -1; 11236 } 11237 } 11238 int retCode = mInstaller.clearUserData(packageName, userId); 11239 if (retCode < 0) { 11240 Slog.w(TAG, "Couldn't remove cache files for package: " 11241 + packageName); 11242 return false; 11243 } 11244 removeKeystoreDataIfNeeded(userId, appId); 11245 return true; 11246 } 11247 11248 /** 11249 * Remove entries from the keystore daemon. Will only remove it if the 11250 * {@code appId} is valid. 11251 */ 11252 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 11253 if (appId < 0) { 11254 return; 11255 } 11256 11257 final KeyStore keyStore = KeyStore.getInstance(); 11258 if (keyStore != null) { 11259 if (userId == UserHandle.USER_ALL) { 11260 for (final int individual : sUserManager.getUserIds()) { 11261 keyStore.clearUid(UserHandle.getUid(individual, appId)); 11262 } 11263 } else { 11264 keyStore.clearUid(UserHandle.getUid(userId, appId)); 11265 } 11266 } else { 11267 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 11268 } 11269 } 11270 11271 @Override 11272 public void deleteApplicationCacheFiles(final String packageName, 11273 final IPackageDataObserver observer) { 11274 mContext.enforceCallingOrSelfPermission( 11275 android.Manifest.permission.DELETE_CACHE_FILES, null); 11276 // Queue up an async operation since the package deletion may take a little while. 11277 final int userId = UserHandle.getCallingUserId(); 11278 mHandler.post(new Runnable() { 11279 public void run() { 11280 mHandler.removeCallbacks(this); 11281 final boolean succeded; 11282 synchronized (mInstallLock) { 11283 succeded = deleteApplicationCacheFilesLI(packageName, userId); 11284 } 11285 clearExternalStorageDataSync(packageName, userId, false); 11286 if(observer != null) { 11287 try { 11288 observer.onRemoveCompleted(packageName, succeded); 11289 } catch (RemoteException e) { 11290 Log.i(TAG, "Observer no longer exists."); 11291 } 11292 } //end if observer 11293 } //end run 11294 }); 11295 } 11296 11297 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 11298 if (packageName == null) { 11299 Slog.w(TAG, "Attempt to delete null packageName."); 11300 return false; 11301 } 11302 PackageParser.Package p; 11303 synchronized (mPackages) { 11304 p = mPackages.get(packageName); 11305 } 11306 if (p == null) { 11307 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 11308 return false; 11309 } 11310 final ApplicationInfo applicationInfo = p.applicationInfo; 11311 if (applicationInfo == null) { 11312 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 11313 return false; 11314 } 11315 int retCode = mInstaller.deleteCacheFiles(packageName, userId); 11316 if (retCode < 0) { 11317 Slog.w(TAG, "Couldn't remove cache files for package: " 11318 + packageName + " u" + userId); 11319 return false; 11320 } 11321 return true; 11322 } 11323 11324 @Override 11325 public void getPackageSizeInfo(final String packageName, int userHandle, 11326 final IPackageStatsObserver observer) { 11327 mContext.enforceCallingOrSelfPermission( 11328 android.Manifest.permission.GET_PACKAGE_SIZE, null); 11329 if (packageName == null) { 11330 throw new IllegalArgumentException("Attempt to get size of null packageName"); 11331 } 11332 11333 PackageStats stats = new PackageStats(packageName, userHandle); 11334 11335 /* 11336 * Queue up an async operation since the package measurement may take a 11337 * little while. 11338 */ 11339 Message msg = mHandler.obtainMessage(INIT_COPY); 11340 msg.obj = new MeasureParams(stats, observer); 11341 mHandler.sendMessage(msg); 11342 } 11343 11344 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 11345 PackageStats pStats) { 11346 if (packageName == null) { 11347 Slog.w(TAG, "Attempt to get size of null packageName."); 11348 return false; 11349 } 11350 PackageParser.Package p; 11351 boolean dataOnly = false; 11352 String libDirRoot = null; 11353 String asecPath = null; 11354 PackageSetting ps = null; 11355 synchronized (mPackages) { 11356 p = mPackages.get(packageName); 11357 ps = mSettings.mPackages.get(packageName); 11358 if(p == null) { 11359 dataOnly = true; 11360 if((ps == null) || (ps.pkg == null)) { 11361 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 11362 return false; 11363 } 11364 p = ps.pkg; 11365 } 11366 if (ps != null) { 11367 libDirRoot = ps.legacyNativeLibraryPathString; 11368 } 11369 if (p != null && (isExternal(p) || isForwardLocked(p))) { 11370 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 11371 if (secureContainerId != null) { 11372 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 11373 } 11374 } 11375 } 11376 String publicSrcDir = null; 11377 if(!dataOnly) { 11378 final ApplicationInfo applicationInfo = p.applicationInfo; 11379 if (applicationInfo == null) { 11380 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 11381 return false; 11382 } 11383 if (isForwardLocked(p)) { 11384 publicSrcDir = applicationInfo.getBaseResourcePath(); 11385 } 11386 } 11387 // TODO: extend to measure size of split APKs 11388 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 11389 // not just the first level. 11390 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 11391 // just the primary. 11392 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 11393 int res = mInstaller.getSizeInfo(packageName, userHandle, p.baseCodePath, libDirRoot, 11394 publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 11395 if (res < 0) { 11396 return false; 11397 } 11398 11399 // Fix-up for forward-locked applications in ASEC containers. 11400 if (!isExternal(p)) { 11401 pStats.codeSize += pStats.externalCodeSize; 11402 pStats.externalCodeSize = 0L; 11403 } 11404 11405 return true; 11406 } 11407 11408 11409 @Override 11410 public void addPackageToPreferred(String packageName) { 11411 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 11412 } 11413 11414 @Override 11415 public void removePackageFromPreferred(String packageName) { 11416 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 11417 } 11418 11419 @Override 11420 public List<PackageInfo> getPreferredPackages(int flags) { 11421 return new ArrayList<PackageInfo>(); 11422 } 11423 11424 private int getUidTargetSdkVersionLockedLPr(int uid) { 11425 Object obj = mSettings.getUserIdLPr(uid); 11426 if (obj instanceof SharedUserSetting) { 11427 final SharedUserSetting sus = (SharedUserSetting) obj; 11428 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 11429 final Iterator<PackageSetting> it = sus.packages.iterator(); 11430 while (it.hasNext()) { 11431 final PackageSetting ps = it.next(); 11432 if (ps.pkg != null) { 11433 int v = ps.pkg.applicationInfo.targetSdkVersion; 11434 if (v < vers) vers = v; 11435 } 11436 } 11437 return vers; 11438 } else if (obj instanceof PackageSetting) { 11439 final PackageSetting ps = (PackageSetting) obj; 11440 if (ps.pkg != null) { 11441 return ps.pkg.applicationInfo.targetSdkVersion; 11442 } 11443 } 11444 return Build.VERSION_CODES.CUR_DEVELOPMENT; 11445 } 11446 11447 @Override 11448 public void addPreferredActivity(IntentFilter filter, int match, 11449 ComponentName[] set, ComponentName activity, int userId) { 11450 addPreferredActivityInternal(filter, match, set, activity, true, userId); 11451 } 11452 11453 private void addPreferredActivityInternal(IntentFilter filter, int match, 11454 ComponentName[] set, ComponentName activity, boolean always, int userId) { 11455 // writer 11456 int callingUid = Binder.getCallingUid(); 11457 enforceCrossUserPermission(callingUid, userId, true, "add preferred activity"); 11458 if (filter.countActions() == 0) { 11459 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 11460 return; 11461 } 11462 synchronized (mPackages) { 11463 if (mContext.checkCallingOrSelfPermission( 11464 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 11465 != PackageManager.PERMISSION_GRANTED) { 11466 if (getUidTargetSdkVersionLockedLPr(callingUid) 11467 < Build.VERSION_CODES.FROYO) { 11468 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 11469 + callingUid); 11470 return; 11471 } 11472 mContext.enforceCallingOrSelfPermission( 11473 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11474 } 11475 11476 Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :"); 11477 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 11478 mSettings.editPreferredActivitiesLPw(userId).addFilter( 11479 new PreferredActivity(filter, match, set, activity, always)); 11480 mSettings.writePackageRestrictionsLPr(userId); 11481 } 11482 } 11483 11484 @Override 11485 public void replacePreferredActivity(IntentFilter filter, int match, 11486 ComponentName[] set, ComponentName activity, int userId) { 11487 if (filter.countActions() != 1) { 11488 throw new IllegalArgumentException( 11489 "replacePreferredActivity expects filter to have only 1 action."); 11490 } 11491 if (filter.countDataAuthorities() != 0 11492 || filter.countDataPaths() != 0 11493 || filter.countDataSchemes() > 1 11494 || filter.countDataTypes() != 0) { 11495 throw new IllegalArgumentException( 11496 "replacePreferredActivity expects filter to have no data authorities, " + 11497 "paths, or types; and at most one scheme."); 11498 } 11499 11500 final int callingUid = Binder.getCallingUid(); 11501 enforceCrossUserPermission(callingUid, userId, true, "replace preferred activity"); 11502 final int callingUserId = UserHandle.getUserId(callingUid); 11503 synchronized (mPackages) { 11504 if (mContext.checkCallingOrSelfPermission( 11505 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 11506 != PackageManager.PERMISSION_GRANTED) { 11507 if (getUidTargetSdkVersionLockedLPr(callingUid) 11508 < Build.VERSION_CODES.FROYO) { 11509 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 11510 + Binder.getCallingUid()); 11511 return; 11512 } 11513 mContext.enforceCallingOrSelfPermission( 11514 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11515 } 11516 11517 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId); 11518 if (pir != null) { 11519 Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0)); 11520 if (filter.countDataSchemes() == 1) { 11521 Uri.Builder builder = new Uri.Builder(); 11522 builder.scheme(filter.getDataScheme(0)); 11523 intent.setData(builder.build()); 11524 } 11525 List<PreferredActivity> matches = pir.queryIntent( 11526 intent, null, true, callingUserId); 11527 if (DEBUG_PREFERRED) { 11528 Slog.i(TAG, matches.size() + " preferred matches for " + intent); 11529 } 11530 for (int i = 0; i < matches.size(); i++) { 11531 PreferredActivity pa = matches.get(i); 11532 if (DEBUG_PREFERRED) { 11533 Slog.i(TAG, "Removing preferred activity " 11534 + pa.mPref.mComponent + ":"); 11535 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 11536 } 11537 pir.removeFilter(pa); 11538 } 11539 } 11540 addPreferredActivityInternal(filter, match, set, activity, true, callingUserId); 11541 } 11542 } 11543 11544 @Override 11545 public void clearPackagePreferredActivities(String packageName) { 11546 final int uid = Binder.getCallingUid(); 11547 // writer 11548 synchronized (mPackages) { 11549 PackageParser.Package pkg = mPackages.get(packageName); 11550 if (pkg == null || pkg.applicationInfo.uid != uid) { 11551 if (mContext.checkCallingOrSelfPermission( 11552 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 11553 != PackageManager.PERMISSION_GRANTED) { 11554 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 11555 < Build.VERSION_CODES.FROYO) { 11556 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 11557 + Binder.getCallingUid()); 11558 return; 11559 } 11560 mContext.enforceCallingOrSelfPermission( 11561 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11562 } 11563 } 11564 11565 int user = UserHandle.getCallingUserId(); 11566 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 11567 mSettings.writePackageRestrictionsLPr(user); 11568 scheduleWriteSettingsLocked(); 11569 } 11570 } 11571 } 11572 11573 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 11574 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 11575 ArrayList<PreferredActivity> removed = null; 11576 boolean changed = false; 11577 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 11578 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 11579 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 11580 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 11581 continue; 11582 } 11583 Iterator<PreferredActivity> it = pir.filterIterator(); 11584 while (it.hasNext()) { 11585 PreferredActivity pa = it.next(); 11586 // Mark entry for removal only if it matches the package name 11587 // and the entry is of type "always". 11588 if (packageName == null || 11589 (pa.mPref.mComponent.getPackageName().equals(packageName) 11590 && pa.mPref.mAlways)) { 11591 if (removed == null) { 11592 removed = new ArrayList<PreferredActivity>(); 11593 } 11594 removed.add(pa); 11595 } 11596 } 11597 if (removed != null) { 11598 for (int j=0; j<removed.size(); j++) { 11599 PreferredActivity pa = removed.get(j); 11600 pir.removeFilter(pa); 11601 } 11602 changed = true; 11603 } 11604 } 11605 return changed; 11606 } 11607 11608 @Override 11609 public void resetPreferredActivities(int userId) { 11610 mContext.enforceCallingOrSelfPermission( 11611 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11612 // writer 11613 synchronized (mPackages) { 11614 int user = UserHandle.getCallingUserId(); 11615 clearPackagePreferredActivitiesLPw(null, user); 11616 mSettings.readDefaultPreferredAppsLPw(this, user); 11617 mSettings.writePackageRestrictionsLPr(user); 11618 scheduleWriteSettingsLocked(); 11619 } 11620 } 11621 11622 @Override 11623 public int getPreferredActivities(List<IntentFilter> outFilters, 11624 List<ComponentName> outActivities, String packageName) { 11625 11626 int num = 0; 11627 final int userId = UserHandle.getCallingUserId(); 11628 // reader 11629 synchronized (mPackages) { 11630 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 11631 if (pir != null) { 11632 final Iterator<PreferredActivity> it = pir.filterIterator(); 11633 while (it.hasNext()) { 11634 final PreferredActivity pa = it.next(); 11635 if (packageName == null 11636 || (pa.mPref.mComponent.getPackageName().equals(packageName) 11637 && pa.mPref.mAlways)) { 11638 if (outFilters != null) { 11639 outFilters.add(new IntentFilter(pa)); 11640 } 11641 if (outActivities != null) { 11642 outActivities.add(pa.mPref.mComponent); 11643 } 11644 } 11645 } 11646 } 11647 } 11648 11649 return num; 11650 } 11651 11652 @Override 11653 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 11654 int userId) { 11655 int callingUid = Binder.getCallingUid(); 11656 if (callingUid != Process.SYSTEM_UID) { 11657 throw new SecurityException( 11658 "addPersistentPreferredActivity can only be run by the system"); 11659 } 11660 if (filter.countActions() == 0) { 11661 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 11662 return; 11663 } 11664 synchronized (mPackages) { 11665 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 11666 " :"); 11667 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 11668 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 11669 new PersistentPreferredActivity(filter, activity)); 11670 mSettings.writePackageRestrictionsLPr(userId); 11671 } 11672 } 11673 11674 @Override 11675 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 11676 int callingUid = Binder.getCallingUid(); 11677 if (callingUid != Process.SYSTEM_UID) { 11678 throw new SecurityException( 11679 "clearPackagePersistentPreferredActivities can only be run by the system"); 11680 } 11681 ArrayList<PersistentPreferredActivity> removed = null; 11682 boolean changed = false; 11683 synchronized (mPackages) { 11684 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 11685 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 11686 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 11687 .valueAt(i); 11688 if (userId != thisUserId) { 11689 continue; 11690 } 11691 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 11692 while (it.hasNext()) { 11693 PersistentPreferredActivity ppa = it.next(); 11694 // Mark entry for removal only if it matches the package name. 11695 if (ppa.mComponent.getPackageName().equals(packageName)) { 11696 if (removed == null) { 11697 removed = new ArrayList<PersistentPreferredActivity>(); 11698 } 11699 removed.add(ppa); 11700 } 11701 } 11702 if (removed != null) { 11703 for (int j=0; j<removed.size(); j++) { 11704 PersistentPreferredActivity ppa = removed.get(j); 11705 ppir.removeFilter(ppa); 11706 } 11707 changed = true; 11708 } 11709 } 11710 11711 if (changed) { 11712 mSettings.writePackageRestrictionsLPr(userId); 11713 } 11714 } 11715 } 11716 11717 @Override 11718 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 11719 int ownerUserId, int sourceUserId, int targetUserId, int flags) { 11720 mContext.enforceCallingOrSelfPermission( 11721 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 11722 int callingUid = Binder.getCallingUid(); 11723 enforceOwnerRights(ownerPackage, ownerUserId, callingUid); 11724 if (intentFilter.countActions() == 0) { 11725 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 11726 return; 11727 } 11728 synchronized (mPackages) { 11729 CrossProfileIntentFilter filter = new CrossProfileIntentFilter(intentFilter, 11730 ownerPackage, UserHandle.getUserId(callingUid), targetUserId, flags); 11731 mSettings.editCrossProfileIntentResolverLPw(sourceUserId).addFilter(filter); 11732 mSettings.writePackageRestrictionsLPr(sourceUserId); 11733 } 11734 } 11735 11736 @Override 11737 public void addCrossProfileIntentsForPackage(String packageName, 11738 int sourceUserId, int targetUserId) { 11739 mContext.enforceCallingOrSelfPermission( 11740 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 11741 mSettings.addCrossProfilePackage(packageName, sourceUserId, targetUserId); 11742 mSettings.writePackageRestrictionsLPr(sourceUserId); 11743 } 11744 11745 @Override 11746 public void removeCrossProfileIntentsForPackage(String packageName, 11747 int sourceUserId, int targetUserId) { 11748 mContext.enforceCallingOrSelfPermission( 11749 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 11750 mSettings.removeCrossProfilePackage(packageName, sourceUserId, targetUserId); 11751 mSettings.writePackageRestrictionsLPr(sourceUserId); 11752 } 11753 11754 @Override 11755 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, 11756 int ownerUserId) { 11757 mContext.enforceCallingOrSelfPermission( 11758 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 11759 int callingUid = Binder.getCallingUid(); 11760 enforceOwnerRights(ownerPackage, ownerUserId, callingUid); 11761 int callingUserId = UserHandle.getUserId(callingUid); 11762 synchronized (mPackages) { 11763 CrossProfileIntentResolver resolver = 11764 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 11765 HashSet<CrossProfileIntentFilter> set = 11766 new HashSet<CrossProfileIntentFilter>(resolver.filterSet()); 11767 for (CrossProfileIntentFilter filter : set) { 11768 if (filter.getOwnerPackage().equals(ownerPackage) 11769 && filter.getOwnerUserId() == callingUserId) { 11770 resolver.removeFilter(filter); 11771 } 11772 } 11773 mSettings.writePackageRestrictionsLPr(sourceUserId); 11774 } 11775 } 11776 11777 // Enforcing that callingUid is owning pkg on userId 11778 private void enforceOwnerRights(String pkg, int userId, int callingUid) { 11779 // The system owns everything. 11780 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 11781 return; 11782 } 11783 int callingUserId = UserHandle.getUserId(callingUid); 11784 if (callingUserId != userId) { 11785 throw new SecurityException("calling uid " + callingUid 11786 + " pretends to own " + pkg + " on user " + userId + " but belongs to user " 11787 + callingUserId); 11788 } 11789 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 11790 if (pi == null) { 11791 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 11792 + callingUserId); 11793 } 11794 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 11795 throw new SecurityException("Calling uid " + callingUid 11796 + " does not own package " + pkg); 11797 } 11798 } 11799 11800 @Override 11801 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 11802 Intent intent = new Intent(Intent.ACTION_MAIN); 11803 intent.addCategory(Intent.CATEGORY_HOME); 11804 11805 final int callingUserId = UserHandle.getCallingUserId(); 11806 List<ResolveInfo> list = queryIntentActivities(intent, null, 11807 PackageManager.GET_META_DATA, callingUserId); 11808 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 11809 true, false, false, callingUserId); 11810 11811 allHomeCandidates.clear(); 11812 if (list != null) { 11813 for (ResolveInfo ri : list) { 11814 allHomeCandidates.add(ri); 11815 } 11816 } 11817 return (preferred == null || preferred.activityInfo == null) 11818 ? null 11819 : new ComponentName(preferred.activityInfo.packageName, 11820 preferred.activityInfo.name); 11821 } 11822 11823 /** 11824 * Check if calling UID is the current home app. This handles both the case 11825 * where the user has selected a specific home app, and where there is only 11826 * one home app. 11827 */ 11828 public boolean checkCallerIsHomeApp() { 11829 final Intent intent = new Intent(Intent.ACTION_MAIN); 11830 intent.addCategory(Intent.CATEGORY_HOME); 11831 11832 final int callingUid = Binder.getCallingUid(); 11833 final int callingUserId = UserHandle.getCallingUserId(); 11834 final List<ResolveInfo> allHomes = queryIntentActivities(intent, null, 0, callingUserId); 11835 final ResolveInfo preferredHome = findPreferredActivity(intent, null, 0, allHomes, 0, true, 11836 false, false, callingUserId); 11837 11838 if (preferredHome != null) { 11839 if (callingUid == preferredHome.activityInfo.applicationInfo.uid) { 11840 return true; 11841 } 11842 } else { 11843 for (ResolveInfo info : allHomes) { 11844 if (callingUid == info.activityInfo.applicationInfo.uid) { 11845 return true; 11846 } 11847 } 11848 } 11849 11850 return false; 11851 } 11852 11853 /** 11854 * Enforce that calling UID is the current home app. This handles both the 11855 * case where the user has selected a specific home app, and where there is 11856 * only one home app. 11857 */ 11858 public void enforceCallerIsHomeApp() { 11859 if (!checkCallerIsHomeApp()) { 11860 throw new SecurityException("Caller is not currently selected home app"); 11861 } 11862 } 11863 11864 @Override 11865 public void setApplicationEnabledSetting(String appPackageName, 11866 int newState, int flags, int userId, String callingPackage) { 11867 if (!sUserManager.exists(userId)) return; 11868 if (callingPackage == null) { 11869 callingPackage = Integer.toString(Binder.getCallingUid()); 11870 } 11871 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 11872 } 11873 11874 @Override 11875 public void setComponentEnabledSetting(ComponentName componentName, 11876 int newState, int flags, int userId) { 11877 if (!sUserManager.exists(userId)) return; 11878 setEnabledSetting(componentName.getPackageName(), 11879 componentName.getClassName(), newState, flags, userId, null); 11880 } 11881 11882 private void setEnabledSetting(final String packageName, String className, int newState, 11883 final int flags, int userId, String callingPackage) { 11884 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 11885 || newState == COMPONENT_ENABLED_STATE_ENABLED 11886 || newState == COMPONENT_ENABLED_STATE_DISABLED 11887 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 11888 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 11889 throw new IllegalArgumentException("Invalid new component state: " 11890 + newState); 11891 } 11892 PackageSetting pkgSetting; 11893 final int uid = Binder.getCallingUid(); 11894 final int permission = mContext.checkCallingOrSelfPermission( 11895 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 11896 enforceCrossUserPermission(uid, userId, false, "set enabled"); 11897 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 11898 boolean sendNow = false; 11899 boolean isApp = (className == null); 11900 String componentName = isApp ? packageName : className; 11901 int packageUid = -1; 11902 ArrayList<String> components; 11903 11904 // writer 11905 synchronized (mPackages) { 11906 pkgSetting = mSettings.mPackages.get(packageName); 11907 if (pkgSetting == null) { 11908 if (className == null) { 11909 throw new IllegalArgumentException( 11910 "Unknown package: " + packageName); 11911 } 11912 throw new IllegalArgumentException( 11913 "Unknown component: " + packageName 11914 + "/" + className); 11915 } 11916 // Allow root and verify that userId is not being specified by a different user 11917 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 11918 throw new SecurityException( 11919 "Permission Denial: attempt to change component state from pid=" 11920 + Binder.getCallingPid() 11921 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 11922 } 11923 if (className == null) { 11924 // We're dealing with an application/package level state change 11925 if (pkgSetting.getEnabled(userId) == newState) { 11926 // Nothing to do 11927 return; 11928 } 11929 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 11930 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 11931 // Don't care about who enables an app. 11932 callingPackage = null; 11933 } 11934 pkgSetting.setEnabled(newState, userId, callingPackage); 11935 // pkgSetting.pkg.mSetEnabled = newState; 11936 } else { 11937 // We're dealing with a component level state change 11938 // First, verify that this is a valid class name. 11939 PackageParser.Package pkg = pkgSetting.pkg; 11940 if (pkg == null || !pkg.hasComponentClassName(className)) { 11941 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 11942 throw new IllegalArgumentException("Component class " + className 11943 + " does not exist in " + packageName); 11944 } else { 11945 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 11946 + className + " does not exist in " + packageName); 11947 } 11948 } 11949 switch (newState) { 11950 case COMPONENT_ENABLED_STATE_ENABLED: 11951 if (!pkgSetting.enableComponentLPw(className, userId)) { 11952 return; 11953 } 11954 break; 11955 case COMPONENT_ENABLED_STATE_DISABLED: 11956 if (!pkgSetting.disableComponentLPw(className, userId)) { 11957 return; 11958 } 11959 break; 11960 case COMPONENT_ENABLED_STATE_DEFAULT: 11961 if (!pkgSetting.restoreComponentLPw(className, userId)) { 11962 return; 11963 } 11964 break; 11965 default: 11966 Slog.e(TAG, "Invalid new component state: " + newState); 11967 return; 11968 } 11969 } 11970 mSettings.writePackageRestrictionsLPr(userId); 11971 components = mPendingBroadcasts.get(userId, packageName); 11972 final boolean newPackage = components == null; 11973 if (newPackage) { 11974 components = new ArrayList<String>(); 11975 } 11976 if (!components.contains(componentName)) { 11977 components.add(componentName); 11978 } 11979 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 11980 sendNow = true; 11981 // Purge entry from pending broadcast list if another one exists already 11982 // since we are sending one right away. 11983 mPendingBroadcasts.remove(userId, packageName); 11984 } else { 11985 if (newPackage) { 11986 mPendingBroadcasts.put(userId, packageName, components); 11987 } 11988 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 11989 // Schedule a message 11990 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 11991 } 11992 } 11993 } 11994 11995 long callingId = Binder.clearCallingIdentity(); 11996 try { 11997 if (sendNow) { 11998 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 11999 sendPackageChangedBroadcast(packageName, 12000 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 12001 } 12002 } finally { 12003 Binder.restoreCallingIdentity(callingId); 12004 } 12005 } 12006 12007 private void sendPackageChangedBroadcast(String packageName, 12008 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 12009 if (DEBUG_INSTALL) 12010 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 12011 + componentNames); 12012 Bundle extras = new Bundle(4); 12013 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 12014 String nameList[] = new String[componentNames.size()]; 12015 componentNames.toArray(nameList); 12016 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 12017 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 12018 extras.putInt(Intent.EXTRA_UID, packageUid); 12019 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 12020 new int[] {UserHandle.getUserId(packageUid)}); 12021 } 12022 12023 @Override 12024 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 12025 if (!sUserManager.exists(userId)) return; 12026 final int uid = Binder.getCallingUid(); 12027 final int permission = mContext.checkCallingOrSelfPermission( 12028 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 12029 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 12030 enforceCrossUserPermission(uid, userId, true, "stop package"); 12031 // writer 12032 synchronized (mPackages) { 12033 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, 12034 uid, userId)) { 12035 scheduleWritePackageRestrictionsLocked(userId); 12036 } 12037 } 12038 } 12039 12040 @Override 12041 public String getInstallerPackageName(String packageName) { 12042 // reader 12043 synchronized (mPackages) { 12044 return mSettings.getInstallerPackageNameLPr(packageName); 12045 } 12046 } 12047 12048 @Override 12049 public int getApplicationEnabledSetting(String packageName, int userId) { 12050 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 12051 int uid = Binder.getCallingUid(); 12052 enforceCrossUserPermission(uid, userId, false, "get enabled"); 12053 // reader 12054 synchronized (mPackages) { 12055 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 12056 } 12057 } 12058 12059 @Override 12060 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 12061 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 12062 int uid = Binder.getCallingUid(); 12063 enforceCrossUserPermission(uid, userId, false, "get component enabled"); 12064 // reader 12065 synchronized (mPackages) { 12066 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 12067 } 12068 } 12069 12070 @Override 12071 public void enterSafeMode() { 12072 enforceSystemOrRoot("Only the system can request entering safe mode"); 12073 12074 if (!mSystemReady) { 12075 mSafeMode = true; 12076 } 12077 } 12078 12079 @Override 12080 public void systemReady() { 12081 mSystemReady = true; 12082 12083 // Read the compatibilty setting when the system is ready. 12084 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 12085 mContext.getContentResolver(), 12086 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 12087 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 12088 if (DEBUG_SETTINGS) { 12089 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 12090 } 12091 12092 synchronized (mPackages) { 12093 // Verify that all of the preferred activity components actually 12094 // exist. It is possible for applications to be updated and at 12095 // that point remove a previously declared activity component that 12096 // had been set as a preferred activity. We try to clean this up 12097 // the next time we encounter that preferred activity, but it is 12098 // possible for the user flow to never be able to return to that 12099 // situation so here we do a sanity check to make sure we haven't 12100 // left any junk around. 12101 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 12102 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 12103 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 12104 removed.clear(); 12105 for (PreferredActivity pa : pir.filterSet()) { 12106 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 12107 removed.add(pa); 12108 } 12109 } 12110 if (removed.size() > 0) { 12111 for (int r=0; r<removed.size(); r++) { 12112 PreferredActivity pa = removed.get(r); 12113 Slog.w(TAG, "Removing dangling preferred activity: " 12114 + pa.mPref.mComponent); 12115 pir.removeFilter(pa); 12116 } 12117 mSettings.writePackageRestrictionsLPr( 12118 mSettings.mPreferredActivities.keyAt(i)); 12119 } 12120 } 12121 } 12122 sUserManager.systemReady(); 12123 } 12124 12125 @Override 12126 public boolean isSafeMode() { 12127 return mSafeMode; 12128 } 12129 12130 @Override 12131 public boolean hasSystemUidErrors() { 12132 return mHasSystemUidErrors; 12133 } 12134 12135 static String arrayToString(int[] array) { 12136 StringBuffer buf = new StringBuffer(128); 12137 buf.append('['); 12138 if (array != null) { 12139 for (int i=0; i<array.length; i++) { 12140 if (i > 0) buf.append(", "); 12141 buf.append(array[i]); 12142 } 12143 } 12144 buf.append(']'); 12145 return buf.toString(); 12146 } 12147 12148 static class DumpState { 12149 public static final int DUMP_LIBS = 1 << 0; 12150 public static final int DUMP_FEATURES = 1 << 1; 12151 public static final int DUMP_RESOLVERS = 1 << 2; 12152 public static final int DUMP_PERMISSIONS = 1 << 3; 12153 public static final int DUMP_PACKAGES = 1 << 4; 12154 public static final int DUMP_SHARED_USERS = 1 << 5; 12155 public static final int DUMP_MESSAGES = 1 << 6; 12156 public static final int DUMP_PROVIDERS = 1 << 7; 12157 public static final int DUMP_VERIFIERS = 1 << 8; 12158 public static final int DUMP_PREFERRED = 1 << 9; 12159 public static final int DUMP_PREFERRED_XML = 1 << 10; 12160 public static final int DUMP_KEYSETS = 1 << 11; 12161 public static final int DUMP_VERSION = 1 << 12; 12162 public static final int DUMP_INSTALLS = 1 << 13; 12163 12164 public static final int OPTION_SHOW_FILTERS = 1 << 0; 12165 12166 private int mTypes; 12167 12168 private int mOptions; 12169 12170 private boolean mTitlePrinted; 12171 12172 private SharedUserSetting mSharedUser; 12173 12174 public boolean isDumping(int type) { 12175 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 12176 return true; 12177 } 12178 12179 return (mTypes & type) != 0; 12180 } 12181 12182 public void setDump(int type) { 12183 mTypes |= type; 12184 } 12185 12186 public boolean isOptionEnabled(int option) { 12187 return (mOptions & option) != 0; 12188 } 12189 12190 public void setOptionEnabled(int option) { 12191 mOptions |= option; 12192 } 12193 12194 public boolean onTitlePrinted() { 12195 final boolean printed = mTitlePrinted; 12196 mTitlePrinted = true; 12197 return printed; 12198 } 12199 12200 public boolean getTitlePrinted() { 12201 return mTitlePrinted; 12202 } 12203 12204 public void setTitlePrinted(boolean enabled) { 12205 mTitlePrinted = enabled; 12206 } 12207 12208 public SharedUserSetting getSharedUser() { 12209 return mSharedUser; 12210 } 12211 12212 public void setSharedUser(SharedUserSetting user) { 12213 mSharedUser = user; 12214 } 12215 } 12216 12217 @Override 12218 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12219 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 12220 != PackageManager.PERMISSION_GRANTED) { 12221 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12222 + Binder.getCallingPid() 12223 + ", uid=" + Binder.getCallingUid() 12224 + " without permission " 12225 + android.Manifest.permission.DUMP); 12226 return; 12227 } 12228 12229 DumpState dumpState = new DumpState(); 12230 boolean fullPreferred = false; 12231 boolean checkin = false; 12232 12233 String packageName = null; 12234 12235 int opti = 0; 12236 while (opti < args.length) { 12237 String opt = args[opti]; 12238 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12239 break; 12240 } 12241 opti++; 12242 if ("-a".equals(opt)) { 12243 // Right now we only know how to print all. 12244 } else if ("-h".equals(opt)) { 12245 pw.println("Package manager dump options:"); 12246 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 12247 pw.println(" --checkin: dump for a checkin"); 12248 pw.println(" -f: print details of intent filters"); 12249 pw.println(" -h: print this help"); 12250 pw.println(" cmd may be one of:"); 12251 pw.println(" l[ibraries]: list known shared libraries"); 12252 pw.println(" f[ibraries]: list device features"); 12253 pw.println(" k[eysets]: print known keysets"); 12254 pw.println(" r[esolvers]: dump intent resolvers"); 12255 pw.println(" perm[issions]: dump permissions"); 12256 pw.println(" pref[erred]: print preferred package settings"); 12257 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 12258 pw.println(" prov[iders]: dump content providers"); 12259 pw.println(" p[ackages]: dump installed packages"); 12260 pw.println(" s[hared-users]: dump shared user IDs"); 12261 pw.println(" m[essages]: print collected runtime messages"); 12262 pw.println(" v[erifiers]: print package verifier info"); 12263 pw.println(" version: print database version info"); 12264 pw.println(" write: write current settings now"); 12265 pw.println(" <package.name>: info about given package"); 12266 pw.println(" installs: details about install sessions"); 12267 return; 12268 } else if ("--checkin".equals(opt)) { 12269 checkin = true; 12270 } else if ("-f".equals(opt)) { 12271 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 12272 } else { 12273 pw.println("Unknown argument: " + opt + "; use -h for help"); 12274 } 12275 } 12276 12277 // Is the caller requesting to dump a particular piece of data? 12278 if (opti < args.length) { 12279 String cmd = args[opti]; 12280 opti++; 12281 // Is this a package name? 12282 if ("android".equals(cmd) || cmd.contains(".")) { 12283 packageName = cmd; 12284 // When dumping a single package, we always dump all of its 12285 // filter information since the amount of data will be reasonable. 12286 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 12287 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 12288 dumpState.setDump(DumpState.DUMP_LIBS); 12289 } else if ("f".equals(cmd) || "features".equals(cmd)) { 12290 dumpState.setDump(DumpState.DUMP_FEATURES); 12291 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 12292 dumpState.setDump(DumpState.DUMP_RESOLVERS); 12293 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 12294 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 12295 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 12296 dumpState.setDump(DumpState.DUMP_PREFERRED); 12297 } else if ("preferred-xml".equals(cmd)) { 12298 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 12299 if (opti < args.length && "--full".equals(args[opti])) { 12300 fullPreferred = true; 12301 opti++; 12302 } 12303 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 12304 dumpState.setDump(DumpState.DUMP_PACKAGES); 12305 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 12306 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 12307 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 12308 dumpState.setDump(DumpState.DUMP_PROVIDERS); 12309 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 12310 dumpState.setDump(DumpState.DUMP_MESSAGES); 12311 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 12312 dumpState.setDump(DumpState.DUMP_VERIFIERS); 12313 } else if ("version".equals(cmd)) { 12314 dumpState.setDump(DumpState.DUMP_VERSION); 12315 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 12316 dumpState.setDump(DumpState.DUMP_KEYSETS); 12317 } else if ("write".equals(cmd)) { 12318 synchronized (mPackages) { 12319 mSettings.writeLPr(); 12320 pw.println("Settings written."); 12321 return; 12322 } 12323 } else if ("installs".equals(cmd)) { 12324 dumpState.setDump(DumpState.DUMP_INSTALLS); 12325 } 12326 } 12327 12328 if (checkin) { 12329 pw.println("vers,1"); 12330 } 12331 12332 // reader 12333 synchronized (mPackages) { 12334 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 12335 if (!checkin) { 12336 if (dumpState.onTitlePrinted()) 12337 pw.println(); 12338 pw.println("Database versions:"); 12339 pw.print(" SDK Version:"); 12340 pw.print(" internal="); 12341 pw.print(mSettings.mInternalSdkPlatform); 12342 pw.print(" external="); 12343 pw.println(mSettings.mExternalSdkPlatform); 12344 pw.print(" DB Version:"); 12345 pw.print(" internal="); 12346 pw.print(mSettings.mInternalDatabaseVersion); 12347 pw.print(" external="); 12348 pw.println(mSettings.mExternalDatabaseVersion); 12349 } 12350 } 12351 12352 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 12353 if (!checkin) { 12354 if (dumpState.onTitlePrinted()) 12355 pw.println(); 12356 pw.println("Verifiers:"); 12357 pw.print(" Required: "); 12358 pw.print(mRequiredVerifierPackage); 12359 pw.print(" (uid="); 12360 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 12361 pw.println(")"); 12362 } else if (mRequiredVerifierPackage != null) { 12363 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 12364 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 12365 } 12366 } 12367 12368 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 12369 boolean printedHeader = false; 12370 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 12371 while (it.hasNext()) { 12372 String name = it.next(); 12373 SharedLibraryEntry ent = mSharedLibraries.get(name); 12374 if (!checkin) { 12375 if (!printedHeader) { 12376 if (dumpState.onTitlePrinted()) 12377 pw.println(); 12378 pw.println("Libraries:"); 12379 printedHeader = true; 12380 } 12381 pw.print(" "); 12382 } else { 12383 pw.print("lib,"); 12384 } 12385 pw.print(name); 12386 if (!checkin) { 12387 pw.print(" -> "); 12388 } 12389 if (ent.path != null) { 12390 if (!checkin) { 12391 pw.print("(jar) "); 12392 pw.print(ent.path); 12393 } else { 12394 pw.print(",jar,"); 12395 pw.print(ent.path); 12396 } 12397 } else { 12398 if (!checkin) { 12399 pw.print("(apk) "); 12400 pw.print(ent.apk); 12401 } else { 12402 pw.print(",apk,"); 12403 pw.print(ent.apk); 12404 } 12405 } 12406 pw.println(); 12407 } 12408 } 12409 12410 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 12411 if (dumpState.onTitlePrinted()) 12412 pw.println(); 12413 if (!checkin) { 12414 pw.println("Features:"); 12415 } 12416 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 12417 while (it.hasNext()) { 12418 String name = it.next(); 12419 if (!checkin) { 12420 pw.print(" "); 12421 } else { 12422 pw.print("feat,"); 12423 } 12424 pw.println(name); 12425 } 12426 } 12427 12428 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 12429 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 12430 : "Activity Resolver Table:", " ", packageName, 12431 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 12432 dumpState.setTitlePrinted(true); 12433 } 12434 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 12435 : "Receiver Resolver Table:", " ", packageName, 12436 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 12437 dumpState.setTitlePrinted(true); 12438 } 12439 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 12440 : "Service Resolver Table:", " ", packageName, 12441 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 12442 dumpState.setTitlePrinted(true); 12443 } 12444 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 12445 : "Provider Resolver Table:", " ", packageName, 12446 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 12447 dumpState.setTitlePrinted(true); 12448 } 12449 } 12450 12451 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 12452 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 12453 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 12454 int user = mSettings.mPreferredActivities.keyAt(i); 12455 if (pir.dump(pw, 12456 dumpState.getTitlePrinted() 12457 ? "\nPreferred Activities User " + user + ":" 12458 : "Preferred Activities User " + user + ":", " ", 12459 packageName, true)) { 12460 dumpState.setTitlePrinted(true); 12461 } 12462 } 12463 } 12464 12465 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 12466 pw.flush(); 12467 FileOutputStream fout = new FileOutputStream(fd); 12468 BufferedOutputStream str = new BufferedOutputStream(fout); 12469 XmlSerializer serializer = new FastXmlSerializer(); 12470 try { 12471 serializer.setOutput(str, "utf-8"); 12472 serializer.startDocument(null, true); 12473 serializer.setFeature( 12474 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 12475 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 12476 serializer.endDocument(); 12477 serializer.flush(); 12478 } catch (IllegalArgumentException e) { 12479 pw.println("Failed writing: " + e); 12480 } catch (IllegalStateException e) { 12481 pw.println("Failed writing: " + e); 12482 } catch (IOException e) { 12483 pw.println("Failed writing: " + e); 12484 } 12485 } 12486 12487 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 12488 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 12489 if (packageName == null) { 12490 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 12491 if (iperm == 0) { 12492 if (dumpState.onTitlePrinted()) 12493 pw.println(); 12494 pw.println("AppOp Permissions:"); 12495 } 12496 pw.print(" AppOp Permission "); 12497 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 12498 pw.println(":"); 12499 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 12500 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 12501 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 12502 } 12503 } 12504 } 12505 } 12506 12507 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 12508 boolean printedSomething = false; 12509 for (PackageParser.Provider p : mProviders.mProviders.values()) { 12510 if (packageName != null && !packageName.equals(p.info.packageName)) { 12511 continue; 12512 } 12513 if (!printedSomething) { 12514 if (dumpState.onTitlePrinted()) 12515 pw.println(); 12516 pw.println("Registered ContentProviders:"); 12517 printedSomething = true; 12518 } 12519 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 12520 pw.print(" "); pw.println(p.toString()); 12521 } 12522 printedSomething = false; 12523 for (Map.Entry<String, PackageParser.Provider> entry : 12524 mProvidersByAuthority.entrySet()) { 12525 PackageParser.Provider p = entry.getValue(); 12526 if (packageName != null && !packageName.equals(p.info.packageName)) { 12527 continue; 12528 } 12529 if (!printedSomething) { 12530 if (dumpState.onTitlePrinted()) 12531 pw.println(); 12532 pw.println("ContentProvider Authorities:"); 12533 printedSomething = true; 12534 } 12535 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 12536 pw.print(" "); pw.println(p.toString()); 12537 if (p.info != null && p.info.applicationInfo != null) { 12538 final String appInfo = p.info.applicationInfo.toString(); 12539 pw.print(" applicationInfo="); pw.println(appInfo); 12540 } 12541 } 12542 } 12543 12544 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 12545 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 12546 } 12547 12548 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 12549 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin); 12550 } 12551 12552 if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 12553 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState); 12554 } 12555 12556 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS)) { 12557 if (dumpState.onTitlePrinted()) pw.println(); 12558 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 12559 } 12560 12561 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 12562 if (dumpState.onTitlePrinted()) pw.println(); 12563 mSettings.dumpReadMessagesLPr(pw, dumpState); 12564 12565 pw.println(); 12566 pw.println("Package warning messages:"); 12567 final File fname = getSettingsProblemFile(); 12568 FileInputStream in = null; 12569 try { 12570 in = new FileInputStream(fname); 12571 final int avail = in.available(); 12572 final byte[] data = new byte[avail]; 12573 in.read(data); 12574 pw.print(new String(data)); 12575 } catch (FileNotFoundException e) { 12576 } catch (IOException e) { 12577 } finally { 12578 if (in != null) { 12579 try { 12580 in.close(); 12581 } catch (IOException e) { 12582 } 12583 } 12584 } 12585 } 12586 } 12587 } 12588 12589 // ------- apps on sdcard specific code ------- 12590 static final boolean DEBUG_SD_INSTALL = false; 12591 12592 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 12593 12594 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 12595 12596 private boolean mMediaMounted = false; 12597 12598 private String getEncryptKey() { 12599 try { 12600 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 12601 SD_ENCRYPTION_KEYSTORE_NAME); 12602 if (sdEncKey == null) { 12603 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 12604 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 12605 if (sdEncKey == null) { 12606 Slog.e(TAG, "Failed to create encryption keys"); 12607 return null; 12608 } 12609 } 12610 return sdEncKey; 12611 } catch (NoSuchAlgorithmException nsae) { 12612 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 12613 return null; 12614 } catch (IOException ioe) { 12615 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 12616 return null; 12617 } 12618 12619 } 12620 12621 /* package */static String getTempContainerId() { 12622 int tmpIdx = 1; 12623 String list[] = PackageHelper.getSecureContainerList(); 12624 if (list != null) { 12625 for (final String name : list) { 12626 // Ignore null and non-temporary container entries 12627 if (name == null || !name.startsWith(mTempContainerPrefix)) { 12628 continue; 12629 } 12630 12631 String subStr = name.substring(mTempContainerPrefix.length()); 12632 try { 12633 int cid = Integer.parseInt(subStr); 12634 if (cid >= tmpIdx) { 12635 tmpIdx = cid + 1; 12636 } 12637 } catch (NumberFormatException e) { 12638 } 12639 } 12640 } 12641 return mTempContainerPrefix + tmpIdx; 12642 } 12643 12644 /* 12645 * Update media status on PackageManager. 12646 */ 12647 @Override 12648 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 12649 int callingUid = Binder.getCallingUid(); 12650 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12651 throw new SecurityException("Media status can only be updated by the system"); 12652 } 12653 // reader; this apparently protects mMediaMounted, but should probably 12654 // be a different lock in that case. 12655 synchronized (mPackages) { 12656 Log.i(TAG, "Updating external media status from " 12657 + (mMediaMounted ? "mounted" : "unmounted") + " to " 12658 + (mediaStatus ? "mounted" : "unmounted")); 12659 if (DEBUG_SD_INSTALL) 12660 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 12661 + ", mMediaMounted=" + mMediaMounted); 12662 if (mediaStatus == mMediaMounted) { 12663 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 12664 : 0, -1); 12665 mHandler.sendMessage(msg); 12666 return; 12667 } 12668 mMediaMounted = mediaStatus; 12669 } 12670 // Queue up an async operation since the package installation may take a 12671 // little while. 12672 mHandler.post(new Runnable() { 12673 public void run() { 12674 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 12675 } 12676 }); 12677 } 12678 12679 /** 12680 * Called by MountService when the initial ASECs to scan are available. 12681 * Should block until all the ASEC containers are finished being scanned. 12682 */ 12683 public void scanAvailableAsecs() { 12684 updateExternalMediaStatusInner(true, false, false); 12685 if (mShouldRestoreconData) { 12686 SELinuxMMAC.setRestoreconDone(); 12687 mShouldRestoreconData = false; 12688 } 12689 } 12690 12691 /* 12692 * Collect information of applications on external media, map them against 12693 * existing containers and update information based on current mount status. 12694 * Please note that we always have to report status if reportStatus has been 12695 * set to true especially when unloading packages. 12696 */ 12697 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 12698 boolean externalStorage) { 12699 // Collection of uids 12700 int uidArr[] = null; 12701 // Collection of stale containers 12702 HashSet<String> removeCids = new HashSet<String>(); 12703 // Collection of packages on external media with valid containers. 12704 HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>(); 12705 // Get list of secure containers. 12706 final String list[] = PackageHelper.getSecureContainerList(); 12707 if (list == null || list.length == 0) { 12708 Log.i(TAG, "No secure containers on sdcard"); 12709 } else { 12710 // Process list of secure containers and categorize them 12711 // as active or stale based on their package internal state. 12712 int uidList[] = new int[list.length]; 12713 int num = 0; 12714 // reader 12715 synchronized (mPackages) { 12716 for (String cid : list) { 12717 if (DEBUG_SD_INSTALL) 12718 Log.i(TAG, "Processing container " + cid); 12719 String pkgName = getAsecPackageName(cid); 12720 if (pkgName == null) { 12721 if (DEBUG_SD_INSTALL) 12722 Log.i(TAG, "Container : " + cid + " stale"); 12723 removeCids.add(cid); 12724 continue; 12725 } 12726 if (DEBUG_SD_INSTALL) 12727 Log.i(TAG, "Looking for pkg : " + pkgName); 12728 12729 final PackageSetting ps = mSettings.mPackages.get(pkgName); 12730 if (ps == null) { 12731 Log.i(TAG, "Deleting container with no matching settings " + cid); 12732 removeCids.add(cid); 12733 continue; 12734 } 12735 12736 /* 12737 * Skip packages that are not external if we're unmounting 12738 * external storage. 12739 */ 12740 if (externalStorage && !isMounted && !isExternal(ps)) { 12741 continue; 12742 } 12743 12744 final AsecInstallArgs args = new AsecInstallArgs(cid, 12745 getAppDexInstructionSets(ps), isForwardLocked(ps), isMultiArch(ps)); 12746 // The package status is changed only if the code path 12747 // matches between settings and the container id. 12748 if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) { 12749 if (DEBUG_SD_INSTALL) { 12750 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 12751 + " at code path: " + ps.codePathString); 12752 } 12753 12754 // We do have a valid package installed on sdcard 12755 processCids.put(args, ps.codePathString); 12756 final int uid = ps.appId; 12757 if (uid != -1) { 12758 uidList[num++] = uid; 12759 } 12760 } else { 12761 Log.i(TAG, "Deleting stale container for " + cid); 12762 removeCids.add(cid); 12763 } 12764 } 12765 } 12766 12767 if (num > 0) { 12768 // Sort uid list 12769 Arrays.sort(uidList, 0, num); 12770 // Throw away duplicates 12771 uidArr = new int[num]; 12772 uidArr[0] = uidList[0]; 12773 int di = 0; 12774 for (int i = 1; i < num; i++) { 12775 if (uidList[i - 1] != uidList[i]) { 12776 uidArr[di++] = uidList[i]; 12777 } 12778 } 12779 } 12780 } 12781 // Process packages with valid entries. 12782 if (isMounted) { 12783 if (DEBUG_SD_INSTALL) 12784 Log.i(TAG, "Loading packages"); 12785 loadMediaPackages(processCids, uidArr, removeCids); 12786 startCleaningPackages(); 12787 } else { 12788 if (DEBUG_SD_INSTALL) 12789 Log.i(TAG, "Unloading packages"); 12790 unloadMediaPackages(processCids, uidArr, reportStatus); 12791 } 12792 } 12793 12794 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 12795 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 12796 int size = pkgList.size(); 12797 if (size > 0) { 12798 // Send broadcasts here 12799 Bundle extras = new Bundle(); 12800 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList 12801 .toArray(new String[size])); 12802 if (uidArr != null) { 12803 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 12804 } 12805 if (replacing) { 12806 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 12807 } 12808 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 12809 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 12810 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 12811 } 12812 } 12813 12814 /* 12815 * Look at potentially valid container ids from processCids If package 12816 * information doesn't match the one on record or package scanning fails, 12817 * the cid is added to list of removeCids. We currently don't delete stale 12818 * containers. 12819 */ 12820 private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], 12821 HashSet<String> removeCids) { 12822 ArrayList<String> pkgList = new ArrayList<String>(); 12823 Set<AsecInstallArgs> keys = processCids.keySet(); 12824 boolean doGc = false; 12825 for (AsecInstallArgs args : keys) { 12826 String codePath = processCids.get(args); 12827 if (DEBUG_SD_INSTALL) 12828 Log.i(TAG, "Loading container : " + args.cid); 12829 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12830 try { 12831 // Make sure there are no container errors first. 12832 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 12833 Slog.e(TAG, "Failed to mount cid : " + args.cid 12834 + " when installing from sdcard"); 12835 continue; 12836 } 12837 // Check code path here. 12838 if (codePath == null || !codePath.equals(args.getCodePath())) { 12839 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 12840 + " does not match one in settings " + codePath); 12841 continue; 12842 } 12843 // Parse package 12844 int parseFlags = mDefParseFlags; 12845 if (args.isExternal()) { 12846 parseFlags |= PackageParser.PARSE_ON_SDCARD; 12847 } 12848 if (args.isFwdLocked()) { 12849 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 12850 } 12851 12852 doGc = true; 12853 synchronized (mInstallLock) { 12854 PackageParser.Package pkg = null; 12855 try { 12856 pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null, null); 12857 } catch (PackageManagerException e) { 12858 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 12859 } 12860 // Scan the package 12861 if (pkg != null) { 12862 /* 12863 * TODO why is the lock being held? doPostInstall is 12864 * called in other places without the lock. This needs 12865 * to be straightened out. 12866 */ 12867 // writer 12868 synchronized (mPackages) { 12869 retCode = PackageManager.INSTALL_SUCCEEDED; 12870 pkgList.add(pkg.packageName); 12871 // Post process args 12872 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 12873 pkg.applicationInfo.uid); 12874 } 12875 } else { 12876 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 12877 } 12878 } 12879 12880 } finally { 12881 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 12882 // Don't destroy container here. Wait till gc clears things 12883 // up. 12884 removeCids.add(args.cid); 12885 } 12886 } 12887 } 12888 // writer 12889 synchronized (mPackages) { 12890 // If the platform SDK has changed since the last time we booted, 12891 // we need to re-grant app permission to catch any new ones that 12892 // appear. This is really a hack, and means that apps can in some 12893 // cases get permissions that the user didn't initially explicitly 12894 // allow... it would be nice to have some better way to handle 12895 // this situation. 12896 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 12897 if (regrantPermissions) 12898 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 12899 + mSdkVersion + "; regranting permissions for external storage"); 12900 mSettings.mExternalSdkPlatform = mSdkVersion; 12901 12902 // Make sure group IDs have been assigned, and any permission 12903 // changes in other apps are accounted for 12904 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 12905 | (regrantPermissions 12906 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 12907 : 0)); 12908 12909 mSettings.updateExternalDatabaseVersion(); 12910 12911 // can downgrade to reader 12912 // Persist settings 12913 mSettings.writeLPr(); 12914 } 12915 // Send a broadcast to let everyone know we are done processing 12916 if (pkgList.size() > 0) { 12917 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 12918 } 12919 // Force gc to avoid any stale parser references that we might have. 12920 if (doGc) { 12921 Runtime.getRuntime().gc(); 12922 } 12923 // List stale containers and destroy stale temporary containers. 12924 if (removeCids != null) { 12925 for (String cid : removeCids) { 12926 if (cid.startsWith(mTempContainerPrefix)) { 12927 Log.i(TAG, "Destroying stale temporary container " + cid); 12928 PackageHelper.destroySdDir(cid); 12929 } else { 12930 Log.w(TAG, "Container " + cid + " is stale"); 12931 } 12932 } 12933 } 12934 } 12935 12936 /* 12937 * Utility method to unload a list of specified containers 12938 */ 12939 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 12940 // Just unmount all valid containers. 12941 for (AsecInstallArgs arg : cidArgs) { 12942 synchronized (mInstallLock) { 12943 arg.doPostDeleteLI(false); 12944 } 12945 } 12946 } 12947 12948 /* 12949 * Unload packages mounted on external media. This involves deleting package 12950 * data from internal structures, sending broadcasts about diabled packages, 12951 * gc'ing to free up references, unmounting all secure containers 12952 * corresponding to packages on external media, and posting a 12953 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 12954 * that we always have to post this message if status has been requested no 12955 * matter what. 12956 */ 12957 private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], 12958 final boolean reportStatus) { 12959 if (DEBUG_SD_INSTALL) 12960 Log.i(TAG, "unloading media packages"); 12961 ArrayList<String> pkgList = new ArrayList<String>(); 12962 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 12963 final Set<AsecInstallArgs> keys = processCids.keySet(); 12964 for (AsecInstallArgs args : keys) { 12965 String pkgName = args.getPackageName(); 12966 if (DEBUG_SD_INSTALL) 12967 Log.i(TAG, "Trying to unload pkg : " + pkgName); 12968 // Delete package internally 12969 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 12970 synchronized (mInstallLock) { 12971 boolean res = deletePackageLI(pkgName, null, false, null, null, 12972 PackageManager.DELETE_KEEP_DATA, outInfo, false); 12973 if (res) { 12974 pkgList.add(pkgName); 12975 } else { 12976 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 12977 failedList.add(args); 12978 } 12979 } 12980 } 12981 12982 // reader 12983 synchronized (mPackages) { 12984 // We didn't update the settings after removing each package; 12985 // write them now for all packages. 12986 mSettings.writeLPr(); 12987 } 12988 12989 // We have to absolutely send UPDATED_MEDIA_STATUS only 12990 // after confirming that all the receivers processed the ordered 12991 // broadcast when packages get disabled, force a gc to clean things up. 12992 // and unload all the containers. 12993 if (pkgList.size() > 0) { 12994 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 12995 new IIntentReceiver.Stub() { 12996 public void performReceive(Intent intent, int resultCode, String data, 12997 Bundle extras, boolean ordered, boolean sticky, 12998 int sendingUser) throws RemoteException { 12999 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 13000 reportStatus ? 1 : 0, 1, keys); 13001 mHandler.sendMessage(msg); 13002 } 13003 }); 13004 } else { 13005 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 13006 keys); 13007 mHandler.sendMessage(msg); 13008 } 13009 } 13010 13011 /** Binder call */ 13012 @Override 13013 public void movePackage(final String packageName, final IPackageMoveObserver observer, 13014 final int flags) { 13015 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 13016 UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 13017 int returnCode = PackageManager.MOVE_SUCCEEDED; 13018 int currFlags = 0; 13019 int newFlags = 0; 13020 // reader 13021 synchronized (mPackages) { 13022 PackageParser.Package pkg = mPackages.get(packageName); 13023 if (pkg == null) { 13024 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 13025 } else { 13026 // Disable moving fwd locked apps and system packages 13027 if (pkg.applicationInfo != null && isSystemApp(pkg)) { 13028 Slog.w(TAG, "Cannot move system application"); 13029 returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 13030 } else if (pkg.mOperationPending) { 13031 Slog.w(TAG, "Attempt to move package which has pending operations"); 13032 returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING; 13033 } else { 13034 // Find install location first 13035 if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 13036 && (flags & PackageManager.MOVE_INTERNAL) != 0) { 13037 Slog.w(TAG, "Ambigous flags specified for move location."); 13038 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 13039 } else { 13040 newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL 13041 : PackageManager.INSTALL_INTERNAL; 13042 currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL 13043 : PackageManager.INSTALL_INTERNAL; 13044 13045 if (newFlags == currFlags) { 13046 Slog.w(TAG, "No move required. Trying to move to same location"); 13047 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 13048 } else { 13049 if (isForwardLocked(pkg)) { 13050 currFlags |= PackageManager.INSTALL_FORWARD_LOCK; 13051 newFlags |= PackageManager.INSTALL_FORWARD_LOCK; 13052 } 13053 } 13054 } 13055 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 13056 pkg.mOperationPending = true; 13057 } 13058 } 13059 } 13060 13061 /* 13062 * TODO this next block probably shouldn't be inside the lock. We 13063 * can't guarantee these won't change after this is fired off 13064 * anyway. 13065 */ 13066 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 13067 processPendingMove(new MoveParams(null, observer, 0, packageName, null, -1, user, false), 13068 returnCode); 13069 } else { 13070 Message msg = mHandler.obtainMessage(INIT_COPY); 13071 final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo); 13072 final boolean multiArch = isMultiArch(pkg.applicationInfo); 13073 InstallArgs srcArgs = createInstallArgsForExisting(currFlags, 13074 pkg.applicationInfo.getCodePath(), pkg.applicationInfo.getResourcePath(), 13075 pkg.applicationInfo.nativeLibraryRootDir, instructionSets, multiArch); 13076 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName, 13077 instructionSets, pkg.applicationInfo.uid, user, multiArch); 13078 msg.obj = mp; 13079 mHandler.sendMessage(msg); 13080 } 13081 } 13082 } 13083 13084 private void processPendingMove(final MoveParams mp, final int currentStatus) { 13085 // Queue up an async operation since the package deletion may take a 13086 // little while. 13087 mHandler.post(new Runnable() { 13088 public void run() { 13089 // TODO fix this; this does nothing. 13090 mHandler.removeCallbacks(this); 13091 int returnCode = currentStatus; 13092 if (currentStatus == PackageManager.MOVE_SUCCEEDED) { 13093 int uidArr[] = null; 13094 ArrayList<String> pkgList = null; 13095 synchronized (mPackages) { 13096 PackageParser.Package pkg = mPackages.get(mp.packageName); 13097 if (pkg == null) { 13098 Slog.w(TAG, " Package " + mp.packageName 13099 + " doesn't exist. Aborting move"); 13100 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 13101 } else if (!mp.srcArgs.getCodePath().equals( 13102 pkg.applicationInfo.getCodePath())) { 13103 Slog.w(TAG, "Package " + mp.packageName + " code path changed from " 13104 + mp.srcArgs.getCodePath() + " to " 13105 + pkg.applicationInfo.getCodePath() 13106 + " Aborting move and returning error"); 13107 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 13108 } else { 13109 uidArr = new int[] { 13110 pkg.applicationInfo.uid 13111 }; 13112 pkgList = new ArrayList<String>(); 13113 pkgList.add(mp.packageName); 13114 } 13115 } 13116 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 13117 // Send resources unavailable broadcast 13118 sendResourcesChangedBroadcast(false, true, pkgList, uidArr, null); 13119 // Update package code and resource paths 13120 synchronized (mInstallLock) { 13121 synchronized (mPackages) { 13122 PackageParser.Package pkg = mPackages.get(mp.packageName); 13123 // Recheck for package again. 13124 if (pkg == null) { 13125 Slog.w(TAG, " Package " + mp.packageName 13126 + " doesn't exist. Aborting move"); 13127 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 13128 } else if (!mp.srcArgs.getCodePath().equals( 13129 pkg.applicationInfo.getCodePath())) { 13130 Slog.w(TAG, "Package " + mp.packageName 13131 + " code path changed from " + mp.srcArgs.getCodePath() 13132 + " to " + pkg.applicationInfo.getCodePath() 13133 + " Aborting move and returning error"); 13134 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 13135 } else { 13136 final String oldCodePath = pkg.codePath; 13137 final String newCodePath = mp.targetArgs.getCodePath(); 13138 final String newResPath = mp.targetArgs.getResourcePath(); 13139 // TODO: This assumes the new style of installation. 13140 // should we look at legacyNativeLibraryPath ? 13141 final String newNativeRoot = new File(pkg.codePath, LIB_DIR_NAME).getAbsolutePath(); 13142 final File newNativeDir = new File(newNativeRoot); 13143 13144 if (!isForwardLocked(pkg) && !isExternal(pkg)) { 13145 // TODO(multiArch): Fix this so that it looks at the existing 13146 // recorded CPU abis from the package. There's no need for a separate 13147 // round of ABI scanning here. 13148 NativeLibraryHelper.Handle handle = null; 13149 try { 13150 handle = NativeLibraryHelper.Handle.create( 13151 new File(newCodePath)); 13152 final int abi = NativeLibraryHelper.findSupportedAbi( 13153 handle, Build.SUPPORTED_ABIS); 13154 if (abi >= 0) { 13155 NativeLibraryHelper.copyNativeBinariesIfNeededLI( 13156 handle, newNativeDir, Build.SUPPORTED_ABIS[abi]); 13157 } 13158 } catch (IOException ioe) { 13159 Slog.w(TAG, "Unable to extract native libs for package :" 13160 + mp.packageName, ioe); 13161 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 13162 } finally { 13163 IoUtils.closeQuietly(handle); 13164 } 13165 } 13166 13167 final int[] users = sUserManager.getUserIds(); 13168 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 13169 for (int user : users) { 13170 // TODO(multiArch): Fix this so that it links to the 13171 // correct directory. We're currently pointing to root. but we 13172 // must point to the arch specific subdirectory (if applicable). 13173 // 13174 // TODO(multiArch): Bogus reference to nativeLibraryDir. 13175 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, 13176 newNativeRoot, user) < 0) { 13177 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 13178 } 13179 } 13180 } 13181 13182 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 13183 pkg.codePath = newCodePath; 13184 pkg.baseCodePath = newCodePath; 13185 // Move dex files around 13186 if (moveDexFilesLI(oldCodePath, pkg) != PackageManager.INSTALL_SUCCEEDED) { 13187 // Moving of dex files failed. Set 13188 // error code and abort move. 13189 pkg.codePath = oldCodePath; 13190 pkg.baseCodePath = oldCodePath; 13191 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 13192 } 13193 } 13194 13195 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 13196 pkg.applicationInfo.setCodePath(newCodePath); 13197 pkg.applicationInfo.setBaseCodePath(newCodePath); 13198 pkg.applicationInfo.setSplitCodePaths(null); 13199 pkg.applicationInfo.setResourcePath(newResPath); 13200 pkg.applicationInfo.setBaseResourcePath(newResPath); 13201 pkg.applicationInfo.setSplitResourcePaths(null); 13202 13203 PackageSetting ps = (PackageSetting) pkg.mExtras; 13204 ps.codePath = new File(pkg.applicationInfo.getCodePath()); 13205 ps.codePathString = ps.codePath.getPath(); 13206 ps.resourcePath = new File(pkg.applicationInfo.getResourcePath()); 13207 ps.resourcePathString = ps.resourcePath.getPath(); 13208 13209 // Note that we don't have to recalculate the primary and secondary 13210 // CPU ABIs because they must already have been calculated during the 13211 // initial install of the app. 13212 ps.legacyNativeLibraryPathString = null; 13213 13214 // Set the application info flag 13215 // correctly. 13216 if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) { 13217 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE; 13218 } else { 13219 pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE; 13220 } 13221 ps.setFlags(pkg.applicationInfo.flags); 13222 mAppDirs.remove(oldCodePath); 13223 mAppDirs.put(newCodePath, pkg); 13224 // Persist settings 13225 mSettings.writeLPr(); 13226 } 13227 } 13228 } 13229 } 13230 // Send resources available broadcast 13231 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 13232 } 13233 } 13234 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 13235 // Clean up failed installation 13236 if (mp.targetArgs != null) { 13237 mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, 13238 -1); 13239 } 13240 } else { 13241 // Force a gc to clear things up. 13242 Runtime.getRuntime().gc(); 13243 // Delete older code 13244 synchronized (mInstallLock) { 13245 mp.srcArgs.doPostDeleteLI(true); 13246 } 13247 } 13248 13249 // Allow more operations on this file if we didn't fail because 13250 // an operation was already pending for this package. 13251 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) { 13252 synchronized (mPackages) { 13253 PackageParser.Package pkg = mPackages.get(mp.packageName); 13254 if (pkg != null) { 13255 pkg.mOperationPending = false; 13256 } 13257 } 13258 } 13259 13260 IPackageMoveObserver observer = mp.observer; 13261 if (observer != null) { 13262 try { 13263 observer.packageMoved(mp.packageName, returnCode); 13264 } catch (RemoteException e) { 13265 Log.i(TAG, "Observer no longer exists."); 13266 } 13267 } 13268 } 13269 }); 13270 } 13271 13272 @Override 13273 public boolean setInstallLocation(int loc) { 13274 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 13275 null); 13276 if (getInstallLocation() == loc) { 13277 return true; 13278 } 13279 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 13280 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 13281 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 13282 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 13283 return true; 13284 } 13285 return false; 13286 } 13287 13288 @Override 13289 public int getInstallLocation() { 13290 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 13291 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 13292 PackageHelper.APP_INSTALL_AUTO); 13293 } 13294 13295 /** Called by UserManagerService */ 13296 void cleanUpUserLILPw(int userHandle) { 13297 mDirtyUsers.remove(userHandle); 13298 mSettings.removeUserLPw(userHandle); 13299 mPendingBroadcasts.remove(userHandle); 13300 if (mInstaller != null) { 13301 // Technically, we shouldn't be doing this with the package lock 13302 // held. However, this is very rare, and there is already so much 13303 // other disk I/O going on, that we'll let it slide for now. 13304 mInstaller.removeUserDataDirs(userHandle); 13305 } 13306 mUserNeedsBadging.delete(userHandle); 13307 } 13308 13309 /** Called by UserManagerService */ 13310 void createNewUserLILPw(int userHandle, File path) { 13311 if (mInstaller != null) { 13312 mInstaller.createUserConfig(userHandle); 13313 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path); 13314 } 13315 } 13316 13317 @Override 13318 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 13319 mContext.enforceCallingOrSelfPermission( 13320 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13321 "Only package verification agents can read the verifier device identity"); 13322 13323 synchronized (mPackages) { 13324 return mSettings.getVerifierDeviceIdentityLPw(); 13325 } 13326 } 13327 13328 @Override 13329 public void setPermissionEnforced(String permission, boolean enforced) { 13330 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); 13331 if (READ_EXTERNAL_STORAGE.equals(permission)) { 13332 synchronized (mPackages) { 13333 if (mSettings.mReadExternalStorageEnforced == null 13334 || mSettings.mReadExternalStorageEnforced != enforced) { 13335 mSettings.mReadExternalStorageEnforced = enforced; 13336 mSettings.writeLPr(); 13337 } 13338 } 13339 // kill any non-foreground processes so we restart them and 13340 // grant/revoke the GID. 13341 final IActivityManager am = ActivityManagerNative.getDefault(); 13342 if (am != null) { 13343 final long token = Binder.clearCallingIdentity(); 13344 try { 13345 am.killProcessesBelowForeground("setPermissionEnforcement"); 13346 } catch (RemoteException e) { 13347 } finally { 13348 Binder.restoreCallingIdentity(token); 13349 } 13350 } 13351 } else { 13352 throw new IllegalArgumentException("No selective enforcement for " + permission); 13353 } 13354 } 13355 13356 @Override 13357 @Deprecated 13358 public boolean isPermissionEnforced(String permission) { 13359 return true; 13360 } 13361 13362 @Override 13363 public boolean isStorageLow() { 13364 final long token = Binder.clearCallingIdentity(); 13365 try { 13366 final DeviceStorageMonitorInternal 13367 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 13368 if (dsm != null) { 13369 return dsm.isMemoryLow(); 13370 } else { 13371 return false; 13372 } 13373 } finally { 13374 Binder.restoreCallingIdentity(token); 13375 } 13376 } 13377 13378 @Override 13379 public IPackageInstaller getPackageInstaller() { 13380 return mInstallerService; 13381 } 13382 13383 private boolean userNeedsBadging(int userId) { 13384 int index = mUserNeedsBadging.indexOfKey(userId); 13385 if (index < 0) { 13386 final UserInfo userInfo; 13387 final long token = Binder.clearCallingIdentity(); 13388 try { 13389 userInfo = sUserManager.getUserInfo(userId); 13390 } finally { 13391 Binder.restoreCallingIdentity(token); 13392 } 13393 final boolean b; 13394 if (userInfo != null && userInfo.isManagedProfile()) { 13395 b = true; 13396 } else { 13397 b = false; 13398 } 13399 mUserNeedsBadging.put(userId, b); 13400 return b; 13401 } 13402 return mUserNeedsBadging.valueAt(index); 13403 } 13404 13405 @Override 13406 public KeySet getKeySetByAlias(String packageName, String alias) { 13407 if (packageName == null || alias == null) { 13408 return null; 13409 } 13410 synchronized(mPackages) { 13411 final PackageParser.Package pkg = mPackages.get(packageName); 13412 if (pkg == null) { 13413 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 13414 throw new IllegalArgumentException("Unknown package: " + packageName); 13415 } 13416 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13417 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 13418 } 13419 } 13420 13421 @Override 13422 public KeySet getSigningKeySet(String packageName) { 13423 if (packageName == null) { 13424 return null; 13425 } 13426 synchronized(mPackages) { 13427 final PackageParser.Package pkg = mPackages.get(packageName); 13428 if (pkg == null) { 13429 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 13430 throw new IllegalArgumentException("Unknown package: " + packageName); 13431 } 13432 if (pkg.applicationInfo.uid != Binder.getCallingUid() 13433 && Process.SYSTEM_UID != Binder.getCallingUid()) { 13434 throw new SecurityException("May not access signing KeySet of other apps."); 13435 } 13436 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13437 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 13438 } 13439 } 13440 13441 @Override 13442 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 13443 if (packageName == null || ks == null) { 13444 return false; 13445 } 13446 synchronized(mPackages) { 13447 final PackageParser.Package pkg = mPackages.get(packageName); 13448 if (pkg == null) { 13449 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 13450 throw new IllegalArgumentException("Unknown package: " + packageName); 13451 } 13452 IBinder ksh = ks.getToken(); 13453 if (ksh instanceof KeySetHandle) { 13454 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13455 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 13456 } 13457 return false; 13458 } 13459 } 13460 13461 @Override 13462 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 13463 if (packageName == null || ks == null) { 13464 return false; 13465 } 13466 synchronized(mPackages) { 13467 final PackageParser.Package pkg = mPackages.get(packageName); 13468 if (pkg == null) { 13469 Slog.w(TAG, "KeySet requested for unknown package:" + packageName); 13470 throw new IllegalArgumentException("Unknown package: " + packageName); 13471 } 13472 IBinder ksh = ks.getToken(); 13473 if (ksh instanceof KeySetHandle) { 13474 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13475 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 13476 } 13477 return false; 13478 } 13479 } 13480} 13481