PackageManagerService.java revision 0b5598c924fc140db5cfee08c17fd91e630b1c9e
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.system.OsConstants.S_IRWXU; 27import static android.system.OsConstants.S_IRGRP; 28import static android.system.OsConstants.S_IXGRP; 29import static android.system.OsConstants.S_IROTH; 30import static android.system.OsConstants.S_IXOTH; 31import static android.os.Process.PACKAGE_INFO_GID; 32import static android.os.Process.SYSTEM_UID; 33import static com.android.internal.util.ArrayUtils.appendInt; 34import static com.android.internal.util.ArrayUtils.removeInt; 35 36import com.android.internal.R; 37import com.android.internal.app.IMediaContainerService; 38import com.android.internal.app.ResolverActivity; 39import com.android.internal.content.NativeLibraryHelper; 40import com.android.internal.content.PackageHelper; 41import com.android.internal.util.FastPrintWriter; 42import com.android.internal.util.FastXmlSerializer; 43import com.android.internal.util.XmlUtils; 44import com.android.server.EventLogTags; 45import com.android.server.IntentResolver; 46import com.android.server.LocalServices; 47import com.android.server.ServiceThread; 48import com.android.server.Watchdog; 49import com.android.server.storage.DeviceStorageMonitorInternal; 50 51import org.xmlpull.v1.XmlPullParser; 52import org.xmlpull.v1.XmlPullParserException; 53import org.xmlpull.v1.XmlSerializer; 54 55import android.app.ActivityManager; 56import android.app.ActivityManagerNative; 57import android.app.IActivityManager; 58import android.app.admin.IDevicePolicyManager; 59import android.app.backup.IBackupManager; 60import android.content.BroadcastReceiver; 61import android.content.ComponentName; 62import android.content.Context; 63import android.content.IIntentReceiver; 64import android.content.Intent; 65import android.content.IntentFilter; 66import android.content.IntentSender; 67import android.content.IntentSender.SendIntentException; 68import android.content.ServiceConnection; 69import android.content.pm.ActivityInfo; 70import android.content.pm.ApplicationInfo; 71import android.content.pm.ContainerEncryptionParams; 72import android.content.pm.FeatureInfo; 73import android.content.pm.IPackageDataObserver; 74import android.content.pm.IPackageDeleteObserver; 75import android.content.pm.IPackageInstallObserver; 76import android.content.pm.IPackageManager; 77import android.content.pm.IPackageMoveObserver; 78import android.content.pm.IPackageStatsObserver; 79import android.content.pm.InstrumentationInfo; 80import android.content.pm.ManifestDigest; 81import android.content.pm.PackageCleanItem; 82import android.content.pm.PackageInfo; 83import android.content.pm.PackageInfoLite; 84import android.content.pm.PackageManager; 85import android.content.pm.PackageParser.ActivityIntentInfo; 86import android.content.pm.PackageParser; 87import android.content.pm.PackageStats; 88import android.content.pm.PackageUserState; 89import android.content.pm.ParceledListSlice; 90import android.content.pm.PermissionGroupInfo; 91import android.content.pm.PermissionInfo; 92import android.content.pm.ProviderInfo; 93import android.content.pm.ResolveInfo; 94import android.content.pm.ServiceInfo; 95import android.content.pm.Signature; 96import android.content.pm.VerificationParams; 97import android.content.pm.VerifierDeviceIdentity; 98import android.content.pm.VerifierInfo; 99import android.content.res.Resources; 100import android.hardware.display.DisplayManager; 101import android.net.Uri; 102import android.os.Binder; 103import android.os.Build; 104import android.os.Bundle; 105import android.os.Environment; 106import android.os.Environment.UserEnvironment; 107import android.os.FileObserver; 108import android.os.FileUtils; 109import android.os.Handler; 110import android.os.IBinder; 111import android.os.Looper; 112import android.os.Message; 113import android.os.Parcel; 114import android.os.ParcelFileDescriptor; 115import android.os.Process; 116import android.os.RemoteException; 117import android.os.SELinux; 118import android.os.ServiceManager; 119import android.os.SystemClock; 120import android.os.SystemProperties; 121import android.os.UserHandle; 122import android.os.UserManager; 123import android.security.KeyStore; 124import android.security.SystemKeyStore; 125import android.system.ErrnoException; 126import android.system.Os; 127import android.system.StructStat; 128import android.text.TextUtils; 129import android.util.AtomicFile; 130import android.util.DisplayMetrics; 131import android.util.EventLog; 132import android.util.Log; 133import android.util.LogPrinter; 134import android.util.PrintStreamPrinter; 135import android.util.Slog; 136import android.util.SparseArray; 137import android.util.Xml; 138import android.view.Display; 139 140import java.io.BufferedInputStream; 141import java.io.BufferedOutputStream; 142import java.io.File; 143import java.io.FileDescriptor; 144import java.io.FileInputStream; 145import java.io.FileNotFoundException; 146import java.io.FileOutputStream; 147import java.io.FileReader; 148import java.io.FilenameFilter; 149import java.io.IOException; 150import java.io.InputStream; 151import java.io.PrintWriter; 152import java.nio.charset.StandardCharsets; 153import java.security.NoSuchAlgorithmException; 154import java.security.PublicKey; 155import java.security.cert.CertificateException; 156import java.text.SimpleDateFormat; 157import java.util.ArrayList; 158import java.util.Arrays; 159import java.util.Collection; 160import java.util.Collections; 161import java.util.Comparator; 162import java.util.Date; 163import java.util.HashMap; 164import java.util.HashSet; 165import java.util.Iterator; 166import java.util.List; 167import java.util.Map; 168import java.util.Set; 169import java.util.concurrent.atomic.AtomicBoolean; 170import java.util.concurrent.atomic.AtomicLong; 171 172import dalvik.system.DexFile; 173import dalvik.system.StaleDexCacheError; 174import dalvik.system.VMRuntime; 175import libcore.io.IoUtils; 176 177/** 178 * Keep track of all those .apks everywhere. 179 * 180 * This is very central to the platform's security; please run the unit 181 * tests whenever making modifications here: 182 * 183mmm frameworks/base/tests/AndroidTests 184adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 185adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 186 * 187 * {@hide} 188 */ 189public class PackageManagerService extends IPackageManager.Stub { 190 static final String TAG = "PackageManager"; 191 static final boolean DEBUG_SETTINGS = false; 192 static final boolean DEBUG_PREFERRED = false; 193 static final boolean DEBUG_UPGRADE = false; 194 private static final boolean DEBUG_INSTALL = false; 195 private static final boolean DEBUG_REMOVE = false; 196 private static final boolean DEBUG_BROADCASTS = false; 197 private static final boolean DEBUG_SHOW_INFO = false; 198 private static final boolean DEBUG_PACKAGE_INFO = false; 199 private static final boolean DEBUG_INTENT_MATCHING = false; 200 private static final boolean DEBUG_PACKAGE_SCANNING = false; 201 private static final boolean DEBUG_APP_DIR_OBSERVER = false; 202 private static final boolean DEBUG_VERIFY = false; 203 private static final boolean DEBUG_DEXOPT = false; 204 205 private static final int RADIO_UID = Process.PHONE_UID; 206 private static final int LOG_UID = Process.LOG_UID; 207 private static final int NFC_UID = Process.NFC_UID; 208 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 209 private static final int SHELL_UID = Process.SHELL_UID; 210 211 private static final boolean GET_CERTIFICATES = true; 212 213 private static final int REMOVE_EVENTS = 214 FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM; 215 private static final int ADD_EVENTS = 216 FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO; 217 218 private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS; 219 // Suffix used during package installation when copying/moving 220 // package apks to install directory. 221 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 222 223 static final int SCAN_MONITOR = 1<<0; 224 static final int SCAN_NO_DEX = 1<<1; 225 static final int SCAN_FORCE_DEX = 1<<2; 226 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 227 static final int SCAN_NEW_INSTALL = 1<<4; 228 static final int SCAN_NO_PATHS = 1<<5; 229 static final int SCAN_UPDATE_TIME = 1<<6; 230 static final int SCAN_DEFER_DEX = 1<<7; 231 static final int SCAN_BOOTING = 1<<8; 232 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 233 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 234 235 static final int REMOVE_CHATTY = 1<<16; 236 237 /** 238 * Timeout (in milliseconds) after which the watchdog should declare that 239 * our handler thread is wedged. The usual default for such things is one 240 * minute but we sometimes do very lengthy I/O operations on this thread, 241 * such as installing multi-gigabyte applications, so ours needs to be longer. 242 */ 243 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 244 245 /** 246 * Whether verification is enabled by default. 247 */ 248 private static final boolean DEFAULT_VERIFY_ENABLE = true; 249 250 /** 251 * The default maximum time to wait for the verification agent to return in 252 * milliseconds. 253 */ 254 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 255 256 /** 257 * The default response for package verification timeout. 258 * 259 * This can be either PackageManager.VERIFICATION_ALLOW or 260 * PackageManager.VERIFICATION_REJECT. 261 */ 262 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 263 264 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 265 266 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 267 DEFAULT_CONTAINER_PACKAGE, 268 "com.android.defcontainer.DefaultContainerService"); 269 270 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 271 272 private static final String LIB_DIR_NAME = "lib"; 273 private static final String LIB64_DIR_NAME = "lib64"; 274 275 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 276 277 static final String mTempContainerPrefix = "smdl2tmp"; 278 279 final ServiceThread mHandlerThread; 280 281 private static String sPreferredInstructionSet; 282 283 private static final String IDMAP_PREFIX = "/data/resource-cache/"; 284 private static final String IDMAP_SUFFIX = "@idmap"; 285 286 final PackageHandler mHandler; 287 288 final int mSdkVersion = Build.VERSION.SDK_INT; 289 final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME) 290 ? null : Build.VERSION.CODENAME; 291 292 final Context mContext; 293 final boolean mFactoryTest; 294 final boolean mOnlyCore; 295 final DisplayMetrics mMetrics; 296 final int mDefParseFlags; 297 final String[] mSeparateProcesses; 298 299 // This is where all application persistent data goes. 300 final File mAppDataDir; 301 302 // This is where all application persistent data goes for secondary users. 303 final File mUserAppDataDir; 304 305 /** The location for ASEC container files on internal storage. */ 306 final String mAsecInternalPath; 307 308 // This is the object monitoring the framework dir. 309 final FileObserver mFrameworkInstallObserver; 310 311 // This is the object monitoring the system app dir. 312 final FileObserver mSystemInstallObserver; 313 314 // This is the object monitoring the privileged system app dir. 315 final FileObserver mPrivilegedInstallObserver; 316 317 // This is the object monitoring the system app dir. 318 final FileObserver mVendorInstallObserver; 319 320 // This is the object monitoring the vendor overlay package dir. 321 final FileObserver mVendorOverlayInstallObserver; 322 323 // This is the object monitoring mAppInstallDir. 324 final FileObserver mAppInstallObserver; 325 326 // This is the object monitoring mDrmAppPrivateInstallDir. 327 final FileObserver mDrmAppInstallObserver; 328 329 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 330 // LOCK HELD. Can be called with mInstallLock held. 331 final Installer mInstaller; 332 333 final File mAppInstallDir; 334 335 /** 336 * Directory to which applications installed internally have native 337 * libraries copied. 338 */ 339 private File mAppLibInstallDir; 340 341 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 342 // apps. 343 final File mDrmAppPrivateInstallDir; 344 345 // ---------------------------------------------------------------- 346 347 // Lock for state used when installing and doing other long running 348 // operations. Methods that must be called with this lock held have 349 // the prefix "LI". 350 final Object mInstallLock = new Object(); 351 352 // These are the directories in the 3rd party applications installed dir 353 // that we have currently loaded packages from. Keys are the application's 354 // installed zip file (absolute codePath), and values are Package. 355 final HashMap<String, PackageParser.Package> mAppDirs = 356 new HashMap<String, PackageParser.Package>(); 357 358 // Information for the parser to write more useful error messages. 359 int mLastScanError; 360 361 // ---------------------------------------------------------------- 362 363 // Keys are String (package name), values are Package. This also serves 364 // as the lock for the global state. Methods that must be called with 365 // this lock held have the prefix "LP". 366 final HashMap<String, PackageParser.Package> mPackages = 367 new HashMap<String, PackageParser.Package>(); 368 369 // Tracks available target package names -> overlay package paths. 370 final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays = 371 new HashMap<String, HashMap<String, PackageParser.Package>>(); 372 373 final Settings mSettings; 374 boolean mRestoredSettings; 375 376 // Group-ids that are given to all packages as read from etc/permissions/*.xml. 377 int[] mGlobalGids; 378 379 // These are the built-in uid -> permission mappings that were read from the 380 // etc/permissions.xml file. 381 final SparseArray<HashSet<String>> mSystemPermissions = 382 new SparseArray<HashSet<String>>(); 383 384 static final class SharedLibraryEntry { 385 final String path; 386 final String apk; 387 388 SharedLibraryEntry(String _path, String _apk) { 389 path = _path; 390 apk = _apk; 391 } 392 } 393 394 // These are the built-in shared libraries that were read from the 395 // etc/permissions.xml file. 396 final HashMap<String, SharedLibraryEntry> mSharedLibraries 397 = new HashMap<String, SharedLibraryEntry>(); 398 399 // Temporary for building the final shared libraries for an .apk. 400 String[] mTmpSharedLibraries = null; 401 402 // These are the features this devices supports that were read from the 403 // etc/permissions.xml file. 404 final HashMap<String, FeatureInfo> mAvailableFeatures = 405 new HashMap<String, FeatureInfo>(); 406 407 // If mac_permissions.xml was found for seinfo labeling. 408 boolean mFoundPolicyFile; 409 410 // If a recursive restorecon of /data/data/<pkg> is needed. 411 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 412 413 // All available activities, for your resolving pleasure. 414 final ActivityIntentResolver mActivities = 415 new ActivityIntentResolver(); 416 417 // All available receivers, for your resolving pleasure. 418 final ActivityIntentResolver mReceivers = 419 new ActivityIntentResolver(); 420 421 // All available services, for your resolving pleasure. 422 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 423 424 // All available providers, for your resolving pleasure. 425 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 426 427 // Mapping from provider base names (first directory in content URI codePath) 428 // to the provider information. 429 final HashMap<String, PackageParser.Provider> mProvidersByAuthority = 430 new HashMap<String, PackageParser.Provider>(); 431 432 // Mapping from instrumentation class names to info about them. 433 final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 434 new HashMap<ComponentName, PackageParser.Instrumentation>(); 435 436 // Mapping from permission names to info about them. 437 final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups = 438 new HashMap<String, PackageParser.PermissionGroup>(); 439 440 // Packages whose data we have transfered into another package, thus 441 // should no longer exist. 442 final HashSet<String> mTransferedPackages = new HashSet<String>(); 443 444 // Broadcast actions that are only available to the system. 445 final HashSet<String> mProtectedBroadcasts = new HashSet<String>(); 446 447 /** List of packages waiting for verification. */ 448 final SparseArray<PackageVerificationState> mPendingVerification 449 = new SparseArray<PackageVerificationState>(); 450 451 HashSet<PackageParser.Package> mDeferredDexOpt = null; 452 453 /** Token for keys in mPendingVerification. */ 454 private int mPendingVerificationToken = 0; 455 456 boolean mSystemReady; 457 boolean mSafeMode; 458 boolean mHasSystemUidErrors; 459 460 ApplicationInfo mAndroidApplication; 461 final ActivityInfo mResolveActivity = new ActivityInfo(); 462 final ResolveInfo mResolveInfo = new ResolveInfo(); 463 ComponentName mResolveComponentName; 464 PackageParser.Package mPlatformPackage; 465 ComponentName mCustomResolverComponentName; 466 467 boolean mResolverReplaced = false; 468 469 // Set of pending broadcasts for aggregating enable/disable of components. 470 static class PendingPackageBroadcasts { 471 // for each user id, a map of <package name -> components within that package> 472 final SparseArray<HashMap<String, ArrayList<String>>> mUidMap; 473 474 public PendingPackageBroadcasts() { 475 mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2); 476 } 477 478 public ArrayList<String> get(int userId, String packageName) { 479 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId); 480 return packages.get(packageName); 481 } 482 483 public void put(int userId, String packageName, ArrayList<String> components) { 484 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId); 485 packages.put(packageName, components); 486 } 487 488 public void remove(int userId, String packageName) { 489 HashMap<String, ArrayList<String>> packages = mUidMap.get(userId); 490 if (packages != null) { 491 packages.remove(packageName); 492 } 493 } 494 495 public void remove(int userId) { 496 mUidMap.remove(userId); 497 } 498 499 public int userIdCount() { 500 return mUidMap.size(); 501 } 502 503 public int userIdAt(int n) { 504 return mUidMap.keyAt(n); 505 } 506 507 public HashMap<String, ArrayList<String>> packagesForUserId(int userId) { 508 return mUidMap.get(userId); 509 } 510 511 public int size() { 512 // total number of pending broadcast entries across all userIds 513 int num = 0; 514 for (int i = 0; i< mUidMap.size(); i++) { 515 num += mUidMap.valueAt(i).size(); 516 } 517 return num; 518 } 519 520 public void clear() { 521 mUidMap.clear(); 522 } 523 524 private HashMap<String, ArrayList<String>> getOrAllocate(int userId) { 525 HashMap<String, ArrayList<String>> map = mUidMap.get(userId); 526 if (map == null) { 527 map = new HashMap<String, ArrayList<String>>(); 528 mUidMap.put(userId, map); 529 } 530 return map; 531 } 532 } 533 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 534 535 // Service Connection to remote media container service to copy 536 // package uri's from external media onto secure containers 537 // or internal storage. 538 private IMediaContainerService mContainerService = null; 539 540 static final int SEND_PENDING_BROADCAST = 1; 541 static final int MCS_BOUND = 3; 542 static final int END_COPY = 4; 543 static final int INIT_COPY = 5; 544 static final int MCS_UNBIND = 6; 545 static final int START_CLEANING_PACKAGE = 7; 546 static final int FIND_INSTALL_LOC = 8; 547 static final int POST_INSTALL = 9; 548 static final int MCS_RECONNECT = 10; 549 static final int MCS_GIVE_UP = 11; 550 static final int UPDATED_MEDIA_STATUS = 12; 551 static final int WRITE_SETTINGS = 13; 552 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 553 static final int PACKAGE_VERIFIED = 15; 554 static final int CHECK_PENDING_VERIFICATION = 16; 555 556 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 557 558 // Delay time in millisecs 559 static final int BROADCAST_DELAY = 10 * 1000; 560 561 static UserManagerService sUserManager; 562 563 // Stores a list of users whose package restrictions file needs to be updated 564 private HashSet<Integer> mDirtyUsers = new HashSet<Integer>(); 565 566 final private DefaultContainerConnection mDefContainerConn = 567 new DefaultContainerConnection(); 568 class DefaultContainerConnection implements ServiceConnection { 569 public void onServiceConnected(ComponentName name, IBinder service) { 570 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 571 IMediaContainerService imcs = 572 IMediaContainerService.Stub.asInterface(service); 573 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 574 } 575 576 public void onServiceDisconnected(ComponentName name) { 577 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 578 } 579 }; 580 581 // Recordkeeping of restore-after-install operations that are currently in flight 582 // between the Package Manager and the Backup Manager 583 class PostInstallData { 584 public InstallArgs args; 585 public PackageInstalledInfo res; 586 587 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 588 args = _a; 589 res = _r; 590 } 591 }; 592 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 593 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 594 595 private final String mRequiredVerifierPackage; 596 597 private final PackageUsage mPackageUsage = new PackageUsage(); 598 599 private class PackageUsage { 600 private static final int WRITE_INTERVAL 601 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 602 603 private final Object mFileLock = new Object(); 604 private final AtomicLong mLastWritten = new AtomicLong(0); 605 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 606 607 void write(boolean force) { 608 if (force) { 609 write(); 610 return; 611 } 612 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 613 && !DEBUG_DEXOPT) { 614 return; 615 } 616 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 617 new Thread("PackageUsage_DiskWriter") { 618 @Override 619 public void run() { 620 try { 621 write(true); 622 } finally { 623 mBackgroundWriteRunning.set(false); 624 } 625 } 626 }.start(); 627 } 628 } 629 630 private void write() { 631 synchronized (mPackages) { 632 synchronized (mFileLock) { 633 AtomicFile file = getFile(); 634 FileOutputStream f = null; 635 try { 636 f = file.startWrite(); 637 BufferedOutputStream out = new BufferedOutputStream(f); 638 FileUtils.setPermissions(file.getBaseFile().getPath(), 0660, SYSTEM_UID, PACKAGE_INFO_GID); 639 StringBuilder sb = new StringBuilder(); 640 for (PackageParser.Package pkg : mPackages.values()) { 641 if (pkg.mLastPackageUsageTimeInMills == 0) { 642 continue; 643 } 644 sb.setLength(0); 645 sb.append(pkg.packageName); 646 sb.append(' '); 647 sb.append((long)pkg.mLastPackageUsageTimeInMills); 648 sb.append('\n'); 649 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 650 } 651 out.flush(); 652 file.finishWrite(f); 653 } catch (IOException e) { 654 if (f != null) { 655 file.failWrite(f); 656 } 657 Log.e(TAG, "Failed to write package usage times", e); 658 } 659 } 660 } 661 mLastWritten.set(SystemClock.elapsedRealtime()); 662 } 663 664 void readLP() { 665 synchronized (mFileLock) { 666 AtomicFile file = getFile(); 667 BufferedInputStream in = null; 668 try { 669 in = new BufferedInputStream(file.openRead()); 670 StringBuffer sb = new StringBuffer(); 671 while (true) { 672 String packageName = readToken(in, sb, ' '); 673 if (packageName == null) { 674 break; 675 } 676 String timeInMillisString = readToken(in, sb, '\n'); 677 if (timeInMillisString == null) { 678 throw new IOException("Failed to find last usage time for package " 679 + packageName); 680 } 681 PackageParser.Package pkg = mPackages.get(packageName); 682 if (pkg == null) { 683 continue; 684 } 685 long timeInMillis; 686 try { 687 timeInMillis = Long.parseLong(timeInMillisString.toString()); 688 } catch (NumberFormatException e) { 689 throw new IOException("Failed to parse " + timeInMillisString 690 + " as a long.", e); 691 } 692 pkg.mLastPackageUsageTimeInMills = timeInMillis; 693 } 694 } catch (FileNotFoundException expected) { 695 } catch (IOException e) { 696 Log.w(TAG, "Failed to read package usage times", e); 697 } finally { 698 IoUtils.closeQuietly(in); 699 } 700 } 701 mLastWritten.set(SystemClock.elapsedRealtime()); 702 } 703 704 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 705 throws IOException { 706 sb.setLength(0); 707 while (true) { 708 int ch = in.read(); 709 if (ch == -1) { 710 if (sb.length() == 0) { 711 return null; 712 } 713 throw new IOException("Unexpected EOF"); 714 } 715 if (ch == endOfToken) { 716 return sb.toString(); 717 } 718 sb.append((char)ch); 719 } 720 } 721 722 private AtomicFile getFile() { 723 File dataDir = Environment.getDataDirectory(); 724 File systemDir = new File(dataDir, "system"); 725 File fname = new File(systemDir, "package-usage.list"); 726 return new AtomicFile(fname); 727 } 728 } 729 730 class PackageHandler extends Handler { 731 private boolean mBound = false; 732 final ArrayList<HandlerParams> mPendingInstalls = 733 new ArrayList<HandlerParams>(); 734 735 private boolean connectToService() { 736 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 737 " DefaultContainerService"); 738 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 739 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 740 if (mContext.bindServiceAsUser(service, mDefContainerConn, 741 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 742 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 743 mBound = true; 744 return true; 745 } 746 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 747 return false; 748 } 749 750 private void disconnectService() { 751 mContainerService = null; 752 mBound = false; 753 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 754 mContext.unbindService(mDefContainerConn); 755 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 756 } 757 758 PackageHandler(Looper looper) { 759 super(looper); 760 } 761 762 public void handleMessage(Message msg) { 763 try { 764 doHandleMessage(msg); 765 } finally { 766 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 767 } 768 } 769 770 void doHandleMessage(Message msg) { 771 switch (msg.what) { 772 case INIT_COPY: { 773 HandlerParams params = (HandlerParams) msg.obj; 774 int idx = mPendingInstalls.size(); 775 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 776 // If a bind was already initiated we dont really 777 // need to do anything. The pending install 778 // will be processed later on. 779 if (!mBound) { 780 // If this is the only one pending we might 781 // have to bind to the service again. 782 if (!connectToService()) { 783 Slog.e(TAG, "Failed to bind to media container service"); 784 params.serviceError(); 785 return; 786 } else { 787 // Once we bind to the service, the first 788 // pending request will be processed. 789 mPendingInstalls.add(idx, params); 790 } 791 } else { 792 mPendingInstalls.add(idx, params); 793 // Already bound to the service. Just make 794 // sure we trigger off processing the first request. 795 if (idx == 0) { 796 mHandler.sendEmptyMessage(MCS_BOUND); 797 } 798 } 799 break; 800 } 801 case MCS_BOUND: { 802 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 803 if (msg.obj != null) { 804 mContainerService = (IMediaContainerService) msg.obj; 805 } 806 if (mContainerService == null) { 807 // Something seriously wrong. Bail out 808 Slog.e(TAG, "Cannot bind to media container service"); 809 for (HandlerParams params : mPendingInstalls) { 810 // Indicate service bind error 811 params.serviceError(); 812 } 813 mPendingInstalls.clear(); 814 } else if (mPendingInstalls.size() > 0) { 815 HandlerParams params = mPendingInstalls.get(0); 816 if (params != null) { 817 if (params.startCopy()) { 818 // We are done... look for more work or to 819 // go idle. 820 if (DEBUG_SD_INSTALL) Log.i(TAG, 821 "Checking for more work or unbind..."); 822 // Delete pending install 823 if (mPendingInstalls.size() > 0) { 824 mPendingInstalls.remove(0); 825 } 826 if (mPendingInstalls.size() == 0) { 827 if (mBound) { 828 if (DEBUG_SD_INSTALL) Log.i(TAG, 829 "Posting delayed MCS_UNBIND"); 830 removeMessages(MCS_UNBIND); 831 Message ubmsg = obtainMessage(MCS_UNBIND); 832 // Unbind after a little delay, to avoid 833 // continual thrashing. 834 sendMessageDelayed(ubmsg, 10000); 835 } 836 } else { 837 // There are more pending requests in queue. 838 // Just post MCS_BOUND message to trigger processing 839 // of next pending install. 840 if (DEBUG_SD_INSTALL) Log.i(TAG, 841 "Posting MCS_BOUND for next woek"); 842 mHandler.sendEmptyMessage(MCS_BOUND); 843 } 844 } 845 } 846 } else { 847 // Should never happen ideally. 848 Slog.w(TAG, "Empty queue"); 849 } 850 break; 851 } 852 case MCS_RECONNECT: { 853 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 854 if (mPendingInstalls.size() > 0) { 855 if (mBound) { 856 disconnectService(); 857 } 858 if (!connectToService()) { 859 Slog.e(TAG, "Failed to bind to media container service"); 860 for (HandlerParams params : mPendingInstalls) { 861 // Indicate service bind error 862 params.serviceError(); 863 } 864 mPendingInstalls.clear(); 865 } 866 } 867 break; 868 } 869 case MCS_UNBIND: { 870 // If there is no actual work left, then time to unbind. 871 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 872 873 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 874 if (mBound) { 875 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 876 877 disconnectService(); 878 } 879 } else if (mPendingInstalls.size() > 0) { 880 // There are more pending requests in queue. 881 // Just post MCS_BOUND message to trigger processing 882 // of next pending install. 883 mHandler.sendEmptyMessage(MCS_BOUND); 884 } 885 886 break; 887 } 888 case MCS_GIVE_UP: { 889 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 890 mPendingInstalls.remove(0); 891 break; 892 } 893 case SEND_PENDING_BROADCAST: { 894 String packages[]; 895 ArrayList<String> components[]; 896 int size = 0; 897 int uids[]; 898 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 899 synchronized (mPackages) { 900 if (mPendingBroadcasts == null) { 901 return; 902 } 903 size = mPendingBroadcasts.size(); 904 if (size <= 0) { 905 // Nothing to be done. Just return 906 return; 907 } 908 packages = new String[size]; 909 components = new ArrayList[size]; 910 uids = new int[size]; 911 int i = 0; // filling out the above arrays 912 913 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 914 int packageUserId = mPendingBroadcasts.userIdAt(n); 915 Iterator<Map.Entry<String, ArrayList<String>>> it 916 = mPendingBroadcasts.packagesForUserId(packageUserId) 917 .entrySet().iterator(); 918 while (it.hasNext() && i < size) { 919 Map.Entry<String, ArrayList<String>> ent = it.next(); 920 packages[i] = ent.getKey(); 921 components[i] = ent.getValue(); 922 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 923 uids[i] = (ps != null) 924 ? UserHandle.getUid(packageUserId, ps.appId) 925 : -1; 926 i++; 927 } 928 } 929 size = i; 930 mPendingBroadcasts.clear(); 931 } 932 // Send broadcasts 933 for (int i = 0; i < size; i++) { 934 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 935 } 936 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 937 break; 938 } 939 case START_CLEANING_PACKAGE: { 940 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 941 final String packageName = (String)msg.obj; 942 final int userId = msg.arg1; 943 final boolean andCode = msg.arg2 != 0; 944 synchronized (mPackages) { 945 if (userId == UserHandle.USER_ALL) { 946 int[] users = sUserManager.getUserIds(); 947 for (int user : users) { 948 mSettings.addPackageToCleanLPw( 949 new PackageCleanItem(user, packageName, andCode)); 950 } 951 } else { 952 mSettings.addPackageToCleanLPw( 953 new PackageCleanItem(userId, packageName, andCode)); 954 } 955 } 956 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 957 startCleaningPackages(); 958 } break; 959 case POST_INSTALL: { 960 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 961 PostInstallData data = mRunningInstalls.get(msg.arg1); 962 mRunningInstalls.delete(msg.arg1); 963 boolean deleteOld = false; 964 965 if (data != null) { 966 InstallArgs args = data.args; 967 PackageInstalledInfo res = data.res; 968 969 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 970 res.removedInfo.sendBroadcast(false, true, false); 971 Bundle extras = new Bundle(1); 972 extras.putInt(Intent.EXTRA_UID, res.uid); 973 // Determine the set of users who are adding this 974 // package for the first time vs. those who are seeing 975 // an update. 976 int[] firstUsers; 977 int[] updateUsers = new int[0]; 978 if (res.origUsers == null || res.origUsers.length == 0) { 979 firstUsers = res.newUsers; 980 } else { 981 firstUsers = new int[0]; 982 for (int i=0; i<res.newUsers.length; i++) { 983 int user = res.newUsers[i]; 984 boolean isNew = true; 985 for (int j=0; j<res.origUsers.length; j++) { 986 if (res.origUsers[j] == user) { 987 isNew = false; 988 break; 989 } 990 } 991 if (isNew) { 992 int[] newFirst = new int[firstUsers.length+1]; 993 System.arraycopy(firstUsers, 0, newFirst, 0, 994 firstUsers.length); 995 newFirst[firstUsers.length] = user; 996 firstUsers = newFirst; 997 } else { 998 int[] newUpdate = new int[updateUsers.length+1]; 999 System.arraycopy(updateUsers, 0, newUpdate, 0, 1000 updateUsers.length); 1001 newUpdate[updateUsers.length] = user; 1002 updateUsers = newUpdate; 1003 } 1004 } 1005 } 1006 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1007 res.pkg.applicationInfo.packageName, 1008 extras, null, null, firstUsers); 1009 final boolean update = res.removedInfo.removedPackage != null; 1010 if (update) { 1011 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1012 } 1013 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 1014 res.pkg.applicationInfo.packageName, 1015 extras, null, null, updateUsers); 1016 if (update) { 1017 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1018 res.pkg.applicationInfo.packageName, 1019 extras, null, null, updateUsers); 1020 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1021 null, null, 1022 res.pkg.applicationInfo.packageName, null, updateUsers); 1023 1024 // treat asec-hosted packages like removable media on upgrade 1025 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) { 1026 if (DEBUG_INSTALL) { 1027 Slog.i(TAG, "upgrading pkg " + res.pkg 1028 + " is ASEC-hosted -> AVAILABLE"); 1029 } 1030 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 1031 ArrayList<String> pkgList = new ArrayList<String>(1); 1032 pkgList.add(res.pkg.applicationInfo.packageName); 1033 sendResourcesChangedBroadcast(true, true, 1034 pkgList,uidArray, null); 1035 } 1036 } 1037 if (res.removedInfo.args != null) { 1038 // Remove the replaced package's older resources safely now 1039 deleteOld = true; 1040 } 1041 1042 // Log current value of "unknown sources" setting 1043 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1044 getUnknownSourcesSettings()); 1045 } 1046 // Force a gc to clear up things 1047 Runtime.getRuntime().gc(); 1048 // We delete after a gc for applications on sdcard. 1049 if (deleteOld) { 1050 synchronized (mInstallLock) { 1051 res.removedInfo.args.doPostDeleteLI(true); 1052 } 1053 } 1054 if (args.observer != null) { 1055 try { 1056 args.observer.packageInstalled(res.name, res.returnCode); 1057 } catch (RemoteException e) { 1058 Slog.i(TAG, "Observer no longer exists."); 1059 } 1060 } 1061 } else { 1062 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1063 } 1064 } break; 1065 case UPDATED_MEDIA_STATUS: { 1066 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1067 boolean reportStatus = msg.arg1 == 1; 1068 boolean doGc = msg.arg2 == 1; 1069 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1070 if (doGc) { 1071 // Force a gc to clear up stale containers. 1072 Runtime.getRuntime().gc(); 1073 } 1074 if (msg.obj != null) { 1075 @SuppressWarnings("unchecked") 1076 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1077 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1078 // Unload containers 1079 unloadAllContainers(args); 1080 } 1081 if (reportStatus) { 1082 try { 1083 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1084 PackageHelper.getMountService().finishMediaUpdate(); 1085 } catch (RemoteException e) { 1086 Log.e(TAG, "MountService not running?"); 1087 } 1088 } 1089 } break; 1090 case WRITE_SETTINGS: { 1091 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1092 synchronized (mPackages) { 1093 removeMessages(WRITE_SETTINGS); 1094 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1095 mSettings.writeLPr(); 1096 mDirtyUsers.clear(); 1097 } 1098 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1099 } break; 1100 case WRITE_PACKAGE_RESTRICTIONS: { 1101 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1102 synchronized (mPackages) { 1103 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1104 for (int userId : mDirtyUsers) { 1105 mSettings.writePackageRestrictionsLPr(userId); 1106 } 1107 mDirtyUsers.clear(); 1108 } 1109 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1110 } break; 1111 case CHECK_PENDING_VERIFICATION: { 1112 final int verificationId = msg.arg1; 1113 final PackageVerificationState state = mPendingVerification.get(verificationId); 1114 1115 if ((state != null) && !state.timeoutExtended()) { 1116 final InstallArgs args = state.getInstallArgs(); 1117 Slog.i(TAG, "Verification timed out for " + args.packageURI.toString()); 1118 mPendingVerification.remove(verificationId); 1119 1120 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1121 1122 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1123 Slog.i(TAG, "Continuing with installation of " 1124 + args.packageURI.toString()); 1125 state.setVerifierResponse(Binder.getCallingUid(), 1126 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1127 broadcastPackageVerified(verificationId, args.packageURI, 1128 PackageManager.VERIFICATION_ALLOW, 1129 state.getInstallArgs().getUser()); 1130 try { 1131 ret = args.copyApk(mContainerService, true); 1132 } catch (RemoteException e) { 1133 Slog.e(TAG, "Could not contact the ContainerService"); 1134 } 1135 } else { 1136 broadcastPackageVerified(verificationId, args.packageURI, 1137 PackageManager.VERIFICATION_REJECT, 1138 state.getInstallArgs().getUser()); 1139 } 1140 1141 processPendingInstall(args, ret); 1142 mHandler.sendEmptyMessage(MCS_UNBIND); 1143 } 1144 break; 1145 } 1146 case PACKAGE_VERIFIED: { 1147 final int verificationId = msg.arg1; 1148 1149 final PackageVerificationState state = mPendingVerification.get(verificationId); 1150 if (state == null) { 1151 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1152 break; 1153 } 1154 1155 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1156 1157 state.setVerifierResponse(response.callerUid, response.code); 1158 1159 if (state.isVerificationComplete()) { 1160 mPendingVerification.remove(verificationId); 1161 1162 final InstallArgs args = state.getInstallArgs(); 1163 1164 int ret; 1165 if (state.isInstallAllowed()) { 1166 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1167 broadcastPackageVerified(verificationId, args.packageURI, 1168 response.code, state.getInstallArgs().getUser()); 1169 try { 1170 ret = args.copyApk(mContainerService, true); 1171 } catch (RemoteException e) { 1172 Slog.e(TAG, "Could not contact the ContainerService"); 1173 } 1174 } else { 1175 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1176 } 1177 1178 processPendingInstall(args, ret); 1179 1180 mHandler.sendEmptyMessage(MCS_UNBIND); 1181 } 1182 1183 break; 1184 } 1185 } 1186 } 1187 } 1188 1189 void scheduleWriteSettingsLocked() { 1190 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1191 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1192 } 1193 } 1194 1195 void scheduleWritePackageRestrictionsLocked(int userId) { 1196 if (!sUserManager.exists(userId)) return; 1197 mDirtyUsers.add(userId); 1198 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1199 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1200 } 1201 } 1202 1203 public static final IPackageManager main(Context context, Installer installer, 1204 boolean factoryTest, boolean onlyCore) { 1205 PackageManagerService m = new PackageManagerService(context, installer, 1206 factoryTest, onlyCore); 1207 ServiceManager.addService("package", m); 1208 return m; 1209 } 1210 1211 static String[] splitString(String str, char sep) { 1212 int count = 1; 1213 int i = 0; 1214 while ((i=str.indexOf(sep, i)) >= 0) { 1215 count++; 1216 i++; 1217 } 1218 1219 String[] res = new String[count]; 1220 i=0; 1221 count = 0; 1222 int lastI=0; 1223 while ((i=str.indexOf(sep, i)) >= 0) { 1224 res[count] = str.substring(lastI, i); 1225 count++; 1226 i++; 1227 lastI = i; 1228 } 1229 res[count] = str.substring(lastI, str.length()); 1230 return res; 1231 } 1232 1233 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1234 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1235 Context.DISPLAY_SERVICE); 1236 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1237 } 1238 1239 public PackageManagerService(Context context, Installer installer, 1240 boolean factoryTest, boolean onlyCore) { 1241 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1242 SystemClock.uptimeMillis()); 1243 1244 if (mSdkVersion <= 0) { 1245 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1246 } 1247 1248 mContext = context; 1249 mFactoryTest = factoryTest; 1250 mOnlyCore = onlyCore; 1251 mMetrics = new DisplayMetrics(); 1252 mSettings = new Settings(context); 1253 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1254 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1255 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1256 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1257 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1258 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1259 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1260 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1261 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1262 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1263 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1264 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1265 1266 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1267 if (separateProcesses != null && separateProcesses.length() > 0) { 1268 if ("*".equals(separateProcesses)) { 1269 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1270 mSeparateProcesses = null; 1271 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1272 } else { 1273 mDefParseFlags = 0; 1274 mSeparateProcesses = separateProcesses.split(","); 1275 Slog.w(TAG, "Running with debug.separate_processes: " 1276 + separateProcesses); 1277 } 1278 } else { 1279 mDefParseFlags = 0; 1280 mSeparateProcesses = null; 1281 } 1282 1283 mInstaller = installer; 1284 1285 getDefaultDisplayMetrics(context, mMetrics); 1286 1287 synchronized (mInstallLock) { 1288 // writer 1289 synchronized (mPackages) { 1290 mHandlerThread = new ServiceThread(TAG, 1291 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1292 mHandlerThread.start(); 1293 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1294 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1295 1296 File dataDir = Environment.getDataDirectory(); 1297 mAppDataDir = new File(dataDir, "data"); 1298 mAppInstallDir = new File(dataDir, "app"); 1299 mAppLibInstallDir = new File(dataDir, "app-lib"); 1300 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1301 mUserAppDataDir = new File(dataDir, "user"); 1302 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1303 1304 sUserManager = new UserManagerService(context, this, 1305 mInstallLock, mPackages); 1306 1307 readPermissions(); 1308 1309 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1310 1311 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1312 mSdkVersion, mOnlyCore); 1313 1314 String customResolverActivity = Resources.getSystem().getString( 1315 R.string.config_customResolverActivity); 1316 if (TextUtils.isEmpty(customResolverActivity)) { 1317 customResolverActivity = null; 1318 } else { 1319 mCustomResolverComponentName = ComponentName.unflattenFromString( 1320 customResolverActivity); 1321 } 1322 1323 long startTime = SystemClock.uptimeMillis(); 1324 1325 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1326 startTime); 1327 1328 // Set flag to monitor and not change apk file paths when 1329 // scanning install directories. 1330 int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; 1331 1332 final HashSet<String> alreadyDexOpted = new HashSet<String>(); 1333 1334 /** 1335 * Add everything in the in the boot class path to the 1336 * list of process files because dexopt will have been run 1337 * if necessary during zygote startup. 1338 */ 1339 String bootClassPath = System.getProperty("java.boot.class.path"); 1340 if (bootClassPath != null) { 1341 String[] paths = splitString(bootClassPath, ':'); 1342 for (int i=0; i<paths.length; i++) { 1343 alreadyDexOpted.add(paths[i]); 1344 } 1345 } else { 1346 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1347 } 1348 1349 boolean didDexOptLibraryOrTool = false; 1350 1351 final List<String> instructionSets = getAllInstructionSets(); 1352 1353 /** 1354 * Ensure all external libraries have had dexopt run on them. 1355 */ 1356 if (mSharedLibraries.size() > 0) { 1357 // NOTE: For now, we're compiling these system "shared libraries" 1358 // (and framework jars) into all available architectures. It's possible 1359 // to compile them only when we come across an app that uses them (there's 1360 // already logic for that in scanPackageLI) but that adds some complexity. 1361 for (String instructionSet : instructionSets) { 1362 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 1363 final String lib = libEntry.path; 1364 if (lib == null) { 1365 continue; 1366 } 1367 1368 try { 1369 if (DexFile.isDexOptNeededInternal(lib, null, instructionSet, false)) { 1370 alreadyDexOpted.add(lib); 1371 1372 // The list of "shared libraries" we have at this point is 1373 mInstaller.dexopt(lib, Process.SYSTEM_UID, true, instructionSet); 1374 didDexOptLibraryOrTool = true; 1375 } 1376 } catch (FileNotFoundException e) { 1377 Slog.w(TAG, "Library not found: " + lib); 1378 } catch (IOException e) { 1379 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1380 + e.getMessage()); 1381 } 1382 } 1383 } 1384 } 1385 1386 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1387 1388 // Gross hack for now: we know this file doesn't contain any 1389 // code, so don't dexopt it to avoid the resulting log spew. 1390 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 1391 1392 // Gross hack for now: we know this file is only part of 1393 // the boot class path for art, so don't dexopt it to 1394 // avoid the resulting log spew. 1395 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 1396 1397 /** 1398 * And there are a number of commands implemented in Java, which 1399 * we currently need to do the dexopt on so that they can be 1400 * run from a non-root shell. 1401 */ 1402 String[] frameworkFiles = frameworkDir.list(); 1403 if (frameworkFiles != null) { 1404 // TODO: We could compile these only for the most preferred ABI. We should 1405 // first double check that the dex files for these commands are not referenced 1406 // by other system apps. 1407 for (String instructionSet : instructionSets) { 1408 for (int i=0; i<frameworkFiles.length; i++) { 1409 File libPath = new File(frameworkDir, frameworkFiles[i]); 1410 String path = libPath.getPath(); 1411 // Skip the file if we already did it. 1412 if (alreadyDexOpted.contains(path)) { 1413 continue; 1414 } 1415 // Skip the file if it is not a type we want to dexopt. 1416 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 1417 continue; 1418 } 1419 try { 1420 if (DexFile.isDexOptNeededInternal(path, null, instructionSet, false)) { 1421 mInstaller.dexopt(path, Process.SYSTEM_UID, true, instructionSet); 1422 didDexOptLibraryOrTool = true; 1423 } 1424 } catch (FileNotFoundException e) { 1425 Slog.w(TAG, "Jar not found: " + path); 1426 } catch (IOException e) { 1427 Slog.w(TAG, "Exception reading jar: " + path, e); 1428 } 1429 } 1430 } 1431 } 1432 1433 if (didDexOptLibraryOrTool) { 1434 pruneDexFiles(new File(dataDir, "dalvik-cache")); 1435 } 1436 1437 // Collect vendor overlay packages. 1438 // (Do this before scanning any apps.) 1439 // For security and version matching reason, only consider 1440 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 1441 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 1442 mVendorOverlayInstallObserver = new AppDirObserver( 1443 vendorOverlayDir.getPath(), OBSERVER_EVENTS, true, false); 1444 mVendorOverlayInstallObserver.startWatching(); 1445 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 1446 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode | SCAN_TRUSTED_OVERLAY, 0); 1447 1448 // Find base frameworks (resource packages without code). 1449 mFrameworkInstallObserver = new AppDirObserver( 1450 frameworkDir.getPath(), OBSERVER_EVENTS, true, false); 1451 mFrameworkInstallObserver.startWatching(); 1452 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 1453 | PackageParser.PARSE_IS_SYSTEM_DIR 1454 | PackageParser.PARSE_IS_PRIVILEGED, 1455 scanMode | SCAN_NO_DEX, 0); 1456 1457 // Collected privileged system packages. 1458 File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 1459 mPrivilegedInstallObserver = new AppDirObserver( 1460 privilegedAppDir.getPath(), OBSERVER_EVENTS, true, true); 1461 mPrivilegedInstallObserver.startWatching(); 1462 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 1463 | PackageParser.PARSE_IS_SYSTEM_DIR 1464 | PackageParser.PARSE_IS_PRIVILEGED, scanMode, 0); 1465 1466 // Collect ordinary system packages. 1467 File systemAppDir = new File(Environment.getRootDirectory(), "app"); 1468 mSystemInstallObserver = new AppDirObserver( 1469 systemAppDir.getPath(), OBSERVER_EVENTS, true, false); 1470 mSystemInstallObserver.startWatching(); 1471 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 1472 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 1473 1474 // Collect all vendor packages. 1475 File vendorAppDir = new File("/vendor/app"); 1476 try { 1477 vendorAppDir = vendorAppDir.getCanonicalFile(); 1478 } catch (IOException e) { 1479 // failed to look up canonical path, continue with original one 1480 } 1481 mVendorInstallObserver = new AppDirObserver( 1482 vendorAppDir.getPath(), OBSERVER_EVENTS, true, false); 1483 mVendorInstallObserver.startWatching(); 1484 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 1485 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 1486 1487 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 1488 mInstaller.moveFiles(); 1489 1490 // Prune any system packages that no longer exist. 1491 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 1492 if (!mOnlyCore) { 1493 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 1494 while (psit.hasNext()) { 1495 PackageSetting ps = psit.next(); 1496 1497 /* 1498 * If this is not a system app, it can't be a 1499 * disable system app. 1500 */ 1501 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1502 continue; 1503 } 1504 1505 /* 1506 * If the package is scanned, it's not erased. 1507 */ 1508 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 1509 if (scannedPkg != null) { 1510 /* 1511 * If the system app is both scanned and in the 1512 * disabled packages list, then it must have been 1513 * added via OTA. Remove it from the currently 1514 * scanned package so the previously user-installed 1515 * application can be scanned. 1516 */ 1517 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 1518 Slog.i(TAG, "Expecting better updatd system app for " + ps.name 1519 + "; removing system app"); 1520 removePackageLI(ps, true); 1521 } 1522 1523 continue; 1524 } 1525 1526 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 1527 psit.remove(); 1528 String msg = "System package " + ps.name 1529 + " no longer exists; wiping its data"; 1530 reportSettingsProblem(Log.WARN, msg); 1531 removeDataDirsLI(ps.name); 1532 } else { 1533 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 1534 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 1535 possiblyDeletedUpdatedSystemApps.add(ps.name); 1536 } 1537 } 1538 } 1539 } 1540 1541 //look for any incomplete package installations 1542 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 1543 //clean up list 1544 for(int i = 0; i < deletePkgsList.size(); i++) { 1545 //clean up here 1546 cleanupInstallFailedPackage(deletePkgsList.get(i)); 1547 } 1548 //delete tmp files 1549 deleteTempPackageFiles(); 1550 1551 // Remove any shared userIDs that have no associated packages 1552 mSettings.pruneSharedUsersLPw(); 1553 1554 if (!mOnlyCore) { 1555 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 1556 SystemClock.uptimeMillis()); 1557 mAppInstallObserver = new AppDirObserver( 1558 mAppInstallDir.getPath(), OBSERVER_EVENTS, false, false); 1559 mAppInstallObserver.startWatching(); 1560 scanDirLI(mAppInstallDir, 0, scanMode, 0); 1561 1562 mDrmAppInstallObserver = new AppDirObserver( 1563 mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false, false); 1564 mDrmAppInstallObserver.startWatching(); 1565 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 1566 scanMode, 0); 1567 1568 /** 1569 * Remove disable package settings for any updated system 1570 * apps that were removed via an OTA. If they're not a 1571 * previously-updated app, remove them completely. 1572 * Otherwise, just revoke their system-level permissions. 1573 */ 1574 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 1575 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 1576 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 1577 1578 String msg; 1579 if (deletedPkg == null) { 1580 msg = "Updated system package " + deletedAppName 1581 + " no longer exists; wiping its data"; 1582 removeDataDirsLI(deletedAppName); 1583 } else { 1584 msg = "Updated system app + " + deletedAppName 1585 + " no longer present; removing system privileges for " 1586 + deletedAppName; 1587 1588 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 1589 1590 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 1591 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 1592 } 1593 reportSettingsProblem(Log.WARN, msg); 1594 } 1595 } else { 1596 mAppInstallObserver = null; 1597 mDrmAppInstallObserver = null; 1598 } 1599 1600 // Now that we know all of the shared libraries, update all clients to have 1601 // the correct library paths. 1602 updateAllSharedLibrariesLPw(); 1603 1604 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 1605 adjustCpuAbisForSharedUserLPw(setting.packages, true /* do dexopt */, 1606 false /* force dexopt */, false /* defer dexopt */); 1607 } 1608 1609 // Now that we know all the packages we are keeping, 1610 // read and update their last usage times. 1611 mPackageUsage.readLP(); 1612 1613 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 1614 SystemClock.uptimeMillis()); 1615 Slog.i(TAG, "Time to scan packages: " 1616 + ((SystemClock.uptimeMillis()-startTime)/1000f) 1617 + " seconds"); 1618 1619 // If the platform SDK has changed since the last time we booted, 1620 // we need to re-grant app permission to catch any new ones that 1621 // appear. This is really a hack, and means that apps can in some 1622 // cases get permissions that the user didn't initially explicitly 1623 // allow... it would be nice to have some better way to handle 1624 // this situation. 1625 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 1626 != mSdkVersion; 1627 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 1628 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 1629 + "; regranting permissions for internal storage"); 1630 mSettings.mInternalSdkPlatform = mSdkVersion; 1631 1632 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 1633 | (regrantPermissions 1634 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 1635 : 0)); 1636 1637 // If this is the first boot, and it is a normal boot, then 1638 // we need to initialize the default preferred apps. 1639 if (!mRestoredSettings && !onlyCore) { 1640 mSettings.readDefaultPreferredAppsLPw(this, 0); 1641 } 1642 1643 // can downgrade to reader 1644 mSettings.writeLPr(); 1645 1646 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 1647 SystemClock.uptimeMillis()); 1648 1649 // Now after opening every single application zip, make sure they 1650 // are all flushed. Not really needed, but keeps things nice and 1651 // tidy. 1652 Runtime.getRuntime().gc(); 1653 1654 mRequiredVerifierPackage = getRequiredVerifierLPr(); 1655 } // synchronized (mPackages) 1656 } // synchronized (mInstallLock) 1657 } 1658 1659 private static void pruneDexFiles(File cacheDir) { 1660 // If we had to do a dexopt of one of the previous 1661 // things, then something on the system has changed. 1662 // Consider this significant, and wipe away all other 1663 // existing dexopt files to ensure we don't leave any 1664 // dangling around. 1665 // 1666 // Additionally, delete all dex files from the root directory 1667 // since there shouldn't be any there anyway. 1668 // 1669 // Note: This isn't as good an indicator as it used to be. It 1670 // used to include the boot classpath but at some point 1671 // DexFile.isDexOptNeeded started returning false for the boot 1672 // class path files in all cases. It is very possible in a 1673 // small maintenance release update that the library and tool 1674 // jars may be unchanged but APK could be removed resulting in 1675 // unused dalvik-cache files. 1676 File[] files = cacheDir.listFiles(); 1677 if (files != null) { 1678 for (File file : files) { 1679 if (!file.isDirectory()) { 1680 Slog.i(TAG, "Pruning dalvik file: " + file.getAbsolutePath()); 1681 file.delete(); 1682 } else { 1683 File[] subDirList = file.listFiles(); 1684 if (subDirList != null) { 1685 for (File subDirFile : subDirList) { 1686 final String fn = subDirFile.getName(); 1687 if (fn.startsWith("data@app@") || fn.startsWith("data@app-private@")) { 1688 Slog.i(TAG, "Pruning dalvik file: " + fn); 1689 subDirFile.delete(); 1690 } 1691 } 1692 } 1693 } 1694 } 1695 } 1696 } 1697 1698 @Override 1699 public boolean isFirstBoot() { 1700 return !mRestoredSettings; 1701 } 1702 1703 @Override 1704 public boolean isOnlyCoreApps() { 1705 return mOnlyCore; 1706 } 1707 1708 private String getRequiredVerifierLPr() { 1709 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 1710 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 1711 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 1712 1713 String requiredVerifier = null; 1714 1715 final int N = receivers.size(); 1716 for (int i = 0; i < N; i++) { 1717 final ResolveInfo info = receivers.get(i); 1718 1719 if (info.activityInfo == null) { 1720 continue; 1721 } 1722 1723 final String packageName = info.activityInfo.packageName; 1724 1725 final PackageSetting ps = mSettings.mPackages.get(packageName); 1726 if (ps == null) { 1727 continue; 1728 } 1729 1730 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1731 if (!gp.grantedPermissions 1732 .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) { 1733 continue; 1734 } 1735 1736 if (requiredVerifier != null) { 1737 throw new RuntimeException("There can be only one required verifier"); 1738 } 1739 1740 requiredVerifier = packageName; 1741 } 1742 1743 return requiredVerifier; 1744 } 1745 1746 @Override 1747 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1748 throws RemoteException { 1749 try { 1750 return super.onTransact(code, data, reply, flags); 1751 } catch (RuntimeException e) { 1752 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 1753 Slog.wtf(TAG, "Package Manager Crash", e); 1754 } 1755 throw e; 1756 } 1757 } 1758 1759 void cleanupInstallFailedPackage(PackageSetting ps) { 1760 Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name); 1761 removeDataDirsLI(ps.name); 1762 if (ps.codePath != null) { 1763 if (!ps.codePath.delete()) { 1764 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath); 1765 } 1766 } 1767 if (ps.resourcePath != null) { 1768 if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) { 1769 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath); 1770 } 1771 } 1772 mSettings.removePackageLPw(ps.name); 1773 } 1774 1775 void readPermissions() { 1776 // Read permissions from .../etc/permission directory. 1777 File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions"); 1778 if (!libraryDir.exists() || !libraryDir.isDirectory()) { 1779 Slog.w(TAG, "No directory " + libraryDir + ", skipping"); 1780 return; 1781 } 1782 if (!libraryDir.canRead()) { 1783 Slog.w(TAG, "Directory " + libraryDir + " cannot be read"); 1784 return; 1785 } 1786 1787 // Iterate over the files in the directory and scan .xml files 1788 for (File f : libraryDir.listFiles()) { 1789 // We'll read platform.xml last 1790 if (f.getPath().endsWith("etc/permissions/platform.xml")) { 1791 continue; 1792 } 1793 1794 if (!f.getPath().endsWith(".xml")) { 1795 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring"); 1796 continue; 1797 } 1798 if (!f.canRead()) { 1799 Slog.w(TAG, "Permissions library file " + f + " cannot be read"); 1800 continue; 1801 } 1802 1803 readPermissionsFromXml(f); 1804 } 1805 1806 // Read permissions from .../etc/permissions/platform.xml last so it will take precedence 1807 final File permFile = new File(Environment.getRootDirectory(), 1808 "etc/permissions/platform.xml"); 1809 readPermissionsFromXml(permFile); 1810 } 1811 1812 private void readPermissionsFromXml(File permFile) { 1813 FileReader permReader = null; 1814 try { 1815 permReader = new FileReader(permFile); 1816 } catch (FileNotFoundException e) { 1817 Slog.w(TAG, "Couldn't find or open permissions file " + permFile); 1818 return; 1819 } 1820 1821 try { 1822 XmlPullParser parser = Xml.newPullParser(); 1823 parser.setInput(permReader); 1824 1825 XmlUtils.beginDocument(parser, "permissions"); 1826 1827 while (true) { 1828 XmlUtils.nextElement(parser); 1829 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { 1830 break; 1831 } 1832 1833 String name = parser.getName(); 1834 if ("group".equals(name)) { 1835 String gidStr = parser.getAttributeValue(null, "gid"); 1836 if (gidStr != null) { 1837 int gid = Process.getGidForName(gidStr); 1838 mGlobalGids = appendInt(mGlobalGids, gid); 1839 } else { 1840 Slog.w(TAG, "<group> without gid at " 1841 + parser.getPositionDescription()); 1842 } 1843 1844 XmlUtils.skipCurrentTag(parser); 1845 continue; 1846 } else if ("permission".equals(name)) { 1847 String perm = parser.getAttributeValue(null, "name"); 1848 if (perm == null) { 1849 Slog.w(TAG, "<permission> without name at " 1850 + parser.getPositionDescription()); 1851 XmlUtils.skipCurrentTag(parser); 1852 continue; 1853 } 1854 perm = perm.intern(); 1855 readPermission(parser, perm); 1856 1857 } else if ("assign-permission".equals(name)) { 1858 String perm = parser.getAttributeValue(null, "name"); 1859 if (perm == null) { 1860 Slog.w(TAG, "<assign-permission> without name at " 1861 + parser.getPositionDescription()); 1862 XmlUtils.skipCurrentTag(parser); 1863 continue; 1864 } 1865 String uidStr = parser.getAttributeValue(null, "uid"); 1866 if (uidStr == null) { 1867 Slog.w(TAG, "<assign-permission> without uid at " 1868 + parser.getPositionDescription()); 1869 XmlUtils.skipCurrentTag(parser); 1870 continue; 1871 } 1872 int uid = Process.getUidForName(uidStr); 1873 if (uid < 0) { 1874 Slog.w(TAG, "<assign-permission> with unknown uid \"" 1875 + uidStr + "\" at " 1876 + parser.getPositionDescription()); 1877 XmlUtils.skipCurrentTag(parser); 1878 continue; 1879 } 1880 perm = perm.intern(); 1881 HashSet<String> perms = mSystemPermissions.get(uid); 1882 if (perms == null) { 1883 perms = new HashSet<String>(); 1884 mSystemPermissions.put(uid, perms); 1885 } 1886 perms.add(perm); 1887 XmlUtils.skipCurrentTag(parser); 1888 1889 } else if ("library".equals(name)) { 1890 String lname = parser.getAttributeValue(null, "name"); 1891 String lfile = parser.getAttributeValue(null, "file"); 1892 if (lname == null) { 1893 Slog.w(TAG, "<library> without name at " 1894 + parser.getPositionDescription()); 1895 } else if (lfile == null) { 1896 Slog.w(TAG, "<library> without file at " 1897 + parser.getPositionDescription()); 1898 } else { 1899 //Log.i(TAG, "Got library " + lname + " in " + lfile); 1900 mSharedLibraries.put(lname, new SharedLibraryEntry(lfile, null)); 1901 } 1902 XmlUtils.skipCurrentTag(parser); 1903 continue; 1904 1905 } else if ("feature".equals(name)) { 1906 String fname = parser.getAttributeValue(null, "name"); 1907 if (fname == null) { 1908 Slog.w(TAG, "<feature> without name at " 1909 + parser.getPositionDescription()); 1910 } else { 1911 //Log.i(TAG, "Got feature " + fname); 1912 FeatureInfo fi = new FeatureInfo(); 1913 fi.name = fname; 1914 mAvailableFeatures.put(fname, fi); 1915 } 1916 XmlUtils.skipCurrentTag(parser); 1917 continue; 1918 1919 } else { 1920 XmlUtils.skipCurrentTag(parser); 1921 continue; 1922 } 1923 1924 } 1925 permReader.close(); 1926 } catch (XmlPullParserException e) { 1927 Slog.w(TAG, "Got execption parsing permissions.", e); 1928 } catch (IOException e) { 1929 Slog.w(TAG, "Got execption parsing permissions.", e); 1930 } 1931 } 1932 1933 void readPermission(XmlPullParser parser, String name) 1934 throws IOException, XmlPullParserException { 1935 1936 name = name.intern(); 1937 1938 BasePermission bp = mSettings.mPermissions.get(name); 1939 if (bp == null) { 1940 bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN); 1941 mSettings.mPermissions.put(name, bp); 1942 } 1943 int outerDepth = parser.getDepth(); 1944 int type; 1945 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1946 && (type != XmlPullParser.END_TAG 1947 || parser.getDepth() > outerDepth)) { 1948 if (type == XmlPullParser.END_TAG 1949 || type == XmlPullParser.TEXT) { 1950 continue; 1951 } 1952 1953 String tagName = parser.getName(); 1954 if ("group".equals(tagName)) { 1955 String gidStr = parser.getAttributeValue(null, "gid"); 1956 if (gidStr != null) { 1957 int gid = Process.getGidForName(gidStr); 1958 bp.gids = appendInt(bp.gids, gid); 1959 } else { 1960 Slog.w(TAG, "<group> without gid at " 1961 + parser.getPositionDescription()); 1962 } 1963 } 1964 XmlUtils.skipCurrentTag(parser); 1965 } 1966 } 1967 1968 static int[] appendInts(int[] cur, int[] add) { 1969 if (add == null) return cur; 1970 if (cur == null) return add; 1971 final int N = add.length; 1972 for (int i=0; i<N; i++) { 1973 cur = appendInt(cur, add[i]); 1974 } 1975 return cur; 1976 } 1977 1978 static int[] removeInts(int[] cur, int[] rem) { 1979 if (rem == null) return cur; 1980 if (cur == null) return cur; 1981 final int N = rem.length; 1982 for (int i=0; i<N; i++) { 1983 cur = removeInt(cur, rem[i]); 1984 } 1985 return cur; 1986 } 1987 1988 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 1989 if (!sUserManager.exists(userId)) return null; 1990 final PackageSetting ps = (PackageSetting) p.mExtras; 1991 if (ps == null) { 1992 return null; 1993 } 1994 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1995 final PackageUserState state = ps.readUserState(userId); 1996 return PackageParser.generatePackageInfo(p, gp.gids, flags, 1997 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions, 1998 state, userId); 1999 } 2000 2001 @Override 2002 public boolean isPackageAvailable(String packageName, int userId) { 2003 if (!sUserManager.exists(userId)) return false; 2004 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available"); 2005 synchronized (mPackages) { 2006 PackageParser.Package p = mPackages.get(packageName); 2007 if (p != null) { 2008 final PackageSetting ps = (PackageSetting) p.mExtras; 2009 if (ps != null) { 2010 final PackageUserState state = ps.readUserState(userId); 2011 if (state != null) { 2012 return PackageParser.isAvailable(state); 2013 } 2014 } 2015 } 2016 } 2017 return false; 2018 } 2019 2020 @Override 2021 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2022 if (!sUserManager.exists(userId)) return null; 2023 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info"); 2024 // reader 2025 synchronized (mPackages) { 2026 PackageParser.Package p = mPackages.get(packageName); 2027 if (DEBUG_PACKAGE_INFO) 2028 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2029 if (p != null) { 2030 return generatePackageInfo(p, flags, userId); 2031 } 2032 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2033 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2034 } 2035 } 2036 return null; 2037 } 2038 2039 @Override 2040 public String[] currentToCanonicalPackageNames(String[] names) { 2041 String[] out = new String[names.length]; 2042 // reader 2043 synchronized (mPackages) { 2044 for (int i=names.length-1; i>=0; i--) { 2045 PackageSetting ps = mSettings.mPackages.get(names[i]); 2046 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2047 } 2048 } 2049 return out; 2050 } 2051 2052 @Override 2053 public String[] canonicalToCurrentPackageNames(String[] names) { 2054 String[] out = new String[names.length]; 2055 // reader 2056 synchronized (mPackages) { 2057 for (int i=names.length-1; i>=0; i--) { 2058 String cur = mSettings.mRenamedPackages.get(names[i]); 2059 out[i] = cur != null ? cur : names[i]; 2060 } 2061 } 2062 return out; 2063 } 2064 2065 @Override 2066 public int getPackageUid(String packageName, int userId) { 2067 if (!sUserManager.exists(userId)) return -1; 2068 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid"); 2069 // reader 2070 synchronized (mPackages) { 2071 PackageParser.Package p = mPackages.get(packageName); 2072 if(p != null) { 2073 return UserHandle.getUid(userId, p.applicationInfo.uid); 2074 } 2075 PackageSetting ps = mSettings.mPackages.get(packageName); 2076 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 2077 return -1; 2078 } 2079 p = ps.pkg; 2080 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 2081 } 2082 } 2083 2084 @Override 2085 public int[] getPackageGids(String packageName) { 2086 // reader 2087 synchronized (mPackages) { 2088 PackageParser.Package p = mPackages.get(packageName); 2089 if (DEBUG_PACKAGE_INFO) 2090 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 2091 if (p != null) { 2092 final PackageSetting ps = (PackageSetting)p.mExtras; 2093 return ps.getGids(); 2094 } 2095 } 2096 // stupid thing to indicate an error. 2097 return new int[0]; 2098 } 2099 2100 static final PermissionInfo generatePermissionInfo( 2101 BasePermission bp, int flags) { 2102 if (bp.perm != null) { 2103 return PackageParser.generatePermissionInfo(bp.perm, flags); 2104 } 2105 PermissionInfo pi = new PermissionInfo(); 2106 pi.name = bp.name; 2107 pi.packageName = bp.sourcePackage; 2108 pi.nonLocalizedLabel = bp.name; 2109 pi.protectionLevel = bp.protectionLevel; 2110 return pi; 2111 } 2112 2113 @Override 2114 public PermissionInfo getPermissionInfo(String name, int flags) { 2115 // reader 2116 synchronized (mPackages) { 2117 final BasePermission p = mSettings.mPermissions.get(name); 2118 if (p != null) { 2119 return generatePermissionInfo(p, flags); 2120 } 2121 return null; 2122 } 2123 } 2124 2125 @Override 2126 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 2127 // reader 2128 synchronized (mPackages) { 2129 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 2130 for (BasePermission p : mSettings.mPermissions.values()) { 2131 if (group == null) { 2132 if (p.perm == null || p.perm.info.group == null) { 2133 out.add(generatePermissionInfo(p, flags)); 2134 } 2135 } else { 2136 if (p.perm != null && group.equals(p.perm.info.group)) { 2137 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 2138 } 2139 } 2140 } 2141 2142 if (out.size() > 0) { 2143 return out; 2144 } 2145 return mPermissionGroups.containsKey(group) ? out : null; 2146 } 2147 } 2148 2149 @Override 2150 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 2151 // reader 2152 synchronized (mPackages) { 2153 return PackageParser.generatePermissionGroupInfo( 2154 mPermissionGroups.get(name), flags); 2155 } 2156 } 2157 2158 @Override 2159 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2160 // reader 2161 synchronized (mPackages) { 2162 final int N = mPermissionGroups.size(); 2163 ArrayList<PermissionGroupInfo> out 2164 = new ArrayList<PermissionGroupInfo>(N); 2165 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2166 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2167 } 2168 return out; 2169 } 2170 } 2171 2172 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2173 int userId) { 2174 if (!sUserManager.exists(userId)) return null; 2175 PackageSetting ps = mSettings.mPackages.get(packageName); 2176 if (ps != null) { 2177 if (ps.pkg == null) { 2178 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2179 flags, userId); 2180 if (pInfo != null) { 2181 return pInfo.applicationInfo; 2182 } 2183 return null; 2184 } 2185 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2186 ps.readUserState(userId), userId); 2187 } 2188 return null; 2189 } 2190 2191 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2192 int userId) { 2193 if (!sUserManager.exists(userId)) return null; 2194 PackageSetting ps = mSettings.mPackages.get(packageName); 2195 if (ps != null) { 2196 PackageParser.Package pkg = ps.pkg; 2197 if (pkg == null) { 2198 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2199 return null; 2200 } 2201 pkg = new PackageParser.Package(packageName); 2202 pkg.applicationInfo.packageName = packageName; 2203 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2204 pkg.applicationInfo.publicSourceDir = ps.resourcePathString; 2205 pkg.applicationInfo.sourceDir = ps.codePathString; 2206 pkg.applicationInfo.dataDir = 2207 getDataPathForPackage(packageName, 0).getPath(); 2208 pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString; 2209 pkg.applicationInfo.requiredCpuAbi = ps.requiredCpuAbiString; 2210 } 2211 return generatePackageInfo(pkg, flags, userId); 2212 } 2213 return null; 2214 } 2215 2216 @Override 2217 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2218 if (!sUserManager.exists(userId)) return null; 2219 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info"); 2220 // writer 2221 synchronized (mPackages) { 2222 PackageParser.Package p = mPackages.get(packageName); 2223 if (DEBUG_PACKAGE_INFO) Log.v( 2224 TAG, "getApplicationInfo " + packageName 2225 + ": " + p); 2226 if (p != null) { 2227 PackageSetting ps = mSettings.mPackages.get(packageName); 2228 if (ps == null) return null; 2229 // Note: isEnabledLP() does not apply here - always return info 2230 return PackageParser.generateApplicationInfo( 2231 p, flags, ps.readUserState(userId), userId); 2232 } 2233 if ("android".equals(packageName)||"system".equals(packageName)) { 2234 return mAndroidApplication; 2235 } 2236 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2237 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2238 } 2239 } 2240 return null; 2241 } 2242 2243 2244 @Override 2245 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) { 2246 mContext.enforceCallingOrSelfPermission( 2247 android.Manifest.permission.CLEAR_APP_CACHE, null); 2248 // Queue up an async operation since clearing cache may take a little while. 2249 mHandler.post(new Runnable() { 2250 public void run() { 2251 mHandler.removeCallbacks(this); 2252 int retCode = -1; 2253 synchronized (mInstallLock) { 2254 retCode = mInstaller.freeCache(freeStorageSize); 2255 if (retCode < 0) { 2256 Slog.w(TAG, "Couldn't clear application caches"); 2257 } 2258 } 2259 if (observer != null) { 2260 try { 2261 observer.onRemoveCompleted(null, (retCode >= 0)); 2262 } catch (RemoteException e) { 2263 Slog.w(TAG, "RemoveException when invoking call back"); 2264 } 2265 } 2266 } 2267 }); 2268 } 2269 2270 @Override 2271 public void freeStorage(final long freeStorageSize, final IntentSender pi) { 2272 mContext.enforceCallingOrSelfPermission( 2273 android.Manifest.permission.CLEAR_APP_CACHE, null); 2274 // Queue up an async operation since clearing cache may take a little while. 2275 mHandler.post(new Runnable() { 2276 public void run() { 2277 mHandler.removeCallbacks(this); 2278 int retCode = -1; 2279 synchronized (mInstallLock) { 2280 retCode = mInstaller.freeCache(freeStorageSize); 2281 if (retCode < 0) { 2282 Slog.w(TAG, "Couldn't clear application caches"); 2283 } 2284 } 2285 if(pi != null) { 2286 try { 2287 // Callback via pending intent 2288 int code = (retCode >= 0) ? 1 : 0; 2289 pi.sendIntent(null, code, null, 2290 null, null); 2291 } catch (SendIntentException e1) { 2292 Slog.i(TAG, "Failed to send pending intent"); 2293 } 2294 } 2295 } 2296 }); 2297 } 2298 2299 @Override 2300 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2301 if (!sUserManager.exists(userId)) return null; 2302 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info"); 2303 synchronized (mPackages) { 2304 PackageParser.Activity a = mActivities.mActivities.get(component); 2305 2306 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2307 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2308 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2309 if (ps == null) return null; 2310 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2311 userId); 2312 } 2313 if (mResolveComponentName.equals(component)) { 2314 return mResolveActivity; 2315 } 2316 } 2317 return null; 2318 } 2319 2320 @Override 2321 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 2322 if (!sUserManager.exists(userId)) return null; 2323 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info"); 2324 synchronized (mPackages) { 2325 PackageParser.Activity a = mReceivers.mActivities.get(component); 2326 if (DEBUG_PACKAGE_INFO) Log.v( 2327 TAG, "getReceiverInfo " + component + ": " + a); 2328 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2329 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2330 if (ps == null) return null; 2331 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2332 userId); 2333 } 2334 } 2335 return null; 2336 } 2337 2338 @Override 2339 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 2340 if (!sUserManager.exists(userId)) return null; 2341 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info"); 2342 synchronized (mPackages) { 2343 PackageParser.Service s = mServices.mServices.get(component); 2344 if (DEBUG_PACKAGE_INFO) Log.v( 2345 TAG, "getServiceInfo " + component + ": " + s); 2346 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 2347 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2348 if (ps == null) return null; 2349 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 2350 userId); 2351 } 2352 } 2353 return null; 2354 } 2355 2356 @Override 2357 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 2358 if (!sUserManager.exists(userId)) return null; 2359 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info"); 2360 synchronized (mPackages) { 2361 PackageParser.Provider p = mProviders.mProviders.get(component); 2362 if (DEBUG_PACKAGE_INFO) Log.v( 2363 TAG, "getProviderInfo " + component + ": " + p); 2364 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 2365 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2366 if (ps == null) return null; 2367 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 2368 userId); 2369 } 2370 } 2371 return null; 2372 } 2373 2374 @Override 2375 public String[] getSystemSharedLibraryNames() { 2376 Set<String> libSet; 2377 synchronized (mPackages) { 2378 libSet = mSharedLibraries.keySet(); 2379 int size = libSet.size(); 2380 if (size > 0) { 2381 String[] libs = new String[size]; 2382 libSet.toArray(libs); 2383 return libs; 2384 } 2385 } 2386 return null; 2387 } 2388 2389 @Override 2390 public FeatureInfo[] getSystemAvailableFeatures() { 2391 Collection<FeatureInfo> featSet; 2392 synchronized (mPackages) { 2393 featSet = mAvailableFeatures.values(); 2394 int size = featSet.size(); 2395 if (size > 0) { 2396 FeatureInfo[] features = new FeatureInfo[size+1]; 2397 featSet.toArray(features); 2398 FeatureInfo fi = new FeatureInfo(); 2399 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 2400 FeatureInfo.GL_ES_VERSION_UNDEFINED); 2401 features[size] = fi; 2402 return features; 2403 } 2404 } 2405 return null; 2406 } 2407 2408 @Override 2409 public boolean hasSystemFeature(String name) { 2410 synchronized (mPackages) { 2411 return mAvailableFeatures.containsKey(name); 2412 } 2413 } 2414 2415 private void checkValidCaller(int uid, int userId) { 2416 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 2417 return; 2418 2419 throw new SecurityException("Caller uid=" + uid 2420 + " is not privileged to communicate with user=" + userId); 2421 } 2422 2423 @Override 2424 public int checkPermission(String permName, String pkgName) { 2425 synchronized (mPackages) { 2426 PackageParser.Package p = mPackages.get(pkgName); 2427 if (p != null && p.mExtras != null) { 2428 PackageSetting ps = (PackageSetting)p.mExtras; 2429 if (ps.sharedUser != null) { 2430 if (ps.sharedUser.grantedPermissions.contains(permName)) { 2431 return PackageManager.PERMISSION_GRANTED; 2432 } 2433 } else if (ps.grantedPermissions.contains(permName)) { 2434 return PackageManager.PERMISSION_GRANTED; 2435 } 2436 } 2437 } 2438 return PackageManager.PERMISSION_DENIED; 2439 } 2440 2441 @Override 2442 public int checkUidPermission(String permName, int uid) { 2443 synchronized (mPackages) { 2444 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2445 if (obj != null) { 2446 GrantedPermissions gp = (GrantedPermissions)obj; 2447 if (gp.grantedPermissions.contains(permName)) { 2448 return PackageManager.PERMISSION_GRANTED; 2449 } 2450 } else { 2451 HashSet<String> perms = mSystemPermissions.get(uid); 2452 if (perms != null && perms.contains(permName)) { 2453 return PackageManager.PERMISSION_GRANTED; 2454 } 2455 } 2456 } 2457 return PackageManager.PERMISSION_DENIED; 2458 } 2459 2460 /** 2461 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 2462 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 2463 * @param message the message to log on security exception 2464 * @return 2465 */ 2466 private void enforceCrossUserPermission(int callingUid, int userId, 2467 boolean requireFullPermission, String message) { 2468 if (userId < 0) { 2469 throw new IllegalArgumentException("Invalid userId " + userId); 2470 } 2471 if (userId == UserHandle.getUserId(callingUid)) return; 2472 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2473 if (requireFullPermission) { 2474 mContext.enforceCallingOrSelfPermission( 2475 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2476 } else { 2477 try { 2478 mContext.enforceCallingOrSelfPermission( 2479 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2480 } catch (SecurityException se) { 2481 mContext.enforceCallingOrSelfPermission( 2482 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 2483 } 2484 } 2485 } 2486 } 2487 2488 private BasePermission findPermissionTreeLP(String permName) { 2489 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 2490 if (permName.startsWith(bp.name) && 2491 permName.length() > bp.name.length() && 2492 permName.charAt(bp.name.length()) == '.') { 2493 return bp; 2494 } 2495 } 2496 return null; 2497 } 2498 2499 private BasePermission checkPermissionTreeLP(String permName) { 2500 if (permName != null) { 2501 BasePermission bp = findPermissionTreeLP(permName); 2502 if (bp != null) { 2503 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 2504 return bp; 2505 } 2506 throw new SecurityException("Calling uid " 2507 + Binder.getCallingUid() 2508 + " is not allowed to add to permission tree " 2509 + bp.name + " owned by uid " + bp.uid); 2510 } 2511 } 2512 throw new SecurityException("No permission tree found for " + permName); 2513 } 2514 2515 static boolean compareStrings(CharSequence s1, CharSequence s2) { 2516 if (s1 == null) { 2517 return s2 == null; 2518 } 2519 if (s2 == null) { 2520 return false; 2521 } 2522 if (s1.getClass() != s2.getClass()) { 2523 return false; 2524 } 2525 return s1.equals(s2); 2526 } 2527 2528 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 2529 if (pi1.icon != pi2.icon) return false; 2530 if (pi1.logo != pi2.logo) return false; 2531 if (pi1.protectionLevel != pi2.protectionLevel) return false; 2532 if (!compareStrings(pi1.name, pi2.name)) return false; 2533 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 2534 // We'll take care of setting this one. 2535 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 2536 // These are not currently stored in settings. 2537 //if (!compareStrings(pi1.group, pi2.group)) return false; 2538 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 2539 //if (pi1.labelRes != pi2.labelRes) return false; 2540 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 2541 return true; 2542 } 2543 2544 boolean addPermissionLocked(PermissionInfo info, boolean async) { 2545 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 2546 throw new SecurityException("Label must be specified in permission"); 2547 } 2548 BasePermission tree = checkPermissionTreeLP(info.name); 2549 BasePermission bp = mSettings.mPermissions.get(info.name); 2550 boolean added = bp == null; 2551 boolean changed = true; 2552 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 2553 if (added) { 2554 bp = new BasePermission(info.name, tree.sourcePackage, 2555 BasePermission.TYPE_DYNAMIC); 2556 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 2557 throw new SecurityException( 2558 "Not allowed to modify non-dynamic permission " 2559 + info.name); 2560 } else { 2561 if (bp.protectionLevel == fixedLevel 2562 && bp.perm.owner.equals(tree.perm.owner) 2563 && bp.uid == tree.uid 2564 && comparePermissionInfos(bp.perm.info, info)) { 2565 changed = false; 2566 } 2567 } 2568 bp.protectionLevel = fixedLevel; 2569 info = new PermissionInfo(info); 2570 info.protectionLevel = fixedLevel; 2571 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 2572 bp.perm.info.packageName = tree.perm.info.packageName; 2573 bp.uid = tree.uid; 2574 if (added) { 2575 mSettings.mPermissions.put(info.name, bp); 2576 } 2577 if (changed) { 2578 if (!async) { 2579 mSettings.writeLPr(); 2580 } else { 2581 scheduleWriteSettingsLocked(); 2582 } 2583 } 2584 return added; 2585 } 2586 2587 @Override 2588 public boolean addPermission(PermissionInfo info) { 2589 synchronized (mPackages) { 2590 return addPermissionLocked(info, false); 2591 } 2592 } 2593 2594 @Override 2595 public boolean addPermissionAsync(PermissionInfo info) { 2596 synchronized (mPackages) { 2597 return addPermissionLocked(info, true); 2598 } 2599 } 2600 2601 @Override 2602 public void removePermission(String name) { 2603 synchronized (mPackages) { 2604 checkPermissionTreeLP(name); 2605 BasePermission bp = mSettings.mPermissions.get(name); 2606 if (bp != null) { 2607 if (bp.type != BasePermission.TYPE_DYNAMIC) { 2608 throw new SecurityException( 2609 "Not allowed to modify non-dynamic permission " 2610 + name); 2611 } 2612 mSettings.mPermissions.remove(name); 2613 mSettings.writeLPr(); 2614 } 2615 } 2616 } 2617 2618 private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) { 2619 int index = pkg.requestedPermissions.indexOf(bp.name); 2620 if (index == -1) { 2621 throw new SecurityException("Package " + pkg.packageName 2622 + " has not requested permission " + bp.name); 2623 } 2624 boolean isNormal = 2625 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) 2626 == PermissionInfo.PROTECTION_NORMAL); 2627 boolean isDangerous = 2628 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) 2629 == PermissionInfo.PROTECTION_DANGEROUS); 2630 boolean isDevelopment = 2631 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0); 2632 2633 if (!isNormal && !isDangerous && !isDevelopment) { 2634 throw new SecurityException("Permission " + bp.name 2635 + " is not a changeable permission type"); 2636 } 2637 2638 if (isNormal || isDangerous) { 2639 if (pkg.requestedPermissionsRequired.get(index)) { 2640 throw new SecurityException("Can't change " + bp.name 2641 + ". It is required by the application"); 2642 } 2643 } 2644 } 2645 2646 @Override 2647 public void grantPermission(String packageName, String permissionName) { 2648 mContext.enforceCallingOrSelfPermission( 2649 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); 2650 synchronized (mPackages) { 2651 final PackageParser.Package pkg = mPackages.get(packageName); 2652 if (pkg == null) { 2653 throw new IllegalArgumentException("Unknown package: " + packageName); 2654 } 2655 final BasePermission bp = mSettings.mPermissions.get(permissionName); 2656 if (bp == null) { 2657 throw new IllegalArgumentException("Unknown permission: " + permissionName); 2658 } 2659 2660 checkGrantRevokePermissions(pkg, bp); 2661 2662 final PackageSetting ps = (PackageSetting) pkg.mExtras; 2663 if (ps == null) { 2664 return; 2665 } 2666 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps; 2667 if (gp.grantedPermissions.add(permissionName)) { 2668 if (ps.haveGids) { 2669 gp.gids = appendInts(gp.gids, bp.gids); 2670 } 2671 mSettings.writeLPr(); 2672 } 2673 } 2674 } 2675 2676 @Override 2677 public void revokePermission(String packageName, String permissionName) { 2678 int changedAppId = -1; 2679 2680 synchronized (mPackages) { 2681 final PackageParser.Package pkg = mPackages.get(packageName); 2682 if (pkg == null) { 2683 throw new IllegalArgumentException("Unknown package: " + packageName); 2684 } 2685 if (pkg.applicationInfo.uid != Binder.getCallingUid()) { 2686 mContext.enforceCallingOrSelfPermission( 2687 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); 2688 } 2689 final BasePermission bp = mSettings.mPermissions.get(permissionName); 2690 if (bp == null) { 2691 throw new IllegalArgumentException("Unknown permission: " + permissionName); 2692 } 2693 2694 checkGrantRevokePermissions(pkg, bp); 2695 2696 final PackageSetting ps = (PackageSetting) pkg.mExtras; 2697 if (ps == null) { 2698 return; 2699 } 2700 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps; 2701 if (gp.grantedPermissions.remove(permissionName)) { 2702 gp.grantedPermissions.remove(permissionName); 2703 if (ps.haveGids) { 2704 gp.gids = removeInts(gp.gids, bp.gids); 2705 } 2706 mSettings.writeLPr(); 2707 changedAppId = ps.appId; 2708 } 2709 } 2710 2711 if (changedAppId >= 0) { 2712 // We changed the perm on someone, kill its processes. 2713 IActivityManager am = ActivityManagerNative.getDefault(); 2714 if (am != null) { 2715 final int callingUserId = UserHandle.getCallingUserId(); 2716 final long ident = Binder.clearCallingIdentity(); 2717 try { 2718 //XXX we should only revoke for the calling user's app permissions, 2719 // but for now we impact all users. 2720 //am.killUid(UserHandle.getUid(callingUserId, changedAppId), 2721 // "revoke " + permissionName); 2722 int[] users = sUserManager.getUserIds(); 2723 for (int user : users) { 2724 am.killUid(UserHandle.getUid(user, changedAppId), 2725 "revoke " + permissionName); 2726 } 2727 } catch (RemoteException e) { 2728 } finally { 2729 Binder.restoreCallingIdentity(ident); 2730 } 2731 } 2732 } 2733 } 2734 2735 @Override 2736 public boolean isProtectedBroadcast(String actionName) { 2737 synchronized (mPackages) { 2738 return mProtectedBroadcasts.contains(actionName); 2739 } 2740 } 2741 2742 @Override 2743 public int checkSignatures(String pkg1, String pkg2) { 2744 synchronized (mPackages) { 2745 final PackageParser.Package p1 = mPackages.get(pkg1); 2746 final PackageParser.Package p2 = mPackages.get(pkg2); 2747 if (p1 == null || p1.mExtras == null 2748 || p2 == null || p2.mExtras == null) { 2749 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2750 } 2751 return compareSignatures(p1.mSignatures, p2.mSignatures); 2752 } 2753 } 2754 2755 @Override 2756 public int checkUidSignatures(int uid1, int uid2) { 2757 // Map to base uids. 2758 uid1 = UserHandle.getAppId(uid1); 2759 uid2 = UserHandle.getAppId(uid2); 2760 // reader 2761 synchronized (mPackages) { 2762 Signature[] s1; 2763 Signature[] s2; 2764 Object obj = mSettings.getUserIdLPr(uid1); 2765 if (obj != null) { 2766 if (obj instanceof SharedUserSetting) { 2767 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 2768 } else if (obj instanceof PackageSetting) { 2769 s1 = ((PackageSetting)obj).signatures.mSignatures; 2770 } else { 2771 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2772 } 2773 } else { 2774 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2775 } 2776 obj = mSettings.getUserIdLPr(uid2); 2777 if (obj != null) { 2778 if (obj instanceof SharedUserSetting) { 2779 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 2780 } else if (obj instanceof PackageSetting) { 2781 s2 = ((PackageSetting)obj).signatures.mSignatures; 2782 } else { 2783 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2784 } 2785 } else { 2786 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2787 } 2788 return compareSignatures(s1, s2); 2789 } 2790 } 2791 2792 /** 2793 * Compares two sets of signatures. Returns: 2794 * <br /> 2795 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 2796 * <br /> 2797 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 2798 * <br /> 2799 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 2800 * <br /> 2801 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 2802 * <br /> 2803 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 2804 */ 2805 static int compareSignatures(Signature[] s1, Signature[] s2) { 2806 if (s1 == null) { 2807 return s2 == null 2808 ? PackageManager.SIGNATURE_NEITHER_SIGNED 2809 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 2810 } 2811 2812 if (s2 == null) { 2813 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 2814 } 2815 2816 if (s1.length != s2.length) { 2817 return PackageManager.SIGNATURE_NO_MATCH; 2818 } 2819 2820 // Since both signature sets are of size 1, we can compare without HashSets. 2821 if (s1.length == 1) { 2822 return s1[0].equals(s2[0]) ? 2823 PackageManager.SIGNATURE_MATCH : 2824 PackageManager.SIGNATURE_NO_MATCH; 2825 } 2826 2827 HashSet<Signature> set1 = new HashSet<Signature>(); 2828 for (Signature sig : s1) { 2829 set1.add(sig); 2830 } 2831 HashSet<Signature> set2 = new HashSet<Signature>(); 2832 for (Signature sig : s2) { 2833 set2.add(sig); 2834 } 2835 // Make sure s2 contains all signatures in s1. 2836 if (set1.equals(set2)) { 2837 return PackageManager.SIGNATURE_MATCH; 2838 } 2839 return PackageManager.SIGNATURE_NO_MATCH; 2840 } 2841 2842 @Override 2843 public String[] getPackagesForUid(int uid) { 2844 uid = UserHandle.getAppId(uid); 2845 // reader 2846 synchronized (mPackages) { 2847 Object obj = mSettings.getUserIdLPr(uid); 2848 if (obj instanceof SharedUserSetting) { 2849 final SharedUserSetting sus = (SharedUserSetting) obj; 2850 final int N = sus.packages.size(); 2851 final String[] res = new String[N]; 2852 final Iterator<PackageSetting> it = sus.packages.iterator(); 2853 int i = 0; 2854 while (it.hasNext()) { 2855 res[i++] = it.next().name; 2856 } 2857 return res; 2858 } else if (obj instanceof PackageSetting) { 2859 final PackageSetting ps = (PackageSetting) obj; 2860 return new String[] { ps.name }; 2861 } 2862 } 2863 return null; 2864 } 2865 2866 @Override 2867 public String getNameForUid(int uid) { 2868 // reader 2869 synchronized (mPackages) { 2870 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2871 if (obj instanceof SharedUserSetting) { 2872 final SharedUserSetting sus = (SharedUserSetting) obj; 2873 return sus.name + ":" + sus.userId; 2874 } else if (obj instanceof PackageSetting) { 2875 final PackageSetting ps = (PackageSetting) obj; 2876 return ps.name; 2877 } 2878 } 2879 return null; 2880 } 2881 2882 @Override 2883 public int getUidForSharedUser(String sharedUserName) { 2884 if(sharedUserName == null) { 2885 return -1; 2886 } 2887 // reader 2888 synchronized (mPackages) { 2889 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false); 2890 if (suid == null) { 2891 return -1; 2892 } 2893 return suid.userId; 2894 } 2895 } 2896 2897 @Override 2898 public int getFlagsForUid(int uid) { 2899 synchronized (mPackages) { 2900 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2901 if (obj instanceof SharedUserSetting) { 2902 final SharedUserSetting sus = (SharedUserSetting) obj; 2903 return sus.pkgFlags; 2904 } else if (obj instanceof PackageSetting) { 2905 final PackageSetting ps = (PackageSetting) obj; 2906 return ps.pkgFlags; 2907 } 2908 } 2909 return 0; 2910 } 2911 2912 @Override 2913 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 2914 int flags, int userId) { 2915 if (!sUserManager.exists(userId)) return null; 2916 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent"); 2917 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2918 return chooseBestActivity(intent, resolvedType, flags, query, userId); 2919 } 2920 2921 @Override 2922 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 2923 IntentFilter filter, int match, ComponentName activity) { 2924 final int userId = UserHandle.getCallingUserId(); 2925 if (DEBUG_PREFERRED) { 2926 Log.v(TAG, "setLastChosenActivity intent=" + intent 2927 + " resolvedType=" + resolvedType 2928 + " flags=" + flags 2929 + " filter=" + filter 2930 + " match=" + match 2931 + " activity=" + activity); 2932 filter.dump(new PrintStreamPrinter(System.out), " "); 2933 } 2934 intent.setComponent(null); 2935 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2936 // Find any earlier preferred or last chosen entries and nuke them 2937 findPreferredActivity(intent, resolvedType, 2938 flags, query, 0, false, true, false, userId); 2939 // Add the new activity as the last chosen for this filter 2940 addPreferredActivityInternal(filter, match, null, activity, false, userId); 2941 } 2942 2943 @Override 2944 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 2945 final int userId = UserHandle.getCallingUserId(); 2946 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 2947 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2948 return findPreferredActivity(intent, resolvedType, flags, query, 0, 2949 false, false, false, userId); 2950 } 2951 2952 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 2953 int flags, List<ResolveInfo> query, int userId) { 2954 if (query != null) { 2955 final int N = query.size(); 2956 if (N == 1) { 2957 return query.get(0); 2958 } else if (N > 1) { 2959 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 2960 // If there is more than one activity with the same priority, 2961 // then let the user decide between them. 2962 ResolveInfo r0 = query.get(0); 2963 ResolveInfo r1 = query.get(1); 2964 if (DEBUG_INTENT_MATCHING || debug) { 2965 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 2966 + r1.activityInfo.name + "=" + r1.priority); 2967 } 2968 // If the first activity has a higher priority, or a different 2969 // default, then it is always desireable to pick it. 2970 if (r0.priority != r1.priority 2971 || r0.preferredOrder != r1.preferredOrder 2972 || r0.isDefault != r1.isDefault) { 2973 return query.get(0); 2974 } 2975 // If we have saved a preference for a preferred activity for 2976 // this Intent, use that. 2977 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 2978 flags, query, r0.priority, true, false, debug, userId); 2979 if (ri != null) { 2980 return ri; 2981 } 2982 if (userId != 0) { 2983 ri = new ResolveInfo(mResolveInfo); 2984 ri.activityInfo = new ActivityInfo(ri.activityInfo); 2985 ri.activityInfo.applicationInfo = new ApplicationInfo( 2986 ri.activityInfo.applicationInfo); 2987 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 2988 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 2989 return ri; 2990 } 2991 return mResolveInfo; 2992 } 2993 } 2994 return null; 2995 } 2996 2997 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 2998 List<ResolveInfo> query, int priority, boolean always, 2999 boolean removeMatches, boolean debug, int userId) { 3000 if (!sUserManager.exists(userId)) return null; 3001 // writer 3002 synchronized (mPackages) { 3003 if (intent.getSelector() != null) { 3004 intent = intent.getSelector(); 3005 } 3006 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 3007 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 3008 // Get the list of preferred activities that handle the intent 3009 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 3010 List<PreferredActivity> prefs = pir != null 3011 ? pir.queryIntent(intent, resolvedType, 3012 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 3013 : null; 3014 if (prefs != null && prefs.size() > 0) { 3015 // First figure out how good the original match set is. 3016 // We will only allow preferred activities that came 3017 // from the same match quality. 3018 int match = 0; 3019 3020 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 3021 3022 final int N = query.size(); 3023 for (int j=0; j<N; j++) { 3024 final ResolveInfo ri = query.get(j); 3025 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 3026 + ": 0x" + Integer.toHexString(match)); 3027 if (ri.match > match) { 3028 match = ri.match; 3029 } 3030 } 3031 3032 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 3033 + Integer.toHexString(match)); 3034 3035 match &= IntentFilter.MATCH_CATEGORY_MASK; 3036 final int M = prefs.size(); 3037 for (int i=0; i<M; i++) { 3038 final PreferredActivity pa = prefs.get(i); 3039 if (DEBUG_PREFERRED || debug) { 3040 Slog.v(TAG, "Checking PreferredActivity ds=" 3041 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 3042 + "\n component=" + pa.mPref.mComponent); 3043 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3044 } 3045 if (pa.mPref.mMatch != match) { 3046 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 3047 + Integer.toHexString(pa.mPref.mMatch)); 3048 continue; 3049 } 3050 // If it's not an "always" type preferred activity and that's what we're 3051 // looking for, skip it. 3052 if (always && !pa.mPref.mAlways) { 3053 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 3054 continue; 3055 } 3056 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 3057 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 3058 if (DEBUG_PREFERRED || debug) { 3059 Slog.v(TAG, "Found preferred activity:"); 3060 if (ai != null) { 3061 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 3062 } else { 3063 Slog.v(TAG, " null"); 3064 } 3065 } 3066 if (ai == null) { 3067 // This previously registered preferred activity 3068 // component is no longer known. Most likely an update 3069 // to the app was installed and in the new version this 3070 // component no longer exists. Clean it up by removing 3071 // it from the preferred activities list, and skip it. 3072 Slog.w(TAG, "Removing dangling preferred activity: " 3073 + pa.mPref.mComponent); 3074 pir.removeFilter(pa); 3075 continue; 3076 } 3077 for (int j=0; j<N; j++) { 3078 final ResolveInfo ri = query.get(j); 3079 if (!ri.activityInfo.applicationInfo.packageName 3080 .equals(ai.applicationInfo.packageName)) { 3081 continue; 3082 } 3083 if (!ri.activityInfo.name.equals(ai.name)) { 3084 continue; 3085 } 3086 3087 if (removeMatches) { 3088 pir.removeFilter(pa); 3089 if (DEBUG_PREFERRED) { 3090 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 3091 } 3092 break; 3093 } 3094 3095 // Okay we found a previously set preferred or last chosen app. 3096 // If the result set is different from when this 3097 // was created, we need to clear it and re-ask the 3098 // user their preference, if we're looking for an "always" type entry. 3099 if (always && !pa.mPref.sameSet(query, priority)) { 3100 Slog.i(TAG, "Result set changed, dropping preferred activity for " 3101 + intent + " type " + resolvedType); 3102 if (DEBUG_PREFERRED) { 3103 Slog.v(TAG, "Removing preferred activity since set changed " 3104 + pa.mPref.mComponent); 3105 } 3106 pir.removeFilter(pa); 3107 // Re-add the filter as a "last chosen" entry (!always) 3108 PreferredActivity lastChosen = new PreferredActivity( 3109 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 3110 pir.addFilter(lastChosen); 3111 mSettings.writePackageRestrictionsLPr(userId); 3112 return null; 3113 } 3114 3115 // Yay! Either the set matched or we're looking for the last chosen 3116 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 3117 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3118 mSettings.writePackageRestrictionsLPr(userId); 3119 return ri; 3120 } 3121 } 3122 } 3123 mSettings.writePackageRestrictionsLPr(userId); 3124 } 3125 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 3126 return null; 3127 } 3128 3129 @Override 3130 public List<ResolveInfo> queryIntentActivities(Intent intent, 3131 String resolvedType, int flags, int userId) { 3132 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3133 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities"); 3134 ComponentName comp = intent.getComponent(); 3135 if (comp == null) { 3136 if (intent.getSelector() != null) { 3137 intent = intent.getSelector(); 3138 comp = intent.getComponent(); 3139 } 3140 } 3141 3142 if (comp != null) { 3143 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3144 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 3145 if (ai != null) { 3146 final ResolveInfo ri = new ResolveInfo(); 3147 ri.activityInfo = ai; 3148 list.add(ri); 3149 } 3150 return list; 3151 } 3152 3153 // reader 3154 synchronized (mPackages) { 3155 final String pkgName = intent.getPackage(); 3156 if (pkgName == null) { 3157 return mActivities.queryIntent(intent, resolvedType, flags, userId); 3158 } 3159 final PackageParser.Package pkg = mPackages.get(pkgName); 3160 if (pkg != null) { 3161 return mActivities.queryIntentForPackage(intent, resolvedType, flags, 3162 pkg.activities, userId); 3163 } 3164 return new ArrayList<ResolveInfo>(); 3165 } 3166 } 3167 3168 @Override 3169 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 3170 Intent[] specifics, String[] specificTypes, Intent intent, 3171 String resolvedType, int flags, int userId) { 3172 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3173 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 3174 "query intent activity options"); 3175 final String resultsAction = intent.getAction(); 3176 3177 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 3178 | PackageManager.GET_RESOLVED_FILTER, userId); 3179 3180 if (DEBUG_INTENT_MATCHING) { 3181 Log.v(TAG, "Query " + intent + ": " + results); 3182 } 3183 3184 int specificsPos = 0; 3185 int N; 3186 3187 // todo: note that the algorithm used here is O(N^2). This 3188 // isn't a problem in our current environment, but if we start running 3189 // into situations where we have more than 5 or 10 matches then this 3190 // should probably be changed to something smarter... 3191 3192 // First we go through and resolve each of the specific items 3193 // that were supplied, taking care of removing any corresponding 3194 // duplicate items in the generic resolve list. 3195 if (specifics != null) { 3196 for (int i=0; i<specifics.length; i++) { 3197 final Intent sintent = specifics[i]; 3198 if (sintent == null) { 3199 continue; 3200 } 3201 3202 if (DEBUG_INTENT_MATCHING) { 3203 Log.v(TAG, "Specific #" + i + ": " + sintent); 3204 } 3205 3206 String action = sintent.getAction(); 3207 if (resultsAction != null && resultsAction.equals(action)) { 3208 // If this action was explicitly requested, then don't 3209 // remove things that have it. 3210 action = null; 3211 } 3212 3213 ResolveInfo ri = null; 3214 ActivityInfo ai = null; 3215 3216 ComponentName comp = sintent.getComponent(); 3217 if (comp == null) { 3218 ri = resolveIntent( 3219 sintent, 3220 specificTypes != null ? specificTypes[i] : null, 3221 flags, userId); 3222 if (ri == null) { 3223 continue; 3224 } 3225 if (ri == mResolveInfo) { 3226 // ACK! Must do something better with this. 3227 } 3228 ai = ri.activityInfo; 3229 comp = new ComponentName(ai.applicationInfo.packageName, 3230 ai.name); 3231 } else { 3232 ai = getActivityInfo(comp, flags, userId); 3233 if (ai == null) { 3234 continue; 3235 } 3236 } 3237 3238 // Look for any generic query activities that are duplicates 3239 // of this specific one, and remove them from the results. 3240 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 3241 N = results.size(); 3242 int j; 3243 for (j=specificsPos; j<N; j++) { 3244 ResolveInfo sri = results.get(j); 3245 if ((sri.activityInfo.name.equals(comp.getClassName()) 3246 && sri.activityInfo.applicationInfo.packageName.equals( 3247 comp.getPackageName())) 3248 || (action != null && sri.filter.matchAction(action))) { 3249 results.remove(j); 3250 if (DEBUG_INTENT_MATCHING) Log.v( 3251 TAG, "Removing duplicate item from " + j 3252 + " due to specific " + specificsPos); 3253 if (ri == null) { 3254 ri = sri; 3255 } 3256 j--; 3257 N--; 3258 } 3259 } 3260 3261 // Add this specific item to its proper place. 3262 if (ri == null) { 3263 ri = new ResolveInfo(); 3264 ri.activityInfo = ai; 3265 } 3266 results.add(specificsPos, ri); 3267 ri.specificIndex = i; 3268 specificsPos++; 3269 } 3270 } 3271 3272 // Now we go through the remaining generic results and remove any 3273 // duplicate actions that are found here. 3274 N = results.size(); 3275 for (int i=specificsPos; i<N-1; i++) { 3276 final ResolveInfo rii = results.get(i); 3277 if (rii.filter == null) { 3278 continue; 3279 } 3280 3281 // Iterate over all of the actions of this result's intent 3282 // filter... typically this should be just one. 3283 final Iterator<String> it = rii.filter.actionsIterator(); 3284 if (it == null) { 3285 continue; 3286 } 3287 while (it.hasNext()) { 3288 final String action = it.next(); 3289 if (resultsAction != null && resultsAction.equals(action)) { 3290 // If this action was explicitly requested, then don't 3291 // remove things that have it. 3292 continue; 3293 } 3294 for (int j=i+1; j<N; j++) { 3295 final ResolveInfo rij = results.get(j); 3296 if (rij.filter != null && rij.filter.hasAction(action)) { 3297 results.remove(j); 3298 if (DEBUG_INTENT_MATCHING) Log.v( 3299 TAG, "Removing duplicate item from " + j 3300 + " due to action " + action + " at " + i); 3301 j--; 3302 N--; 3303 } 3304 } 3305 } 3306 3307 // If the caller didn't request filter information, drop it now 3308 // so we don't have to marshall/unmarshall it. 3309 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 3310 rii.filter = null; 3311 } 3312 } 3313 3314 // Filter out the caller activity if so requested. 3315 if (caller != null) { 3316 N = results.size(); 3317 for (int i=0; i<N; i++) { 3318 ActivityInfo ainfo = results.get(i).activityInfo; 3319 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 3320 && caller.getClassName().equals(ainfo.name)) { 3321 results.remove(i); 3322 break; 3323 } 3324 } 3325 } 3326 3327 // If the caller didn't request filter information, 3328 // drop them now so we don't have to 3329 // marshall/unmarshall it. 3330 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 3331 N = results.size(); 3332 for (int i=0; i<N; i++) { 3333 results.get(i).filter = null; 3334 } 3335 } 3336 3337 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 3338 return results; 3339 } 3340 3341 @Override 3342 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 3343 int userId) { 3344 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3345 ComponentName comp = intent.getComponent(); 3346 if (comp == null) { 3347 if (intent.getSelector() != null) { 3348 intent = intent.getSelector(); 3349 comp = intent.getComponent(); 3350 } 3351 } 3352 if (comp != null) { 3353 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3354 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 3355 if (ai != null) { 3356 ResolveInfo ri = new ResolveInfo(); 3357 ri.activityInfo = ai; 3358 list.add(ri); 3359 } 3360 return list; 3361 } 3362 3363 // reader 3364 synchronized (mPackages) { 3365 String pkgName = intent.getPackage(); 3366 if (pkgName == null) { 3367 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 3368 } 3369 final PackageParser.Package pkg = mPackages.get(pkgName); 3370 if (pkg != null) { 3371 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 3372 userId); 3373 } 3374 return null; 3375 } 3376 } 3377 3378 @Override 3379 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 3380 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 3381 if (!sUserManager.exists(userId)) return null; 3382 if (query != null) { 3383 if (query.size() >= 1) { 3384 // If there is more than one service with the same priority, 3385 // just arbitrarily pick the first one. 3386 return query.get(0); 3387 } 3388 } 3389 return null; 3390 } 3391 3392 @Override 3393 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 3394 int userId) { 3395 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3396 ComponentName comp = intent.getComponent(); 3397 if (comp == null) { 3398 if (intent.getSelector() != null) { 3399 intent = intent.getSelector(); 3400 comp = intent.getComponent(); 3401 } 3402 } 3403 if (comp != null) { 3404 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3405 final ServiceInfo si = getServiceInfo(comp, flags, userId); 3406 if (si != null) { 3407 final ResolveInfo ri = new ResolveInfo(); 3408 ri.serviceInfo = si; 3409 list.add(ri); 3410 } 3411 return list; 3412 } 3413 3414 // reader 3415 synchronized (mPackages) { 3416 String pkgName = intent.getPackage(); 3417 if (pkgName == null) { 3418 return mServices.queryIntent(intent, resolvedType, flags, userId); 3419 } 3420 final PackageParser.Package pkg = mPackages.get(pkgName); 3421 if (pkg != null) { 3422 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 3423 userId); 3424 } 3425 return null; 3426 } 3427 } 3428 3429 @Override 3430 public List<ResolveInfo> queryIntentContentProviders( 3431 Intent intent, String resolvedType, int flags, int userId) { 3432 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3433 ComponentName comp = intent.getComponent(); 3434 if (comp == null) { 3435 if (intent.getSelector() != null) { 3436 intent = intent.getSelector(); 3437 comp = intent.getComponent(); 3438 } 3439 } 3440 if (comp != null) { 3441 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3442 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 3443 if (pi != null) { 3444 final ResolveInfo ri = new ResolveInfo(); 3445 ri.providerInfo = pi; 3446 list.add(ri); 3447 } 3448 return list; 3449 } 3450 3451 // reader 3452 synchronized (mPackages) { 3453 String pkgName = intent.getPackage(); 3454 if (pkgName == null) { 3455 return mProviders.queryIntent(intent, resolvedType, flags, userId); 3456 } 3457 final PackageParser.Package pkg = mPackages.get(pkgName); 3458 if (pkg != null) { 3459 return mProviders.queryIntentForPackage( 3460 intent, resolvedType, flags, pkg.providers, userId); 3461 } 3462 return null; 3463 } 3464 } 3465 3466 @Override 3467 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 3468 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3469 3470 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages"); 3471 3472 // writer 3473 synchronized (mPackages) { 3474 ArrayList<PackageInfo> list; 3475 if (listUninstalled) { 3476 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 3477 for (PackageSetting ps : mSettings.mPackages.values()) { 3478 PackageInfo pi; 3479 if (ps.pkg != null) { 3480 pi = generatePackageInfo(ps.pkg, flags, userId); 3481 } else { 3482 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 3483 } 3484 if (pi != null) { 3485 list.add(pi); 3486 } 3487 } 3488 } else { 3489 list = new ArrayList<PackageInfo>(mPackages.size()); 3490 for (PackageParser.Package p : mPackages.values()) { 3491 PackageInfo pi = generatePackageInfo(p, flags, userId); 3492 if (pi != null) { 3493 list.add(pi); 3494 } 3495 } 3496 } 3497 3498 return new ParceledListSlice<PackageInfo>(list); 3499 } 3500 } 3501 3502 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 3503 String[] permissions, boolean[] tmp, int flags, int userId) { 3504 int numMatch = 0; 3505 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 3506 for (int i=0; i<permissions.length; i++) { 3507 if (gp.grantedPermissions.contains(permissions[i])) { 3508 tmp[i] = true; 3509 numMatch++; 3510 } else { 3511 tmp[i] = false; 3512 } 3513 } 3514 if (numMatch == 0) { 3515 return; 3516 } 3517 PackageInfo pi; 3518 if (ps.pkg != null) { 3519 pi = generatePackageInfo(ps.pkg, flags, userId); 3520 } else { 3521 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 3522 } 3523 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 3524 if (numMatch == permissions.length) { 3525 pi.requestedPermissions = permissions; 3526 } else { 3527 pi.requestedPermissions = new String[numMatch]; 3528 numMatch = 0; 3529 for (int i=0; i<permissions.length; i++) { 3530 if (tmp[i]) { 3531 pi.requestedPermissions[numMatch] = permissions[i]; 3532 numMatch++; 3533 } 3534 } 3535 } 3536 } 3537 list.add(pi); 3538 } 3539 3540 @Override 3541 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 3542 String[] permissions, int flags, int userId) { 3543 if (!sUserManager.exists(userId)) return null; 3544 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3545 3546 // writer 3547 synchronized (mPackages) { 3548 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 3549 boolean[] tmpBools = new boolean[permissions.length]; 3550 if (listUninstalled) { 3551 for (PackageSetting ps : mSettings.mPackages.values()) { 3552 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 3553 } 3554 } else { 3555 for (PackageParser.Package pkg : mPackages.values()) { 3556 PackageSetting ps = (PackageSetting)pkg.mExtras; 3557 if (ps != null) { 3558 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 3559 userId); 3560 } 3561 } 3562 } 3563 3564 return new ParceledListSlice<PackageInfo>(list); 3565 } 3566 } 3567 3568 @Override 3569 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 3570 if (!sUserManager.exists(userId)) return null; 3571 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3572 3573 // writer 3574 synchronized (mPackages) { 3575 ArrayList<ApplicationInfo> list; 3576 if (listUninstalled) { 3577 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 3578 for (PackageSetting ps : mSettings.mPackages.values()) { 3579 ApplicationInfo ai; 3580 if (ps.pkg != null) { 3581 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 3582 ps.readUserState(userId), userId); 3583 } else { 3584 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 3585 } 3586 if (ai != null) { 3587 list.add(ai); 3588 } 3589 } 3590 } else { 3591 list = new ArrayList<ApplicationInfo>(mPackages.size()); 3592 for (PackageParser.Package p : mPackages.values()) { 3593 if (p.mExtras != null) { 3594 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 3595 ((PackageSetting)p.mExtras).readUserState(userId), userId); 3596 if (ai != null) { 3597 list.add(ai); 3598 } 3599 } 3600 } 3601 } 3602 3603 return new ParceledListSlice<ApplicationInfo>(list); 3604 } 3605 } 3606 3607 public List<ApplicationInfo> getPersistentApplications(int flags) { 3608 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 3609 3610 // reader 3611 synchronized (mPackages) { 3612 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 3613 final int userId = UserHandle.getCallingUserId(); 3614 while (i.hasNext()) { 3615 final PackageParser.Package p = i.next(); 3616 if (p.applicationInfo != null 3617 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 3618 && (!mSafeMode || isSystemApp(p))) { 3619 PackageSetting ps = mSettings.mPackages.get(p.packageName); 3620 if (ps != null) { 3621 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 3622 ps.readUserState(userId), userId); 3623 if (ai != null) { 3624 finalList.add(ai); 3625 } 3626 } 3627 } 3628 } 3629 } 3630 3631 return finalList; 3632 } 3633 3634 @Override 3635 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 3636 if (!sUserManager.exists(userId)) return null; 3637 // reader 3638 synchronized (mPackages) { 3639 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 3640 PackageSetting ps = provider != null 3641 ? mSettings.mPackages.get(provider.owner.packageName) 3642 : null; 3643 return ps != null 3644 && mSettings.isEnabledLPr(provider.info, flags, userId) 3645 && (!mSafeMode || (provider.info.applicationInfo.flags 3646 &ApplicationInfo.FLAG_SYSTEM) != 0) 3647 ? PackageParser.generateProviderInfo(provider, flags, 3648 ps.readUserState(userId), userId) 3649 : null; 3650 } 3651 } 3652 3653 /** 3654 * @deprecated 3655 */ 3656 @Deprecated 3657 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 3658 // reader 3659 synchronized (mPackages) { 3660 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 3661 .entrySet().iterator(); 3662 final int userId = UserHandle.getCallingUserId(); 3663 while (i.hasNext()) { 3664 Map.Entry<String, PackageParser.Provider> entry = i.next(); 3665 PackageParser.Provider p = entry.getValue(); 3666 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 3667 3668 if (ps != null && p.syncable 3669 && (!mSafeMode || (p.info.applicationInfo.flags 3670 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 3671 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 3672 ps.readUserState(userId), userId); 3673 if (info != null) { 3674 outNames.add(entry.getKey()); 3675 outInfo.add(info); 3676 } 3677 } 3678 } 3679 } 3680 } 3681 3682 @Override 3683 public List<ProviderInfo> queryContentProviders(String processName, 3684 int uid, int flags) { 3685 ArrayList<ProviderInfo> finalList = null; 3686 // reader 3687 synchronized (mPackages) { 3688 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 3689 final int userId = processName != null ? 3690 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 3691 while (i.hasNext()) { 3692 final PackageParser.Provider p = i.next(); 3693 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 3694 if (ps != null && p.info.authority != null 3695 && (processName == null 3696 || (p.info.processName.equals(processName) 3697 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 3698 && mSettings.isEnabledLPr(p.info, flags, userId) 3699 && (!mSafeMode 3700 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 3701 if (finalList == null) { 3702 finalList = new ArrayList<ProviderInfo>(3); 3703 } 3704 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 3705 ps.readUserState(userId), userId); 3706 if (info != null) { 3707 finalList.add(info); 3708 } 3709 } 3710 } 3711 } 3712 3713 if (finalList != null) { 3714 Collections.sort(finalList, mProviderInitOrderSorter); 3715 } 3716 3717 return finalList; 3718 } 3719 3720 @Override 3721 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 3722 int flags) { 3723 // reader 3724 synchronized (mPackages) { 3725 final PackageParser.Instrumentation i = mInstrumentation.get(name); 3726 return PackageParser.generateInstrumentationInfo(i, flags); 3727 } 3728 } 3729 3730 @Override 3731 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 3732 int flags) { 3733 ArrayList<InstrumentationInfo> finalList = 3734 new ArrayList<InstrumentationInfo>(); 3735 3736 // reader 3737 synchronized (mPackages) { 3738 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 3739 while (i.hasNext()) { 3740 final PackageParser.Instrumentation p = i.next(); 3741 if (targetPackage == null 3742 || targetPackage.equals(p.info.targetPackage)) { 3743 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 3744 flags); 3745 if (ii != null) { 3746 finalList.add(ii); 3747 } 3748 } 3749 } 3750 } 3751 3752 return finalList; 3753 } 3754 3755 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 3756 HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 3757 if (overlays == null) { 3758 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 3759 return; 3760 } 3761 for (PackageParser.Package opkg : overlays.values()) { 3762 // Not much to do if idmap fails: we already logged the error 3763 // and we certainly don't want to abort installation of pkg simply 3764 // because an overlay didn't fit properly. For these reasons, 3765 // ignore the return value of createIdmapForPackagePairLI. 3766 createIdmapForPackagePairLI(pkg, opkg); 3767 } 3768 } 3769 3770 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 3771 PackageParser.Package opkg) { 3772 if (!opkg.mTrustedOverlay) { 3773 Slog.w(TAG, "Skipping target and overlay pair " + pkg.mScanPath + " and " + 3774 opkg.mScanPath + ": overlay not trusted"); 3775 return false; 3776 } 3777 HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 3778 if (overlaySet == null) { 3779 Slog.e(TAG, "was about to create idmap for " + pkg.mScanPath + " and " + 3780 opkg.mScanPath + " but target package has no known overlays"); 3781 return false; 3782 } 3783 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 3784 if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, sharedGid) != 0) { 3785 Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath); 3786 return false; 3787 } 3788 PackageParser.Package[] overlayArray = 3789 overlaySet.values().toArray(new PackageParser.Package[0]); 3790 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 3791 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 3792 return p1.mOverlayPriority - p2.mOverlayPriority; 3793 } 3794 }; 3795 Arrays.sort(overlayArray, cmp); 3796 3797 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 3798 int i = 0; 3799 for (PackageParser.Package p : overlayArray) { 3800 pkg.applicationInfo.resourceDirs[i++] = p.applicationInfo.sourceDir; 3801 } 3802 return true; 3803 } 3804 3805 private void scanDirLI(File dir, int flags, int scanMode, long currentTime) { 3806 String[] files = dir.list(); 3807 if (files == null) { 3808 Log.d(TAG, "No files in app dir " + dir); 3809 return; 3810 } 3811 3812 if (DEBUG_PACKAGE_SCANNING) { 3813 Log.d(TAG, "Scanning app dir " + dir + " scanMode=" + scanMode 3814 + " flags=0x" + Integer.toHexString(flags)); 3815 } 3816 3817 int i; 3818 for (i=0; i<files.length; i++) { 3819 File file = new File(dir, files[i]); 3820 if (!isPackageFilename(files[i])) { 3821 // Ignore entries which are not apk's 3822 continue; 3823 } 3824 PackageParser.Package pkg = scanPackageLI(file, 3825 flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null); 3826 // Don't mess around with apps in system partition. 3827 if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 && 3828 mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) { 3829 // Delete the apk 3830 Slog.w(TAG, "Cleaning up failed install of " + file); 3831 file.delete(); 3832 } 3833 } 3834 } 3835 3836 private static File getSettingsProblemFile() { 3837 File dataDir = Environment.getDataDirectory(); 3838 File systemDir = new File(dataDir, "system"); 3839 File fname = new File(systemDir, "uiderrors.txt"); 3840 return fname; 3841 } 3842 3843 static void reportSettingsProblem(int priority, String msg) { 3844 try { 3845 File fname = getSettingsProblemFile(); 3846 FileOutputStream out = new FileOutputStream(fname, true); 3847 PrintWriter pw = new FastPrintWriter(out); 3848 SimpleDateFormat formatter = new SimpleDateFormat(); 3849 String dateString = formatter.format(new Date(System.currentTimeMillis())); 3850 pw.println(dateString + ": " + msg); 3851 pw.close(); 3852 FileUtils.setPermissions( 3853 fname.toString(), 3854 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 3855 -1, -1); 3856 } catch (java.io.IOException e) { 3857 } 3858 Slog.println(priority, TAG, msg); 3859 } 3860 3861 private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps, 3862 PackageParser.Package pkg, File srcFile, int parseFlags) { 3863 if (GET_CERTIFICATES) { 3864 if (ps != null 3865 && ps.codePath.equals(srcFile) 3866 && ps.timeStamp == srcFile.lastModified()) { 3867 if (ps.signatures.mSignatures != null 3868 && ps.signatures.mSignatures.length != 0) { 3869 // Optimization: reuse the existing cached certificates 3870 // if the package appears to be unchanged. 3871 pkg.mSignatures = ps.signatures.mSignatures; 3872 return true; 3873 } 3874 3875 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures. Collecting certs again to recover them."); 3876 } else { 3877 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 3878 } 3879 3880 if (!pp.collectCertificates(pkg, parseFlags)) { 3881 mLastScanError = pp.getParseError(); 3882 return false; 3883 } 3884 } 3885 return true; 3886 } 3887 3888 /* 3889 * Scan a package and return the newly parsed package. 3890 * Returns null in case of errors and the error code is stored in mLastScanError 3891 */ 3892 private PackageParser.Package scanPackageLI(File scanFile, 3893 int parseFlags, int scanMode, long currentTime, UserHandle user) { 3894 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 3895 String scanPath = scanFile.getPath(); 3896 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath); 3897 parseFlags |= mDefParseFlags; 3898 PackageParser pp = new PackageParser(scanPath); 3899 pp.setSeparateProcesses(mSeparateProcesses); 3900 pp.setOnlyCoreApps(mOnlyCore); 3901 final PackageParser.Package pkg = pp.parsePackage(scanFile, 3902 scanPath, mMetrics, parseFlags, (scanMode & SCAN_TRUSTED_OVERLAY) != 0); 3903 3904 if (pkg == null) { 3905 mLastScanError = pp.getParseError(); 3906 return null; 3907 } 3908 3909 PackageSetting ps = null; 3910 PackageSetting updatedPkg; 3911 // reader 3912 synchronized (mPackages) { 3913 // Look to see if we already know about this package. 3914 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 3915 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 3916 // This package has been renamed to its original name. Let's 3917 // use that. 3918 ps = mSettings.peekPackageLPr(oldName); 3919 } 3920 // If there was no original package, see one for the real package name. 3921 if (ps == null) { 3922 ps = mSettings.peekPackageLPr(pkg.packageName); 3923 } 3924 // Check to see if this package could be hiding/updating a system 3925 // package. Must look for it either under the original or real 3926 // package name depending on our state. 3927 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 3928 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 3929 } 3930 boolean updatedPkgBetter = false; 3931 // First check if this is a system package that may involve an update 3932 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 3933 if (ps != null && !ps.codePath.equals(scanFile)) { 3934 // The path has changed from what was last scanned... check the 3935 // version of the new path against what we have stored to determine 3936 // what to do. 3937 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 3938 if (pkg.mVersionCode < ps.versionCode) { 3939 // The system package has been updated and the code path does not match 3940 // Ignore entry. Skip it. 3941 Log.i(TAG, "Package " + ps.name + " at " + scanFile 3942 + " ignored: updated version " + ps.versionCode 3943 + " better than this " + pkg.mVersionCode); 3944 if (!updatedPkg.codePath.equals(scanFile)) { 3945 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 3946 + ps.name + " changing from " + updatedPkg.codePathString 3947 + " to " + scanFile); 3948 updatedPkg.codePath = scanFile; 3949 updatedPkg.codePathString = scanFile.toString(); 3950 // This is the point at which we know that the system-disk APK 3951 // for this package has moved during a reboot (e.g. due to an OTA), 3952 // so we need to reevaluate it for privilege policy. 3953 if (locationIsPrivileged(scanFile)) { 3954 updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED; 3955 } 3956 } 3957 updatedPkg.pkg = pkg; 3958 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 3959 return null; 3960 } else { 3961 // The current app on the system partion is better than 3962 // what we have updated to on the data partition; switch 3963 // back to the system partition version. 3964 // At this point, its safely assumed that package installation for 3965 // apps in system partition will go through. If not there won't be a working 3966 // version of the app 3967 // writer 3968 synchronized (mPackages) { 3969 // Just remove the loaded entries from package lists. 3970 mPackages.remove(ps.name); 3971 } 3972 Slog.w(TAG, "Package " + ps.name + " at " + scanFile 3973 + "reverting from " + ps.codePathString 3974 + ": new version " + pkg.mVersionCode 3975 + " better than installed " + ps.versionCode); 3976 3977 InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps), 3978 ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString, 3979 getAppInstructionSetFromSettings(ps)); 3980 synchronized (mInstallLock) { 3981 args.cleanUpResourcesLI(); 3982 } 3983 synchronized (mPackages) { 3984 mSettings.enableSystemPackageLPw(ps.name); 3985 } 3986 updatedPkgBetter = true; 3987 } 3988 } 3989 } 3990 3991 if (updatedPkg != null) { 3992 // An updated system app will not have the PARSE_IS_SYSTEM flag set 3993 // initially 3994 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 3995 3996 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 3997 // flag set initially 3998 if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) { 3999 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 4000 } 4001 } 4002 // Verify certificates against what was last scanned 4003 if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) { 4004 Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName); 4005 return null; 4006 } 4007 4008 /* 4009 * A new system app appeared, but we already had a non-system one of the 4010 * same name installed earlier. 4011 */ 4012 boolean shouldHideSystemApp = false; 4013 if (updatedPkg == null && ps != null 4014 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 4015 /* 4016 * Check to make sure the signatures match first. If they don't, 4017 * wipe the installed application and its data. 4018 */ 4019 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 4020 != PackageManager.SIGNATURE_MATCH) { 4021 if (DEBUG_INSTALL) Slog.d(TAG, "Signature mismatch!"); 4022 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 4023 ps = null; 4024 } else { 4025 /* 4026 * If the newly-added system app is an older version than the 4027 * already installed version, hide it. It will be scanned later 4028 * and re-added like an update. 4029 */ 4030 if (pkg.mVersionCode < ps.versionCode) { 4031 shouldHideSystemApp = true; 4032 } else { 4033 /* 4034 * The newly found system app is a newer version that the 4035 * one previously installed. Simply remove the 4036 * already-installed application and replace it with our own 4037 * while keeping the application data. 4038 */ 4039 Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from " 4040 + ps.codePathString + ": new version " + pkg.mVersionCode 4041 + " better than installed " + ps.versionCode); 4042 InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps), 4043 ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString, 4044 getAppInstructionSetFromSettings(ps)); 4045 synchronized (mInstallLock) { 4046 args.cleanUpResourcesLI(); 4047 } 4048 } 4049 } 4050 } 4051 4052 // The apk is forward locked (not public) if its code and resources 4053 // are kept in different files. (except for app in either system or 4054 // vendor path). 4055 // TODO grab this value from PackageSettings 4056 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 4057 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 4058 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 4059 } 4060 } 4061 4062 String codePath = null; 4063 String resPath = null; 4064 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 4065 if (ps != null && ps.resourcePathString != null) { 4066 resPath = ps.resourcePathString; 4067 } else { 4068 // Should not happen at all. Just log an error. 4069 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 4070 } 4071 } else { 4072 resPath = pkg.mScanPath; 4073 } 4074 4075 codePath = pkg.mScanPath; 4076 // Set application objects path explicitly. 4077 setApplicationInfoPaths(pkg, codePath, resPath); 4078 // Note that we invoke the following method only if we are about to unpack an application 4079 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode 4080 | SCAN_UPDATE_SIGNATURE, currentTime, user); 4081 4082 /* 4083 * If the system app should be overridden by a previously installed 4084 * data, hide the system app now and let the /data/app scan pick it up 4085 * again. 4086 */ 4087 if (shouldHideSystemApp) { 4088 synchronized (mPackages) { 4089 /* 4090 * We have to grant systems permissions before we hide, because 4091 * grantPermissions will assume the package update is trying to 4092 * expand its permissions. 4093 */ 4094 grantPermissionsLPw(pkg, true); 4095 mSettings.disableSystemPackageLPw(pkg.packageName); 4096 } 4097 } 4098 4099 return scannedPkg; 4100 } 4101 4102 private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath, 4103 String destResPath) { 4104 pkg.mPath = pkg.mScanPath = destCodePath; 4105 pkg.applicationInfo.sourceDir = destCodePath; 4106 pkg.applicationInfo.publicSourceDir = destResPath; 4107 } 4108 4109 private static String fixProcessName(String defProcessName, 4110 String processName, int uid) { 4111 if (processName == null) { 4112 return defProcessName; 4113 } 4114 return processName; 4115 } 4116 4117 private boolean verifySignaturesLP(PackageSetting pkgSetting, 4118 PackageParser.Package pkg) { 4119 if (pkgSetting.signatures.mSignatures != null) { 4120 // Already existing package. Make sure signatures match 4121 if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) != 4122 PackageManager.SIGNATURE_MATCH) { 4123 Slog.e(TAG, "Package " + pkg.packageName 4124 + " signatures do not match the previously installed version; ignoring!"); 4125 mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 4126 return false; 4127 } 4128 } 4129 // Check for shared user signatures 4130 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 4131 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 4132 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 4133 Slog.e(TAG, "Package " + pkg.packageName 4134 + " has no signatures that match those in shared user " 4135 + pkgSetting.sharedUser.name + "; ignoring!"); 4136 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 4137 return false; 4138 } 4139 } 4140 return true; 4141 } 4142 4143 /** 4144 * Enforces that only the system UID or root's UID can call a method exposed 4145 * via Binder. 4146 * 4147 * @param message used as message if SecurityException is thrown 4148 * @throws SecurityException if the caller is not system or root 4149 */ 4150 private static final void enforceSystemOrRoot(String message) { 4151 final int uid = Binder.getCallingUid(); 4152 if (uid != Process.SYSTEM_UID && uid != 0) { 4153 throw new SecurityException(message); 4154 } 4155 } 4156 4157 @Override 4158 public void performBootDexOpt() { 4159 enforceSystemOrRoot("Only the system can request dexopt be performed"); 4160 4161 final HashSet<PackageParser.Package> pkgs; 4162 synchronized (mPackages) { 4163 pkgs = mDeferredDexOpt; 4164 mDeferredDexOpt = null; 4165 } 4166 4167 if (pkgs != null) { 4168 // Filter out packages that aren't recently used. 4169 // 4170 // The exception is first boot of a non-eng device, which 4171 // should do a full dexopt. 4172 boolean eng = "eng".equals(SystemProperties.get("ro.build.type")); 4173 if (eng || !isFirstBoot()) { 4174 // TODO: add a property to control this? 4175 long dexOptLRUThresholdInMinutes; 4176 if (eng) { 4177 dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. 4178 } else { 4179 dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. 4180 } 4181 long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; 4182 4183 int total = pkgs.size(); 4184 int skipped = 0; 4185 long now = System.currentTimeMillis(); 4186 for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { 4187 PackageParser.Package pkg = i.next(); 4188 long then = pkg.mLastPackageUsageTimeInMills; 4189 if (then + dexOptLRUThresholdInMills < now) { 4190 if (DEBUG_DEXOPT) { 4191 Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + 4192 ((then == 0) ? "never" : new Date(then))); 4193 } 4194 i.remove(); 4195 skipped++; 4196 } 4197 } 4198 if (DEBUG_DEXOPT) { 4199 Log.i(TAG, "Skipped optimizing " + skipped + " of " + total); 4200 } 4201 } 4202 4203 int i = 0; 4204 for (PackageParser.Package pkg : pkgs) { 4205 i++; 4206 if (DEBUG_DEXOPT) { 4207 Log.i(TAG, "Optimizing app " + i + " of " + pkgs.size() 4208 + ": " + pkg.packageName); 4209 } 4210 if (!isFirstBoot()) { 4211 try { 4212 ActivityManagerNative.getDefault().showBootMessage( 4213 mContext.getResources().getString( 4214 R.string.android_upgrading_apk, 4215 i, pkgs.size()), true); 4216 } catch (RemoteException e) { 4217 } 4218 } 4219 PackageParser.Package p = pkg; 4220 synchronized (mInstallLock) { 4221 if (p.mDexOptNeeded) { 4222 performDexOptLI(p, false /* force dex */, false /* defer */, 4223 true /* include dependencies */); 4224 } 4225 } 4226 } 4227 } 4228 } 4229 4230 @Override 4231 public boolean performDexOpt(String packageName) { 4232 enforceSystemOrRoot("Only the system can request dexopt be performed"); 4233 return performDexOpt(packageName, true); 4234 } 4235 4236 public boolean performDexOpt(String packageName, boolean updateUsage) { 4237 4238 PackageParser.Package p; 4239 synchronized (mPackages) { 4240 p = mPackages.get(packageName); 4241 if (p == null) { 4242 return false; 4243 } 4244 if (updateUsage) { 4245 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 4246 } 4247 mPackageUsage.write(); 4248 if (!p.mDexOptNeeded) { 4249 return false; 4250 } 4251 } 4252 4253 synchronized (mInstallLock) { 4254 return performDexOptLI(p, false /* force dex */, false /* defer */, 4255 true /* include dependencies */) == DEX_OPT_PERFORMED; 4256 } 4257 } 4258 4259 public HashSet<String> getPackagesThatNeedDexOpt() { 4260 HashSet<String> pkgs = null; 4261 synchronized (mPackages) { 4262 for (PackageParser.Package p : mPackages.values()) { 4263 if (DEBUG_DEXOPT) { 4264 Log.i(TAG, p.packageName + " mDexOptNeeded=" + p.mDexOptNeeded); 4265 } 4266 if (!p.mDexOptNeeded) { 4267 continue; 4268 } 4269 if (pkgs == null) { 4270 pkgs = new HashSet<String>(); 4271 } 4272 pkgs.add(p.packageName); 4273 } 4274 } 4275 return pkgs; 4276 } 4277 4278 public void shutdown() { 4279 mPackageUsage.write(true); 4280 } 4281 4282 private void performDexOptLibsLI(ArrayList<String> libs, String instructionSet, 4283 boolean forceDex, boolean defer, HashSet<String> done) { 4284 for (int i=0; i<libs.size(); i++) { 4285 PackageParser.Package libPkg; 4286 String libName; 4287 synchronized (mPackages) { 4288 libName = libs.get(i); 4289 SharedLibraryEntry lib = mSharedLibraries.get(libName); 4290 if (lib != null && lib.apk != null) { 4291 libPkg = mPackages.get(lib.apk); 4292 } else { 4293 libPkg = null; 4294 } 4295 } 4296 if (libPkg != null && !done.contains(libName)) { 4297 performDexOptLI(libPkg, instructionSet, forceDex, defer, done); 4298 } 4299 } 4300 } 4301 4302 static final int DEX_OPT_SKIPPED = 0; 4303 static final int DEX_OPT_PERFORMED = 1; 4304 static final int DEX_OPT_DEFERRED = 2; 4305 static final int DEX_OPT_FAILED = -1; 4306 4307 private int performDexOptLI(PackageParser.Package pkg, String instructionSetOverride, 4308 boolean forceDex, boolean defer, HashSet<String> done) { 4309 final String instructionSet = instructionSetOverride != null ? 4310 instructionSetOverride : getAppInstructionSet(pkg.applicationInfo); 4311 4312 if (done != null) { 4313 done.add(pkg.packageName); 4314 if (pkg.usesLibraries != null) { 4315 performDexOptLibsLI(pkg.usesLibraries, instructionSet, forceDex, defer, done); 4316 } 4317 if (pkg.usesOptionalLibraries != null) { 4318 performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSet, forceDex, defer, done); 4319 } 4320 } 4321 4322 boolean performed = false; 4323 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 4324 String path = pkg.mScanPath; 4325 try { 4326 boolean isDexOptNeededInternal = DexFile.isDexOptNeededInternal(path, 4327 pkg.packageName, 4328 instructionSet, 4329 defer); 4330 // There are three basic cases here: 4331 // 1.) we need to dexopt, either because we are forced or it is needed 4332 // 2.) we are defering a needed dexopt 4333 // 3.) we are skipping an unneeded dexopt 4334 if (forceDex || (!defer && isDexOptNeededInternal)) { 4335 Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName); 4336 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4337 int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg), 4338 pkg.packageName, instructionSet); 4339 // Note that we ran dexopt, since rerunning will 4340 // probably just result in an error again. 4341 pkg.mDexOptNeeded = false; 4342 if (ret < 0) { 4343 return DEX_OPT_FAILED; 4344 } 4345 return DEX_OPT_PERFORMED; 4346 } 4347 if (defer && isDexOptNeededInternal) { 4348 if (mDeferredDexOpt == null) { 4349 mDeferredDexOpt = new HashSet<PackageParser.Package>(); 4350 } 4351 mDeferredDexOpt.add(pkg); 4352 return DEX_OPT_DEFERRED; 4353 } 4354 pkg.mDexOptNeeded = false; 4355 return DEX_OPT_SKIPPED; 4356 } catch (FileNotFoundException e) { 4357 Slog.w(TAG, "Apk not found for dexopt: " + path); 4358 return DEX_OPT_FAILED; 4359 } catch (IOException e) { 4360 Slog.w(TAG, "IOException reading apk: " + path, e); 4361 return DEX_OPT_FAILED; 4362 } catch (StaleDexCacheError e) { 4363 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e); 4364 return DEX_OPT_FAILED; 4365 } catch (Exception e) { 4366 Slog.w(TAG, "Exception when doing dexopt : ", e); 4367 return DEX_OPT_FAILED; 4368 } 4369 } 4370 return DEX_OPT_SKIPPED; 4371 } 4372 4373 private String getAppInstructionSet(ApplicationInfo info) { 4374 String instructionSet = getPreferredInstructionSet(); 4375 4376 if (info.requiredCpuAbi != null) { 4377 instructionSet = VMRuntime.getInstructionSet(info.requiredCpuAbi); 4378 } 4379 4380 return instructionSet; 4381 } 4382 4383 private String getAppInstructionSetFromSettings(PackageSetting ps) { 4384 String instructionSet = getPreferredInstructionSet(); 4385 4386 if (ps.requiredCpuAbiString != null) { 4387 instructionSet = VMRuntime.getInstructionSet(ps.requiredCpuAbiString); 4388 } 4389 4390 return instructionSet; 4391 } 4392 4393 private static String getPreferredInstructionSet() { 4394 if (sPreferredInstructionSet == null) { 4395 sPreferredInstructionSet = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]); 4396 } 4397 4398 return sPreferredInstructionSet; 4399 } 4400 4401 private static List<String> getAllInstructionSets() { 4402 final String[] allAbis = Build.SUPPORTED_ABIS; 4403 final List<String> allInstructionSets = new ArrayList<String>(allAbis.length); 4404 4405 for (String abi : allAbis) { 4406 final String instructionSet = VMRuntime.getInstructionSet(abi); 4407 if (!allInstructionSets.contains(instructionSet)) { 4408 allInstructionSets.add(instructionSet); 4409 } 4410 } 4411 4412 return allInstructionSets; 4413 } 4414 4415 private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer, 4416 boolean inclDependencies) { 4417 HashSet<String> done; 4418 if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) { 4419 done = new HashSet<String>(); 4420 done.add(pkg.packageName); 4421 } else { 4422 done = null; 4423 } 4424 return performDexOptLI(pkg, null /* instruction set override */, forceDex, defer, done); 4425 } 4426 4427 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 4428 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 4429 Slog.w(TAG, "Unable to update from " + oldPkg.name 4430 + " to " + newPkg.packageName 4431 + ": old package not in system partition"); 4432 return false; 4433 } else if (mPackages.get(oldPkg.name) != null) { 4434 Slog.w(TAG, "Unable to update from " + oldPkg.name 4435 + " to " + newPkg.packageName 4436 + ": old package still exists"); 4437 return false; 4438 } 4439 return true; 4440 } 4441 4442 File getDataPathForUser(int userId) { 4443 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId); 4444 } 4445 4446 private File getDataPathForPackage(String packageName, int userId) { 4447 /* 4448 * Until we fully support multiple users, return the directory we 4449 * previously would have. The PackageManagerTests will need to be 4450 * revised when this is changed back.. 4451 */ 4452 if (userId == 0) { 4453 return new File(mAppDataDir, packageName); 4454 } else { 4455 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId 4456 + File.separator + packageName); 4457 } 4458 } 4459 4460 private int createDataDirsLI(String packageName, int uid, String seinfo) { 4461 int[] users = sUserManager.getUserIds(); 4462 int res = mInstaller.install(packageName, uid, uid, seinfo); 4463 if (res < 0) { 4464 return res; 4465 } 4466 for (int user : users) { 4467 if (user != 0) { 4468 res = mInstaller.createUserData(packageName, 4469 UserHandle.getUid(user, uid), user, seinfo); 4470 if (res < 0) { 4471 return res; 4472 } 4473 } 4474 } 4475 return res; 4476 } 4477 4478 private int removeDataDirsLI(String packageName) { 4479 int[] users = sUserManager.getUserIds(); 4480 int res = 0; 4481 for (int user : users) { 4482 int resInner = mInstaller.remove(packageName, user); 4483 if (resInner < 0) { 4484 res = resInner; 4485 } 4486 } 4487 4488 final File nativeLibraryFile = new File(mAppLibInstallDir, packageName); 4489 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile); 4490 if (!nativeLibraryFile.delete()) { 4491 Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath()); 4492 } 4493 4494 return res; 4495 } 4496 4497 private int addSharedLibraryLPw(final SharedLibraryEntry file, int num, 4498 PackageParser.Package changingLib) { 4499 if (file.path != null) { 4500 mTmpSharedLibraries[num] = file.path; 4501 return num+1; 4502 } 4503 PackageParser.Package p = mPackages.get(file.apk); 4504 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 4505 // If we are doing this while in the middle of updating a library apk, 4506 // then we need to make sure to use that new apk for determining the 4507 // dependencies here. (We haven't yet finished committing the new apk 4508 // to the package manager state.) 4509 if (p == null || p.packageName.equals(changingLib.packageName)) { 4510 p = changingLib; 4511 } 4512 } 4513 if (p != null) { 4514 String path = p.mPath; 4515 for (int i=0; i<num; i++) { 4516 if (mTmpSharedLibraries[i].equals(path)) { 4517 return num; 4518 } 4519 } 4520 mTmpSharedLibraries[num] = p.mPath; 4521 return num+1; 4522 } 4523 return num; 4524 } 4525 4526 private boolean updateSharedLibrariesLPw(PackageParser.Package pkg, 4527 PackageParser.Package changingLib) { 4528 // We might be upgrading from a version of the platform that did not 4529 // provide per-package native library directories for system apps. 4530 // Fix that up here. 4531 if (isSystemApp(pkg)) { 4532 PackageSetting ps = mSettings.mPackages.get(pkg.applicationInfo.packageName); 4533 setInternalAppNativeLibraryPath(pkg, ps); 4534 } 4535 4536 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 4537 if (mTmpSharedLibraries == null || 4538 mTmpSharedLibraries.length < mSharedLibraries.size()) { 4539 mTmpSharedLibraries = new String[mSharedLibraries.size()]; 4540 } 4541 int num = 0; 4542 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 4543 for (int i=0; i<N; i++) { 4544 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 4545 if (file == null) { 4546 Slog.e(TAG, "Package " + pkg.packageName 4547 + " requires unavailable shared library " 4548 + pkg.usesLibraries.get(i) + "; failing!"); 4549 mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 4550 return false; 4551 } 4552 num = addSharedLibraryLPw(file, num, changingLib); 4553 } 4554 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 4555 for (int i=0; i<N; i++) { 4556 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 4557 if (file == null) { 4558 Slog.w(TAG, "Package " + pkg.packageName 4559 + " desires unavailable shared library " 4560 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 4561 } else { 4562 num = addSharedLibraryLPw(file, num, changingLib); 4563 } 4564 } 4565 if (num > 0) { 4566 pkg.usesLibraryFiles = new String[num]; 4567 System.arraycopy(mTmpSharedLibraries, 0, 4568 pkg.usesLibraryFiles, 0, num); 4569 } else { 4570 pkg.usesLibraryFiles = null; 4571 } 4572 } 4573 return true; 4574 } 4575 4576 private static boolean hasString(List<String> list, List<String> which) { 4577 if (list == null) { 4578 return false; 4579 } 4580 for (int i=list.size()-1; i>=0; i--) { 4581 for (int j=which.size()-1; j>=0; j--) { 4582 if (which.get(j).equals(list.get(i))) { 4583 return true; 4584 } 4585 } 4586 } 4587 return false; 4588 } 4589 4590 private void updateAllSharedLibrariesLPw() { 4591 for (PackageParser.Package pkg : mPackages.values()) { 4592 updateSharedLibrariesLPw(pkg, null); 4593 } 4594 } 4595 4596 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 4597 PackageParser.Package changingPkg) { 4598 ArrayList<PackageParser.Package> res = null; 4599 for (PackageParser.Package pkg : mPackages.values()) { 4600 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 4601 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 4602 if (res == null) { 4603 res = new ArrayList<PackageParser.Package>(); 4604 } 4605 res.add(pkg); 4606 updateSharedLibrariesLPw(pkg, changingPkg); 4607 } 4608 } 4609 return res; 4610 } 4611 4612 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, 4613 int parseFlags, int scanMode, long currentTime, UserHandle user) { 4614 File scanFile = new File(pkg.mScanPath); 4615 if (scanFile == null || pkg.applicationInfo.sourceDir == null || 4616 pkg.applicationInfo.publicSourceDir == null) { 4617 // Bail out. The resource and code paths haven't been set. 4618 Slog.w(TAG, " Code and resource paths haven't been set correctly"); 4619 mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK; 4620 return null; 4621 } 4622 4623 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 4624 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 4625 } 4626 4627 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 4628 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED; 4629 } 4630 4631 if (mCustomResolverComponentName != null && 4632 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 4633 setUpCustomResolverActivity(pkg); 4634 } 4635 4636 if (pkg.packageName.equals("android")) { 4637 synchronized (mPackages) { 4638 if (mAndroidApplication != null) { 4639 Slog.w(TAG, "*************************************************"); 4640 Slog.w(TAG, "Core android package being redefined. Skipping."); 4641 Slog.w(TAG, " file=" + scanFile); 4642 Slog.w(TAG, "*************************************************"); 4643 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 4644 return null; 4645 } 4646 4647 // Set up information for our fall-back user intent resolution activity. 4648 mPlatformPackage = pkg; 4649 pkg.mVersionCode = mSdkVersion; 4650 mAndroidApplication = pkg.applicationInfo; 4651 4652 if (!mResolverReplaced) { 4653 mResolveActivity.applicationInfo = mAndroidApplication; 4654 mResolveActivity.name = ResolverActivity.class.getName(); 4655 mResolveActivity.packageName = mAndroidApplication.packageName; 4656 mResolveActivity.processName = "system:ui"; 4657 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 4658 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 4659 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 4660 mResolveActivity.exported = true; 4661 mResolveActivity.enabled = true; 4662 mResolveInfo.activityInfo = mResolveActivity; 4663 mResolveInfo.priority = 0; 4664 mResolveInfo.preferredOrder = 0; 4665 mResolveInfo.match = 0; 4666 mResolveComponentName = new ComponentName( 4667 mAndroidApplication.packageName, mResolveActivity.name); 4668 } 4669 } 4670 } 4671 4672 if (DEBUG_PACKAGE_SCANNING) { 4673 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 4674 Log.d(TAG, "Scanning package " + pkg.packageName); 4675 } 4676 4677 if (mPackages.containsKey(pkg.packageName) 4678 || mSharedLibraries.containsKey(pkg.packageName)) { 4679 Slog.w(TAG, "Application package " + pkg.packageName 4680 + " already installed. Skipping duplicate."); 4681 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 4682 return null; 4683 } 4684 4685 // Initialize package source and resource directories 4686 File destCodeFile = new File(pkg.applicationInfo.sourceDir); 4687 File destResourceFile = new File(pkg.applicationInfo.publicSourceDir); 4688 4689 SharedUserSetting suid = null; 4690 PackageSetting pkgSetting = null; 4691 4692 if (!isSystemApp(pkg)) { 4693 // Only system apps can use these features. 4694 pkg.mOriginalPackages = null; 4695 pkg.mRealPackage = null; 4696 pkg.mAdoptPermissions = null; 4697 } 4698 4699 // writer 4700 synchronized (mPackages) { 4701 if (pkg.mSharedUserId != null) { 4702 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true); 4703 if (suid == null) { 4704 Slog.w(TAG, "Creating application package " + pkg.packageName 4705 + " for shared user failed"); 4706 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4707 return null; 4708 } 4709 if (DEBUG_PACKAGE_SCANNING) { 4710 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 4711 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 4712 + "): packages=" + suid.packages); 4713 } 4714 } 4715 4716 // Check if we are renaming from an original package name. 4717 PackageSetting origPackage = null; 4718 String realName = null; 4719 if (pkg.mOriginalPackages != null) { 4720 // This package may need to be renamed to a previously 4721 // installed name. Let's check on that... 4722 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 4723 if (pkg.mOriginalPackages.contains(renamed)) { 4724 // This package had originally been installed as the 4725 // original name, and we have already taken care of 4726 // transitioning to the new one. Just update the new 4727 // one to continue using the old name. 4728 realName = pkg.mRealPackage; 4729 if (!pkg.packageName.equals(renamed)) { 4730 // Callers into this function may have already taken 4731 // care of renaming the package; only do it here if 4732 // it is not already done. 4733 pkg.setPackageName(renamed); 4734 } 4735 4736 } else { 4737 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 4738 if ((origPackage = mSettings.peekPackageLPr( 4739 pkg.mOriginalPackages.get(i))) != null) { 4740 // We do have the package already installed under its 4741 // original name... should we use it? 4742 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 4743 // New package is not compatible with original. 4744 origPackage = null; 4745 continue; 4746 } else if (origPackage.sharedUser != null) { 4747 // Make sure uid is compatible between packages. 4748 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 4749 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 4750 + " to " + pkg.packageName + ": old uid " 4751 + origPackage.sharedUser.name 4752 + " differs from " + pkg.mSharedUserId); 4753 origPackage = null; 4754 continue; 4755 } 4756 } else { 4757 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 4758 + pkg.packageName + " to old name " + origPackage.name); 4759 } 4760 break; 4761 } 4762 } 4763 } 4764 } 4765 4766 if (mTransferedPackages.contains(pkg.packageName)) { 4767 Slog.w(TAG, "Package " + pkg.packageName 4768 + " was transferred to another, but its .apk remains"); 4769 } 4770 4771 // Just create the setting, don't add it yet. For already existing packages 4772 // the PkgSetting exists already and doesn't have to be created. 4773 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 4774 destResourceFile, pkg.applicationInfo.nativeLibraryDir, 4775 pkg.applicationInfo.requiredCpuAbi, 4776 pkg.applicationInfo.flags, user, false); 4777 if (pkgSetting == null) { 4778 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed"); 4779 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4780 return null; 4781 } 4782 4783 if (pkgSetting.origPackage != null) { 4784 // If we are first transitioning from an original package, 4785 // fix up the new package's name now. We need to do this after 4786 // looking up the package under its new name, so getPackageLP 4787 // can take care of fiddling things correctly. 4788 pkg.setPackageName(origPackage.name); 4789 4790 // File a report about this. 4791 String msg = "New package " + pkgSetting.realName 4792 + " renamed to replace old package " + pkgSetting.name; 4793 reportSettingsProblem(Log.WARN, msg); 4794 4795 // Make a note of it. 4796 mTransferedPackages.add(origPackage.name); 4797 4798 // No longer need to retain this. 4799 pkgSetting.origPackage = null; 4800 } 4801 4802 if (realName != null) { 4803 // Make a note of it. 4804 mTransferedPackages.add(pkg.packageName); 4805 } 4806 4807 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 4808 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 4809 } 4810 4811 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 4812 // Check all shared libraries and map to their actual file path. 4813 // We only do this here for apps not on a system dir, because those 4814 // are the only ones that can fail an install due to this. We 4815 // will take care of the system apps by updating all of their 4816 // library paths after the scan is done. 4817 if (!updateSharedLibrariesLPw(pkg, null)) { 4818 return null; 4819 } 4820 } 4821 4822 if (mFoundPolicyFile) { 4823 SELinuxMMAC.assignSeinfoValue(pkg); 4824 } 4825 4826 pkg.applicationInfo.uid = pkgSetting.appId; 4827 pkg.mExtras = pkgSetting; 4828 4829 if (!verifySignaturesLP(pkgSetting, pkg)) { 4830 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 4831 return null; 4832 } 4833 // The signature has changed, but this package is in the system 4834 // image... let's recover! 4835 pkgSetting.signatures.mSignatures = pkg.mSignatures; 4836 // However... if this package is part of a shared user, but it 4837 // doesn't match the signature of the shared user, let's fail. 4838 // What this means is that you can't change the signatures 4839 // associated with an overall shared user, which doesn't seem all 4840 // that unreasonable. 4841 if (pkgSetting.sharedUser != null) { 4842 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 4843 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 4844 Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser); 4845 mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 4846 return null; 4847 } 4848 } 4849 // File a report about this. 4850 String msg = "System package " + pkg.packageName 4851 + " signature changed; retaining data."; 4852 reportSettingsProblem(Log.WARN, msg); 4853 } 4854 4855 // Verify that this new package doesn't have any content providers 4856 // that conflict with existing packages. Only do this if the 4857 // package isn't already installed, since we don't want to break 4858 // things that are installed. 4859 if ((scanMode&SCAN_NEW_INSTALL) != 0) { 4860 final int N = pkg.providers.size(); 4861 int i; 4862 for (i=0; i<N; i++) { 4863 PackageParser.Provider p = pkg.providers.get(i); 4864 if (p.info.authority != null) { 4865 String names[] = p.info.authority.split(";"); 4866 for (int j = 0; j < names.length; j++) { 4867 if (mProvidersByAuthority.containsKey(names[j])) { 4868 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 4869 Slog.w(TAG, "Can't install because provider name " + names[j] + 4870 " (in package " + pkg.applicationInfo.packageName + 4871 ") is already used by " 4872 + ((other != null && other.getComponentName() != null) 4873 ? other.getComponentName().getPackageName() : "?")); 4874 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 4875 return null; 4876 } 4877 } 4878 } 4879 } 4880 } 4881 4882 if (pkg.mAdoptPermissions != null) { 4883 // This package wants to adopt ownership of permissions from 4884 // another package. 4885 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 4886 final String origName = pkg.mAdoptPermissions.get(i); 4887 final PackageSetting orig = mSettings.peekPackageLPr(origName); 4888 if (orig != null) { 4889 if (verifyPackageUpdateLPr(orig, pkg)) { 4890 Slog.i(TAG, "Adopting permissions from " + origName + " to " 4891 + pkg.packageName); 4892 mSettings.transferPermissionsLPw(origName, pkg.packageName); 4893 } 4894 } 4895 } 4896 } 4897 } 4898 4899 final String pkgName = pkg.packageName; 4900 4901 final long scanFileTime = scanFile.lastModified(); 4902 final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0; 4903 pkg.applicationInfo.processName = fixProcessName( 4904 pkg.applicationInfo.packageName, 4905 pkg.applicationInfo.processName, 4906 pkg.applicationInfo.uid); 4907 4908 File dataPath; 4909 if (mPlatformPackage == pkg) { 4910 // The system package is special. 4911 dataPath = new File (Environment.getDataDirectory(), "system"); 4912 pkg.applicationInfo.dataDir = dataPath.getPath(); 4913 } else { 4914 // This is a normal package, need to make its data directory. 4915 dataPath = getDataPathForPackage(pkg.packageName, 0); 4916 4917 boolean uidError = false; 4918 4919 if (dataPath.exists()) { 4920 int currentUid = 0; 4921 try { 4922 StructStat stat = Os.stat(dataPath.getPath()); 4923 currentUid = stat.st_uid; 4924 } catch (ErrnoException e) { 4925 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 4926 } 4927 4928 // If we have mismatched owners for the data path, we have a problem. 4929 if (currentUid != pkg.applicationInfo.uid) { 4930 boolean recovered = false; 4931 if (currentUid == 0) { 4932 // The directory somehow became owned by root. Wow. 4933 // This is probably because the system was stopped while 4934 // installd was in the middle of messing with its libs 4935 // directory. Ask installd to fix that. 4936 int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid, 4937 pkg.applicationInfo.uid); 4938 if (ret >= 0) { 4939 recovered = true; 4940 String msg = "Package " + pkg.packageName 4941 + " unexpectedly changed to uid 0; recovered to " + 4942 + pkg.applicationInfo.uid; 4943 reportSettingsProblem(Log.WARN, msg); 4944 } 4945 } 4946 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 4947 || (scanMode&SCAN_BOOTING) != 0)) { 4948 // If this is a system app, we can at least delete its 4949 // current data so the application will still work. 4950 int ret = removeDataDirsLI(pkgName); 4951 if (ret >= 0) { 4952 // TODO: Kill the processes first 4953 // Old data gone! 4954 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 4955 ? "System package " : "Third party package "; 4956 String msg = prefix + pkg.packageName 4957 + " has changed from uid: " 4958 + currentUid + " to " 4959 + pkg.applicationInfo.uid + "; old data erased"; 4960 reportSettingsProblem(Log.WARN, msg); 4961 recovered = true; 4962 4963 // And now re-install the app. 4964 ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 4965 pkg.applicationInfo.seinfo); 4966 if (ret == -1) { 4967 // Ack should not happen! 4968 msg = prefix + pkg.packageName 4969 + " could not have data directory re-created after delete."; 4970 reportSettingsProblem(Log.WARN, msg); 4971 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4972 return null; 4973 } 4974 } 4975 if (!recovered) { 4976 mHasSystemUidErrors = true; 4977 } 4978 } else if (!recovered) { 4979 // If we allow this install to proceed, we will be broken. 4980 // Abort, abort! 4981 mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED; 4982 return null; 4983 } 4984 if (!recovered) { 4985 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 4986 + pkg.applicationInfo.uid + "/fs_" 4987 + currentUid; 4988 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 4989 String msg = "Package " + pkg.packageName 4990 + " has mismatched uid: " 4991 + currentUid + " on disk, " 4992 + pkg.applicationInfo.uid + " in settings"; 4993 // writer 4994 synchronized (mPackages) { 4995 mSettings.mReadMessages.append(msg); 4996 mSettings.mReadMessages.append('\n'); 4997 uidError = true; 4998 if (!pkgSetting.uidError) { 4999 reportSettingsProblem(Log.ERROR, msg); 5000 } 5001 } 5002 } 5003 } 5004 pkg.applicationInfo.dataDir = dataPath.getPath(); 5005 if (mShouldRestoreconData) { 5006 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 5007 mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo, 5008 pkg.applicationInfo.uid); 5009 } 5010 } else { 5011 if (DEBUG_PACKAGE_SCANNING) { 5012 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5013 Log.v(TAG, "Want this data dir: " + dataPath); 5014 } 5015 //invoke installer to do the actual installation 5016 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 5017 pkg.applicationInfo.seinfo); 5018 if (ret < 0) { 5019 // Error from installer 5020 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5021 return null; 5022 } 5023 5024 if (dataPath.exists()) { 5025 pkg.applicationInfo.dataDir = dataPath.getPath(); 5026 } else { 5027 Slog.w(TAG, "Unable to create data directory: " + dataPath); 5028 pkg.applicationInfo.dataDir = null; 5029 } 5030 } 5031 5032 /* 5033 * Set the data dir to the default "/data/data/<package name>/lib" 5034 * if we got here without anyone telling us different (e.g., apps 5035 * stored on SD card have their native libraries stored in the ASEC 5036 * container with the APK). 5037 * 5038 * This happens during an upgrade from a package settings file that 5039 * doesn't have a native library path attribute at all. 5040 */ 5041 if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) { 5042 if (pkgSetting.nativeLibraryPathString == null) { 5043 setInternalAppNativeLibraryPath(pkg, pkgSetting); 5044 } else { 5045 pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString; 5046 } 5047 } 5048 pkgSetting.uidError = uidError; 5049 } 5050 5051 String path = scanFile.getPath(); 5052 /* Note: We don't want to unpack the native binaries for 5053 * system applications, unless they have been updated 5054 * (the binaries are already under /system/lib). 5055 * Also, don't unpack libs for apps on the external card 5056 * since they should have their libraries in the ASEC 5057 * container already. 5058 * 5059 * In other words, we're going to unpack the binaries 5060 * only for non-system apps and system app upgrades. 5061 */ 5062 if (pkg.applicationInfo.nativeLibraryDir != null) { 5063 try { 5064 File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); 5065 final String dataPathString = dataPath.getCanonicalPath(); 5066 5067 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { 5068 /* 5069 * Upgrading from a previous version of the OS sometimes 5070 * leaves native libraries in the /data/data/<app>/lib 5071 * directory for system apps even when they shouldn't be. 5072 * Recent changes in the JNI library search path 5073 * necessitates we remove those to match previous behavior. 5074 */ 5075 if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) { 5076 Log.i(TAG, "removed obsolete native libraries for system package " 5077 + path); 5078 } 5079 5080 setInternalAppAbi(pkg, pkgSetting); 5081 } else { 5082 if (!isForwardLocked(pkg) && !isExternal(pkg)) { 5083 /* 5084 * Update native library dir if it starts with 5085 * /data/data 5086 */ 5087 if (nativeLibraryDir.getPath().startsWith(dataPathString)) { 5088 setInternalAppNativeLibraryPath(pkg, pkgSetting); 5089 nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); 5090 } 5091 5092 try { 5093 int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir); 5094 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 5095 Slog.e(TAG, "Unable to copy native libraries"); 5096 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 5097 return null; 5098 } 5099 5100 // We've successfully copied native libraries across, so we make a 5101 // note of what ABI we're using 5102 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 5103 pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_ABIS[copyRet]; 5104 } else { 5105 pkg.applicationInfo.requiredCpuAbi = null; 5106 } 5107 } catch (IOException e) { 5108 Slog.e(TAG, "Unable to copy native libraries", e); 5109 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 5110 return null; 5111 } 5112 } else { 5113 // We don't have to copy the shared libraries if we're in the ASEC container 5114 // but we still need to scan the file to figure out what ABI the app needs. 5115 // 5116 // TODO: This duplicates work done in the default container service. It's possible 5117 // to clean this up but we'll need to change the interface between this service 5118 // and IMediaContainerService (but doing so will spread this logic out, rather 5119 // than centralizing it). 5120 final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile); 5121 final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS); 5122 if (abi >= 0) { 5123 pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_ABIS[abi]; 5124 } else if (abi == PackageManager.NO_NATIVE_LIBRARIES) { 5125 // Note that (non upgraded) system apps will not have any native 5126 // libraries bundled in their APK, but we're guaranteed not to be 5127 // such an app at this point. 5128 pkg.applicationInfo.requiredCpuAbi = null; 5129 } else { 5130 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 5131 return null; 5132 } 5133 handle.close(); 5134 } 5135 5136 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 5137 final int[] userIds = sUserManager.getUserIds(); 5138 synchronized (mInstallLock) { 5139 for (int userId : userIds) { 5140 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, 5141 pkg.applicationInfo.nativeLibraryDir, userId) < 0) { 5142 Slog.w(TAG, "Failed linking native library dir (user=" + userId 5143 + ")"); 5144 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 5145 return null; 5146 } 5147 } 5148 } 5149 } 5150 } catch (IOException ioe) { 5151 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 5152 } 5153 } 5154 pkg.mScanPath = path; 5155 5156 if ((scanMode&SCAN_NO_DEX) == 0) { 5157 if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false) 5158 == DEX_OPT_FAILED) { 5159 if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5160 removeDataDirsLI(pkg.packageName); 5161 } 5162 5163 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; 5164 return null; 5165 } 5166 } 5167 5168 if (mFactoryTest && pkg.requestedPermissions.contains( 5169 android.Manifest.permission.FACTORY_TEST)) { 5170 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 5171 } 5172 5173 ArrayList<PackageParser.Package> clientLibPkgs = null; 5174 5175 // writer 5176 synchronized (mPackages) { 5177 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 5178 // Only system apps can add new shared libraries. 5179 if (pkg.libraryNames != null) { 5180 for (int i=0; i<pkg.libraryNames.size(); i++) { 5181 String name = pkg.libraryNames.get(i); 5182 boolean allowed = false; 5183 if (isUpdatedSystemApp(pkg)) { 5184 // New library entries can only be added through the 5185 // system image. This is important to get rid of a lot 5186 // of nasty edge cases: for example if we allowed a non- 5187 // system update of the app to add a library, then uninstalling 5188 // the update would make the library go away, and assumptions 5189 // we made such as through app install filtering would now 5190 // have allowed apps on the device which aren't compatible 5191 // with it. Better to just have the restriction here, be 5192 // conservative, and create many fewer cases that can negatively 5193 // impact the user experience. 5194 final PackageSetting sysPs = mSettings 5195 .getDisabledSystemPkgLPr(pkg.packageName); 5196 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 5197 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 5198 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 5199 allowed = true; 5200 allowed = true; 5201 break; 5202 } 5203 } 5204 } 5205 } else { 5206 allowed = true; 5207 } 5208 if (allowed) { 5209 if (!mSharedLibraries.containsKey(name)) { 5210 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 5211 } else if (!name.equals(pkg.packageName)) { 5212 Slog.w(TAG, "Package " + pkg.packageName + " library " 5213 + name + " already exists; skipping"); 5214 } 5215 } else { 5216 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 5217 + name + " that is not declared on system image; skipping"); 5218 } 5219 } 5220 if ((scanMode&SCAN_BOOTING) == 0) { 5221 // If we are not booting, we need to update any applications 5222 // that are clients of our shared library. If we are booting, 5223 // this will all be done once the scan is complete. 5224 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 5225 } 5226 } 5227 } 5228 } 5229 5230 // We also need to dexopt any apps that are dependent on this library. Note that 5231 // if these fail, we should abort the install since installing the library will 5232 // result in some apps being broken. 5233 if (clientLibPkgs != null) { 5234 if ((scanMode&SCAN_NO_DEX) == 0) { 5235 for (int i=0; i<clientLibPkgs.size(); i++) { 5236 PackageParser.Package clientPkg = clientLibPkgs.get(i); 5237 if (performDexOptLI(clientPkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false) 5238 == DEX_OPT_FAILED) { 5239 if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5240 removeDataDirsLI(pkg.packageName); 5241 } 5242 5243 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; 5244 return null; 5245 } 5246 } 5247 } 5248 } 5249 5250 // Request the ActivityManager to kill the process(only for existing packages) 5251 // so that we do not end up in a confused state while the user is still using the older 5252 // version of the application while the new one gets installed. 5253 if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 5254 // If the package lives in an asec, tell everyone that the container is going 5255 // away so they can clean up any references to its resources (which would prevent 5256 // vold from being able to unmount the asec) 5257 if (isForwardLocked(pkg) || isExternal(pkg)) { 5258 if (DEBUG_INSTALL) { 5259 Slog.i(TAG, "upgrading pkg " + pkg + " is ASEC-hosted -> UNAVAILABLE"); 5260 } 5261 final int[] uidArray = new int[] { pkg.applicationInfo.uid }; 5262 final ArrayList<String> pkgList = new ArrayList<String>(1); 5263 pkgList.add(pkg.applicationInfo.packageName); 5264 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 5265 } 5266 5267 // Post the request that it be killed now that the going-away broadcast is en route 5268 killApplication(pkg.applicationInfo.packageName, 5269 pkg.applicationInfo.uid, "update pkg"); 5270 } 5271 5272 // Also need to kill any apps that are dependent on the library. 5273 if (clientLibPkgs != null) { 5274 for (int i=0; i<clientLibPkgs.size(); i++) { 5275 PackageParser.Package clientPkg = clientLibPkgs.get(i); 5276 killApplication(clientPkg.applicationInfo.packageName, 5277 clientPkg.applicationInfo.uid, "update lib"); 5278 } 5279 } 5280 5281 // writer 5282 synchronized (mPackages) { 5283 if ((scanMode&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 5284 // We don't do this here during boot because we can do it all 5285 // at once after scanning all existing packages. 5286 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 5287 true, forceDex, (scanMode & SCAN_DEFER_DEX) != 0); 5288 } 5289 // We don't expect installation to fail beyond this point, 5290 if ((scanMode&SCAN_MONITOR) != 0) { 5291 mAppDirs.put(pkg.mPath, pkg); 5292 } 5293 // Add the new setting to mSettings 5294 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 5295 // Add the new setting to mPackages 5296 mPackages.put(pkg.applicationInfo.packageName, pkg); 5297 // Make sure we don't accidentally delete its data. 5298 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 5299 while (iter.hasNext()) { 5300 PackageCleanItem item = iter.next(); 5301 if (pkgName.equals(item.packageName)) { 5302 iter.remove(); 5303 } 5304 } 5305 5306 // Take care of first install / last update times. 5307 if (currentTime != 0) { 5308 if (pkgSetting.firstInstallTime == 0) { 5309 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 5310 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) { 5311 pkgSetting.lastUpdateTime = currentTime; 5312 } 5313 } else if (pkgSetting.firstInstallTime == 0) { 5314 // We need *something*. Take time time stamp of the file. 5315 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 5316 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 5317 if (scanFileTime != pkgSetting.timeStamp) { 5318 // A package on the system image has changed; consider this 5319 // to be an update. 5320 pkgSetting.lastUpdateTime = scanFileTime; 5321 } 5322 } 5323 5324 // Add the package's KeySets to the global KeySetManager 5325 KeySetManager ksm = mSettings.mKeySetManager; 5326 try { 5327 ksm.addSigningKeySetToPackage(pkg.packageName, pkg.mSigningKeys); 5328 if (pkg.mKeySetMapping != null) { 5329 for (Map.Entry<String, Set<PublicKey>> entry : pkg.mKeySetMapping.entrySet()) { 5330 if (entry.getValue() != null) { 5331 ksm.addDefinedKeySetToPackage(pkg.packageName, 5332 entry.getValue(), entry.getKey()); 5333 } 5334 } 5335 } 5336 } catch (NullPointerException e) { 5337 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e); 5338 } catch (IllegalArgumentException e) { 5339 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e); 5340 } 5341 5342 int N = pkg.providers.size(); 5343 StringBuilder r = null; 5344 int i; 5345 for (i=0; i<N; i++) { 5346 PackageParser.Provider p = pkg.providers.get(i); 5347 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 5348 p.info.processName, pkg.applicationInfo.uid); 5349 mProviders.addProvider(p); 5350 p.syncable = p.info.isSyncable; 5351 if (p.info.authority != null) { 5352 String names[] = p.info.authority.split(";"); 5353 p.info.authority = null; 5354 for (int j = 0; j < names.length; j++) { 5355 if (j == 1 && p.syncable) { 5356 // We only want the first authority for a provider to possibly be 5357 // syncable, so if we already added this provider using a different 5358 // authority clear the syncable flag. We copy the provider before 5359 // changing it because the mProviders object contains a reference 5360 // to a provider that we don't want to change. 5361 // Only do this for the second authority since the resulting provider 5362 // object can be the same for all future authorities for this provider. 5363 p = new PackageParser.Provider(p); 5364 p.syncable = false; 5365 } 5366 if (!mProvidersByAuthority.containsKey(names[j])) { 5367 mProvidersByAuthority.put(names[j], p); 5368 if (p.info.authority == null) { 5369 p.info.authority = names[j]; 5370 } else { 5371 p.info.authority = p.info.authority + ";" + names[j]; 5372 } 5373 if (DEBUG_PACKAGE_SCANNING) { 5374 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5375 Log.d(TAG, "Registered content provider: " + names[j] 5376 + ", className = " + p.info.name + ", isSyncable = " 5377 + p.info.isSyncable); 5378 } 5379 } else { 5380 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 5381 Slog.w(TAG, "Skipping provider name " + names[j] + 5382 " (in package " + pkg.applicationInfo.packageName + 5383 "): name already used by " 5384 + ((other != null && other.getComponentName() != null) 5385 ? other.getComponentName().getPackageName() : "?")); 5386 } 5387 } 5388 } 5389 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5390 if (r == null) { 5391 r = new StringBuilder(256); 5392 } else { 5393 r.append(' '); 5394 } 5395 r.append(p.info.name); 5396 } 5397 } 5398 if (r != null) { 5399 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 5400 } 5401 5402 N = pkg.services.size(); 5403 r = null; 5404 for (i=0; i<N; i++) { 5405 PackageParser.Service s = pkg.services.get(i); 5406 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 5407 s.info.processName, pkg.applicationInfo.uid); 5408 mServices.addService(s); 5409 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5410 if (r == null) { 5411 r = new StringBuilder(256); 5412 } else { 5413 r.append(' '); 5414 } 5415 r.append(s.info.name); 5416 } 5417 } 5418 if (r != null) { 5419 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 5420 } 5421 5422 N = pkg.receivers.size(); 5423 r = null; 5424 for (i=0; i<N; i++) { 5425 PackageParser.Activity a = pkg.receivers.get(i); 5426 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 5427 a.info.processName, pkg.applicationInfo.uid); 5428 mReceivers.addActivity(a, "receiver"); 5429 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5430 if (r == null) { 5431 r = new StringBuilder(256); 5432 } else { 5433 r.append(' '); 5434 } 5435 r.append(a.info.name); 5436 } 5437 } 5438 if (r != null) { 5439 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 5440 } 5441 5442 N = pkg.activities.size(); 5443 r = null; 5444 for (i=0; i<N; i++) { 5445 PackageParser.Activity a = pkg.activities.get(i); 5446 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 5447 a.info.processName, pkg.applicationInfo.uid); 5448 mActivities.addActivity(a, "activity"); 5449 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5450 if (r == null) { 5451 r = new StringBuilder(256); 5452 } else { 5453 r.append(' '); 5454 } 5455 r.append(a.info.name); 5456 } 5457 } 5458 if (r != null) { 5459 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 5460 } 5461 5462 N = pkg.permissionGroups.size(); 5463 r = null; 5464 for (i=0; i<N; i++) { 5465 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 5466 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 5467 if (cur == null) { 5468 mPermissionGroups.put(pg.info.name, pg); 5469 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5470 if (r == null) { 5471 r = new StringBuilder(256); 5472 } else { 5473 r.append(' '); 5474 } 5475 r.append(pg.info.name); 5476 } 5477 } else { 5478 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 5479 + pg.info.packageName + " ignored: original from " 5480 + cur.info.packageName); 5481 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5482 if (r == null) { 5483 r = new StringBuilder(256); 5484 } else { 5485 r.append(' '); 5486 } 5487 r.append("DUP:"); 5488 r.append(pg.info.name); 5489 } 5490 } 5491 } 5492 if (r != null) { 5493 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 5494 } 5495 5496 N = pkg.permissions.size(); 5497 r = null; 5498 for (i=0; i<N; i++) { 5499 PackageParser.Permission p = pkg.permissions.get(i); 5500 HashMap<String, BasePermission> permissionMap = 5501 p.tree ? mSettings.mPermissionTrees 5502 : mSettings.mPermissions; 5503 p.group = mPermissionGroups.get(p.info.group); 5504 if (p.info.group == null || p.group != null) { 5505 BasePermission bp = permissionMap.get(p.info.name); 5506 if (bp == null) { 5507 bp = new BasePermission(p.info.name, p.info.packageName, 5508 BasePermission.TYPE_NORMAL); 5509 permissionMap.put(p.info.name, bp); 5510 } 5511 if (bp.perm == null) { 5512 if (bp.sourcePackage != null 5513 && !bp.sourcePackage.equals(p.info.packageName)) { 5514 // If this is a permission that was formerly defined by a non-system 5515 // app, but is now defined by a system app (following an upgrade), 5516 // discard the previous declaration and consider the system's to be 5517 // canonical. 5518 if (isSystemApp(p.owner)) { 5519 Slog.i(TAG, "New decl " + p.owner + " of permission " 5520 + p.info.name + " is system"); 5521 bp.sourcePackage = null; 5522 } 5523 } 5524 if (bp.sourcePackage == null 5525 || bp.sourcePackage.equals(p.info.packageName)) { 5526 BasePermission tree = findPermissionTreeLP(p.info.name); 5527 if (tree == null 5528 || tree.sourcePackage.equals(p.info.packageName)) { 5529 bp.packageSetting = pkgSetting; 5530 bp.perm = p; 5531 bp.uid = pkg.applicationInfo.uid; 5532 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5533 if (r == null) { 5534 r = new StringBuilder(256); 5535 } else { 5536 r.append(' '); 5537 } 5538 r.append(p.info.name); 5539 } 5540 } else { 5541 Slog.w(TAG, "Permission " + p.info.name + " from package " 5542 + p.info.packageName + " ignored: base tree " 5543 + tree.name + " is from package " 5544 + tree.sourcePackage); 5545 } 5546 } else { 5547 Slog.w(TAG, "Permission " + p.info.name + " from package " 5548 + p.info.packageName + " ignored: original from " 5549 + bp.sourcePackage); 5550 } 5551 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5552 if (r == null) { 5553 r = new StringBuilder(256); 5554 } else { 5555 r.append(' '); 5556 } 5557 r.append("DUP:"); 5558 r.append(p.info.name); 5559 } 5560 if (bp.perm == p) { 5561 bp.protectionLevel = p.info.protectionLevel; 5562 } 5563 } else { 5564 Slog.w(TAG, "Permission " + p.info.name + " from package " 5565 + p.info.packageName + " ignored: no group " 5566 + p.group); 5567 } 5568 } 5569 if (r != null) { 5570 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 5571 } 5572 5573 N = pkg.instrumentation.size(); 5574 r = null; 5575 for (i=0; i<N; i++) { 5576 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 5577 a.info.packageName = pkg.applicationInfo.packageName; 5578 a.info.sourceDir = pkg.applicationInfo.sourceDir; 5579 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 5580 a.info.dataDir = pkg.applicationInfo.dataDir; 5581 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 5582 mInstrumentation.put(a.getComponentName(), a); 5583 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5584 if (r == null) { 5585 r = new StringBuilder(256); 5586 } else { 5587 r.append(' '); 5588 } 5589 r.append(a.info.name); 5590 } 5591 } 5592 if (r != null) { 5593 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 5594 } 5595 5596 if (pkg.protectedBroadcasts != null) { 5597 N = pkg.protectedBroadcasts.size(); 5598 for (i=0; i<N; i++) { 5599 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 5600 } 5601 } 5602 5603 pkgSetting.setTimeStamp(scanFileTime); 5604 5605 // Create idmap files for pairs of (packages, overlay packages). 5606 // Note: "android", ie framework-res.apk, is handled by native layers. 5607 if (pkg.mOverlayTarget != null) { 5608 // This is an overlay package. 5609 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 5610 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 5611 mOverlays.put(pkg.mOverlayTarget, 5612 new HashMap<String, PackageParser.Package>()); 5613 } 5614 HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 5615 map.put(pkg.packageName, pkg); 5616 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 5617 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 5618 mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 5619 return null; 5620 } 5621 } 5622 } else if (mOverlays.containsKey(pkg.packageName) && 5623 !pkg.packageName.equals("android")) { 5624 // This is a regular package, with one or more known overlay packages. 5625 createIdmapsForPackageLI(pkg); 5626 } 5627 } 5628 5629 return pkg; 5630 } 5631 5632 public void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 5633 boolean doDexOpt, boolean forceDexOpt, boolean deferDexOpt) { 5634 String requiredInstructionSet = null; 5635 PackageSetting requirer = null; 5636 for (PackageSetting ps : packagesForUser) { 5637 if (ps.requiredCpuAbiString != null) { 5638 final String instructionSet = VMRuntime.getInstructionSet(ps.requiredCpuAbiString); 5639 if (requiredInstructionSet != null) { 5640 if (!instructionSet.equals(requiredInstructionSet)) { 5641 // We have a mismatch between instruction sets (say arm vs arm64). 5642 // 5643 // TODO: We should rescan all the packages in a shared UID to check if 5644 // they do contain shared libs for other ABIs in addition to the ones we've 5645 // already extracted. For example, the package might contain both arm64-v8a 5646 // and armeabi-v7a shared libs, and we'd have chosen arm64-v8a on 64 bit 5647 // devices. 5648 String errorMessage = "Instruction set mismatch, " + requirer.pkg.packageName 5649 + " requires " + requiredInstructionSet + " whereas " + ps.pkg.packageName 5650 + " requires " + instructionSet; 5651 Slog.e(TAG, errorMessage); 5652 5653 reportSettingsProblem(Log.WARN, errorMessage); 5654 // Give up, don't bother making any other changes to the package settings. 5655 return; 5656 } 5657 } else { 5658 requiredInstructionSet = instructionSet; 5659 requirer = ps; 5660 } 5661 } 5662 } 5663 5664 if (requiredInstructionSet != null) { 5665 for (PackageSetting ps : packagesForUser) { 5666 if (ps.requiredCpuAbiString == null) { 5667 ps.requiredCpuAbiString = requirer.requiredCpuAbiString; 5668 if (ps.pkg != null) { 5669 ps.pkg.applicationInfo.requiredCpuAbi = requirer.requiredCpuAbiString; 5670 Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + ps.requiredCpuAbiString); 5671 if (doDexOpt) { 5672 performDexOptLI(ps.pkg, forceDexOpt, deferDexOpt, true); 5673 mInstaller.rmdex(ps.codePathString, getPreferredInstructionSet()); 5674 } 5675 } 5676 } 5677 } 5678 } 5679 } 5680 5681 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 5682 synchronized (mPackages) { 5683 mResolverReplaced = true; 5684 // Set up information for custom user intent resolution activity. 5685 mResolveActivity.applicationInfo = pkg.applicationInfo; 5686 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 5687 mResolveActivity.packageName = pkg.applicationInfo.packageName; 5688 mResolveActivity.processName = null; 5689 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 5690 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 5691 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 5692 mResolveActivity.theme = 0; 5693 mResolveActivity.exported = true; 5694 mResolveActivity.enabled = true; 5695 mResolveInfo.activityInfo = mResolveActivity; 5696 mResolveInfo.priority = 0; 5697 mResolveInfo.preferredOrder = 0; 5698 mResolveInfo.match = 0; 5699 mResolveComponentName = mCustomResolverComponentName; 5700 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 5701 mResolveComponentName); 5702 } 5703 } 5704 5705 private String calculateApkRoot(final String codePathString) { 5706 final File codePath = new File(codePathString); 5707 final File codeRoot; 5708 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 5709 codeRoot = Environment.getRootDirectory(); 5710 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 5711 codeRoot = Environment.getOemDirectory(); 5712 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 5713 codeRoot = Environment.getVendorDirectory(); 5714 } else { 5715 // Unrecognized code path; take its top real segment as the apk root: 5716 // e.g. /something/app/blah.apk => /something 5717 try { 5718 File f = codePath.getCanonicalFile(); 5719 File parent = f.getParentFile(); // non-null because codePath is a file 5720 File tmp; 5721 while ((tmp = parent.getParentFile()) != null) { 5722 f = parent; 5723 parent = tmp; 5724 } 5725 codeRoot = f; 5726 Slog.w(TAG, "Unrecognized code path " 5727 + codePath + " - using " + codeRoot); 5728 } catch (IOException e) { 5729 // Can't canonicalize the lib path -- shenanigans? 5730 Slog.w(TAG, "Can't canonicalize code path " + codePath); 5731 return Environment.getRootDirectory().getPath(); 5732 } 5733 } 5734 return codeRoot.getPath(); 5735 } 5736 5737 // This is the initial scan-time determination of how to handle a given 5738 // package for purposes of native library location. 5739 private void setInternalAppNativeLibraryPath(PackageParser.Package pkg, 5740 PackageSetting pkgSetting) { 5741 // "bundled" here means system-installed with no overriding update 5742 final boolean bundledApk = isSystemApp(pkg) && !isUpdatedSystemApp(pkg); 5743 final String apkName = getApkName(pkg.applicationInfo.sourceDir); 5744 final File libDir; 5745 if (bundledApk) { 5746 // If "/system/lib64/apkname" exists, assume that is the per-package 5747 // native library directory to use; otherwise use "/system/lib/apkname". 5748 String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir); 5749 File lib64 = new File(apkRoot, LIB64_DIR_NAME); 5750 File packLib64 = new File(lib64, apkName); 5751 libDir = (packLib64.exists()) ? lib64 : new File(apkRoot, LIB_DIR_NAME); 5752 } else { 5753 libDir = mAppLibInstallDir; 5754 } 5755 final String nativeLibraryPath = (new File(libDir, apkName)).getPath(); 5756 pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath; 5757 pkgSetting.nativeLibraryPathString = nativeLibraryPath; 5758 } 5759 5760 // Deduces the required ABI of an upgraded system app. 5761 private void setInternalAppAbi(PackageParser.Package pkg, PackageSetting pkgSetting) { 5762 final String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir); 5763 final String apkName = getApkName(pkg.applicationInfo.sourceDir); 5764 5765 // This is of the form "/system/lib64/<packagename>", "/vendor/lib64/<packagename>" 5766 // or similar. 5767 final File lib64 = new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath()); 5768 final File lib = new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath()); 5769 5770 // Assume that the bundled native libraries always correspond to the 5771 // most preferred 32 or 64 bit ABI. 5772 if (lib64.exists()) { 5773 pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 5774 pkgSetting.requiredCpuAbiString = Build.SUPPORTED_64_BIT_ABIS[0]; 5775 } else if (lib.exists()) { 5776 pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 5777 pkgSetting.requiredCpuAbiString = Build.SUPPORTED_32_BIT_ABIS[0]; 5778 } else { 5779 // This is the case where the app has no native code. 5780 pkg.applicationInfo.requiredCpuAbi = null; 5781 pkgSetting.requiredCpuAbiString = null; 5782 } 5783 } 5784 5785 private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir) 5786 throws IOException { 5787 if (!nativeLibraryDir.isDirectory()) { 5788 nativeLibraryDir.delete(); 5789 5790 if (!nativeLibraryDir.mkdir()) { 5791 throw new IOException("Cannot create " + nativeLibraryDir.getPath()); 5792 } 5793 5794 try { 5795 Os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 5796 } catch (ErrnoException e) { 5797 throw new IOException("Cannot chmod native library directory " 5798 + nativeLibraryDir.getPath(), e); 5799 } 5800 } else if (!SELinux.restorecon(nativeLibraryDir)) { 5801 throw new IOException("Cannot set SELinux context for " + nativeLibraryDir.getPath()); 5802 } 5803 5804 /* 5805 * If this is an internal application or our nativeLibraryPath points to 5806 * the app-lib directory, unpack the libraries if necessary. 5807 */ 5808 final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile); 5809 try { 5810 int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS); 5811 if (abi >= 0) { 5812 int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, 5813 nativeLibraryDir, Build.SUPPORTED_ABIS[abi]); 5814 if (copyRet != PackageManager.INSTALL_SUCCEEDED) { 5815 return copyRet; 5816 } 5817 } 5818 5819 return abi; 5820 } finally { 5821 handle.close(); 5822 } 5823 } 5824 5825 private void killApplication(String pkgName, int appId, String reason) { 5826 // Request the ActivityManager to kill the process(only for existing packages) 5827 // so that we do not end up in a confused state while the user is still using the older 5828 // version of the application while the new one gets installed. 5829 IActivityManager am = ActivityManagerNative.getDefault(); 5830 if (am != null) { 5831 try { 5832 am.killApplicationWithAppId(pkgName, appId, reason); 5833 } catch (RemoteException e) { 5834 } 5835 } 5836 } 5837 5838 void removePackageLI(PackageSetting ps, boolean chatty) { 5839 if (DEBUG_INSTALL) { 5840 if (chatty) 5841 Log.d(TAG, "Removing package " + ps.name); 5842 } 5843 5844 // writer 5845 synchronized (mPackages) { 5846 mPackages.remove(ps.name); 5847 if (ps.codePathString != null) { 5848 mAppDirs.remove(ps.codePathString); 5849 } 5850 5851 final PackageParser.Package pkg = ps.pkg; 5852 if (pkg != null) { 5853 cleanPackageDataStructuresLILPw(pkg, chatty); 5854 } 5855 } 5856 } 5857 5858 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 5859 if (DEBUG_INSTALL) { 5860 if (chatty) 5861 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 5862 } 5863 5864 // writer 5865 synchronized (mPackages) { 5866 mPackages.remove(pkg.applicationInfo.packageName); 5867 if (pkg.mPath != null) { 5868 mAppDirs.remove(pkg.mPath); 5869 } 5870 cleanPackageDataStructuresLILPw(pkg, chatty); 5871 } 5872 } 5873 5874 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 5875 int N = pkg.providers.size(); 5876 StringBuilder r = null; 5877 int i; 5878 for (i=0; i<N; i++) { 5879 PackageParser.Provider p = pkg.providers.get(i); 5880 mProviders.removeProvider(p); 5881 if (p.info.authority == null) { 5882 5883 /* There was another ContentProvider with this authority when 5884 * this app was installed so this authority is null, 5885 * Ignore it as we don't have to unregister the provider. 5886 */ 5887 continue; 5888 } 5889 String names[] = p.info.authority.split(";"); 5890 for (int j = 0; j < names.length; j++) { 5891 if (mProvidersByAuthority.get(names[j]) == p) { 5892 mProvidersByAuthority.remove(names[j]); 5893 if (DEBUG_REMOVE) { 5894 if (chatty) 5895 Log.d(TAG, "Unregistered content provider: " + names[j] 5896 + ", className = " + p.info.name + ", isSyncable = " 5897 + p.info.isSyncable); 5898 } 5899 } 5900 } 5901 if (DEBUG_REMOVE && chatty) { 5902 if (r == null) { 5903 r = new StringBuilder(256); 5904 } else { 5905 r.append(' '); 5906 } 5907 r.append(p.info.name); 5908 } 5909 } 5910 if (r != null) { 5911 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 5912 } 5913 5914 N = pkg.services.size(); 5915 r = null; 5916 for (i=0; i<N; i++) { 5917 PackageParser.Service s = pkg.services.get(i); 5918 mServices.removeService(s); 5919 if (chatty) { 5920 if (r == null) { 5921 r = new StringBuilder(256); 5922 } else { 5923 r.append(' '); 5924 } 5925 r.append(s.info.name); 5926 } 5927 } 5928 if (r != null) { 5929 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 5930 } 5931 5932 N = pkg.receivers.size(); 5933 r = null; 5934 for (i=0; i<N; i++) { 5935 PackageParser.Activity a = pkg.receivers.get(i); 5936 mReceivers.removeActivity(a, "receiver"); 5937 if (DEBUG_REMOVE && chatty) { 5938 if (r == null) { 5939 r = new StringBuilder(256); 5940 } else { 5941 r.append(' '); 5942 } 5943 r.append(a.info.name); 5944 } 5945 } 5946 if (r != null) { 5947 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 5948 } 5949 5950 N = pkg.activities.size(); 5951 r = null; 5952 for (i=0; i<N; i++) { 5953 PackageParser.Activity a = pkg.activities.get(i); 5954 mActivities.removeActivity(a, "activity"); 5955 if (DEBUG_REMOVE && chatty) { 5956 if (r == null) { 5957 r = new StringBuilder(256); 5958 } else { 5959 r.append(' '); 5960 } 5961 r.append(a.info.name); 5962 } 5963 } 5964 if (r != null) { 5965 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 5966 } 5967 5968 N = pkg.permissions.size(); 5969 r = null; 5970 for (i=0; i<N; i++) { 5971 PackageParser.Permission p = pkg.permissions.get(i); 5972 BasePermission bp = mSettings.mPermissions.get(p.info.name); 5973 if (bp == null) { 5974 bp = mSettings.mPermissionTrees.get(p.info.name); 5975 } 5976 if (bp != null && bp.perm == p) { 5977 bp.perm = null; 5978 if (DEBUG_REMOVE && chatty) { 5979 if (r == null) { 5980 r = new StringBuilder(256); 5981 } else { 5982 r.append(' '); 5983 } 5984 r.append(p.info.name); 5985 } 5986 } 5987 } 5988 if (r != null) { 5989 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 5990 } 5991 5992 N = pkg.instrumentation.size(); 5993 r = null; 5994 for (i=0; i<N; i++) { 5995 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 5996 mInstrumentation.remove(a.getComponentName()); 5997 if (DEBUG_REMOVE && chatty) { 5998 if (r == null) { 5999 r = new StringBuilder(256); 6000 } else { 6001 r.append(' '); 6002 } 6003 r.append(a.info.name); 6004 } 6005 } 6006 if (r != null) { 6007 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 6008 } 6009 6010 r = null; 6011 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 6012 // Only system apps can hold shared libraries. 6013 if (pkg.libraryNames != null) { 6014 for (i=0; i<pkg.libraryNames.size(); i++) { 6015 String name = pkg.libraryNames.get(i); 6016 SharedLibraryEntry cur = mSharedLibraries.get(name); 6017 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 6018 mSharedLibraries.remove(name); 6019 if (DEBUG_REMOVE && chatty) { 6020 if (r == null) { 6021 r = new StringBuilder(256); 6022 } else { 6023 r.append(' '); 6024 } 6025 r.append(name); 6026 } 6027 } 6028 } 6029 } 6030 } 6031 if (r != null) { 6032 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 6033 } 6034 } 6035 6036 private static final boolean isPackageFilename(String name) { 6037 return name != null && name.endsWith(".apk"); 6038 } 6039 6040 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 6041 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 6042 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 6043 return true; 6044 } 6045 } 6046 return false; 6047 } 6048 6049 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 6050 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 6051 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 6052 6053 private void updatePermissionsLPw(String changingPkg, 6054 PackageParser.Package pkgInfo, int flags) { 6055 // Make sure there are no dangling permission trees. 6056 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 6057 while (it.hasNext()) { 6058 final BasePermission bp = it.next(); 6059 if (bp.packageSetting == null) { 6060 // We may not yet have parsed the package, so just see if 6061 // we still know about its settings. 6062 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 6063 } 6064 if (bp.packageSetting == null) { 6065 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 6066 + " from package " + bp.sourcePackage); 6067 it.remove(); 6068 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 6069 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 6070 Slog.i(TAG, "Removing old permission tree: " + bp.name 6071 + " from package " + bp.sourcePackage); 6072 flags |= UPDATE_PERMISSIONS_ALL; 6073 it.remove(); 6074 } 6075 } 6076 } 6077 6078 // Make sure all dynamic permissions have been assigned to a package, 6079 // and make sure there are no dangling permissions. 6080 it = mSettings.mPermissions.values().iterator(); 6081 while (it.hasNext()) { 6082 final BasePermission bp = it.next(); 6083 if (bp.type == BasePermission.TYPE_DYNAMIC) { 6084 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 6085 + bp.name + " pkg=" + bp.sourcePackage 6086 + " info=" + bp.pendingInfo); 6087 if (bp.packageSetting == null && bp.pendingInfo != null) { 6088 final BasePermission tree = findPermissionTreeLP(bp.name); 6089 if (tree != null && tree.perm != null) { 6090 bp.packageSetting = tree.packageSetting; 6091 bp.perm = new PackageParser.Permission(tree.perm.owner, 6092 new PermissionInfo(bp.pendingInfo)); 6093 bp.perm.info.packageName = tree.perm.info.packageName; 6094 bp.perm.info.name = bp.name; 6095 bp.uid = tree.uid; 6096 } 6097 } 6098 } 6099 if (bp.packageSetting == null) { 6100 // We may not yet have parsed the package, so just see if 6101 // we still know about its settings. 6102 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 6103 } 6104 if (bp.packageSetting == null) { 6105 Slog.w(TAG, "Removing dangling permission: " + bp.name 6106 + " from package " + bp.sourcePackage); 6107 it.remove(); 6108 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 6109 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 6110 Slog.i(TAG, "Removing old permission: " + bp.name 6111 + " from package " + bp.sourcePackage); 6112 flags |= UPDATE_PERMISSIONS_ALL; 6113 it.remove(); 6114 } 6115 } 6116 } 6117 6118 // Now update the permissions for all packages, in particular 6119 // replace the granted permissions of the system packages. 6120 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 6121 for (PackageParser.Package pkg : mPackages.values()) { 6122 if (pkg != pkgInfo) { 6123 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0); 6124 } 6125 } 6126 } 6127 6128 if (pkgInfo != null) { 6129 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0); 6130 } 6131 } 6132 6133 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) { 6134 final PackageSetting ps = (PackageSetting) pkg.mExtras; 6135 if (ps == null) { 6136 return; 6137 } 6138 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 6139 HashSet<String> origPermissions = gp.grantedPermissions; 6140 boolean changedPermission = false; 6141 6142 if (replace) { 6143 ps.permissionsFixed = false; 6144 if (gp == ps) { 6145 origPermissions = new HashSet<String>(gp.grantedPermissions); 6146 gp.grantedPermissions.clear(); 6147 gp.gids = mGlobalGids; 6148 } 6149 } 6150 6151 if (gp.gids == null) { 6152 gp.gids = mGlobalGids; 6153 } 6154 6155 final int N = pkg.requestedPermissions.size(); 6156 for (int i=0; i<N; i++) { 6157 final String name = pkg.requestedPermissions.get(i); 6158 final boolean required = pkg.requestedPermissionsRequired.get(i); 6159 final BasePermission bp = mSettings.mPermissions.get(name); 6160 if (DEBUG_INSTALL) { 6161 if (gp != ps) { 6162 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 6163 } 6164 } 6165 6166 if (bp == null || bp.packageSetting == null) { 6167 Slog.w(TAG, "Unknown permission " + name 6168 + " in package " + pkg.packageName); 6169 continue; 6170 } 6171 6172 final String perm = bp.name; 6173 boolean allowed; 6174 boolean allowedSig = false; 6175 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 6176 if (level == PermissionInfo.PROTECTION_NORMAL 6177 || level == PermissionInfo.PROTECTION_DANGEROUS) { 6178 // We grant a normal or dangerous permission if any of the following 6179 // are true: 6180 // 1) The permission is required 6181 // 2) The permission is optional, but was granted in the past 6182 // 3) The permission is optional, but was requested by an 6183 // app in /system (not /data) 6184 // 6185 // Otherwise, reject the permission. 6186 allowed = (required || origPermissions.contains(perm) 6187 || (isSystemApp(ps) && !isUpdatedSystemApp(ps))); 6188 } else if (bp.packageSetting == null) { 6189 // This permission is invalid; skip it. 6190 allowed = false; 6191 } else if (level == PermissionInfo.PROTECTION_SIGNATURE) { 6192 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions); 6193 if (allowed) { 6194 allowedSig = true; 6195 } 6196 } else { 6197 allowed = false; 6198 } 6199 if (DEBUG_INSTALL) { 6200 if (gp != ps) { 6201 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 6202 } 6203 } 6204 if (allowed) { 6205 if (!isSystemApp(ps) && ps.permissionsFixed) { 6206 // If this is an existing, non-system package, then 6207 // we can't add any new permissions to it. 6208 if (!allowedSig && !gp.grantedPermissions.contains(perm)) { 6209 // Except... if this is a permission that was added 6210 // to the platform (note: need to only do this when 6211 // updating the platform). 6212 allowed = isNewPlatformPermissionForPackage(perm, pkg); 6213 } 6214 } 6215 if (allowed) { 6216 if (!gp.grantedPermissions.contains(perm)) { 6217 changedPermission = true; 6218 gp.grantedPermissions.add(perm); 6219 gp.gids = appendInts(gp.gids, bp.gids); 6220 } else if (!ps.haveGids) { 6221 gp.gids = appendInts(gp.gids, bp.gids); 6222 } 6223 } else { 6224 Slog.w(TAG, "Not granting permission " + perm 6225 + " to package " + pkg.packageName 6226 + " because it was previously installed without"); 6227 } 6228 } else { 6229 if (gp.grantedPermissions.remove(perm)) { 6230 changedPermission = true; 6231 gp.gids = removeInts(gp.gids, bp.gids); 6232 Slog.i(TAG, "Un-granting permission " + perm 6233 + " from package " + pkg.packageName 6234 + " (protectionLevel=" + bp.protectionLevel 6235 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 6236 + ")"); 6237 } else { 6238 Slog.w(TAG, "Not granting permission " + perm 6239 + " to package " + pkg.packageName 6240 + " (protectionLevel=" + bp.protectionLevel 6241 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 6242 + ")"); 6243 } 6244 } 6245 } 6246 6247 if ((changedPermission || replace) && !ps.permissionsFixed && 6248 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 6249 // This is the first that we have heard about this package, so the 6250 // permissions we have now selected are fixed until explicitly 6251 // changed. 6252 ps.permissionsFixed = true; 6253 } 6254 ps.haveGids = true; 6255 } 6256 6257 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 6258 boolean allowed = false; 6259 final int NP = PackageParser.NEW_PERMISSIONS.length; 6260 for (int ip=0; ip<NP; ip++) { 6261 final PackageParser.NewPermissionInfo npi 6262 = PackageParser.NEW_PERMISSIONS[ip]; 6263 if (npi.name.equals(perm) 6264 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 6265 allowed = true; 6266 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 6267 + pkg.packageName); 6268 break; 6269 } 6270 } 6271 return allowed; 6272 } 6273 6274 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 6275 BasePermission bp, HashSet<String> origPermissions) { 6276 boolean allowed; 6277 allowed = (compareSignatures( 6278 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 6279 == PackageManager.SIGNATURE_MATCH) 6280 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 6281 == PackageManager.SIGNATURE_MATCH); 6282 if (!allowed && (bp.protectionLevel 6283 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) { 6284 if (isSystemApp(pkg)) { 6285 // For updated system applications, a system permission 6286 // is granted only if it had been defined by the original application. 6287 if (isUpdatedSystemApp(pkg)) { 6288 final PackageSetting sysPs = mSettings 6289 .getDisabledSystemPkgLPr(pkg.packageName); 6290 final GrantedPermissions origGp = sysPs.sharedUser != null 6291 ? sysPs.sharedUser : sysPs; 6292 6293 if (origGp.grantedPermissions.contains(perm)) { 6294 // If the original was granted this permission, we take 6295 // that grant decision as read and propagate it to the 6296 // update. 6297 allowed = true; 6298 } else { 6299 // The system apk may have been updated with an older 6300 // version of the one on the data partition, but which 6301 // granted a new system permission that it didn't have 6302 // before. In this case we do want to allow the app to 6303 // now get the new permission if the ancestral apk is 6304 // privileged to get it. 6305 if (sysPs.pkg != null && sysPs.isPrivileged()) { 6306 for (int j=0; 6307 j<sysPs.pkg.requestedPermissions.size(); j++) { 6308 if (perm.equals( 6309 sysPs.pkg.requestedPermissions.get(j))) { 6310 allowed = true; 6311 break; 6312 } 6313 } 6314 } 6315 } 6316 } else { 6317 allowed = isPrivilegedApp(pkg); 6318 } 6319 } 6320 } 6321 if (!allowed && (bp.protectionLevel 6322 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 6323 // For development permissions, a development permission 6324 // is granted only if it was already granted. 6325 allowed = origPermissions.contains(perm); 6326 } 6327 return allowed; 6328 } 6329 6330 final class ActivityIntentResolver 6331 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 6332 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 6333 boolean defaultOnly, int userId) { 6334 if (!sUserManager.exists(userId)) return null; 6335 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 6336 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 6337 } 6338 6339 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 6340 int userId) { 6341 if (!sUserManager.exists(userId)) return null; 6342 mFlags = flags; 6343 return super.queryIntent(intent, resolvedType, 6344 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 6345 } 6346 6347 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 6348 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 6349 if (!sUserManager.exists(userId)) return null; 6350 if (packageActivities == null) { 6351 return null; 6352 } 6353 mFlags = flags; 6354 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 6355 final int N = packageActivities.size(); 6356 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 6357 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 6358 6359 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 6360 for (int i = 0; i < N; ++i) { 6361 intentFilters = packageActivities.get(i).intents; 6362 if (intentFilters != null && intentFilters.size() > 0) { 6363 PackageParser.ActivityIntentInfo[] array = 6364 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 6365 intentFilters.toArray(array); 6366 listCut.add(array); 6367 } 6368 } 6369 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 6370 } 6371 6372 public final void addActivity(PackageParser.Activity a, String type) { 6373 final boolean systemApp = isSystemApp(a.info.applicationInfo); 6374 mActivities.put(a.getComponentName(), a); 6375 if (DEBUG_SHOW_INFO) 6376 Log.v( 6377 TAG, " " + type + " " + 6378 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 6379 if (DEBUG_SHOW_INFO) 6380 Log.v(TAG, " Class=" + a.info.name); 6381 final int NI = a.intents.size(); 6382 for (int j=0; j<NI; j++) { 6383 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 6384 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 6385 intent.setPriority(0); 6386 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 6387 + a.className + " with priority > 0, forcing to 0"); 6388 } 6389 if (DEBUG_SHOW_INFO) { 6390 Log.v(TAG, " IntentFilter:"); 6391 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6392 } 6393 if (!intent.debugCheck()) { 6394 Log.w(TAG, "==> For Activity " + a.info.name); 6395 } 6396 addFilter(intent); 6397 } 6398 } 6399 6400 public final void removeActivity(PackageParser.Activity a, String type) { 6401 mActivities.remove(a.getComponentName()); 6402 if (DEBUG_SHOW_INFO) { 6403 Log.v(TAG, " " + type + " " 6404 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 6405 : a.info.name) + ":"); 6406 Log.v(TAG, " Class=" + a.info.name); 6407 } 6408 final int NI = a.intents.size(); 6409 for (int j=0; j<NI; j++) { 6410 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 6411 if (DEBUG_SHOW_INFO) { 6412 Log.v(TAG, " IntentFilter:"); 6413 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6414 } 6415 removeFilter(intent); 6416 } 6417 } 6418 6419 @Override 6420 protected boolean allowFilterResult( 6421 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 6422 ActivityInfo filterAi = filter.activity.info; 6423 for (int i=dest.size()-1; i>=0; i--) { 6424 ActivityInfo destAi = dest.get(i).activityInfo; 6425 if (destAi.name == filterAi.name 6426 && destAi.packageName == filterAi.packageName) { 6427 return false; 6428 } 6429 } 6430 return true; 6431 } 6432 6433 @Override 6434 protected ActivityIntentInfo[] newArray(int size) { 6435 return new ActivityIntentInfo[size]; 6436 } 6437 6438 @Override 6439 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 6440 if (!sUserManager.exists(userId)) return true; 6441 PackageParser.Package p = filter.activity.owner; 6442 if (p != null) { 6443 PackageSetting ps = (PackageSetting)p.mExtras; 6444 if (ps != null) { 6445 // System apps are never considered stopped for purposes of 6446 // filtering, because there may be no way for the user to 6447 // actually re-launch them. 6448 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 6449 && ps.getStopped(userId); 6450 } 6451 } 6452 return false; 6453 } 6454 6455 @Override 6456 protected boolean isPackageForFilter(String packageName, 6457 PackageParser.ActivityIntentInfo info) { 6458 return packageName.equals(info.activity.owner.packageName); 6459 } 6460 6461 @Override 6462 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 6463 int match, int userId) { 6464 if (!sUserManager.exists(userId)) return null; 6465 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 6466 return null; 6467 } 6468 final PackageParser.Activity activity = info.activity; 6469 if (mSafeMode && (activity.info.applicationInfo.flags 6470 &ApplicationInfo.FLAG_SYSTEM) == 0) { 6471 return null; 6472 } 6473 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 6474 if (ps == null) { 6475 return null; 6476 } 6477 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 6478 ps.readUserState(userId), userId); 6479 if (ai == null) { 6480 return null; 6481 } 6482 final ResolveInfo res = new ResolveInfo(); 6483 res.activityInfo = ai; 6484 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 6485 res.filter = info; 6486 } 6487 res.priority = info.getPriority(); 6488 res.preferredOrder = activity.owner.mPreferredOrder; 6489 //System.out.println("Result: " + res.activityInfo.className + 6490 // " = " + res.priority); 6491 res.match = match; 6492 res.isDefault = info.hasDefault; 6493 res.labelRes = info.labelRes; 6494 res.nonLocalizedLabel = info.nonLocalizedLabel; 6495 res.icon = info.icon; 6496 res.system = isSystemApp(res.activityInfo.applicationInfo); 6497 return res; 6498 } 6499 6500 @Override 6501 protected void sortResults(List<ResolveInfo> results) { 6502 Collections.sort(results, mResolvePrioritySorter); 6503 } 6504 6505 @Override 6506 protected void dumpFilter(PrintWriter out, String prefix, 6507 PackageParser.ActivityIntentInfo filter) { 6508 out.print(prefix); out.print( 6509 Integer.toHexString(System.identityHashCode(filter.activity))); 6510 out.print(' '); 6511 filter.activity.printComponentShortName(out); 6512 out.print(" filter "); 6513 out.println(Integer.toHexString(System.identityHashCode(filter))); 6514 } 6515 6516// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 6517// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 6518// final List<ResolveInfo> retList = Lists.newArrayList(); 6519// while (i.hasNext()) { 6520// final ResolveInfo resolveInfo = i.next(); 6521// if (isEnabledLP(resolveInfo.activityInfo)) { 6522// retList.add(resolveInfo); 6523// } 6524// } 6525// return retList; 6526// } 6527 6528 // Keys are String (activity class name), values are Activity. 6529 private final HashMap<ComponentName, PackageParser.Activity> mActivities 6530 = new HashMap<ComponentName, PackageParser.Activity>(); 6531 private int mFlags; 6532 } 6533 6534 private final class ServiceIntentResolver 6535 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 6536 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 6537 boolean defaultOnly, int userId) { 6538 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 6539 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 6540 } 6541 6542 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 6543 int userId) { 6544 if (!sUserManager.exists(userId)) return null; 6545 mFlags = flags; 6546 return super.queryIntent(intent, resolvedType, 6547 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 6548 } 6549 6550 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 6551 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 6552 if (!sUserManager.exists(userId)) return null; 6553 if (packageServices == null) { 6554 return null; 6555 } 6556 mFlags = flags; 6557 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 6558 final int N = packageServices.size(); 6559 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 6560 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 6561 6562 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 6563 for (int i = 0; i < N; ++i) { 6564 intentFilters = packageServices.get(i).intents; 6565 if (intentFilters != null && intentFilters.size() > 0) { 6566 PackageParser.ServiceIntentInfo[] array = 6567 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 6568 intentFilters.toArray(array); 6569 listCut.add(array); 6570 } 6571 } 6572 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 6573 } 6574 6575 public final void addService(PackageParser.Service s) { 6576 mServices.put(s.getComponentName(), s); 6577 if (DEBUG_SHOW_INFO) { 6578 Log.v(TAG, " " 6579 + (s.info.nonLocalizedLabel != null 6580 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 6581 Log.v(TAG, " Class=" + s.info.name); 6582 } 6583 final int NI = s.intents.size(); 6584 int j; 6585 for (j=0; j<NI; j++) { 6586 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 6587 if (DEBUG_SHOW_INFO) { 6588 Log.v(TAG, " IntentFilter:"); 6589 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6590 } 6591 if (!intent.debugCheck()) { 6592 Log.w(TAG, "==> For Service " + s.info.name); 6593 } 6594 addFilter(intent); 6595 } 6596 } 6597 6598 public final void removeService(PackageParser.Service s) { 6599 mServices.remove(s.getComponentName()); 6600 if (DEBUG_SHOW_INFO) { 6601 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 6602 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 6603 Log.v(TAG, " Class=" + s.info.name); 6604 } 6605 final int NI = s.intents.size(); 6606 int j; 6607 for (j=0; j<NI; j++) { 6608 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 6609 if (DEBUG_SHOW_INFO) { 6610 Log.v(TAG, " IntentFilter:"); 6611 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6612 } 6613 removeFilter(intent); 6614 } 6615 } 6616 6617 @Override 6618 protected boolean allowFilterResult( 6619 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 6620 ServiceInfo filterSi = filter.service.info; 6621 for (int i=dest.size()-1; i>=0; i--) { 6622 ServiceInfo destAi = dest.get(i).serviceInfo; 6623 if (destAi.name == filterSi.name 6624 && destAi.packageName == filterSi.packageName) { 6625 return false; 6626 } 6627 } 6628 return true; 6629 } 6630 6631 @Override 6632 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 6633 return new PackageParser.ServiceIntentInfo[size]; 6634 } 6635 6636 @Override 6637 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 6638 if (!sUserManager.exists(userId)) return true; 6639 PackageParser.Package p = filter.service.owner; 6640 if (p != null) { 6641 PackageSetting ps = (PackageSetting)p.mExtras; 6642 if (ps != null) { 6643 // System apps are never considered stopped for purposes of 6644 // filtering, because there may be no way for the user to 6645 // actually re-launch them. 6646 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 6647 && ps.getStopped(userId); 6648 } 6649 } 6650 return false; 6651 } 6652 6653 @Override 6654 protected boolean isPackageForFilter(String packageName, 6655 PackageParser.ServiceIntentInfo info) { 6656 return packageName.equals(info.service.owner.packageName); 6657 } 6658 6659 @Override 6660 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 6661 int match, int userId) { 6662 if (!sUserManager.exists(userId)) return null; 6663 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 6664 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 6665 return null; 6666 } 6667 final PackageParser.Service service = info.service; 6668 if (mSafeMode && (service.info.applicationInfo.flags 6669 &ApplicationInfo.FLAG_SYSTEM) == 0) { 6670 return null; 6671 } 6672 PackageSetting ps = (PackageSetting) service.owner.mExtras; 6673 if (ps == null) { 6674 return null; 6675 } 6676 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 6677 ps.readUserState(userId), userId); 6678 if (si == null) { 6679 return null; 6680 } 6681 final ResolveInfo res = new ResolveInfo(); 6682 res.serviceInfo = si; 6683 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 6684 res.filter = filter; 6685 } 6686 res.priority = info.getPriority(); 6687 res.preferredOrder = service.owner.mPreferredOrder; 6688 //System.out.println("Result: " + res.activityInfo.className + 6689 // " = " + res.priority); 6690 res.match = match; 6691 res.isDefault = info.hasDefault; 6692 res.labelRes = info.labelRes; 6693 res.nonLocalizedLabel = info.nonLocalizedLabel; 6694 res.icon = info.icon; 6695 res.system = isSystemApp(res.serviceInfo.applicationInfo); 6696 return res; 6697 } 6698 6699 @Override 6700 protected void sortResults(List<ResolveInfo> results) { 6701 Collections.sort(results, mResolvePrioritySorter); 6702 } 6703 6704 @Override 6705 protected void dumpFilter(PrintWriter out, String prefix, 6706 PackageParser.ServiceIntentInfo filter) { 6707 out.print(prefix); out.print( 6708 Integer.toHexString(System.identityHashCode(filter.service))); 6709 out.print(' '); 6710 filter.service.printComponentShortName(out); 6711 out.print(" filter "); 6712 out.println(Integer.toHexString(System.identityHashCode(filter))); 6713 } 6714 6715// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 6716// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 6717// final List<ResolveInfo> retList = Lists.newArrayList(); 6718// while (i.hasNext()) { 6719// final ResolveInfo resolveInfo = (ResolveInfo) i; 6720// if (isEnabledLP(resolveInfo.serviceInfo)) { 6721// retList.add(resolveInfo); 6722// } 6723// } 6724// return retList; 6725// } 6726 6727 // Keys are String (activity class name), values are Activity. 6728 private final HashMap<ComponentName, PackageParser.Service> mServices 6729 = new HashMap<ComponentName, PackageParser.Service>(); 6730 private int mFlags; 6731 }; 6732 6733 private final class ProviderIntentResolver 6734 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 6735 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 6736 boolean defaultOnly, int userId) { 6737 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 6738 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 6739 } 6740 6741 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 6742 int userId) { 6743 if (!sUserManager.exists(userId)) 6744 return null; 6745 mFlags = flags; 6746 return super.queryIntent(intent, resolvedType, 6747 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 6748 } 6749 6750 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 6751 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 6752 if (!sUserManager.exists(userId)) 6753 return null; 6754 if (packageProviders == null) { 6755 return null; 6756 } 6757 mFlags = flags; 6758 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 6759 final int N = packageProviders.size(); 6760 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 6761 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 6762 6763 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 6764 for (int i = 0; i < N; ++i) { 6765 intentFilters = packageProviders.get(i).intents; 6766 if (intentFilters != null && intentFilters.size() > 0) { 6767 PackageParser.ProviderIntentInfo[] array = 6768 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 6769 intentFilters.toArray(array); 6770 listCut.add(array); 6771 } 6772 } 6773 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 6774 } 6775 6776 public final void addProvider(PackageParser.Provider p) { 6777 mProviders.put(p.getComponentName(), p); 6778 if (DEBUG_SHOW_INFO) { 6779 Log.v(TAG, " " 6780 + (p.info.nonLocalizedLabel != null 6781 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 6782 Log.v(TAG, " Class=" + p.info.name); 6783 } 6784 final int NI = p.intents.size(); 6785 int j; 6786 for (j = 0; j < NI; j++) { 6787 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 6788 if (DEBUG_SHOW_INFO) { 6789 Log.v(TAG, " IntentFilter:"); 6790 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6791 } 6792 if (!intent.debugCheck()) { 6793 Log.w(TAG, "==> For Provider " + p.info.name); 6794 } 6795 addFilter(intent); 6796 } 6797 } 6798 6799 public final void removeProvider(PackageParser.Provider p) { 6800 mProviders.remove(p.getComponentName()); 6801 if (DEBUG_SHOW_INFO) { 6802 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 6803 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 6804 Log.v(TAG, " Class=" + p.info.name); 6805 } 6806 final int NI = p.intents.size(); 6807 int j; 6808 for (j = 0; j < NI; j++) { 6809 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 6810 if (DEBUG_SHOW_INFO) { 6811 Log.v(TAG, " IntentFilter:"); 6812 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6813 } 6814 removeFilter(intent); 6815 } 6816 } 6817 6818 @Override 6819 protected boolean allowFilterResult( 6820 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 6821 ProviderInfo filterPi = filter.provider.info; 6822 for (int i = dest.size() - 1; i >= 0; i--) { 6823 ProviderInfo destPi = dest.get(i).providerInfo; 6824 if (destPi.name == filterPi.name 6825 && destPi.packageName == filterPi.packageName) { 6826 return false; 6827 } 6828 } 6829 return true; 6830 } 6831 6832 @Override 6833 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 6834 return new PackageParser.ProviderIntentInfo[size]; 6835 } 6836 6837 @Override 6838 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 6839 if (!sUserManager.exists(userId)) 6840 return true; 6841 PackageParser.Package p = filter.provider.owner; 6842 if (p != null) { 6843 PackageSetting ps = (PackageSetting) p.mExtras; 6844 if (ps != null) { 6845 // System apps are never considered stopped for purposes of 6846 // filtering, because there may be no way for the user to 6847 // actually re-launch them. 6848 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 6849 && ps.getStopped(userId); 6850 } 6851 } 6852 return false; 6853 } 6854 6855 @Override 6856 protected boolean isPackageForFilter(String packageName, 6857 PackageParser.ProviderIntentInfo info) { 6858 return packageName.equals(info.provider.owner.packageName); 6859 } 6860 6861 @Override 6862 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 6863 int match, int userId) { 6864 if (!sUserManager.exists(userId)) 6865 return null; 6866 final PackageParser.ProviderIntentInfo info = filter; 6867 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 6868 return null; 6869 } 6870 final PackageParser.Provider provider = info.provider; 6871 if (mSafeMode && (provider.info.applicationInfo.flags 6872 & ApplicationInfo.FLAG_SYSTEM) == 0) { 6873 return null; 6874 } 6875 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 6876 if (ps == null) { 6877 return null; 6878 } 6879 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 6880 ps.readUserState(userId), userId); 6881 if (pi == null) { 6882 return null; 6883 } 6884 final ResolveInfo res = new ResolveInfo(); 6885 res.providerInfo = pi; 6886 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 6887 res.filter = filter; 6888 } 6889 res.priority = info.getPriority(); 6890 res.preferredOrder = provider.owner.mPreferredOrder; 6891 res.match = match; 6892 res.isDefault = info.hasDefault; 6893 res.labelRes = info.labelRes; 6894 res.nonLocalizedLabel = info.nonLocalizedLabel; 6895 res.icon = info.icon; 6896 res.system = isSystemApp(res.providerInfo.applicationInfo); 6897 return res; 6898 } 6899 6900 @Override 6901 protected void sortResults(List<ResolveInfo> results) { 6902 Collections.sort(results, mResolvePrioritySorter); 6903 } 6904 6905 @Override 6906 protected void dumpFilter(PrintWriter out, String prefix, 6907 PackageParser.ProviderIntentInfo filter) { 6908 out.print(prefix); 6909 out.print( 6910 Integer.toHexString(System.identityHashCode(filter.provider))); 6911 out.print(' '); 6912 filter.provider.printComponentShortName(out); 6913 out.print(" filter "); 6914 out.println(Integer.toHexString(System.identityHashCode(filter))); 6915 } 6916 6917 private final HashMap<ComponentName, PackageParser.Provider> mProviders 6918 = new HashMap<ComponentName, PackageParser.Provider>(); 6919 private int mFlags; 6920 }; 6921 6922 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 6923 new Comparator<ResolveInfo>() { 6924 public int compare(ResolveInfo r1, ResolveInfo r2) { 6925 int v1 = r1.priority; 6926 int v2 = r2.priority; 6927 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 6928 if (v1 != v2) { 6929 return (v1 > v2) ? -1 : 1; 6930 } 6931 v1 = r1.preferredOrder; 6932 v2 = r2.preferredOrder; 6933 if (v1 != v2) { 6934 return (v1 > v2) ? -1 : 1; 6935 } 6936 if (r1.isDefault != r2.isDefault) { 6937 return r1.isDefault ? -1 : 1; 6938 } 6939 v1 = r1.match; 6940 v2 = r2.match; 6941 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 6942 if (v1 != v2) { 6943 return (v1 > v2) ? -1 : 1; 6944 } 6945 if (r1.system != r2.system) { 6946 return r1.system ? -1 : 1; 6947 } 6948 return 0; 6949 } 6950 }; 6951 6952 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 6953 new Comparator<ProviderInfo>() { 6954 public int compare(ProviderInfo p1, ProviderInfo p2) { 6955 final int v1 = p1.initOrder; 6956 final int v2 = p2.initOrder; 6957 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 6958 } 6959 }; 6960 6961 static final void sendPackageBroadcast(String action, String pkg, 6962 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, 6963 int[] userIds) { 6964 IActivityManager am = ActivityManagerNative.getDefault(); 6965 if (am != null) { 6966 try { 6967 if (userIds == null) { 6968 userIds = am.getRunningUserIds(); 6969 } 6970 for (int id : userIds) { 6971 final Intent intent = new Intent(action, 6972 pkg != null ? Uri.fromParts("package", pkg, null) : null); 6973 if (extras != null) { 6974 intent.putExtras(extras); 6975 } 6976 if (targetPkg != null) { 6977 intent.setPackage(targetPkg); 6978 } 6979 // Modify the UID when posting to other users 6980 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 6981 if (uid > 0 && UserHandle.getUserId(uid) != id) { 6982 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 6983 intent.putExtra(Intent.EXTRA_UID, uid); 6984 } 6985 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 6986 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 6987 if (DEBUG_BROADCASTS) { 6988 RuntimeException here = new RuntimeException("here"); 6989 here.fillInStackTrace(); 6990 Slog.d(TAG, "Sending to user " + id + ": " 6991 + intent.toShortString(false, true, false, false) 6992 + " " + intent.getExtras(), here); 6993 } 6994 am.broadcastIntent(null, intent, null, finishedReceiver, 6995 0, null, null, null, android.app.AppOpsManager.OP_NONE, 6996 finishedReceiver != null, false, id); 6997 } 6998 } catch (RemoteException ex) { 6999 } 7000 } 7001 } 7002 7003 /** 7004 * Check if the external storage media is available. This is true if there 7005 * is a mounted external storage medium or if the external storage is 7006 * emulated. 7007 */ 7008 private boolean isExternalMediaAvailable() { 7009 return mMediaMounted || Environment.isExternalStorageEmulated(); 7010 } 7011 7012 @Override 7013 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 7014 // writer 7015 synchronized (mPackages) { 7016 if (!isExternalMediaAvailable()) { 7017 // If the external storage is no longer mounted at this point, 7018 // the caller may not have been able to delete all of this 7019 // packages files and can not delete any more. Bail. 7020 return null; 7021 } 7022 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 7023 if (lastPackage != null) { 7024 pkgs.remove(lastPackage); 7025 } 7026 if (pkgs.size() > 0) { 7027 return pkgs.get(0); 7028 } 7029 } 7030 return null; 7031 } 7032 7033 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 7034 if (false) { 7035 RuntimeException here = new RuntimeException("here"); 7036 here.fillInStackTrace(); 7037 Slog.d(TAG, "Schedule cleaning " + packageName + " user=" + userId 7038 + " andCode=" + andCode, here); 7039 } 7040 mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE, 7041 userId, andCode ? 1 : 0, packageName)); 7042 } 7043 7044 void startCleaningPackages() { 7045 // reader 7046 synchronized (mPackages) { 7047 if (!isExternalMediaAvailable()) { 7048 return; 7049 } 7050 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 7051 return; 7052 } 7053 } 7054 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 7055 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 7056 IActivityManager am = ActivityManagerNative.getDefault(); 7057 if (am != null) { 7058 try { 7059 am.startService(null, intent, null, UserHandle.USER_OWNER); 7060 } catch (RemoteException e) { 7061 } 7062 } 7063 } 7064 7065 private final class AppDirObserver extends FileObserver { 7066 public AppDirObserver(String path, int mask, boolean isrom, boolean isPrivileged) { 7067 super(path, mask); 7068 mRootDir = path; 7069 mIsRom = isrom; 7070 mIsPrivileged = isPrivileged; 7071 } 7072 7073 public void onEvent(int event, String path) { 7074 String removedPackage = null; 7075 int removedAppId = -1; 7076 int[] removedUsers = null; 7077 String addedPackage = null; 7078 int addedAppId = -1; 7079 int[] addedUsers = null; 7080 7081 // TODO post a message to the handler to obtain serial ordering 7082 synchronized (mInstallLock) { 7083 String fullPathStr = null; 7084 File fullPath = null; 7085 if (path != null) { 7086 fullPath = new File(mRootDir, path); 7087 fullPathStr = fullPath.getPath(); 7088 } 7089 7090 if (DEBUG_APP_DIR_OBSERVER) 7091 Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event)); 7092 7093 if (!isPackageFilename(path)) { 7094 if (DEBUG_APP_DIR_OBSERVER) 7095 Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr); 7096 return; 7097 } 7098 7099 // Ignore packages that are being installed or 7100 // have just been installed. 7101 if (ignoreCodePath(fullPathStr)) { 7102 return; 7103 } 7104 PackageParser.Package p = null; 7105 PackageSetting ps = null; 7106 // reader 7107 synchronized (mPackages) { 7108 p = mAppDirs.get(fullPathStr); 7109 if (p != null) { 7110 ps = mSettings.mPackages.get(p.applicationInfo.packageName); 7111 if (ps != null) { 7112 removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 7113 } else { 7114 removedUsers = sUserManager.getUserIds(); 7115 } 7116 } 7117 addedUsers = sUserManager.getUserIds(); 7118 } 7119 if ((event&REMOVE_EVENTS) != 0) { 7120 if (ps != null) { 7121 if (DEBUG_REMOVE) Slog.d(TAG, "Package disappeared: " + ps); 7122 removePackageLI(ps, true); 7123 removedPackage = ps.name; 7124 removedAppId = ps.appId; 7125 } 7126 } 7127 7128 if ((event&ADD_EVENTS) != 0) { 7129 if (p == null) { 7130 if (DEBUG_INSTALL) Slog.d(TAG, "New file appeared: " + fullPath); 7131 int flags = PackageParser.PARSE_CHATTY | PackageParser.PARSE_MUST_BE_APK; 7132 if (mIsRom) { 7133 flags |= PackageParser.PARSE_IS_SYSTEM 7134 | PackageParser.PARSE_IS_SYSTEM_DIR; 7135 if (mIsPrivileged) { 7136 flags |= PackageParser.PARSE_IS_PRIVILEGED; 7137 } 7138 } 7139 p = scanPackageLI(fullPath, flags, 7140 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME, 7141 System.currentTimeMillis(), UserHandle.ALL); 7142 if (p != null) { 7143 /* 7144 * TODO this seems dangerous as the package may have 7145 * changed since we last acquired the mPackages 7146 * lock. 7147 */ 7148 // writer 7149 synchronized (mPackages) { 7150 updatePermissionsLPw(p.packageName, p, 7151 p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0); 7152 } 7153 addedPackage = p.applicationInfo.packageName; 7154 addedAppId = UserHandle.getAppId(p.applicationInfo.uid); 7155 } 7156 } 7157 } 7158 7159 // reader 7160 synchronized (mPackages) { 7161 mSettings.writeLPr(); 7162 } 7163 } 7164 7165 if (removedPackage != null) { 7166 Bundle extras = new Bundle(1); 7167 extras.putInt(Intent.EXTRA_UID, removedAppId); 7168 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false); 7169 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 7170 extras, null, null, removedUsers); 7171 } 7172 if (addedPackage != null) { 7173 Bundle extras = new Bundle(1); 7174 extras.putInt(Intent.EXTRA_UID, addedAppId); 7175 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage, 7176 extras, null, null, addedUsers); 7177 } 7178 } 7179 7180 private final String mRootDir; 7181 private final boolean mIsRom; 7182 private final boolean mIsPrivileged; 7183 } 7184 7185 /* Called when a downloaded package installation has been confirmed by the user */ 7186 public void installPackage( 7187 final Uri packageURI, final IPackageInstallObserver observer, final int flags) { 7188 installPackage(packageURI, observer, flags, null); 7189 } 7190 7191 /* Called when a downloaded package installation has been confirmed by the user */ 7192 @Override 7193 public void installPackage( 7194 final Uri packageURI, final IPackageInstallObserver observer, final int flags, 7195 final String installerPackageName) { 7196 installPackageWithVerification(packageURI, observer, flags, installerPackageName, null, 7197 null, null); 7198 } 7199 7200 @Override 7201 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 7202 int flags, String installerPackageName, Uri verificationURI, 7203 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) { 7204 VerificationParams verificationParams = new VerificationParams(verificationURI, null, null, 7205 VerificationParams.NO_UID, manifestDigest); 7206 installPackageWithVerificationAndEncryption(packageURI, observer, flags, 7207 installerPackageName, verificationParams, encryptionParams); 7208 } 7209 7210 @Override 7211 public void installPackageWithVerificationAndEncryption(Uri packageURI, 7212 IPackageInstallObserver observer, int flags, String installerPackageName, 7213 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 7214 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 7215 null); 7216 7217 final int uid = Binder.getCallingUid(); 7218 if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) { 7219 try { 7220 observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED); 7221 } catch (RemoteException re) { 7222 } 7223 return; 7224 } 7225 7226 UserHandle user; 7227 if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) { 7228 user = UserHandle.ALL; 7229 } else { 7230 user = new UserHandle(UserHandle.getUserId(uid)); 7231 } 7232 7233 final int filteredFlags; 7234 7235 if (uid == Process.SHELL_UID || uid == 0) { 7236 if (DEBUG_INSTALL) { 7237 Slog.v(TAG, "Install from ADB"); 7238 } 7239 filteredFlags = flags | PackageManager.INSTALL_FROM_ADB; 7240 } else { 7241 filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB; 7242 } 7243 7244 verificationParams.setInstallerUid(uid); 7245 7246 final Message msg = mHandler.obtainMessage(INIT_COPY); 7247 msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName, 7248 verificationParams, encryptionParams, user); 7249 mHandler.sendMessage(msg); 7250 } 7251 7252 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 7253 Bundle extras = new Bundle(1); 7254 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 7255 7256 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 7257 packageName, extras, null, null, new int[] {userId}); 7258 try { 7259 IActivityManager am = ActivityManagerNative.getDefault(); 7260 final boolean isSystem = 7261 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 7262 if (isSystem && am.isUserRunning(userId, false)) { 7263 // The just-installed/enabled app is bundled on the system, so presumed 7264 // to be able to run automatically without needing an explicit launch. 7265 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 7266 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 7267 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 7268 .setPackage(packageName); 7269 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 7270 android.app.AppOpsManager.OP_NONE, false, false, userId); 7271 } 7272 } catch (RemoteException e) { 7273 // shouldn't happen 7274 Slog.w(TAG, "Unable to bootstrap installed package", e); 7275 } 7276 } 7277 7278 @Override 7279 public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked, 7280 int userId) { 7281 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 7282 PackageSetting pkgSetting; 7283 final int uid = Binder.getCallingUid(); 7284 if (UserHandle.getUserId(uid) != userId) { 7285 mContext.enforceCallingOrSelfPermission( 7286 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 7287 "setApplicationBlockedSetting for user " + userId); 7288 } 7289 7290 if (blocked && isPackageDeviceAdmin(packageName, userId)) { 7291 Slog.w(TAG, "Not blocking package " + packageName + ": has active device admin"); 7292 return false; 7293 } 7294 7295 long callingId = Binder.clearCallingIdentity(); 7296 try { 7297 boolean sendAdded = false; 7298 boolean sendRemoved = false; 7299 // writer 7300 synchronized (mPackages) { 7301 pkgSetting = mSettings.mPackages.get(packageName); 7302 if (pkgSetting == null) { 7303 return false; 7304 } 7305 if (pkgSetting.getBlocked(userId) != blocked) { 7306 pkgSetting.setBlocked(blocked, userId); 7307 mSettings.writePackageRestrictionsLPr(userId); 7308 if (blocked) { 7309 sendRemoved = true; 7310 } else { 7311 sendAdded = true; 7312 } 7313 } 7314 } 7315 if (sendAdded) { 7316 sendPackageAddedForUser(packageName, pkgSetting, userId); 7317 return true; 7318 } 7319 if (sendRemoved) { 7320 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 7321 "blocking pkg"); 7322 sendPackageBlockedForUser(packageName, pkgSetting, userId); 7323 } 7324 } finally { 7325 Binder.restoreCallingIdentity(callingId); 7326 } 7327 return false; 7328 } 7329 7330 private void sendPackageBlockedForUser(String packageName, PackageSetting pkgSetting, 7331 int userId) { 7332 final PackageRemovedInfo info = new PackageRemovedInfo(); 7333 info.removedPackage = packageName; 7334 info.removedUsers = new int[] {userId}; 7335 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 7336 info.sendBroadcast(false, false, false); 7337 } 7338 7339 /** 7340 * Returns true if application is not found or there was an error. Otherwise it returns 7341 * the blocked state of the package for the given user. 7342 */ 7343 @Override 7344 public boolean getApplicationBlockedSettingAsUser(String packageName, int userId) { 7345 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 7346 PackageSetting pkgSetting; 7347 final int uid = Binder.getCallingUid(); 7348 if (UserHandle.getUserId(uid) != userId) { 7349 mContext.enforceCallingPermission( 7350 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 7351 "getApplicationBlocked for user " + userId); 7352 } 7353 long callingId = Binder.clearCallingIdentity(); 7354 try { 7355 // writer 7356 synchronized (mPackages) { 7357 pkgSetting = mSettings.mPackages.get(packageName); 7358 if (pkgSetting == null) { 7359 return true; 7360 } 7361 return pkgSetting.getBlocked(userId); 7362 } 7363 } finally { 7364 Binder.restoreCallingIdentity(callingId); 7365 } 7366 } 7367 7368 /** 7369 * @hide 7370 */ 7371 @Override 7372 public int installExistingPackageAsUser(String packageName, int userId) { 7373 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 7374 null); 7375 PackageSetting pkgSetting; 7376 final int uid = Binder.getCallingUid(); 7377 if (UserHandle.getUserId(uid) != userId) { 7378 mContext.enforceCallingPermission( 7379 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 7380 "installExistingPackage for user " + userId); 7381 } 7382 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 7383 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 7384 } 7385 7386 long callingId = Binder.clearCallingIdentity(); 7387 try { 7388 boolean sendAdded = false; 7389 Bundle extras = new Bundle(1); 7390 7391 // writer 7392 synchronized (mPackages) { 7393 pkgSetting = mSettings.mPackages.get(packageName); 7394 if (pkgSetting == null) { 7395 return PackageManager.INSTALL_FAILED_INVALID_URI; 7396 } 7397 if (!pkgSetting.getInstalled(userId)) { 7398 pkgSetting.setInstalled(true, userId); 7399 pkgSetting.setBlocked(false, userId); 7400 mSettings.writePackageRestrictionsLPr(userId); 7401 sendAdded = true; 7402 } 7403 } 7404 7405 if (sendAdded) { 7406 sendPackageAddedForUser(packageName, pkgSetting, userId); 7407 } 7408 } finally { 7409 Binder.restoreCallingIdentity(callingId); 7410 } 7411 7412 return PackageManager.INSTALL_SUCCEEDED; 7413 } 7414 7415 private boolean isUserRestricted(int userId, String restrictionKey) { 7416 Bundle restrictions = sUserManager.getUserRestrictions(userId); 7417 if (restrictions.getBoolean(restrictionKey, false)) { 7418 Log.w(TAG, "User is restricted: " + restrictionKey); 7419 return true; 7420 } 7421 return false; 7422 } 7423 7424 @Override 7425 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 7426 mContext.enforceCallingOrSelfPermission( 7427 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 7428 "Only package verification agents can verify applications"); 7429 7430 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 7431 final PackageVerificationResponse response = new PackageVerificationResponse( 7432 verificationCode, Binder.getCallingUid()); 7433 msg.arg1 = id; 7434 msg.obj = response; 7435 mHandler.sendMessage(msg); 7436 } 7437 7438 @Override 7439 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 7440 long millisecondsToDelay) { 7441 mContext.enforceCallingOrSelfPermission( 7442 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 7443 "Only package verification agents can extend verification timeouts"); 7444 7445 final PackageVerificationState state = mPendingVerification.get(id); 7446 final PackageVerificationResponse response = new PackageVerificationResponse( 7447 verificationCodeAtTimeout, Binder.getCallingUid()); 7448 7449 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 7450 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 7451 } 7452 if (millisecondsToDelay < 0) { 7453 millisecondsToDelay = 0; 7454 } 7455 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 7456 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 7457 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 7458 } 7459 7460 if ((state != null) && !state.timeoutExtended()) { 7461 state.extendTimeout(); 7462 7463 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 7464 msg.arg1 = id; 7465 msg.obj = response; 7466 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 7467 } 7468 } 7469 7470 private void broadcastPackageVerified(int verificationId, Uri packageUri, 7471 int verificationCode, UserHandle user) { 7472 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 7473 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 7474 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 7475 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 7476 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 7477 7478 mContext.sendBroadcastAsUser(intent, user, 7479 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 7480 } 7481 7482 private ComponentName matchComponentForVerifier(String packageName, 7483 List<ResolveInfo> receivers) { 7484 ActivityInfo targetReceiver = null; 7485 7486 final int NR = receivers.size(); 7487 for (int i = 0; i < NR; i++) { 7488 final ResolveInfo info = receivers.get(i); 7489 if (info.activityInfo == null) { 7490 continue; 7491 } 7492 7493 if (packageName.equals(info.activityInfo.packageName)) { 7494 targetReceiver = info.activityInfo; 7495 break; 7496 } 7497 } 7498 7499 if (targetReceiver == null) { 7500 return null; 7501 } 7502 7503 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 7504 } 7505 7506 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 7507 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 7508 if (pkgInfo.verifiers.length == 0) { 7509 return null; 7510 } 7511 7512 final int N = pkgInfo.verifiers.length; 7513 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 7514 for (int i = 0; i < N; i++) { 7515 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 7516 7517 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 7518 receivers); 7519 if (comp == null) { 7520 continue; 7521 } 7522 7523 final int verifierUid = getUidForVerifier(verifierInfo); 7524 if (verifierUid == -1) { 7525 continue; 7526 } 7527 7528 if (DEBUG_VERIFY) { 7529 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 7530 + " with the correct signature"); 7531 } 7532 sufficientVerifiers.add(comp); 7533 verificationState.addSufficientVerifier(verifierUid); 7534 } 7535 7536 return sufficientVerifiers; 7537 } 7538 7539 private int getUidForVerifier(VerifierInfo verifierInfo) { 7540 synchronized (mPackages) { 7541 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 7542 if (pkg == null) { 7543 return -1; 7544 } else if (pkg.mSignatures.length != 1) { 7545 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 7546 + " has more than one signature; ignoring"); 7547 return -1; 7548 } 7549 7550 /* 7551 * If the public key of the package's signature does not match 7552 * our expected public key, then this is a different package and 7553 * we should skip. 7554 */ 7555 7556 final byte[] expectedPublicKey; 7557 try { 7558 final Signature verifierSig = pkg.mSignatures[0]; 7559 final PublicKey publicKey = verifierSig.getPublicKey(); 7560 expectedPublicKey = publicKey.getEncoded(); 7561 } catch (CertificateException e) { 7562 return -1; 7563 } 7564 7565 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 7566 7567 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 7568 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 7569 + " does not have the expected public key; ignoring"); 7570 return -1; 7571 } 7572 7573 return pkg.applicationInfo.uid; 7574 } 7575 } 7576 7577 @Override 7578 public void finishPackageInstall(int token) { 7579 enforceSystemOrRoot("Only the system is allowed to finish installs"); 7580 7581 if (DEBUG_INSTALL) { 7582 Slog.v(TAG, "BM finishing package install for " + token); 7583 } 7584 7585 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 7586 mHandler.sendMessage(msg); 7587 } 7588 7589 /** 7590 * Get the verification agent timeout. 7591 * 7592 * @return verification timeout in milliseconds 7593 */ 7594 private long getVerificationTimeout() { 7595 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 7596 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 7597 DEFAULT_VERIFICATION_TIMEOUT); 7598 } 7599 7600 /** 7601 * Get the default verification agent response code. 7602 * 7603 * @return default verification response code 7604 */ 7605 private int getDefaultVerificationResponse() { 7606 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 7607 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 7608 DEFAULT_VERIFICATION_RESPONSE); 7609 } 7610 7611 /** 7612 * Check whether or not package verification has been enabled. 7613 * 7614 * @return true if verification should be performed 7615 */ 7616 private boolean isVerificationEnabled(int flags) { 7617 if (!DEFAULT_VERIFY_ENABLE) { 7618 return false; 7619 } 7620 7621 // Check if installing from ADB 7622 if ((flags & PackageManager.INSTALL_FROM_ADB) != 0) { 7623 // Do not run verification in a test harness environment 7624 if (ActivityManager.isRunningInTestHarness()) { 7625 return false; 7626 } 7627 // Check if the developer does not want package verification for ADB installs 7628 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 7629 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 7630 return false; 7631 } 7632 } 7633 7634 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 7635 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 7636 } 7637 7638 /** 7639 * Get the "allow unknown sources" setting. 7640 * 7641 * @return the current "allow unknown sources" setting 7642 */ 7643 private int getUnknownSourcesSettings() { 7644 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 7645 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 7646 -1); 7647 } 7648 7649 @Override 7650 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 7651 final int uid = Binder.getCallingUid(); 7652 // writer 7653 synchronized (mPackages) { 7654 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 7655 if (targetPackageSetting == null) { 7656 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 7657 } 7658 7659 PackageSetting installerPackageSetting; 7660 if (installerPackageName != null) { 7661 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 7662 if (installerPackageSetting == null) { 7663 throw new IllegalArgumentException("Unknown installer package: " 7664 + installerPackageName); 7665 } 7666 } else { 7667 installerPackageSetting = null; 7668 } 7669 7670 Signature[] callerSignature; 7671 Object obj = mSettings.getUserIdLPr(uid); 7672 if (obj != null) { 7673 if (obj instanceof SharedUserSetting) { 7674 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 7675 } else if (obj instanceof PackageSetting) { 7676 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 7677 } else { 7678 throw new SecurityException("Bad object " + obj + " for uid " + uid); 7679 } 7680 } else { 7681 throw new SecurityException("Unknown calling uid " + uid); 7682 } 7683 7684 // Verify: can't set installerPackageName to a package that is 7685 // not signed with the same cert as the caller. 7686 if (installerPackageSetting != null) { 7687 if (compareSignatures(callerSignature, 7688 installerPackageSetting.signatures.mSignatures) 7689 != PackageManager.SIGNATURE_MATCH) { 7690 throw new SecurityException( 7691 "Caller does not have same cert as new installer package " 7692 + installerPackageName); 7693 } 7694 } 7695 7696 // Verify: if target already has an installer package, it must 7697 // be signed with the same cert as the caller. 7698 if (targetPackageSetting.installerPackageName != null) { 7699 PackageSetting setting = mSettings.mPackages.get( 7700 targetPackageSetting.installerPackageName); 7701 // If the currently set package isn't valid, then it's always 7702 // okay to change it. 7703 if (setting != null) { 7704 if (compareSignatures(callerSignature, 7705 setting.signatures.mSignatures) 7706 != PackageManager.SIGNATURE_MATCH) { 7707 throw new SecurityException( 7708 "Caller does not have same cert as old installer package " 7709 + targetPackageSetting.installerPackageName); 7710 } 7711 } 7712 } 7713 7714 // Okay! 7715 targetPackageSetting.installerPackageName = installerPackageName; 7716 scheduleWriteSettingsLocked(); 7717 } 7718 } 7719 7720 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 7721 // Queue up an async operation since the package installation may take a little while. 7722 mHandler.post(new Runnable() { 7723 public void run() { 7724 mHandler.removeCallbacks(this); 7725 // Result object to be returned 7726 PackageInstalledInfo res = new PackageInstalledInfo(); 7727 res.returnCode = currentStatus; 7728 res.uid = -1; 7729 res.pkg = null; 7730 res.removedInfo = new PackageRemovedInfo(); 7731 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 7732 args.doPreInstall(res.returnCode); 7733 synchronized (mInstallLock) { 7734 installPackageLI(args, true, res); 7735 } 7736 args.doPostInstall(res.returnCode, res.uid); 7737 } 7738 7739 // A restore should be performed at this point if (a) the install 7740 // succeeded, (b) the operation is not an update, and (c) the new 7741 // package has a backupAgent defined. 7742 final boolean update = res.removedInfo.removedPackage != null; 7743 boolean doRestore = (!update 7744 && res.pkg != null 7745 && res.pkg.applicationInfo.backupAgentName != null); 7746 7747 // Set up the post-install work request bookkeeping. This will be used 7748 // and cleaned up by the post-install event handling regardless of whether 7749 // there's a restore pass performed. Token values are >= 1. 7750 int token; 7751 if (mNextInstallToken < 0) mNextInstallToken = 1; 7752 token = mNextInstallToken++; 7753 7754 PostInstallData data = new PostInstallData(args, res); 7755 mRunningInstalls.put(token, data); 7756 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 7757 7758 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 7759 // Pass responsibility to the Backup Manager. It will perform a 7760 // restore if appropriate, then pass responsibility back to the 7761 // Package Manager to run the post-install observer callbacks 7762 // and broadcasts. 7763 IBackupManager bm = IBackupManager.Stub.asInterface( 7764 ServiceManager.getService(Context.BACKUP_SERVICE)); 7765 if (bm != null) { 7766 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 7767 + " to BM for possible restore"); 7768 try { 7769 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 7770 } catch (RemoteException e) { 7771 // can't happen; the backup manager is local 7772 } catch (Exception e) { 7773 Slog.e(TAG, "Exception trying to enqueue restore", e); 7774 doRestore = false; 7775 } 7776 } else { 7777 Slog.e(TAG, "Backup Manager not found!"); 7778 doRestore = false; 7779 } 7780 } 7781 7782 if (!doRestore) { 7783 // No restore possible, or the Backup Manager was mysteriously not 7784 // available -- just fire the post-install work request directly. 7785 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 7786 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 7787 mHandler.sendMessage(msg); 7788 } 7789 } 7790 }); 7791 } 7792 7793 private abstract class HandlerParams { 7794 private static final int MAX_RETRIES = 4; 7795 7796 /** 7797 * Number of times startCopy() has been attempted and had a non-fatal 7798 * error. 7799 */ 7800 private int mRetries = 0; 7801 7802 /** User handle for the user requesting the information or installation. */ 7803 private final UserHandle mUser; 7804 7805 HandlerParams(UserHandle user) { 7806 mUser = user; 7807 } 7808 7809 UserHandle getUser() { 7810 return mUser; 7811 } 7812 7813 final boolean startCopy() { 7814 boolean res; 7815 try { 7816 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 7817 7818 if (++mRetries > MAX_RETRIES) { 7819 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 7820 mHandler.sendEmptyMessage(MCS_GIVE_UP); 7821 handleServiceError(); 7822 return false; 7823 } else { 7824 handleStartCopy(); 7825 res = true; 7826 } 7827 } catch (RemoteException e) { 7828 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 7829 mHandler.sendEmptyMessage(MCS_RECONNECT); 7830 res = false; 7831 } 7832 handleReturnCode(); 7833 return res; 7834 } 7835 7836 final void serviceError() { 7837 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 7838 handleServiceError(); 7839 handleReturnCode(); 7840 } 7841 7842 abstract void handleStartCopy() throws RemoteException; 7843 abstract void handleServiceError(); 7844 abstract void handleReturnCode(); 7845 } 7846 7847 class MeasureParams extends HandlerParams { 7848 private final PackageStats mStats; 7849 private boolean mSuccess; 7850 7851 private final IPackageStatsObserver mObserver; 7852 7853 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 7854 super(new UserHandle(stats.userHandle)); 7855 mObserver = observer; 7856 mStats = stats; 7857 } 7858 7859 @Override 7860 public String toString() { 7861 return "MeasureParams{" 7862 + Integer.toHexString(System.identityHashCode(this)) 7863 + " " + mStats.packageName + "}"; 7864 } 7865 7866 @Override 7867 void handleStartCopy() throws RemoteException { 7868 synchronized (mInstallLock) { 7869 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 7870 } 7871 7872 final boolean mounted; 7873 if (Environment.isExternalStorageEmulated()) { 7874 mounted = true; 7875 } else { 7876 final String status = Environment.getExternalStorageState(); 7877 mounted = (Environment.MEDIA_MOUNTED.equals(status) 7878 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 7879 } 7880 7881 if (mounted) { 7882 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 7883 7884 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 7885 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 7886 7887 mStats.externalDataSize = calculateDirectorySize(mContainerService, 7888 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 7889 7890 // Always subtract cache size, since it's a subdirectory 7891 mStats.externalDataSize -= mStats.externalCacheSize; 7892 7893 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 7894 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 7895 7896 mStats.externalObbSize = calculateDirectorySize(mContainerService, 7897 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 7898 } 7899 } 7900 7901 @Override 7902 void handleReturnCode() { 7903 if (mObserver != null) { 7904 try { 7905 mObserver.onGetStatsCompleted(mStats, mSuccess); 7906 } catch (RemoteException e) { 7907 Slog.i(TAG, "Observer no longer exists."); 7908 } 7909 } 7910 } 7911 7912 @Override 7913 void handleServiceError() { 7914 Slog.e(TAG, "Could not measure application " + mStats.packageName 7915 + " external storage"); 7916 } 7917 } 7918 7919 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 7920 throws RemoteException { 7921 long result = 0; 7922 for (File path : paths) { 7923 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 7924 } 7925 return result; 7926 } 7927 7928 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 7929 for (File path : paths) { 7930 try { 7931 mcs.clearDirectory(path.getAbsolutePath()); 7932 } catch (RemoteException e) { 7933 } 7934 } 7935 } 7936 7937 class InstallParams extends HandlerParams { 7938 final IPackageInstallObserver observer; 7939 int flags; 7940 7941 private final Uri mPackageURI; 7942 final String installerPackageName; 7943 final VerificationParams verificationParams; 7944 private InstallArgs mArgs; 7945 private int mRet; 7946 private File mTempPackage; 7947 final ContainerEncryptionParams encryptionParams; 7948 7949 InstallParams(Uri packageURI, 7950 IPackageInstallObserver observer, int flags, 7951 String installerPackageName, VerificationParams verificationParams, 7952 ContainerEncryptionParams encryptionParams, UserHandle user) { 7953 super(user); 7954 this.mPackageURI = packageURI; 7955 this.flags = flags; 7956 this.observer = observer; 7957 this.installerPackageName = installerPackageName; 7958 this.verificationParams = verificationParams; 7959 this.encryptionParams = encryptionParams; 7960 } 7961 7962 @Override 7963 public String toString() { 7964 return "InstallParams{" 7965 + Integer.toHexString(System.identityHashCode(this)) 7966 + " " + mPackageURI + "}"; 7967 } 7968 7969 public ManifestDigest getManifestDigest() { 7970 if (verificationParams == null) { 7971 return null; 7972 } 7973 return verificationParams.getManifestDigest(); 7974 } 7975 7976 private int installLocationPolicy(PackageInfoLite pkgLite, int flags) { 7977 String packageName = pkgLite.packageName; 7978 int installLocation = pkgLite.installLocation; 7979 boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 7980 // reader 7981 synchronized (mPackages) { 7982 PackageParser.Package pkg = mPackages.get(packageName); 7983 if (pkg != null) { 7984 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 7985 // Check for downgrading. 7986 if ((flags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 7987 if (pkgLite.versionCode < pkg.mVersionCode) { 7988 Slog.w(TAG, "Can't install update of " + packageName 7989 + " update version " + pkgLite.versionCode 7990 + " is older than installed version " 7991 + pkg.mVersionCode); 7992 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 7993 } 7994 } 7995 // Check for updated system application. 7996 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 7997 if (onSd) { 7998 Slog.w(TAG, "Cannot install update to system app on sdcard"); 7999 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 8000 } 8001 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8002 } else { 8003 if (onSd) { 8004 // Install flag overrides everything. 8005 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8006 } 8007 // If current upgrade specifies particular preference 8008 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 8009 // Application explicitly specified internal. 8010 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8011 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 8012 // App explictly prefers external. Let policy decide 8013 } else { 8014 // Prefer previous location 8015 if (isExternal(pkg)) { 8016 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8017 } 8018 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 8019 } 8020 } 8021 } else { 8022 // Invalid install. Return error code 8023 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 8024 } 8025 } 8026 } 8027 // All the special cases have been taken care of. 8028 // Return result based on recommended install location. 8029 if (onSd) { 8030 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 8031 } 8032 return pkgLite.recommendedInstallLocation; 8033 } 8034 8035 private long getMemoryLowThreshold() { 8036 final DeviceStorageMonitorInternal 8037 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 8038 if (dsm == null) { 8039 return 0L; 8040 } 8041 return dsm.getMemoryLowThreshold(); 8042 } 8043 8044 /* 8045 * Invoke remote method to get package information and install 8046 * location values. Override install location based on default 8047 * policy if needed and then create install arguments based 8048 * on the install location. 8049 */ 8050 public void handleStartCopy() throws RemoteException { 8051 int ret = PackageManager.INSTALL_SUCCEEDED; 8052 final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 8053 final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0; 8054 PackageInfoLite pkgLite = null; 8055 8056 if (onInt && onSd) { 8057 // Check if both bits are set. 8058 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 8059 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 8060 } else { 8061 final long lowThreshold = getMemoryLowThreshold(); 8062 if (lowThreshold == 0L) { 8063 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 8064 } 8065 8066 try { 8067 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, mPackageURI, 8068 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8069 8070 final File packageFile; 8071 if (encryptionParams != null || !"file".equals(mPackageURI.getScheme())) { 8072 mTempPackage = createTempPackageFile(mDrmAppPrivateInstallDir); 8073 if (mTempPackage != null) { 8074 ParcelFileDescriptor out; 8075 try { 8076 out = ParcelFileDescriptor.open(mTempPackage, 8077 ParcelFileDescriptor.MODE_READ_WRITE); 8078 } catch (FileNotFoundException e) { 8079 out = null; 8080 Slog.e(TAG, "Failed to create temporary file for : " + mPackageURI); 8081 } 8082 8083 // Make a temporary file for decryption. 8084 ret = mContainerService 8085 .copyResource(mPackageURI, encryptionParams, out); 8086 IoUtils.closeQuietly(out); 8087 8088 packageFile = mTempPackage; 8089 8090 FileUtils.setPermissions(packageFile.getAbsolutePath(), 8091 FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP 8092 | FileUtils.S_IROTH, 8093 -1, -1); 8094 } else { 8095 packageFile = null; 8096 } 8097 } else { 8098 packageFile = new File(mPackageURI.getPath()); 8099 } 8100 8101 if (packageFile != null) { 8102 // Remote call to find out default install location 8103 final String packageFilePath = packageFile.getAbsolutePath(); 8104 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags, 8105 lowThreshold); 8106 8107 /* 8108 * If we have too little free space, try to free cache 8109 * before giving up. 8110 */ 8111 if (pkgLite.recommendedInstallLocation 8112 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 8113 final long size = mContainerService.calculateInstalledSize( 8114 packageFilePath, isForwardLocked()); 8115 if (mInstaller.freeCache(size + lowThreshold) >= 0) { 8116 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, 8117 flags, lowThreshold); 8118 } 8119 /* 8120 * The cache free must have deleted the file we 8121 * downloaded to install. 8122 * 8123 * TODO: fix the "freeCache" call to not delete 8124 * the file we care about. 8125 */ 8126 if (pkgLite.recommendedInstallLocation 8127 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 8128 pkgLite.recommendedInstallLocation 8129 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 8130 } 8131 } 8132 } 8133 } finally { 8134 mContext.revokeUriPermission(mPackageURI, 8135 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8136 } 8137 } 8138 8139 if (ret == PackageManager.INSTALL_SUCCEEDED) { 8140 int loc = pkgLite.recommendedInstallLocation; 8141 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 8142 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 8143 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 8144 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 8145 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 8146 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8147 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 8148 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 8149 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 8150 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 8151 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 8152 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 8153 } else { 8154 // Override with defaults if needed. 8155 loc = installLocationPolicy(pkgLite, flags); 8156 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 8157 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 8158 } else if (!onSd && !onInt) { 8159 // Override install location with flags 8160 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 8161 // Set the flag to install on external media. 8162 flags |= PackageManager.INSTALL_EXTERNAL; 8163 flags &= ~PackageManager.INSTALL_INTERNAL; 8164 } else { 8165 // Make sure the flag for installing on external 8166 // media is unset 8167 flags |= PackageManager.INSTALL_INTERNAL; 8168 flags &= ~PackageManager.INSTALL_EXTERNAL; 8169 } 8170 } 8171 } 8172 } 8173 8174 final InstallArgs args = createInstallArgs(this); 8175 mArgs = args; 8176 8177 if (ret == PackageManager.INSTALL_SUCCEEDED) { 8178 /* 8179 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 8180 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 8181 */ 8182 int userIdentifier = getUser().getIdentifier(); 8183 if (userIdentifier == UserHandle.USER_ALL 8184 && ((flags & PackageManager.INSTALL_FROM_ADB) != 0)) { 8185 userIdentifier = UserHandle.USER_OWNER; 8186 } 8187 8188 /* 8189 * Determine if we have any installed package verifiers. If we 8190 * do, then we'll defer to them to verify the packages. 8191 */ 8192 final int requiredUid = mRequiredVerifierPackage == null ? -1 8193 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 8194 if (requiredUid != -1 && isVerificationEnabled(flags)) { 8195 final Intent verification = new Intent( 8196 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 8197 verification.setDataAndType(getPackageUri(), PACKAGE_MIME_TYPE); 8198 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 8199 8200 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 8201 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 8202 0 /* TODO: Which userId? */); 8203 8204 if (DEBUG_VERIFY) { 8205 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 8206 + verification.toString() + " with " + pkgLite.verifiers.length 8207 + " optional verifiers"); 8208 } 8209 8210 final int verificationId = mPendingVerificationToken++; 8211 8212 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 8213 8214 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 8215 installerPackageName); 8216 8217 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags); 8218 8219 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 8220 pkgLite.packageName); 8221 8222 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 8223 pkgLite.versionCode); 8224 8225 if (verificationParams != null) { 8226 if (verificationParams.getVerificationURI() != null) { 8227 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 8228 verificationParams.getVerificationURI()); 8229 } 8230 if (verificationParams.getOriginatingURI() != null) { 8231 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 8232 verificationParams.getOriginatingURI()); 8233 } 8234 if (verificationParams.getReferrer() != null) { 8235 verification.putExtra(Intent.EXTRA_REFERRER, 8236 verificationParams.getReferrer()); 8237 } 8238 if (verificationParams.getOriginatingUid() >= 0) { 8239 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 8240 verificationParams.getOriginatingUid()); 8241 } 8242 if (verificationParams.getInstallerUid() >= 0) { 8243 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 8244 verificationParams.getInstallerUid()); 8245 } 8246 } 8247 8248 final PackageVerificationState verificationState = new PackageVerificationState( 8249 requiredUid, args); 8250 8251 mPendingVerification.append(verificationId, verificationState); 8252 8253 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 8254 receivers, verificationState); 8255 8256 /* 8257 * If any sufficient verifiers were listed in the package 8258 * manifest, attempt to ask them. 8259 */ 8260 if (sufficientVerifiers != null) { 8261 final int N = sufficientVerifiers.size(); 8262 if (N == 0) { 8263 Slog.i(TAG, "Additional verifiers required, but none installed."); 8264 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 8265 } else { 8266 for (int i = 0; i < N; i++) { 8267 final ComponentName verifierComponent = sufficientVerifiers.get(i); 8268 8269 final Intent sufficientIntent = new Intent(verification); 8270 sufficientIntent.setComponent(verifierComponent); 8271 8272 mContext.sendBroadcastAsUser(sufficientIntent, getUser()); 8273 } 8274 } 8275 } 8276 8277 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 8278 mRequiredVerifierPackage, receivers); 8279 if (ret == PackageManager.INSTALL_SUCCEEDED 8280 && mRequiredVerifierPackage != null) { 8281 /* 8282 * Send the intent to the required verification agent, 8283 * but only start the verification timeout after the 8284 * target BroadcastReceivers have run. 8285 */ 8286 verification.setComponent(requiredVerifierComponent); 8287 mContext.sendOrderedBroadcastAsUser(verification, getUser(), 8288 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8289 new BroadcastReceiver() { 8290 @Override 8291 public void onReceive(Context context, Intent intent) { 8292 final Message msg = mHandler 8293 .obtainMessage(CHECK_PENDING_VERIFICATION); 8294 msg.arg1 = verificationId; 8295 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 8296 } 8297 }, null, 0, null, null); 8298 8299 /* 8300 * We don't want the copy to proceed until verification 8301 * succeeds, so null out this field. 8302 */ 8303 mArgs = null; 8304 } 8305 } else { 8306 /* 8307 * No package verification is enabled, so immediately start 8308 * the remote call to initiate copy using temporary file. 8309 */ 8310 ret = args.copyApk(mContainerService, true); 8311 } 8312 } 8313 8314 mRet = ret; 8315 } 8316 8317 @Override 8318 void handleReturnCode() { 8319 // If mArgs is null, then MCS couldn't be reached. When it 8320 // reconnects, it will try again to install. At that point, this 8321 // will succeed. 8322 if (mArgs != null) { 8323 processPendingInstall(mArgs, mRet); 8324 8325 if (mTempPackage != null) { 8326 if (!mTempPackage.delete()) { 8327 Slog.w(TAG, "Couldn't delete temporary file: " + 8328 mTempPackage.getAbsolutePath()); 8329 } 8330 } 8331 } 8332 } 8333 8334 @Override 8335 void handleServiceError() { 8336 mArgs = createInstallArgs(this); 8337 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 8338 } 8339 8340 public boolean isForwardLocked() { 8341 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 8342 } 8343 8344 public Uri getPackageUri() { 8345 if (mTempPackage != null) { 8346 return Uri.fromFile(mTempPackage); 8347 } else { 8348 return mPackageURI; 8349 } 8350 } 8351 } 8352 8353 /* 8354 * Utility class used in movePackage api. 8355 * srcArgs and targetArgs are not set for invalid flags and make 8356 * sure to do null checks when invoking methods on them. 8357 * We probably want to return ErrorPrams for both failed installs 8358 * and moves. 8359 */ 8360 class MoveParams extends HandlerParams { 8361 final IPackageMoveObserver observer; 8362 final int flags; 8363 final String packageName; 8364 final InstallArgs srcArgs; 8365 final InstallArgs targetArgs; 8366 int uid; 8367 int mRet; 8368 8369 MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, 8370 String packageName, String dataDir, String instructionSet, 8371 int uid, UserHandle user) { 8372 super(user); 8373 this.srcArgs = srcArgs; 8374 this.observer = observer; 8375 this.flags = flags; 8376 this.packageName = packageName; 8377 this.uid = uid; 8378 if (srcArgs != null) { 8379 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath())); 8380 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir, instructionSet); 8381 } else { 8382 targetArgs = null; 8383 } 8384 } 8385 8386 @Override 8387 public String toString() { 8388 return "MoveParams{" 8389 + Integer.toHexString(System.identityHashCode(this)) 8390 + " " + packageName + "}"; 8391 } 8392 8393 public void handleStartCopy() throws RemoteException { 8394 mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8395 // Check for storage space on target medium 8396 if (!targetArgs.checkFreeStorage(mContainerService)) { 8397 Log.w(TAG, "Insufficient storage to install"); 8398 return; 8399 } 8400 8401 mRet = srcArgs.doPreCopy(); 8402 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8403 return; 8404 } 8405 8406 mRet = targetArgs.copyApk(mContainerService, false); 8407 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8408 srcArgs.doPostCopy(uid); 8409 return; 8410 } 8411 8412 mRet = srcArgs.doPostCopy(uid); 8413 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8414 return; 8415 } 8416 8417 mRet = targetArgs.doPreInstall(mRet); 8418 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8419 return; 8420 } 8421 8422 if (DEBUG_SD_INSTALL) { 8423 StringBuilder builder = new StringBuilder(); 8424 if (srcArgs != null) { 8425 builder.append("src: "); 8426 builder.append(srcArgs.getCodePath()); 8427 } 8428 if (targetArgs != null) { 8429 builder.append(" target : "); 8430 builder.append(targetArgs.getCodePath()); 8431 } 8432 Log.i(TAG, builder.toString()); 8433 } 8434 } 8435 8436 @Override 8437 void handleReturnCode() { 8438 targetArgs.doPostInstall(mRet, uid); 8439 int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 8440 if (mRet == PackageManager.INSTALL_SUCCEEDED) { 8441 currentStatus = PackageManager.MOVE_SUCCEEDED; 8442 } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){ 8443 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 8444 } 8445 processPendingMove(this, currentStatus); 8446 } 8447 8448 @Override 8449 void handleServiceError() { 8450 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 8451 } 8452 } 8453 8454 /** 8455 * Used during creation of InstallArgs 8456 * 8457 * @param flags package installation flags 8458 * @return true if should be installed on external storage 8459 */ 8460 private static boolean installOnSd(int flags) { 8461 if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { 8462 return false; 8463 } 8464 if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { 8465 return true; 8466 } 8467 return false; 8468 } 8469 8470 /** 8471 * Used during creation of InstallArgs 8472 * 8473 * @param flags package installation flags 8474 * @return true if should be installed as forward locked 8475 */ 8476 private static boolean installForwardLocked(int flags) { 8477 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 8478 } 8479 8480 private InstallArgs createInstallArgs(InstallParams params) { 8481 if (installOnSd(params.flags) || params.isForwardLocked()) { 8482 return new AsecInstallArgs(params); 8483 } else { 8484 return new FileInstallArgs(params); 8485 } 8486 } 8487 8488 private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath, 8489 String nativeLibraryPath, String instructionSet) { 8490 final boolean isInAsec; 8491 if (installOnSd(flags)) { 8492 /* Apps on SD card are always in ASEC containers. */ 8493 isInAsec = true; 8494 } else if (installForwardLocked(flags) 8495 && !fullCodePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 8496 /* 8497 * Forward-locked apps are only in ASEC containers if they're the 8498 * new style 8499 */ 8500 isInAsec = true; 8501 } else { 8502 isInAsec = false; 8503 } 8504 8505 if (isInAsec) { 8506 return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath, 8507 instructionSet, installOnSd(flags), installForwardLocked(flags)); 8508 } else { 8509 return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath, 8510 instructionSet); 8511 } 8512 } 8513 8514 // Used by package mover 8515 private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir, 8516 String instructionSet) { 8517 if (installOnSd(flags) || installForwardLocked(flags)) { 8518 String cid = getNextCodePath(packageURI.getPath(), pkgName, "/" 8519 + AsecInstallArgs.RES_FILE_NAME); 8520 return new AsecInstallArgs(packageURI, cid, instructionSet, installOnSd(flags), 8521 installForwardLocked(flags)); 8522 } else { 8523 return new FileInstallArgs(packageURI, pkgName, dataDir, instructionSet); 8524 } 8525 } 8526 8527 static abstract class InstallArgs { 8528 final IPackageInstallObserver observer; 8529 // Always refers to PackageManager flags only 8530 final int flags; 8531 final Uri packageURI; 8532 final String installerPackageName; 8533 final ManifestDigest manifestDigest; 8534 final UserHandle user; 8535 final String instructionSet; 8536 8537 InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags, 8538 String installerPackageName, ManifestDigest manifestDigest, 8539 UserHandle user, String instructionSet) { 8540 this.packageURI = packageURI; 8541 this.flags = flags; 8542 this.observer = observer; 8543 this.installerPackageName = installerPackageName; 8544 this.manifestDigest = manifestDigest; 8545 this.user = user; 8546 this.instructionSet = instructionSet; 8547 } 8548 8549 abstract void createCopyFile(); 8550 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 8551 abstract int doPreInstall(int status); 8552 abstract boolean doRename(int status, String pkgName, String oldCodePath); 8553 8554 abstract int doPostInstall(int status, int uid); 8555 abstract String getCodePath(); 8556 abstract String getResourcePath(); 8557 abstract String getNativeLibraryPath(); 8558 // Need installer lock especially for dex file removal. 8559 abstract void cleanUpResourcesLI(); 8560 abstract boolean doPostDeleteLI(boolean delete); 8561 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 8562 8563 /** 8564 * Called before the source arguments are copied. This is used mostly 8565 * for MoveParams when it needs to read the source file to put it in the 8566 * destination. 8567 */ 8568 int doPreCopy() { 8569 return PackageManager.INSTALL_SUCCEEDED; 8570 } 8571 8572 /** 8573 * Called after the source arguments are copied. This is used mostly for 8574 * MoveParams when it needs to read the source file to put it in the 8575 * destination. 8576 * 8577 * @return 8578 */ 8579 int doPostCopy(int uid) { 8580 return PackageManager.INSTALL_SUCCEEDED; 8581 } 8582 8583 protected boolean isFwdLocked() { 8584 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 8585 } 8586 8587 UserHandle getUser() { 8588 return user; 8589 } 8590 } 8591 8592 class FileInstallArgs extends InstallArgs { 8593 File installDir; 8594 String codeFileName; 8595 String resourceFileName; 8596 String libraryPath; 8597 boolean created = false; 8598 8599 FileInstallArgs(InstallParams params) { 8600 super(params.getPackageUri(), params.observer, params.flags, 8601 params.installerPackageName, params.getManifestDigest(), 8602 params.getUser(), null /* instruction set */); 8603 } 8604 8605 FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, 8606 String instructionSet) { 8607 super(null, null, 0, null, null, null, instructionSet); 8608 File codeFile = new File(fullCodePath); 8609 installDir = codeFile.getParentFile(); 8610 codeFileName = fullCodePath; 8611 resourceFileName = fullResourcePath; 8612 libraryPath = nativeLibraryPath; 8613 } 8614 8615 FileInstallArgs(Uri packageURI, String pkgName, String dataDir, String instructionSet) { 8616 super(packageURI, null, 0, null, null, null, instructionSet); 8617 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 8618 String apkName = getNextCodePath(null, pkgName, ".apk"); 8619 codeFileName = new File(installDir, apkName + ".apk").getPath(); 8620 resourceFileName = getResourcePathFromCodePath(); 8621 libraryPath = new File(mAppLibInstallDir, pkgName).getPath(); 8622 } 8623 8624 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 8625 final long lowThreshold; 8626 8627 final DeviceStorageMonitorInternal 8628 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 8629 if (dsm == null) { 8630 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 8631 lowThreshold = 0L; 8632 } else { 8633 if (dsm.isMemoryLow()) { 8634 Log.w(TAG, "Memory is reported as being too low; aborting package install"); 8635 return false; 8636 } 8637 8638 lowThreshold = dsm.getMemoryLowThreshold(); 8639 } 8640 8641 try { 8642 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 8643 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8644 return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold); 8645 } finally { 8646 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 8647 } 8648 } 8649 8650 String getCodePath() { 8651 return codeFileName; 8652 } 8653 8654 void createCopyFile() { 8655 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 8656 codeFileName = createTempPackageFile(installDir).getPath(); 8657 resourceFileName = getResourcePathFromCodePath(); 8658 libraryPath = getLibraryPathFromCodePath(); 8659 created = true; 8660 } 8661 8662 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 8663 if (temp) { 8664 // Generate temp file name 8665 createCopyFile(); 8666 } 8667 // Get a ParcelFileDescriptor to write to the output file 8668 File codeFile = new File(codeFileName); 8669 if (!created) { 8670 try { 8671 codeFile.createNewFile(); 8672 // Set permissions 8673 if (!setPermissions()) { 8674 // Failed setting permissions. 8675 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8676 } 8677 } catch (IOException e) { 8678 Slog.w(TAG, "Failed to create file " + codeFile); 8679 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8680 } 8681 } 8682 ParcelFileDescriptor out = null; 8683 try { 8684 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE); 8685 } catch (FileNotFoundException e) { 8686 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName); 8687 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8688 } 8689 // Copy the resource now 8690 int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8691 try { 8692 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 8693 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8694 ret = imcs.copyResource(packageURI, null, out); 8695 } finally { 8696 IoUtils.closeQuietly(out); 8697 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 8698 } 8699 8700 if (isFwdLocked()) { 8701 final File destResourceFile = new File(getResourcePath()); 8702 8703 // Copy the public files 8704 try { 8705 PackageHelper.extractPublicFiles(codeFileName, destResourceFile); 8706 } catch (IOException e) { 8707 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" 8708 + " forward-locked app."); 8709 destResourceFile.delete(); 8710 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8711 } 8712 } 8713 8714 final File nativeLibraryFile = new File(getNativeLibraryPath()); 8715 Slog.i(TAG, "Copying native libraries to " + nativeLibraryFile.getPath()); 8716 if (nativeLibraryFile.exists()) { 8717 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile); 8718 nativeLibraryFile.delete(); 8719 } 8720 try { 8721 int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile); 8722 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 8723 return copyRet; 8724 } 8725 } catch (IOException e) { 8726 Slog.e(TAG, "Copying native libraries failed", e); 8727 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 8728 } 8729 8730 return ret; 8731 } 8732 8733 int doPreInstall(int status) { 8734 if (status != PackageManager.INSTALL_SUCCEEDED) { 8735 cleanUp(); 8736 } 8737 return status; 8738 } 8739 8740 boolean doRename(int status, final String pkgName, String oldCodePath) { 8741 if (status != PackageManager.INSTALL_SUCCEEDED) { 8742 cleanUp(); 8743 return false; 8744 } else { 8745 final File oldCodeFile = new File(getCodePath()); 8746 final File oldResourceFile = new File(getResourcePath()); 8747 final File oldLibraryFile = new File(getNativeLibraryPath()); 8748 8749 // Rename APK file based on packageName 8750 final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk"); 8751 final File newCodeFile = new File(installDir, apkName + ".apk"); 8752 if (!oldCodeFile.renameTo(newCodeFile)) { 8753 return false; 8754 } 8755 codeFileName = newCodeFile.getPath(); 8756 8757 // Rename public resource file if it's forward-locked. 8758 final File newResFile = new File(getResourcePathFromCodePath()); 8759 if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) { 8760 return false; 8761 } 8762 resourceFileName = newResFile.getPath(); 8763 8764 // Rename library path 8765 final File newLibraryFile = new File(getLibraryPathFromCodePath()); 8766 if (newLibraryFile.exists()) { 8767 NativeLibraryHelper.removeNativeBinariesFromDirLI(newLibraryFile); 8768 newLibraryFile.delete(); 8769 } 8770 if (!oldLibraryFile.renameTo(newLibraryFile)) { 8771 Slog.e(TAG, "Cannot rename native library directory " 8772 + oldLibraryFile.getPath() + " to " + newLibraryFile.getPath()); 8773 return false; 8774 } 8775 libraryPath = newLibraryFile.getPath(); 8776 8777 // Attempt to set permissions 8778 if (!setPermissions()) { 8779 return false; 8780 } 8781 8782 if (!SELinux.restorecon(newCodeFile)) { 8783 return false; 8784 } 8785 8786 return true; 8787 } 8788 } 8789 8790 int doPostInstall(int status, int uid) { 8791 if (status != PackageManager.INSTALL_SUCCEEDED) { 8792 cleanUp(); 8793 } 8794 return status; 8795 } 8796 8797 String getResourcePath() { 8798 return resourceFileName; 8799 } 8800 8801 private String getResourcePathFromCodePath() { 8802 final String codePath = getCodePath(); 8803 if (isFwdLocked()) { 8804 final StringBuilder sb = new StringBuilder(); 8805 8806 sb.append(mAppInstallDir.getPath()); 8807 sb.append('/'); 8808 sb.append(getApkName(codePath)); 8809 sb.append(".zip"); 8810 8811 /* 8812 * If our APK is a temporary file, mark the resource as a 8813 * temporary file as well so it can be cleaned up after 8814 * catastrophic failure. 8815 */ 8816 if (codePath.endsWith(".tmp")) { 8817 sb.append(".tmp"); 8818 } 8819 8820 return sb.toString(); 8821 } else { 8822 return codePath; 8823 } 8824 } 8825 8826 private String getLibraryPathFromCodePath() { 8827 return new File(mAppLibInstallDir, getApkName(getCodePath())).getPath(); 8828 } 8829 8830 @Override 8831 String getNativeLibraryPath() { 8832 if (libraryPath == null) { 8833 libraryPath = getLibraryPathFromCodePath(); 8834 } 8835 return libraryPath; 8836 } 8837 8838 private boolean cleanUp() { 8839 boolean ret = true; 8840 String sourceDir = getCodePath(); 8841 String publicSourceDir = getResourcePath(); 8842 if (sourceDir != null) { 8843 File sourceFile = new File(sourceDir); 8844 if (!sourceFile.exists()) { 8845 Slog.w(TAG, "Package source " + sourceDir + " does not exist."); 8846 ret = false; 8847 } 8848 // Delete application's code and resources 8849 sourceFile.delete(); 8850 } 8851 if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) { 8852 final File publicSourceFile = new File(publicSourceDir); 8853 if (!publicSourceFile.exists()) { 8854 Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist."); 8855 } 8856 if (publicSourceFile.exists()) { 8857 publicSourceFile.delete(); 8858 } 8859 } 8860 8861 if (libraryPath != null) { 8862 File nativeLibraryFile = new File(libraryPath); 8863 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile); 8864 if (!nativeLibraryFile.delete()) { 8865 Slog.w(TAG, "Couldn't delete native library directory " + libraryPath); 8866 } 8867 } 8868 8869 return ret; 8870 } 8871 8872 void cleanUpResourcesLI() { 8873 String sourceDir = getCodePath(); 8874 if (cleanUp()) { 8875 if (instructionSet == null) { 8876 throw new IllegalStateException("instructionSet == null"); 8877 } 8878 int retCode = mInstaller.rmdex(sourceDir, instructionSet); 8879 if (retCode < 0) { 8880 Slog.w(TAG, "Couldn't remove dex file for package: " 8881 + " at location " 8882 + sourceDir + ", retcode=" + retCode); 8883 // we don't consider this to be a failure of the core package deletion 8884 } 8885 } 8886 } 8887 8888 private boolean setPermissions() { 8889 // TODO Do this in a more elegant way later on. for now just a hack 8890 if (!isFwdLocked()) { 8891 final int filePermissions = 8892 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP 8893 |FileUtils.S_IROTH; 8894 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1); 8895 if (retCode != 0) { 8896 Slog.e(TAG, "Couldn't set new package file permissions for " + 8897 getCodePath() 8898 + ". The return code was: " + retCode); 8899 // TODO Define new internal error 8900 return false; 8901 } 8902 return true; 8903 } 8904 return true; 8905 } 8906 8907 boolean doPostDeleteLI(boolean delete) { 8908 // XXX err, shouldn't we respect the delete flag? 8909 cleanUpResourcesLI(); 8910 return true; 8911 } 8912 } 8913 8914 private boolean isAsecExternal(String cid) { 8915 final String asecPath = PackageHelper.getSdFilesystem(cid); 8916 return !asecPath.startsWith(mAsecInternalPath); 8917 } 8918 8919 /** 8920 * Extract the MountService "container ID" from the full code path of an 8921 * .apk. 8922 */ 8923 static String cidFromCodePath(String fullCodePath) { 8924 int eidx = fullCodePath.lastIndexOf("/"); 8925 String subStr1 = fullCodePath.substring(0, eidx); 8926 int sidx = subStr1.lastIndexOf("/"); 8927 return subStr1.substring(sidx+1, eidx); 8928 } 8929 8930 class AsecInstallArgs extends InstallArgs { 8931 static final String RES_FILE_NAME = "pkg.apk"; 8932 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 8933 8934 String cid; 8935 String packagePath; 8936 String resourcePath; 8937 String libraryPath; 8938 8939 AsecInstallArgs(InstallParams params) { 8940 super(params.getPackageUri(), params.observer, params.flags, 8941 params.installerPackageName, params.getManifestDigest(), 8942 params.getUser(), null /* instruction set */); 8943 } 8944 8945 AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, 8946 String instructionSet, boolean isExternal, boolean isForwardLocked) { 8947 super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0) 8948 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), 8949 null, null, null, instructionSet); 8950 // Extract cid from fullCodePath 8951 int eidx = fullCodePath.lastIndexOf("/"); 8952 String subStr1 = fullCodePath.substring(0, eidx); 8953 int sidx = subStr1.lastIndexOf("/"); 8954 cid = subStr1.substring(sidx+1, eidx); 8955 setCachePath(subStr1); 8956 } 8957 8958 AsecInstallArgs(String cid, String instructionSet, boolean isForwardLocked) { 8959 super(null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0) 8960 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), 8961 null, null, null, instructionSet); 8962 this.cid = cid; 8963 setCachePath(PackageHelper.getSdDir(cid)); 8964 } 8965 8966 AsecInstallArgs(Uri packageURI, String cid, String instructionSet, 8967 boolean isExternal, boolean isForwardLocked) { 8968 super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0) 8969 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), 8970 null, null, null, instructionSet); 8971 this.cid = cid; 8972 } 8973 8974 void createCopyFile() { 8975 cid = getTempContainerId(); 8976 } 8977 8978 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 8979 try { 8980 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 8981 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8982 return imcs.checkExternalFreeStorage(packageURI, isFwdLocked()); 8983 } finally { 8984 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 8985 } 8986 } 8987 8988 private final boolean isExternal() { 8989 return (flags & PackageManager.INSTALL_EXTERNAL) != 0; 8990 } 8991 8992 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 8993 if (temp) { 8994 createCopyFile(); 8995 } else { 8996 /* 8997 * Pre-emptively destroy the container since it's destroyed if 8998 * copying fails due to it existing anyway. 8999 */ 9000 PackageHelper.destroySdDir(cid); 9001 } 9002 9003 final String newCachePath; 9004 try { 9005 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 9006 Intent.FLAG_GRANT_READ_URI_PERMISSION); 9007 newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(), 9008 RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked()); 9009 } finally { 9010 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 9011 } 9012 9013 if (newCachePath != null) { 9014 setCachePath(newCachePath); 9015 return PackageManager.INSTALL_SUCCEEDED; 9016 } else { 9017 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9018 } 9019 } 9020 9021 @Override 9022 String getCodePath() { 9023 return packagePath; 9024 } 9025 9026 @Override 9027 String getResourcePath() { 9028 return resourcePath; 9029 } 9030 9031 @Override 9032 String getNativeLibraryPath() { 9033 return libraryPath; 9034 } 9035 9036 int doPreInstall(int status) { 9037 if (status != PackageManager.INSTALL_SUCCEEDED) { 9038 // Destroy container 9039 PackageHelper.destroySdDir(cid); 9040 } else { 9041 boolean mounted = PackageHelper.isContainerMounted(cid); 9042 if (!mounted) { 9043 String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(), 9044 Process.SYSTEM_UID); 9045 if (newCachePath != null) { 9046 setCachePath(newCachePath); 9047 } else { 9048 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9049 } 9050 } 9051 } 9052 return status; 9053 } 9054 9055 boolean doRename(int status, final String pkgName, 9056 String oldCodePath) { 9057 String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME); 9058 String newCachePath = null; 9059 if (PackageHelper.isContainerMounted(cid)) { 9060 // Unmount the container 9061 if (!PackageHelper.unMountSdDir(cid)) { 9062 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 9063 return false; 9064 } 9065 } 9066 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 9067 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 9068 " which might be stale. Will try to clean up."); 9069 // Clean up the stale container and proceed to recreate. 9070 if (!PackageHelper.destroySdDir(newCacheId)) { 9071 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 9072 return false; 9073 } 9074 // Successfully cleaned up stale container. Try to rename again. 9075 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 9076 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 9077 + " inspite of cleaning it up."); 9078 return false; 9079 } 9080 } 9081 if (!PackageHelper.isContainerMounted(newCacheId)) { 9082 Slog.w(TAG, "Mounting container " + newCacheId); 9083 newCachePath = PackageHelper.mountSdDir(newCacheId, 9084 getEncryptKey(), Process.SYSTEM_UID); 9085 } else { 9086 newCachePath = PackageHelper.getSdDir(newCacheId); 9087 } 9088 if (newCachePath == null) { 9089 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 9090 return false; 9091 } 9092 Log.i(TAG, "Succesfully renamed " + cid + 9093 " to " + newCacheId + 9094 " at new path: " + newCachePath); 9095 cid = newCacheId; 9096 setCachePath(newCachePath); 9097 return true; 9098 } 9099 9100 private void setCachePath(String newCachePath) { 9101 File cachePath = new File(newCachePath); 9102 libraryPath = new File(cachePath, LIB_DIR_NAME).getPath(); 9103 packagePath = new File(cachePath, RES_FILE_NAME).getPath(); 9104 9105 if (isFwdLocked()) { 9106 resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath(); 9107 } else { 9108 resourcePath = packagePath; 9109 } 9110 } 9111 9112 int doPostInstall(int status, int uid) { 9113 if (status != PackageManager.INSTALL_SUCCEEDED) { 9114 cleanUp(); 9115 } else { 9116 final int groupOwner; 9117 final String protectedFile; 9118 if (isFwdLocked()) { 9119 groupOwner = UserHandle.getSharedAppGid(uid); 9120 protectedFile = RES_FILE_NAME; 9121 } else { 9122 groupOwner = -1; 9123 protectedFile = null; 9124 } 9125 9126 if (uid < Process.FIRST_APPLICATION_UID 9127 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 9128 Slog.e(TAG, "Failed to finalize " + cid); 9129 PackageHelper.destroySdDir(cid); 9130 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9131 } 9132 9133 boolean mounted = PackageHelper.isContainerMounted(cid); 9134 if (!mounted) { 9135 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 9136 } 9137 } 9138 return status; 9139 } 9140 9141 private void cleanUp() { 9142 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 9143 9144 // Destroy secure container 9145 PackageHelper.destroySdDir(cid); 9146 } 9147 9148 void cleanUpResourcesLI() { 9149 String sourceFile = getCodePath(); 9150 // Remove dex file 9151 if (instructionSet == null) { 9152 throw new IllegalStateException("instructionSet == null"); 9153 } 9154 int retCode = mInstaller.rmdex(sourceFile, instructionSet); 9155 if (retCode < 0) { 9156 Slog.w(TAG, "Couldn't remove dex file for package: " 9157 + " at location " 9158 + sourceFile.toString() + ", retcode=" + retCode); 9159 // we don't consider this to be a failure of the core package deletion 9160 } 9161 cleanUp(); 9162 } 9163 9164 boolean matchContainer(String app) { 9165 if (cid.startsWith(app)) { 9166 return true; 9167 } 9168 return false; 9169 } 9170 9171 String getPackageName() { 9172 return getAsecPackageName(cid); 9173 } 9174 9175 boolean doPostDeleteLI(boolean delete) { 9176 boolean ret = false; 9177 boolean mounted = PackageHelper.isContainerMounted(cid); 9178 if (mounted) { 9179 // Unmount first 9180 ret = PackageHelper.unMountSdDir(cid); 9181 } 9182 if (ret && delete) { 9183 cleanUpResourcesLI(); 9184 } 9185 return ret; 9186 } 9187 9188 @Override 9189 int doPreCopy() { 9190 if (isFwdLocked()) { 9191 if (!PackageHelper.fixSdPermissions(cid, 9192 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 9193 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9194 } 9195 } 9196 9197 return PackageManager.INSTALL_SUCCEEDED; 9198 } 9199 9200 @Override 9201 int doPostCopy(int uid) { 9202 if (isFwdLocked()) { 9203 if (uid < Process.FIRST_APPLICATION_UID 9204 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 9205 RES_FILE_NAME)) { 9206 Slog.e(TAG, "Failed to finalize " + cid); 9207 PackageHelper.destroySdDir(cid); 9208 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 9209 } 9210 } 9211 9212 return PackageManager.INSTALL_SUCCEEDED; 9213 } 9214 }; 9215 9216 static String getAsecPackageName(String packageCid) { 9217 int idx = packageCid.lastIndexOf("-"); 9218 if (idx == -1) { 9219 return packageCid; 9220 } 9221 return packageCid.substring(0, idx); 9222 } 9223 9224 // Utility method used to create code paths based on package name and available index. 9225 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 9226 String idxStr = ""; 9227 int idx = 1; 9228 // Fall back to default value of idx=1 if prefix is not 9229 // part of oldCodePath 9230 if (oldCodePath != null) { 9231 String subStr = oldCodePath; 9232 // Drop the suffix right away 9233 if (subStr.endsWith(suffix)) { 9234 subStr = subStr.substring(0, subStr.length() - suffix.length()); 9235 } 9236 // If oldCodePath already contains prefix find out the 9237 // ending index to either increment or decrement. 9238 int sidx = subStr.lastIndexOf(prefix); 9239 if (sidx != -1) { 9240 subStr = subStr.substring(sidx + prefix.length()); 9241 if (subStr != null) { 9242 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 9243 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 9244 } 9245 try { 9246 idx = Integer.parseInt(subStr); 9247 if (idx <= 1) { 9248 idx++; 9249 } else { 9250 idx--; 9251 } 9252 } catch(NumberFormatException e) { 9253 } 9254 } 9255 } 9256 } 9257 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 9258 return prefix + idxStr; 9259 } 9260 9261 // Utility method used to ignore ADD/REMOVE events 9262 // by directory observer. 9263 private static boolean ignoreCodePath(String fullPathStr) { 9264 String apkName = getApkName(fullPathStr); 9265 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX); 9266 if (idx != -1 && ((idx+1) < apkName.length())) { 9267 // Make sure the package ends with a numeral 9268 String version = apkName.substring(idx+1); 9269 try { 9270 Integer.parseInt(version); 9271 return true; 9272 } catch (NumberFormatException e) {} 9273 } 9274 return false; 9275 } 9276 9277 // Utility method that returns the relative package path with respect 9278 // to the installation directory. Like say for /data/data/com.test-1.apk 9279 // string com.test-1 is returned. 9280 static String getApkName(String codePath) { 9281 if (codePath == null) { 9282 return null; 9283 } 9284 int sidx = codePath.lastIndexOf("/"); 9285 int eidx = codePath.lastIndexOf("."); 9286 if (eidx == -1) { 9287 eidx = codePath.length(); 9288 } else if (eidx == 0) { 9289 Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name"); 9290 return null; 9291 } 9292 return codePath.substring(sidx+1, eidx); 9293 } 9294 9295 class PackageInstalledInfo { 9296 String name; 9297 int uid; 9298 // The set of users that originally had this package installed. 9299 int[] origUsers; 9300 // The set of users that now have this package installed. 9301 int[] newUsers; 9302 PackageParser.Package pkg; 9303 int returnCode; 9304 PackageRemovedInfo removedInfo; 9305 } 9306 9307 /* 9308 * Install a non-existing package. 9309 */ 9310 private void installNewPackageLI(PackageParser.Package pkg, 9311 int parseFlags, int scanMode, UserHandle user, 9312 String installerPackageName, PackageInstalledInfo res) { 9313 // Remember this for later, in case we need to rollback this install 9314 String pkgName = pkg.packageName; 9315 9316 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 9317 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists(); 9318 synchronized(mPackages) { 9319 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 9320 // A package with the same name is already installed, though 9321 // it has been renamed to an older name. The package we 9322 // are trying to install should be installed as an update to 9323 // the existing one, but that has not been requested, so bail. 9324 Slog.w(TAG, "Attempt to re-install " + pkgName 9325 + " without first uninstalling package running as " 9326 + mSettings.mRenamedPackages.get(pkgName)); 9327 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 9328 return; 9329 } 9330 if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) { 9331 // Don't allow installation over an existing package with the same name. 9332 Slog.w(TAG, "Attempt to re-install " + pkgName 9333 + " without first uninstalling."); 9334 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 9335 return; 9336 } 9337 } 9338 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 9339 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode, 9340 System.currentTimeMillis(), user); 9341 if (newPackage == null) { 9342 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 9343 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 9344 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 9345 } 9346 } else { 9347 updateSettingsLI(newPackage, 9348 installerPackageName, 9349 null, null, 9350 res); 9351 // delete the partially installed application. the data directory will have to be 9352 // restored if it was already existing 9353 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 9354 // remove package from internal structures. Note that we want deletePackageX to 9355 // delete the package data and cache directories that it created in 9356 // scanPackageLocked, unless those directories existed before we even tried to 9357 // install. 9358 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 9359 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 9360 res.removedInfo, true); 9361 } 9362 } 9363 } 9364 9365 private void replacePackageLI(PackageParser.Package pkg, 9366 int parseFlags, int scanMode, UserHandle user, 9367 String installerPackageName, PackageInstalledInfo res) { 9368 9369 PackageParser.Package oldPackage; 9370 String pkgName = pkg.packageName; 9371 int[] allUsers; 9372 boolean[] perUserInstalled; 9373 9374 // First find the old package info and check signatures 9375 synchronized(mPackages) { 9376 oldPackage = mPackages.get(pkgName); 9377 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 9378 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 9379 != PackageManager.SIGNATURE_MATCH) { 9380 Slog.w(TAG, "New package has a different signature: " + pkgName); 9381 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 9382 return; 9383 } 9384 9385 // In case of rollback, remember per-user/profile install state 9386 PackageSetting ps = mSettings.mPackages.get(pkgName); 9387 allUsers = sUserManager.getUserIds(); 9388 perUserInstalled = new boolean[allUsers.length]; 9389 for (int i = 0; i < allUsers.length; i++) { 9390 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 9391 } 9392 } 9393 boolean sysPkg = (isSystemApp(oldPackage)); 9394 if (sysPkg) { 9395 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, 9396 user, allUsers, perUserInstalled, installerPackageName, res); 9397 } else { 9398 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, 9399 user, allUsers, perUserInstalled, installerPackageName, res); 9400 } 9401 } 9402 9403 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 9404 PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, 9405 int[] allUsers, boolean[] perUserInstalled, 9406 String installerPackageName, PackageInstalledInfo res) { 9407 PackageParser.Package newPackage = null; 9408 String pkgName = deletedPackage.packageName; 9409 boolean deletedPkg = true; 9410 boolean updatedSettings = false; 9411 9412 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 9413 + deletedPackage); 9414 long origUpdateTime; 9415 if (pkg.mExtras != null) { 9416 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 9417 } else { 9418 origUpdateTime = 0; 9419 } 9420 9421 // First delete the existing package while retaining the data directory 9422 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 9423 res.removedInfo, true)) { 9424 // If the existing package wasn't successfully deleted 9425 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 9426 deletedPkg = false; 9427 } else { 9428 // Successfully deleted the old package. Now proceed with re-installation 9429 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 9430 newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME, 9431 System.currentTimeMillis(), user); 9432 if (newPackage == null) { 9433 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 9434 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 9435 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 9436 } 9437 } else { 9438 updateSettingsLI(newPackage, 9439 installerPackageName, 9440 allUsers, perUserInstalled, 9441 res); 9442 updatedSettings = true; 9443 } 9444 } 9445 9446 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 9447 // remove package from internal structures. Note that we want deletePackageX to 9448 // delete the package data and cache directories that it created in 9449 // scanPackageLocked, unless those directories existed before we even tried to 9450 // install. 9451 if(updatedSettings) { 9452 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 9453 deletePackageLI( 9454 pkgName, null, true, allUsers, perUserInstalled, 9455 PackageManager.DELETE_KEEP_DATA, 9456 res.removedInfo, true); 9457 } 9458 // Since we failed to install the new package we need to restore the old 9459 // package that we deleted. 9460 if(deletedPkg) { 9461 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 9462 File restoreFile = new File(deletedPackage.mPath); 9463 // Parse old package 9464 boolean oldOnSd = isExternal(deletedPackage); 9465 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 9466 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) | 9467 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0); 9468 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE 9469 | SCAN_UPDATE_TIME; 9470 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode, 9471 origUpdateTime, null) == null) { 9472 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade"); 9473 return; 9474 } 9475 // Restore of old package succeeded. Update permissions. 9476 // writer 9477 synchronized (mPackages) { 9478 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 9479 UPDATE_PERMISSIONS_ALL); 9480 // can downgrade to reader 9481 mSettings.writeLPr(); 9482 } 9483 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 9484 } 9485 } 9486 } 9487 9488 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 9489 PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, 9490 int[] allUsers, boolean[] perUserInstalled, 9491 String installerPackageName, PackageInstalledInfo res) { 9492 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 9493 + ", old=" + deletedPackage); 9494 PackageParser.Package newPackage = null; 9495 boolean updatedSettings = false; 9496 parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING | 9497 PackageParser.PARSE_IS_SYSTEM; 9498 if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) { 9499 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 9500 } 9501 String packageName = deletedPackage.packageName; 9502 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 9503 if (packageName == null) { 9504 Slog.w(TAG, "Attempt to delete null packageName."); 9505 return; 9506 } 9507 PackageParser.Package oldPkg; 9508 PackageSetting oldPkgSetting; 9509 // reader 9510 synchronized (mPackages) { 9511 oldPkg = mPackages.get(packageName); 9512 oldPkgSetting = mSettings.mPackages.get(packageName); 9513 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 9514 (oldPkgSetting == null)) { 9515 Slog.w(TAG, "Couldn't find package:"+packageName+" information"); 9516 return; 9517 } 9518 } 9519 9520 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); 9521 9522 res.removedInfo.uid = oldPkg.applicationInfo.uid; 9523 res.removedInfo.removedPackage = packageName; 9524 // Remove existing system package 9525 removePackageLI(oldPkgSetting, true); 9526 // writer 9527 synchronized (mPackages) { 9528 if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) { 9529 // We didn't need to disable the .apk as a current system package, 9530 // which means we are replacing another update that is already 9531 // installed. We need to make sure to delete the older one's .apk. 9532 res.removedInfo.args = createInstallArgs(0, 9533 deletedPackage.applicationInfo.sourceDir, 9534 deletedPackage.applicationInfo.publicSourceDir, 9535 deletedPackage.applicationInfo.nativeLibraryDir, 9536 getAppInstructionSet(deletedPackage.applicationInfo)); 9537 } else { 9538 res.removedInfo.args = null; 9539 } 9540 } 9541 9542 // Successfully disabled the old package. Now proceed with re-installation 9543 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 9544 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 9545 newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user); 9546 if (newPackage == null) { 9547 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 9548 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 9549 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 9550 } 9551 } else { 9552 if (newPackage.mExtras != null) { 9553 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras; 9554 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 9555 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 9556 } 9557 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); 9558 updatedSettings = true; 9559 } 9560 9561 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 9562 // Re installation failed. Restore old information 9563 // Remove new pkg information 9564 if (newPackage != null) { 9565 removeInstalledPackageLI(newPackage, true); 9566 } 9567 // Add back the old system package 9568 scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user); 9569 // Restore the old system information in Settings 9570 synchronized(mPackages) { 9571 if (updatedSettings) { 9572 mSettings.enableSystemPackageLPw(packageName); 9573 mSettings.setInstallerPackageName(packageName, 9574 oldPkgSetting.installerPackageName); 9575 } 9576 mSettings.writeLPr(); 9577 } 9578 } 9579 } 9580 9581 // Utility method used to move dex files during install. 9582 private int moveDexFilesLI(PackageParser.Package newPackage) { 9583 if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 9584 final String instructionSet = getAppInstructionSet(newPackage.applicationInfo); 9585 int retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath, 9586 instructionSet); 9587 if (retCode != 0) { 9588 /* 9589 * Programs may be lazily run through dexopt, so the 9590 * source may not exist. However, something seems to 9591 * have gone wrong, so note that dexopt needs to be 9592 * run again and remove the source file. In addition, 9593 * remove the target to make sure there isn't a stale 9594 * file from a previous version of the package. 9595 */ 9596 newPackage.mDexOptNeeded = true; 9597 mInstaller.rmdex(newPackage.mScanPath, instructionSet); 9598 mInstaller.rmdex(newPackage.mPath, instructionSet); 9599 } 9600 } 9601 return PackageManager.INSTALL_SUCCEEDED; 9602 } 9603 9604 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 9605 int[] allUsers, boolean[] perUserInstalled, 9606 PackageInstalledInfo res) { 9607 String pkgName = newPackage.packageName; 9608 synchronized (mPackages) { 9609 //write settings. the installStatus will be incomplete at this stage. 9610 //note that the new package setting would have already been 9611 //added to mPackages. It hasn't been persisted yet. 9612 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 9613 mSettings.writeLPr(); 9614 } 9615 9616 if ((res.returnCode = moveDexFilesLI(newPackage)) 9617 != PackageManager.INSTALL_SUCCEEDED) { 9618 // Discontinue if moving dex files failed. 9619 return; 9620 } 9621 9622 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.mPath); 9623 9624 synchronized (mPackages) { 9625 updatePermissionsLPw(newPackage.packageName, newPackage, 9626 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 9627 ? UPDATE_PERMISSIONS_ALL : 0)); 9628 // For system-bundled packages, we assume that installing an upgraded version 9629 // of the package implies that the user actually wants to run that new code, 9630 // so we enable the package. 9631 if (isSystemApp(newPackage)) { 9632 // NB: implicit assumption that system package upgrades apply to all users 9633 if (DEBUG_INSTALL) { 9634 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 9635 } 9636 PackageSetting ps = mSettings.mPackages.get(pkgName); 9637 if (ps != null) { 9638 if (res.origUsers != null) { 9639 for (int userHandle : res.origUsers) { 9640 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 9641 userHandle, installerPackageName); 9642 } 9643 } 9644 // Also convey the prior install/uninstall state 9645 if (allUsers != null && perUserInstalled != null) { 9646 for (int i = 0; i < allUsers.length; i++) { 9647 if (DEBUG_INSTALL) { 9648 Slog.d(TAG, " user " + allUsers[i] 9649 + " => " + perUserInstalled[i]); 9650 } 9651 ps.setInstalled(perUserInstalled[i], allUsers[i]); 9652 } 9653 // these install state changes will be persisted in the 9654 // upcoming call to mSettings.writeLPr(). 9655 } 9656 } 9657 } 9658 res.name = pkgName; 9659 res.uid = newPackage.applicationInfo.uid; 9660 res.pkg = newPackage; 9661 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 9662 mSettings.setInstallerPackageName(pkgName, installerPackageName); 9663 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 9664 //to update install status 9665 mSettings.writeLPr(); 9666 } 9667 } 9668 9669 private void installPackageLI(InstallArgs args, 9670 boolean newInstall, PackageInstalledInfo res) { 9671 int pFlags = args.flags; 9672 String installerPackageName = args.installerPackageName; 9673 File tmpPackageFile = new File(args.getCodePath()); 9674 boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 9675 boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0); 9676 boolean replace = false; 9677 int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE 9678 | (newInstall ? SCAN_NEW_INSTALL : 0); 9679 // Result object to be returned 9680 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 9681 9682 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 9683 // Retrieve PackageSettings and parse package 9684 int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 9685 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 9686 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0); 9687 PackageParser pp = new PackageParser(tmpPackageFile.getPath()); 9688 pp.setSeparateProcesses(mSeparateProcesses); 9689 final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile, 9690 null, mMetrics, parseFlags); 9691 if (pkg == null) { 9692 res.returnCode = pp.getParseError(); 9693 return; 9694 } 9695 String pkgName = res.name = pkg.packageName; 9696 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 9697 if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) { 9698 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY; 9699 return; 9700 } 9701 } 9702 if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) { 9703 res.returnCode = pp.getParseError(); 9704 return; 9705 } 9706 9707 /* If the installer passed in a manifest digest, compare it now. */ 9708 if (args.manifestDigest != null) { 9709 if (DEBUG_INSTALL) { 9710 final String parsedManifest = pkg.manifestDigest == null ? "null" 9711 : pkg.manifestDigest.toString(); 9712 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 9713 + parsedManifest); 9714 } 9715 9716 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 9717 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 9718 return; 9719 } 9720 } else if (DEBUG_INSTALL) { 9721 final String parsedManifest = pkg.manifestDigest == null 9722 ? "null" : pkg.manifestDigest.toString(); 9723 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 9724 } 9725 9726 // Get rid of all references to package scan path via parser. 9727 pp = null; 9728 String oldCodePath = null; 9729 boolean systemApp = false; 9730 synchronized (mPackages) { 9731 // Check if installing already existing package 9732 if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 9733 String oldName = mSettings.mRenamedPackages.get(pkgName); 9734 if (pkg.mOriginalPackages != null 9735 && pkg.mOriginalPackages.contains(oldName) 9736 && mPackages.containsKey(oldName)) { 9737 // This package is derived from an original package, 9738 // and this device has been updating from that original 9739 // name. We must continue using the original name, so 9740 // rename the new package here. 9741 pkg.setPackageName(oldName); 9742 pkgName = pkg.packageName; 9743 replace = true; 9744 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 9745 + oldName + " pkgName=" + pkgName); 9746 } else if (mPackages.containsKey(pkgName)) { 9747 // This package, under its official name, already exists 9748 // on the device; we should replace it. 9749 replace = true; 9750 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 9751 } 9752 } 9753 PackageSetting ps = mSettings.mPackages.get(pkgName); 9754 if (ps != null) { 9755 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 9756 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 9757 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 9758 systemApp = (ps.pkg.applicationInfo.flags & 9759 ApplicationInfo.FLAG_SYSTEM) != 0; 9760 } 9761 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 9762 } 9763 } 9764 9765 if (systemApp && onSd) { 9766 // Disable updates to system apps on sdcard 9767 Slog.w(TAG, "Cannot install updates to system apps on sdcard"); 9768 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9769 return; 9770 } 9771 9772 if (!args.doRename(res.returnCode, pkgName, oldCodePath)) { 9773 res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9774 return; 9775 } 9776 // Set application objects path explicitly after the rename 9777 setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath()); 9778 pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath(); 9779 if (replace) { 9780 replacePackageLI(pkg, parseFlags, scanMode, args.user, 9781 installerPackageName, res); 9782 } else { 9783 installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user, 9784 installerPackageName, res); 9785 } 9786 synchronized (mPackages) { 9787 final PackageSetting ps = mSettings.mPackages.get(pkgName); 9788 if (ps != null) { 9789 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 9790 } 9791 } 9792 } 9793 9794 private static boolean isForwardLocked(PackageParser.Package pkg) { 9795 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 9796 } 9797 9798 9799 private boolean isForwardLocked(PackageSetting ps) { 9800 return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 9801 } 9802 9803 private static boolean isExternal(PackageParser.Package pkg) { 9804 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 9805 } 9806 9807 private static boolean isExternal(PackageSetting ps) { 9808 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 9809 } 9810 9811 private static boolean isSystemApp(PackageParser.Package pkg) { 9812 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 9813 } 9814 9815 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 9816 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0; 9817 } 9818 9819 private static boolean isSystemApp(ApplicationInfo info) { 9820 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 9821 } 9822 9823 private static boolean isSystemApp(PackageSetting ps) { 9824 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 9825 } 9826 9827 private static boolean isUpdatedSystemApp(PackageSetting ps) { 9828 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 9829 } 9830 9831 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) { 9832 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 9833 } 9834 9835 private int packageFlagsToInstallFlags(PackageSetting ps) { 9836 int installFlags = 0; 9837 if (isExternal(ps)) { 9838 installFlags |= PackageManager.INSTALL_EXTERNAL; 9839 } 9840 if (isForwardLocked(ps)) { 9841 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 9842 } 9843 return installFlags; 9844 } 9845 9846 private void deleteTempPackageFiles() { 9847 final FilenameFilter filter = new FilenameFilter() { 9848 public boolean accept(File dir, String name) { 9849 return name.startsWith("vmdl") && name.endsWith(".tmp"); 9850 } 9851 }; 9852 deleteTempPackageFilesInDirectory(mAppInstallDir, filter); 9853 deleteTempPackageFilesInDirectory(mDrmAppPrivateInstallDir, filter); 9854 } 9855 9856 private static final void deleteTempPackageFilesInDirectory(File directory, 9857 FilenameFilter filter) { 9858 final String[] tmpFilesList = directory.list(filter); 9859 if (tmpFilesList == null) { 9860 return; 9861 } 9862 for (int i = 0; i < tmpFilesList.length; i++) { 9863 final File tmpFile = new File(directory, tmpFilesList[i]); 9864 tmpFile.delete(); 9865 } 9866 } 9867 9868 private File createTempPackageFile(File installDir) { 9869 File tmpPackageFile; 9870 try { 9871 tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir); 9872 } catch (IOException e) { 9873 Slog.e(TAG, "Couldn't create temp file for downloaded package file."); 9874 return null; 9875 } 9876 try { 9877 FileUtils.setPermissions( 9878 tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR, 9879 -1, -1); 9880 if (!SELinux.restorecon(tmpPackageFile)) { 9881 return null; 9882 } 9883 } catch (IOException e) { 9884 Slog.e(TAG, "Trouble getting the canoncical path for a temp file."); 9885 return null; 9886 } 9887 return tmpPackageFile; 9888 } 9889 9890 @Override 9891 public void deletePackageAsUser(final String packageName, 9892 final IPackageDeleteObserver observer, 9893 final int userId, final int flags) { 9894 mContext.enforceCallingOrSelfPermission( 9895 android.Manifest.permission.DELETE_PACKAGES, null); 9896 final int uid = Binder.getCallingUid(); 9897 if (UserHandle.getUserId(uid) != userId) { 9898 mContext.enforceCallingPermission( 9899 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 9900 "deletePackage for user " + userId); 9901 } 9902 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 9903 try { 9904 observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED); 9905 } catch (RemoteException re) { 9906 } 9907 return; 9908 } 9909 9910 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 9911 // Queue up an async operation since the package deletion may take a little while. 9912 mHandler.post(new Runnable() { 9913 public void run() { 9914 mHandler.removeCallbacks(this); 9915 final int returnCode = deletePackageX(packageName, userId, flags); 9916 if (observer != null) { 9917 try { 9918 observer.packageDeleted(packageName, returnCode); 9919 } catch (RemoteException e) { 9920 Log.i(TAG, "Observer no longer exists."); 9921 } //end catch 9922 } //end if 9923 } //end run 9924 }); 9925 } 9926 9927 private boolean isPackageDeviceAdmin(String packageName, int userId) { 9928 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 9929 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 9930 try { 9931 if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId) 9932 || dpm.isDeviceOwner(packageName))) { 9933 return true; 9934 } 9935 } catch (RemoteException e) { 9936 } 9937 return false; 9938 } 9939 9940 /** 9941 * This method is an internal method that could be get invoked either 9942 * to delete an installed package or to clean up a failed installation. 9943 * After deleting an installed package, a broadcast is sent to notify any 9944 * listeners that the package has been installed. For cleaning up a failed 9945 * installation, the broadcast is not necessary since the package's 9946 * installation wouldn't have sent the initial broadcast either 9947 * The key steps in deleting a package are 9948 * deleting the package information in internal structures like mPackages, 9949 * deleting the packages base directories through installd 9950 * updating mSettings to reflect current status 9951 * persisting settings for later use 9952 * sending a broadcast if necessary 9953 */ 9954 private int deletePackageX(String packageName, int userId, int flags) { 9955 final PackageRemovedInfo info = new PackageRemovedInfo(); 9956 final boolean res; 9957 9958 if (isPackageDeviceAdmin(packageName, userId)) { 9959 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 9960 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 9961 } 9962 9963 boolean removedForAllUsers = false; 9964 boolean systemUpdate = false; 9965 9966 // for the uninstall-updates case and restricted profiles, remember the per- 9967 // userhandle installed state 9968 int[] allUsers; 9969 boolean[] perUserInstalled; 9970 synchronized (mPackages) { 9971 PackageSetting ps = mSettings.mPackages.get(packageName); 9972 allUsers = sUserManager.getUserIds(); 9973 perUserInstalled = new boolean[allUsers.length]; 9974 for (int i = 0; i < allUsers.length; i++) { 9975 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 9976 } 9977 } 9978 9979 synchronized (mInstallLock) { 9980 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 9981 res = deletePackageLI(packageName, 9982 (flags & PackageManager.DELETE_ALL_USERS) != 0 9983 ? UserHandle.ALL : new UserHandle(userId), 9984 true, allUsers, perUserInstalled, 9985 flags | REMOVE_CHATTY, info, true); 9986 systemUpdate = info.isRemovedPackageSystemUpdate; 9987 if (res && !systemUpdate && mPackages.get(packageName) == null) { 9988 removedForAllUsers = true; 9989 } 9990 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 9991 + " removedForAllUsers=" + removedForAllUsers); 9992 } 9993 9994 if (res) { 9995 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 9996 9997 // If the removed package was a system update, the old system package 9998 // was re-enabled; we need to broadcast this information 9999 if (systemUpdate) { 10000 Bundle extras = new Bundle(1); 10001 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 10002 ? info.removedAppId : info.uid); 10003 extras.putBoolean(Intent.EXTRA_REPLACING, true); 10004 10005 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 10006 extras, null, null, null); 10007 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 10008 extras, null, null, null); 10009 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 10010 null, packageName, null, null); 10011 } 10012 } 10013 // Force a gc here. 10014 Runtime.getRuntime().gc(); 10015 // Delete the resources here after sending the broadcast to let 10016 // other processes clean up before deleting resources. 10017 if (info.args != null) { 10018 synchronized (mInstallLock) { 10019 info.args.doPostDeleteLI(true); 10020 } 10021 } 10022 10023 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 10024 } 10025 10026 static class PackageRemovedInfo { 10027 String removedPackage; 10028 int uid = -1; 10029 int removedAppId = -1; 10030 int[] removedUsers = null; 10031 boolean isRemovedPackageSystemUpdate = false; 10032 // Clean up resources deleted packages. 10033 InstallArgs args = null; 10034 10035 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 10036 Bundle extras = new Bundle(1); 10037 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 10038 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 10039 if (replacing) { 10040 extras.putBoolean(Intent.EXTRA_REPLACING, true); 10041 } 10042 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 10043 if (removedPackage != null) { 10044 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 10045 extras, null, null, removedUsers); 10046 if (fullRemove && !replacing) { 10047 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 10048 extras, null, null, removedUsers); 10049 } 10050 } 10051 if (removedAppId >= 0) { 10052 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 10053 removedUsers); 10054 } 10055 } 10056 } 10057 10058 /* 10059 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 10060 * flag is not set, the data directory is removed as well. 10061 * make sure this flag is set for partially installed apps. If not its meaningless to 10062 * delete a partially installed application. 10063 */ 10064 private void removePackageDataLI(PackageSetting ps, 10065 int[] allUserHandles, boolean[] perUserInstalled, 10066 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 10067 String packageName = ps.name; 10068 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 10069 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 10070 // Retrieve object to delete permissions for shared user later on 10071 final PackageSetting deletedPs; 10072 // reader 10073 synchronized (mPackages) { 10074 deletedPs = mSettings.mPackages.get(packageName); 10075 if (outInfo != null) { 10076 outInfo.removedPackage = packageName; 10077 outInfo.removedUsers = deletedPs != null 10078 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 10079 : null; 10080 } 10081 } 10082 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 10083 removeDataDirsLI(packageName); 10084 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 10085 } 10086 // writer 10087 synchronized (mPackages) { 10088 if (deletedPs != null) { 10089 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 10090 if (outInfo != null) { 10091 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 10092 } 10093 if (deletedPs != null) { 10094 updatePermissionsLPw(deletedPs.name, null, 0); 10095 if (deletedPs.sharedUser != null) { 10096 // remove permissions associated with package 10097 mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids); 10098 } 10099 } 10100 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 10101 } 10102 // make sure to preserve per-user disabled state if this removal was just 10103 // a downgrade of a system app to the factory package 10104 if (allUserHandles != null && perUserInstalled != null) { 10105 if (DEBUG_REMOVE) { 10106 Slog.d(TAG, "Propagating install state across downgrade"); 10107 } 10108 for (int i = 0; i < allUserHandles.length; i++) { 10109 if (DEBUG_REMOVE) { 10110 Slog.d(TAG, " user " + allUserHandles[i] 10111 + " => " + perUserInstalled[i]); 10112 } 10113 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 10114 } 10115 } 10116 } 10117 // can downgrade to reader 10118 if (writeSettings) { 10119 // Save settings now 10120 mSettings.writeLPr(); 10121 } 10122 } 10123 if (outInfo != null) { 10124 // A user ID was deleted here. Go through all users and remove it 10125 // from KeyStore. 10126 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 10127 } 10128 } 10129 10130 static boolean locationIsPrivileged(File path) { 10131 try { 10132 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 10133 .getCanonicalPath(); 10134 return path.getCanonicalPath().startsWith(privilegedAppDir); 10135 } catch (IOException e) { 10136 Slog.e(TAG, "Unable to access code path " + path); 10137 } 10138 return false; 10139 } 10140 10141 /* 10142 * Tries to delete system package. 10143 */ 10144 private boolean deleteSystemPackageLI(PackageSetting newPs, 10145 int[] allUserHandles, boolean[] perUserInstalled, 10146 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 10147 final boolean applyUserRestrictions 10148 = (allUserHandles != null) && (perUserInstalled != null); 10149 PackageSetting disabledPs = null; 10150 // Confirm if the system package has been updated 10151 // An updated system app can be deleted. This will also have to restore 10152 // the system pkg from system partition 10153 // reader 10154 synchronized (mPackages) { 10155 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 10156 } 10157 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 10158 + " disabledPs=" + disabledPs); 10159 if (disabledPs == null) { 10160 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 10161 return false; 10162 } else if (DEBUG_REMOVE) { 10163 Slog.d(TAG, "Deleting system pkg from data partition"); 10164 } 10165 if (DEBUG_REMOVE) { 10166 if (applyUserRestrictions) { 10167 Slog.d(TAG, "Remembering install states:"); 10168 for (int i = 0; i < allUserHandles.length; i++) { 10169 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 10170 } 10171 } 10172 } 10173 // Delete the updated package 10174 outInfo.isRemovedPackageSystemUpdate = true; 10175 if (disabledPs.versionCode < newPs.versionCode) { 10176 // Delete data for downgrades 10177 flags &= ~PackageManager.DELETE_KEEP_DATA; 10178 } else { 10179 // Preserve data by setting flag 10180 flags |= PackageManager.DELETE_KEEP_DATA; 10181 } 10182 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 10183 allUserHandles, perUserInstalled, outInfo, writeSettings); 10184 if (!ret) { 10185 return false; 10186 } 10187 // writer 10188 synchronized (mPackages) { 10189 // Reinstate the old system package 10190 mSettings.enableSystemPackageLPw(newPs.name); 10191 // Remove any native libraries from the upgraded package. 10192 NativeLibraryHelper.removeNativeBinariesLI(newPs.nativeLibraryPathString); 10193 } 10194 // Install the system package 10195 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 10196 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 10197 if (locationIsPrivileged(disabledPs.codePath)) { 10198 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 10199 } 10200 PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath, 10201 parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null); 10202 10203 if (newPkg == null) { 10204 Slog.w(TAG, "Failed to restore system package:" + newPs.name 10205 + " with error:" + mLastScanError); 10206 return false; 10207 } 10208 // writer 10209 synchronized (mPackages) { 10210 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 10211 setInternalAppNativeLibraryPath(newPkg, ps); 10212 updatePermissionsLPw(newPkg.packageName, newPkg, 10213 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 10214 if (applyUserRestrictions) { 10215 if (DEBUG_REMOVE) { 10216 Slog.d(TAG, "Propagating install state across reinstall"); 10217 } 10218 for (int i = 0; i < allUserHandles.length; i++) { 10219 if (DEBUG_REMOVE) { 10220 Slog.d(TAG, " user " + allUserHandles[i] 10221 + " => " + perUserInstalled[i]); 10222 } 10223 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 10224 } 10225 // Regardless of writeSettings we need to ensure that this restriction 10226 // state propagation is persisted 10227 mSettings.writeAllUsersPackageRestrictionsLPr(); 10228 } 10229 // can downgrade to reader here 10230 if (writeSettings) { 10231 mSettings.writeLPr(); 10232 } 10233 } 10234 return true; 10235 } 10236 10237 private boolean deleteInstalledPackageLI(PackageSetting ps, 10238 boolean deleteCodeAndResources, int flags, 10239 int[] allUserHandles, boolean[] perUserInstalled, 10240 PackageRemovedInfo outInfo, boolean writeSettings) { 10241 if (outInfo != null) { 10242 outInfo.uid = ps.appId; 10243 } 10244 10245 // Delete package data from internal structures and also remove data if flag is set 10246 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 10247 10248 // Delete application code and resources 10249 if (deleteCodeAndResources && (outInfo != null)) { 10250 outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString, 10251 ps.resourcePathString, ps.nativeLibraryPathString, 10252 getAppInstructionSetFromSettings(ps)); 10253 } 10254 return true; 10255 } 10256 10257 /* 10258 * This method handles package deletion in general 10259 */ 10260 private boolean deletePackageLI(String packageName, UserHandle user, 10261 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 10262 int flags, PackageRemovedInfo outInfo, 10263 boolean writeSettings) { 10264 if (packageName == null) { 10265 Slog.w(TAG, "Attempt to delete null packageName."); 10266 return false; 10267 } 10268 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 10269 PackageSetting ps; 10270 boolean dataOnly = false; 10271 int removeUser = -1; 10272 int appId = -1; 10273 synchronized (mPackages) { 10274 ps = mSettings.mPackages.get(packageName); 10275 if (ps == null) { 10276 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 10277 return false; 10278 } 10279 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 10280 && user.getIdentifier() != UserHandle.USER_ALL) { 10281 // The caller is asking that the package only be deleted for a single 10282 // user. To do this, we just mark its uninstalled state and delete 10283 // its data. If this is a system app, we only allow this to happen if 10284 // they have set the special DELETE_SYSTEM_APP which requests different 10285 // semantics than normal for uninstalling system apps. 10286 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 10287 ps.setUserState(user.getIdentifier(), 10288 COMPONENT_ENABLED_STATE_DEFAULT, 10289 false, //installed 10290 true, //stopped 10291 true, //notLaunched 10292 false, //blocked 10293 null, null, null); 10294 if (!isSystemApp(ps)) { 10295 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 10296 // Other user still have this package installed, so all 10297 // we need to do is clear this user's data and save that 10298 // it is uninstalled. 10299 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 10300 removeUser = user.getIdentifier(); 10301 appId = ps.appId; 10302 mSettings.writePackageRestrictionsLPr(removeUser); 10303 } else { 10304 // We need to set it back to 'installed' so the uninstall 10305 // broadcasts will be sent correctly. 10306 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 10307 ps.setInstalled(true, user.getIdentifier()); 10308 } 10309 } else { 10310 // This is a system app, so we assume that the 10311 // other users still have this package installed, so all 10312 // we need to do is clear this user's data and save that 10313 // it is uninstalled. 10314 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 10315 removeUser = user.getIdentifier(); 10316 appId = ps.appId; 10317 mSettings.writePackageRestrictionsLPr(removeUser); 10318 } 10319 } 10320 } 10321 10322 if (removeUser >= 0) { 10323 // From above, we determined that we are deleting this only 10324 // for a single user. Continue the work here. 10325 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 10326 if (outInfo != null) { 10327 outInfo.removedPackage = packageName; 10328 outInfo.removedAppId = appId; 10329 outInfo.removedUsers = new int[] {removeUser}; 10330 } 10331 mInstaller.clearUserData(packageName, removeUser); 10332 removeKeystoreDataIfNeeded(removeUser, appId); 10333 schedulePackageCleaning(packageName, removeUser, false); 10334 return true; 10335 } 10336 10337 if (dataOnly) { 10338 // Delete application data first 10339 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 10340 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 10341 return true; 10342 } 10343 10344 boolean ret = false; 10345 mSettings.mKeySetManager.removeAppKeySetData(packageName); 10346 if (isSystemApp(ps)) { 10347 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 10348 // When an updated system application is deleted we delete the existing resources as well and 10349 // fall back to existing code in system partition 10350 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 10351 flags, outInfo, writeSettings); 10352 } else { 10353 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 10354 // Kill application pre-emptively especially for apps on sd. 10355 killApplication(packageName, ps.appId, "uninstall pkg"); 10356 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 10357 allUserHandles, perUserInstalled, 10358 outInfo, writeSettings); 10359 } 10360 10361 return ret; 10362 } 10363 10364 private final class ClearStorageConnection implements ServiceConnection { 10365 IMediaContainerService mContainerService; 10366 10367 @Override 10368 public void onServiceConnected(ComponentName name, IBinder service) { 10369 synchronized (this) { 10370 mContainerService = IMediaContainerService.Stub.asInterface(service); 10371 notifyAll(); 10372 } 10373 } 10374 10375 @Override 10376 public void onServiceDisconnected(ComponentName name) { 10377 } 10378 } 10379 10380 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 10381 final boolean mounted; 10382 if (Environment.isExternalStorageEmulated()) { 10383 mounted = true; 10384 } else { 10385 final String status = Environment.getExternalStorageState(); 10386 10387 mounted = status.equals(Environment.MEDIA_MOUNTED) 10388 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 10389 } 10390 10391 if (!mounted) { 10392 return; 10393 } 10394 10395 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 10396 int[] users; 10397 if (userId == UserHandle.USER_ALL) { 10398 users = sUserManager.getUserIds(); 10399 } else { 10400 users = new int[] { userId }; 10401 } 10402 final ClearStorageConnection conn = new ClearStorageConnection(); 10403 if (mContext.bindServiceAsUser( 10404 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 10405 try { 10406 for (int curUser : users) { 10407 long timeout = SystemClock.uptimeMillis() + 5000; 10408 synchronized (conn) { 10409 long now = SystemClock.uptimeMillis(); 10410 while (conn.mContainerService == null && now < timeout) { 10411 try { 10412 conn.wait(timeout - now); 10413 } catch (InterruptedException e) { 10414 } 10415 } 10416 } 10417 if (conn.mContainerService == null) { 10418 return; 10419 } 10420 10421 final UserEnvironment userEnv = new UserEnvironment(curUser); 10422 clearDirectory(conn.mContainerService, 10423 userEnv.buildExternalStorageAppCacheDirs(packageName)); 10424 if (allData) { 10425 clearDirectory(conn.mContainerService, 10426 userEnv.buildExternalStorageAppDataDirs(packageName)); 10427 clearDirectory(conn.mContainerService, 10428 userEnv.buildExternalStorageAppMediaDirs(packageName)); 10429 } 10430 } 10431 } finally { 10432 mContext.unbindService(conn); 10433 } 10434 } 10435 } 10436 10437 @Override 10438 public void clearApplicationUserData(final String packageName, 10439 final IPackageDataObserver observer, final int userId) { 10440 mContext.enforceCallingOrSelfPermission( 10441 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 10442 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data"); 10443 // Queue up an async operation since the package deletion may take a little while. 10444 mHandler.post(new Runnable() { 10445 public void run() { 10446 mHandler.removeCallbacks(this); 10447 final boolean succeeded; 10448 synchronized (mInstallLock) { 10449 succeeded = clearApplicationUserDataLI(packageName, userId); 10450 } 10451 clearExternalStorageDataSync(packageName, userId, true); 10452 if (succeeded) { 10453 // invoke DeviceStorageMonitor's update method to clear any notifications 10454 DeviceStorageMonitorInternal 10455 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 10456 if (dsm != null) { 10457 dsm.checkMemory(); 10458 } 10459 } 10460 if(observer != null) { 10461 try { 10462 observer.onRemoveCompleted(packageName, succeeded); 10463 } catch (RemoteException e) { 10464 Log.i(TAG, "Observer no longer exists."); 10465 } 10466 } //end if observer 10467 } //end run 10468 }); 10469 } 10470 10471 private boolean clearApplicationUserDataLI(String packageName, int userId) { 10472 if (packageName == null) { 10473 Slog.w(TAG, "Attempt to delete null packageName."); 10474 return false; 10475 } 10476 PackageParser.Package p; 10477 boolean dataOnly = false; 10478 final int appId; 10479 synchronized (mPackages) { 10480 p = mPackages.get(packageName); 10481 if (p == null) { 10482 dataOnly = true; 10483 PackageSetting ps = mSettings.mPackages.get(packageName); 10484 if ((ps == null) || (ps.pkg == null)) { 10485 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 10486 return false; 10487 } 10488 p = ps.pkg; 10489 } 10490 if (!dataOnly) { 10491 // need to check this only for fully installed applications 10492 if (p == null) { 10493 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 10494 return false; 10495 } 10496 final ApplicationInfo applicationInfo = p.applicationInfo; 10497 if (applicationInfo == null) { 10498 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 10499 return false; 10500 } 10501 } 10502 if (p != null && p.applicationInfo != null) { 10503 appId = p.applicationInfo.uid; 10504 } else { 10505 appId = -1; 10506 } 10507 } 10508 int retCode = mInstaller.clearUserData(packageName, userId); 10509 if (retCode < 0) { 10510 Slog.w(TAG, "Couldn't remove cache files for package: " 10511 + packageName); 10512 return false; 10513 } 10514 removeKeystoreDataIfNeeded(userId, appId); 10515 return true; 10516 } 10517 10518 /** 10519 * Remove entries from the keystore daemon. Will only remove it if the 10520 * {@code appId} is valid. 10521 */ 10522 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 10523 if (appId < 0) { 10524 return; 10525 } 10526 10527 final KeyStore keyStore = KeyStore.getInstance(); 10528 if (keyStore != null) { 10529 if (userId == UserHandle.USER_ALL) { 10530 for (final int individual : sUserManager.getUserIds()) { 10531 keyStore.clearUid(UserHandle.getUid(individual, appId)); 10532 } 10533 } else { 10534 keyStore.clearUid(UserHandle.getUid(userId, appId)); 10535 } 10536 } else { 10537 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 10538 } 10539 } 10540 10541 @Override 10542 public void deleteApplicationCacheFiles(final String packageName, 10543 final IPackageDataObserver observer) { 10544 mContext.enforceCallingOrSelfPermission( 10545 android.Manifest.permission.DELETE_CACHE_FILES, null); 10546 // Queue up an async operation since the package deletion may take a little while. 10547 final int userId = UserHandle.getCallingUserId(); 10548 mHandler.post(new Runnable() { 10549 public void run() { 10550 mHandler.removeCallbacks(this); 10551 final boolean succeded; 10552 synchronized (mInstallLock) { 10553 succeded = deleteApplicationCacheFilesLI(packageName, userId); 10554 } 10555 clearExternalStorageDataSync(packageName, userId, false); 10556 if(observer != null) { 10557 try { 10558 observer.onRemoveCompleted(packageName, succeded); 10559 } catch (RemoteException e) { 10560 Log.i(TAG, "Observer no longer exists."); 10561 } 10562 } //end if observer 10563 } //end run 10564 }); 10565 } 10566 10567 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 10568 if (packageName == null) { 10569 Slog.w(TAG, "Attempt to delete null packageName."); 10570 return false; 10571 } 10572 PackageParser.Package p; 10573 synchronized (mPackages) { 10574 p = mPackages.get(packageName); 10575 } 10576 if (p == null) { 10577 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 10578 return false; 10579 } 10580 final ApplicationInfo applicationInfo = p.applicationInfo; 10581 if (applicationInfo == null) { 10582 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 10583 return false; 10584 } 10585 int retCode = mInstaller.deleteCacheFiles(packageName, userId); 10586 if (retCode < 0) { 10587 Slog.w(TAG, "Couldn't remove cache files for package: " 10588 + packageName + " u" + userId); 10589 return false; 10590 } 10591 return true; 10592 } 10593 10594 @Override 10595 public void getPackageSizeInfo(final String packageName, int userHandle, 10596 final IPackageStatsObserver observer) { 10597 mContext.enforceCallingOrSelfPermission( 10598 android.Manifest.permission.GET_PACKAGE_SIZE, null); 10599 10600 PackageStats stats = new PackageStats(packageName, userHandle); 10601 10602 /* 10603 * Queue up an async operation since the package measurement may take a 10604 * little while. 10605 */ 10606 Message msg = mHandler.obtainMessage(INIT_COPY); 10607 msg.obj = new MeasureParams(stats, observer); 10608 mHandler.sendMessage(msg); 10609 } 10610 10611 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 10612 PackageStats pStats) { 10613 if (packageName == null) { 10614 Slog.w(TAG, "Attempt to get size of null packageName."); 10615 return false; 10616 } 10617 PackageParser.Package p; 10618 boolean dataOnly = false; 10619 String libDirPath = null; 10620 String asecPath = null; 10621 PackageSetting ps = null; 10622 synchronized (mPackages) { 10623 p = mPackages.get(packageName); 10624 ps = mSettings.mPackages.get(packageName); 10625 if(p == null) { 10626 dataOnly = true; 10627 if((ps == null) || (ps.pkg == null)) { 10628 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 10629 return false; 10630 } 10631 p = ps.pkg; 10632 } 10633 if (ps != null) { 10634 libDirPath = ps.nativeLibraryPathString; 10635 } 10636 if (p != null && (isExternal(p) || isForwardLocked(p))) { 10637 String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir); 10638 if (secureContainerId != null) { 10639 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 10640 } 10641 } 10642 } 10643 String publicSrcDir = null; 10644 if(!dataOnly) { 10645 final ApplicationInfo applicationInfo = p.applicationInfo; 10646 if (applicationInfo == null) { 10647 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 10648 return false; 10649 } 10650 if (isForwardLocked(p)) { 10651 publicSrcDir = applicationInfo.publicSourceDir; 10652 } 10653 } 10654 int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath, 10655 publicSrcDir, asecPath, getAppInstructionSetFromSettings(ps), 10656 pStats); 10657 if (res < 0) { 10658 return false; 10659 } 10660 10661 // Fix-up for forward-locked applications in ASEC containers. 10662 if (!isExternal(p)) { 10663 pStats.codeSize += pStats.externalCodeSize; 10664 pStats.externalCodeSize = 0L; 10665 } 10666 10667 return true; 10668 } 10669 10670 10671 @Override 10672 public void addPackageToPreferred(String packageName) { 10673 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 10674 } 10675 10676 @Override 10677 public void removePackageFromPreferred(String packageName) { 10678 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 10679 } 10680 10681 @Override 10682 public List<PackageInfo> getPreferredPackages(int flags) { 10683 return new ArrayList<PackageInfo>(); 10684 } 10685 10686 private int getUidTargetSdkVersionLockedLPr(int uid) { 10687 Object obj = mSettings.getUserIdLPr(uid); 10688 if (obj instanceof SharedUserSetting) { 10689 final SharedUserSetting sus = (SharedUserSetting) obj; 10690 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 10691 final Iterator<PackageSetting> it = sus.packages.iterator(); 10692 while (it.hasNext()) { 10693 final PackageSetting ps = it.next(); 10694 if (ps.pkg != null) { 10695 int v = ps.pkg.applicationInfo.targetSdkVersion; 10696 if (v < vers) vers = v; 10697 } 10698 } 10699 return vers; 10700 } else if (obj instanceof PackageSetting) { 10701 final PackageSetting ps = (PackageSetting) obj; 10702 if (ps.pkg != null) { 10703 return ps.pkg.applicationInfo.targetSdkVersion; 10704 } 10705 } 10706 return Build.VERSION_CODES.CUR_DEVELOPMENT; 10707 } 10708 10709 @Override 10710 public void addPreferredActivity(IntentFilter filter, int match, 10711 ComponentName[] set, ComponentName activity, int userId) { 10712 addPreferredActivityInternal(filter, match, set, activity, true, userId); 10713 } 10714 10715 private void addPreferredActivityInternal(IntentFilter filter, int match, 10716 ComponentName[] set, ComponentName activity, boolean always, int userId) { 10717 // writer 10718 int callingUid = Binder.getCallingUid(); 10719 enforceCrossUserPermission(callingUid, userId, true, "add preferred activity"); 10720 if (filter.countActions() == 0) { 10721 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 10722 return; 10723 } 10724 synchronized (mPackages) { 10725 if (mContext.checkCallingOrSelfPermission( 10726 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 10727 != PackageManager.PERMISSION_GRANTED) { 10728 if (getUidTargetSdkVersionLockedLPr(callingUid) 10729 < Build.VERSION_CODES.FROYO) { 10730 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 10731 + callingUid); 10732 return; 10733 } 10734 mContext.enforceCallingOrSelfPermission( 10735 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10736 } 10737 10738 Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :"); 10739 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 10740 mSettings.editPreferredActivitiesLPw(userId).addFilter( 10741 new PreferredActivity(filter, match, set, activity, always)); 10742 mSettings.writePackageRestrictionsLPr(userId); 10743 } 10744 } 10745 10746 @Override 10747 public void replacePreferredActivity(IntentFilter filter, int match, 10748 ComponentName[] set, ComponentName activity) { 10749 if (filter.countActions() != 1) { 10750 throw new IllegalArgumentException( 10751 "replacePreferredActivity expects filter to have only 1 action."); 10752 } 10753 if (filter.countDataAuthorities() != 0 10754 || filter.countDataPaths() != 0 10755 || filter.countDataSchemes() > 1 10756 || filter.countDataTypes() != 0) { 10757 throw new IllegalArgumentException( 10758 "replacePreferredActivity expects filter to have no data authorities, " + 10759 "paths, or types; and at most one scheme."); 10760 } 10761 synchronized (mPackages) { 10762 if (mContext.checkCallingOrSelfPermission( 10763 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 10764 != PackageManager.PERMISSION_GRANTED) { 10765 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 10766 < Build.VERSION_CODES.FROYO) { 10767 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 10768 + Binder.getCallingUid()); 10769 return; 10770 } 10771 mContext.enforceCallingOrSelfPermission( 10772 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10773 } 10774 10775 final int callingUserId = UserHandle.getCallingUserId(); 10776 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId); 10777 if (pir != null) { 10778 Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0)); 10779 if (filter.countDataSchemes() == 1) { 10780 Uri.Builder builder = new Uri.Builder(); 10781 builder.scheme(filter.getDataScheme(0)); 10782 intent.setData(builder.build()); 10783 } 10784 List<PreferredActivity> matches = pir.queryIntent( 10785 intent, null, true, callingUserId); 10786 if (DEBUG_PREFERRED) { 10787 Slog.i(TAG, matches.size() + " preferred matches for " + intent); 10788 } 10789 for (int i = 0; i < matches.size(); i++) { 10790 PreferredActivity pa = matches.get(i); 10791 if (DEBUG_PREFERRED) { 10792 Slog.i(TAG, "Removing preferred activity " 10793 + pa.mPref.mComponent + ":"); 10794 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 10795 } 10796 pir.removeFilter(pa); 10797 } 10798 } 10799 addPreferredActivityInternal(filter, match, set, activity, true, callingUserId); 10800 } 10801 } 10802 10803 @Override 10804 public void clearPackagePreferredActivities(String packageName) { 10805 final int uid = Binder.getCallingUid(); 10806 // writer 10807 synchronized (mPackages) { 10808 PackageParser.Package pkg = mPackages.get(packageName); 10809 if (pkg == null || pkg.applicationInfo.uid != uid) { 10810 if (mContext.checkCallingOrSelfPermission( 10811 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 10812 != PackageManager.PERMISSION_GRANTED) { 10813 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 10814 < Build.VERSION_CODES.FROYO) { 10815 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 10816 + Binder.getCallingUid()); 10817 return; 10818 } 10819 mContext.enforceCallingOrSelfPermission( 10820 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10821 } 10822 } 10823 10824 int user = UserHandle.getCallingUserId(); 10825 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 10826 mSettings.writePackageRestrictionsLPr(user); 10827 scheduleWriteSettingsLocked(); 10828 } 10829 } 10830 } 10831 10832 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 10833 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 10834 ArrayList<PreferredActivity> removed = null; 10835 boolean changed = false; 10836 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 10837 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 10838 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 10839 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 10840 continue; 10841 } 10842 Iterator<PreferredActivity> it = pir.filterIterator(); 10843 while (it.hasNext()) { 10844 PreferredActivity pa = it.next(); 10845 // Mark entry for removal only if it matches the package name 10846 // and the entry is of type "always". 10847 if (packageName == null || 10848 (pa.mPref.mComponent.getPackageName().equals(packageName) 10849 && pa.mPref.mAlways)) { 10850 if (removed == null) { 10851 removed = new ArrayList<PreferredActivity>(); 10852 } 10853 removed.add(pa); 10854 } 10855 } 10856 if (removed != null) { 10857 for (int j=0; j<removed.size(); j++) { 10858 PreferredActivity pa = removed.get(j); 10859 pir.removeFilter(pa); 10860 } 10861 changed = true; 10862 } 10863 } 10864 return changed; 10865 } 10866 10867 @Override 10868 public void resetPreferredActivities(int userId) { 10869 mContext.enforceCallingOrSelfPermission( 10870 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10871 // writer 10872 synchronized (mPackages) { 10873 int user = UserHandle.getCallingUserId(); 10874 clearPackagePreferredActivitiesLPw(null, user); 10875 mSettings.readDefaultPreferredAppsLPw(this, user); 10876 mSettings.writePackageRestrictionsLPr(user); 10877 scheduleWriteSettingsLocked(); 10878 } 10879 } 10880 10881 @Override 10882 public int getPreferredActivities(List<IntentFilter> outFilters, 10883 List<ComponentName> outActivities, String packageName) { 10884 10885 int num = 0; 10886 final int userId = UserHandle.getCallingUserId(); 10887 // reader 10888 synchronized (mPackages) { 10889 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 10890 if (pir != null) { 10891 final Iterator<PreferredActivity> it = pir.filterIterator(); 10892 while (it.hasNext()) { 10893 final PreferredActivity pa = it.next(); 10894 if (packageName == null 10895 || (pa.mPref.mComponent.getPackageName().equals(packageName) 10896 && pa.mPref.mAlways)) { 10897 if (outFilters != null) { 10898 outFilters.add(new IntentFilter(pa)); 10899 } 10900 if (outActivities != null) { 10901 outActivities.add(pa.mPref.mComponent); 10902 } 10903 } 10904 } 10905 } 10906 } 10907 10908 return num; 10909 } 10910 10911 @Override 10912 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 10913 Intent intent = new Intent(Intent.ACTION_MAIN); 10914 intent.addCategory(Intent.CATEGORY_HOME); 10915 10916 final int callingUserId = UserHandle.getCallingUserId(); 10917 List<ResolveInfo> list = queryIntentActivities(intent, null, 10918 PackageManager.GET_META_DATA, callingUserId); 10919 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 10920 true, false, false, callingUserId); 10921 10922 allHomeCandidates.clear(); 10923 if (list != null) { 10924 for (ResolveInfo ri : list) { 10925 allHomeCandidates.add(ri); 10926 } 10927 } 10928 return (preferred == null || preferred.activityInfo == null) 10929 ? null 10930 : new ComponentName(preferred.activityInfo.packageName, 10931 preferred.activityInfo.name); 10932 } 10933 10934 @Override 10935 public void setApplicationEnabledSetting(String appPackageName, 10936 int newState, int flags, int userId, String callingPackage) { 10937 if (!sUserManager.exists(userId)) return; 10938 if (callingPackage == null) { 10939 callingPackage = Integer.toString(Binder.getCallingUid()); 10940 } 10941 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 10942 } 10943 10944 @Override 10945 public void setComponentEnabledSetting(ComponentName componentName, 10946 int newState, int flags, int userId) { 10947 if (!sUserManager.exists(userId)) return; 10948 setEnabledSetting(componentName.getPackageName(), 10949 componentName.getClassName(), newState, flags, userId, null); 10950 } 10951 10952 private void setEnabledSetting(final String packageName, String className, int newState, 10953 final int flags, int userId, String callingPackage) { 10954 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 10955 || newState == COMPONENT_ENABLED_STATE_ENABLED 10956 || newState == COMPONENT_ENABLED_STATE_DISABLED 10957 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 10958 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 10959 throw new IllegalArgumentException("Invalid new component state: " 10960 + newState); 10961 } 10962 PackageSetting pkgSetting; 10963 final int uid = Binder.getCallingUid(); 10964 final int permission = mContext.checkCallingOrSelfPermission( 10965 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 10966 enforceCrossUserPermission(uid, userId, false, "set enabled"); 10967 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 10968 boolean sendNow = false; 10969 boolean isApp = (className == null); 10970 String componentName = isApp ? packageName : className; 10971 int packageUid = -1; 10972 ArrayList<String> components; 10973 10974 // writer 10975 synchronized (mPackages) { 10976 pkgSetting = mSettings.mPackages.get(packageName); 10977 if (pkgSetting == null) { 10978 if (className == null) { 10979 throw new IllegalArgumentException( 10980 "Unknown package: " + packageName); 10981 } 10982 throw new IllegalArgumentException( 10983 "Unknown component: " + packageName 10984 + "/" + className); 10985 } 10986 // Allow root and verify that userId is not being specified by a different user 10987 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 10988 throw new SecurityException( 10989 "Permission Denial: attempt to change component state from pid=" 10990 + Binder.getCallingPid() 10991 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 10992 } 10993 if (className == null) { 10994 // We're dealing with an application/package level state change 10995 if (pkgSetting.getEnabled(userId) == newState) { 10996 // Nothing to do 10997 return; 10998 } 10999 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 11000 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 11001 // Don't care about who enables an app. 11002 callingPackage = null; 11003 } 11004 pkgSetting.setEnabled(newState, userId, callingPackage); 11005 // pkgSetting.pkg.mSetEnabled = newState; 11006 } else { 11007 // We're dealing with a component level state change 11008 // First, verify that this is a valid class name. 11009 PackageParser.Package pkg = pkgSetting.pkg; 11010 if (pkg == null || !pkg.hasComponentClassName(className)) { 11011 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 11012 throw new IllegalArgumentException("Component class " + className 11013 + " does not exist in " + packageName); 11014 } else { 11015 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 11016 + className + " does not exist in " + packageName); 11017 } 11018 } 11019 switch (newState) { 11020 case COMPONENT_ENABLED_STATE_ENABLED: 11021 if (!pkgSetting.enableComponentLPw(className, userId)) { 11022 return; 11023 } 11024 break; 11025 case COMPONENT_ENABLED_STATE_DISABLED: 11026 if (!pkgSetting.disableComponentLPw(className, userId)) { 11027 return; 11028 } 11029 break; 11030 case COMPONENT_ENABLED_STATE_DEFAULT: 11031 if (!pkgSetting.restoreComponentLPw(className, userId)) { 11032 return; 11033 } 11034 break; 11035 default: 11036 Slog.e(TAG, "Invalid new component state: " + newState); 11037 return; 11038 } 11039 } 11040 mSettings.writePackageRestrictionsLPr(userId); 11041 components = mPendingBroadcasts.get(userId, packageName); 11042 final boolean newPackage = components == null; 11043 if (newPackage) { 11044 components = new ArrayList<String>(); 11045 } 11046 if (!components.contains(componentName)) { 11047 components.add(componentName); 11048 } 11049 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 11050 sendNow = true; 11051 // Purge entry from pending broadcast list if another one exists already 11052 // since we are sending one right away. 11053 mPendingBroadcasts.remove(userId, packageName); 11054 } else { 11055 if (newPackage) { 11056 mPendingBroadcasts.put(userId, packageName, components); 11057 } 11058 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 11059 // Schedule a message 11060 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 11061 } 11062 } 11063 } 11064 11065 long callingId = Binder.clearCallingIdentity(); 11066 try { 11067 if (sendNow) { 11068 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 11069 sendPackageChangedBroadcast(packageName, 11070 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 11071 } 11072 } finally { 11073 Binder.restoreCallingIdentity(callingId); 11074 } 11075 } 11076 11077 private void sendPackageChangedBroadcast(String packageName, 11078 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 11079 if (DEBUG_INSTALL) 11080 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 11081 + componentNames); 11082 Bundle extras = new Bundle(4); 11083 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 11084 String nameList[] = new String[componentNames.size()]; 11085 componentNames.toArray(nameList); 11086 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 11087 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 11088 extras.putInt(Intent.EXTRA_UID, packageUid); 11089 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 11090 new int[] {UserHandle.getUserId(packageUid)}); 11091 } 11092 11093 @Override 11094 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 11095 if (!sUserManager.exists(userId)) return; 11096 final int uid = Binder.getCallingUid(); 11097 final int permission = mContext.checkCallingOrSelfPermission( 11098 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 11099 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 11100 enforceCrossUserPermission(uid, userId, true, "stop package"); 11101 // writer 11102 synchronized (mPackages) { 11103 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, 11104 uid, userId)) { 11105 scheduleWritePackageRestrictionsLocked(userId); 11106 } 11107 } 11108 } 11109 11110 @Override 11111 public String getInstallerPackageName(String packageName) { 11112 // reader 11113 synchronized (mPackages) { 11114 return mSettings.getInstallerPackageNameLPr(packageName); 11115 } 11116 } 11117 11118 @Override 11119 public int getApplicationEnabledSetting(String packageName, int userId) { 11120 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 11121 int uid = Binder.getCallingUid(); 11122 enforceCrossUserPermission(uid, userId, false, "get enabled"); 11123 // reader 11124 synchronized (mPackages) { 11125 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 11126 } 11127 } 11128 11129 @Override 11130 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 11131 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 11132 int uid = Binder.getCallingUid(); 11133 enforceCrossUserPermission(uid, userId, false, "get component enabled"); 11134 // reader 11135 synchronized (mPackages) { 11136 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 11137 } 11138 } 11139 11140 @Override 11141 public void enterSafeMode() { 11142 enforceSystemOrRoot("Only the system can request entering safe mode"); 11143 11144 if (!mSystemReady) { 11145 mSafeMode = true; 11146 } 11147 } 11148 11149 @Override 11150 public void systemReady() { 11151 mSystemReady = true; 11152 11153 // Read the compatibilty setting when the system is ready. 11154 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 11155 mContext.getContentResolver(), 11156 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 11157 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 11158 if (DEBUG_SETTINGS) { 11159 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 11160 } 11161 11162 synchronized (mPackages) { 11163 // Verify that all of the preferred activity components actually 11164 // exist. It is possible for applications to be updated and at 11165 // that point remove a previously declared activity component that 11166 // had been set as a preferred activity. We try to clean this up 11167 // the next time we encounter that preferred activity, but it is 11168 // possible for the user flow to never be able to return to that 11169 // situation so here we do a sanity check to make sure we haven't 11170 // left any junk around. 11171 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 11172 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 11173 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 11174 removed.clear(); 11175 for (PreferredActivity pa : pir.filterSet()) { 11176 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 11177 removed.add(pa); 11178 } 11179 } 11180 if (removed.size() > 0) { 11181 for (int j=0; j<removed.size(); j++) { 11182 PreferredActivity pa = removed.get(i); 11183 Slog.w(TAG, "Removing dangling preferred activity: " 11184 + pa.mPref.mComponent); 11185 pir.removeFilter(pa); 11186 } 11187 mSettings.writePackageRestrictionsLPr( 11188 mSettings.mPreferredActivities.keyAt(i)); 11189 } 11190 } 11191 } 11192 sUserManager.systemReady(); 11193 } 11194 11195 @Override 11196 public boolean isSafeMode() { 11197 return mSafeMode; 11198 } 11199 11200 @Override 11201 public boolean hasSystemUidErrors() { 11202 return mHasSystemUidErrors; 11203 } 11204 11205 static String arrayToString(int[] array) { 11206 StringBuffer buf = new StringBuffer(128); 11207 buf.append('['); 11208 if (array != null) { 11209 for (int i=0; i<array.length; i++) { 11210 if (i > 0) buf.append(", "); 11211 buf.append(array[i]); 11212 } 11213 } 11214 buf.append(']'); 11215 return buf.toString(); 11216 } 11217 11218 static class DumpState { 11219 public static final int DUMP_LIBS = 1 << 0; 11220 11221 public static final int DUMP_FEATURES = 1 << 1; 11222 11223 public static final int DUMP_RESOLVERS = 1 << 2; 11224 11225 public static final int DUMP_PERMISSIONS = 1 << 3; 11226 11227 public static final int DUMP_PACKAGES = 1 << 4; 11228 11229 public static final int DUMP_SHARED_USERS = 1 << 5; 11230 11231 public static final int DUMP_MESSAGES = 1 << 6; 11232 11233 public static final int DUMP_PROVIDERS = 1 << 7; 11234 11235 public static final int DUMP_VERIFIERS = 1 << 8; 11236 11237 public static final int DUMP_PREFERRED = 1 << 9; 11238 11239 public static final int DUMP_PREFERRED_XML = 1 << 10; 11240 11241 public static final int DUMP_KEYSETS = 1 << 11; 11242 11243 public static final int OPTION_SHOW_FILTERS = 1 << 0; 11244 11245 private int mTypes; 11246 11247 private int mOptions; 11248 11249 private boolean mTitlePrinted; 11250 11251 private SharedUserSetting mSharedUser; 11252 11253 public boolean isDumping(int type) { 11254 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 11255 return true; 11256 } 11257 11258 return (mTypes & type) != 0; 11259 } 11260 11261 public void setDump(int type) { 11262 mTypes |= type; 11263 } 11264 11265 public boolean isOptionEnabled(int option) { 11266 return (mOptions & option) != 0; 11267 } 11268 11269 public void setOptionEnabled(int option) { 11270 mOptions |= option; 11271 } 11272 11273 public boolean onTitlePrinted() { 11274 final boolean printed = mTitlePrinted; 11275 mTitlePrinted = true; 11276 return printed; 11277 } 11278 11279 public boolean getTitlePrinted() { 11280 return mTitlePrinted; 11281 } 11282 11283 public void setTitlePrinted(boolean enabled) { 11284 mTitlePrinted = enabled; 11285 } 11286 11287 public SharedUserSetting getSharedUser() { 11288 return mSharedUser; 11289 } 11290 11291 public void setSharedUser(SharedUserSetting user) { 11292 mSharedUser = user; 11293 } 11294 } 11295 11296 @Override 11297 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11298 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 11299 != PackageManager.PERMISSION_GRANTED) { 11300 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11301 + Binder.getCallingPid() 11302 + ", uid=" + Binder.getCallingUid() 11303 + " without permission " 11304 + android.Manifest.permission.DUMP); 11305 return; 11306 } 11307 11308 DumpState dumpState = new DumpState(); 11309 boolean fullPreferred = false; 11310 boolean checkin = false; 11311 11312 String packageName = null; 11313 11314 int opti = 0; 11315 while (opti < args.length) { 11316 String opt = args[opti]; 11317 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11318 break; 11319 } 11320 opti++; 11321 if ("-a".equals(opt)) { 11322 // Right now we only know how to print all. 11323 } else if ("-h".equals(opt)) { 11324 pw.println("Package manager dump options:"); 11325 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 11326 pw.println(" --checkin: dump for a checkin"); 11327 pw.println(" -f: print details of intent filters"); 11328 pw.println(" -h: print this help"); 11329 pw.println(" cmd may be one of:"); 11330 pw.println(" l[ibraries]: list known shared libraries"); 11331 pw.println(" f[ibraries]: list device features"); 11332 pw.println(" r[esolvers]: dump intent resolvers"); 11333 pw.println(" perm[issions]: dump permissions"); 11334 pw.println(" pref[erred]: print preferred package settings"); 11335 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 11336 pw.println(" prov[iders]: dump content providers"); 11337 pw.println(" p[ackages]: dump installed packages"); 11338 pw.println(" s[hared-users]: dump shared user IDs"); 11339 pw.println(" m[essages]: print collected runtime messages"); 11340 pw.println(" v[erifiers]: print package verifier info"); 11341 pw.println(" <package.name>: info about given package"); 11342 pw.println(" k[eysets]: print known keysets"); 11343 return; 11344 } else if ("--checkin".equals(opt)) { 11345 checkin = true; 11346 } else if ("-f".equals(opt)) { 11347 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 11348 } else { 11349 pw.println("Unknown argument: " + opt + "; use -h for help"); 11350 } 11351 } 11352 11353 // Is the caller requesting to dump a particular piece of data? 11354 if (opti < args.length) { 11355 String cmd = args[opti]; 11356 opti++; 11357 // Is this a package name? 11358 if ("android".equals(cmd) || cmd.contains(".")) { 11359 packageName = cmd; 11360 // When dumping a single package, we always dump all of its 11361 // filter information since the amount of data will be reasonable. 11362 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 11363 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 11364 dumpState.setDump(DumpState.DUMP_LIBS); 11365 } else if ("f".equals(cmd) || "features".equals(cmd)) { 11366 dumpState.setDump(DumpState.DUMP_FEATURES); 11367 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 11368 dumpState.setDump(DumpState.DUMP_RESOLVERS); 11369 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 11370 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 11371 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 11372 dumpState.setDump(DumpState.DUMP_PREFERRED); 11373 } else if ("preferred-xml".equals(cmd)) { 11374 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 11375 if (opti < args.length && "--full".equals(args[opti])) { 11376 fullPreferred = true; 11377 opti++; 11378 } 11379 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 11380 dumpState.setDump(DumpState.DUMP_PACKAGES); 11381 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 11382 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 11383 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 11384 dumpState.setDump(DumpState.DUMP_PROVIDERS); 11385 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 11386 dumpState.setDump(DumpState.DUMP_MESSAGES); 11387 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 11388 dumpState.setDump(DumpState.DUMP_VERIFIERS); 11389 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 11390 dumpState.setDump(DumpState.DUMP_KEYSETS); 11391 } 11392 } 11393 11394 if (checkin) { 11395 pw.println("vers,1"); 11396 } 11397 11398 // reader 11399 synchronized (mPackages) { 11400 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 11401 if (!checkin) { 11402 if (dumpState.onTitlePrinted()) 11403 pw.println(); 11404 pw.println("Verifiers:"); 11405 pw.print(" Required: "); 11406 pw.print(mRequiredVerifierPackage); 11407 pw.print(" (uid="); 11408 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 11409 pw.println(")"); 11410 } else if (mRequiredVerifierPackage != null) { 11411 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 11412 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 11413 } 11414 } 11415 11416 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 11417 boolean printedHeader = false; 11418 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 11419 while (it.hasNext()) { 11420 String name = it.next(); 11421 SharedLibraryEntry ent = mSharedLibraries.get(name); 11422 if (!checkin) { 11423 if (!printedHeader) { 11424 if (dumpState.onTitlePrinted()) 11425 pw.println(); 11426 pw.println("Libraries:"); 11427 printedHeader = true; 11428 } 11429 pw.print(" "); 11430 } else { 11431 pw.print("lib,"); 11432 } 11433 pw.print(name); 11434 if (!checkin) { 11435 pw.print(" -> "); 11436 } 11437 if (ent.path != null) { 11438 if (!checkin) { 11439 pw.print("(jar) "); 11440 pw.print(ent.path); 11441 } else { 11442 pw.print(",jar,"); 11443 pw.print(ent.path); 11444 } 11445 } else { 11446 if (!checkin) { 11447 pw.print("(apk) "); 11448 pw.print(ent.apk); 11449 } else { 11450 pw.print(",apk,"); 11451 pw.print(ent.apk); 11452 } 11453 } 11454 pw.println(); 11455 } 11456 } 11457 11458 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 11459 if (dumpState.onTitlePrinted()) 11460 pw.println(); 11461 if (!checkin) { 11462 pw.println("Features:"); 11463 } 11464 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 11465 while (it.hasNext()) { 11466 String name = it.next(); 11467 if (!checkin) { 11468 pw.print(" "); 11469 } else { 11470 pw.print("feat,"); 11471 } 11472 pw.println(name); 11473 } 11474 } 11475 11476 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 11477 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 11478 : "Activity Resolver Table:", " ", packageName, 11479 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 11480 dumpState.setTitlePrinted(true); 11481 } 11482 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 11483 : "Receiver Resolver Table:", " ", packageName, 11484 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 11485 dumpState.setTitlePrinted(true); 11486 } 11487 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 11488 : "Service Resolver Table:", " ", packageName, 11489 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 11490 dumpState.setTitlePrinted(true); 11491 } 11492 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 11493 : "Provider Resolver Table:", " ", packageName, 11494 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 11495 dumpState.setTitlePrinted(true); 11496 } 11497 } 11498 11499 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 11500 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 11501 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 11502 int user = mSettings.mPreferredActivities.keyAt(i); 11503 if (pir.dump(pw, 11504 dumpState.getTitlePrinted() 11505 ? "\nPreferred Activities User " + user + ":" 11506 : "Preferred Activities User " + user + ":", " ", 11507 packageName, true)) { 11508 dumpState.setTitlePrinted(true); 11509 } 11510 } 11511 } 11512 11513 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 11514 pw.flush(); 11515 FileOutputStream fout = new FileOutputStream(fd); 11516 BufferedOutputStream str = new BufferedOutputStream(fout); 11517 XmlSerializer serializer = new FastXmlSerializer(); 11518 try { 11519 serializer.setOutput(str, "utf-8"); 11520 serializer.startDocument(null, true); 11521 serializer.setFeature( 11522 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 11523 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 11524 serializer.endDocument(); 11525 serializer.flush(); 11526 } catch (IllegalArgumentException e) { 11527 pw.println("Failed writing: " + e); 11528 } catch (IllegalStateException e) { 11529 pw.println("Failed writing: " + e); 11530 } catch (IOException e) { 11531 pw.println("Failed writing: " + e); 11532 } 11533 } 11534 11535 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 11536 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 11537 } 11538 11539 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 11540 boolean printedSomething = false; 11541 for (PackageParser.Provider p : mProviders.mProviders.values()) { 11542 if (packageName != null && !packageName.equals(p.info.packageName)) { 11543 continue; 11544 } 11545 if (!printedSomething) { 11546 if (dumpState.onTitlePrinted()) 11547 pw.println(); 11548 pw.println("Registered ContentProviders:"); 11549 printedSomething = true; 11550 } 11551 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 11552 pw.print(" "); pw.println(p.toString()); 11553 } 11554 printedSomething = false; 11555 for (Map.Entry<String, PackageParser.Provider> entry : 11556 mProvidersByAuthority.entrySet()) { 11557 PackageParser.Provider p = entry.getValue(); 11558 if (packageName != null && !packageName.equals(p.info.packageName)) { 11559 continue; 11560 } 11561 if (!printedSomething) { 11562 if (dumpState.onTitlePrinted()) 11563 pw.println(); 11564 pw.println("ContentProvider Authorities:"); 11565 printedSomething = true; 11566 } 11567 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 11568 pw.print(" "); pw.println(p.toString()); 11569 if (p.info != null && p.info.applicationInfo != null) { 11570 final String appInfo = p.info.applicationInfo.toString(); 11571 pw.print(" applicationInfo="); pw.println(appInfo); 11572 } 11573 } 11574 } 11575 11576 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 11577 mSettings.mKeySetManager.dump(pw, packageName, dumpState); 11578 } 11579 11580 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 11581 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin); 11582 } 11583 11584 if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 11585 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState); 11586 } 11587 11588 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 11589 if (dumpState.onTitlePrinted()) 11590 pw.println(); 11591 mSettings.dumpReadMessagesLPr(pw, dumpState); 11592 11593 pw.println(); 11594 pw.println("Package warning messages:"); 11595 final File fname = getSettingsProblemFile(); 11596 FileInputStream in = null; 11597 try { 11598 in = new FileInputStream(fname); 11599 final int avail = in.available(); 11600 final byte[] data = new byte[avail]; 11601 in.read(data); 11602 pw.print(new String(data)); 11603 } catch (FileNotFoundException e) { 11604 } catch (IOException e) { 11605 } finally { 11606 if (in != null) { 11607 try { 11608 in.close(); 11609 } catch (IOException e) { 11610 } 11611 } 11612 } 11613 } 11614 } 11615 } 11616 11617 // ------- apps on sdcard specific code ------- 11618 static final boolean DEBUG_SD_INSTALL = false; 11619 11620 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 11621 11622 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 11623 11624 private boolean mMediaMounted = false; 11625 11626 private String getEncryptKey() { 11627 try { 11628 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 11629 SD_ENCRYPTION_KEYSTORE_NAME); 11630 if (sdEncKey == null) { 11631 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 11632 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 11633 if (sdEncKey == null) { 11634 Slog.e(TAG, "Failed to create encryption keys"); 11635 return null; 11636 } 11637 } 11638 return sdEncKey; 11639 } catch (NoSuchAlgorithmException nsae) { 11640 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 11641 return null; 11642 } catch (IOException ioe) { 11643 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 11644 return null; 11645 } 11646 11647 } 11648 11649 /* package */static String getTempContainerId() { 11650 int tmpIdx = 1; 11651 String list[] = PackageHelper.getSecureContainerList(); 11652 if (list != null) { 11653 for (final String name : list) { 11654 // Ignore null and non-temporary container entries 11655 if (name == null || !name.startsWith(mTempContainerPrefix)) { 11656 continue; 11657 } 11658 11659 String subStr = name.substring(mTempContainerPrefix.length()); 11660 try { 11661 int cid = Integer.parseInt(subStr); 11662 if (cid >= tmpIdx) { 11663 tmpIdx = cid + 1; 11664 } 11665 } catch (NumberFormatException e) { 11666 } 11667 } 11668 } 11669 return mTempContainerPrefix + tmpIdx; 11670 } 11671 11672 /* 11673 * Update media status on PackageManager. 11674 */ 11675 @Override 11676 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 11677 int callingUid = Binder.getCallingUid(); 11678 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 11679 throw new SecurityException("Media status can only be updated by the system"); 11680 } 11681 // reader; this apparently protects mMediaMounted, but should probably 11682 // be a different lock in that case. 11683 synchronized (mPackages) { 11684 Log.i(TAG, "Updating external media status from " 11685 + (mMediaMounted ? "mounted" : "unmounted") + " to " 11686 + (mediaStatus ? "mounted" : "unmounted")); 11687 if (DEBUG_SD_INSTALL) 11688 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 11689 + ", mMediaMounted=" + mMediaMounted); 11690 if (mediaStatus == mMediaMounted) { 11691 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 11692 : 0, -1); 11693 mHandler.sendMessage(msg); 11694 return; 11695 } 11696 mMediaMounted = mediaStatus; 11697 } 11698 // Queue up an async operation since the package installation may take a 11699 // little while. 11700 mHandler.post(new Runnable() { 11701 public void run() { 11702 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 11703 } 11704 }); 11705 } 11706 11707 /** 11708 * Called by MountService when the initial ASECs to scan are available. 11709 * Should block until all the ASEC containers are finished being scanned. 11710 */ 11711 public void scanAvailableAsecs() { 11712 updateExternalMediaStatusInner(true, false, false); 11713 if (mShouldRestoreconData) { 11714 SELinuxMMAC.setRestoreconDone(); 11715 mShouldRestoreconData = false; 11716 } 11717 } 11718 11719 /* 11720 * Collect information of applications on external media, map them against 11721 * existing containers and update information based on current mount status. 11722 * Please note that we always have to report status if reportStatus has been 11723 * set to true especially when unloading packages. 11724 */ 11725 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 11726 boolean externalStorage) { 11727 // Collection of uids 11728 int uidArr[] = null; 11729 // Collection of stale containers 11730 HashSet<String> removeCids = new HashSet<String>(); 11731 // Collection of packages on external media with valid containers. 11732 HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>(); 11733 // Get list of secure containers. 11734 final String list[] = PackageHelper.getSecureContainerList(); 11735 if (list == null || list.length == 0) { 11736 Log.i(TAG, "No secure containers on sdcard"); 11737 } else { 11738 // Process list of secure containers and categorize them 11739 // as active or stale based on their package internal state. 11740 int uidList[] = new int[list.length]; 11741 int num = 0; 11742 // reader 11743 synchronized (mPackages) { 11744 for (String cid : list) { 11745 if (DEBUG_SD_INSTALL) 11746 Log.i(TAG, "Processing container " + cid); 11747 String pkgName = getAsecPackageName(cid); 11748 if (pkgName == null) { 11749 if (DEBUG_SD_INSTALL) 11750 Log.i(TAG, "Container : " + cid + " stale"); 11751 removeCids.add(cid); 11752 continue; 11753 } 11754 if (DEBUG_SD_INSTALL) 11755 Log.i(TAG, "Looking for pkg : " + pkgName); 11756 11757 final PackageSetting ps = mSettings.mPackages.get(pkgName); 11758 if (ps == null) { 11759 Log.i(TAG, "Deleting container with no matching settings " + cid); 11760 removeCids.add(cid); 11761 continue; 11762 } 11763 11764 /* 11765 * Skip packages that are not external if we're unmounting 11766 * external storage. 11767 */ 11768 if (externalStorage && !isMounted && !isExternal(ps)) { 11769 continue; 11770 } 11771 11772 final AsecInstallArgs args = new AsecInstallArgs(cid, 11773 getAppInstructionSetFromSettings(ps), 11774 isForwardLocked(ps)); 11775 // The package status is changed only if the code path 11776 // matches between settings and the container id. 11777 if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) { 11778 if (DEBUG_SD_INSTALL) { 11779 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 11780 + " at code path: " + ps.codePathString); 11781 } 11782 11783 // We do have a valid package installed on sdcard 11784 processCids.put(args, ps.codePathString); 11785 final int uid = ps.appId; 11786 if (uid != -1) { 11787 uidList[num++] = uid; 11788 } 11789 } else { 11790 Log.i(TAG, "Deleting stale container for " + cid); 11791 removeCids.add(cid); 11792 } 11793 } 11794 } 11795 11796 if (num > 0) { 11797 // Sort uid list 11798 Arrays.sort(uidList, 0, num); 11799 // Throw away duplicates 11800 uidArr = new int[num]; 11801 uidArr[0] = uidList[0]; 11802 int di = 0; 11803 for (int i = 1; i < num; i++) { 11804 if (uidList[i - 1] != uidList[i]) { 11805 uidArr[di++] = uidList[i]; 11806 } 11807 } 11808 } 11809 } 11810 // Process packages with valid entries. 11811 if (isMounted) { 11812 if (DEBUG_SD_INSTALL) 11813 Log.i(TAG, "Loading packages"); 11814 loadMediaPackages(processCids, uidArr, removeCids); 11815 startCleaningPackages(); 11816 } else { 11817 if (DEBUG_SD_INSTALL) 11818 Log.i(TAG, "Unloading packages"); 11819 unloadMediaPackages(processCids, uidArr, reportStatus); 11820 } 11821 } 11822 11823 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 11824 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 11825 int size = pkgList.size(); 11826 if (size > 0) { 11827 // Send broadcasts here 11828 Bundle extras = new Bundle(); 11829 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList 11830 .toArray(new String[size])); 11831 if (uidArr != null) { 11832 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 11833 } 11834 if (replacing) { 11835 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 11836 } 11837 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 11838 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 11839 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 11840 } 11841 } 11842 11843 /* 11844 * Look at potentially valid container ids from processCids If package 11845 * information doesn't match the one on record or package scanning fails, 11846 * the cid is added to list of removeCids. We currently don't delete stale 11847 * containers. 11848 */ 11849 private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], 11850 HashSet<String> removeCids) { 11851 ArrayList<String> pkgList = new ArrayList<String>(); 11852 Set<AsecInstallArgs> keys = processCids.keySet(); 11853 boolean doGc = false; 11854 for (AsecInstallArgs args : keys) { 11855 String codePath = processCids.get(args); 11856 if (DEBUG_SD_INSTALL) 11857 Log.i(TAG, "Loading container : " + args.cid); 11858 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11859 try { 11860 // Make sure there are no container errors first. 11861 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 11862 Slog.e(TAG, "Failed to mount cid : " + args.cid 11863 + " when installing from sdcard"); 11864 continue; 11865 } 11866 // Check code path here. 11867 if (codePath == null || !codePath.equals(args.getCodePath())) { 11868 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 11869 + " does not match one in settings " + codePath); 11870 continue; 11871 } 11872 // Parse package 11873 int parseFlags = mDefParseFlags; 11874 if (args.isExternal()) { 11875 parseFlags |= PackageParser.PARSE_ON_SDCARD; 11876 } 11877 if (args.isFwdLocked()) { 11878 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 11879 } 11880 11881 doGc = true; 11882 synchronized (mInstallLock) { 11883 final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags, 11884 0, 0, null); 11885 // Scan the package 11886 if (pkg != null) { 11887 /* 11888 * TODO why is the lock being held? doPostInstall is 11889 * called in other places without the lock. This needs 11890 * to be straightened out. 11891 */ 11892 // writer 11893 synchronized (mPackages) { 11894 retCode = PackageManager.INSTALL_SUCCEEDED; 11895 pkgList.add(pkg.packageName); 11896 // Post process args 11897 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 11898 pkg.applicationInfo.uid); 11899 } 11900 } else { 11901 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 11902 } 11903 } 11904 11905 } finally { 11906 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 11907 // Don't destroy container here. Wait till gc clears things 11908 // up. 11909 removeCids.add(args.cid); 11910 } 11911 } 11912 } 11913 // writer 11914 synchronized (mPackages) { 11915 // If the platform SDK has changed since the last time we booted, 11916 // we need to re-grant app permission to catch any new ones that 11917 // appear. This is really a hack, and means that apps can in some 11918 // cases get permissions that the user didn't initially explicitly 11919 // allow... it would be nice to have some better way to handle 11920 // this situation. 11921 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 11922 if (regrantPermissions) 11923 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 11924 + mSdkVersion + "; regranting permissions for external storage"); 11925 mSettings.mExternalSdkPlatform = mSdkVersion; 11926 11927 // Make sure group IDs have been assigned, and any permission 11928 // changes in other apps are accounted for 11929 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 11930 | (regrantPermissions 11931 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 11932 : 0)); 11933 // can downgrade to reader 11934 // Persist settings 11935 mSettings.writeLPr(); 11936 } 11937 // Send a broadcast to let everyone know we are done processing 11938 if (pkgList.size() > 0) { 11939 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 11940 } 11941 // Force gc to avoid any stale parser references that we might have. 11942 if (doGc) { 11943 Runtime.getRuntime().gc(); 11944 } 11945 // List stale containers and destroy stale temporary containers. 11946 if (removeCids != null) { 11947 for (String cid : removeCids) { 11948 if (cid.startsWith(mTempContainerPrefix)) { 11949 Log.i(TAG, "Destroying stale temporary container " + cid); 11950 PackageHelper.destroySdDir(cid); 11951 } else { 11952 Log.w(TAG, "Container " + cid + " is stale"); 11953 } 11954 } 11955 } 11956 } 11957 11958 /* 11959 * Utility method to unload a list of specified containers 11960 */ 11961 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 11962 // Just unmount all valid containers. 11963 for (AsecInstallArgs arg : cidArgs) { 11964 synchronized (mInstallLock) { 11965 arg.doPostDeleteLI(false); 11966 } 11967 } 11968 } 11969 11970 /* 11971 * Unload packages mounted on external media. This involves deleting package 11972 * data from internal structures, sending broadcasts about diabled packages, 11973 * gc'ing to free up references, unmounting all secure containers 11974 * corresponding to packages on external media, and posting a 11975 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 11976 * that we always have to post this message if status has been requested no 11977 * matter what. 11978 */ 11979 private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], 11980 final boolean reportStatus) { 11981 if (DEBUG_SD_INSTALL) 11982 Log.i(TAG, "unloading media packages"); 11983 ArrayList<String> pkgList = new ArrayList<String>(); 11984 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 11985 final Set<AsecInstallArgs> keys = processCids.keySet(); 11986 for (AsecInstallArgs args : keys) { 11987 String pkgName = args.getPackageName(); 11988 if (DEBUG_SD_INSTALL) 11989 Log.i(TAG, "Trying to unload pkg : " + pkgName); 11990 // Delete package internally 11991 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 11992 synchronized (mInstallLock) { 11993 boolean res = deletePackageLI(pkgName, null, false, null, null, 11994 PackageManager.DELETE_KEEP_DATA, outInfo, false); 11995 if (res) { 11996 pkgList.add(pkgName); 11997 } else { 11998 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 11999 failedList.add(args); 12000 } 12001 } 12002 } 12003 12004 // reader 12005 synchronized (mPackages) { 12006 // We didn't update the settings after removing each package; 12007 // write them now for all packages. 12008 mSettings.writeLPr(); 12009 } 12010 12011 // We have to absolutely send UPDATED_MEDIA_STATUS only 12012 // after confirming that all the receivers processed the ordered 12013 // broadcast when packages get disabled, force a gc to clean things up. 12014 // and unload all the containers. 12015 if (pkgList.size() > 0) { 12016 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 12017 new IIntentReceiver.Stub() { 12018 public void performReceive(Intent intent, int resultCode, String data, 12019 Bundle extras, boolean ordered, boolean sticky, 12020 int sendingUser) throws RemoteException { 12021 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 12022 reportStatus ? 1 : 0, 1, keys); 12023 mHandler.sendMessage(msg); 12024 } 12025 }); 12026 } else { 12027 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 12028 keys); 12029 mHandler.sendMessage(msg); 12030 } 12031 } 12032 12033 /** Binder call */ 12034 @Override 12035 public void movePackage(final String packageName, final IPackageMoveObserver observer, 12036 final int flags) { 12037 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 12038 UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 12039 int returnCode = PackageManager.MOVE_SUCCEEDED; 12040 int currFlags = 0; 12041 int newFlags = 0; 12042 // reader 12043 synchronized (mPackages) { 12044 PackageParser.Package pkg = mPackages.get(packageName); 12045 if (pkg == null) { 12046 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 12047 } else { 12048 // Disable moving fwd locked apps and system packages 12049 if (pkg.applicationInfo != null && isSystemApp(pkg)) { 12050 Slog.w(TAG, "Cannot move system application"); 12051 returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 12052 } else if (pkg.mOperationPending) { 12053 Slog.w(TAG, "Attempt to move package which has pending operations"); 12054 returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING; 12055 } else { 12056 // Find install location first 12057 if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 12058 && (flags & PackageManager.MOVE_INTERNAL) != 0) { 12059 Slog.w(TAG, "Ambigous flags specified for move location."); 12060 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 12061 } else { 12062 newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL 12063 : PackageManager.INSTALL_INTERNAL; 12064 currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL 12065 : PackageManager.INSTALL_INTERNAL; 12066 12067 if (newFlags == currFlags) { 12068 Slog.w(TAG, "No move required. Trying to move to same location"); 12069 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 12070 } else { 12071 if (isForwardLocked(pkg)) { 12072 currFlags |= PackageManager.INSTALL_FORWARD_LOCK; 12073 newFlags |= PackageManager.INSTALL_FORWARD_LOCK; 12074 } 12075 } 12076 } 12077 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 12078 pkg.mOperationPending = true; 12079 } 12080 } 12081 } 12082 12083 /* 12084 * TODO this next block probably shouldn't be inside the lock. We 12085 * can't guarantee these won't change after this is fired off 12086 * anyway. 12087 */ 12088 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 12089 processPendingMove(new MoveParams(null, observer, 0, packageName, null, 12090 null, -1, user), 12091 returnCode); 12092 } else { 12093 Message msg = mHandler.obtainMessage(INIT_COPY); 12094 final String instructionSet = getAppInstructionSet(pkg.applicationInfo); 12095 InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir, 12096 pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir, 12097 instructionSet); 12098 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName, 12099 pkg.applicationInfo.dataDir, instructionSet, pkg.applicationInfo.uid, user); 12100 msg.obj = mp; 12101 mHandler.sendMessage(msg); 12102 } 12103 } 12104 } 12105 12106 private void processPendingMove(final MoveParams mp, final int currentStatus) { 12107 // Queue up an async operation since the package deletion may take a 12108 // little while. 12109 mHandler.post(new Runnable() { 12110 public void run() { 12111 // TODO fix this; this does nothing. 12112 mHandler.removeCallbacks(this); 12113 int returnCode = currentStatus; 12114 if (currentStatus == PackageManager.MOVE_SUCCEEDED) { 12115 int uidArr[] = null; 12116 ArrayList<String> pkgList = null; 12117 synchronized (mPackages) { 12118 PackageParser.Package pkg = mPackages.get(mp.packageName); 12119 if (pkg == null) { 12120 Slog.w(TAG, " Package " + mp.packageName 12121 + " doesn't exist. Aborting move"); 12122 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 12123 } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) { 12124 Slog.w(TAG, "Package " + mp.packageName + " code path changed from " 12125 + mp.srcArgs.getCodePath() + " to " 12126 + pkg.applicationInfo.sourceDir 12127 + " Aborting move and returning error"); 12128 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 12129 } else { 12130 uidArr = new int[] { 12131 pkg.applicationInfo.uid 12132 }; 12133 pkgList = new ArrayList<String>(); 12134 pkgList.add(mp.packageName); 12135 } 12136 } 12137 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 12138 // Send resources unavailable broadcast 12139 sendResourcesChangedBroadcast(false, true, pkgList, uidArr, null); 12140 // Update package code and resource paths 12141 synchronized (mInstallLock) { 12142 synchronized (mPackages) { 12143 PackageParser.Package pkg = mPackages.get(mp.packageName); 12144 // Recheck for package again. 12145 if (pkg == null) { 12146 Slog.w(TAG, " Package " + mp.packageName 12147 + " doesn't exist. Aborting move"); 12148 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 12149 } else if (!mp.srcArgs.getCodePath().equals( 12150 pkg.applicationInfo.sourceDir)) { 12151 Slog.w(TAG, "Package " + mp.packageName 12152 + " code path changed from " + mp.srcArgs.getCodePath() 12153 + " to " + pkg.applicationInfo.sourceDir 12154 + " Aborting move and returning error"); 12155 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 12156 } else { 12157 final String oldCodePath = pkg.mPath; 12158 final String newCodePath = mp.targetArgs.getCodePath(); 12159 final String newResPath = mp.targetArgs.getResourcePath(); 12160 final String newNativePath = mp.targetArgs 12161 .getNativeLibraryPath(); 12162 12163 final File newNativeDir = new File(newNativePath); 12164 12165 if (!isForwardLocked(pkg) && !isExternal(pkg)) { 12166 // NOTE: We do not report any errors from the APK scan and library 12167 // copy at this point. 12168 NativeLibraryHelper.ApkHandle handle = 12169 new NativeLibraryHelper.ApkHandle(newCodePath); 12170 final int abi = NativeLibraryHelper.findSupportedAbi( 12171 handle, Build.SUPPORTED_ABIS); 12172 if (abi >= 0) { 12173 NativeLibraryHelper.copyNativeBinariesIfNeededLI( 12174 handle, newNativeDir, Build.SUPPORTED_ABIS[abi]); 12175 } 12176 handle.close(); 12177 } 12178 final int[] users = sUserManager.getUserIds(); 12179 for (int user : users) { 12180 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, 12181 newNativePath, user) < 0) { 12182 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 12183 } 12184 } 12185 12186 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 12187 pkg.mPath = newCodePath; 12188 // Move dex files around 12189 if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) { 12190 // Moving of dex files failed. Set 12191 // error code and abort move. 12192 pkg.mPath = pkg.mScanPath; 12193 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 12194 } 12195 } 12196 12197 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 12198 pkg.mScanPath = newCodePath; 12199 pkg.applicationInfo.sourceDir = newCodePath; 12200 pkg.applicationInfo.publicSourceDir = newResPath; 12201 pkg.applicationInfo.nativeLibraryDir = newNativePath; 12202 PackageSetting ps = (PackageSetting) pkg.mExtras; 12203 ps.codePath = new File(pkg.applicationInfo.sourceDir); 12204 ps.codePathString = ps.codePath.getPath(); 12205 ps.resourcePath = new File( 12206 pkg.applicationInfo.publicSourceDir); 12207 ps.resourcePathString = ps.resourcePath.getPath(); 12208 ps.nativeLibraryPathString = newNativePath; 12209 // Set the application info flag 12210 // correctly. 12211 if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) { 12212 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE; 12213 } else { 12214 pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE; 12215 } 12216 ps.setFlags(pkg.applicationInfo.flags); 12217 mAppDirs.remove(oldCodePath); 12218 mAppDirs.put(newCodePath, pkg); 12219 // Persist settings 12220 mSettings.writeLPr(); 12221 } 12222 } 12223 } 12224 } 12225 // Send resources available broadcast 12226 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 12227 } 12228 } 12229 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 12230 // Clean up failed installation 12231 if (mp.targetArgs != null) { 12232 mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, 12233 -1); 12234 } 12235 } else { 12236 // Force a gc to clear things up. 12237 Runtime.getRuntime().gc(); 12238 // Delete older code 12239 synchronized (mInstallLock) { 12240 mp.srcArgs.doPostDeleteLI(true); 12241 } 12242 } 12243 12244 // Allow more operations on this file if we didn't fail because 12245 // an operation was already pending for this package. 12246 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) { 12247 synchronized (mPackages) { 12248 PackageParser.Package pkg = mPackages.get(mp.packageName); 12249 if (pkg != null) { 12250 pkg.mOperationPending = false; 12251 } 12252 } 12253 } 12254 12255 IPackageMoveObserver observer = mp.observer; 12256 if (observer != null) { 12257 try { 12258 observer.packageMoved(mp.packageName, returnCode); 12259 } catch (RemoteException e) { 12260 Log.i(TAG, "Observer no longer exists."); 12261 } 12262 } 12263 } 12264 }); 12265 } 12266 12267 @Override 12268 public boolean setInstallLocation(int loc) { 12269 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 12270 null); 12271 if (getInstallLocation() == loc) { 12272 return true; 12273 } 12274 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 12275 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 12276 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 12277 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 12278 return true; 12279 } 12280 return false; 12281 } 12282 12283 @Override 12284 public int getInstallLocation() { 12285 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12286 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 12287 PackageHelper.APP_INSTALL_AUTO); 12288 } 12289 12290 /** Called by UserManagerService */ 12291 void cleanUpUserLILPw(int userHandle) { 12292 mDirtyUsers.remove(userHandle); 12293 mSettings.removeUserLPr(userHandle); 12294 mPendingBroadcasts.remove(userHandle); 12295 if (mInstaller != null) { 12296 // Technically, we shouldn't be doing this with the package lock 12297 // held. However, this is very rare, and there is already so much 12298 // other disk I/O going on, that we'll let it slide for now. 12299 mInstaller.removeUserDataDirs(userHandle); 12300 } 12301 } 12302 12303 /** Called by UserManagerService */ 12304 void createNewUserLILPw(int userHandle, File path) { 12305 if (mInstaller != null) { 12306 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path); 12307 } 12308 } 12309 12310 @Override 12311 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 12312 mContext.enforceCallingOrSelfPermission( 12313 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12314 "Only package verification agents can read the verifier device identity"); 12315 12316 synchronized (mPackages) { 12317 return mSettings.getVerifierDeviceIdentityLPw(); 12318 } 12319 } 12320 12321 @Override 12322 public void setPermissionEnforced(String permission, boolean enforced) { 12323 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); 12324 if (READ_EXTERNAL_STORAGE.equals(permission)) { 12325 synchronized (mPackages) { 12326 if (mSettings.mReadExternalStorageEnforced == null 12327 || mSettings.mReadExternalStorageEnforced != enforced) { 12328 mSettings.mReadExternalStorageEnforced = enforced; 12329 mSettings.writeLPr(); 12330 } 12331 } 12332 // kill any non-foreground processes so we restart them and 12333 // grant/revoke the GID. 12334 final IActivityManager am = ActivityManagerNative.getDefault(); 12335 if (am != null) { 12336 final long token = Binder.clearCallingIdentity(); 12337 try { 12338 am.killProcessesBelowForeground("setPermissionEnforcement"); 12339 } catch (RemoteException e) { 12340 } finally { 12341 Binder.restoreCallingIdentity(token); 12342 } 12343 } 12344 } else { 12345 throw new IllegalArgumentException("No selective enforcement for " + permission); 12346 } 12347 } 12348 12349 @Override 12350 @Deprecated 12351 public boolean isPermissionEnforced(String permission) { 12352 return true; 12353 } 12354 12355 @Override 12356 public boolean isStorageLow() { 12357 final long token = Binder.clearCallingIdentity(); 12358 try { 12359 final DeviceStorageMonitorInternal 12360 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 12361 if (dsm != null) { 12362 return dsm.isMemoryLow(); 12363 } else { 12364 return false; 12365 } 12366 } finally { 12367 Binder.restoreCallingIdentity(token); 12368 } 12369 } 12370} 12371