PackageManagerService.java revision 12e75126909152c448f70c48f3d2f2884cb359bd
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 com.android.internal.util.ArrayUtils.appendInt; 27import static com.android.internal.util.ArrayUtils.removeInt; 28import static libcore.io.OsConstants.S_IRWXU; 29import static libcore.io.OsConstants.S_IRGRP; 30import static libcore.io.OsConstants.S_IXGRP; 31import static libcore.io.OsConstants.S_IROTH; 32import static libcore.io.OsConstants.S_IXOTH; 33 34import com.android.internal.app.IMediaContainerService; 35import com.android.internal.app.ResolverActivity; 36import com.android.internal.content.NativeLibraryHelper; 37import com.android.internal.content.PackageHelper; 38import com.android.internal.util.FastPrintWriter; 39import com.android.internal.util.FastXmlSerializer; 40import com.android.internal.util.XmlUtils; 41import com.android.server.EventLogTags; 42import com.android.server.IntentResolver; 43import com.android.server.ServiceThread; 44 45import com.android.server.LocalServices; 46import com.android.server.Watchdog; 47import org.xmlpull.v1.XmlPullParser; 48import org.xmlpull.v1.XmlPullParserException; 49import org.xmlpull.v1.XmlSerializer; 50 51import android.app.ActivityManager; 52import android.app.ActivityManagerNative; 53import android.app.IActivityManager; 54import android.app.admin.IDevicePolicyManager; 55import android.app.backup.IBackupManager; 56import android.content.BroadcastReceiver; 57import android.content.ComponentName; 58import android.content.Context; 59import android.content.IIntentReceiver; 60import android.content.Intent; 61import android.content.IntentFilter; 62import android.content.IntentSender; 63import android.content.IntentSender.SendIntentException; 64import android.content.ServiceConnection; 65import android.content.pm.ActivityInfo; 66import android.content.pm.ApplicationInfo; 67import android.content.pm.ContainerEncryptionParams; 68import android.content.pm.FeatureInfo; 69import android.content.pm.IPackageDataObserver; 70import android.content.pm.IPackageDeleteObserver; 71import android.content.pm.IPackageInstallObserver; 72import android.content.pm.IPackageInstallObserver2; 73import android.content.pm.IPackageManager; 74import android.content.pm.IPackageMoveObserver; 75import android.content.pm.IPackageStatsObserver; 76import android.content.pm.InstrumentationInfo; 77import android.content.pm.ManifestDigest; 78import android.content.pm.PackageCleanItem; 79import android.content.pm.PackageInfo; 80import android.content.pm.PackageInfoLite; 81import android.content.pm.PackageManager; 82import android.content.pm.PackageParser; 83import android.content.pm.PackageParser.ActivityIntentInfo; 84import android.content.pm.PackageStats; 85import android.content.pm.PackageUserState; 86import android.content.pm.ParceledListSlice; 87import android.content.pm.PermissionGroupInfo; 88import android.content.pm.PermissionInfo; 89import android.content.pm.ProviderInfo; 90import android.content.pm.ResolveInfo; 91import android.content.pm.ServiceInfo; 92import android.content.pm.Signature; 93import android.content.pm.VerificationParams; 94import android.content.pm.VerifierDeviceIdentity; 95import android.content.pm.VerifierInfo; 96import android.content.res.Resources; 97import android.hardware.display.DisplayManager; 98import android.net.Uri; 99import android.os.Binder; 100import android.os.Build; 101import android.os.Bundle; 102import android.os.Environment; 103import android.os.Environment.UserEnvironment; 104import android.os.FileObserver; 105import android.os.FileUtils; 106import android.os.Handler; 107import android.os.IBinder; 108import android.os.Looper; 109import android.os.Message; 110import android.os.Parcel; 111import android.os.ParcelFileDescriptor; 112import android.os.Process; 113import android.os.RemoteException; 114import android.os.SELinux; 115import android.os.ServiceManager; 116import android.os.SystemClock; 117import android.os.SystemProperties; 118import android.os.UserHandle; 119import android.os.UserManager; 120import android.security.KeyStore; 121import android.security.SystemKeyStore; 122import android.text.TextUtils; 123import android.util.DisplayMetrics; 124import android.util.EventLog; 125import android.util.Log; 126import android.util.LogPrinter; 127import android.util.PrintStreamPrinter; 128import android.util.Slog; 129import android.util.SparseArray; 130import android.util.Xml; 131import android.view.Display; 132 133import java.io.BufferedOutputStream; 134import java.io.File; 135import java.io.FileDescriptor; 136import java.io.FileInputStream; 137import java.io.FileNotFoundException; 138import java.io.FileOutputStream; 139import java.io.FileReader; 140import java.io.FilenameFilter; 141import java.io.IOException; 142import java.io.PrintWriter; 143import java.security.NoSuchAlgorithmException; 144import java.security.PublicKey; 145import java.security.cert.CertificateException; 146import java.text.SimpleDateFormat; 147import java.util.ArrayList; 148import java.util.Arrays; 149import java.util.Collection; 150import java.util.Collections; 151import java.util.Comparator; 152import java.util.Date; 153import java.util.HashMap; 154import java.util.HashSet; 155import java.util.Iterator; 156import java.util.List; 157import java.util.Map; 158import java.util.Set; 159 160import libcore.io.ErrnoException; 161import libcore.io.IoUtils; 162import libcore.io.Libcore; 163import libcore.io.StructStat; 164 165import com.android.internal.R; 166import com.android.server.storage.DeviceStorageMonitorInternal; 167 168/** 169 * Keep track of all those .apks everywhere. 170 * 171 * This is very central to the platform's security; please run the unit 172 * tests whenever making modifications here: 173 * 174mmm frameworks/base/tests/AndroidTests 175adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 176adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 177 * 178 * {@hide} 179 */ 180public class PackageManagerService extends IPackageManager.Stub { 181 static final String TAG = "PackageManager"; 182 static final boolean DEBUG_SETTINGS = false; 183 static final boolean DEBUG_PREFERRED = false; 184 static final boolean DEBUG_UPGRADE = false; 185 private static final boolean DEBUG_INSTALL = false; 186 private static final boolean DEBUG_REMOVE = false; 187 private static final boolean DEBUG_BROADCASTS = false; 188 private static final boolean DEBUG_SHOW_INFO = false; 189 private static final boolean DEBUG_PACKAGE_INFO = false; 190 private static final boolean DEBUG_INTENT_MATCHING = false; 191 private static final boolean DEBUG_PACKAGE_SCANNING = false; 192 private static final boolean DEBUG_APP_DIR_OBSERVER = false; 193 private static final boolean DEBUG_VERIFY = false; 194 195 private static final int RADIO_UID = Process.PHONE_UID; 196 private static final int LOG_UID = Process.LOG_UID; 197 private static final int NFC_UID = Process.NFC_UID; 198 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 199 private static final int SHELL_UID = Process.SHELL_UID; 200 201 // Cap the size of permission trees that 3rd party apps can define 202 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 203 204 private static final int REMOVE_EVENTS = 205 FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM; 206 private static final int ADD_EVENTS = 207 FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO; 208 209 private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS; 210 // Suffix used during package installation when copying/moving 211 // package apks to install directory. 212 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 213 214 static final int SCAN_MONITOR = 1<<0; 215 static final int SCAN_NO_DEX = 1<<1; 216 static final int SCAN_FORCE_DEX = 1<<2; 217 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 218 static final int SCAN_NEW_INSTALL = 1<<4; 219 static final int SCAN_NO_PATHS = 1<<5; 220 static final int SCAN_UPDATE_TIME = 1<<6; 221 static final int SCAN_DEFER_DEX = 1<<7; 222 static final int SCAN_BOOTING = 1<<8; 223 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 224 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 225 226 static final int REMOVE_CHATTY = 1<<16; 227 228 /** 229 * Timeout (in milliseconds) after which the watchdog should declare that 230 * our handler thread is wedged. The usual default for such things is one 231 * minute but we sometimes do very lengthy I/O operations on this thread, 232 * such as installing multi-gigabyte applications, so ours needs to be longer. 233 */ 234 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 235 236 /** 237 * Whether verification is enabled by default. 238 */ 239 private static final boolean DEFAULT_VERIFY_ENABLE = true; 240 241 /** 242 * The default maximum time to wait for the verification agent to return in 243 * milliseconds. 244 */ 245 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 246 247 /** 248 * The default response for package verification timeout. 249 * 250 * This can be either PackageManager.VERIFICATION_ALLOW or 251 * PackageManager.VERIFICATION_REJECT. 252 */ 253 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 254 255 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 256 257 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 258 DEFAULT_CONTAINER_PACKAGE, 259 "com.android.defcontainer.DefaultContainerService"); 260 261 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 262 263 private static final String LIB_DIR_NAME = "lib"; 264 private static final String LIB64_DIR_NAME = "lib64"; 265 266 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 267 268 static final String mTempContainerPrefix = "smdl2tmp"; 269 270 final ServiceThread mHandlerThread; 271 272 private static final String IDMAP_PREFIX = "/data/resource-cache/"; 273 private static final String IDMAP_SUFFIX = "@idmap"; 274 275 final PackageHandler mHandler; 276 277 final int mSdkVersion = Build.VERSION.SDK_INT; 278 final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME) 279 ? null : Build.VERSION.CODENAME; 280 281 final Context mContext; 282 final boolean mFactoryTest; 283 final boolean mOnlyCore; 284 final boolean mNoDexOpt; 285 final DisplayMetrics mMetrics; 286 final int mDefParseFlags; 287 final String[] mSeparateProcesses; 288 289 // This is where all application persistent data goes. 290 final File mAppDataDir; 291 292 // This is where all application persistent data goes for secondary users. 293 final File mUserAppDataDir; 294 295 /** The location for ASEC container files on internal storage. */ 296 final String mAsecInternalPath; 297 298 // This is the object monitoring the framework dir. 299 final FileObserver mFrameworkInstallObserver; 300 301 // This is the object monitoring the system app dir. 302 final FileObserver mSystemInstallObserver; 303 304 // This is the object monitoring the privileged system app dir. 305 final FileObserver mPrivilegedInstallObserver; 306 307 // This is the object monitoring the vendor app dir. 308 final FileObserver mVendorInstallObserver; 309 310 // This is the object monitoring the vendor overlay package dir. 311 final FileObserver mVendorOverlayInstallObserver; 312 313 // This is the object monitoring the OEM app dir. 314 final FileObserver mOemInstallObserver; 315 316 // This is the object monitoring mAppInstallDir. 317 final FileObserver mAppInstallObserver; 318 319 // This is the object monitoring mDrmAppPrivateInstallDir. 320 final FileObserver mDrmAppInstallObserver; 321 322 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 323 // LOCK HELD. Can be called with mInstallLock held. 324 final Installer mInstaller; 325 326 final File mAppInstallDir; 327 328 /** 329 * Directory to which applications installed internally have native 330 * libraries copied. 331 */ 332 private File mAppLibInstallDir; 333 334 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 335 // apps. 336 final File mDrmAppPrivateInstallDir; 337 338 // ---------------------------------------------------------------- 339 340 // Lock for state used when installing and doing other long running 341 // operations. Methods that must be called with this lock held have 342 // the suffix "LI". 343 final Object mInstallLock = new Object(); 344 345 // These are the directories in the 3rd party applications installed dir 346 // that we have currently loaded packages from. Keys are the application's 347 // installed zip file (absolute codePath), and values are Package. 348 final HashMap<String, PackageParser.Package> mAppDirs = 349 new HashMap<String, PackageParser.Package>(); 350 351 // Information for the parser to write more useful error messages. 352 int mLastScanError; 353 354 // ---------------------------------------------------------------- 355 356 // Keys are String (package name), values are Package. This also serves 357 // as the lock for the global state. Methods that must be called with 358 // this lock held have the prefix "LP". 359 final HashMap<String, PackageParser.Package> mPackages = 360 new HashMap<String, PackageParser.Package>(); 361 362 // Tracks available target package names -> overlay package paths. 363 final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays = 364 new HashMap<String, HashMap<String, PackageParser.Package>>(); 365 366 final Settings mSettings; 367 boolean mRestoredSettings; 368 369 // Group-ids that are given to all packages as read from etc/permissions/*.xml. 370 int[] mGlobalGids; 371 372 // These are the built-in uid -> permission mappings that were read from the 373 // etc/permissions.xml file. 374 final SparseArray<HashSet<String>> mSystemPermissions = 375 new SparseArray<HashSet<String>>(); 376 377 static final class SharedLibraryEntry { 378 final String path; 379 final String apk; 380 381 SharedLibraryEntry(String _path, String _apk) { 382 path = _path; 383 apk = _apk; 384 } 385 } 386 387 // These are the built-in shared libraries that were read from the 388 // etc/permissions.xml file. 389 final HashMap<String, SharedLibraryEntry> mSharedLibraries 390 = new HashMap<String, SharedLibraryEntry>(); 391 392 // Temporary for building the final shared libraries for an .apk. 393 String[] mTmpSharedLibraries = null; 394 395 // These are the features this devices supports that were read from the 396 // etc/permissions.xml file. 397 final HashMap<String, FeatureInfo> mAvailableFeatures = 398 new HashMap<String, FeatureInfo>(); 399 400 // If mac_permissions.xml was found for seinfo labeling. 401 boolean mFoundPolicyFile; 402 403 // If a recursive restorecon of /data/data/<pkg> is needed. 404 private boolean mShouldRestoreconData = SELinuxMMAC.shouldRestorecon(); 405 406 // All available activities, for your resolving pleasure. 407 final ActivityIntentResolver mActivities = 408 new ActivityIntentResolver(); 409 410 // All available receivers, for your resolving pleasure. 411 final ActivityIntentResolver mReceivers = 412 new ActivityIntentResolver(); 413 414 // All available services, for your resolving pleasure. 415 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 416 417 // All available providers, for your resolving pleasure. 418 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 419 420 // Mapping from provider base names (first directory in content URI codePath) 421 // to the provider information. 422 final HashMap<String, PackageParser.Provider> mProvidersByAuthority = 423 new HashMap<String, PackageParser.Provider>(); 424 425 // Mapping from instrumentation class names to info about them. 426 final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 427 new HashMap<ComponentName, PackageParser.Instrumentation>(); 428 429 // Mapping from permission names to info about them. 430 final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups = 431 new HashMap<String, PackageParser.PermissionGroup>(); 432 433 // Packages whose data we have transfered into another package, thus 434 // should no longer exist. 435 final HashSet<String> mTransferedPackages = new HashSet<String>(); 436 437 // Broadcast actions that are only available to the system. 438 final HashSet<String> mProtectedBroadcasts = new HashSet<String>(); 439 440 /** List of packages waiting for verification. */ 441 final SparseArray<PackageVerificationState> mPendingVerification 442 = new SparseArray<PackageVerificationState>(); 443 444 HashSet<PackageParser.Package> mDeferredDexOpt = null; 445 446 /** Token for keys in mPendingVerification. */ 447 private int mPendingVerificationToken = 0; 448 449 boolean mSystemReady; 450 boolean mSafeMode; 451 boolean mHasSystemUidErrors; 452 453 ApplicationInfo mAndroidApplication; 454 final ActivityInfo mResolveActivity = new ActivityInfo(); 455 final ResolveInfo mResolveInfo = new ResolveInfo(); 456 ComponentName mResolveComponentName; 457 PackageParser.Package mPlatformPackage; 458 ComponentName mCustomResolverComponentName; 459 460 boolean mResolverReplaced = false; 461 462 // Set of pending broadcasts for aggregating enable/disable of components. 463 static class PendingPackageBroadcasts { 464 // for each user id, a map of <package name -> components within that package> 465 final SparseArray<HashMap<String, ArrayList<String>>> mUidMap; 466 467 public PendingPackageBroadcasts() { 468 mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2); 469 } 470 471 public ArrayList<String> get(int userId, String packageName) { 472 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId); 473 return packages.get(packageName); 474 } 475 476 public void put(int userId, String packageName, ArrayList<String> components) { 477 HashMap<String, ArrayList<String>> packages = getOrAllocate(userId); 478 packages.put(packageName, components); 479 } 480 481 public void remove(int userId, String packageName) { 482 HashMap<String, ArrayList<String>> packages = mUidMap.get(userId); 483 if (packages != null) { 484 packages.remove(packageName); 485 } 486 } 487 488 public void remove(int userId) { 489 mUidMap.remove(userId); 490 } 491 492 public int userIdCount() { 493 return mUidMap.size(); 494 } 495 496 public int userIdAt(int n) { 497 return mUidMap.keyAt(n); 498 } 499 500 public HashMap<String, ArrayList<String>> packagesForUserId(int userId) { 501 return mUidMap.get(userId); 502 } 503 504 public int size() { 505 // total number of pending broadcast entries across all userIds 506 int num = 0; 507 for (int i = 0; i< mUidMap.size(); i++) { 508 num += mUidMap.valueAt(i).size(); 509 } 510 return num; 511 } 512 513 public void clear() { 514 mUidMap.clear(); 515 } 516 517 private HashMap<String, ArrayList<String>> getOrAllocate(int userId) { 518 HashMap<String, ArrayList<String>> map = mUidMap.get(userId); 519 if (map == null) { 520 map = new HashMap<String, ArrayList<String>>(); 521 mUidMap.put(userId, map); 522 } 523 return map; 524 } 525 } 526 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 527 528 // Service Connection to remote media container service to copy 529 // package uri's from external media onto secure containers 530 // or internal storage. 531 private IMediaContainerService mContainerService = null; 532 533 static final int SEND_PENDING_BROADCAST = 1; 534 static final int MCS_BOUND = 3; 535 static final int END_COPY = 4; 536 static final int INIT_COPY = 5; 537 static final int MCS_UNBIND = 6; 538 static final int START_CLEANING_PACKAGE = 7; 539 static final int FIND_INSTALL_LOC = 8; 540 static final int POST_INSTALL = 9; 541 static final int MCS_RECONNECT = 10; 542 static final int MCS_GIVE_UP = 11; 543 static final int UPDATED_MEDIA_STATUS = 12; 544 static final int WRITE_SETTINGS = 13; 545 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 546 static final int PACKAGE_VERIFIED = 15; 547 static final int CHECK_PENDING_VERIFICATION = 16; 548 549 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 550 551 // Delay time in millisecs 552 static final int BROADCAST_DELAY = 10 * 1000; 553 554 static UserManagerService sUserManager; 555 556 // Stores a list of users whose package restrictions file needs to be updated 557 private HashSet<Integer> mDirtyUsers = new HashSet<Integer>(); 558 559 final private DefaultContainerConnection mDefContainerConn = 560 new DefaultContainerConnection(); 561 class DefaultContainerConnection implements ServiceConnection { 562 public void onServiceConnected(ComponentName name, IBinder service) { 563 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 564 IMediaContainerService imcs = 565 IMediaContainerService.Stub.asInterface(service); 566 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 567 } 568 569 public void onServiceDisconnected(ComponentName name) { 570 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 571 } 572 }; 573 574 // Recordkeeping of restore-after-install operations that are currently in flight 575 // between the Package Manager and the Backup Manager 576 class PostInstallData { 577 public InstallArgs args; 578 public PackageInstalledInfo res; 579 580 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 581 args = _a; 582 res = _r; 583 } 584 }; 585 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 586 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 587 588 private final String mRequiredVerifierPackage; 589 590 class PackageHandler extends Handler { 591 private boolean mBound = false; 592 final ArrayList<HandlerParams> mPendingInstalls = 593 new ArrayList<HandlerParams>(); 594 595 private boolean connectToService() { 596 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 597 " DefaultContainerService"); 598 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 599 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 600 if (mContext.bindServiceAsUser(service, mDefContainerConn, 601 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 602 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 603 mBound = true; 604 return true; 605 } 606 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 607 return false; 608 } 609 610 private void disconnectService() { 611 mContainerService = null; 612 mBound = false; 613 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 614 mContext.unbindService(mDefContainerConn); 615 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 616 } 617 618 PackageHandler(Looper looper) { 619 super(looper); 620 } 621 622 public void handleMessage(Message msg) { 623 try { 624 doHandleMessage(msg); 625 } finally { 626 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 627 } 628 } 629 630 void doHandleMessage(Message msg) { 631 switch (msg.what) { 632 case INIT_COPY: { 633 HandlerParams params = (HandlerParams) msg.obj; 634 int idx = mPendingInstalls.size(); 635 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 636 // If a bind was already initiated we dont really 637 // need to do anything. The pending install 638 // will be processed later on. 639 if (!mBound) { 640 // If this is the only one pending we might 641 // have to bind to the service again. 642 if (!connectToService()) { 643 Slog.e(TAG, "Failed to bind to media container service"); 644 params.serviceError(); 645 return; 646 } else { 647 // Once we bind to the service, the first 648 // pending request will be processed. 649 mPendingInstalls.add(idx, params); 650 } 651 } else { 652 mPendingInstalls.add(idx, params); 653 // Already bound to the service. Just make 654 // sure we trigger off processing the first request. 655 if (idx == 0) { 656 mHandler.sendEmptyMessage(MCS_BOUND); 657 } 658 } 659 break; 660 } 661 case MCS_BOUND: { 662 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 663 if (msg.obj != null) { 664 mContainerService = (IMediaContainerService) msg.obj; 665 } 666 if (mContainerService == null) { 667 // Something seriously wrong. Bail out 668 Slog.e(TAG, "Cannot bind to media container service"); 669 for (HandlerParams params : mPendingInstalls) { 670 // Indicate service bind error 671 params.serviceError(); 672 } 673 mPendingInstalls.clear(); 674 } else if (mPendingInstalls.size() > 0) { 675 HandlerParams params = mPendingInstalls.get(0); 676 if (params != null) { 677 if (params.startCopy()) { 678 // We are done... look for more work or to 679 // go idle. 680 if (DEBUG_SD_INSTALL) Log.i(TAG, 681 "Checking for more work or unbind..."); 682 // Delete pending install 683 if (mPendingInstalls.size() > 0) { 684 mPendingInstalls.remove(0); 685 } 686 if (mPendingInstalls.size() == 0) { 687 if (mBound) { 688 if (DEBUG_SD_INSTALL) Log.i(TAG, 689 "Posting delayed MCS_UNBIND"); 690 removeMessages(MCS_UNBIND); 691 Message ubmsg = obtainMessage(MCS_UNBIND); 692 // Unbind after a little delay, to avoid 693 // continual thrashing. 694 sendMessageDelayed(ubmsg, 10000); 695 } 696 } else { 697 // There are more pending requests in queue. 698 // Just post MCS_BOUND message to trigger processing 699 // of next pending install. 700 if (DEBUG_SD_INSTALL) Log.i(TAG, 701 "Posting MCS_BOUND for next work"); 702 mHandler.sendEmptyMessage(MCS_BOUND); 703 } 704 } 705 } 706 } else { 707 // Should never happen ideally. 708 Slog.w(TAG, "Empty queue"); 709 } 710 break; 711 } 712 case MCS_RECONNECT: { 713 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 714 if (mPendingInstalls.size() > 0) { 715 if (mBound) { 716 disconnectService(); 717 } 718 if (!connectToService()) { 719 Slog.e(TAG, "Failed to bind to media container service"); 720 for (HandlerParams params : mPendingInstalls) { 721 // Indicate service bind error 722 params.serviceError(); 723 } 724 mPendingInstalls.clear(); 725 } 726 } 727 break; 728 } 729 case MCS_UNBIND: { 730 // If there is no actual work left, then time to unbind. 731 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 732 733 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 734 if (mBound) { 735 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 736 737 disconnectService(); 738 } 739 } else if (mPendingInstalls.size() > 0) { 740 // There are more pending requests in queue. 741 // Just post MCS_BOUND message to trigger processing 742 // of next pending install. 743 mHandler.sendEmptyMessage(MCS_BOUND); 744 } 745 746 break; 747 } 748 case MCS_GIVE_UP: { 749 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 750 mPendingInstalls.remove(0); 751 break; 752 } 753 case SEND_PENDING_BROADCAST: { 754 String packages[]; 755 ArrayList<String> components[]; 756 int size = 0; 757 int uids[]; 758 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 759 synchronized (mPackages) { 760 if (mPendingBroadcasts == null) { 761 return; 762 } 763 size = mPendingBroadcasts.size(); 764 if (size <= 0) { 765 // Nothing to be done. Just return 766 return; 767 } 768 packages = new String[size]; 769 components = new ArrayList[size]; 770 uids = new int[size]; 771 int i = 0; // filling out the above arrays 772 773 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 774 int packageUserId = mPendingBroadcasts.userIdAt(n); 775 Iterator<Map.Entry<String, ArrayList<String>>> it 776 = mPendingBroadcasts.packagesForUserId(packageUserId) 777 .entrySet().iterator(); 778 while (it.hasNext() && i < size) { 779 Map.Entry<String, ArrayList<String>> ent = it.next(); 780 packages[i] = ent.getKey(); 781 components[i] = ent.getValue(); 782 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 783 uids[i] = (ps != null) 784 ? UserHandle.getUid(packageUserId, ps.appId) 785 : -1; 786 i++; 787 } 788 } 789 size = i; 790 mPendingBroadcasts.clear(); 791 } 792 // Send broadcasts 793 for (int i = 0; i < size; i++) { 794 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 795 } 796 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 797 break; 798 } 799 case START_CLEANING_PACKAGE: { 800 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 801 final String packageName = (String)msg.obj; 802 final int userId = msg.arg1; 803 final boolean andCode = msg.arg2 != 0; 804 synchronized (mPackages) { 805 if (userId == UserHandle.USER_ALL) { 806 int[] users = sUserManager.getUserIds(); 807 for (int user : users) { 808 mSettings.addPackageToCleanLPw( 809 new PackageCleanItem(user, packageName, andCode)); 810 } 811 } else { 812 mSettings.addPackageToCleanLPw( 813 new PackageCleanItem(userId, packageName, andCode)); 814 } 815 } 816 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 817 startCleaningPackages(); 818 } break; 819 case POST_INSTALL: { 820 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 821 PostInstallData data = mRunningInstalls.get(msg.arg1); 822 mRunningInstalls.delete(msg.arg1); 823 boolean deleteOld = false; 824 825 if (data != null) { 826 InstallArgs args = data.args; 827 PackageInstalledInfo res = data.res; 828 829 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 830 res.removedInfo.sendBroadcast(false, true, false); 831 Bundle extras = new Bundle(1); 832 extras.putInt(Intent.EXTRA_UID, res.uid); 833 // Determine the set of users who are adding this 834 // package for the first time vs. those who are seeing 835 // an update. 836 int[] firstUsers; 837 int[] updateUsers = new int[0]; 838 if (res.origUsers == null || res.origUsers.length == 0) { 839 firstUsers = res.newUsers; 840 } else { 841 firstUsers = new int[0]; 842 for (int i=0; i<res.newUsers.length; i++) { 843 int user = res.newUsers[i]; 844 boolean isNew = true; 845 for (int j=0; j<res.origUsers.length; j++) { 846 if (res.origUsers[j] == user) { 847 isNew = false; 848 break; 849 } 850 } 851 if (isNew) { 852 int[] newFirst = new int[firstUsers.length+1]; 853 System.arraycopy(firstUsers, 0, newFirst, 0, 854 firstUsers.length); 855 newFirst[firstUsers.length] = user; 856 firstUsers = newFirst; 857 } else { 858 int[] newUpdate = new int[updateUsers.length+1]; 859 System.arraycopy(updateUsers, 0, newUpdate, 0, 860 updateUsers.length); 861 newUpdate[updateUsers.length] = user; 862 updateUsers = newUpdate; 863 } 864 } 865 } 866 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 867 res.pkg.applicationInfo.packageName, 868 extras, null, null, firstUsers); 869 final boolean update = res.removedInfo.removedPackage != null; 870 if (update) { 871 extras.putBoolean(Intent.EXTRA_REPLACING, true); 872 } 873 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 874 res.pkg.applicationInfo.packageName, 875 extras, null, null, updateUsers); 876 if (update) { 877 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 878 res.pkg.applicationInfo.packageName, 879 extras, null, null, updateUsers); 880 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 881 null, null, 882 res.pkg.applicationInfo.packageName, null, updateUsers); 883 884 // treat asec-hosted packages like removable media on upgrade 885 if (isForwardLocked(res.pkg) || isExternal(res.pkg)) { 886 if (DEBUG_INSTALL) { 887 Slog.i(TAG, "upgrading pkg " + res.pkg 888 + " is ASEC-hosted -> AVAILABLE"); 889 } 890 int[] uidArray = new int[] { res.pkg.applicationInfo.uid }; 891 ArrayList<String> pkgList = new ArrayList<String>(1); 892 pkgList.add(res.pkg.applicationInfo.packageName); 893 sendResourcesChangedBroadcast(true, true, 894 pkgList,uidArray, null); 895 } 896 } 897 if (res.removedInfo.args != null) { 898 // Remove the replaced package's older resources safely now 899 deleteOld = true; 900 } 901 902 // Log current value of "unknown sources" setting 903 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 904 getUnknownSourcesSettings()); 905 } 906 // Force a gc to clear up things 907 Runtime.getRuntime().gc(); 908 // We delete after a gc for applications on sdcard. 909 if (deleteOld) { 910 synchronized (mInstallLock) { 911 res.removedInfo.args.doPostDeleteLI(true); 912 } 913 } 914 if (args.observer != null) { 915 try { 916 args.observer.packageInstalled(res.name, res.returnCode); 917 } catch (RemoteException e) { 918 Slog.i(TAG, "Observer no longer exists."); 919 } 920 } 921 if (args.observer2 != null) { 922 try { 923 Bundle extras = extrasForInstallResult(res); 924 args.observer2.packageInstalled(res.name, extras, res.returnCode); 925 } catch (RemoteException e) { 926 Slog.i(TAG, "Observer no longer exists."); 927 } 928 } 929 } else { 930 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 931 } 932 } break; 933 case UPDATED_MEDIA_STATUS: { 934 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 935 boolean reportStatus = msg.arg1 == 1; 936 boolean doGc = msg.arg2 == 1; 937 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 938 if (doGc) { 939 // Force a gc to clear up stale containers. 940 Runtime.getRuntime().gc(); 941 } 942 if (msg.obj != null) { 943 @SuppressWarnings("unchecked") 944 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 945 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 946 // Unload containers 947 unloadAllContainers(args); 948 } 949 if (reportStatus) { 950 try { 951 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 952 PackageHelper.getMountService().finishMediaUpdate(); 953 } catch (RemoteException e) { 954 Log.e(TAG, "MountService not running?"); 955 } 956 } 957 } break; 958 case WRITE_SETTINGS: { 959 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 960 synchronized (mPackages) { 961 removeMessages(WRITE_SETTINGS); 962 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 963 mSettings.writeLPr(); 964 mDirtyUsers.clear(); 965 } 966 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 967 } break; 968 case WRITE_PACKAGE_RESTRICTIONS: { 969 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 970 synchronized (mPackages) { 971 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 972 for (int userId : mDirtyUsers) { 973 mSettings.writePackageRestrictionsLPr(userId); 974 } 975 mDirtyUsers.clear(); 976 } 977 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 978 } break; 979 case CHECK_PENDING_VERIFICATION: { 980 final int verificationId = msg.arg1; 981 final PackageVerificationState state = mPendingVerification.get(verificationId); 982 983 if ((state != null) && !state.timeoutExtended()) { 984 final InstallArgs args = state.getInstallArgs(); 985 Slog.i(TAG, "Verification timed out for " + args.packageURI.toString()); 986 mPendingVerification.remove(verificationId); 987 988 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 989 990 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 991 Slog.i(TAG, "Continuing with installation of " 992 + args.packageURI.toString()); 993 state.setVerifierResponse(Binder.getCallingUid(), 994 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 995 broadcastPackageVerified(verificationId, args.packageURI, 996 PackageManager.VERIFICATION_ALLOW, 997 state.getInstallArgs().getUser()); 998 try { 999 ret = args.copyApk(mContainerService, true); 1000 } catch (RemoteException e) { 1001 Slog.e(TAG, "Could not contact the ContainerService"); 1002 } 1003 } else { 1004 broadcastPackageVerified(verificationId, args.packageURI, 1005 PackageManager.VERIFICATION_REJECT, 1006 state.getInstallArgs().getUser()); 1007 } 1008 1009 processPendingInstall(args, ret); 1010 mHandler.sendEmptyMessage(MCS_UNBIND); 1011 } 1012 break; 1013 } 1014 case PACKAGE_VERIFIED: { 1015 final int verificationId = msg.arg1; 1016 1017 final PackageVerificationState state = mPendingVerification.get(verificationId); 1018 if (state == null) { 1019 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1020 break; 1021 } 1022 1023 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1024 1025 state.setVerifierResponse(response.callerUid, response.code); 1026 1027 if (state.isVerificationComplete()) { 1028 mPendingVerification.remove(verificationId); 1029 1030 final InstallArgs args = state.getInstallArgs(); 1031 1032 int ret; 1033 if (state.isInstallAllowed()) { 1034 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1035 broadcastPackageVerified(verificationId, args.packageURI, 1036 response.code, state.getInstallArgs().getUser()); 1037 try { 1038 ret = args.copyApk(mContainerService, true); 1039 } catch (RemoteException e) { 1040 Slog.e(TAG, "Could not contact the ContainerService"); 1041 } 1042 } else { 1043 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1044 } 1045 1046 processPendingInstall(args, ret); 1047 1048 mHandler.sendEmptyMessage(MCS_UNBIND); 1049 } 1050 1051 break; 1052 } 1053 } 1054 } 1055 } 1056 1057 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1058 Bundle extras = null; 1059 switch (res.returnCode) { 1060 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1061 extras = new Bundle(); 1062 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1063 res.origPermission); 1064 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1065 res.origPackage); 1066 break; 1067 } 1068 } 1069 return extras; 1070 } 1071 1072 void scheduleWriteSettingsLocked() { 1073 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1074 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1075 } 1076 } 1077 1078 void scheduleWritePackageRestrictionsLocked(int userId) { 1079 if (!sUserManager.exists(userId)) return; 1080 mDirtyUsers.add(userId); 1081 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1082 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1083 } 1084 } 1085 1086 public static final IPackageManager main(Context context, Installer installer, 1087 boolean factoryTest, boolean onlyCore) { 1088 PackageManagerService m = new PackageManagerService(context, installer, 1089 factoryTest, onlyCore); 1090 ServiceManager.addService("package", m); 1091 return m; 1092 } 1093 1094 static String[] splitString(String str, char sep) { 1095 int count = 1; 1096 int i = 0; 1097 while ((i=str.indexOf(sep, i)) >= 0) { 1098 count++; 1099 i++; 1100 } 1101 1102 String[] res = new String[count]; 1103 i=0; 1104 count = 0; 1105 int lastI=0; 1106 while ((i=str.indexOf(sep, i)) >= 0) { 1107 res[count] = str.substring(lastI, i); 1108 count++; 1109 i++; 1110 lastI = i; 1111 } 1112 res[count] = str.substring(lastI, str.length()); 1113 return res; 1114 } 1115 1116 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 1117 DisplayManager displayManager = (DisplayManager) context.getSystemService( 1118 Context.DISPLAY_SERVICE); 1119 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 1120 } 1121 1122 public PackageManagerService(Context context, Installer installer, 1123 boolean factoryTest, boolean onlyCore) { 1124 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 1125 SystemClock.uptimeMillis()); 1126 1127 if (mSdkVersion <= 0) { 1128 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 1129 } 1130 1131 mContext = context; 1132 mFactoryTest = factoryTest; 1133 mOnlyCore = onlyCore; 1134 mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 1135 mMetrics = new DisplayMetrics(); 1136 mSettings = new Settings(context); 1137 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 1138 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1139 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 1140 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1141 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 1142 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1143 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 1144 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1145 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 1146 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1147 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 1148 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); 1149 1150 String separateProcesses = SystemProperties.get("debug.separate_processes"); 1151 if (separateProcesses != null && separateProcesses.length() > 0) { 1152 if ("*".equals(separateProcesses)) { 1153 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 1154 mSeparateProcesses = null; 1155 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 1156 } else { 1157 mDefParseFlags = 0; 1158 mSeparateProcesses = separateProcesses.split(","); 1159 Slog.w(TAG, "Running with debug.separate_processes: " 1160 + separateProcesses); 1161 } 1162 } else { 1163 mDefParseFlags = 0; 1164 mSeparateProcesses = null; 1165 } 1166 1167 mInstaller = installer; 1168 1169 getDefaultDisplayMetrics(context, mMetrics); 1170 1171 synchronized (mInstallLock) { 1172 // writer 1173 synchronized (mPackages) { 1174 mHandlerThread = new ServiceThread(TAG, 1175 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 1176 mHandlerThread.start(); 1177 mHandler = new PackageHandler(mHandlerThread.getLooper()); 1178 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 1179 1180 File dataDir = Environment.getDataDirectory(); 1181 mAppDataDir = new File(dataDir, "data"); 1182 mAppInstallDir = new File(dataDir, "app"); 1183 mAppLibInstallDir = new File(dataDir, "app-lib"); 1184 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 1185 mUserAppDataDir = new File(dataDir, "user"); 1186 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 1187 1188 sUserManager = new UserManagerService(context, this, 1189 mInstallLock, mPackages); 1190 1191 // Read permissions and features from system 1192 readPermissions(Environment.buildPath( 1193 Environment.getRootDirectory(), "etc", "permissions"), false); 1194 // Only read features from OEM 1195 readPermissions(Environment.buildPath( 1196 Environment.getOemDirectory(), "etc", "permissions"), true); 1197 1198 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 1199 1200 mRestoredSettings = mSettings.readLPw(this, sUserManager.getUsers(false), 1201 mSdkVersion, mOnlyCore); 1202 1203 String customResolverActivity = Resources.getSystem().getString( 1204 R.string.config_customResolverActivity); 1205 if (TextUtils.isEmpty(customResolverActivity)) { 1206 customResolverActivity = null; 1207 } else { 1208 mCustomResolverComponentName = ComponentName.unflattenFromString( 1209 customResolverActivity); 1210 } 1211 1212 long startTime = SystemClock.uptimeMillis(); 1213 1214 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 1215 startTime); 1216 1217 // Set flag to monitor and not change apk file paths when 1218 // scanning install directories. 1219 int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; 1220 if (mNoDexOpt) { 1221 Slog.w(TAG, "Running ENG build: no pre-dexopt!"); 1222 scanMode |= SCAN_NO_DEX; 1223 } 1224 1225 final HashSet<String> alreadyDexOpted = new HashSet<String>(); 1226 1227 /** 1228 * Add everything in the in the boot class path to the 1229 * list of process files because dexopt will have been run 1230 * if necessary during zygote startup. 1231 */ 1232 String bootClassPath = System.getProperty("java.boot.class.path"); 1233 if (bootClassPath != null) { 1234 String[] paths = splitString(bootClassPath, ':'); 1235 for (int i=0; i<paths.length; i++) { 1236 alreadyDexOpted.add(paths[i]); 1237 } 1238 } else { 1239 Slog.w(TAG, "No BOOTCLASSPATH found!"); 1240 } 1241 1242 boolean didDexOpt = false; 1243 1244 /** 1245 * Ensure all external libraries have had dexopt run on them. 1246 */ 1247 if (mSharedLibraries.size() > 0) { 1248 Iterator<SharedLibraryEntry> libs = mSharedLibraries.values().iterator(); 1249 while (libs.hasNext()) { 1250 String lib = libs.next().path; 1251 if (lib == null) { 1252 continue; 1253 } 1254 try { 1255 if (dalvik.system.DexFile.isDexOptNeededInternal(lib, null, false)) { 1256 alreadyDexOpted.add(lib); 1257 mInstaller.dexopt(lib, Process.SYSTEM_UID, true); 1258 didDexOpt = true; 1259 } 1260 } catch (FileNotFoundException e) { 1261 Slog.w(TAG, "Library not found: " + lib); 1262 } catch (IOException e) { 1263 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 1264 + e.getMessage()); 1265 } 1266 } 1267 } 1268 1269 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 1270 1271 // Gross hack for now: we know this file doesn't contain any 1272 // code, so don't dexopt it to avoid the resulting log spew. 1273 alreadyDexOpted.add(frameworkDir.getPath() + "/framework-res.apk"); 1274 1275 // Gross hack for now: we know this file is only part of 1276 // the boot class path for art, so don't dexopt it to 1277 // avoid the resulting log spew. 1278 alreadyDexOpted.add(frameworkDir.getPath() + "/core-libart.jar"); 1279 1280 /** 1281 * And there are a number of commands implemented in Java, which 1282 * we currently need to do the dexopt on so that they can be 1283 * run from a non-root shell. 1284 */ 1285 String[] frameworkFiles = frameworkDir.list(); 1286 if (frameworkFiles != null) { 1287 for (int i=0; i<frameworkFiles.length; i++) { 1288 File libPath = new File(frameworkDir, frameworkFiles[i]); 1289 String path = libPath.getPath(); 1290 // Skip the file if we alrady did it. 1291 if (alreadyDexOpted.contains(path)) { 1292 continue; 1293 } 1294 // Skip the file if it is not a type we want to dexopt. 1295 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 1296 continue; 1297 } 1298 try { 1299 if (dalvik.system.DexFile.isDexOptNeededInternal(path, null, false)) { 1300 mInstaller.dexopt(path, Process.SYSTEM_UID, true); 1301 didDexOpt = true; 1302 } 1303 } catch (FileNotFoundException e) { 1304 Slog.w(TAG, "Jar not found: " + path); 1305 } catch (IOException e) { 1306 Slog.w(TAG, "Exception reading jar: " + path, e); 1307 } 1308 } 1309 } 1310 1311 if (didDexOpt) { 1312 File dalvikCacheDir = new File(dataDir, "dalvik-cache"); 1313 1314 // If we had to do a dexopt of one of the previous 1315 // things, then something on the system has changed. 1316 // Consider this significant, and wipe away all other 1317 // existing dexopt files to ensure we don't leave any 1318 // dangling around. 1319 String[] files = dalvikCacheDir.list(); 1320 if (files != null) { 1321 for (int i=0; i<files.length; i++) { 1322 String fn = files[i]; 1323 if (fn.startsWith("data@app@") 1324 || fn.startsWith("data@app-private@")) { 1325 Slog.i(TAG, "Pruning dalvik file: " + fn); 1326 (new File(dalvikCacheDir, fn)).delete(); 1327 } 1328 } 1329 } 1330 } 1331 1332 // Collect vendor overlay packages. 1333 // (Do this before scanning any apps.) 1334 // For security and version matching reason, only consider 1335 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 1336 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 1337 mVendorOverlayInstallObserver = new AppDirObserver( 1338 vendorOverlayDir.getPath(), OBSERVER_EVENTS, true, false); 1339 mVendorOverlayInstallObserver.startWatching(); 1340 scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 1341 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode | SCAN_TRUSTED_OVERLAY, 0); 1342 1343 // Find base frameworks (resource packages without code). 1344 mFrameworkInstallObserver = new AppDirObserver( 1345 frameworkDir.getPath(), OBSERVER_EVENTS, true, false); 1346 mFrameworkInstallObserver.startWatching(); 1347 scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 1348 | PackageParser.PARSE_IS_SYSTEM_DIR 1349 | PackageParser.PARSE_IS_PRIVILEGED, 1350 scanMode | SCAN_NO_DEX, 0); 1351 1352 // Collected privileged system packages. 1353 File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 1354 mPrivilegedInstallObserver = new AppDirObserver( 1355 privilegedAppDir.getPath(), OBSERVER_EVENTS, true, true); 1356 mPrivilegedInstallObserver.startWatching(); 1357 scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 1358 | PackageParser.PARSE_IS_SYSTEM_DIR 1359 | PackageParser.PARSE_IS_PRIVILEGED, scanMode, 0); 1360 1361 // Collect ordinary system packages. 1362 File systemAppDir = new File(Environment.getRootDirectory(), "app"); 1363 mSystemInstallObserver = new AppDirObserver( 1364 systemAppDir.getPath(), OBSERVER_EVENTS, true, false); 1365 mSystemInstallObserver.startWatching(); 1366 scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 1367 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 1368 1369 // Collect all vendor packages. 1370 File vendorAppDir = new File("/vendor/app"); 1371 try { 1372 vendorAppDir = vendorAppDir.getCanonicalFile(); 1373 } catch (IOException e) { 1374 // failed to look up canonical path, continue with original one 1375 } 1376 mVendorInstallObserver = new AppDirObserver( 1377 vendorAppDir.getPath(), OBSERVER_EVENTS, true, false); 1378 mVendorInstallObserver.startWatching(); 1379 scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 1380 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 1381 1382 // Collect all OEM packages. 1383 File oemAppDir = new File(Environment.getOemDirectory(), "app"); 1384 mOemInstallObserver = new AppDirObserver( 1385 oemAppDir.getPath(), OBSERVER_EVENTS, true, false); 1386 mOemInstallObserver.startWatching(); 1387 scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 1388 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 1389 1390 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 1391 mInstaller.moveFiles(); 1392 1393 // Prune any system packages that no longer exist. 1394 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 1395 if (!mOnlyCore) { 1396 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 1397 while (psit.hasNext()) { 1398 PackageSetting ps = psit.next(); 1399 1400 /* 1401 * If this is not a system app, it can't be a 1402 * disable system app. 1403 */ 1404 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 1405 continue; 1406 } 1407 1408 /* 1409 * If the package is scanned, it's not erased. 1410 */ 1411 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 1412 if (scannedPkg != null) { 1413 /* 1414 * If the system app is both scanned and in the 1415 * disabled packages list, then it must have been 1416 * added via OTA. Remove it from the currently 1417 * scanned package so the previously user-installed 1418 * application can be scanned. 1419 */ 1420 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 1421 Slog.i(TAG, "Expecting better updatd system app for " + ps.name 1422 + "; removing system app"); 1423 removePackageLI(ps, true); 1424 } 1425 1426 continue; 1427 } 1428 1429 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 1430 psit.remove(); 1431 String msg = "System package " + ps.name 1432 + " no longer exists; wiping its data"; 1433 reportSettingsProblem(Log.WARN, msg); 1434 removeDataDirsLI(ps.name); 1435 } else { 1436 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 1437 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 1438 possiblyDeletedUpdatedSystemApps.add(ps.name); 1439 } 1440 } 1441 } 1442 } 1443 1444 //look for any incomplete package installations 1445 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 1446 //clean up list 1447 for(int i = 0; i < deletePkgsList.size(); i++) { 1448 //clean up here 1449 cleanupInstallFailedPackage(deletePkgsList.get(i)); 1450 } 1451 //delete tmp files 1452 deleteTempPackageFiles(); 1453 1454 // Remove any shared userIDs that have no associated packages 1455 mSettings.pruneSharedUsersLPw(); 1456 1457 if (!mOnlyCore) { 1458 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 1459 SystemClock.uptimeMillis()); 1460 mAppInstallObserver = new AppDirObserver( 1461 mAppInstallDir.getPath(), OBSERVER_EVENTS, false, false); 1462 mAppInstallObserver.startWatching(); 1463 scanDirLI(mAppInstallDir, 0, scanMode, 0); 1464 1465 mDrmAppInstallObserver = new AppDirObserver( 1466 mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false, false); 1467 mDrmAppInstallObserver.startWatching(); 1468 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 1469 scanMode, 0); 1470 1471 /** 1472 * Remove disable package settings for any updated system 1473 * apps that were removed via an OTA. If they're not a 1474 * previously-updated app, remove them completely. 1475 * Otherwise, just revoke their system-level permissions. 1476 */ 1477 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 1478 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 1479 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 1480 1481 String msg; 1482 if (deletedPkg == null) { 1483 msg = "Updated system package " + deletedAppName 1484 + " no longer exists; wiping its data"; 1485 removeDataDirsLI(deletedAppName); 1486 } else { 1487 msg = "Updated system app + " + deletedAppName 1488 + " no longer present; removing system privileges for " 1489 + deletedAppName; 1490 1491 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 1492 1493 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 1494 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 1495 } 1496 reportSettingsProblem(Log.WARN, msg); 1497 } 1498 } else { 1499 mAppInstallObserver = null; 1500 mDrmAppInstallObserver = null; 1501 } 1502 1503 // Now that we know all of the shared libraries, update all clients to have 1504 // the correct library paths. 1505 updateAllSharedLibrariesLPw(); 1506 1507 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 1508 SystemClock.uptimeMillis()); 1509 Slog.i(TAG, "Time to scan packages: " 1510 + ((SystemClock.uptimeMillis()-startTime)/1000f) 1511 + " seconds"); 1512 1513 // If the platform SDK has changed since the last time we booted, 1514 // we need to re-grant app permission to catch any new ones that 1515 // appear. This is really a hack, and means that apps can in some 1516 // cases get permissions that the user didn't initially explicitly 1517 // allow... it would be nice to have some better way to handle 1518 // this situation. 1519 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 1520 != mSdkVersion; 1521 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 1522 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 1523 + "; regranting permissions for internal storage"); 1524 mSettings.mInternalSdkPlatform = mSdkVersion; 1525 1526 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 1527 | (regrantPermissions 1528 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 1529 : 0)); 1530 1531 // If this is the first boot, and it is a normal boot, then 1532 // we need to initialize the default preferred apps. 1533 if (!mRestoredSettings && !onlyCore) { 1534 mSettings.readDefaultPreferredAppsLPw(this, 0); 1535 } 1536 1537 // can downgrade to reader 1538 mSettings.writeLPr(); 1539 1540 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 1541 SystemClock.uptimeMillis()); 1542 1543 // Now after opening every single application zip, make sure they 1544 // are all flushed. Not really needed, but keeps things nice and 1545 // tidy. 1546 Runtime.getRuntime().gc(); 1547 1548 mRequiredVerifierPackage = getRequiredVerifierLPr(); 1549 } // synchronized (mPackages) 1550 } // synchronized (mInstallLock) 1551 } 1552 1553 public boolean isFirstBoot() { 1554 return !mRestoredSettings; 1555 } 1556 1557 public boolean isOnlyCoreApps() { 1558 return mOnlyCore; 1559 } 1560 1561 private String getRequiredVerifierLPr() { 1562 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 1563 final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, 1564 PackageManager.GET_DISABLED_COMPONENTS, 0 /* TODO: Which userId? */); 1565 1566 String requiredVerifier = null; 1567 1568 final int N = receivers.size(); 1569 for (int i = 0; i < N; i++) { 1570 final ResolveInfo info = receivers.get(i); 1571 1572 if (info.activityInfo == null) { 1573 continue; 1574 } 1575 1576 final String packageName = info.activityInfo.packageName; 1577 1578 final PackageSetting ps = mSettings.mPackages.get(packageName); 1579 if (ps == null) { 1580 continue; 1581 } 1582 1583 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1584 if (!gp.grantedPermissions 1585 .contains(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)) { 1586 continue; 1587 } 1588 1589 if (requiredVerifier != null) { 1590 throw new RuntimeException("There can be only one required verifier"); 1591 } 1592 1593 requiredVerifier = packageName; 1594 } 1595 1596 return requiredVerifier; 1597 } 1598 1599 @Override 1600 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1601 throws RemoteException { 1602 try { 1603 return super.onTransact(code, data, reply, flags); 1604 } catch (RuntimeException e) { 1605 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 1606 Slog.wtf(TAG, "Package Manager Crash", e); 1607 } 1608 throw e; 1609 } 1610 } 1611 1612 void cleanupInstallFailedPackage(PackageSetting ps) { 1613 Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name); 1614 removeDataDirsLI(ps.name); 1615 if (ps.codePath != null) { 1616 if (!ps.codePath.delete()) { 1617 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath); 1618 } 1619 } 1620 if (ps.resourcePath != null) { 1621 if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) { 1622 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath); 1623 } 1624 } 1625 mSettings.removePackageLPw(ps.name); 1626 } 1627 1628 void readPermissions(File libraryDir, boolean onlyFeatures) { 1629 // Read permissions from .../etc/permission directory. 1630 if (!libraryDir.exists() || !libraryDir.isDirectory()) { 1631 Slog.w(TAG, "No directory " + libraryDir + ", skipping"); 1632 return; 1633 } 1634 if (!libraryDir.canRead()) { 1635 Slog.w(TAG, "Directory " + libraryDir + " cannot be read"); 1636 return; 1637 } 1638 1639 // Iterate over the files in the directory and scan .xml files 1640 for (File f : libraryDir.listFiles()) { 1641 // We'll read platform.xml last 1642 if (f.getPath().endsWith("etc/permissions/platform.xml")) { 1643 continue; 1644 } 1645 1646 if (!f.getPath().endsWith(".xml")) { 1647 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring"); 1648 continue; 1649 } 1650 if (!f.canRead()) { 1651 Slog.w(TAG, "Permissions library file " + f + " cannot be read"); 1652 continue; 1653 } 1654 1655 readPermissionsFromXml(f, onlyFeatures); 1656 } 1657 1658 // Read permissions from .../etc/permissions/platform.xml last so it will take precedence 1659 final File permFile = new File(Environment.getRootDirectory(), 1660 "etc/permissions/platform.xml"); 1661 readPermissionsFromXml(permFile, onlyFeatures); 1662 } 1663 1664 private void readPermissionsFromXml(File permFile, boolean onlyFeatures) { 1665 FileReader permReader = null; 1666 try { 1667 permReader = new FileReader(permFile); 1668 } catch (FileNotFoundException e) { 1669 Slog.w(TAG, "Couldn't find or open permissions file " + permFile); 1670 return; 1671 } 1672 1673 try { 1674 XmlPullParser parser = Xml.newPullParser(); 1675 parser.setInput(permReader); 1676 1677 XmlUtils.beginDocument(parser, "permissions"); 1678 1679 while (true) { 1680 XmlUtils.nextElement(parser); 1681 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { 1682 break; 1683 } 1684 1685 String name = parser.getName(); 1686 if ("group".equals(name) && !onlyFeatures) { 1687 String gidStr = parser.getAttributeValue(null, "gid"); 1688 if (gidStr != null) { 1689 int gid = Process.getGidForName(gidStr); 1690 mGlobalGids = appendInt(mGlobalGids, gid); 1691 } else { 1692 Slog.w(TAG, "<group> without gid at " 1693 + parser.getPositionDescription()); 1694 } 1695 1696 XmlUtils.skipCurrentTag(parser); 1697 continue; 1698 } else if ("permission".equals(name) && !onlyFeatures) { 1699 String perm = parser.getAttributeValue(null, "name"); 1700 if (perm == null) { 1701 Slog.w(TAG, "<permission> without name at " 1702 + parser.getPositionDescription()); 1703 XmlUtils.skipCurrentTag(parser); 1704 continue; 1705 } 1706 perm = perm.intern(); 1707 readPermission(parser, perm); 1708 1709 } else if ("assign-permission".equals(name) && !onlyFeatures) { 1710 String perm = parser.getAttributeValue(null, "name"); 1711 if (perm == null) { 1712 Slog.w(TAG, "<assign-permission> without name at " 1713 + parser.getPositionDescription()); 1714 XmlUtils.skipCurrentTag(parser); 1715 continue; 1716 } 1717 String uidStr = parser.getAttributeValue(null, "uid"); 1718 if (uidStr == null) { 1719 Slog.w(TAG, "<assign-permission> without uid at " 1720 + parser.getPositionDescription()); 1721 XmlUtils.skipCurrentTag(parser); 1722 continue; 1723 } 1724 int uid = Process.getUidForName(uidStr); 1725 if (uid < 0) { 1726 Slog.w(TAG, "<assign-permission> with unknown uid \"" 1727 + uidStr + "\" at " 1728 + parser.getPositionDescription()); 1729 XmlUtils.skipCurrentTag(parser); 1730 continue; 1731 } 1732 perm = perm.intern(); 1733 HashSet<String> perms = mSystemPermissions.get(uid); 1734 if (perms == null) { 1735 perms = new HashSet<String>(); 1736 mSystemPermissions.put(uid, perms); 1737 } 1738 perms.add(perm); 1739 XmlUtils.skipCurrentTag(parser); 1740 1741 } else if ("library".equals(name) && !onlyFeatures) { 1742 String lname = parser.getAttributeValue(null, "name"); 1743 String lfile = parser.getAttributeValue(null, "file"); 1744 if (lname == null) { 1745 Slog.w(TAG, "<library> without name at " 1746 + parser.getPositionDescription()); 1747 } else if (lfile == null) { 1748 Slog.w(TAG, "<library> without file at " 1749 + parser.getPositionDescription()); 1750 } else { 1751 //Log.i(TAG, "Got library " + lname + " in " + lfile); 1752 mSharedLibraries.put(lname, new SharedLibraryEntry(lfile, null)); 1753 } 1754 XmlUtils.skipCurrentTag(parser); 1755 continue; 1756 1757 } else if ("feature".equals(name)) { 1758 String fname = parser.getAttributeValue(null, "name"); 1759 if (fname == null) { 1760 Slog.w(TAG, "<feature> without name at " 1761 + parser.getPositionDescription()); 1762 } else { 1763 //Log.i(TAG, "Got feature " + fname); 1764 FeatureInfo fi = new FeatureInfo(); 1765 fi.name = fname; 1766 mAvailableFeatures.put(fname, fi); 1767 } 1768 XmlUtils.skipCurrentTag(parser); 1769 continue; 1770 1771 } else { 1772 XmlUtils.skipCurrentTag(parser); 1773 continue; 1774 } 1775 1776 } 1777 permReader.close(); 1778 } catch (XmlPullParserException e) { 1779 Slog.w(TAG, "Got execption parsing permissions.", e); 1780 } catch (IOException e) { 1781 Slog.w(TAG, "Got execption parsing permissions.", e); 1782 } 1783 } 1784 1785 void readPermission(XmlPullParser parser, String name) 1786 throws IOException, XmlPullParserException { 1787 1788 name = name.intern(); 1789 1790 BasePermission bp = mSettings.mPermissions.get(name); 1791 if (bp == null) { 1792 bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN); 1793 mSettings.mPermissions.put(name, bp); 1794 } 1795 int outerDepth = parser.getDepth(); 1796 int type; 1797 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1798 && (type != XmlPullParser.END_TAG 1799 || parser.getDepth() > outerDepth)) { 1800 if (type == XmlPullParser.END_TAG 1801 || type == XmlPullParser.TEXT) { 1802 continue; 1803 } 1804 1805 String tagName = parser.getName(); 1806 if ("group".equals(tagName)) { 1807 String gidStr = parser.getAttributeValue(null, "gid"); 1808 if (gidStr != null) { 1809 int gid = Process.getGidForName(gidStr); 1810 bp.gids = appendInt(bp.gids, gid); 1811 } else { 1812 Slog.w(TAG, "<group> without gid at " 1813 + parser.getPositionDescription()); 1814 } 1815 } 1816 XmlUtils.skipCurrentTag(parser); 1817 } 1818 } 1819 1820 static int[] appendInts(int[] cur, int[] add) { 1821 if (add == null) return cur; 1822 if (cur == null) return add; 1823 final int N = add.length; 1824 for (int i=0; i<N; i++) { 1825 cur = appendInt(cur, add[i]); 1826 } 1827 return cur; 1828 } 1829 1830 static int[] removeInts(int[] cur, int[] rem) { 1831 if (rem == null) return cur; 1832 if (cur == null) return cur; 1833 final int N = rem.length; 1834 for (int i=0; i<N; i++) { 1835 cur = removeInt(cur, rem[i]); 1836 } 1837 return cur; 1838 } 1839 1840 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 1841 if (!sUserManager.exists(userId)) return null; 1842 PackageInfo pi; 1843 final PackageSetting ps = (PackageSetting) p.mExtras; 1844 if (ps == null) { 1845 return null; 1846 } 1847 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1848 final PackageUserState state = ps.readUserState(userId); 1849 return PackageParser.generatePackageInfo(p, gp.gids, flags, 1850 ps.firstInstallTime, ps.lastUpdateTime, gp.grantedPermissions, 1851 state, userId); 1852 } 1853 1854 public boolean isPackageAvailable(String packageName, int userId) { 1855 if (!sUserManager.exists(userId)) return false; 1856 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available"); 1857 synchronized (mPackages) { 1858 PackageParser.Package p = mPackages.get(packageName); 1859 if (p != null) { 1860 final PackageSetting ps = (PackageSetting) p.mExtras; 1861 if (ps != null) { 1862 final PackageUserState state = ps.readUserState(userId); 1863 if (state != null) { 1864 return PackageParser.isAvailable(state); 1865 } 1866 } 1867 } 1868 } 1869 return false; 1870 } 1871 1872 @Override 1873 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 1874 if (!sUserManager.exists(userId)) return null; 1875 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info"); 1876 // reader 1877 synchronized (mPackages) { 1878 PackageParser.Package p = mPackages.get(packageName); 1879 if (DEBUG_PACKAGE_INFO) 1880 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 1881 if (p != null) { 1882 return generatePackageInfo(p, flags, userId); 1883 } 1884 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 1885 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 1886 } 1887 } 1888 return null; 1889 } 1890 1891 public String[] currentToCanonicalPackageNames(String[] names) { 1892 String[] out = new String[names.length]; 1893 // reader 1894 synchronized (mPackages) { 1895 for (int i=names.length-1; i>=0; i--) { 1896 PackageSetting ps = mSettings.mPackages.get(names[i]); 1897 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 1898 } 1899 } 1900 return out; 1901 } 1902 1903 public String[] canonicalToCurrentPackageNames(String[] names) { 1904 String[] out = new String[names.length]; 1905 // reader 1906 synchronized (mPackages) { 1907 for (int i=names.length-1; i>=0; i--) { 1908 String cur = mSettings.mRenamedPackages.get(names[i]); 1909 out[i] = cur != null ? cur : names[i]; 1910 } 1911 } 1912 return out; 1913 } 1914 1915 @Override 1916 public int getPackageUid(String packageName, int userId) { 1917 if (!sUserManager.exists(userId)) return -1; 1918 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid"); 1919 // reader 1920 synchronized (mPackages) { 1921 PackageParser.Package p = mPackages.get(packageName); 1922 if(p != null) { 1923 return UserHandle.getUid(userId, p.applicationInfo.uid); 1924 } 1925 PackageSetting ps = mSettings.mPackages.get(packageName); 1926 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 1927 return -1; 1928 } 1929 p = ps.pkg; 1930 return p != null ? UserHandle.getUid(userId, p.applicationInfo.uid) : -1; 1931 } 1932 } 1933 1934 @Override 1935 public int[] getPackageGids(String packageName) { 1936 // reader 1937 synchronized (mPackages) { 1938 PackageParser.Package p = mPackages.get(packageName); 1939 if (DEBUG_PACKAGE_INFO) 1940 Log.v(TAG, "getPackageGids" + packageName + ": " + p); 1941 if (p != null) { 1942 final PackageSetting ps = (PackageSetting)p.mExtras; 1943 return ps.getGids(); 1944 } 1945 } 1946 // stupid thing to indicate an error. 1947 return new int[0]; 1948 } 1949 1950 static final PermissionInfo generatePermissionInfo( 1951 BasePermission bp, int flags) { 1952 if (bp.perm != null) { 1953 return PackageParser.generatePermissionInfo(bp.perm, flags); 1954 } 1955 PermissionInfo pi = new PermissionInfo(); 1956 pi.name = bp.name; 1957 pi.packageName = bp.sourcePackage; 1958 pi.nonLocalizedLabel = bp.name; 1959 pi.protectionLevel = bp.protectionLevel; 1960 return pi; 1961 } 1962 1963 public PermissionInfo getPermissionInfo(String name, int flags) { 1964 // reader 1965 synchronized (mPackages) { 1966 final BasePermission p = mSettings.mPermissions.get(name); 1967 if (p != null) { 1968 return generatePermissionInfo(p, flags); 1969 } 1970 return null; 1971 } 1972 } 1973 1974 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 1975 // reader 1976 synchronized (mPackages) { 1977 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 1978 for (BasePermission p : mSettings.mPermissions.values()) { 1979 if (group == null) { 1980 if (p.perm == null || p.perm.info.group == null) { 1981 out.add(generatePermissionInfo(p, flags)); 1982 } 1983 } else { 1984 if (p.perm != null && group.equals(p.perm.info.group)) { 1985 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 1986 } 1987 } 1988 } 1989 1990 if (out.size() > 0) { 1991 return out; 1992 } 1993 return mPermissionGroups.containsKey(group) ? out : null; 1994 } 1995 } 1996 1997 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 1998 // reader 1999 synchronized (mPackages) { 2000 return PackageParser.generatePermissionGroupInfo( 2001 mPermissionGroups.get(name), flags); 2002 } 2003 } 2004 2005 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 2006 // reader 2007 synchronized (mPackages) { 2008 final int N = mPermissionGroups.size(); 2009 ArrayList<PermissionGroupInfo> out 2010 = new ArrayList<PermissionGroupInfo>(N); 2011 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 2012 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 2013 } 2014 return out; 2015 } 2016 } 2017 2018 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 2019 int userId) { 2020 if (!sUserManager.exists(userId)) return null; 2021 PackageSetting ps = mSettings.mPackages.get(packageName); 2022 if (ps != null) { 2023 if (ps.pkg == null) { 2024 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 2025 flags, userId); 2026 if (pInfo != null) { 2027 return pInfo.applicationInfo; 2028 } 2029 return null; 2030 } 2031 return PackageParser.generateApplicationInfo(ps.pkg, flags, 2032 ps.readUserState(userId), userId); 2033 } 2034 return null; 2035 } 2036 2037 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 2038 int userId) { 2039 if (!sUserManager.exists(userId)) return null; 2040 PackageSetting ps = mSettings.mPackages.get(packageName); 2041 if (ps != null) { 2042 PackageParser.Package pkg = ps.pkg; 2043 if (pkg == null) { 2044 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) == 0) { 2045 return null; 2046 } 2047 pkg = new PackageParser.Package(packageName); 2048 pkg.applicationInfo.packageName = packageName; 2049 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 2050 pkg.applicationInfo.publicSourceDir = ps.resourcePathString; 2051 pkg.applicationInfo.sourceDir = ps.codePathString; 2052 pkg.applicationInfo.dataDir = 2053 getDataPathForPackage(packageName, 0).getPath(); 2054 pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString; 2055 pkg.applicationInfo.requiredCpuAbi = ps.requiredCpuAbiString; 2056 } 2057 return generatePackageInfo(pkg, flags, userId); 2058 } 2059 return null; 2060 } 2061 2062 @Override 2063 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 2064 if (!sUserManager.exists(userId)) return null; 2065 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info"); 2066 // writer 2067 synchronized (mPackages) { 2068 PackageParser.Package p = mPackages.get(packageName); 2069 if (DEBUG_PACKAGE_INFO) Log.v( 2070 TAG, "getApplicationInfo " + packageName 2071 + ": " + p); 2072 if (p != null) { 2073 PackageSetting ps = mSettings.mPackages.get(packageName); 2074 if (ps == null) return null; 2075 // Note: isEnabledLP() does not apply here - always return info 2076 return PackageParser.generateApplicationInfo( 2077 p, flags, ps.readUserState(userId), userId); 2078 } 2079 if ("android".equals(packageName)||"system".equals(packageName)) { 2080 return mAndroidApplication; 2081 } 2082 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 2083 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 2084 } 2085 } 2086 return null; 2087 } 2088 2089 2090 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) { 2091 mContext.enforceCallingOrSelfPermission( 2092 android.Manifest.permission.CLEAR_APP_CACHE, null); 2093 // Queue up an async operation since clearing cache may take a little while. 2094 mHandler.post(new Runnable() { 2095 public void run() { 2096 mHandler.removeCallbacks(this); 2097 int retCode = -1; 2098 synchronized (mInstallLock) { 2099 retCode = mInstaller.freeCache(freeStorageSize); 2100 if (retCode < 0) { 2101 Slog.w(TAG, "Couldn't clear application caches"); 2102 } 2103 } 2104 if (observer != null) { 2105 try { 2106 observer.onRemoveCompleted(null, (retCode >= 0)); 2107 } catch (RemoteException e) { 2108 Slog.w(TAG, "RemoveException when invoking call back"); 2109 } 2110 } 2111 } 2112 }); 2113 } 2114 2115 public void freeStorage(final long freeStorageSize, final IntentSender pi) { 2116 mContext.enforceCallingOrSelfPermission( 2117 android.Manifest.permission.CLEAR_APP_CACHE, null); 2118 // Queue up an async operation since clearing cache may take a little while. 2119 mHandler.post(new Runnable() { 2120 public void run() { 2121 mHandler.removeCallbacks(this); 2122 int retCode = -1; 2123 synchronized (mInstallLock) { 2124 retCode = mInstaller.freeCache(freeStorageSize); 2125 if (retCode < 0) { 2126 Slog.w(TAG, "Couldn't clear application caches"); 2127 } 2128 } 2129 if(pi != null) { 2130 try { 2131 // Callback via pending intent 2132 int code = (retCode >= 0) ? 1 : 0; 2133 pi.sendIntent(null, code, null, 2134 null, null); 2135 } catch (SendIntentException e1) { 2136 Slog.i(TAG, "Failed to send pending intent"); 2137 } 2138 } 2139 } 2140 }); 2141 } 2142 2143 @Override 2144 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 2145 if (!sUserManager.exists(userId)) return null; 2146 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info"); 2147 synchronized (mPackages) { 2148 PackageParser.Activity a = mActivities.mActivities.get(component); 2149 2150 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 2151 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2152 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2153 if (ps == null) return null; 2154 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2155 userId); 2156 } 2157 if (mResolveComponentName.equals(component)) { 2158 return mResolveActivity; 2159 } 2160 } 2161 return null; 2162 } 2163 2164 @Override 2165 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 2166 if (!sUserManager.exists(userId)) return null; 2167 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info"); 2168 synchronized (mPackages) { 2169 PackageParser.Activity a = mReceivers.mActivities.get(component); 2170 if (DEBUG_PACKAGE_INFO) Log.v( 2171 TAG, "getReceiverInfo " + component + ": " + a); 2172 if (a != null && mSettings.isEnabledLPr(a.info, flags, userId)) { 2173 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2174 if (ps == null) return null; 2175 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 2176 userId); 2177 } 2178 } 2179 return null; 2180 } 2181 2182 @Override 2183 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 2184 if (!sUserManager.exists(userId)) return null; 2185 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info"); 2186 synchronized (mPackages) { 2187 PackageParser.Service s = mServices.mServices.get(component); 2188 if (DEBUG_PACKAGE_INFO) Log.v( 2189 TAG, "getServiceInfo " + component + ": " + s); 2190 if (s != null && mSettings.isEnabledLPr(s.info, flags, userId)) { 2191 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2192 if (ps == null) return null; 2193 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 2194 userId); 2195 } 2196 } 2197 return null; 2198 } 2199 2200 @Override 2201 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 2202 if (!sUserManager.exists(userId)) return null; 2203 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info"); 2204 synchronized (mPackages) { 2205 PackageParser.Provider p = mProviders.mProviders.get(component); 2206 if (DEBUG_PACKAGE_INFO) Log.v( 2207 TAG, "getProviderInfo " + component + ": " + p); 2208 if (p != null && mSettings.isEnabledLPr(p.info, flags, userId)) { 2209 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 2210 if (ps == null) return null; 2211 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 2212 userId); 2213 } 2214 } 2215 return null; 2216 } 2217 2218 public String[] getSystemSharedLibraryNames() { 2219 Set<String> libSet; 2220 synchronized (mPackages) { 2221 libSet = mSharedLibraries.keySet(); 2222 int size = libSet.size(); 2223 if (size > 0) { 2224 String[] libs = new String[size]; 2225 libSet.toArray(libs); 2226 return libs; 2227 } 2228 } 2229 return null; 2230 } 2231 2232 public FeatureInfo[] getSystemAvailableFeatures() { 2233 Collection<FeatureInfo> featSet; 2234 synchronized (mPackages) { 2235 featSet = mAvailableFeatures.values(); 2236 int size = featSet.size(); 2237 if (size > 0) { 2238 FeatureInfo[] features = new FeatureInfo[size+1]; 2239 featSet.toArray(features); 2240 FeatureInfo fi = new FeatureInfo(); 2241 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 2242 FeatureInfo.GL_ES_VERSION_UNDEFINED); 2243 features[size] = fi; 2244 return features; 2245 } 2246 } 2247 return null; 2248 } 2249 2250 public boolean hasSystemFeature(String name) { 2251 synchronized (mPackages) { 2252 return mAvailableFeatures.containsKey(name); 2253 } 2254 } 2255 2256 private void checkValidCaller(int uid, int userId) { 2257 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) 2258 return; 2259 2260 throw new SecurityException("Caller uid=" + uid 2261 + " is not privileged to communicate with user=" + userId); 2262 } 2263 2264 public int checkPermission(String permName, String pkgName) { 2265 synchronized (mPackages) { 2266 PackageParser.Package p = mPackages.get(pkgName); 2267 if (p != null && p.mExtras != null) { 2268 PackageSetting ps = (PackageSetting)p.mExtras; 2269 if (ps.sharedUser != null) { 2270 if (ps.sharedUser.grantedPermissions.contains(permName)) { 2271 return PackageManager.PERMISSION_GRANTED; 2272 } 2273 } else if (ps.grantedPermissions.contains(permName)) { 2274 return PackageManager.PERMISSION_GRANTED; 2275 } 2276 } 2277 } 2278 return PackageManager.PERMISSION_DENIED; 2279 } 2280 2281 public int checkUidPermission(String permName, int uid) { 2282 synchronized (mPackages) { 2283 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2284 if (obj != null) { 2285 GrantedPermissions gp = (GrantedPermissions)obj; 2286 if (gp.grantedPermissions.contains(permName)) { 2287 return PackageManager.PERMISSION_GRANTED; 2288 } 2289 } else { 2290 HashSet<String> perms = mSystemPermissions.get(uid); 2291 if (perms != null && perms.contains(permName)) { 2292 return PackageManager.PERMISSION_GRANTED; 2293 } 2294 } 2295 } 2296 return PackageManager.PERMISSION_DENIED; 2297 } 2298 2299 /** 2300 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 2301 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 2302 * @param message the message to log on security exception 2303 * @return 2304 */ 2305 private void enforceCrossUserPermission(int callingUid, int userId, 2306 boolean requireFullPermission, String message) { 2307 if (userId < 0) { 2308 throw new IllegalArgumentException("Invalid userId " + userId); 2309 } 2310 if (userId == UserHandle.getUserId(callingUid)) return; 2311 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 2312 if (requireFullPermission) { 2313 mContext.enforceCallingOrSelfPermission( 2314 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2315 } else { 2316 try { 2317 mContext.enforceCallingOrSelfPermission( 2318 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 2319 } catch (SecurityException se) { 2320 mContext.enforceCallingOrSelfPermission( 2321 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 2322 } 2323 } 2324 } 2325 } 2326 2327 private BasePermission findPermissionTreeLP(String permName) { 2328 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 2329 if (permName.startsWith(bp.name) && 2330 permName.length() > bp.name.length() && 2331 permName.charAt(bp.name.length()) == '.') { 2332 return bp; 2333 } 2334 } 2335 return null; 2336 } 2337 2338 private BasePermission checkPermissionTreeLP(String permName) { 2339 if (permName != null) { 2340 BasePermission bp = findPermissionTreeLP(permName); 2341 if (bp != null) { 2342 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 2343 return bp; 2344 } 2345 throw new SecurityException("Calling uid " 2346 + Binder.getCallingUid() 2347 + " is not allowed to add to permission tree " 2348 + bp.name + " owned by uid " + bp.uid); 2349 } 2350 } 2351 throw new SecurityException("No permission tree found for " + permName); 2352 } 2353 2354 static boolean compareStrings(CharSequence s1, CharSequence s2) { 2355 if (s1 == null) { 2356 return s2 == null; 2357 } 2358 if (s2 == null) { 2359 return false; 2360 } 2361 if (s1.getClass() != s2.getClass()) { 2362 return false; 2363 } 2364 return s1.equals(s2); 2365 } 2366 2367 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 2368 if (pi1.icon != pi2.icon) return false; 2369 if (pi1.logo != pi2.logo) return false; 2370 if (pi1.protectionLevel != pi2.protectionLevel) return false; 2371 if (!compareStrings(pi1.name, pi2.name)) return false; 2372 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 2373 // We'll take care of setting this one. 2374 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 2375 // These are not currently stored in settings. 2376 //if (!compareStrings(pi1.group, pi2.group)) return false; 2377 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 2378 //if (pi1.labelRes != pi2.labelRes) return false; 2379 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 2380 return true; 2381 } 2382 2383 int permissionInfoFootprint(PermissionInfo info) { 2384 int size = info.name.length(); 2385 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 2386 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 2387 return size; 2388 } 2389 2390 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 2391 int size = 0; 2392 for (BasePermission perm : mSettings.mPermissions.values()) { 2393 if (perm.uid == tree.uid) { 2394 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 2395 } 2396 } 2397 return size; 2398 } 2399 2400 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 2401 // We calculate the max size of permissions defined by this uid and throw 2402 // if that plus the size of 'info' would exceed our stated maximum. 2403 if (tree.uid != Process.SYSTEM_UID) { 2404 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 2405 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 2406 throw new SecurityException("Permission tree size cap exceeded"); 2407 } 2408 } 2409 } 2410 2411 boolean addPermissionLocked(PermissionInfo info, boolean async) { 2412 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 2413 throw new SecurityException("Label must be specified in permission"); 2414 } 2415 BasePermission tree = checkPermissionTreeLP(info.name); 2416 BasePermission bp = mSettings.mPermissions.get(info.name); 2417 boolean added = bp == null; 2418 boolean changed = true; 2419 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 2420 if (added) { 2421 enforcePermissionCapLocked(info, tree); 2422 bp = new BasePermission(info.name, tree.sourcePackage, 2423 BasePermission.TYPE_DYNAMIC); 2424 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 2425 throw new SecurityException( 2426 "Not allowed to modify non-dynamic permission " 2427 + info.name); 2428 } else { 2429 if (bp.protectionLevel == fixedLevel 2430 && bp.perm.owner.equals(tree.perm.owner) 2431 && bp.uid == tree.uid 2432 && comparePermissionInfos(bp.perm.info, info)) { 2433 changed = false; 2434 } 2435 } 2436 bp.protectionLevel = fixedLevel; 2437 info = new PermissionInfo(info); 2438 info.protectionLevel = fixedLevel; 2439 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 2440 bp.perm.info.packageName = tree.perm.info.packageName; 2441 bp.uid = tree.uid; 2442 if (added) { 2443 mSettings.mPermissions.put(info.name, bp); 2444 } 2445 if (changed) { 2446 if (!async) { 2447 mSettings.writeLPr(); 2448 } else { 2449 scheduleWriteSettingsLocked(); 2450 } 2451 } 2452 return added; 2453 } 2454 2455 public boolean addPermission(PermissionInfo info) { 2456 synchronized (mPackages) { 2457 return addPermissionLocked(info, false); 2458 } 2459 } 2460 2461 public boolean addPermissionAsync(PermissionInfo info) { 2462 synchronized (mPackages) { 2463 return addPermissionLocked(info, true); 2464 } 2465 } 2466 2467 public void removePermission(String name) { 2468 synchronized (mPackages) { 2469 checkPermissionTreeLP(name); 2470 BasePermission bp = mSettings.mPermissions.get(name); 2471 if (bp != null) { 2472 if (bp.type != BasePermission.TYPE_DYNAMIC) { 2473 throw new SecurityException( 2474 "Not allowed to modify non-dynamic permission " 2475 + name); 2476 } 2477 mSettings.mPermissions.remove(name); 2478 mSettings.writeLPr(); 2479 } 2480 } 2481 } 2482 2483 private static void checkGrantRevokePermissions(PackageParser.Package pkg, BasePermission bp) { 2484 int index = pkg.requestedPermissions.indexOf(bp.name); 2485 if (index == -1) { 2486 throw new SecurityException("Package " + pkg.packageName 2487 + " has not requested permission " + bp.name); 2488 } 2489 boolean isNormal = 2490 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) 2491 == PermissionInfo.PROTECTION_NORMAL); 2492 boolean isDangerous = 2493 ((bp.protectionLevel&PermissionInfo.PROTECTION_MASK_BASE) 2494 == PermissionInfo.PROTECTION_DANGEROUS); 2495 boolean isDevelopment = 2496 ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0); 2497 2498 if (!isNormal && !isDangerous && !isDevelopment) { 2499 throw new SecurityException("Permission " + bp.name 2500 + " is not a changeable permission type"); 2501 } 2502 2503 if (isNormal || isDangerous) { 2504 if (pkg.requestedPermissionsRequired.get(index)) { 2505 throw new SecurityException("Can't change " + bp.name 2506 + ". It is required by the application"); 2507 } 2508 } 2509 } 2510 2511 public void grantPermission(String packageName, String permissionName) { 2512 mContext.enforceCallingOrSelfPermission( 2513 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); 2514 synchronized (mPackages) { 2515 final PackageParser.Package pkg = mPackages.get(packageName); 2516 if (pkg == null) { 2517 throw new IllegalArgumentException("Unknown package: " + packageName); 2518 } 2519 final BasePermission bp = mSettings.mPermissions.get(permissionName); 2520 if (bp == null) { 2521 throw new IllegalArgumentException("Unknown permission: " + permissionName); 2522 } 2523 2524 checkGrantRevokePermissions(pkg, bp); 2525 2526 final PackageSetting ps = (PackageSetting) pkg.mExtras; 2527 if (ps == null) { 2528 return; 2529 } 2530 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps; 2531 if (gp.grantedPermissions.add(permissionName)) { 2532 if (ps.haveGids) { 2533 gp.gids = appendInts(gp.gids, bp.gids); 2534 } 2535 mSettings.writeLPr(); 2536 } 2537 } 2538 } 2539 2540 public void revokePermission(String packageName, String permissionName) { 2541 int changedAppId = -1; 2542 2543 synchronized (mPackages) { 2544 final PackageParser.Package pkg = mPackages.get(packageName); 2545 if (pkg == null) { 2546 throw new IllegalArgumentException("Unknown package: " + packageName); 2547 } 2548 if (pkg.applicationInfo.uid != Binder.getCallingUid()) { 2549 mContext.enforceCallingOrSelfPermission( 2550 android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null); 2551 } 2552 final BasePermission bp = mSettings.mPermissions.get(permissionName); 2553 if (bp == null) { 2554 throw new IllegalArgumentException("Unknown permission: " + permissionName); 2555 } 2556 2557 checkGrantRevokePermissions(pkg, bp); 2558 2559 final PackageSetting ps = (PackageSetting) pkg.mExtras; 2560 if (ps == null) { 2561 return; 2562 } 2563 final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps; 2564 if (gp.grantedPermissions.remove(permissionName)) { 2565 gp.grantedPermissions.remove(permissionName); 2566 if (ps.haveGids) { 2567 gp.gids = removeInts(gp.gids, bp.gids); 2568 } 2569 mSettings.writeLPr(); 2570 changedAppId = ps.appId; 2571 } 2572 } 2573 2574 if (changedAppId >= 0) { 2575 // We changed the perm on someone, kill its processes. 2576 IActivityManager am = ActivityManagerNative.getDefault(); 2577 if (am != null) { 2578 final int callingUserId = UserHandle.getCallingUserId(); 2579 final long ident = Binder.clearCallingIdentity(); 2580 try { 2581 //XXX we should only revoke for the calling user's app permissions, 2582 // but for now we impact all users. 2583 //am.killUid(UserHandle.getUid(callingUserId, changedAppId), 2584 // "revoke " + permissionName); 2585 int[] users = sUserManager.getUserIds(); 2586 for (int user : users) { 2587 am.killUid(UserHandle.getUid(user, changedAppId), 2588 "revoke " + permissionName); 2589 } 2590 } catch (RemoteException e) { 2591 } finally { 2592 Binder.restoreCallingIdentity(ident); 2593 } 2594 } 2595 } 2596 } 2597 2598 public boolean isProtectedBroadcast(String actionName) { 2599 synchronized (mPackages) { 2600 return mProtectedBroadcasts.contains(actionName); 2601 } 2602 } 2603 2604 public int checkSignatures(String pkg1, String pkg2) { 2605 synchronized (mPackages) { 2606 final PackageParser.Package p1 = mPackages.get(pkg1); 2607 final PackageParser.Package p2 = mPackages.get(pkg2); 2608 if (p1 == null || p1.mExtras == null 2609 || p2 == null || p2.mExtras == null) { 2610 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2611 } 2612 return compareSignatures(p1.mSignatures, p2.mSignatures); 2613 } 2614 } 2615 2616 public int checkUidSignatures(int uid1, int uid2) { 2617 // Map to base uids. 2618 uid1 = UserHandle.getAppId(uid1); 2619 uid2 = UserHandle.getAppId(uid2); 2620 // reader 2621 synchronized (mPackages) { 2622 Signature[] s1; 2623 Signature[] s2; 2624 Object obj = mSettings.getUserIdLPr(uid1); 2625 if (obj != null) { 2626 if (obj instanceof SharedUserSetting) { 2627 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 2628 } else if (obj instanceof PackageSetting) { 2629 s1 = ((PackageSetting)obj).signatures.mSignatures; 2630 } else { 2631 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2632 } 2633 } else { 2634 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2635 } 2636 obj = mSettings.getUserIdLPr(uid2); 2637 if (obj != null) { 2638 if (obj instanceof SharedUserSetting) { 2639 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 2640 } else if (obj instanceof PackageSetting) { 2641 s2 = ((PackageSetting)obj).signatures.mSignatures; 2642 } else { 2643 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2644 } 2645 } else { 2646 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 2647 } 2648 return compareSignatures(s1, s2); 2649 } 2650 } 2651 2652 /** 2653 * Compares two sets of signatures. Returns: 2654 * <br /> 2655 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 2656 * <br /> 2657 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 2658 * <br /> 2659 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 2660 * <br /> 2661 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 2662 * <br /> 2663 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 2664 */ 2665 static int compareSignatures(Signature[] s1, Signature[] s2) { 2666 if (s1 == null) { 2667 return s2 == null 2668 ? PackageManager.SIGNATURE_NEITHER_SIGNED 2669 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 2670 } 2671 2672 if (s2 == null) { 2673 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 2674 } 2675 2676 if (s1.length != s2.length) { 2677 return PackageManager.SIGNATURE_NO_MATCH; 2678 } 2679 2680 // Since both signature sets are of size 1, we can compare without HashSets. 2681 if (s1.length == 1) { 2682 return s1[0].equals(s2[0]) ? 2683 PackageManager.SIGNATURE_MATCH : 2684 PackageManager.SIGNATURE_NO_MATCH; 2685 } 2686 2687 HashSet<Signature> set1 = new HashSet<Signature>(); 2688 for (Signature sig : s1) { 2689 set1.add(sig); 2690 } 2691 HashSet<Signature> set2 = new HashSet<Signature>(); 2692 for (Signature sig : s2) { 2693 set2.add(sig); 2694 } 2695 // Make sure s2 contains all signatures in s1. 2696 if (set1.equals(set2)) { 2697 return PackageManager.SIGNATURE_MATCH; 2698 } 2699 return PackageManager.SIGNATURE_NO_MATCH; 2700 } 2701 2702 public String[] getPackagesForUid(int uid) { 2703 uid = UserHandle.getAppId(uid); 2704 // reader 2705 synchronized (mPackages) { 2706 Object obj = mSettings.getUserIdLPr(uid); 2707 if (obj instanceof SharedUserSetting) { 2708 final SharedUserSetting sus = (SharedUserSetting) obj; 2709 final int N = sus.packages.size(); 2710 final String[] res = new String[N]; 2711 final Iterator<PackageSetting> it = sus.packages.iterator(); 2712 int i = 0; 2713 while (it.hasNext()) { 2714 res[i++] = it.next().name; 2715 } 2716 return res; 2717 } else if (obj instanceof PackageSetting) { 2718 final PackageSetting ps = (PackageSetting) obj; 2719 return new String[] { ps.name }; 2720 } 2721 } 2722 return null; 2723 } 2724 2725 public String getNameForUid(int uid) { 2726 // reader 2727 synchronized (mPackages) { 2728 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2729 if (obj instanceof SharedUserSetting) { 2730 final SharedUserSetting sus = (SharedUserSetting) obj; 2731 return sus.name + ":" + sus.userId; 2732 } else if (obj instanceof PackageSetting) { 2733 final PackageSetting ps = (PackageSetting) obj; 2734 return ps.name; 2735 } 2736 } 2737 return null; 2738 } 2739 2740 public int getUidForSharedUser(String sharedUserName) { 2741 if(sharedUserName == null) { 2742 return -1; 2743 } 2744 // reader 2745 synchronized (mPackages) { 2746 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, false); 2747 if (suid == null) { 2748 return -1; 2749 } 2750 return suid.userId; 2751 } 2752 } 2753 2754 public int getFlagsForUid(int uid) { 2755 synchronized (mPackages) { 2756 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 2757 if (obj instanceof SharedUserSetting) { 2758 final SharedUserSetting sus = (SharedUserSetting) obj; 2759 return sus.pkgFlags; 2760 } else if (obj instanceof PackageSetting) { 2761 final PackageSetting ps = (PackageSetting) obj; 2762 return ps.pkgFlags; 2763 } 2764 } 2765 return 0; 2766 } 2767 2768 @Override 2769 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 2770 int flags, int userId) { 2771 if (!sUserManager.exists(userId)) return null; 2772 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent"); 2773 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2774 return chooseBestActivity(intent, resolvedType, flags, query, userId); 2775 } 2776 2777 @Override 2778 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 2779 IntentFilter filter, int match, ComponentName activity) { 2780 final int userId = UserHandle.getCallingUserId(); 2781 if (DEBUG_PREFERRED) { 2782 Log.v(TAG, "setLastChosenActivity intent=" + intent 2783 + " resolvedType=" + resolvedType 2784 + " flags=" + flags 2785 + " filter=" + filter 2786 + " match=" + match 2787 + " activity=" + activity); 2788 filter.dump(new PrintStreamPrinter(System.out), " "); 2789 } 2790 intent.setComponent(null); 2791 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2792 // Find any earlier preferred or last chosen entries and nuke them 2793 findPreferredActivity(intent, resolvedType, 2794 flags, query, 0, false, true, false, userId); 2795 // Add the new activity as the last chosen for this filter 2796 addPreferredActivityInternal(filter, match, null, activity, false, userId); 2797 } 2798 2799 @Override 2800 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 2801 final int userId = UserHandle.getCallingUserId(); 2802 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 2803 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 2804 return findPreferredActivity(intent, resolvedType, flags, query, 0, 2805 false, false, false, userId); 2806 } 2807 2808 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 2809 int flags, List<ResolveInfo> query, int userId) { 2810 if (query != null) { 2811 final int N = query.size(); 2812 if (N == 1) { 2813 return query.get(0); 2814 } else if (N > 1) { 2815 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 2816 // If there is more than one activity with the same priority, 2817 // then let the user decide between them. 2818 ResolveInfo r0 = query.get(0); 2819 ResolveInfo r1 = query.get(1); 2820 if (DEBUG_INTENT_MATCHING || debug) { 2821 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 2822 + r1.activityInfo.name + "=" + r1.priority); 2823 } 2824 // If the first activity has a higher priority, or a different 2825 // default, then it is always desireable to pick it. 2826 if (r0.priority != r1.priority 2827 || r0.preferredOrder != r1.preferredOrder 2828 || r0.isDefault != r1.isDefault) { 2829 return query.get(0); 2830 } 2831 // If we have saved a preference for a preferred activity for 2832 // this Intent, use that. 2833 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 2834 flags, query, r0.priority, true, false, debug, userId); 2835 if (ri != null) { 2836 return ri; 2837 } 2838 if (userId != 0) { 2839 ri = new ResolveInfo(mResolveInfo); 2840 ri.activityInfo = new ActivityInfo(ri.activityInfo); 2841 ri.activityInfo.applicationInfo = new ApplicationInfo( 2842 ri.activityInfo.applicationInfo); 2843 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 2844 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 2845 return ri; 2846 } 2847 return mResolveInfo; 2848 } 2849 } 2850 return null; 2851 } 2852 2853 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 2854 int flags, List<ResolveInfo> query, boolean debug, int userId) { 2855 final int N = query.size(); 2856 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 2857 .get(userId); 2858 // Get the list of persistent preferred activities that handle the intent 2859 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 2860 List<PersistentPreferredActivity> pprefs = ppir != null 2861 ? ppir.queryIntent(intent, resolvedType, 2862 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 2863 : null; 2864 if (pprefs != null && pprefs.size() > 0) { 2865 final int M = pprefs.size(); 2866 for (int i=0; i<M; i++) { 2867 final PersistentPreferredActivity ppa = pprefs.get(i); 2868 if (DEBUG_PREFERRED || debug) { 2869 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 2870 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 2871 + "\n component=" + ppa.mComponent); 2872 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 2873 } 2874 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 2875 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 2876 if (DEBUG_PREFERRED || debug) { 2877 Slog.v(TAG, "Found persistent preferred activity:"); 2878 if (ai != null) { 2879 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 2880 } else { 2881 Slog.v(TAG, " null"); 2882 } 2883 } 2884 if (ai == null) { 2885 // This previously registered persistent preferred activity 2886 // component is no longer known. Ignore it and do NOT remove it. 2887 continue; 2888 } 2889 for (int j=0; j<N; j++) { 2890 final ResolveInfo ri = query.get(j); 2891 if (!ri.activityInfo.applicationInfo.packageName 2892 .equals(ai.applicationInfo.packageName)) { 2893 continue; 2894 } 2895 if (!ri.activityInfo.name.equals(ai.name)) { 2896 continue; 2897 } 2898 // Found a persistent preference that can handle the intent. 2899 if (DEBUG_PREFERRED || debug) { 2900 Slog.v(TAG, "Returning persistent preferred activity: " + 2901 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 2902 } 2903 return ri; 2904 } 2905 } 2906 } 2907 return null; 2908 } 2909 2910 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 2911 List<ResolveInfo> query, int priority, boolean always, 2912 boolean removeMatches, boolean debug, int userId) { 2913 if (!sUserManager.exists(userId)) return null; 2914 // writer 2915 synchronized (mPackages) { 2916 if (intent.getSelector() != null) { 2917 intent = intent.getSelector(); 2918 } 2919 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 2920 2921 // Try to find a matching persistent preferred activity. 2922 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 2923 debug, userId); 2924 2925 // If a persistent preferred activity matched, use it. 2926 if (pri != null) { 2927 return pri; 2928 } 2929 2930 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 2931 // Get the list of preferred activities that handle the intent 2932 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 2933 List<PreferredActivity> prefs = pir != null 2934 ? pir.queryIntent(intent, resolvedType, 2935 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 2936 : null; 2937 if (prefs != null && prefs.size() > 0) { 2938 // First figure out how good the original match set is. 2939 // We will only allow preferred activities that came 2940 // from the same match quality. 2941 int match = 0; 2942 2943 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 2944 2945 final int N = query.size(); 2946 for (int j=0; j<N; j++) { 2947 final ResolveInfo ri = query.get(j); 2948 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 2949 + ": 0x" + Integer.toHexString(match)); 2950 if (ri.match > match) { 2951 match = ri.match; 2952 } 2953 } 2954 2955 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 2956 + Integer.toHexString(match)); 2957 2958 match &= IntentFilter.MATCH_CATEGORY_MASK; 2959 final int M = prefs.size(); 2960 for (int i=0; i<M; i++) { 2961 final PreferredActivity pa = prefs.get(i); 2962 if (DEBUG_PREFERRED || debug) { 2963 Slog.v(TAG, "Checking PreferredActivity ds=" 2964 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 2965 + "\n component=" + pa.mPref.mComponent); 2966 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 2967 } 2968 if (pa.mPref.mMatch != match) { 2969 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 2970 + Integer.toHexString(pa.mPref.mMatch)); 2971 continue; 2972 } 2973 // If it's not an "always" type preferred activity and that's what we're 2974 // looking for, skip it. 2975 if (always && !pa.mPref.mAlways) { 2976 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 2977 continue; 2978 } 2979 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 2980 flags | PackageManager.GET_DISABLED_COMPONENTS, userId); 2981 if (DEBUG_PREFERRED || debug) { 2982 Slog.v(TAG, "Found preferred activity:"); 2983 if (ai != null) { 2984 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 2985 } else { 2986 Slog.v(TAG, " null"); 2987 } 2988 } 2989 if (ai == null) { 2990 // This previously registered preferred activity 2991 // component is no longer known. Most likely an update 2992 // to the app was installed and in the new version this 2993 // component no longer exists. Clean it up by removing 2994 // it from the preferred activities list, and skip it. 2995 Slog.w(TAG, "Removing dangling preferred activity: " 2996 + pa.mPref.mComponent); 2997 pir.removeFilter(pa); 2998 continue; 2999 } 3000 for (int j=0; j<N; j++) { 3001 final ResolveInfo ri = query.get(j); 3002 if (!ri.activityInfo.applicationInfo.packageName 3003 .equals(ai.applicationInfo.packageName)) { 3004 continue; 3005 } 3006 if (!ri.activityInfo.name.equals(ai.name)) { 3007 continue; 3008 } 3009 3010 if (removeMatches) { 3011 pir.removeFilter(pa); 3012 if (DEBUG_PREFERRED) { 3013 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 3014 } 3015 break; 3016 } 3017 3018 // Okay we found a previously set preferred or last chosen app. 3019 // If the result set is different from when this 3020 // was created, we need to clear it and re-ask the 3021 // user their preference, if we're looking for an "always" type entry. 3022 if (always && !pa.mPref.sameSet(query, priority)) { 3023 Slog.i(TAG, "Result set changed, dropping preferred activity for " 3024 + intent + " type " + resolvedType); 3025 if (DEBUG_PREFERRED) { 3026 Slog.v(TAG, "Removing preferred activity since set changed " 3027 + pa.mPref.mComponent); 3028 } 3029 pir.removeFilter(pa); 3030 // Re-add the filter as a "last chosen" entry (!always) 3031 PreferredActivity lastChosen = new PreferredActivity( 3032 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 3033 pir.addFilter(lastChosen); 3034 mSettings.writePackageRestrictionsLPr(userId); 3035 return null; 3036 } 3037 3038 // Yay! Either the set matched or we're looking for the last chosen 3039 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 3040 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 3041 mSettings.writePackageRestrictionsLPr(userId); 3042 return ri; 3043 } 3044 } 3045 } 3046 mSettings.writePackageRestrictionsLPr(userId); 3047 } 3048 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 3049 return null; 3050 } 3051 3052 @Override 3053 public List<ResolveInfo> queryIntentActivities(Intent intent, 3054 String resolvedType, int flags, int userId) { 3055 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3056 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities"); 3057 ComponentName comp = intent.getComponent(); 3058 if (comp == null) { 3059 if (intent.getSelector() != null) { 3060 intent = intent.getSelector(); 3061 comp = intent.getComponent(); 3062 } 3063 } 3064 3065 if (comp != null) { 3066 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3067 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 3068 if (ai != null) { 3069 final ResolveInfo ri = new ResolveInfo(); 3070 ri.activityInfo = ai; 3071 list.add(ri); 3072 } 3073 return list; 3074 } 3075 3076 // reader 3077 synchronized (mPackages) { 3078 final String pkgName = intent.getPackage(); 3079 if (pkgName == null) { 3080 return mActivities.queryIntent(intent, resolvedType, flags, userId); 3081 } 3082 final PackageParser.Package pkg = mPackages.get(pkgName); 3083 if (pkg != null) { 3084 return mActivities.queryIntentForPackage(intent, resolvedType, flags, 3085 pkg.activities, userId); 3086 } 3087 return new ArrayList<ResolveInfo>(); 3088 } 3089 } 3090 3091 @Override 3092 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 3093 Intent[] specifics, String[] specificTypes, Intent intent, 3094 String resolvedType, int flags, int userId) { 3095 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3096 enforceCrossUserPermission(Binder.getCallingUid(), userId, false, 3097 "query intent activity options"); 3098 final String resultsAction = intent.getAction(); 3099 3100 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 3101 | PackageManager.GET_RESOLVED_FILTER, userId); 3102 3103 if (DEBUG_INTENT_MATCHING) { 3104 Log.v(TAG, "Query " + intent + ": " + results); 3105 } 3106 3107 int specificsPos = 0; 3108 int N; 3109 3110 // todo: note that the algorithm used here is O(N^2). This 3111 // isn't a problem in our current environment, but if we start running 3112 // into situations where we have more than 5 or 10 matches then this 3113 // should probably be changed to something smarter... 3114 3115 // First we go through and resolve each of the specific items 3116 // that were supplied, taking care of removing any corresponding 3117 // duplicate items in the generic resolve list. 3118 if (specifics != null) { 3119 for (int i=0; i<specifics.length; i++) { 3120 final Intent sintent = specifics[i]; 3121 if (sintent == null) { 3122 continue; 3123 } 3124 3125 if (DEBUG_INTENT_MATCHING) { 3126 Log.v(TAG, "Specific #" + i + ": " + sintent); 3127 } 3128 3129 String action = sintent.getAction(); 3130 if (resultsAction != null && resultsAction.equals(action)) { 3131 // If this action was explicitly requested, then don't 3132 // remove things that have it. 3133 action = null; 3134 } 3135 3136 ResolveInfo ri = null; 3137 ActivityInfo ai = null; 3138 3139 ComponentName comp = sintent.getComponent(); 3140 if (comp == null) { 3141 ri = resolveIntent( 3142 sintent, 3143 specificTypes != null ? specificTypes[i] : null, 3144 flags, userId); 3145 if (ri == null) { 3146 continue; 3147 } 3148 if (ri == mResolveInfo) { 3149 // ACK! Must do something better with this. 3150 } 3151 ai = ri.activityInfo; 3152 comp = new ComponentName(ai.applicationInfo.packageName, 3153 ai.name); 3154 } else { 3155 ai = getActivityInfo(comp, flags, userId); 3156 if (ai == null) { 3157 continue; 3158 } 3159 } 3160 3161 // Look for any generic query activities that are duplicates 3162 // of this specific one, and remove them from the results. 3163 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 3164 N = results.size(); 3165 int j; 3166 for (j=specificsPos; j<N; j++) { 3167 ResolveInfo sri = results.get(j); 3168 if ((sri.activityInfo.name.equals(comp.getClassName()) 3169 && sri.activityInfo.applicationInfo.packageName.equals( 3170 comp.getPackageName())) 3171 || (action != null && sri.filter.matchAction(action))) { 3172 results.remove(j); 3173 if (DEBUG_INTENT_MATCHING) Log.v( 3174 TAG, "Removing duplicate item from " + j 3175 + " due to specific " + specificsPos); 3176 if (ri == null) { 3177 ri = sri; 3178 } 3179 j--; 3180 N--; 3181 } 3182 } 3183 3184 // Add this specific item to its proper place. 3185 if (ri == null) { 3186 ri = new ResolveInfo(); 3187 ri.activityInfo = ai; 3188 } 3189 results.add(specificsPos, ri); 3190 ri.specificIndex = i; 3191 specificsPos++; 3192 } 3193 } 3194 3195 // Now we go through the remaining generic results and remove any 3196 // duplicate actions that are found here. 3197 N = results.size(); 3198 for (int i=specificsPos; i<N-1; i++) { 3199 final ResolveInfo rii = results.get(i); 3200 if (rii.filter == null) { 3201 continue; 3202 } 3203 3204 // Iterate over all of the actions of this result's intent 3205 // filter... typically this should be just one. 3206 final Iterator<String> it = rii.filter.actionsIterator(); 3207 if (it == null) { 3208 continue; 3209 } 3210 while (it.hasNext()) { 3211 final String action = it.next(); 3212 if (resultsAction != null && resultsAction.equals(action)) { 3213 // If this action was explicitly requested, then don't 3214 // remove things that have it. 3215 continue; 3216 } 3217 for (int j=i+1; j<N; j++) { 3218 final ResolveInfo rij = results.get(j); 3219 if (rij.filter != null && rij.filter.hasAction(action)) { 3220 results.remove(j); 3221 if (DEBUG_INTENT_MATCHING) Log.v( 3222 TAG, "Removing duplicate item from " + j 3223 + " due to action " + action + " at " + i); 3224 j--; 3225 N--; 3226 } 3227 } 3228 } 3229 3230 // If the caller didn't request filter information, drop it now 3231 // so we don't have to marshall/unmarshall it. 3232 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 3233 rii.filter = null; 3234 } 3235 } 3236 3237 // Filter out the caller activity if so requested. 3238 if (caller != null) { 3239 N = results.size(); 3240 for (int i=0; i<N; i++) { 3241 ActivityInfo ainfo = results.get(i).activityInfo; 3242 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 3243 && caller.getClassName().equals(ainfo.name)) { 3244 results.remove(i); 3245 break; 3246 } 3247 } 3248 } 3249 3250 // If the caller didn't request filter information, 3251 // drop them now so we don't have to 3252 // marshall/unmarshall it. 3253 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 3254 N = results.size(); 3255 for (int i=0; i<N; i++) { 3256 results.get(i).filter = null; 3257 } 3258 } 3259 3260 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 3261 return results; 3262 } 3263 3264 @Override 3265 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 3266 int userId) { 3267 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3268 ComponentName comp = intent.getComponent(); 3269 if (comp == null) { 3270 if (intent.getSelector() != null) { 3271 intent = intent.getSelector(); 3272 comp = intent.getComponent(); 3273 } 3274 } 3275 if (comp != null) { 3276 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3277 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 3278 if (ai != null) { 3279 ResolveInfo ri = new ResolveInfo(); 3280 ri.activityInfo = ai; 3281 list.add(ri); 3282 } 3283 return list; 3284 } 3285 3286 // reader 3287 synchronized (mPackages) { 3288 String pkgName = intent.getPackage(); 3289 if (pkgName == null) { 3290 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 3291 } 3292 final PackageParser.Package pkg = mPackages.get(pkgName); 3293 if (pkg != null) { 3294 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 3295 userId); 3296 } 3297 return null; 3298 } 3299 } 3300 3301 @Override 3302 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 3303 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 3304 if (!sUserManager.exists(userId)) return null; 3305 if (query != null) { 3306 if (query.size() >= 1) { 3307 // If there is more than one service with the same priority, 3308 // just arbitrarily pick the first one. 3309 return query.get(0); 3310 } 3311 } 3312 return null; 3313 } 3314 3315 @Override 3316 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 3317 int userId) { 3318 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3319 ComponentName comp = intent.getComponent(); 3320 if (comp == null) { 3321 if (intent.getSelector() != null) { 3322 intent = intent.getSelector(); 3323 comp = intent.getComponent(); 3324 } 3325 } 3326 if (comp != null) { 3327 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3328 final ServiceInfo si = getServiceInfo(comp, flags, userId); 3329 if (si != null) { 3330 final ResolveInfo ri = new ResolveInfo(); 3331 ri.serviceInfo = si; 3332 list.add(ri); 3333 } 3334 return list; 3335 } 3336 3337 // reader 3338 synchronized (mPackages) { 3339 String pkgName = intent.getPackage(); 3340 if (pkgName == null) { 3341 return mServices.queryIntent(intent, resolvedType, flags, userId); 3342 } 3343 final PackageParser.Package pkg = mPackages.get(pkgName); 3344 if (pkg != null) { 3345 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 3346 userId); 3347 } 3348 return null; 3349 } 3350 } 3351 3352 @Override 3353 public List<ResolveInfo> queryIntentContentProviders( 3354 Intent intent, String resolvedType, int flags, int userId) { 3355 if (!sUserManager.exists(userId)) return Collections.emptyList(); 3356 ComponentName comp = intent.getComponent(); 3357 if (comp == null) { 3358 if (intent.getSelector() != null) { 3359 intent = intent.getSelector(); 3360 comp = intent.getComponent(); 3361 } 3362 } 3363 if (comp != null) { 3364 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 3365 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 3366 if (pi != null) { 3367 final ResolveInfo ri = new ResolveInfo(); 3368 ri.providerInfo = pi; 3369 list.add(ri); 3370 } 3371 return list; 3372 } 3373 3374 // reader 3375 synchronized (mPackages) { 3376 String pkgName = intent.getPackage(); 3377 if (pkgName == null) { 3378 return mProviders.queryIntent(intent, resolvedType, flags, userId); 3379 } 3380 final PackageParser.Package pkg = mPackages.get(pkgName); 3381 if (pkg != null) { 3382 return mProviders.queryIntentForPackage( 3383 intent, resolvedType, flags, pkg.providers, userId); 3384 } 3385 return null; 3386 } 3387 } 3388 3389 @Override 3390 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 3391 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3392 3393 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages"); 3394 3395 // writer 3396 synchronized (mPackages) { 3397 ArrayList<PackageInfo> list; 3398 if (listUninstalled) { 3399 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 3400 for (PackageSetting ps : mSettings.mPackages.values()) { 3401 PackageInfo pi; 3402 if (ps.pkg != null) { 3403 pi = generatePackageInfo(ps.pkg, flags, userId); 3404 } else { 3405 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 3406 } 3407 if (pi != null) { 3408 list.add(pi); 3409 } 3410 } 3411 } else { 3412 list = new ArrayList<PackageInfo>(mPackages.size()); 3413 for (PackageParser.Package p : mPackages.values()) { 3414 PackageInfo pi = generatePackageInfo(p, flags, userId); 3415 if (pi != null) { 3416 list.add(pi); 3417 } 3418 } 3419 } 3420 3421 return new ParceledListSlice<PackageInfo>(list); 3422 } 3423 } 3424 3425 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 3426 String[] permissions, boolean[] tmp, int flags, int userId) { 3427 int numMatch = 0; 3428 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 3429 for (int i=0; i<permissions.length; i++) { 3430 if (gp.grantedPermissions.contains(permissions[i])) { 3431 tmp[i] = true; 3432 numMatch++; 3433 } else { 3434 tmp[i] = false; 3435 } 3436 } 3437 if (numMatch == 0) { 3438 return; 3439 } 3440 PackageInfo pi; 3441 if (ps.pkg != null) { 3442 pi = generatePackageInfo(ps.pkg, flags, userId); 3443 } else { 3444 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 3445 } 3446 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 3447 if (numMatch == permissions.length) { 3448 pi.requestedPermissions = permissions; 3449 } else { 3450 pi.requestedPermissions = new String[numMatch]; 3451 numMatch = 0; 3452 for (int i=0; i<permissions.length; i++) { 3453 if (tmp[i]) { 3454 pi.requestedPermissions[numMatch] = permissions[i]; 3455 numMatch++; 3456 } 3457 } 3458 } 3459 } 3460 list.add(pi); 3461 } 3462 3463 @Override 3464 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 3465 String[] permissions, int flags, int userId) { 3466 if (!sUserManager.exists(userId)) return null; 3467 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3468 3469 // writer 3470 synchronized (mPackages) { 3471 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 3472 boolean[] tmpBools = new boolean[permissions.length]; 3473 if (listUninstalled) { 3474 for (PackageSetting ps : mSettings.mPackages.values()) { 3475 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 3476 } 3477 } else { 3478 for (PackageParser.Package pkg : mPackages.values()) { 3479 PackageSetting ps = (PackageSetting)pkg.mExtras; 3480 if (ps != null) { 3481 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 3482 userId); 3483 } 3484 } 3485 } 3486 3487 return new ParceledListSlice<PackageInfo>(list); 3488 } 3489 } 3490 3491 @Override 3492 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 3493 if (!sUserManager.exists(userId)) return null; 3494 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 3495 3496 // writer 3497 synchronized (mPackages) { 3498 ArrayList<ApplicationInfo> list; 3499 if (listUninstalled) { 3500 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 3501 for (PackageSetting ps : mSettings.mPackages.values()) { 3502 ApplicationInfo ai; 3503 if (ps.pkg != null) { 3504 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 3505 ps.readUserState(userId), userId); 3506 } else { 3507 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 3508 } 3509 if (ai != null) { 3510 list.add(ai); 3511 } 3512 } 3513 } else { 3514 list = new ArrayList<ApplicationInfo>(mPackages.size()); 3515 for (PackageParser.Package p : mPackages.values()) { 3516 if (p.mExtras != null) { 3517 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 3518 ((PackageSetting)p.mExtras).readUserState(userId), userId); 3519 if (ai != null) { 3520 list.add(ai); 3521 } 3522 } 3523 } 3524 } 3525 3526 return new ParceledListSlice<ApplicationInfo>(list); 3527 } 3528 } 3529 3530 public List<ApplicationInfo> getPersistentApplications(int flags) { 3531 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 3532 3533 // reader 3534 synchronized (mPackages) { 3535 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 3536 final int userId = UserHandle.getCallingUserId(); 3537 while (i.hasNext()) { 3538 final PackageParser.Package p = i.next(); 3539 if (p.applicationInfo != null 3540 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 3541 && (!mSafeMode || isSystemApp(p))) { 3542 PackageSetting ps = mSettings.mPackages.get(p.packageName); 3543 if (ps != null) { 3544 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 3545 ps.readUserState(userId), userId); 3546 if (ai != null) { 3547 finalList.add(ai); 3548 } 3549 } 3550 } 3551 } 3552 } 3553 3554 return finalList; 3555 } 3556 3557 @Override 3558 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 3559 if (!sUserManager.exists(userId)) return null; 3560 // reader 3561 synchronized (mPackages) { 3562 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 3563 PackageSetting ps = provider != null 3564 ? mSettings.mPackages.get(provider.owner.packageName) 3565 : null; 3566 return ps != null 3567 && mSettings.isEnabledLPr(provider.info, flags, userId) 3568 && (!mSafeMode || (provider.info.applicationInfo.flags 3569 &ApplicationInfo.FLAG_SYSTEM) != 0) 3570 ? PackageParser.generateProviderInfo(provider, flags, 3571 ps.readUserState(userId), userId) 3572 : null; 3573 } 3574 } 3575 3576 /** 3577 * @deprecated 3578 */ 3579 @Deprecated 3580 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 3581 // reader 3582 synchronized (mPackages) { 3583 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 3584 .entrySet().iterator(); 3585 final int userId = UserHandle.getCallingUserId(); 3586 while (i.hasNext()) { 3587 Map.Entry<String, PackageParser.Provider> entry = i.next(); 3588 PackageParser.Provider p = entry.getValue(); 3589 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 3590 3591 if (ps != null && p.syncable 3592 && (!mSafeMode || (p.info.applicationInfo.flags 3593 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 3594 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 3595 ps.readUserState(userId), userId); 3596 if (info != null) { 3597 outNames.add(entry.getKey()); 3598 outInfo.add(info); 3599 } 3600 } 3601 } 3602 } 3603 } 3604 3605 public List<ProviderInfo> queryContentProviders(String processName, 3606 int uid, int flags) { 3607 ArrayList<ProviderInfo> finalList = null; 3608 // reader 3609 synchronized (mPackages) { 3610 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 3611 final int userId = processName != null ? 3612 UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); 3613 while (i.hasNext()) { 3614 final PackageParser.Provider p = i.next(); 3615 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 3616 if (ps != null && p.info.authority != null 3617 && (processName == null 3618 || (p.info.processName.equals(processName) 3619 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 3620 && mSettings.isEnabledLPr(p.info, flags, userId) 3621 && (!mSafeMode 3622 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 3623 if (finalList == null) { 3624 finalList = new ArrayList<ProviderInfo>(3); 3625 } 3626 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 3627 ps.readUserState(userId), userId); 3628 if (info != null) { 3629 finalList.add(info); 3630 } 3631 } 3632 } 3633 } 3634 3635 if (finalList != null) { 3636 Collections.sort(finalList, mProviderInitOrderSorter); 3637 } 3638 3639 return finalList; 3640 } 3641 3642 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 3643 int flags) { 3644 // reader 3645 synchronized (mPackages) { 3646 final PackageParser.Instrumentation i = mInstrumentation.get(name); 3647 return PackageParser.generateInstrumentationInfo(i, flags); 3648 } 3649 } 3650 3651 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 3652 int flags) { 3653 ArrayList<InstrumentationInfo> finalList = 3654 new ArrayList<InstrumentationInfo>(); 3655 3656 // reader 3657 synchronized (mPackages) { 3658 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 3659 while (i.hasNext()) { 3660 final PackageParser.Instrumentation p = i.next(); 3661 if (targetPackage == null 3662 || targetPackage.equals(p.info.targetPackage)) { 3663 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 3664 flags); 3665 if (ii != null) { 3666 finalList.add(ii); 3667 } 3668 } 3669 } 3670 } 3671 3672 return finalList; 3673 } 3674 3675 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 3676 HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 3677 if (overlays == null) { 3678 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 3679 return; 3680 } 3681 for (PackageParser.Package opkg : overlays.values()) { 3682 // Not much to do if idmap fails: we already logged the error 3683 // and we certainly don't want to abort installation of pkg simply 3684 // because an overlay didn't fit properly. For these reasons, 3685 // ignore the return value of createIdmapForPackagePairLI. 3686 createIdmapForPackagePairLI(pkg, opkg); 3687 } 3688 } 3689 3690 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 3691 PackageParser.Package opkg) { 3692 if (!opkg.mTrustedOverlay) { 3693 Slog.w(TAG, "Skipping target and overlay pair " + pkg.mScanPath + " and " + 3694 opkg.mScanPath + ": overlay not trusted"); 3695 return false; 3696 } 3697 HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 3698 if (overlaySet == null) { 3699 Slog.e(TAG, "was about to create idmap for " + pkg.mScanPath + " and " + 3700 opkg.mScanPath + " but target package has no known overlays"); 3701 return false; 3702 } 3703 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 3704 if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, sharedGid) != 0) { 3705 Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath); 3706 return false; 3707 } 3708 PackageParser.Package[] overlayArray = 3709 overlaySet.values().toArray(new PackageParser.Package[0]); 3710 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 3711 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 3712 return p1.mOverlayPriority - p2.mOverlayPriority; 3713 } 3714 }; 3715 Arrays.sort(overlayArray, cmp); 3716 3717 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 3718 int i = 0; 3719 for (PackageParser.Package p : overlayArray) { 3720 pkg.applicationInfo.resourceDirs[i++] = p.applicationInfo.sourceDir; 3721 } 3722 return true; 3723 } 3724 3725 private void scanDirLI(File dir, int flags, int scanMode, long currentTime) { 3726 String[] files = dir.list(); 3727 if (files == null) { 3728 Log.d(TAG, "No files in app dir " + dir); 3729 return; 3730 } 3731 3732 if (DEBUG_PACKAGE_SCANNING) { 3733 Log.d(TAG, "Scanning app dir " + dir + " scanMode=" + scanMode 3734 + " flags=0x" + Integer.toHexString(flags)); 3735 } 3736 3737 int i; 3738 for (i=0; i<files.length; i++) { 3739 File file = new File(dir, files[i]); 3740 if (!isPackageFilename(files[i])) { 3741 // Ignore entries which are not apk's 3742 continue; 3743 } 3744 PackageParser.Package pkg = scanPackageLI(file, 3745 flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null); 3746 // Don't mess around with apps in system partition. 3747 if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 && 3748 mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) { 3749 // Delete the apk 3750 Slog.w(TAG, "Cleaning up failed install of " + file); 3751 file.delete(); 3752 } 3753 } 3754 } 3755 3756 private static File getSettingsProblemFile() { 3757 File dataDir = Environment.getDataDirectory(); 3758 File systemDir = new File(dataDir, "system"); 3759 File fname = new File(systemDir, "uiderrors.txt"); 3760 return fname; 3761 } 3762 3763 static void reportSettingsProblem(int priority, String msg) { 3764 try { 3765 File fname = getSettingsProblemFile(); 3766 FileOutputStream out = new FileOutputStream(fname, true); 3767 PrintWriter pw = new FastPrintWriter(out); 3768 SimpleDateFormat formatter = new SimpleDateFormat(); 3769 String dateString = formatter.format(new Date(System.currentTimeMillis())); 3770 pw.println(dateString + ": " + msg); 3771 pw.close(); 3772 FileUtils.setPermissions( 3773 fname.toString(), 3774 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 3775 -1, -1); 3776 } catch (java.io.IOException e) { 3777 } 3778 Slog.println(priority, TAG, msg); 3779 } 3780 3781 private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps, 3782 PackageParser.Package pkg, File srcFile, int parseFlags) { 3783 if (ps != null 3784 && ps.codePath.equals(srcFile) 3785 && ps.timeStamp == srcFile.lastModified()) { 3786 if (ps.signatures.mSignatures != null 3787 && ps.signatures.mSignatures.length != 0) { 3788 // Optimization: reuse the existing cached certificates 3789 // if the package appears to be unchanged. 3790 pkg.mSignatures = ps.signatures.mSignatures; 3791 return true; 3792 } 3793 3794 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures. Collecting certs again to recover them."); 3795 } else { 3796 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 3797 } 3798 3799 if (!pp.collectCertificates(pkg, parseFlags)) { 3800 mLastScanError = pp.getParseError(); 3801 return false; 3802 } 3803 return true; 3804 } 3805 3806 /* 3807 * Scan a package and return the newly parsed package. 3808 * Returns null in case of errors and the error code is stored in mLastScanError 3809 */ 3810 private PackageParser.Package scanPackageLI(File scanFile, 3811 int parseFlags, int scanMode, long currentTime, UserHandle user) { 3812 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 3813 String scanPath = scanFile.getPath(); 3814 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath); 3815 parseFlags |= mDefParseFlags; 3816 PackageParser pp = new PackageParser(scanPath); 3817 pp.setSeparateProcesses(mSeparateProcesses); 3818 pp.setOnlyCoreApps(mOnlyCore); 3819 final PackageParser.Package pkg = pp.parsePackage(scanFile, 3820 scanPath, mMetrics, parseFlags, (scanMode & SCAN_TRUSTED_OVERLAY) != 0); 3821 3822 if (pkg == null) { 3823 mLastScanError = pp.getParseError(); 3824 return null; 3825 } 3826 3827 PackageSetting ps = null; 3828 PackageSetting updatedPkg; 3829 // reader 3830 synchronized (mPackages) { 3831 // Look to see if we already know about this package. 3832 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 3833 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 3834 // This package has been renamed to its original name. Let's 3835 // use that. 3836 ps = mSettings.peekPackageLPr(oldName); 3837 } 3838 // If there was no original package, see one for the real package name. 3839 if (ps == null) { 3840 ps = mSettings.peekPackageLPr(pkg.packageName); 3841 } 3842 // Check to see if this package could be hiding/updating a system 3843 // package. Must look for it either under the original or real 3844 // package name depending on our state. 3845 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 3846 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 3847 } 3848 boolean updatedPkgBetter = false; 3849 // First check if this is a system package that may involve an update 3850 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 3851 if (ps != null && !ps.codePath.equals(scanFile)) { 3852 // The path has changed from what was last scanned... check the 3853 // version of the new path against what we have stored to determine 3854 // what to do. 3855 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 3856 if (pkg.mVersionCode < ps.versionCode) { 3857 // The system package has been updated and the code path does not match 3858 // Ignore entry. Skip it. 3859 Log.i(TAG, "Package " + ps.name + " at " + scanFile 3860 + " ignored: updated version " + ps.versionCode 3861 + " better than this " + pkg.mVersionCode); 3862 if (!updatedPkg.codePath.equals(scanFile)) { 3863 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : " 3864 + ps.name + " changing from " + updatedPkg.codePathString 3865 + " to " + scanFile); 3866 updatedPkg.codePath = scanFile; 3867 updatedPkg.codePathString = scanFile.toString(); 3868 // This is the point at which we know that the system-disk APK 3869 // for this package has moved during a reboot (e.g. due to an OTA), 3870 // so we need to reevaluate it for privilege policy. 3871 if (locationIsPrivileged(scanFile)) { 3872 updatedPkg.pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED; 3873 } 3874 } 3875 updatedPkg.pkg = pkg; 3876 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 3877 return null; 3878 } else { 3879 // The current app on the system partion is better than 3880 // what we have updated to on the data partition; switch 3881 // back to the system partition version. 3882 // At this point, its safely assumed that package installation for 3883 // apps in system partition will go through. If not there won't be a working 3884 // version of the app 3885 // writer 3886 synchronized (mPackages) { 3887 // Just remove the loaded entries from package lists. 3888 mPackages.remove(ps.name); 3889 } 3890 Slog.w(TAG, "Package " + ps.name + " at " + scanFile 3891 + "reverting from " + ps.codePathString 3892 + ": new version " + pkg.mVersionCode 3893 + " better than installed " + ps.versionCode); 3894 3895 InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps), 3896 ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString); 3897 synchronized (mInstallLock) { 3898 args.cleanUpResourcesLI(); 3899 } 3900 synchronized (mPackages) { 3901 mSettings.enableSystemPackageLPw(ps.name); 3902 } 3903 updatedPkgBetter = true; 3904 } 3905 } 3906 } 3907 3908 if (updatedPkg != null) { 3909 // An updated system app will not have the PARSE_IS_SYSTEM flag set 3910 // initially 3911 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 3912 3913 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 3914 // flag set initially 3915 if ((updatedPkg.pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0) { 3916 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 3917 } 3918 } 3919 // Verify certificates against what was last scanned 3920 if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) { 3921 Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName); 3922 return null; 3923 } 3924 3925 /* 3926 * A new system app appeared, but we already had a non-system one of the 3927 * same name installed earlier. 3928 */ 3929 boolean shouldHideSystemApp = false; 3930 if (updatedPkg == null && ps != null 3931 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 3932 /* 3933 * Check to make sure the signatures match first. If they don't, 3934 * wipe the installed application and its data. 3935 */ 3936 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 3937 != PackageManager.SIGNATURE_MATCH) { 3938 if (DEBUG_INSTALL) Slog.d(TAG, "Signature mismatch!"); 3939 deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false); 3940 ps = null; 3941 } else { 3942 /* 3943 * If the newly-added system app is an older version than the 3944 * already installed version, hide it. It will be scanned later 3945 * and re-added like an update. 3946 */ 3947 if (pkg.mVersionCode < ps.versionCode) { 3948 shouldHideSystemApp = true; 3949 } else { 3950 /* 3951 * The newly found system app is a newer version that the 3952 * one previously installed. Simply remove the 3953 * already-installed application and replace it with our own 3954 * while keeping the application data. 3955 */ 3956 Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from " 3957 + ps.codePathString + ": new version " + pkg.mVersionCode 3958 + " better than installed " + ps.versionCode); 3959 InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps), 3960 ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString); 3961 synchronized (mInstallLock) { 3962 args.cleanUpResourcesLI(); 3963 } 3964 } 3965 } 3966 } 3967 3968 // The apk is forward locked (not public) if its code and resources 3969 // are kept in different files. (except for app in either system or 3970 // vendor path). 3971 // TODO grab this value from PackageSettings 3972 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 3973 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 3974 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 3975 } 3976 } 3977 3978 String codePath = null; 3979 String resPath = null; 3980 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 3981 if (ps != null && ps.resourcePathString != null) { 3982 resPath = ps.resourcePathString; 3983 } else { 3984 // Should not happen at all. Just log an error. 3985 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 3986 } 3987 } else { 3988 resPath = pkg.mScanPath; 3989 } 3990 3991 codePath = pkg.mScanPath; 3992 // Set application objects path explicitly. 3993 setApplicationInfoPaths(pkg, codePath, resPath); 3994 // Applications can run with the primary Cpu Abi unless otherwise is specified 3995 pkg.applicationInfo.requiredCpuAbi = null; 3996 // Note that we invoke the following method only if we are about to unpack an application 3997 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode 3998 | SCAN_UPDATE_SIGNATURE, currentTime, user); 3999 4000 /* 4001 * If the system app should be overridden by a previously installed 4002 * data, hide the system app now and let the /data/app scan pick it up 4003 * again. 4004 */ 4005 if (shouldHideSystemApp) { 4006 synchronized (mPackages) { 4007 /* 4008 * We have to grant systems permissions before we hide, because 4009 * grantPermissions will assume the package update is trying to 4010 * expand its permissions. 4011 */ 4012 grantPermissionsLPw(pkg, true); 4013 mSettings.disableSystemPackageLPw(pkg.packageName); 4014 } 4015 } 4016 4017 return scannedPkg; 4018 } 4019 4020 private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath, 4021 String destResPath) { 4022 pkg.mPath = pkg.mScanPath = destCodePath; 4023 pkg.applicationInfo.sourceDir = destCodePath; 4024 pkg.applicationInfo.publicSourceDir = destResPath; 4025 } 4026 4027 private static String fixProcessName(String defProcessName, 4028 String processName, int uid) { 4029 if (processName == null) { 4030 return defProcessName; 4031 } 4032 return processName; 4033 } 4034 4035 private boolean verifySignaturesLP(PackageSetting pkgSetting, 4036 PackageParser.Package pkg) { 4037 if (pkgSetting.signatures.mSignatures != null) { 4038 // Already existing package. Make sure signatures match 4039 if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) != 4040 PackageManager.SIGNATURE_MATCH) { 4041 Slog.e(TAG, "Package " + pkg.packageName 4042 + " signatures do not match the previously installed version; ignoring!"); 4043 mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 4044 return false; 4045 } 4046 } 4047 // Check for shared user signatures 4048 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 4049 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 4050 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 4051 Slog.e(TAG, "Package " + pkg.packageName 4052 + " has no signatures that match those in shared user " 4053 + pkgSetting.sharedUser.name + "; ignoring!"); 4054 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 4055 return false; 4056 } 4057 } 4058 return true; 4059 } 4060 4061 /** 4062 * Enforces that only the system UID or root's UID can call a method exposed 4063 * via Binder. 4064 * 4065 * @param message used as message if SecurityException is thrown 4066 * @throws SecurityException if the caller is not system or root 4067 */ 4068 private static final void enforceSystemOrRoot(String message) { 4069 final int uid = Binder.getCallingUid(); 4070 if (uid != Process.SYSTEM_UID && uid != 0) { 4071 throw new SecurityException(message); 4072 } 4073 } 4074 4075 public void performBootDexOpt() { 4076 HashSet<PackageParser.Package> pkgs = null; 4077 synchronized (mPackages) { 4078 pkgs = mDeferredDexOpt; 4079 mDeferredDexOpt = null; 4080 } 4081 if (pkgs != null) { 4082 int i = 0; 4083 for (PackageParser.Package pkg : pkgs) { 4084 if (!isFirstBoot()) { 4085 i++; 4086 try { 4087 ActivityManagerNative.getDefault().showBootMessage( 4088 mContext.getResources().getString( 4089 com.android.internal.R.string.android_upgrading_apk, 4090 i, pkgs.size()), true); 4091 } catch (RemoteException e) { 4092 } 4093 } 4094 PackageParser.Package p = pkg; 4095 synchronized (mInstallLock) { 4096 if (!p.mDidDexOpt) { 4097 performDexOptLI(p, false, false, true); 4098 } 4099 } 4100 } 4101 } 4102 } 4103 4104 public boolean performDexOpt(String packageName) { 4105 enforceSystemOrRoot("Only the system can request dexopt be performed"); 4106 4107 if (!mNoDexOpt) { 4108 return false; 4109 } 4110 4111 PackageParser.Package p; 4112 synchronized (mPackages) { 4113 p = mPackages.get(packageName); 4114 if (p == null || p.mDidDexOpt) { 4115 return false; 4116 } 4117 } 4118 synchronized (mInstallLock) { 4119 return performDexOptLI(p, false, false, true) == DEX_OPT_PERFORMED; 4120 } 4121 } 4122 4123 private void performDexOptLibsLI(ArrayList<String> libs, boolean forceDex, boolean defer, 4124 HashSet<String> done) { 4125 for (int i=0; i<libs.size(); i++) { 4126 PackageParser.Package libPkg; 4127 String libName; 4128 synchronized (mPackages) { 4129 libName = libs.get(i); 4130 SharedLibraryEntry lib = mSharedLibraries.get(libName); 4131 if (lib != null && lib.apk != null) { 4132 libPkg = mPackages.get(lib.apk); 4133 } else { 4134 libPkg = null; 4135 } 4136 } 4137 if (libPkg != null && !done.contains(libName)) { 4138 performDexOptLI(libPkg, forceDex, defer, done); 4139 } 4140 } 4141 } 4142 4143 static final int DEX_OPT_SKIPPED = 0; 4144 static final int DEX_OPT_PERFORMED = 1; 4145 static final int DEX_OPT_DEFERRED = 2; 4146 static final int DEX_OPT_FAILED = -1; 4147 4148 private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer, 4149 HashSet<String> done) { 4150 boolean performed = false; 4151 if (done != null) { 4152 done.add(pkg.packageName); 4153 if (pkg.usesLibraries != null) { 4154 performDexOptLibsLI(pkg.usesLibraries, forceDex, defer, done); 4155 } 4156 if (pkg.usesOptionalLibraries != null) { 4157 performDexOptLibsLI(pkg.usesOptionalLibraries, forceDex, defer, done); 4158 } 4159 } 4160 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 4161 String path = pkg.mScanPath; 4162 int ret = 0; 4163 try { 4164 if (forceDex || dalvik.system.DexFile.isDexOptNeededInternal(path, pkg.packageName, 4165 defer)) { 4166 if (!forceDex && defer) { 4167 if (mDeferredDexOpt == null) { 4168 mDeferredDexOpt = new HashSet<PackageParser.Package>(); 4169 } 4170 mDeferredDexOpt.add(pkg); 4171 return DEX_OPT_DEFERRED; 4172 } else { 4173 Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName); 4174 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 4175 ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg), 4176 pkg.packageName); 4177 pkg.mDidDexOpt = true; 4178 performed = true; 4179 } 4180 } 4181 } catch (FileNotFoundException e) { 4182 Slog.w(TAG, "Apk not found for dexopt: " + path); 4183 ret = -1; 4184 } catch (IOException e) { 4185 Slog.w(TAG, "IOException reading apk: " + path, e); 4186 ret = -1; 4187 } catch (dalvik.system.StaleDexCacheError e) { 4188 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e); 4189 ret = -1; 4190 } catch (Exception e) { 4191 Slog.w(TAG, "Exception when doing dexopt : ", e); 4192 ret = -1; 4193 } 4194 if (ret < 0) { 4195 //error from installer 4196 return DEX_OPT_FAILED; 4197 } 4198 } 4199 4200 return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED; 4201 } 4202 4203 private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer, 4204 boolean inclDependencies) { 4205 HashSet<String> done; 4206 boolean performed = false; 4207 if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) { 4208 done = new HashSet<String>(); 4209 done.add(pkg.packageName); 4210 } else { 4211 done = null; 4212 } 4213 return performDexOptLI(pkg, forceDex, defer, done); 4214 } 4215 4216 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 4217 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 4218 Slog.w(TAG, "Unable to update from " + oldPkg.name 4219 + " to " + newPkg.packageName 4220 + ": old package not in system partition"); 4221 return false; 4222 } else if (mPackages.get(oldPkg.name) != null) { 4223 Slog.w(TAG, "Unable to update from " + oldPkg.name 4224 + " to " + newPkg.packageName 4225 + ": old package still exists"); 4226 return false; 4227 } 4228 return true; 4229 } 4230 4231 File getDataPathForUser(int userId) { 4232 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId); 4233 } 4234 4235 private File getDataPathForPackage(String packageName, int userId) { 4236 /* 4237 * Until we fully support multiple users, return the directory we 4238 * previously would have. The PackageManagerTests will need to be 4239 * revised when this is changed back.. 4240 */ 4241 if (userId == 0) { 4242 return new File(mAppDataDir, packageName); 4243 } else { 4244 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId 4245 + File.separator + packageName); 4246 } 4247 } 4248 4249 private int createDataDirsLI(String packageName, int uid, String seinfo) { 4250 int[] users = sUserManager.getUserIds(); 4251 int res = mInstaller.install(packageName, uid, uid, seinfo); 4252 if (res < 0) { 4253 return res; 4254 } 4255 for (int user : users) { 4256 if (user != 0) { 4257 res = mInstaller.createUserData(packageName, 4258 UserHandle.getUid(user, uid), user, seinfo); 4259 if (res < 0) { 4260 return res; 4261 } 4262 } 4263 } 4264 return res; 4265 } 4266 4267 private int removeDataDirsLI(String packageName) { 4268 int[] users = sUserManager.getUserIds(); 4269 int res = 0; 4270 for (int user : users) { 4271 int resInner = mInstaller.remove(packageName, user); 4272 if (resInner < 0) { 4273 res = resInner; 4274 } 4275 } 4276 4277 final File nativeLibraryFile = new File(mAppLibInstallDir, packageName); 4278 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile); 4279 if (!nativeLibraryFile.delete()) { 4280 Slog.w(TAG, "Couldn't delete native library directory " + nativeLibraryFile.getPath()); 4281 } 4282 4283 return res; 4284 } 4285 4286 private int addSharedLibraryLPw(final SharedLibraryEntry file, int num, 4287 PackageParser.Package changingLib) { 4288 if (file.path != null) { 4289 mTmpSharedLibraries[num] = file.path; 4290 return num+1; 4291 } 4292 PackageParser.Package p = mPackages.get(file.apk); 4293 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 4294 // If we are doing this while in the middle of updating a library apk, 4295 // then we need to make sure to use that new apk for determining the 4296 // dependencies here. (We haven't yet finished committing the new apk 4297 // to the package manager state.) 4298 if (p == null || p.packageName.equals(changingLib.packageName)) { 4299 p = changingLib; 4300 } 4301 } 4302 if (p != null) { 4303 String path = p.mPath; 4304 for (int i=0; i<num; i++) { 4305 if (mTmpSharedLibraries[i].equals(path)) { 4306 return num; 4307 } 4308 } 4309 mTmpSharedLibraries[num] = p.mPath; 4310 return num+1; 4311 } 4312 return num; 4313 } 4314 4315 private boolean updateSharedLibrariesLPw(PackageParser.Package pkg, 4316 PackageParser.Package changingLib) { 4317 // We might be upgrading from a version of the platform that did not 4318 // provide per-package native library directories for system apps. 4319 // Fix that up here. 4320 if (isSystemApp(pkg)) { 4321 PackageSetting ps = mSettings.mPackages.get(pkg.applicationInfo.packageName); 4322 setInternalAppNativeLibraryPath(pkg, ps); 4323 } 4324 4325 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 4326 if (mTmpSharedLibraries == null || 4327 mTmpSharedLibraries.length < mSharedLibraries.size()) { 4328 mTmpSharedLibraries = new String[mSharedLibraries.size()]; 4329 } 4330 int num = 0; 4331 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 4332 for (int i=0; i<N; i++) { 4333 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 4334 if (file == null) { 4335 Slog.e(TAG, "Package " + pkg.packageName 4336 + " requires unavailable shared library " 4337 + pkg.usesLibraries.get(i) + "; failing!"); 4338 mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 4339 return false; 4340 } 4341 num = addSharedLibraryLPw(file, num, changingLib); 4342 } 4343 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 4344 for (int i=0; i<N; i++) { 4345 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 4346 if (file == null) { 4347 Slog.w(TAG, "Package " + pkg.packageName 4348 + " desires unavailable shared library " 4349 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 4350 } else { 4351 num = addSharedLibraryLPw(file, num, changingLib); 4352 } 4353 } 4354 if (num > 0) { 4355 pkg.usesLibraryFiles = new String[num]; 4356 System.arraycopy(mTmpSharedLibraries, 0, 4357 pkg.usesLibraryFiles, 0, num); 4358 } else { 4359 pkg.usesLibraryFiles = null; 4360 } 4361 } 4362 return true; 4363 } 4364 4365 private static boolean hasString(List<String> list, List<String> which) { 4366 if (list == null) { 4367 return false; 4368 } 4369 for (int i=list.size()-1; i>=0; i--) { 4370 for (int j=which.size()-1; j>=0; j--) { 4371 if (which.get(j).equals(list.get(i))) { 4372 return true; 4373 } 4374 } 4375 } 4376 return false; 4377 } 4378 4379 private void updateAllSharedLibrariesLPw() { 4380 for (PackageParser.Package pkg : mPackages.values()) { 4381 updateSharedLibrariesLPw(pkg, null); 4382 } 4383 } 4384 4385 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 4386 PackageParser.Package changingPkg) { 4387 ArrayList<PackageParser.Package> res = null; 4388 for (PackageParser.Package pkg : mPackages.values()) { 4389 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 4390 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 4391 if (res == null) { 4392 res = new ArrayList<PackageParser.Package>(); 4393 } 4394 res.add(pkg); 4395 updateSharedLibrariesLPw(pkg, changingPkg); 4396 } 4397 } 4398 return res; 4399 } 4400 4401 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, 4402 int parseFlags, int scanMode, long currentTime, UserHandle user) { 4403 File scanFile = new File(pkg.mScanPath); 4404 if (scanFile == null || pkg.applicationInfo.sourceDir == null || 4405 pkg.applicationInfo.publicSourceDir == null) { 4406 // Bail out. The resource and code paths haven't been set. 4407 Slog.w(TAG, " Code and resource paths haven't been set correctly"); 4408 mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK; 4409 return null; 4410 } 4411 4412 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 4413 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 4414 } 4415 4416 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 4417 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_PRIVILEGED; 4418 } 4419 4420 if (mCustomResolverComponentName != null && 4421 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 4422 setUpCustomResolverActivity(pkg); 4423 } 4424 4425 if (pkg.packageName.equals("android")) { 4426 synchronized (mPackages) { 4427 if (mAndroidApplication != null) { 4428 Slog.w(TAG, "*************************************************"); 4429 Slog.w(TAG, "Core android package being redefined. Skipping."); 4430 Slog.w(TAG, " file=" + scanFile); 4431 Slog.w(TAG, "*************************************************"); 4432 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 4433 return null; 4434 } 4435 4436 // Set up information for our fall-back user intent resolution activity. 4437 mPlatformPackage = pkg; 4438 pkg.mVersionCode = mSdkVersion; 4439 mAndroidApplication = pkg.applicationInfo; 4440 4441 if (!mResolverReplaced) { 4442 mResolveActivity.applicationInfo = mAndroidApplication; 4443 mResolveActivity.name = ResolverActivity.class.getName(); 4444 mResolveActivity.packageName = mAndroidApplication.packageName; 4445 mResolveActivity.processName = "system:ui"; 4446 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 4447 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 4448 mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert; 4449 mResolveActivity.exported = true; 4450 mResolveActivity.enabled = true; 4451 mResolveInfo.activityInfo = mResolveActivity; 4452 mResolveInfo.priority = 0; 4453 mResolveInfo.preferredOrder = 0; 4454 mResolveInfo.match = 0; 4455 mResolveComponentName = new ComponentName( 4456 mAndroidApplication.packageName, mResolveActivity.name); 4457 } 4458 } 4459 } 4460 4461 if (DEBUG_PACKAGE_SCANNING) { 4462 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 4463 Log.d(TAG, "Scanning package " + pkg.packageName); 4464 } 4465 4466 if (mPackages.containsKey(pkg.packageName) 4467 || mSharedLibraries.containsKey(pkg.packageName)) { 4468 Slog.w(TAG, "Application package " + pkg.packageName 4469 + " already installed. Skipping duplicate."); 4470 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 4471 return null; 4472 } 4473 4474 // Initialize package source and resource directories 4475 File destCodeFile = new File(pkg.applicationInfo.sourceDir); 4476 File destResourceFile = new File(pkg.applicationInfo.publicSourceDir); 4477 4478 SharedUserSetting suid = null; 4479 PackageSetting pkgSetting = null; 4480 4481 if (!isSystemApp(pkg)) { 4482 // Only system apps can use these features. 4483 pkg.mOriginalPackages = null; 4484 pkg.mRealPackage = null; 4485 pkg.mAdoptPermissions = null; 4486 } 4487 4488 // writer 4489 synchronized (mPackages) { 4490 if (pkg.mSharedUserId != null) { 4491 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, true); 4492 if (suid == null) { 4493 Slog.w(TAG, "Creating application package " + pkg.packageName 4494 + " for shared user failed"); 4495 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4496 return null; 4497 } 4498 if (DEBUG_PACKAGE_SCANNING) { 4499 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 4500 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 4501 + "): packages=" + suid.packages); 4502 } 4503 } 4504 4505 // Check if we are renaming from an original package name. 4506 PackageSetting origPackage = null; 4507 String realName = null; 4508 if (pkg.mOriginalPackages != null) { 4509 // This package may need to be renamed to a previously 4510 // installed name. Let's check on that... 4511 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 4512 if (pkg.mOriginalPackages.contains(renamed)) { 4513 // This package had originally been installed as the 4514 // original name, and we have already taken care of 4515 // transitioning to the new one. Just update the new 4516 // one to continue using the old name. 4517 realName = pkg.mRealPackage; 4518 if (!pkg.packageName.equals(renamed)) { 4519 // Callers into this function may have already taken 4520 // care of renaming the package; only do it here if 4521 // it is not already done. 4522 pkg.setPackageName(renamed); 4523 } 4524 4525 } else { 4526 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 4527 if ((origPackage = mSettings.peekPackageLPr( 4528 pkg.mOriginalPackages.get(i))) != null) { 4529 // We do have the package already installed under its 4530 // original name... should we use it? 4531 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 4532 // New package is not compatible with original. 4533 origPackage = null; 4534 continue; 4535 } else if (origPackage.sharedUser != null) { 4536 // Make sure uid is compatible between packages. 4537 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 4538 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 4539 + " to " + pkg.packageName + ": old uid " 4540 + origPackage.sharedUser.name 4541 + " differs from " + pkg.mSharedUserId); 4542 origPackage = null; 4543 continue; 4544 } 4545 } else { 4546 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 4547 + pkg.packageName + " to old name " + origPackage.name); 4548 } 4549 break; 4550 } 4551 } 4552 } 4553 } 4554 4555 if (mTransferedPackages.contains(pkg.packageName)) { 4556 Slog.w(TAG, "Package " + pkg.packageName 4557 + " was transferred to another, but its .apk remains"); 4558 } 4559 4560 // Just create the setting, don't add it yet. For already existing packages 4561 // the PkgSetting exists already and doesn't have to be created. 4562 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 4563 destResourceFile, pkg.applicationInfo.nativeLibraryDir, 4564 pkg.applicationInfo.requiredCpuAbi, 4565 pkg.applicationInfo.flags, user, false); 4566 if (pkgSetting == null) { 4567 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed"); 4568 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4569 return null; 4570 } 4571 4572 if (pkgSetting.origPackage != null) { 4573 // If we are first transitioning from an original package, 4574 // fix up the new package's name now. We need to do this after 4575 // looking up the package under its new name, so getPackageLP 4576 // can take care of fiddling things correctly. 4577 pkg.setPackageName(origPackage.name); 4578 4579 // File a report about this. 4580 String msg = "New package " + pkgSetting.realName 4581 + " renamed to replace old package " + pkgSetting.name; 4582 reportSettingsProblem(Log.WARN, msg); 4583 4584 // Make a note of it. 4585 mTransferedPackages.add(origPackage.name); 4586 4587 // No longer need to retain this. 4588 pkgSetting.origPackage = null; 4589 } 4590 4591 if (realName != null) { 4592 // Make a note of it. 4593 mTransferedPackages.add(pkg.packageName); 4594 } 4595 4596 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 4597 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 4598 } 4599 4600 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 4601 // Check all shared libraries and map to their actual file path. 4602 // We only do this here for apps not on a system dir, because those 4603 // are the only ones that can fail an install due to this. We 4604 // will take care of the system apps by updating all of their 4605 // library paths after the scan is done. 4606 if (!updateSharedLibrariesLPw(pkg, null)) { 4607 return null; 4608 } 4609 } 4610 4611 if (mFoundPolicyFile) { 4612 SELinuxMMAC.assignSeinfoValue(pkg); 4613 } 4614 4615 pkg.applicationInfo.uid = pkgSetting.appId; 4616 pkg.mExtras = pkgSetting; 4617 4618 if (!verifySignaturesLP(pkgSetting, pkg)) { 4619 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 4620 return null; 4621 } 4622 // The signature has changed, but this package is in the system 4623 // image... let's recover! 4624 pkgSetting.signatures.mSignatures = pkg.mSignatures; 4625 // However... if this package is part of a shared user, but it 4626 // doesn't match the signature of the shared user, let's fail. 4627 // What this means is that you can't change the signatures 4628 // associated with an overall shared user, which doesn't seem all 4629 // that unreasonable. 4630 if (pkgSetting.sharedUser != null) { 4631 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 4632 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 4633 Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser); 4634 mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 4635 return null; 4636 } 4637 } 4638 // File a report about this. 4639 String msg = "System package " + pkg.packageName 4640 + " signature changed; retaining data."; 4641 reportSettingsProblem(Log.WARN, msg); 4642 } 4643 4644 // Verify that this new package doesn't have any content providers 4645 // that conflict with existing packages. Only do this if the 4646 // package isn't already installed, since we don't want to break 4647 // things that are installed. 4648 if ((scanMode&SCAN_NEW_INSTALL) != 0) { 4649 final int N = pkg.providers.size(); 4650 int i; 4651 for (i=0; i<N; i++) { 4652 PackageParser.Provider p = pkg.providers.get(i); 4653 if (p.info.authority != null) { 4654 String names[] = p.info.authority.split(";"); 4655 for (int j = 0; j < names.length; j++) { 4656 if (mProvidersByAuthority.containsKey(names[j])) { 4657 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 4658 Slog.w(TAG, "Can't install because provider name " + names[j] + 4659 " (in package " + pkg.applicationInfo.packageName + 4660 ") is already used by " 4661 + ((other != null && other.getComponentName() != null) 4662 ? other.getComponentName().getPackageName() : "?")); 4663 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 4664 return null; 4665 } 4666 } 4667 } 4668 } 4669 } 4670 4671 if (pkg.mAdoptPermissions != null) { 4672 // This package wants to adopt ownership of permissions from 4673 // another package. 4674 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 4675 final String origName = pkg.mAdoptPermissions.get(i); 4676 final PackageSetting orig = mSettings.peekPackageLPr(origName); 4677 if (orig != null) { 4678 if (verifyPackageUpdateLPr(orig, pkg)) { 4679 Slog.i(TAG, "Adopting permissions from " + origName + " to " 4680 + pkg.packageName); 4681 mSettings.transferPermissionsLPw(origName, pkg.packageName); 4682 } 4683 } 4684 } 4685 } 4686 } 4687 4688 final String pkgName = pkg.packageName; 4689 4690 final long scanFileTime = scanFile.lastModified(); 4691 final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0; 4692 pkg.applicationInfo.processName = fixProcessName( 4693 pkg.applicationInfo.packageName, 4694 pkg.applicationInfo.processName, 4695 pkg.applicationInfo.uid); 4696 4697 File dataPath; 4698 if (mPlatformPackage == pkg) { 4699 // The system package is special. 4700 dataPath = new File (Environment.getDataDirectory(), "system"); 4701 pkg.applicationInfo.dataDir = dataPath.getPath(); 4702 } else { 4703 // This is a normal package, need to make its data directory. 4704 dataPath = getDataPathForPackage(pkg.packageName, 0); 4705 4706 boolean uidError = false; 4707 4708 if (dataPath.exists()) { 4709 int currentUid = 0; 4710 try { 4711 StructStat stat = Libcore.os.stat(dataPath.getPath()); 4712 currentUid = stat.st_uid; 4713 } catch (ErrnoException e) { 4714 Slog.e(TAG, "Couldn't stat path " + dataPath.getPath(), e); 4715 } 4716 4717 // If we have mismatched owners for the data path, we have a problem. 4718 if (currentUid != pkg.applicationInfo.uid) { 4719 boolean recovered = false; 4720 if (currentUid == 0) { 4721 // The directory somehow became owned by root. Wow. 4722 // This is probably because the system was stopped while 4723 // installd was in the middle of messing with its libs 4724 // directory. Ask installd to fix that. 4725 int ret = mInstaller.fixUid(pkgName, pkg.applicationInfo.uid, 4726 pkg.applicationInfo.uid); 4727 if (ret >= 0) { 4728 recovered = true; 4729 String msg = "Package " + pkg.packageName 4730 + " unexpectedly changed to uid 0; recovered to " + 4731 + pkg.applicationInfo.uid; 4732 reportSettingsProblem(Log.WARN, msg); 4733 } 4734 } 4735 if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 4736 || (scanMode&SCAN_BOOTING) != 0)) { 4737 // If this is a system app, we can at least delete its 4738 // current data so the application will still work. 4739 int ret = removeDataDirsLI(pkgName); 4740 if (ret >= 0) { 4741 // TODO: Kill the processes first 4742 // Old data gone! 4743 String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0 4744 ? "System package " : "Third party package "; 4745 String msg = prefix + pkg.packageName 4746 + " has changed from uid: " 4747 + currentUid + " to " 4748 + pkg.applicationInfo.uid + "; old data erased"; 4749 reportSettingsProblem(Log.WARN, msg); 4750 recovered = true; 4751 4752 // And now re-install the app. 4753 ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 4754 pkg.applicationInfo.seinfo); 4755 if (ret == -1) { 4756 // Ack should not happen! 4757 msg = prefix + pkg.packageName 4758 + " could not have data directory re-created after delete."; 4759 reportSettingsProblem(Log.WARN, msg); 4760 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4761 return null; 4762 } 4763 } 4764 if (!recovered) { 4765 mHasSystemUidErrors = true; 4766 } 4767 } else if (!recovered) { 4768 // If we allow this install to proceed, we will be broken. 4769 // Abort, abort! 4770 mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED; 4771 return null; 4772 } 4773 if (!recovered) { 4774 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 4775 + pkg.applicationInfo.uid + "/fs_" 4776 + currentUid; 4777 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 4778 String msg = "Package " + pkg.packageName 4779 + " has mismatched uid: " 4780 + currentUid + " on disk, " 4781 + pkg.applicationInfo.uid + " in settings"; 4782 // writer 4783 synchronized (mPackages) { 4784 mSettings.mReadMessages.append(msg); 4785 mSettings.mReadMessages.append('\n'); 4786 uidError = true; 4787 if (!pkgSetting.uidError) { 4788 reportSettingsProblem(Log.ERROR, msg); 4789 } 4790 } 4791 } 4792 } 4793 pkg.applicationInfo.dataDir = dataPath.getPath(); 4794 if (mShouldRestoreconData) { 4795 Slog.i(TAG, "SELinux relabeling of " + pkg.packageName + " issued."); 4796 mInstaller.restoreconData(pkg.packageName, pkg.applicationInfo.seinfo, 4797 pkg.applicationInfo.uid); 4798 } 4799 } else { 4800 if (DEBUG_PACKAGE_SCANNING) { 4801 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 4802 Log.v(TAG, "Want this data dir: " + dataPath); 4803 } 4804 //invoke installer to do the actual installation 4805 int ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, 4806 pkg.applicationInfo.seinfo); 4807 if (ret < 0) { 4808 // Error from installer 4809 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4810 return null; 4811 } 4812 4813 if (dataPath.exists()) { 4814 pkg.applicationInfo.dataDir = dataPath.getPath(); 4815 } else { 4816 Slog.w(TAG, "Unable to create data directory: " + dataPath); 4817 pkg.applicationInfo.dataDir = null; 4818 } 4819 } 4820 4821 /* 4822 * Set the data dir to the default "/data/data/<package name>/lib" 4823 * if we got here without anyone telling us different (e.g., apps 4824 * stored on SD card have their native libraries stored in the ASEC 4825 * container with the APK). 4826 * 4827 * This happens during an upgrade from a package settings file that 4828 * doesn't have a native library path attribute at all. 4829 */ 4830 if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) { 4831 if (pkgSetting.nativeLibraryPathString == null) { 4832 setInternalAppNativeLibraryPath(pkg, pkgSetting); 4833 } else { 4834 pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString; 4835 } 4836 } 4837 pkgSetting.uidError = uidError; 4838 } 4839 4840 String path = scanFile.getPath(); 4841 /* Note: We don't want to unpack the native binaries for 4842 * system applications, unless they have been updated 4843 * (the binaries are already under /system/lib). 4844 * Also, don't unpack libs for apps on the external card 4845 * since they should have their libraries in the ASEC 4846 * container already. 4847 * 4848 * In other words, we're going to unpack the binaries 4849 * only for non-system apps and system app upgrades. 4850 */ 4851 if (pkg.applicationInfo.nativeLibraryDir != null) { 4852 try { 4853 File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); 4854 final String dataPathString = dataPath.getCanonicalPath(); 4855 4856 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { 4857 /* 4858 * Upgrading from a previous version of the OS sometimes 4859 * leaves native libraries in the /data/data/<app>/lib 4860 * directory for system apps even when they shouldn't be. 4861 * Recent changes in the JNI library search path 4862 * necessitates we remove those to match previous behavior. 4863 */ 4864 if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) { 4865 Log.i(TAG, "removed obsolete native libraries for system package " 4866 + path); 4867 } 4868 } else { 4869 if (!isForwardLocked(pkg) && !isExternal(pkg)) { 4870 /* 4871 * Update native library dir if it starts with 4872 * /data/data 4873 */ 4874 if (nativeLibraryDir.getPath().startsWith(dataPathString)) { 4875 setInternalAppNativeLibraryPath(pkg, pkgSetting); 4876 nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); 4877 } 4878 4879 try { 4880 int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir); 4881 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 4882 Slog.e(TAG, "Unable to copy native libraries"); 4883 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 4884 return null; 4885 } 4886 4887 // We've successfully copied native libraries across, so we make a 4888 // note of what ABI we're using 4889 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 4890 pkg.applicationInfo.requiredCpuAbi = Build.SUPPORTED_ABIS[copyRet]; 4891 } else { 4892 pkg.applicationInfo.requiredCpuAbi = null; 4893 } 4894 } catch (IOException e) { 4895 Slog.e(TAG, "Unable to copy native libraries", e); 4896 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 4897 return null; 4898 } 4899 } 4900 4901 if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); 4902 final int[] userIds = sUserManager.getUserIds(); 4903 synchronized (mInstallLock) { 4904 for (int userId : userIds) { 4905 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, 4906 pkg.applicationInfo.nativeLibraryDir, userId) < 0) { 4907 Slog.w(TAG, "Failed linking native library dir (user=" + userId 4908 + ")"); 4909 mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 4910 return null; 4911 } 4912 } 4913 } 4914 } 4915 } catch (IOException ioe) { 4916 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 4917 } 4918 } 4919 pkg.mScanPath = path; 4920 4921 if ((scanMode&SCAN_NO_DEX) == 0) { 4922 if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false) 4923 == DEX_OPT_FAILED) { 4924 if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 4925 removeDataDirsLI(pkg.packageName); 4926 } 4927 4928 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; 4929 return null; 4930 } 4931 } 4932 4933 if (mFactoryTest && pkg.requestedPermissions.contains( 4934 android.Manifest.permission.FACTORY_TEST)) { 4935 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 4936 } 4937 4938 ArrayList<PackageParser.Package> clientLibPkgs = null; 4939 4940 // writer 4941 synchronized (mPackages) { 4942 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 4943 // Only system apps can add new shared libraries. 4944 if (pkg.libraryNames != null) { 4945 for (int i=0; i<pkg.libraryNames.size(); i++) { 4946 String name = pkg.libraryNames.get(i); 4947 boolean allowed = false; 4948 if (isUpdatedSystemApp(pkg)) { 4949 // New library entries can only be added through the 4950 // system image. This is important to get rid of a lot 4951 // of nasty edge cases: for example if we allowed a non- 4952 // system update of the app to add a library, then uninstalling 4953 // the update would make the library go away, and assumptions 4954 // we made such as through app install filtering would now 4955 // have allowed apps on the device which aren't compatible 4956 // with it. Better to just have the restriction here, be 4957 // conservative, and create many fewer cases that can negatively 4958 // impact the user experience. 4959 final PackageSetting sysPs = mSettings 4960 .getDisabledSystemPkgLPr(pkg.packageName); 4961 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 4962 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 4963 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 4964 allowed = true; 4965 allowed = true; 4966 break; 4967 } 4968 } 4969 } 4970 } else { 4971 allowed = true; 4972 } 4973 if (allowed) { 4974 if (!mSharedLibraries.containsKey(name)) { 4975 mSharedLibraries.put(name, new SharedLibraryEntry(null, 4976 pkg.packageName)); 4977 } else if (!name.equals(pkg.packageName)) { 4978 Slog.w(TAG, "Package " + pkg.packageName + " library " 4979 + name + " already exists; skipping"); 4980 } 4981 } else { 4982 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 4983 + name + " that is not declared on system image; skipping"); 4984 } 4985 } 4986 if ((scanMode&SCAN_BOOTING) == 0) { 4987 // If we are not booting, we need to update any applications 4988 // that are clients of our shared library. If we are booting, 4989 // this will all be done once the scan is complete. 4990 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 4991 } 4992 } 4993 } 4994 } 4995 4996 // We also need to dexopt any apps that are dependent on this library. Note that 4997 // if these fail, we should abort the install since installing the library will 4998 // result in some apps being broken. 4999 if (clientLibPkgs != null) { 5000 if ((scanMode&SCAN_NO_DEX) == 0) { 5001 for (int i=0; i<clientLibPkgs.size(); i++) { 5002 PackageParser.Package clientPkg = clientLibPkgs.get(i); 5003 if (performDexOptLI(clientPkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false) 5004 == DEX_OPT_FAILED) { 5005 if ((scanMode & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 5006 removeDataDirsLI(pkg.packageName); 5007 } 5008 5009 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; 5010 return null; 5011 } 5012 } 5013 } 5014 } 5015 5016 // Request the ActivityManager to kill the process(only for existing packages) 5017 // so that we do not end up in a confused state while the user is still using the older 5018 // version of the application while the new one gets installed. 5019 if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 5020 // If the package lives in an asec, tell everyone that the container is going 5021 // away so they can clean up any references to its resources (which would prevent 5022 // vold from being able to unmount the asec) 5023 if (isForwardLocked(pkg) || isExternal(pkg)) { 5024 if (DEBUG_INSTALL) { 5025 Slog.i(TAG, "upgrading pkg " + pkg + " is ASEC-hosted -> UNAVAILABLE"); 5026 } 5027 final int[] uidArray = new int[] { pkg.applicationInfo.uid }; 5028 final ArrayList<String> pkgList = new ArrayList<String>(1); 5029 pkgList.add(pkg.applicationInfo.packageName); 5030 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 5031 } 5032 5033 // Post the request that it be killed now that the going-away broadcast is en route 5034 killApplication(pkg.applicationInfo.packageName, 5035 pkg.applicationInfo.uid, "update pkg"); 5036 } 5037 5038 // Also need to kill any apps that are dependent on the library. 5039 if (clientLibPkgs != null) { 5040 for (int i=0; i<clientLibPkgs.size(); i++) { 5041 PackageParser.Package clientPkg = clientLibPkgs.get(i); 5042 killApplication(clientPkg.applicationInfo.packageName, 5043 clientPkg.applicationInfo.uid, "update lib"); 5044 } 5045 } 5046 5047 // writer 5048 synchronized (mPackages) { 5049 // We don't expect installation to fail beyond this point, 5050 if ((scanMode&SCAN_MONITOR) != 0) { 5051 mAppDirs.put(pkg.mPath, pkg); 5052 } 5053 // Add the new setting to mSettings 5054 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 5055 // Add the new setting to mPackages 5056 mPackages.put(pkg.applicationInfo.packageName, pkg); 5057 // Make sure we don't accidentally delete its data. 5058 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 5059 while (iter.hasNext()) { 5060 PackageCleanItem item = iter.next(); 5061 if (pkgName.equals(item.packageName)) { 5062 iter.remove(); 5063 } 5064 } 5065 5066 // Take care of first install / last update times. 5067 if (currentTime != 0) { 5068 if (pkgSetting.firstInstallTime == 0) { 5069 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 5070 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) { 5071 pkgSetting.lastUpdateTime = currentTime; 5072 } 5073 } else if (pkgSetting.firstInstallTime == 0) { 5074 // We need *something*. Take time time stamp of the file. 5075 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 5076 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 5077 if (scanFileTime != pkgSetting.timeStamp) { 5078 // A package on the system image has changed; consider this 5079 // to be an update. 5080 pkgSetting.lastUpdateTime = scanFileTime; 5081 } 5082 } 5083 5084 // Add the package's KeySets to the global KeySetManager 5085 KeySetManager ksm = mSettings.mKeySetManager; 5086 try { 5087 ksm.addSigningKeySetToPackage(pkg.packageName, pkg.mSigningKeys); 5088 if (pkg.mKeySetMapping != null) { 5089 for (Map.Entry<String, Set<PublicKey>> entry : pkg.mKeySetMapping.entrySet()) { 5090 if (entry.getValue() != null) { 5091 ksm.addDefinedKeySetToPackage(pkg.packageName, 5092 entry.getValue(), entry.getKey()); 5093 } 5094 } 5095 } 5096 } catch (NullPointerException e) { 5097 Slog.e(TAG, "Could not add KeySet to " + pkg.packageName, e); 5098 } catch (IllegalArgumentException e) { 5099 Slog.e(TAG, "Could not add KeySet to malformed package" + pkg.packageName, e); 5100 } 5101 5102 int N = pkg.providers.size(); 5103 StringBuilder r = null; 5104 int i; 5105 for (i=0; i<N; i++) { 5106 PackageParser.Provider p = pkg.providers.get(i); 5107 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 5108 p.info.processName, pkg.applicationInfo.uid); 5109 mProviders.addProvider(p); 5110 p.syncable = p.info.isSyncable; 5111 if (p.info.authority != null) { 5112 String names[] = p.info.authority.split(";"); 5113 p.info.authority = null; 5114 for (int j = 0; j < names.length; j++) { 5115 if (j == 1 && p.syncable) { 5116 // We only want the first authority for a provider to possibly be 5117 // syncable, so if we already added this provider using a different 5118 // authority clear the syncable flag. We copy the provider before 5119 // changing it because the mProviders object contains a reference 5120 // to a provider that we don't want to change. 5121 // Only do this for the second authority since the resulting provider 5122 // object can be the same for all future authorities for this provider. 5123 p = new PackageParser.Provider(p); 5124 p.syncable = false; 5125 } 5126 if (!mProvidersByAuthority.containsKey(names[j])) { 5127 mProvidersByAuthority.put(names[j], p); 5128 if (p.info.authority == null) { 5129 p.info.authority = names[j]; 5130 } else { 5131 p.info.authority = p.info.authority + ";" + names[j]; 5132 } 5133 if (DEBUG_PACKAGE_SCANNING) { 5134 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 5135 Log.d(TAG, "Registered content provider: " + names[j] 5136 + ", className = " + p.info.name + ", isSyncable = " 5137 + p.info.isSyncable); 5138 } 5139 } else { 5140 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 5141 Slog.w(TAG, "Skipping provider name " + names[j] + 5142 " (in package " + pkg.applicationInfo.packageName + 5143 "): name already used by " 5144 + ((other != null && other.getComponentName() != null) 5145 ? other.getComponentName().getPackageName() : "?")); 5146 } 5147 } 5148 } 5149 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5150 if (r == null) { 5151 r = new StringBuilder(256); 5152 } else { 5153 r.append(' '); 5154 } 5155 r.append(p.info.name); 5156 } 5157 } 5158 if (r != null) { 5159 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 5160 } 5161 5162 N = pkg.services.size(); 5163 r = null; 5164 for (i=0; i<N; i++) { 5165 PackageParser.Service s = pkg.services.get(i); 5166 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 5167 s.info.processName, pkg.applicationInfo.uid); 5168 mServices.addService(s); 5169 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5170 if (r == null) { 5171 r = new StringBuilder(256); 5172 } else { 5173 r.append(' '); 5174 } 5175 r.append(s.info.name); 5176 } 5177 } 5178 if (r != null) { 5179 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 5180 } 5181 5182 N = pkg.receivers.size(); 5183 r = null; 5184 for (i=0; i<N; i++) { 5185 PackageParser.Activity a = pkg.receivers.get(i); 5186 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 5187 a.info.processName, pkg.applicationInfo.uid); 5188 mReceivers.addActivity(a, "receiver"); 5189 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5190 if (r == null) { 5191 r = new StringBuilder(256); 5192 } else { 5193 r.append(' '); 5194 } 5195 r.append(a.info.name); 5196 } 5197 } 5198 if (r != null) { 5199 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 5200 } 5201 5202 N = pkg.activities.size(); 5203 r = null; 5204 for (i=0; i<N; i++) { 5205 PackageParser.Activity a = pkg.activities.get(i); 5206 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 5207 a.info.processName, pkg.applicationInfo.uid); 5208 mActivities.addActivity(a, "activity"); 5209 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5210 if (r == null) { 5211 r = new StringBuilder(256); 5212 } else { 5213 r.append(' '); 5214 } 5215 r.append(a.info.name); 5216 } 5217 } 5218 if (r != null) { 5219 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 5220 } 5221 5222 N = pkg.permissionGroups.size(); 5223 r = null; 5224 for (i=0; i<N; i++) { 5225 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 5226 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 5227 if (cur == null) { 5228 mPermissionGroups.put(pg.info.name, pg); 5229 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5230 if (r == null) { 5231 r = new StringBuilder(256); 5232 } else { 5233 r.append(' '); 5234 } 5235 r.append(pg.info.name); 5236 } 5237 } else { 5238 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 5239 + pg.info.packageName + " ignored: original from " 5240 + cur.info.packageName); 5241 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5242 if (r == null) { 5243 r = new StringBuilder(256); 5244 } else { 5245 r.append(' '); 5246 } 5247 r.append("DUP:"); 5248 r.append(pg.info.name); 5249 } 5250 } 5251 } 5252 if (r != null) { 5253 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 5254 } 5255 5256 N = pkg.permissions.size(); 5257 r = null; 5258 for (i=0; i<N; i++) { 5259 PackageParser.Permission p = pkg.permissions.get(i); 5260 HashMap<String, BasePermission> permissionMap = 5261 p.tree ? mSettings.mPermissionTrees 5262 : mSettings.mPermissions; 5263 p.group = mPermissionGroups.get(p.info.group); 5264 if (p.info.group == null || p.group != null) { 5265 BasePermission bp = permissionMap.get(p.info.name); 5266 if (bp == null) { 5267 bp = new BasePermission(p.info.name, p.info.packageName, 5268 BasePermission.TYPE_NORMAL); 5269 permissionMap.put(p.info.name, bp); 5270 } 5271 if (bp.perm == null) { 5272 if (bp.sourcePackage != null 5273 && !bp.sourcePackage.equals(p.info.packageName)) { 5274 // If this is a permission that was formerly defined by a non-system 5275 // app, but is now defined by a system app (following an upgrade), 5276 // discard the previous declaration and consider the system's to be 5277 // canonical. 5278 if (isSystemApp(p.owner)) { 5279 String msg = "New decl " + p.owner + " of permission " 5280 + p.info.name + " is system"; 5281 reportSettingsProblem(Log.WARN, msg); 5282 bp.sourcePackage = null; 5283 } 5284 } 5285 if (bp.sourcePackage == null 5286 || bp.sourcePackage.equals(p.info.packageName)) { 5287 BasePermission tree = findPermissionTreeLP(p.info.name); 5288 if (tree == null 5289 || tree.sourcePackage.equals(p.info.packageName)) { 5290 bp.packageSetting = pkgSetting; 5291 bp.perm = p; 5292 bp.uid = pkg.applicationInfo.uid; 5293 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5294 if (r == null) { 5295 r = new StringBuilder(256); 5296 } else { 5297 r.append(' '); 5298 } 5299 r.append(p.info.name); 5300 } 5301 } else { 5302 Slog.w(TAG, "Permission " + p.info.name + " from package " 5303 + p.info.packageName + " ignored: base tree " 5304 + tree.name + " is from package " 5305 + tree.sourcePackage); 5306 } 5307 } else { 5308 Slog.w(TAG, "Permission " + p.info.name + " from package " 5309 + p.info.packageName + " ignored: original from " 5310 + bp.sourcePackage); 5311 } 5312 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5313 if (r == null) { 5314 r = new StringBuilder(256); 5315 } else { 5316 r.append(' '); 5317 } 5318 r.append("DUP:"); 5319 r.append(p.info.name); 5320 } 5321 if (bp.perm == p) { 5322 bp.protectionLevel = p.info.protectionLevel; 5323 } 5324 } else { 5325 Slog.w(TAG, "Permission " + p.info.name + " from package " 5326 + p.info.packageName + " ignored: no group " 5327 + p.group); 5328 } 5329 } 5330 if (r != null) { 5331 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 5332 } 5333 5334 N = pkg.instrumentation.size(); 5335 r = null; 5336 for (i=0; i<N; i++) { 5337 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 5338 a.info.packageName = pkg.applicationInfo.packageName; 5339 a.info.sourceDir = pkg.applicationInfo.sourceDir; 5340 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 5341 a.info.dataDir = pkg.applicationInfo.dataDir; 5342 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 5343 mInstrumentation.put(a.getComponentName(), a); 5344 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 5345 if (r == null) { 5346 r = new StringBuilder(256); 5347 } else { 5348 r.append(' '); 5349 } 5350 r.append(a.info.name); 5351 } 5352 } 5353 if (r != null) { 5354 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 5355 } 5356 5357 if (pkg.protectedBroadcasts != null) { 5358 N = pkg.protectedBroadcasts.size(); 5359 for (i=0; i<N; i++) { 5360 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 5361 } 5362 } 5363 5364 pkgSetting.setTimeStamp(scanFileTime); 5365 5366 // Create idmap files for pairs of (packages, overlay packages). 5367 // Note: "android", ie framework-res.apk, is handled by native layers. 5368 if (pkg.mOverlayTarget != null) { 5369 // This is an overlay package. 5370 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 5371 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 5372 mOverlays.put(pkg.mOverlayTarget, 5373 new HashMap<String, PackageParser.Package>()); 5374 } 5375 HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 5376 map.put(pkg.packageName, pkg); 5377 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 5378 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 5379 mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 5380 return null; 5381 } 5382 } 5383 } else if (mOverlays.containsKey(pkg.packageName) && 5384 !pkg.packageName.equals("android")) { 5385 // This is a regular package, with one or more known overlay packages. 5386 createIdmapsForPackageLI(pkg); 5387 } 5388 } 5389 5390 return pkg; 5391 } 5392 5393 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 5394 synchronized (mPackages) { 5395 mResolverReplaced = true; 5396 // Set up information for custom user intent resolution activity. 5397 mResolveActivity.applicationInfo = pkg.applicationInfo; 5398 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 5399 mResolveActivity.packageName = pkg.applicationInfo.packageName; 5400 mResolveActivity.processName = null; 5401 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 5402 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 5403 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 5404 mResolveActivity.theme = 0; 5405 mResolveActivity.exported = true; 5406 mResolveActivity.enabled = true; 5407 mResolveInfo.activityInfo = mResolveActivity; 5408 mResolveInfo.priority = 0; 5409 mResolveInfo.preferredOrder = 0; 5410 mResolveInfo.match = 0; 5411 mResolveComponentName = mCustomResolverComponentName; 5412 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 5413 mResolveComponentName); 5414 } 5415 } 5416 5417 private String calculateApkRoot(final String codePathString) { 5418 final File codePath = new File(codePathString); 5419 final File codeRoot; 5420 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 5421 codeRoot = Environment.getRootDirectory(); 5422 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 5423 codeRoot = Environment.getRootDirectory(); 5424 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 5425 codeRoot = Environment.getVendorDirectory(); 5426 } else { 5427 // Unrecognized code path; take its top real segment as the apk root: 5428 // e.g. /something/app/blah.apk => /something 5429 try { 5430 File f = codePath.getCanonicalFile(); 5431 File parent = f.getParentFile(); // non-null because codePath is a file 5432 File tmp; 5433 while ((tmp = parent.getParentFile()) != null) { 5434 f = parent; 5435 parent = tmp; 5436 } 5437 codeRoot = f; 5438 Slog.w(TAG, "Unrecognized code path " 5439 + codePath + " - using " + codeRoot); 5440 } catch (IOException e) { 5441 // Can't canonicalize the lib path -- shenanigans? 5442 Slog.w(TAG, "Can't canonicalize code path " + codePath); 5443 return Environment.getRootDirectory().getPath(); 5444 } 5445 } 5446 return codeRoot.getPath(); 5447 } 5448 5449 // This is the initial scan-time determination of how to handle a given 5450 // package for purposes of native library location. 5451 private void setInternalAppNativeLibraryPath(PackageParser.Package pkg, 5452 PackageSetting pkgSetting) { 5453 // "bundled" here means system-installed with no overriding update 5454 final boolean bundledApk = isSystemApp(pkg) && !isUpdatedSystemApp(pkg); 5455 final String apkName = getApkName(pkg.applicationInfo.sourceDir); 5456 final File libDir; 5457 if (bundledApk) { 5458 // If "/system/lib64/apkname" exists, assume that is the per-package 5459 // native library directory to use; otherwise use "/system/lib/apkname". 5460 String apkRoot = calculateApkRoot(pkg.applicationInfo.sourceDir); 5461 File lib64 = new File(apkRoot, LIB64_DIR_NAME); 5462 File packLib64 = new File(lib64, apkName); 5463 libDir = (packLib64.exists()) ? lib64 : new File(apkRoot, LIB_DIR_NAME); 5464 } else { 5465 libDir = mAppLibInstallDir; 5466 } 5467 final String nativeLibraryPath = (new File(libDir, apkName)).getPath(); 5468 pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath; 5469 pkgSetting.nativeLibraryPathString = nativeLibraryPath; 5470 } 5471 5472 private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir) 5473 throws IOException { 5474 if (!nativeLibraryDir.isDirectory()) { 5475 nativeLibraryDir.delete(); 5476 5477 if (!nativeLibraryDir.mkdir()) { 5478 throw new IOException("Cannot create " + nativeLibraryDir.getPath()); 5479 } 5480 5481 try { 5482 Libcore.os.chmod(nativeLibraryDir.getPath(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH 5483 | S_IXOTH); 5484 } catch (ErrnoException e) { 5485 throw new IOException("Cannot chmod native library directory " 5486 + nativeLibraryDir.getPath(), e); 5487 } 5488 } else if (!SELinux.restorecon(nativeLibraryDir)) { 5489 throw new IOException("Cannot set SELinux context for " + nativeLibraryDir.getPath()); 5490 } 5491 5492 /* 5493 * If this is an internal application or our nativeLibraryPath points to 5494 * the app-lib directory, unpack the libraries if necessary. 5495 */ 5496 final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile); 5497 try { 5498 int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS); 5499 if (abi >= 0) { 5500 int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, 5501 nativeLibraryDir, Build.SUPPORTED_ABIS[abi]); 5502 if (copyRet != PackageManager.INSTALL_SUCCEEDED) { 5503 return copyRet; 5504 } 5505 } 5506 5507 return abi; 5508 } finally { 5509 handle.close(); 5510 } 5511 } 5512 5513 private void killApplication(String pkgName, int appId, String reason) { 5514 // Request the ActivityManager to kill the process(only for existing packages) 5515 // so that we do not end up in a confused state while the user is still using the older 5516 // version of the application while the new one gets installed. 5517 IActivityManager am = ActivityManagerNative.getDefault(); 5518 if (am != null) { 5519 try { 5520 am.killApplicationWithAppId(pkgName, appId, reason); 5521 } catch (RemoteException e) { 5522 } 5523 } 5524 } 5525 5526 void removePackageLI(PackageSetting ps, boolean chatty) { 5527 if (DEBUG_INSTALL) { 5528 if (chatty) 5529 Log.d(TAG, "Removing package " + ps.name); 5530 } 5531 5532 // writer 5533 synchronized (mPackages) { 5534 mPackages.remove(ps.name); 5535 if (ps.codePathString != null) { 5536 mAppDirs.remove(ps.codePathString); 5537 } 5538 5539 final PackageParser.Package pkg = ps.pkg; 5540 if (pkg != null) { 5541 cleanPackageDataStructuresLILPw(pkg, chatty); 5542 } 5543 } 5544 } 5545 5546 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 5547 if (DEBUG_INSTALL) { 5548 if (chatty) 5549 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 5550 } 5551 5552 // writer 5553 synchronized (mPackages) { 5554 mPackages.remove(pkg.applicationInfo.packageName); 5555 if (pkg.mPath != null) { 5556 mAppDirs.remove(pkg.mPath); 5557 } 5558 cleanPackageDataStructuresLILPw(pkg, chatty); 5559 } 5560 } 5561 5562 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 5563 int N = pkg.providers.size(); 5564 StringBuilder r = null; 5565 int i; 5566 for (i=0; i<N; i++) { 5567 PackageParser.Provider p = pkg.providers.get(i); 5568 mProviders.removeProvider(p); 5569 if (p.info.authority == null) { 5570 5571 /* There was another ContentProvider with this authority when 5572 * this app was installed so this authority is null, 5573 * Ignore it as we don't have to unregister the provider. 5574 */ 5575 continue; 5576 } 5577 String names[] = p.info.authority.split(";"); 5578 for (int j = 0; j < names.length; j++) { 5579 if (mProvidersByAuthority.get(names[j]) == p) { 5580 mProvidersByAuthority.remove(names[j]); 5581 if (DEBUG_REMOVE) { 5582 if (chatty) 5583 Log.d(TAG, "Unregistered content provider: " + names[j] 5584 + ", className = " + p.info.name + ", isSyncable = " 5585 + p.info.isSyncable); 5586 } 5587 } 5588 } 5589 if (DEBUG_REMOVE && chatty) { 5590 if (r == null) { 5591 r = new StringBuilder(256); 5592 } else { 5593 r.append(' '); 5594 } 5595 r.append(p.info.name); 5596 } 5597 } 5598 if (r != null) { 5599 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 5600 } 5601 5602 N = pkg.services.size(); 5603 r = null; 5604 for (i=0; i<N; i++) { 5605 PackageParser.Service s = pkg.services.get(i); 5606 mServices.removeService(s); 5607 if (chatty) { 5608 if (r == null) { 5609 r = new StringBuilder(256); 5610 } else { 5611 r.append(' '); 5612 } 5613 r.append(s.info.name); 5614 } 5615 } 5616 if (r != null) { 5617 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 5618 } 5619 5620 N = pkg.receivers.size(); 5621 r = null; 5622 for (i=0; i<N; i++) { 5623 PackageParser.Activity a = pkg.receivers.get(i); 5624 mReceivers.removeActivity(a, "receiver"); 5625 if (DEBUG_REMOVE && chatty) { 5626 if (r == null) { 5627 r = new StringBuilder(256); 5628 } else { 5629 r.append(' '); 5630 } 5631 r.append(a.info.name); 5632 } 5633 } 5634 if (r != null) { 5635 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 5636 } 5637 5638 N = pkg.activities.size(); 5639 r = null; 5640 for (i=0; i<N; i++) { 5641 PackageParser.Activity a = pkg.activities.get(i); 5642 mActivities.removeActivity(a, "activity"); 5643 if (DEBUG_REMOVE && chatty) { 5644 if (r == null) { 5645 r = new StringBuilder(256); 5646 } else { 5647 r.append(' '); 5648 } 5649 r.append(a.info.name); 5650 } 5651 } 5652 if (r != null) { 5653 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 5654 } 5655 5656 N = pkg.permissions.size(); 5657 r = null; 5658 for (i=0; i<N; i++) { 5659 PackageParser.Permission p = pkg.permissions.get(i); 5660 BasePermission bp = mSettings.mPermissions.get(p.info.name); 5661 if (bp == null) { 5662 bp = mSettings.mPermissionTrees.get(p.info.name); 5663 } 5664 if (bp != null && bp.perm == p) { 5665 bp.perm = null; 5666 if (DEBUG_REMOVE && chatty) { 5667 if (r == null) { 5668 r = new StringBuilder(256); 5669 } else { 5670 r.append(' '); 5671 } 5672 r.append(p.info.name); 5673 } 5674 } 5675 } 5676 if (r != null) { 5677 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 5678 } 5679 5680 N = pkg.instrumentation.size(); 5681 r = null; 5682 for (i=0; i<N; i++) { 5683 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 5684 mInstrumentation.remove(a.getComponentName()); 5685 if (DEBUG_REMOVE && chatty) { 5686 if (r == null) { 5687 r = new StringBuilder(256); 5688 } else { 5689 r.append(' '); 5690 } 5691 r.append(a.info.name); 5692 } 5693 } 5694 if (r != null) { 5695 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 5696 } 5697 5698 r = null; 5699 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 5700 // Only system apps can hold shared libraries. 5701 if (pkg.libraryNames != null) { 5702 for (i=0; i<pkg.libraryNames.size(); i++) { 5703 String name = pkg.libraryNames.get(i); 5704 SharedLibraryEntry cur = mSharedLibraries.get(name); 5705 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 5706 mSharedLibraries.remove(name); 5707 if (DEBUG_REMOVE && chatty) { 5708 if (r == null) { 5709 r = new StringBuilder(256); 5710 } else { 5711 r.append(' '); 5712 } 5713 r.append(name); 5714 } 5715 } 5716 } 5717 } 5718 } 5719 if (r != null) { 5720 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 5721 } 5722 } 5723 5724 private static final boolean isPackageFilename(String name) { 5725 return name != null && name.endsWith(".apk"); 5726 } 5727 5728 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 5729 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 5730 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 5731 return true; 5732 } 5733 } 5734 return false; 5735 } 5736 5737 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 5738 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 5739 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 5740 5741 private void updatePermissionsLPw(String changingPkg, 5742 PackageParser.Package pkgInfo, int flags) { 5743 // Make sure there are no dangling permission trees. 5744 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 5745 while (it.hasNext()) { 5746 final BasePermission bp = it.next(); 5747 if (bp.packageSetting == null) { 5748 // We may not yet have parsed the package, so just see if 5749 // we still know about its settings. 5750 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 5751 } 5752 if (bp.packageSetting == null) { 5753 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 5754 + " from package " + bp.sourcePackage); 5755 it.remove(); 5756 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 5757 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 5758 Slog.i(TAG, "Removing old permission tree: " + bp.name 5759 + " from package " + bp.sourcePackage); 5760 flags |= UPDATE_PERMISSIONS_ALL; 5761 it.remove(); 5762 } 5763 } 5764 } 5765 5766 // Make sure all dynamic permissions have been assigned to a package, 5767 // and make sure there are no dangling permissions. 5768 it = mSettings.mPermissions.values().iterator(); 5769 while (it.hasNext()) { 5770 final BasePermission bp = it.next(); 5771 if (bp.type == BasePermission.TYPE_DYNAMIC) { 5772 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 5773 + bp.name + " pkg=" + bp.sourcePackage 5774 + " info=" + bp.pendingInfo); 5775 if (bp.packageSetting == null && bp.pendingInfo != null) { 5776 final BasePermission tree = findPermissionTreeLP(bp.name); 5777 if (tree != null && tree.perm != null) { 5778 bp.packageSetting = tree.packageSetting; 5779 bp.perm = new PackageParser.Permission(tree.perm.owner, 5780 new PermissionInfo(bp.pendingInfo)); 5781 bp.perm.info.packageName = tree.perm.info.packageName; 5782 bp.perm.info.name = bp.name; 5783 bp.uid = tree.uid; 5784 } 5785 } 5786 } 5787 if (bp.packageSetting == null) { 5788 // We may not yet have parsed the package, so just see if 5789 // we still know about its settings. 5790 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 5791 } 5792 if (bp.packageSetting == null) { 5793 Slog.w(TAG, "Removing dangling permission: " + bp.name 5794 + " from package " + bp.sourcePackage); 5795 it.remove(); 5796 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 5797 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 5798 Slog.i(TAG, "Removing old permission: " + bp.name 5799 + " from package " + bp.sourcePackage); 5800 flags |= UPDATE_PERMISSIONS_ALL; 5801 it.remove(); 5802 } 5803 } 5804 } 5805 5806 // Now update the permissions for all packages, in particular 5807 // replace the granted permissions of the system packages. 5808 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 5809 for (PackageParser.Package pkg : mPackages.values()) { 5810 if (pkg != pkgInfo) { 5811 grantPermissionsLPw(pkg, (flags&UPDATE_PERMISSIONS_REPLACE_ALL) != 0); 5812 } 5813 } 5814 } 5815 5816 if (pkgInfo != null) { 5817 grantPermissionsLPw(pkgInfo, (flags&UPDATE_PERMISSIONS_REPLACE_PKG) != 0); 5818 } 5819 } 5820 5821 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) { 5822 final PackageSetting ps = (PackageSetting) pkg.mExtras; 5823 if (ps == null) { 5824 return; 5825 } 5826 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 5827 HashSet<String> origPermissions = gp.grantedPermissions; 5828 boolean changedPermission = false; 5829 5830 if (replace) { 5831 ps.permissionsFixed = false; 5832 if (gp == ps) { 5833 origPermissions = new HashSet<String>(gp.grantedPermissions); 5834 gp.grantedPermissions.clear(); 5835 gp.gids = mGlobalGids; 5836 } 5837 } 5838 5839 if (gp.gids == null) { 5840 gp.gids = mGlobalGids; 5841 } 5842 5843 final int N = pkg.requestedPermissions.size(); 5844 for (int i=0; i<N; i++) { 5845 final String name = pkg.requestedPermissions.get(i); 5846 final boolean required = pkg.requestedPermissionsRequired.get(i); 5847 final BasePermission bp = mSettings.mPermissions.get(name); 5848 if (DEBUG_INSTALL) { 5849 if (gp != ps) { 5850 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 5851 } 5852 } 5853 5854 if (bp == null || bp.packageSetting == null) { 5855 Slog.w(TAG, "Unknown permission " + name 5856 + " in package " + pkg.packageName); 5857 continue; 5858 } 5859 5860 final String perm = bp.name; 5861 boolean allowed; 5862 boolean allowedSig = false; 5863 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 5864 if (level == PermissionInfo.PROTECTION_NORMAL 5865 || level == PermissionInfo.PROTECTION_DANGEROUS) { 5866 // We grant a normal or dangerous permission if any of the following 5867 // are true: 5868 // 1) The permission is required 5869 // 2) The permission is optional, but was granted in the past 5870 // 3) The permission is optional, but was requested by an 5871 // app in /system (not /data) 5872 // 5873 // Otherwise, reject the permission. 5874 allowed = (required || origPermissions.contains(perm) 5875 || (isSystemApp(ps) && !isUpdatedSystemApp(ps))); 5876 } else if (bp.packageSetting == null) { 5877 // This permission is invalid; skip it. 5878 allowed = false; 5879 } else if (level == PermissionInfo.PROTECTION_SIGNATURE) { 5880 allowed = grantSignaturePermission(perm, pkg, bp, origPermissions); 5881 if (allowed) { 5882 allowedSig = true; 5883 } 5884 } else { 5885 allowed = false; 5886 } 5887 if (DEBUG_INSTALL) { 5888 if (gp != ps) { 5889 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 5890 } 5891 } 5892 if (allowed) { 5893 if (!isSystemApp(ps) && ps.permissionsFixed) { 5894 // If this is an existing, non-system package, then 5895 // we can't add any new permissions to it. 5896 if (!allowedSig && !gp.grantedPermissions.contains(perm)) { 5897 // Except... if this is a permission that was added 5898 // to the platform (note: need to only do this when 5899 // updating the platform). 5900 allowed = isNewPlatformPermissionForPackage(perm, pkg); 5901 } 5902 } 5903 if (allowed) { 5904 if (!gp.grantedPermissions.contains(perm)) { 5905 changedPermission = true; 5906 gp.grantedPermissions.add(perm); 5907 gp.gids = appendInts(gp.gids, bp.gids); 5908 } else if (!ps.haveGids) { 5909 gp.gids = appendInts(gp.gids, bp.gids); 5910 } 5911 } else { 5912 Slog.w(TAG, "Not granting permission " + perm 5913 + " to package " + pkg.packageName 5914 + " because it was previously installed without"); 5915 } 5916 } else { 5917 if (gp.grantedPermissions.remove(perm)) { 5918 changedPermission = true; 5919 gp.gids = removeInts(gp.gids, bp.gids); 5920 Slog.i(TAG, "Un-granting permission " + perm 5921 + " from package " + pkg.packageName 5922 + " (protectionLevel=" + bp.protectionLevel 5923 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 5924 + ")"); 5925 } else { 5926 Slog.w(TAG, "Not granting permission " + perm 5927 + " to package " + pkg.packageName 5928 + " (protectionLevel=" + bp.protectionLevel 5929 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 5930 + ")"); 5931 } 5932 } 5933 } 5934 5935 if ((changedPermission || replace) && !ps.permissionsFixed && 5936 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 5937 // This is the first that we have heard about this package, so the 5938 // permissions we have now selected are fixed until explicitly 5939 // changed. 5940 ps.permissionsFixed = true; 5941 } 5942 ps.haveGids = true; 5943 } 5944 5945 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 5946 boolean allowed = false; 5947 final int NP = PackageParser.NEW_PERMISSIONS.length; 5948 for (int ip=0; ip<NP; ip++) { 5949 final PackageParser.NewPermissionInfo npi 5950 = PackageParser.NEW_PERMISSIONS[ip]; 5951 if (npi.name.equals(perm) 5952 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 5953 allowed = true; 5954 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 5955 + pkg.packageName); 5956 break; 5957 } 5958 } 5959 return allowed; 5960 } 5961 5962 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 5963 BasePermission bp, HashSet<String> origPermissions) { 5964 boolean allowed; 5965 allowed = (compareSignatures( 5966 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 5967 == PackageManager.SIGNATURE_MATCH) 5968 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 5969 == PackageManager.SIGNATURE_MATCH); 5970 if (!allowed && (bp.protectionLevel 5971 & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) { 5972 if (isSystemApp(pkg)) { 5973 // For updated system applications, a system permission 5974 // is granted only if it had been defined by the original application. 5975 if (isUpdatedSystemApp(pkg)) { 5976 final PackageSetting sysPs = mSettings 5977 .getDisabledSystemPkgLPr(pkg.packageName); 5978 final GrantedPermissions origGp = sysPs.sharedUser != null 5979 ? sysPs.sharedUser : sysPs; 5980 5981 if (origGp.grantedPermissions.contains(perm)) { 5982 // If the original was granted this permission, we take 5983 // that grant decision as read and propagate it to the 5984 // update. 5985 allowed = true; 5986 } else { 5987 // The system apk may have been updated with an older 5988 // version of the one on the data partition, but which 5989 // granted a new system permission that it didn't have 5990 // before. In this case we do want to allow the app to 5991 // now get the new permission if the ancestral apk is 5992 // privileged to get it. 5993 if (sysPs.pkg != null && sysPs.isPrivileged()) { 5994 for (int j=0; 5995 j<sysPs.pkg.requestedPermissions.size(); j++) { 5996 if (perm.equals( 5997 sysPs.pkg.requestedPermissions.get(j))) { 5998 allowed = true; 5999 break; 6000 } 6001 } 6002 } 6003 } 6004 } else { 6005 allowed = isPrivilegedApp(pkg); 6006 } 6007 } 6008 } 6009 if (!allowed && (bp.protectionLevel 6010 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 6011 // For development permissions, a development permission 6012 // is granted only if it was already granted. 6013 allowed = origPermissions.contains(perm); 6014 } 6015 return allowed; 6016 } 6017 6018 final class ActivityIntentResolver 6019 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 6020 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 6021 boolean defaultOnly, int userId) { 6022 if (!sUserManager.exists(userId)) return null; 6023 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 6024 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 6025 } 6026 6027 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 6028 int userId) { 6029 if (!sUserManager.exists(userId)) return null; 6030 mFlags = flags; 6031 return super.queryIntent(intent, resolvedType, 6032 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 6033 } 6034 6035 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 6036 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 6037 if (!sUserManager.exists(userId)) return null; 6038 if (packageActivities == null) { 6039 return null; 6040 } 6041 mFlags = flags; 6042 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 6043 final int N = packageActivities.size(); 6044 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 6045 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 6046 6047 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 6048 for (int i = 0; i < N; ++i) { 6049 intentFilters = packageActivities.get(i).intents; 6050 if (intentFilters != null && intentFilters.size() > 0) { 6051 PackageParser.ActivityIntentInfo[] array = 6052 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 6053 intentFilters.toArray(array); 6054 listCut.add(array); 6055 } 6056 } 6057 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 6058 } 6059 6060 public final void addActivity(PackageParser.Activity a, String type) { 6061 final boolean systemApp = isSystemApp(a.info.applicationInfo); 6062 mActivities.put(a.getComponentName(), a); 6063 if (DEBUG_SHOW_INFO) 6064 Log.v( 6065 TAG, " " + type + " " + 6066 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 6067 if (DEBUG_SHOW_INFO) 6068 Log.v(TAG, " Class=" + a.info.name); 6069 final int NI = a.intents.size(); 6070 for (int j=0; j<NI; j++) { 6071 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 6072 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 6073 intent.setPriority(0); 6074 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 6075 + a.className + " with priority > 0, forcing to 0"); 6076 } 6077 if (DEBUG_SHOW_INFO) { 6078 Log.v(TAG, " IntentFilter:"); 6079 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6080 } 6081 if (!intent.debugCheck()) { 6082 Log.w(TAG, "==> For Activity " + a.info.name); 6083 } 6084 addFilter(intent); 6085 } 6086 } 6087 6088 public final void removeActivity(PackageParser.Activity a, String type) { 6089 mActivities.remove(a.getComponentName()); 6090 if (DEBUG_SHOW_INFO) { 6091 Log.v(TAG, " " + type + " " 6092 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 6093 : a.info.name) + ":"); 6094 Log.v(TAG, " Class=" + a.info.name); 6095 } 6096 final int NI = a.intents.size(); 6097 for (int j=0; j<NI; j++) { 6098 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 6099 if (DEBUG_SHOW_INFO) { 6100 Log.v(TAG, " IntentFilter:"); 6101 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6102 } 6103 removeFilter(intent); 6104 } 6105 } 6106 6107 @Override 6108 protected boolean allowFilterResult( 6109 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 6110 ActivityInfo filterAi = filter.activity.info; 6111 for (int i=dest.size()-1; i>=0; i--) { 6112 ActivityInfo destAi = dest.get(i).activityInfo; 6113 if (destAi.name == filterAi.name 6114 && destAi.packageName == filterAi.packageName) { 6115 return false; 6116 } 6117 } 6118 return true; 6119 } 6120 6121 @Override 6122 protected ActivityIntentInfo[] newArray(int size) { 6123 return new ActivityIntentInfo[size]; 6124 } 6125 6126 @Override 6127 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 6128 if (!sUserManager.exists(userId)) return true; 6129 PackageParser.Package p = filter.activity.owner; 6130 if (p != null) { 6131 PackageSetting ps = (PackageSetting)p.mExtras; 6132 if (ps != null) { 6133 // System apps are never considered stopped for purposes of 6134 // filtering, because there may be no way for the user to 6135 // actually re-launch them. 6136 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 6137 && ps.getStopped(userId); 6138 } 6139 } 6140 return false; 6141 } 6142 6143 @Override 6144 protected boolean isPackageForFilter(String packageName, 6145 PackageParser.ActivityIntentInfo info) { 6146 return packageName.equals(info.activity.owner.packageName); 6147 } 6148 6149 @Override 6150 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 6151 int match, int userId) { 6152 if (!sUserManager.exists(userId)) return null; 6153 if (!mSettings.isEnabledLPr(info.activity.info, mFlags, userId)) { 6154 return null; 6155 } 6156 final PackageParser.Activity activity = info.activity; 6157 if (mSafeMode && (activity.info.applicationInfo.flags 6158 &ApplicationInfo.FLAG_SYSTEM) == 0) { 6159 return null; 6160 } 6161 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 6162 if (ps == null) { 6163 return null; 6164 } 6165 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 6166 ps.readUserState(userId), userId); 6167 if (ai == null) { 6168 return null; 6169 } 6170 final ResolveInfo res = new ResolveInfo(); 6171 res.activityInfo = ai; 6172 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 6173 res.filter = info; 6174 } 6175 res.priority = info.getPriority(); 6176 res.preferredOrder = activity.owner.mPreferredOrder; 6177 //System.out.println("Result: " + res.activityInfo.className + 6178 // " = " + res.priority); 6179 res.match = match; 6180 res.isDefault = info.hasDefault; 6181 res.labelRes = info.labelRes; 6182 res.nonLocalizedLabel = info.nonLocalizedLabel; 6183 res.icon = info.icon; 6184 res.system = isSystemApp(res.activityInfo.applicationInfo); 6185 return res; 6186 } 6187 6188 @Override 6189 protected void sortResults(List<ResolveInfo> results) { 6190 Collections.sort(results, mResolvePrioritySorter); 6191 } 6192 6193 @Override 6194 protected void dumpFilter(PrintWriter out, String prefix, 6195 PackageParser.ActivityIntentInfo filter) { 6196 out.print(prefix); out.print( 6197 Integer.toHexString(System.identityHashCode(filter.activity))); 6198 out.print(' '); 6199 filter.activity.printComponentShortName(out); 6200 out.print(" filter "); 6201 out.println(Integer.toHexString(System.identityHashCode(filter))); 6202 } 6203 6204// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 6205// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 6206// final List<ResolveInfo> retList = Lists.newArrayList(); 6207// while (i.hasNext()) { 6208// final ResolveInfo resolveInfo = i.next(); 6209// if (isEnabledLP(resolveInfo.activityInfo)) { 6210// retList.add(resolveInfo); 6211// } 6212// } 6213// return retList; 6214// } 6215 6216 // Keys are String (activity class name), values are Activity. 6217 private final HashMap<ComponentName, PackageParser.Activity> mActivities 6218 = new HashMap<ComponentName, PackageParser.Activity>(); 6219 private int mFlags; 6220 } 6221 6222 private final class ServiceIntentResolver 6223 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 6224 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 6225 boolean defaultOnly, int userId) { 6226 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 6227 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 6228 } 6229 6230 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 6231 int userId) { 6232 if (!sUserManager.exists(userId)) return null; 6233 mFlags = flags; 6234 return super.queryIntent(intent, resolvedType, 6235 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 6236 } 6237 6238 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 6239 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 6240 if (!sUserManager.exists(userId)) return null; 6241 if (packageServices == null) { 6242 return null; 6243 } 6244 mFlags = flags; 6245 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 6246 final int N = packageServices.size(); 6247 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 6248 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 6249 6250 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 6251 for (int i = 0; i < N; ++i) { 6252 intentFilters = packageServices.get(i).intents; 6253 if (intentFilters != null && intentFilters.size() > 0) { 6254 PackageParser.ServiceIntentInfo[] array = 6255 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 6256 intentFilters.toArray(array); 6257 listCut.add(array); 6258 } 6259 } 6260 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 6261 } 6262 6263 public final void addService(PackageParser.Service s) { 6264 mServices.put(s.getComponentName(), s); 6265 if (DEBUG_SHOW_INFO) { 6266 Log.v(TAG, " " 6267 + (s.info.nonLocalizedLabel != null 6268 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 6269 Log.v(TAG, " Class=" + s.info.name); 6270 } 6271 final int NI = s.intents.size(); 6272 int j; 6273 for (j=0; j<NI; j++) { 6274 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 6275 if (DEBUG_SHOW_INFO) { 6276 Log.v(TAG, " IntentFilter:"); 6277 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6278 } 6279 if (!intent.debugCheck()) { 6280 Log.w(TAG, "==> For Service " + s.info.name); 6281 } 6282 addFilter(intent); 6283 } 6284 } 6285 6286 public final void removeService(PackageParser.Service s) { 6287 mServices.remove(s.getComponentName()); 6288 if (DEBUG_SHOW_INFO) { 6289 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 6290 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 6291 Log.v(TAG, " Class=" + s.info.name); 6292 } 6293 final int NI = s.intents.size(); 6294 int j; 6295 for (j=0; j<NI; j++) { 6296 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 6297 if (DEBUG_SHOW_INFO) { 6298 Log.v(TAG, " IntentFilter:"); 6299 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6300 } 6301 removeFilter(intent); 6302 } 6303 } 6304 6305 @Override 6306 protected boolean allowFilterResult( 6307 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 6308 ServiceInfo filterSi = filter.service.info; 6309 for (int i=dest.size()-1; i>=0; i--) { 6310 ServiceInfo destAi = dest.get(i).serviceInfo; 6311 if (destAi.name == filterSi.name 6312 && destAi.packageName == filterSi.packageName) { 6313 return false; 6314 } 6315 } 6316 return true; 6317 } 6318 6319 @Override 6320 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 6321 return new PackageParser.ServiceIntentInfo[size]; 6322 } 6323 6324 @Override 6325 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 6326 if (!sUserManager.exists(userId)) return true; 6327 PackageParser.Package p = filter.service.owner; 6328 if (p != null) { 6329 PackageSetting ps = (PackageSetting)p.mExtras; 6330 if (ps != null) { 6331 // System apps are never considered stopped for purposes of 6332 // filtering, because there may be no way for the user to 6333 // actually re-launch them. 6334 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 6335 && ps.getStopped(userId); 6336 } 6337 } 6338 return false; 6339 } 6340 6341 @Override 6342 protected boolean isPackageForFilter(String packageName, 6343 PackageParser.ServiceIntentInfo info) { 6344 return packageName.equals(info.service.owner.packageName); 6345 } 6346 6347 @Override 6348 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 6349 int match, int userId) { 6350 if (!sUserManager.exists(userId)) return null; 6351 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 6352 if (!mSettings.isEnabledLPr(info.service.info, mFlags, userId)) { 6353 return null; 6354 } 6355 final PackageParser.Service service = info.service; 6356 if (mSafeMode && (service.info.applicationInfo.flags 6357 &ApplicationInfo.FLAG_SYSTEM) == 0) { 6358 return null; 6359 } 6360 PackageSetting ps = (PackageSetting) service.owner.mExtras; 6361 if (ps == null) { 6362 return null; 6363 } 6364 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 6365 ps.readUserState(userId), userId); 6366 if (si == null) { 6367 return null; 6368 } 6369 final ResolveInfo res = new ResolveInfo(); 6370 res.serviceInfo = si; 6371 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 6372 res.filter = filter; 6373 } 6374 res.priority = info.getPriority(); 6375 res.preferredOrder = service.owner.mPreferredOrder; 6376 //System.out.println("Result: " + res.activityInfo.className + 6377 // " = " + res.priority); 6378 res.match = match; 6379 res.isDefault = info.hasDefault; 6380 res.labelRes = info.labelRes; 6381 res.nonLocalizedLabel = info.nonLocalizedLabel; 6382 res.icon = info.icon; 6383 res.system = isSystemApp(res.serviceInfo.applicationInfo); 6384 return res; 6385 } 6386 6387 @Override 6388 protected void sortResults(List<ResolveInfo> results) { 6389 Collections.sort(results, mResolvePrioritySorter); 6390 } 6391 6392 @Override 6393 protected void dumpFilter(PrintWriter out, String prefix, 6394 PackageParser.ServiceIntentInfo filter) { 6395 out.print(prefix); out.print( 6396 Integer.toHexString(System.identityHashCode(filter.service))); 6397 out.print(' '); 6398 filter.service.printComponentShortName(out); 6399 out.print(" filter "); 6400 out.println(Integer.toHexString(System.identityHashCode(filter))); 6401 } 6402 6403// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 6404// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 6405// final List<ResolveInfo> retList = Lists.newArrayList(); 6406// while (i.hasNext()) { 6407// final ResolveInfo resolveInfo = (ResolveInfo) i; 6408// if (isEnabledLP(resolveInfo.serviceInfo)) { 6409// retList.add(resolveInfo); 6410// } 6411// } 6412// return retList; 6413// } 6414 6415 // Keys are String (activity class name), values are Activity. 6416 private final HashMap<ComponentName, PackageParser.Service> mServices 6417 = new HashMap<ComponentName, PackageParser.Service>(); 6418 private int mFlags; 6419 }; 6420 6421 private final class ProviderIntentResolver 6422 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 6423 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 6424 boolean defaultOnly, int userId) { 6425 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 6426 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 6427 } 6428 6429 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 6430 int userId) { 6431 if (!sUserManager.exists(userId)) 6432 return null; 6433 mFlags = flags; 6434 return super.queryIntent(intent, resolvedType, 6435 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 6436 } 6437 6438 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 6439 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 6440 if (!sUserManager.exists(userId)) 6441 return null; 6442 if (packageProviders == null) { 6443 return null; 6444 } 6445 mFlags = flags; 6446 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 6447 final int N = packageProviders.size(); 6448 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 6449 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 6450 6451 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 6452 for (int i = 0; i < N; ++i) { 6453 intentFilters = packageProviders.get(i).intents; 6454 if (intentFilters != null && intentFilters.size() > 0) { 6455 PackageParser.ProviderIntentInfo[] array = 6456 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 6457 intentFilters.toArray(array); 6458 listCut.add(array); 6459 } 6460 } 6461 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 6462 } 6463 6464 public final void addProvider(PackageParser.Provider p) { 6465 if (mProviders.containsKey(p.getComponentName())) { 6466 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 6467 return; 6468 } 6469 6470 mProviders.put(p.getComponentName(), p); 6471 if (DEBUG_SHOW_INFO) { 6472 Log.v(TAG, " " 6473 + (p.info.nonLocalizedLabel != null 6474 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 6475 Log.v(TAG, " Class=" + p.info.name); 6476 } 6477 final int NI = p.intents.size(); 6478 int j; 6479 for (j = 0; j < NI; j++) { 6480 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 6481 if (DEBUG_SHOW_INFO) { 6482 Log.v(TAG, " IntentFilter:"); 6483 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6484 } 6485 if (!intent.debugCheck()) { 6486 Log.w(TAG, "==> For Provider " + p.info.name); 6487 } 6488 addFilter(intent); 6489 } 6490 } 6491 6492 public final void removeProvider(PackageParser.Provider p) { 6493 mProviders.remove(p.getComponentName()); 6494 if (DEBUG_SHOW_INFO) { 6495 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 6496 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 6497 Log.v(TAG, " Class=" + p.info.name); 6498 } 6499 final int NI = p.intents.size(); 6500 int j; 6501 for (j = 0; j < NI; j++) { 6502 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 6503 if (DEBUG_SHOW_INFO) { 6504 Log.v(TAG, " IntentFilter:"); 6505 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 6506 } 6507 removeFilter(intent); 6508 } 6509 } 6510 6511 @Override 6512 protected boolean allowFilterResult( 6513 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 6514 ProviderInfo filterPi = filter.provider.info; 6515 for (int i = dest.size() - 1; i >= 0; i--) { 6516 ProviderInfo destPi = dest.get(i).providerInfo; 6517 if (destPi.name == filterPi.name 6518 && destPi.packageName == filterPi.packageName) { 6519 return false; 6520 } 6521 } 6522 return true; 6523 } 6524 6525 @Override 6526 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 6527 return new PackageParser.ProviderIntentInfo[size]; 6528 } 6529 6530 @Override 6531 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 6532 if (!sUserManager.exists(userId)) 6533 return true; 6534 PackageParser.Package p = filter.provider.owner; 6535 if (p != null) { 6536 PackageSetting ps = (PackageSetting) p.mExtras; 6537 if (ps != null) { 6538 // System apps are never considered stopped for purposes of 6539 // filtering, because there may be no way for the user to 6540 // actually re-launch them. 6541 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 6542 && ps.getStopped(userId); 6543 } 6544 } 6545 return false; 6546 } 6547 6548 @Override 6549 protected boolean isPackageForFilter(String packageName, 6550 PackageParser.ProviderIntentInfo info) { 6551 return packageName.equals(info.provider.owner.packageName); 6552 } 6553 6554 @Override 6555 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 6556 int match, int userId) { 6557 if (!sUserManager.exists(userId)) 6558 return null; 6559 final PackageParser.ProviderIntentInfo info = filter; 6560 if (!mSettings.isEnabledLPr(info.provider.info, mFlags, userId)) { 6561 return null; 6562 } 6563 final PackageParser.Provider provider = info.provider; 6564 if (mSafeMode && (provider.info.applicationInfo.flags 6565 & ApplicationInfo.FLAG_SYSTEM) == 0) { 6566 return null; 6567 } 6568 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 6569 if (ps == null) { 6570 return null; 6571 } 6572 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 6573 ps.readUserState(userId), userId); 6574 if (pi == null) { 6575 return null; 6576 } 6577 final ResolveInfo res = new ResolveInfo(); 6578 res.providerInfo = pi; 6579 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 6580 res.filter = filter; 6581 } 6582 res.priority = info.getPriority(); 6583 res.preferredOrder = provider.owner.mPreferredOrder; 6584 res.match = match; 6585 res.isDefault = info.hasDefault; 6586 res.labelRes = info.labelRes; 6587 res.nonLocalizedLabel = info.nonLocalizedLabel; 6588 res.icon = info.icon; 6589 res.system = isSystemApp(res.providerInfo.applicationInfo); 6590 return res; 6591 } 6592 6593 @Override 6594 protected void sortResults(List<ResolveInfo> results) { 6595 Collections.sort(results, mResolvePrioritySorter); 6596 } 6597 6598 @Override 6599 protected void dumpFilter(PrintWriter out, String prefix, 6600 PackageParser.ProviderIntentInfo filter) { 6601 out.print(prefix); 6602 out.print( 6603 Integer.toHexString(System.identityHashCode(filter.provider))); 6604 out.print(' '); 6605 filter.provider.printComponentShortName(out); 6606 out.print(" filter "); 6607 out.println(Integer.toHexString(System.identityHashCode(filter))); 6608 } 6609 6610 private final HashMap<ComponentName, PackageParser.Provider> mProviders 6611 = new HashMap<ComponentName, PackageParser.Provider>(); 6612 private int mFlags; 6613 }; 6614 6615 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 6616 new Comparator<ResolveInfo>() { 6617 public int compare(ResolveInfo r1, ResolveInfo r2) { 6618 int v1 = r1.priority; 6619 int v2 = r2.priority; 6620 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 6621 if (v1 != v2) { 6622 return (v1 > v2) ? -1 : 1; 6623 } 6624 v1 = r1.preferredOrder; 6625 v2 = r2.preferredOrder; 6626 if (v1 != v2) { 6627 return (v1 > v2) ? -1 : 1; 6628 } 6629 if (r1.isDefault != r2.isDefault) { 6630 return r1.isDefault ? -1 : 1; 6631 } 6632 v1 = r1.match; 6633 v2 = r2.match; 6634 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 6635 if (v1 != v2) { 6636 return (v1 > v2) ? -1 : 1; 6637 } 6638 if (r1.system != r2.system) { 6639 return r1.system ? -1 : 1; 6640 } 6641 return 0; 6642 } 6643 }; 6644 6645 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 6646 new Comparator<ProviderInfo>() { 6647 public int compare(ProviderInfo p1, ProviderInfo p2) { 6648 final int v1 = p1.initOrder; 6649 final int v2 = p2.initOrder; 6650 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 6651 } 6652 }; 6653 6654 static final void sendPackageBroadcast(String action, String pkg, 6655 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver, 6656 int[] userIds) { 6657 IActivityManager am = ActivityManagerNative.getDefault(); 6658 if (am != null) { 6659 try { 6660 if (userIds == null) { 6661 userIds = am.getRunningUserIds(); 6662 } 6663 for (int id : userIds) { 6664 final Intent intent = new Intent(action, 6665 pkg != null ? Uri.fromParts("package", pkg, null) : null); 6666 if (extras != null) { 6667 intent.putExtras(extras); 6668 } 6669 if (targetPkg != null) { 6670 intent.setPackage(targetPkg); 6671 } 6672 // Modify the UID when posting to other users 6673 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 6674 if (uid > 0 && UserHandle.getUserId(uid) != id) { 6675 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 6676 intent.putExtra(Intent.EXTRA_UID, uid); 6677 } 6678 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 6679 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 6680 if (DEBUG_BROADCASTS) { 6681 RuntimeException here = new RuntimeException("here"); 6682 here.fillInStackTrace(); 6683 Slog.d(TAG, "Sending to user " + id + ": " 6684 + intent.toShortString(false, true, false, false) 6685 + " " + intent.getExtras(), here); 6686 } 6687 am.broadcastIntent(null, intent, null, finishedReceiver, 6688 0, null, null, null, android.app.AppOpsManager.OP_NONE, 6689 finishedReceiver != null, false, id); 6690 } 6691 } catch (RemoteException ex) { 6692 } 6693 } 6694 } 6695 6696 /** 6697 * Check if the external storage media is available. This is true if there 6698 * is a mounted external storage medium or if the external storage is 6699 * emulated. 6700 */ 6701 private boolean isExternalMediaAvailable() { 6702 return mMediaMounted || Environment.isExternalStorageEmulated(); 6703 } 6704 6705 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 6706 // writer 6707 synchronized (mPackages) { 6708 if (!isExternalMediaAvailable()) { 6709 // If the external storage is no longer mounted at this point, 6710 // the caller may not have been able to delete all of this 6711 // packages files and can not delete any more. Bail. 6712 return null; 6713 } 6714 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 6715 if (lastPackage != null) { 6716 pkgs.remove(lastPackage); 6717 } 6718 if (pkgs.size() > 0) { 6719 return pkgs.get(0); 6720 } 6721 } 6722 return null; 6723 } 6724 6725 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 6726 if (false) { 6727 RuntimeException here = new RuntimeException("here"); 6728 here.fillInStackTrace(); 6729 Slog.d(TAG, "Schedule cleaning " + packageName + " user=" + userId 6730 + " andCode=" + andCode, here); 6731 } 6732 mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE, 6733 userId, andCode ? 1 : 0, packageName)); 6734 } 6735 6736 void startCleaningPackages() { 6737 // reader 6738 synchronized (mPackages) { 6739 if (!isExternalMediaAvailable()) { 6740 return; 6741 } 6742 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 6743 return; 6744 } 6745 } 6746 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 6747 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 6748 IActivityManager am = ActivityManagerNative.getDefault(); 6749 if (am != null) { 6750 try { 6751 am.startService(null, intent, null, UserHandle.USER_OWNER); 6752 } catch (RemoteException e) { 6753 } 6754 } 6755 } 6756 6757 private final class AppDirObserver extends FileObserver { 6758 public AppDirObserver(String path, int mask, boolean isrom, boolean isPrivileged) { 6759 super(path, mask); 6760 mRootDir = path; 6761 mIsRom = isrom; 6762 mIsPrivileged = isPrivileged; 6763 } 6764 6765 public void onEvent(int event, String path) { 6766 String removedPackage = null; 6767 int removedAppId = -1; 6768 int[] removedUsers = null; 6769 String addedPackage = null; 6770 int addedAppId = -1; 6771 int[] addedUsers = null; 6772 6773 // TODO post a message to the handler to obtain serial ordering 6774 synchronized (mInstallLock) { 6775 String fullPathStr = null; 6776 File fullPath = null; 6777 if (path != null) { 6778 fullPath = new File(mRootDir, path); 6779 fullPathStr = fullPath.getPath(); 6780 } 6781 6782 if (DEBUG_APP_DIR_OBSERVER) 6783 Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event)); 6784 6785 if (!isPackageFilename(path)) { 6786 if (DEBUG_APP_DIR_OBSERVER) 6787 Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr); 6788 return; 6789 } 6790 6791 // Ignore packages that are being installed or 6792 // have just been installed. 6793 if (ignoreCodePath(fullPathStr)) { 6794 return; 6795 } 6796 PackageParser.Package p = null; 6797 PackageSetting ps = null; 6798 // reader 6799 synchronized (mPackages) { 6800 p = mAppDirs.get(fullPathStr); 6801 if (p != null) { 6802 ps = mSettings.mPackages.get(p.applicationInfo.packageName); 6803 if (ps != null) { 6804 removedUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 6805 } else { 6806 removedUsers = sUserManager.getUserIds(); 6807 } 6808 } 6809 addedUsers = sUserManager.getUserIds(); 6810 } 6811 if ((event&REMOVE_EVENTS) != 0) { 6812 if (ps != null) { 6813 if (DEBUG_REMOVE) Slog.d(TAG, "Package disappeared: " + ps); 6814 removePackageLI(ps, true); 6815 removedPackage = ps.name; 6816 removedAppId = ps.appId; 6817 } 6818 } 6819 6820 if ((event&ADD_EVENTS) != 0) { 6821 if (p == null) { 6822 if (DEBUG_INSTALL) Slog.d(TAG, "New file appeared: " + fullPath); 6823 int flags = PackageParser.PARSE_CHATTY | PackageParser.PARSE_MUST_BE_APK; 6824 if (mIsRom) { 6825 flags |= PackageParser.PARSE_IS_SYSTEM 6826 | PackageParser.PARSE_IS_SYSTEM_DIR; 6827 if (mIsPrivileged) { 6828 flags |= PackageParser.PARSE_IS_PRIVILEGED; 6829 } 6830 } 6831 p = scanPackageLI(fullPath, flags, 6832 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME, 6833 System.currentTimeMillis(), UserHandle.ALL); 6834 if (p != null) { 6835 /* 6836 * TODO this seems dangerous as the package may have 6837 * changed since we last acquired the mPackages 6838 * lock. 6839 */ 6840 // writer 6841 synchronized (mPackages) { 6842 updatePermissionsLPw(p.packageName, p, 6843 p.permissions.size() > 0 ? UPDATE_PERMISSIONS_ALL : 0); 6844 } 6845 addedPackage = p.applicationInfo.packageName; 6846 addedAppId = UserHandle.getAppId(p.applicationInfo.uid); 6847 } 6848 } 6849 } 6850 6851 // reader 6852 synchronized (mPackages) { 6853 mSettings.writeLPr(); 6854 } 6855 } 6856 6857 if (removedPackage != null) { 6858 Bundle extras = new Bundle(1); 6859 extras.putInt(Intent.EXTRA_UID, removedAppId); 6860 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false); 6861 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 6862 extras, null, null, removedUsers); 6863 } 6864 if (addedPackage != null) { 6865 Bundle extras = new Bundle(1); 6866 extras.putInt(Intent.EXTRA_UID, addedAppId); 6867 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage, 6868 extras, null, null, addedUsers); 6869 } 6870 } 6871 6872 private final String mRootDir; 6873 private final boolean mIsRom; 6874 private final boolean mIsPrivileged; 6875 } 6876 6877 /* 6878 * The old-style observer methods all just trampoline to the newer signature with 6879 * expanded install observer API. The older API continues to work but does not 6880 * supply the additional details of the Observer2 API. 6881 */ 6882 6883 /* Called when a downloaded package installation has been confirmed by the user */ 6884 public void installPackage( 6885 final Uri packageURI, final IPackageInstallObserver observer, final int flags) { 6886 installPackageEtc(packageURI, observer, null, flags, null); 6887 } 6888 6889 /* Called when a downloaded package installation has been confirmed by the user */ 6890 public void installPackage( 6891 final Uri packageURI, final IPackageInstallObserver observer, final int flags, 6892 final String installerPackageName) { 6893 installPackageWithVerificationEtc(packageURI, observer, null, flags, 6894 installerPackageName, null, null, null); 6895 } 6896 6897 @Override 6898 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 6899 int flags, String installerPackageName, Uri verificationURI, 6900 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) { 6901 VerificationParams verificationParams = new VerificationParams(verificationURI, null, null, 6902 VerificationParams.NO_UID, manifestDigest); 6903 installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null, flags, 6904 installerPackageName, verificationParams, encryptionParams); 6905 } 6906 6907 public void installPackageWithVerificationAndEncryption(Uri packageURI, 6908 IPackageInstallObserver observer, int flags, String installerPackageName, 6909 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 6910 installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null, flags, 6911 installerPackageName, verificationParams, encryptionParams); 6912 } 6913 6914 /* 6915 * And here are the "live" versions that take both observer arguments 6916 */ 6917 public void installPackageEtc( 6918 final Uri packageURI, final IPackageInstallObserver observer, 6919 IPackageInstallObserver2 observer2, final int flags) { 6920 installPackageEtc(packageURI, observer, observer2, flags, null); 6921 } 6922 6923 public void installPackageEtc( 6924 final Uri packageURI, final IPackageInstallObserver observer, 6925 final IPackageInstallObserver2 observer2, final int flags, 6926 final String installerPackageName) { 6927 installPackageWithVerificationEtc(packageURI, observer, observer2, flags, 6928 installerPackageName, null, null, null); 6929 } 6930 6931 @Override 6932 public void installPackageWithVerificationEtc(Uri packageURI, IPackageInstallObserver observer, 6933 IPackageInstallObserver2 observer2, 6934 int flags, String installerPackageName, Uri verificationURI, 6935 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) { 6936 VerificationParams verificationParams = new VerificationParams(verificationURI, null, null, 6937 VerificationParams.NO_UID, manifestDigest); 6938 installPackageWithVerificationAndEncryptionEtc(packageURI, observer, observer2, flags, 6939 installerPackageName, verificationParams, encryptionParams); 6940 } 6941 6942 /* 6943 * All of the installPackage...*() methods redirect to this one for the master implementation 6944 */ 6945 public void installPackageWithVerificationAndEncryptionEtc(Uri packageURI, 6946 IPackageInstallObserver observer, IPackageInstallObserver2 observer2, 6947 int flags, String installerPackageName, 6948 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) { 6949 if (observer == null && observer2 == null) { 6950 throw new IllegalArgumentException("No install observer supplied"); 6951 } 6952 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 6953 null); 6954 6955 final int uid = Binder.getCallingUid(); 6956 if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) { 6957 try { 6958 if (observer != null) { 6959 observer.packageInstalled("", PackageManager.INSTALL_FAILED_USER_RESTRICTED); 6960 } 6961 if (observer2 != null) { 6962 observer2.packageInstalled("", null, PackageManager.INSTALL_FAILED_USER_RESTRICTED); 6963 } 6964 } catch (RemoteException re) { 6965 } 6966 return; 6967 } 6968 6969 UserHandle user; 6970 if ((flags&PackageManager.INSTALL_ALL_USERS) != 0) { 6971 user = UserHandle.ALL; 6972 } else { 6973 user = new UserHandle(UserHandle.getUserId(uid)); 6974 } 6975 6976 final int filteredFlags; 6977 6978 if (uid == Process.SHELL_UID || uid == 0) { 6979 if (DEBUG_INSTALL) { 6980 Slog.v(TAG, "Install from ADB"); 6981 } 6982 filteredFlags = flags | PackageManager.INSTALL_FROM_ADB; 6983 } else { 6984 filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB; 6985 } 6986 6987 verificationParams.setInstallerUid(uid); 6988 6989 final Message msg = mHandler.obtainMessage(INIT_COPY); 6990 msg.obj = new InstallParams(packageURI, observer, observer2, filteredFlags, 6991 installerPackageName, verificationParams, encryptionParams, user); 6992 mHandler.sendMessage(msg); 6993 } 6994 6995 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) { 6996 Bundle extras = new Bundle(1); 6997 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId)); 6998 6999 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 7000 packageName, extras, null, null, new int[] {userId}); 7001 try { 7002 IActivityManager am = ActivityManagerNative.getDefault(); 7003 final boolean isSystem = 7004 isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 7005 if (isSystem && am.isUserRunning(userId, false)) { 7006 // The just-installed/enabled app is bundled on the system, so presumed 7007 // to be able to run automatically without needing an explicit launch. 7008 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 7009 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 7010 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 7011 .setPackage(packageName); 7012 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 7013 android.app.AppOpsManager.OP_NONE, false, false, userId); 7014 } 7015 } catch (RemoteException e) { 7016 // shouldn't happen 7017 Slog.w(TAG, "Unable to bootstrap installed package", e); 7018 } 7019 } 7020 7021 @Override 7022 public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked, 7023 int userId) { 7024 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 7025 PackageSetting pkgSetting; 7026 final int uid = Binder.getCallingUid(); 7027 if (UserHandle.getUserId(uid) != userId) { 7028 mContext.enforceCallingOrSelfPermission( 7029 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 7030 "setApplicationBlockedSetting for user " + userId); 7031 } 7032 7033 if (blocked && isPackageDeviceAdmin(packageName, userId)) { 7034 Slog.w(TAG, "Not blocking package " + packageName + ": has active device admin"); 7035 return false; 7036 } 7037 7038 long callingId = Binder.clearCallingIdentity(); 7039 try { 7040 boolean sendAdded = false; 7041 boolean sendRemoved = false; 7042 // writer 7043 synchronized (mPackages) { 7044 pkgSetting = mSettings.mPackages.get(packageName); 7045 if (pkgSetting == null) { 7046 return false; 7047 } 7048 if (pkgSetting.getBlocked(userId) != blocked) { 7049 pkgSetting.setBlocked(blocked, userId); 7050 mSettings.writePackageRestrictionsLPr(userId); 7051 if (blocked) { 7052 sendRemoved = true; 7053 } else { 7054 sendAdded = true; 7055 } 7056 } 7057 } 7058 if (sendAdded) { 7059 sendPackageAddedForUser(packageName, pkgSetting, userId); 7060 return true; 7061 } 7062 if (sendRemoved) { 7063 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 7064 "blocking pkg"); 7065 sendPackageBlockedForUser(packageName, pkgSetting, userId); 7066 } 7067 } finally { 7068 Binder.restoreCallingIdentity(callingId); 7069 } 7070 return false; 7071 } 7072 7073 private void sendPackageBlockedForUser(String packageName, PackageSetting pkgSetting, 7074 int userId) { 7075 final PackageRemovedInfo info = new PackageRemovedInfo(); 7076 info.removedPackage = packageName; 7077 info.removedUsers = new int[] {userId}; 7078 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 7079 info.sendBroadcast(false, false, false); 7080 } 7081 7082 /** 7083 * Returns true if application is not found or there was an error. Otherwise it returns 7084 * the blocked state of the package for the given user. 7085 */ 7086 @Override 7087 public boolean getApplicationBlockedSettingAsUser(String packageName, int userId) { 7088 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 7089 PackageSetting pkgSetting; 7090 final int uid = Binder.getCallingUid(); 7091 if (UserHandle.getUserId(uid) != userId) { 7092 mContext.enforceCallingPermission( 7093 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 7094 "getApplicationBlocked for user " + userId); 7095 } 7096 long callingId = Binder.clearCallingIdentity(); 7097 try { 7098 // writer 7099 synchronized (mPackages) { 7100 pkgSetting = mSettings.mPackages.get(packageName); 7101 if (pkgSetting == null) { 7102 return true; 7103 } 7104 return pkgSetting.getBlocked(userId); 7105 } 7106 } finally { 7107 Binder.restoreCallingIdentity(callingId); 7108 } 7109 } 7110 7111 /** 7112 * @hide 7113 */ 7114 @Override 7115 public int installExistingPackageAsUser(String packageName, int userId) { 7116 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 7117 null); 7118 PackageSetting pkgSetting; 7119 final int uid = Binder.getCallingUid(); 7120 if (UserHandle.getUserId(uid) != userId) { 7121 mContext.enforceCallingPermission( 7122 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 7123 "installExistingPackage for user " + userId); 7124 } 7125 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 7126 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 7127 } 7128 7129 long callingId = Binder.clearCallingIdentity(); 7130 try { 7131 boolean sendAdded = false; 7132 Bundle extras = new Bundle(1); 7133 7134 // writer 7135 synchronized (mPackages) { 7136 pkgSetting = mSettings.mPackages.get(packageName); 7137 if (pkgSetting == null) { 7138 return PackageManager.INSTALL_FAILED_INVALID_URI; 7139 } 7140 if (!pkgSetting.getInstalled(userId)) { 7141 pkgSetting.setInstalled(true, userId); 7142 pkgSetting.setBlocked(false, userId); 7143 mSettings.writePackageRestrictionsLPr(userId); 7144 sendAdded = true; 7145 } 7146 } 7147 7148 if (sendAdded) { 7149 sendPackageAddedForUser(packageName, pkgSetting, userId); 7150 } 7151 } finally { 7152 Binder.restoreCallingIdentity(callingId); 7153 } 7154 7155 return PackageManager.INSTALL_SUCCEEDED; 7156 } 7157 7158 private boolean isUserRestricted(int userId, String restrictionKey) { 7159 Bundle restrictions = sUserManager.getUserRestrictions(userId); 7160 if (restrictions.getBoolean(restrictionKey, false)) { 7161 Log.w(TAG, "User is restricted: " + restrictionKey); 7162 return true; 7163 } 7164 return false; 7165 } 7166 7167 @Override 7168 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 7169 mContext.enforceCallingOrSelfPermission( 7170 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 7171 "Only package verification agents can verify applications"); 7172 7173 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 7174 final PackageVerificationResponse response = new PackageVerificationResponse( 7175 verificationCode, Binder.getCallingUid()); 7176 msg.arg1 = id; 7177 msg.obj = response; 7178 mHandler.sendMessage(msg); 7179 } 7180 7181 @Override 7182 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 7183 long millisecondsToDelay) { 7184 mContext.enforceCallingOrSelfPermission( 7185 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 7186 "Only package verification agents can extend verification timeouts"); 7187 7188 final PackageVerificationState state = mPendingVerification.get(id); 7189 final PackageVerificationResponse response = new PackageVerificationResponse( 7190 verificationCodeAtTimeout, Binder.getCallingUid()); 7191 7192 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 7193 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 7194 } 7195 if (millisecondsToDelay < 0) { 7196 millisecondsToDelay = 0; 7197 } 7198 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 7199 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 7200 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 7201 } 7202 7203 if ((state != null) && !state.timeoutExtended()) { 7204 state.extendTimeout(); 7205 7206 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 7207 msg.arg1 = id; 7208 msg.obj = response; 7209 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 7210 } 7211 } 7212 7213 private void broadcastPackageVerified(int verificationId, Uri packageUri, 7214 int verificationCode, UserHandle user) { 7215 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 7216 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 7217 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 7218 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 7219 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 7220 7221 mContext.sendBroadcastAsUser(intent, user, 7222 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 7223 } 7224 7225 private ComponentName matchComponentForVerifier(String packageName, 7226 List<ResolveInfo> receivers) { 7227 ActivityInfo targetReceiver = null; 7228 7229 final int NR = receivers.size(); 7230 for (int i = 0; i < NR; i++) { 7231 final ResolveInfo info = receivers.get(i); 7232 if (info.activityInfo == null) { 7233 continue; 7234 } 7235 7236 if (packageName.equals(info.activityInfo.packageName)) { 7237 targetReceiver = info.activityInfo; 7238 break; 7239 } 7240 } 7241 7242 if (targetReceiver == null) { 7243 return null; 7244 } 7245 7246 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 7247 } 7248 7249 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 7250 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 7251 if (pkgInfo.verifiers.length == 0) { 7252 return null; 7253 } 7254 7255 final int N = pkgInfo.verifiers.length; 7256 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 7257 for (int i = 0; i < N; i++) { 7258 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 7259 7260 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 7261 receivers); 7262 if (comp == null) { 7263 continue; 7264 } 7265 7266 final int verifierUid = getUidForVerifier(verifierInfo); 7267 if (verifierUid == -1) { 7268 continue; 7269 } 7270 7271 if (DEBUG_VERIFY) { 7272 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 7273 + " with the correct signature"); 7274 } 7275 sufficientVerifiers.add(comp); 7276 verificationState.addSufficientVerifier(verifierUid); 7277 } 7278 7279 return sufficientVerifiers; 7280 } 7281 7282 private int getUidForVerifier(VerifierInfo verifierInfo) { 7283 synchronized (mPackages) { 7284 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 7285 if (pkg == null) { 7286 return -1; 7287 } else if (pkg.mSignatures.length != 1) { 7288 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 7289 + " has more than one signature; ignoring"); 7290 return -1; 7291 } 7292 7293 /* 7294 * If the public key of the package's signature does not match 7295 * our expected public key, then this is a different package and 7296 * we should skip. 7297 */ 7298 7299 final byte[] expectedPublicKey; 7300 try { 7301 final Signature verifierSig = pkg.mSignatures[0]; 7302 final PublicKey publicKey = verifierSig.getPublicKey(); 7303 expectedPublicKey = publicKey.getEncoded(); 7304 } catch (CertificateException e) { 7305 return -1; 7306 } 7307 7308 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 7309 7310 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 7311 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 7312 + " does not have the expected public key; ignoring"); 7313 return -1; 7314 } 7315 7316 return pkg.applicationInfo.uid; 7317 } 7318 } 7319 7320 public void finishPackageInstall(int token) { 7321 enforceSystemOrRoot("Only the system is allowed to finish installs"); 7322 7323 if (DEBUG_INSTALL) { 7324 Slog.v(TAG, "BM finishing package install for " + token); 7325 } 7326 7327 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 7328 mHandler.sendMessage(msg); 7329 } 7330 7331 /** 7332 * Get the verification agent timeout. 7333 * 7334 * @return verification timeout in milliseconds 7335 */ 7336 private long getVerificationTimeout() { 7337 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 7338 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 7339 DEFAULT_VERIFICATION_TIMEOUT); 7340 } 7341 7342 /** 7343 * Get the default verification agent response code. 7344 * 7345 * @return default verification response code 7346 */ 7347 private int getDefaultVerificationResponse() { 7348 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 7349 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 7350 DEFAULT_VERIFICATION_RESPONSE); 7351 } 7352 7353 /** 7354 * Check whether or not package verification has been enabled. 7355 * 7356 * @return true if verification should be performed 7357 */ 7358 private boolean isVerificationEnabled(int flags) { 7359 if (!DEFAULT_VERIFY_ENABLE) { 7360 return false; 7361 } 7362 7363 // Check if installing from ADB 7364 if ((flags & PackageManager.INSTALL_FROM_ADB) != 0) { 7365 // Do not run verification in a test harness environment 7366 if (ActivityManager.isRunningInTestHarness()) { 7367 return false; 7368 } 7369 // Check if the developer does not want package verification for ADB installs 7370 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 7371 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 7372 return false; 7373 } 7374 } 7375 7376 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 7377 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 7378 } 7379 7380 /** 7381 * Get the "allow unknown sources" setting. 7382 * 7383 * @return the current "allow unknown sources" setting 7384 */ 7385 private int getUnknownSourcesSettings() { 7386 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 7387 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 7388 -1); 7389 } 7390 7391 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 7392 final int uid = Binder.getCallingUid(); 7393 // writer 7394 synchronized (mPackages) { 7395 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 7396 if (targetPackageSetting == null) { 7397 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 7398 } 7399 7400 PackageSetting installerPackageSetting; 7401 if (installerPackageName != null) { 7402 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 7403 if (installerPackageSetting == null) { 7404 throw new IllegalArgumentException("Unknown installer package: " 7405 + installerPackageName); 7406 } 7407 } else { 7408 installerPackageSetting = null; 7409 } 7410 7411 Signature[] callerSignature; 7412 Object obj = mSettings.getUserIdLPr(uid); 7413 if (obj != null) { 7414 if (obj instanceof SharedUserSetting) { 7415 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 7416 } else if (obj instanceof PackageSetting) { 7417 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 7418 } else { 7419 throw new SecurityException("Bad object " + obj + " for uid " + uid); 7420 } 7421 } else { 7422 throw new SecurityException("Unknown calling uid " + uid); 7423 } 7424 7425 // Verify: can't set installerPackageName to a package that is 7426 // not signed with the same cert as the caller. 7427 if (installerPackageSetting != null) { 7428 if (compareSignatures(callerSignature, 7429 installerPackageSetting.signatures.mSignatures) 7430 != PackageManager.SIGNATURE_MATCH) { 7431 throw new SecurityException( 7432 "Caller does not have same cert as new installer package " 7433 + installerPackageName); 7434 } 7435 } 7436 7437 // Verify: if target already has an installer package, it must 7438 // be signed with the same cert as the caller. 7439 if (targetPackageSetting.installerPackageName != null) { 7440 PackageSetting setting = mSettings.mPackages.get( 7441 targetPackageSetting.installerPackageName); 7442 // If the currently set package isn't valid, then it's always 7443 // okay to change it. 7444 if (setting != null) { 7445 if (compareSignatures(callerSignature, 7446 setting.signatures.mSignatures) 7447 != PackageManager.SIGNATURE_MATCH) { 7448 throw new SecurityException( 7449 "Caller does not have same cert as old installer package " 7450 + targetPackageSetting.installerPackageName); 7451 } 7452 } 7453 } 7454 7455 // Okay! 7456 targetPackageSetting.installerPackageName = installerPackageName; 7457 scheduleWriteSettingsLocked(); 7458 } 7459 } 7460 7461 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 7462 // Queue up an async operation since the package installation may take a little while. 7463 mHandler.post(new Runnable() { 7464 public void run() { 7465 mHandler.removeCallbacks(this); 7466 // Result object to be returned 7467 PackageInstalledInfo res = new PackageInstalledInfo(); 7468 res.returnCode = currentStatus; 7469 res.uid = -1; 7470 res.pkg = null; 7471 res.removedInfo = new PackageRemovedInfo(); 7472 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 7473 args.doPreInstall(res.returnCode); 7474 synchronized (mInstallLock) { 7475 installPackageLI(args, true, res); 7476 } 7477 args.doPostInstall(res.returnCode, res.uid); 7478 } 7479 7480 // A restore should be performed at this point if (a) the install 7481 // succeeded, (b) the operation is not an update, and (c) the new 7482 // package has a backupAgent defined. 7483 final boolean update = res.removedInfo.removedPackage != null; 7484 boolean doRestore = (!update 7485 && res.pkg != null 7486 && res.pkg.applicationInfo.backupAgentName != null); 7487 7488 // Set up the post-install work request bookkeeping. This will be used 7489 // and cleaned up by the post-install event handling regardless of whether 7490 // there's a restore pass performed. Token values are >= 1. 7491 int token; 7492 if (mNextInstallToken < 0) mNextInstallToken = 1; 7493 token = mNextInstallToken++; 7494 7495 PostInstallData data = new PostInstallData(args, res); 7496 mRunningInstalls.put(token, data); 7497 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 7498 7499 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 7500 // Pass responsibility to the Backup Manager. It will perform a 7501 // restore if appropriate, then pass responsibility back to the 7502 // Package Manager to run the post-install observer callbacks 7503 // and broadcasts. 7504 IBackupManager bm = IBackupManager.Stub.asInterface( 7505 ServiceManager.getService(Context.BACKUP_SERVICE)); 7506 if (bm != null) { 7507 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 7508 + " to BM for possible restore"); 7509 try { 7510 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 7511 } catch (RemoteException e) { 7512 // can't happen; the backup manager is local 7513 } catch (Exception e) { 7514 Slog.e(TAG, "Exception trying to enqueue restore", e); 7515 doRestore = false; 7516 } 7517 } else { 7518 Slog.e(TAG, "Backup Manager not found!"); 7519 doRestore = false; 7520 } 7521 } 7522 7523 if (!doRestore) { 7524 // No restore possible, or the Backup Manager was mysteriously not 7525 // available -- just fire the post-install work request directly. 7526 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 7527 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 7528 mHandler.sendMessage(msg); 7529 } 7530 } 7531 }); 7532 } 7533 7534 private abstract class HandlerParams { 7535 private static final int MAX_RETRIES = 4; 7536 7537 /** 7538 * Number of times startCopy() has been attempted and had a non-fatal 7539 * error. 7540 */ 7541 private int mRetries = 0; 7542 7543 /** User handle for the user requesting the information or installation. */ 7544 private final UserHandle mUser; 7545 7546 HandlerParams(UserHandle user) { 7547 mUser = user; 7548 } 7549 7550 UserHandle getUser() { 7551 return mUser; 7552 } 7553 7554 final boolean startCopy() { 7555 boolean res; 7556 try { 7557 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 7558 7559 if (++mRetries > MAX_RETRIES) { 7560 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 7561 mHandler.sendEmptyMessage(MCS_GIVE_UP); 7562 handleServiceError(); 7563 return false; 7564 } else { 7565 handleStartCopy(); 7566 res = true; 7567 } 7568 } catch (RemoteException e) { 7569 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 7570 mHandler.sendEmptyMessage(MCS_RECONNECT); 7571 res = false; 7572 } 7573 handleReturnCode(); 7574 return res; 7575 } 7576 7577 final void serviceError() { 7578 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 7579 handleServiceError(); 7580 handleReturnCode(); 7581 } 7582 7583 abstract void handleStartCopy() throws RemoteException; 7584 abstract void handleServiceError(); 7585 abstract void handleReturnCode(); 7586 } 7587 7588 class MeasureParams extends HandlerParams { 7589 private final PackageStats mStats; 7590 private boolean mSuccess; 7591 7592 private final IPackageStatsObserver mObserver; 7593 7594 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 7595 super(new UserHandle(stats.userHandle)); 7596 mObserver = observer; 7597 mStats = stats; 7598 } 7599 7600 @Override 7601 public String toString() { 7602 return "MeasureParams{" 7603 + Integer.toHexString(System.identityHashCode(this)) 7604 + " " + mStats.packageName + "}"; 7605 } 7606 7607 @Override 7608 void handleStartCopy() throws RemoteException { 7609 synchronized (mInstallLock) { 7610 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 7611 } 7612 7613 if (mSuccess) { 7614 final boolean mounted; 7615 if (Environment.isExternalStorageEmulated()) { 7616 mounted = true; 7617 } else { 7618 final String status = Environment.getExternalStorageState(); 7619 mounted = (Environment.MEDIA_MOUNTED.equals(status) 7620 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 7621 } 7622 7623 if (mounted) { 7624 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 7625 7626 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 7627 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 7628 7629 mStats.externalDataSize = calculateDirectorySize(mContainerService, 7630 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 7631 7632 // Always subtract cache size, since it's a subdirectory 7633 mStats.externalDataSize -= mStats.externalCacheSize; 7634 7635 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 7636 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 7637 7638 mStats.externalObbSize = calculateDirectorySize(mContainerService, 7639 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 7640 } 7641 } 7642 } 7643 7644 @Override 7645 void handleReturnCode() { 7646 if (mObserver != null) { 7647 try { 7648 mObserver.onGetStatsCompleted(mStats, mSuccess); 7649 } catch (RemoteException e) { 7650 Slog.i(TAG, "Observer no longer exists."); 7651 } 7652 } 7653 } 7654 7655 @Override 7656 void handleServiceError() { 7657 Slog.e(TAG, "Could not measure application " + mStats.packageName 7658 + " external storage"); 7659 } 7660 } 7661 7662 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 7663 throws RemoteException { 7664 long result = 0; 7665 for (File path : paths) { 7666 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 7667 } 7668 return result; 7669 } 7670 7671 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 7672 for (File path : paths) { 7673 try { 7674 mcs.clearDirectory(path.getAbsolutePath()); 7675 } catch (RemoteException e) { 7676 } 7677 } 7678 } 7679 7680 class InstallParams extends HandlerParams { 7681 final IPackageInstallObserver observer; 7682 final IPackageInstallObserver2 observer2; 7683 int flags; 7684 7685 private final Uri mPackageURI; 7686 final String installerPackageName; 7687 final VerificationParams verificationParams; 7688 private InstallArgs mArgs; 7689 private int mRet; 7690 private File mTempPackage; 7691 final ContainerEncryptionParams encryptionParams; 7692 7693 InstallParams(Uri packageURI, 7694 IPackageInstallObserver observer, IPackageInstallObserver2 observer2, 7695 int flags, String installerPackageName, VerificationParams verificationParams, 7696 ContainerEncryptionParams encryptionParams, UserHandle user) { 7697 super(user); 7698 this.mPackageURI = packageURI; 7699 this.flags = flags; 7700 this.observer = observer; 7701 this.observer2 = observer2; 7702 this.installerPackageName = installerPackageName; 7703 this.verificationParams = verificationParams; 7704 this.encryptionParams = encryptionParams; 7705 } 7706 7707 @Override 7708 public String toString() { 7709 return "InstallParams{" 7710 + Integer.toHexString(System.identityHashCode(this)) 7711 + " " + mPackageURI + "}"; 7712 } 7713 7714 public ManifestDigest getManifestDigest() { 7715 if (verificationParams == null) { 7716 return null; 7717 } 7718 return verificationParams.getManifestDigest(); 7719 } 7720 7721 private int installLocationPolicy(PackageInfoLite pkgLite, int flags) { 7722 String packageName = pkgLite.packageName; 7723 int installLocation = pkgLite.installLocation; 7724 boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 7725 // reader 7726 synchronized (mPackages) { 7727 PackageParser.Package pkg = mPackages.get(packageName); 7728 if (pkg != null) { 7729 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 7730 // Check for downgrading. 7731 if ((flags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0) { 7732 if (pkgLite.versionCode < pkg.mVersionCode) { 7733 Slog.w(TAG, "Can't install update of " + packageName 7734 + " update version " + pkgLite.versionCode 7735 + " is older than installed version " 7736 + pkg.mVersionCode); 7737 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 7738 } 7739 } 7740 // Check for updated system application. 7741 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 7742 if (onSd) { 7743 Slog.w(TAG, "Cannot install update to system app on sdcard"); 7744 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 7745 } 7746 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 7747 } else { 7748 if (onSd) { 7749 // Install flag overrides everything. 7750 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 7751 } 7752 // If current upgrade specifies particular preference 7753 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 7754 // Application explicitly specified internal. 7755 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 7756 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 7757 // App explictly prefers external. Let policy decide 7758 } else { 7759 // Prefer previous location 7760 if (isExternal(pkg)) { 7761 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 7762 } 7763 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 7764 } 7765 } 7766 } else { 7767 // Invalid install. Return error code 7768 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 7769 } 7770 } 7771 } 7772 // All the special cases have been taken care of. 7773 // Return result based on recommended install location. 7774 if (onSd) { 7775 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 7776 } 7777 return pkgLite.recommendedInstallLocation; 7778 } 7779 7780 private long getMemoryLowThreshold() { 7781 final DeviceStorageMonitorInternal 7782 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 7783 if (dsm == null) { 7784 return 0L; 7785 } 7786 return dsm.getMemoryLowThreshold(); 7787 } 7788 7789 /* 7790 * Invoke remote method to get package information and install 7791 * location values. Override install location based on default 7792 * policy if needed and then create install arguments based 7793 * on the install location. 7794 */ 7795 public void handleStartCopy() throws RemoteException { 7796 int ret = PackageManager.INSTALL_SUCCEEDED; 7797 final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 7798 final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0; 7799 PackageInfoLite pkgLite = null; 7800 7801 if (onInt && onSd) { 7802 // Check if both bits are set. 7803 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 7804 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 7805 } else { 7806 final long lowThreshold = getMemoryLowThreshold(); 7807 if (lowThreshold == 0L) { 7808 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 7809 } 7810 7811 try { 7812 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, mPackageURI, 7813 Intent.FLAG_GRANT_READ_URI_PERMISSION); 7814 7815 final File packageFile; 7816 if (encryptionParams != null || !"file".equals(mPackageURI.getScheme())) { 7817 mTempPackage = createTempPackageFile(mDrmAppPrivateInstallDir); 7818 if (mTempPackage != null) { 7819 ParcelFileDescriptor out; 7820 try { 7821 out = ParcelFileDescriptor.open(mTempPackage, 7822 ParcelFileDescriptor.MODE_READ_WRITE); 7823 } catch (FileNotFoundException e) { 7824 out = null; 7825 Slog.e(TAG, "Failed to create temporary file for : " + mPackageURI); 7826 } 7827 7828 // Make a temporary file for decryption. 7829 ret = mContainerService 7830 .copyResource(mPackageURI, encryptionParams, out); 7831 IoUtils.closeQuietly(out); 7832 7833 packageFile = mTempPackage; 7834 7835 FileUtils.setPermissions(packageFile.getAbsolutePath(), 7836 FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP 7837 | FileUtils.S_IROTH, 7838 -1, -1); 7839 } else { 7840 packageFile = null; 7841 } 7842 } else { 7843 packageFile = new File(mPackageURI.getPath()); 7844 } 7845 7846 if (packageFile != null) { 7847 // Remote call to find out default install location 7848 final String packageFilePath = packageFile.getAbsolutePath(); 7849 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags, 7850 lowThreshold); 7851 7852 /* 7853 * If we have too little free space, try to free cache 7854 * before giving up. 7855 */ 7856 if (pkgLite.recommendedInstallLocation 7857 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 7858 final long size = mContainerService.calculateInstalledSize( 7859 packageFilePath, isForwardLocked()); 7860 if (mInstaller.freeCache(size + lowThreshold) >= 0) { 7861 pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, 7862 flags, lowThreshold); 7863 } 7864 /* 7865 * The cache free must have deleted the file we 7866 * downloaded to install. 7867 * 7868 * TODO: fix the "freeCache" call to not delete 7869 * the file we care about. 7870 */ 7871 if (pkgLite.recommendedInstallLocation 7872 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 7873 pkgLite.recommendedInstallLocation 7874 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 7875 } 7876 } 7877 } 7878 } finally { 7879 mContext.revokeUriPermission(mPackageURI, 7880 Intent.FLAG_GRANT_READ_URI_PERMISSION); 7881 } 7882 } 7883 7884 if (ret == PackageManager.INSTALL_SUCCEEDED) { 7885 int loc = pkgLite.recommendedInstallLocation; 7886 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 7887 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 7888 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 7889 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 7890 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 7891 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 7892 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 7893 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 7894 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 7895 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 7896 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 7897 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 7898 } else { 7899 // Override with defaults if needed. 7900 loc = installLocationPolicy(pkgLite, flags); 7901 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 7902 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 7903 } else if (!onSd && !onInt) { 7904 // Override install location with flags 7905 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 7906 // Set the flag to install on external media. 7907 flags |= PackageManager.INSTALL_EXTERNAL; 7908 flags &= ~PackageManager.INSTALL_INTERNAL; 7909 } else { 7910 // Make sure the flag for installing on external 7911 // media is unset 7912 flags |= PackageManager.INSTALL_INTERNAL; 7913 flags &= ~PackageManager.INSTALL_EXTERNAL; 7914 } 7915 } 7916 } 7917 } 7918 7919 final InstallArgs args = createInstallArgs(this); 7920 mArgs = args; 7921 7922 if (ret == PackageManager.INSTALL_SUCCEEDED) { 7923 /* 7924 * ADB installs appear as UserHandle.USER_ALL, and can only be performed by 7925 * UserHandle.USER_OWNER, so use the package verifier for UserHandle.USER_OWNER. 7926 */ 7927 int userIdentifier = getUser().getIdentifier(); 7928 if (userIdentifier == UserHandle.USER_ALL 7929 && ((flags & PackageManager.INSTALL_FROM_ADB) != 0)) { 7930 userIdentifier = UserHandle.USER_OWNER; 7931 } 7932 7933 /* 7934 * Determine if we have any installed package verifiers. If we 7935 * do, then we'll defer to them to verify the packages. 7936 */ 7937 final int requiredUid = mRequiredVerifierPackage == null ? -1 7938 : getPackageUid(mRequiredVerifierPackage, userIdentifier); 7939 if (requiredUid != -1 && isVerificationEnabled(flags)) { 7940 final Intent verification = new Intent( 7941 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 7942 verification.setDataAndType(getPackageUri(), PACKAGE_MIME_TYPE); 7943 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 7944 7945 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 7946 PACKAGE_MIME_TYPE, PackageManager.GET_DISABLED_COMPONENTS, 7947 0 /* TODO: Which userId? */); 7948 7949 if (DEBUG_VERIFY) { 7950 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 7951 + verification.toString() + " with " + pkgLite.verifiers.length 7952 + " optional verifiers"); 7953 } 7954 7955 final int verificationId = mPendingVerificationToken++; 7956 7957 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 7958 7959 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 7960 installerPackageName); 7961 7962 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags); 7963 7964 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 7965 pkgLite.packageName); 7966 7967 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 7968 pkgLite.versionCode); 7969 7970 if (verificationParams != null) { 7971 if (verificationParams.getVerificationURI() != null) { 7972 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 7973 verificationParams.getVerificationURI()); 7974 } 7975 if (verificationParams.getOriginatingURI() != null) { 7976 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 7977 verificationParams.getOriginatingURI()); 7978 } 7979 if (verificationParams.getReferrer() != null) { 7980 verification.putExtra(Intent.EXTRA_REFERRER, 7981 verificationParams.getReferrer()); 7982 } 7983 if (verificationParams.getOriginatingUid() >= 0) { 7984 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 7985 verificationParams.getOriginatingUid()); 7986 } 7987 if (verificationParams.getInstallerUid() >= 0) { 7988 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 7989 verificationParams.getInstallerUid()); 7990 } 7991 } 7992 7993 final PackageVerificationState verificationState = new PackageVerificationState( 7994 requiredUid, args); 7995 7996 mPendingVerification.append(verificationId, verificationState); 7997 7998 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 7999 receivers, verificationState); 8000 8001 /* 8002 * If any sufficient verifiers were listed in the package 8003 * manifest, attempt to ask them. 8004 */ 8005 if (sufficientVerifiers != null) { 8006 final int N = sufficientVerifiers.size(); 8007 if (N == 0) { 8008 Slog.i(TAG, "Additional verifiers required, but none installed."); 8009 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 8010 } else { 8011 for (int i = 0; i < N; i++) { 8012 final ComponentName verifierComponent = sufficientVerifiers.get(i); 8013 8014 final Intent sufficientIntent = new Intent(verification); 8015 sufficientIntent.setComponent(verifierComponent); 8016 8017 mContext.sendBroadcastAsUser(sufficientIntent, getUser()); 8018 } 8019 } 8020 } 8021 8022 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 8023 mRequiredVerifierPackage, receivers); 8024 if (ret == PackageManager.INSTALL_SUCCEEDED 8025 && mRequiredVerifierPackage != null) { 8026 /* 8027 * Send the intent to the required verification agent, 8028 * but only start the verification timeout after the 8029 * target BroadcastReceivers have run. 8030 */ 8031 verification.setComponent(requiredVerifierComponent); 8032 mContext.sendOrderedBroadcastAsUser(verification, getUser(), 8033 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8034 new BroadcastReceiver() { 8035 @Override 8036 public void onReceive(Context context, Intent intent) { 8037 final Message msg = mHandler 8038 .obtainMessage(CHECK_PENDING_VERIFICATION); 8039 msg.arg1 = verificationId; 8040 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 8041 } 8042 }, null, 0, null, null); 8043 8044 /* 8045 * We don't want the copy to proceed until verification 8046 * succeeds, so null out this field. 8047 */ 8048 mArgs = null; 8049 } 8050 } else { 8051 /* 8052 * No package verification is enabled, so immediately start 8053 * the remote call to initiate copy using temporary file. 8054 */ 8055 ret = args.copyApk(mContainerService, true); 8056 } 8057 } 8058 8059 mRet = ret; 8060 } 8061 8062 @Override 8063 void handleReturnCode() { 8064 // If mArgs is null, then MCS couldn't be reached. When it 8065 // reconnects, it will try again to install. At that point, this 8066 // will succeed. 8067 if (mArgs != null) { 8068 processPendingInstall(mArgs, mRet); 8069 8070 if (mTempPackage != null) { 8071 if (!mTempPackage.delete()) { 8072 Slog.w(TAG, "Couldn't delete temporary file: " + 8073 mTempPackage.getAbsolutePath()); 8074 } 8075 } 8076 } 8077 } 8078 8079 @Override 8080 void handleServiceError() { 8081 mArgs = createInstallArgs(this); 8082 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 8083 } 8084 8085 public boolean isForwardLocked() { 8086 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 8087 } 8088 8089 public Uri getPackageUri() { 8090 if (mTempPackage != null) { 8091 return Uri.fromFile(mTempPackage); 8092 } else { 8093 return mPackageURI; 8094 } 8095 } 8096 } 8097 8098 /* 8099 * Utility class used in movePackage api. 8100 * srcArgs and targetArgs are not set for invalid flags and make 8101 * sure to do null checks when invoking methods on them. 8102 * We probably want to return ErrorPrams for both failed installs 8103 * and moves. 8104 */ 8105 class MoveParams extends HandlerParams { 8106 final IPackageMoveObserver observer; 8107 final int flags; 8108 final String packageName; 8109 final InstallArgs srcArgs; 8110 final InstallArgs targetArgs; 8111 int uid; 8112 int mRet; 8113 8114 MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, 8115 String packageName, String dataDir, int uid, UserHandle user) { 8116 super(user); 8117 this.srcArgs = srcArgs; 8118 this.observer = observer; 8119 this.flags = flags; 8120 this.packageName = packageName; 8121 this.uid = uid; 8122 if (srcArgs != null) { 8123 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath())); 8124 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir); 8125 } else { 8126 targetArgs = null; 8127 } 8128 } 8129 8130 @Override 8131 public String toString() { 8132 return "MoveParams{" 8133 + Integer.toHexString(System.identityHashCode(this)) 8134 + " " + packageName + "}"; 8135 } 8136 8137 public void handleStartCopy() throws RemoteException { 8138 mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8139 // Check for storage space on target medium 8140 if (!targetArgs.checkFreeStorage(mContainerService)) { 8141 Log.w(TAG, "Insufficient storage to install"); 8142 return; 8143 } 8144 8145 mRet = srcArgs.doPreCopy(); 8146 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8147 return; 8148 } 8149 8150 mRet = targetArgs.copyApk(mContainerService, false); 8151 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8152 srcArgs.doPostCopy(uid); 8153 return; 8154 } 8155 8156 mRet = srcArgs.doPostCopy(uid); 8157 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8158 return; 8159 } 8160 8161 mRet = targetArgs.doPreInstall(mRet); 8162 if (mRet != PackageManager.INSTALL_SUCCEEDED) { 8163 return; 8164 } 8165 8166 if (DEBUG_SD_INSTALL) { 8167 StringBuilder builder = new StringBuilder(); 8168 if (srcArgs != null) { 8169 builder.append("src: "); 8170 builder.append(srcArgs.getCodePath()); 8171 } 8172 if (targetArgs != null) { 8173 builder.append(" target : "); 8174 builder.append(targetArgs.getCodePath()); 8175 } 8176 Log.i(TAG, builder.toString()); 8177 } 8178 } 8179 8180 @Override 8181 void handleReturnCode() { 8182 targetArgs.doPostInstall(mRet, uid); 8183 int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 8184 if (mRet == PackageManager.INSTALL_SUCCEEDED) { 8185 currentStatus = PackageManager.MOVE_SUCCEEDED; 8186 } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){ 8187 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 8188 } 8189 processPendingMove(this, currentStatus); 8190 } 8191 8192 @Override 8193 void handleServiceError() { 8194 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 8195 } 8196 } 8197 8198 /** 8199 * Used during creation of InstallArgs 8200 * 8201 * @param flags package installation flags 8202 * @return true if should be installed on external storage 8203 */ 8204 private static boolean installOnSd(int flags) { 8205 if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { 8206 return false; 8207 } 8208 if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { 8209 return true; 8210 } 8211 return false; 8212 } 8213 8214 /** 8215 * Used during creation of InstallArgs 8216 * 8217 * @param flags package installation flags 8218 * @return true if should be installed as forward locked 8219 */ 8220 private static boolean installForwardLocked(int flags) { 8221 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 8222 } 8223 8224 private InstallArgs createInstallArgs(InstallParams params) { 8225 if (installOnSd(params.flags) || params.isForwardLocked()) { 8226 return new AsecInstallArgs(params); 8227 } else { 8228 return new FileInstallArgs(params); 8229 } 8230 } 8231 8232 private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath, 8233 String nativeLibraryPath) { 8234 final boolean isInAsec; 8235 if (installOnSd(flags)) { 8236 /* Apps on SD card are always in ASEC containers. */ 8237 isInAsec = true; 8238 } else if (installForwardLocked(flags) 8239 && !fullCodePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 8240 /* 8241 * Forward-locked apps are only in ASEC containers if they're the 8242 * new style 8243 */ 8244 isInAsec = true; 8245 } else { 8246 isInAsec = false; 8247 } 8248 8249 if (isInAsec) { 8250 return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath, 8251 installOnSd(flags), installForwardLocked(flags)); 8252 } else { 8253 return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); 8254 } 8255 } 8256 8257 // Used by package mover 8258 private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) { 8259 if (installOnSd(flags) || installForwardLocked(flags)) { 8260 String cid = getNextCodePath(packageURI.getPath(), pkgName, "/" 8261 + AsecInstallArgs.RES_FILE_NAME); 8262 return new AsecInstallArgs(packageURI, cid, installOnSd(flags), 8263 installForwardLocked(flags)); 8264 } else { 8265 return new FileInstallArgs(packageURI, pkgName, dataDir); 8266 } 8267 } 8268 8269 static abstract class InstallArgs { 8270 final IPackageInstallObserver observer; 8271 final IPackageInstallObserver2 observer2; 8272 // Always refers to PackageManager flags only 8273 final int flags; 8274 final Uri packageURI; 8275 final String installerPackageName; 8276 final ManifestDigest manifestDigest; 8277 final UserHandle user; 8278 8279 InstallArgs(Uri packageURI, 8280 IPackageInstallObserver observer, IPackageInstallObserver2 observer2, 8281 int flags, String installerPackageName, ManifestDigest manifestDigest, 8282 UserHandle user) { 8283 this.packageURI = packageURI; 8284 this.flags = flags; 8285 this.observer = observer; 8286 this.observer2 = observer2; 8287 this.installerPackageName = installerPackageName; 8288 this.manifestDigest = manifestDigest; 8289 this.user = user; 8290 } 8291 8292 abstract void createCopyFile(); 8293 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 8294 abstract int doPreInstall(int status); 8295 abstract boolean doRename(int status, String pkgName, String oldCodePath); 8296 8297 abstract int doPostInstall(int status, int uid); 8298 abstract String getCodePath(); 8299 abstract String getResourcePath(); 8300 abstract String getNativeLibraryPath(); 8301 // Need installer lock especially for dex file removal. 8302 abstract void cleanUpResourcesLI(); 8303 abstract boolean doPostDeleteLI(boolean delete); 8304 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 8305 8306 /** 8307 * Called before the source arguments are copied. This is used mostly 8308 * for MoveParams when it needs to read the source file to put it in the 8309 * destination. 8310 */ 8311 int doPreCopy() { 8312 return PackageManager.INSTALL_SUCCEEDED; 8313 } 8314 8315 /** 8316 * Called after the source arguments are copied. This is used mostly for 8317 * MoveParams when it needs to read the source file to put it in the 8318 * destination. 8319 * 8320 * @return 8321 */ 8322 int doPostCopy(int uid) { 8323 return PackageManager.INSTALL_SUCCEEDED; 8324 } 8325 8326 protected boolean isFwdLocked() { 8327 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 8328 } 8329 8330 UserHandle getUser() { 8331 return user; 8332 } 8333 } 8334 8335 class FileInstallArgs extends InstallArgs { 8336 File installDir; 8337 String codeFileName; 8338 String resourceFileName; 8339 String libraryPath; 8340 boolean created = false; 8341 8342 FileInstallArgs(InstallParams params) { 8343 super(params.getPackageUri(), params.observer, params.observer2, params.flags, 8344 params.installerPackageName, params.getManifestDigest(), 8345 params.getUser()); 8346 } 8347 8348 FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) { 8349 super(null, null, null, 0, null, null, null); 8350 File codeFile = new File(fullCodePath); 8351 installDir = codeFile.getParentFile(); 8352 codeFileName = fullCodePath; 8353 resourceFileName = fullResourcePath; 8354 libraryPath = nativeLibraryPath; 8355 } 8356 8357 FileInstallArgs(Uri packageURI, String pkgName, String dataDir) { 8358 super(packageURI, null, null, 0, null, null, null); 8359 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 8360 String apkName = getNextCodePath(null, pkgName, ".apk"); 8361 codeFileName = new File(installDir, apkName + ".apk").getPath(); 8362 resourceFileName = getResourcePathFromCodePath(); 8363 libraryPath = new File(mAppLibInstallDir, pkgName).getPath(); 8364 } 8365 8366 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 8367 final long lowThreshold; 8368 8369 final DeviceStorageMonitorInternal 8370 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 8371 if (dsm == null) { 8372 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 8373 lowThreshold = 0L; 8374 } else { 8375 if (dsm.isMemoryLow()) { 8376 Log.w(TAG, "Memory is reported as being too low; aborting package install"); 8377 return false; 8378 } 8379 8380 lowThreshold = dsm.getMemoryLowThreshold(); 8381 } 8382 8383 try { 8384 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 8385 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8386 return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold); 8387 } finally { 8388 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 8389 } 8390 } 8391 8392 String getCodePath() { 8393 return codeFileName; 8394 } 8395 8396 void createCopyFile() { 8397 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 8398 codeFileName = createTempPackageFile(installDir).getPath(); 8399 resourceFileName = getResourcePathFromCodePath(); 8400 libraryPath = getLibraryPathFromCodePath(); 8401 created = true; 8402 } 8403 8404 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 8405 if (temp) { 8406 // Generate temp file name 8407 createCopyFile(); 8408 } 8409 // Get a ParcelFileDescriptor to write to the output file 8410 File codeFile = new File(codeFileName); 8411 if (!created) { 8412 try { 8413 codeFile.createNewFile(); 8414 // Set permissions 8415 if (!setPermissions()) { 8416 // Failed setting permissions. 8417 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8418 } 8419 } catch (IOException e) { 8420 Slog.w(TAG, "Failed to create file " + codeFile); 8421 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8422 } 8423 } 8424 ParcelFileDescriptor out = null; 8425 try { 8426 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE); 8427 } catch (FileNotFoundException e) { 8428 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName); 8429 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8430 } 8431 // Copy the resource now 8432 int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8433 try { 8434 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 8435 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8436 ret = imcs.copyResource(packageURI, null, out); 8437 } finally { 8438 IoUtils.closeQuietly(out); 8439 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 8440 } 8441 8442 if (isFwdLocked()) { 8443 final File destResourceFile = new File(getResourcePath()); 8444 8445 // Copy the public files 8446 try { 8447 PackageHelper.extractPublicFiles(codeFileName, destResourceFile); 8448 } catch (IOException e) { 8449 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" 8450 + " forward-locked app."); 8451 destResourceFile.delete(); 8452 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 8453 } 8454 } 8455 8456 final File nativeLibraryFile = new File(getNativeLibraryPath()); 8457 Slog.i(TAG, "Copying native libraries to " + nativeLibraryFile.getPath()); 8458 if (nativeLibraryFile.exists()) { 8459 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile); 8460 nativeLibraryFile.delete(); 8461 } 8462 try { 8463 int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile); 8464 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 8465 return copyRet; 8466 } 8467 } catch (IOException e) { 8468 Slog.e(TAG, "Copying native libraries failed", e); 8469 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 8470 } 8471 8472 return ret; 8473 } 8474 8475 int doPreInstall(int status) { 8476 if (status != PackageManager.INSTALL_SUCCEEDED) { 8477 cleanUp(); 8478 } 8479 return status; 8480 } 8481 8482 boolean doRename(int status, final String pkgName, String oldCodePath) { 8483 if (status != PackageManager.INSTALL_SUCCEEDED) { 8484 cleanUp(); 8485 return false; 8486 } else { 8487 final File oldCodeFile = new File(getCodePath()); 8488 final File oldResourceFile = new File(getResourcePath()); 8489 final File oldLibraryFile = new File(getNativeLibraryPath()); 8490 8491 // Rename APK file based on packageName 8492 final String apkName = getNextCodePath(oldCodePath, pkgName, ".apk"); 8493 final File newCodeFile = new File(installDir, apkName + ".apk"); 8494 if (!oldCodeFile.renameTo(newCodeFile)) { 8495 return false; 8496 } 8497 codeFileName = newCodeFile.getPath(); 8498 8499 // Rename public resource file if it's forward-locked. 8500 final File newResFile = new File(getResourcePathFromCodePath()); 8501 if (isFwdLocked() && !oldResourceFile.renameTo(newResFile)) { 8502 return false; 8503 } 8504 resourceFileName = newResFile.getPath(); 8505 8506 // Rename library path 8507 final File newLibraryFile = new File(getLibraryPathFromCodePath()); 8508 if (newLibraryFile.exists()) { 8509 NativeLibraryHelper.removeNativeBinariesFromDirLI(newLibraryFile); 8510 newLibraryFile.delete(); 8511 } 8512 if (!oldLibraryFile.renameTo(newLibraryFile)) { 8513 Slog.e(TAG, "Cannot rename native library directory " 8514 + oldLibraryFile.getPath() + " to " + newLibraryFile.getPath()); 8515 return false; 8516 } 8517 libraryPath = newLibraryFile.getPath(); 8518 8519 // Attempt to set permissions 8520 if (!setPermissions()) { 8521 return false; 8522 } 8523 8524 if (!SELinux.restorecon(newCodeFile)) { 8525 return false; 8526 } 8527 8528 return true; 8529 } 8530 } 8531 8532 int doPostInstall(int status, int uid) { 8533 if (status != PackageManager.INSTALL_SUCCEEDED) { 8534 cleanUp(); 8535 } 8536 return status; 8537 } 8538 8539 String getResourcePath() { 8540 return resourceFileName; 8541 } 8542 8543 private String getResourcePathFromCodePath() { 8544 final String codePath = getCodePath(); 8545 if (isFwdLocked()) { 8546 final StringBuilder sb = new StringBuilder(); 8547 8548 sb.append(mAppInstallDir.getPath()); 8549 sb.append('/'); 8550 sb.append(getApkName(codePath)); 8551 sb.append(".zip"); 8552 8553 /* 8554 * If our APK is a temporary file, mark the resource as a 8555 * temporary file as well so it can be cleaned up after 8556 * catastrophic failure. 8557 */ 8558 if (codePath.endsWith(".tmp")) { 8559 sb.append(".tmp"); 8560 } 8561 8562 return sb.toString(); 8563 } else { 8564 return codePath; 8565 } 8566 } 8567 8568 private String getLibraryPathFromCodePath() { 8569 return new File(mAppLibInstallDir, getApkName(getCodePath())).getPath(); 8570 } 8571 8572 @Override 8573 String getNativeLibraryPath() { 8574 if (libraryPath == null) { 8575 libraryPath = getLibraryPathFromCodePath(); 8576 } 8577 return libraryPath; 8578 } 8579 8580 private boolean cleanUp() { 8581 boolean ret = true; 8582 String sourceDir = getCodePath(); 8583 String publicSourceDir = getResourcePath(); 8584 if (sourceDir != null) { 8585 File sourceFile = new File(sourceDir); 8586 if (!sourceFile.exists()) { 8587 Slog.w(TAG, "Package source " + sourceDir + " does not exist."); 8588 ret = false; 8589 } 8590 // Delete application's code and resources 8591 sourceFile.delete(); 8592 } 8593 if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) { 8594 final File publicSourceFile = new File(publicSourceDir); 8595 if (!publicSourceFile.exists()) { 8596 Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist."); 8597 } 8598 if (publicSourceFile.exists()) { 8599 publicSourceFile.delete(); 8600 } 8601 } 8602 8603 if (libraryPath != null) { 8604 File nativeLibraryFile = new File(libraryPath); 8605 NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile); 8606 if (!nativeLibraryFile.delete()) { 8607 Slog.w(TAG, "Couldn't delete native library directory " + libraryPath); 8608 } 8609 } 8610 8611 return ret; 8612 } 8613 8614 void cleanUpResourcesLI() { 8615 String sourceDir = getCodePath(); 8616 if (cleanUp()) { 8617 int retCode = mInstaller.rmdex(sourceDir); 8618 if (retCode < 0) { 8619 Slog.w(TAG, "Couldn't remove dex file for package: " 8620 + " at location " 8621 + sourceDir + ", retcode=" + retCode); 8622 // we don't consider this to be a failure of the core package deletion 8623 } 8624 } 8625 } 8626 8627 private boolean setPermissions() { 8628 // TODO Do this in a more elegant way later on. for now just a hack 8629 if (!isFwdLocked()) { 8630 final int filePermissions = 8631 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP 8632 |FileUtils.S_IROTH; 8633 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1); 8634 if (retCode != 0) { 8635 Slog.e(TAG, "Couldn't set new package file permissions for " + 8636 getCodePath() 8637 + ". The return code was: " + retCode); 8638 // TODO Define new internal error 8639 return false; 8640 } 8641 return true; 8642 } 8643 return true; 8644 } 8645 8646 boolean doPostDeleteLI(boolean delete) { 8647 // XXX err, shouldn't we respect the delete flag? 8648 cleanUpResourcesLI(); 8649 return true; 8650 } 8651 } 8652 8653 private boolean isAsecExternal(String cid) { 8654 final String asecPath = PackageHelper.getSdFilesystem(cid); 8655 return !asecPath.startsWith(mAsecInternalPath); 8656 } 8657 8658 /** 8659 * Extract the MountService "container ID" from the full code path of an 8660 * .apk. 8661 */ 8662 static String cidFromCodePath(String fullCodePath) { 8663 int eidx = fullCodePath.lastIndexOf("/"); 8664 String subStr1 = fullCodePath.substring(0, eidx); 8665 int sidx = subStr1.lastIndexOf("/"); 8666 return subStr1.substring(sidx+1, eidx); 8667 } 8668 8669 class AsecInstallArgs extends InstallArgs { 8670 static final String RES_FILE_NAME = "pkg.apk"; 8671 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 8672 8673 String cid; 8674 String packagePath; 8675 String resourcePath; 8676 String libraryPath; 8677 8678 AsecInstallArgs(InstallParams params) { 8679 super(params.getPackageUri(), params.observer, params.observer2, params.flags, 8680 params.installerPackageName, params.getManifestDigest(), 8681 params.getUser()); 8682 } 8683 8684 AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, 8685 boolean isExternal, boolean isForwardLocked) { 8686 super(null, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0) 8687 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), 8688 null, null, null); 8689 // Extract cid from fullCodePath 8690 int eidx = fullCodePath.lastIndexOf("/"); 8691 String subStr1 = fullCodePath.substring(0, eidx); 8692 int sidx = subStr1.lastIndexOf("/"); 8693 cid = subStr1.substring(sidx+1, eidx); 8694 setCachePath(subStr1); 8695 } 8696 8697 AsecInstallArgs(String cid, boolean isForwardLocked) { 8698 super(null, null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0) 8699 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), 8700 null, null, null); 8701 this.cid = cid; 8702 setCachePath(PackageHelper.getSdDir(cid)); 8703 } 8704 8705 AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) { 8706 super(packageURI, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0) 8707 | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), 8708 null, null, null); 8709 this.cid = cid; 8710 } 8711 8712 void createCopyFile() { 8713 cid = getTempContainerId(); 8714 } 8715 8716 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 8717 try { 8718 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 8719 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8720 return imcs.checkExternalFreeStorage(packageURI, isFwdLocked()); 8721 } finally { 8722 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 8723 } 8724 } 8725 8726 private final boolean isExternal() { 8727 return (flags & PackageManager.INSTALL_EXTERNAL) != 0; 8728 } 8729 8730 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 8731 if (temp) { 8732 createCopyFile(); 8733 } else { 8734 /* 8735 * Pre-emptively destroy the container since it's destroyed if 8736 * copying fails due to it existing anyway. 8737 */ 8738 PackageHelper.destroySdDir(cid); 8739 } 8740 8741 final String newCachePath; 8742 try { 8743 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 8744 Intent.FLAG_GRANT_READ_URI_PERMISSION); 8745 newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(), 8746 RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked()); 8747 } finally { 8748 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 8749 } 8750 8751 if (newCachePath != null) { 8752 setCachePath(newCachePath); 8753 return PackageManager.INSTALL_SUCCEEDED; 8754 } else { 8755 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 8756 } 8757 } 8758 8759 @Override 8760 String getCodePath() { 8761 return packagePath; 8762 } 8763 8764 @Override 8765 String getResourcePath() { 8766 return resourcePath; 8767 } 8768 8769 @Override 8770 String getNativeLibraryPath() { 8771 return libraryPath; 8772 } 8773 8774 int doPreInstall(int status) { 8775 if (status != PackageManager.INSTALL_SUCCEEDED) { 8776 // Destroy container 8777 PackageHelper.destroySdDir(cid); 8778 } else { 8779 boolean mounted = PackageHelper.isContainerMounted(cid); 8780 if (!mounted) { 8781 String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(), 8782 Process.SYSTEM_UID); 8783 if (newCachePath != null) { 8784 setCachePath(newCachePath); 8785 } else { 8786 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 8787 } 8788 } 8789 } 8790 return status; 8791 } 8792 8793 boolean doRename(int status, final String pkgName, 8794 String oldCodePath) { 8795 String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME); 8796 String newCachePath = null; 8797 if (PackageHelper.isContainerMounted(cid)) { 8798 // Unmount the container 8799 if (!PackageHelper.unMountSdDir(cid)) { 8800 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 8801 return false; 8802 } 8803 } 8804 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 8805 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 8806 " which might be stale. Will try to clean up."); 8807 // Clean up the stale container and proceed to recreate. 8808 if (!PackageHelper.destroySdDir(newCacheId)) { 8809 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 8810 return false; 8811 } 8812 // Successfully cleaned up stale container. Try to rename again. 8813 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 8814 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 8815 + " inspite of cleaning it up."); 8816 return false; 8817 } 8818 } 8819 if (!PackageHelper.isContainerMounted(newCacheId)) { 8820 Slog.w(TAG, "Mounting container " + newCacheId); 8821 newCachePath = PackageHelper.mountSdDir(newCacheId, 8822 getEncryptKey(), Process.SYSTEM_UID); 8823 } else { 8824 newCachePath = PackageHelper.getSdDir(newCacheId); 8825 } 8826 if (newCachePath == null) { 8827 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 8828 return false; 8829 } 8830 Log.i(TAG, "Succesfully renamed " + cid + 8831 " to " + newCacheId + 8832 " at new path: " + newCachePath); 8833 cid = newCacheId; 8834 setCachePath(newCachePath); 8835 return true; 8836 } 8837 8838 private void setCachePath(String newCachePath) { 8839 File cachePath = new File(newCachePath); 8840 libraryPath = new File(cachePath, LIB_DIR_NAME).getPath(); 8841 packagePath = new File(cachePath, RES_FILE_NAME).getPath(); 8842 8843 if (isFwdLocked()) { 8844 resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath(); 8845 } else { 8846 resourcePath = packagePath; 8847 } 8848 } 8849 8850 int doPostInstall(int status, int uid) { 8851 if (status != PackageManager.INSTALL_SUCCEEDED) { 8852 cleanUp(); 8853 } else { 8854 final int groupOwner; 8855 final String protectedFile; 8856 if (isFwdLocked()) { 8857 groupOwner = UserHandle.getSharedAppGid(uid); 8858 protectedFile = RES_FILE_NAME; 8859 } else { 8860 groupOwner = -1; 8861 protectedFile = null; 8862 } 8863 8864 if (uid < Process.FIRST_APPLICATION_UID 8865 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 8866 Slog.e(TAG, "Failed to finalize " + cid); 8867 PackageHelper.destroySdDir(cid); 8868 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 8869 } 8870 8871 boolean mounted = PackageHelper.isContainerMounted(cid); 8872 if (!mounted) { 8873 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 8874 } 8875 } 8876 return status; 8877 } 8878 8879 private void cleanUp() { 8880 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 8881 8882 // Destroy secure container 8883 PackageHelper.destroySdDir(cid); 8884 } 8885 8886 void cleanUpResourcesLI() { 8887 String sourceFile = getCodePath(); 8888 // Remove dex file 8889 int retCode = mInstaller.rmdex(sourceFile); 8890 if (retCode < 0) { 8891 Slog.w(TAG, "Couldn't remove dex file for package: " 8892 + " at location " 8893 + sourceFile.toString() + ", retcode=" + retCode); 8894 // we don't consider this to be a failure of the core package deletion 8895 } 8896 cleanUp(); 8897 } 8898 8899 boolean matchContainer(String app) { 8900 if (cid.startsWith(app)) { 8901 return true; 8902 } 8903 return false; 8904 } 8905 8906 String getPackageName() { 8907 return getAsecPackageName(cid); 8908 } 8909 8910 boolean doPostDeleteLI(boolean delete) { 8911 boolean ret = false; 8912 boolean mounted = PackageHelper.isContainerMounted(cid); 8913 if (mounted) { 8914 // Unmount first 8915 ret = PackageHelper.unMountSdDir(cid); 8916 } 8917 if (ret && delete) { 8918 cleanUpResourcesLI(); 8919 } 8920 return ret; 8921 } 8922 8923 @Override 8924 int doPreCopy() { 8925 if (isFwdLocked()) { 8926 if (!PackageHelper.fixSdPermissions(cid, 8927 getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { 8928 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 8929 } 8930 } 8931 8932 return PackageManager.INSTALL_SUCCEEDED; 8933 } 8934 8935 @Override 8936 int doPostCopy(int uid) { 8937 if (isFwdLocked()) { 8938 if (uid < Process.FIRST_APPLICATION_UID 8939 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 8940 RES_FILE_NAME)) { 8941 Slog.e(TAG, "Failed to finalize " + cid); 8942 PackageHelper.destroySdDir(cid); 8943 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 8944 } 8945 } 8946 8947 return PackageManager.INSTALL_SUCCEEDED; 8948 } 8949 }; 8950 8951 static String getAsecPackageName(String packageCid) { 8952 int idx = packageCid.lastIndexOf("-"); 8953 if (idx == -1) { 8954 return packageCid; 8955 } 8956 return packageCid.substring(0, idx); 8957 } 8958 8959 // Utility method used to create code paths based on package name and available index. 8960 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 8961 String idxStr = ""; 8962 int idx = 1; 8963 // Fall back to default value of idx=1 if prefix is not 8964 // part of oldCodePath 8965 if (oldCodePath != null) { 8966 String subStr = oldCodePath; 8967 // Drop the suffix right away 8968 if (subStr.endsWith(suffix)) { 8969 subStr = subStr.substring(0, subStr.length() - suffix.length()); 8970 } 8971 // If oldCodePath already contains prefix find out the 8972 // ending index to either increment or decrement. 8973 int sidx = subStr.lastIndexOf(prefix); 8974 if (sidx != -1) { 8975 subStr = subStr.substring(sidx + prefix.length()); 8976 if (subStr != null) { 8977 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 8978 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 8979 } 8980 try { 8981 idx = Integer.parseInt(subStr); 8982 if (idx <= 1) { 8983 idx++; 8984 } else { 8985 idx--; 8986 } 8987 } catch(NumberFormatException e) { 8988 } 8989 } 8990 } 8991 } 8992 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 8993 return prefix + idxStr; 8994 } 8995 8996 // Utility method used to ignore ADD/REMOVE events 8997 // by directory observer. 8998 private static boolean ignoreCodePath(String fullPathStr) { 8999 String apkName = getApkName(fullPathStr); 9000 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX); 9001 if (idx != -1 && ((idx+1) < apkName.length())) { 9002 // Make sure the package ends with a numeral 9003 String version = apkName.substring(idx+1); 9004 try { 9005 Integer.parseInt(version); 9006 return true; 9007 } catch (NumberFormatException e) {} 9008 } 9009 return false; 9010 } 9011 9012 // Utility method that returns the relative package path with respect 9013 // to the installation directory. Like say for /data/data/com.test-1.apk 9014 // string com.test-1 is returned. 9015 static String getApkName(String codePath) { 9016 if (codePath == null) { 9017 return null; 9018 } 9019 int sidx = codePath.lastIndexOf("/"); 9020 int eidx = codePath.lastIndexOf("."); 9021 if (eidx == -1) { 9022 eidx = codePath.length(); 9023 } else if (eidx == 0) { 9024 Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name"); 9025 return null; 9026 } 9027 return codePath.substring(sidx+1, eidx); 9028 } 9029 9030 class PackageInstalledInfo { 9031 String name; 9032 int uid; 9033 // The set of users that originally had this package installed. 9034 int[] origUsers; 9035 // The set of users that now have this package installed. 9036 int[] newUsers; 9037 PackageParser.Package pkg; 9038 int returnCode; 9039 PackageRemovedInfo removedInfo; 9040 9041 // In some error cases we want to convey more info back to the observer 9042 String origPackage; 9043 String origPermission; 9044 } 9045 9046 /* 9047 * Install a non-existing package. 9048 */ 9049 private void installNewPackageLI(PackageParser.Package pkg, 9050 int parseFlags, int scanMode, UserHandle user, 9051 String installerPackageName, PackageInstalledInfo res) { 9052 // Remember this for later, in case we need to rollback this install 9053 String pkgName = pkg.packageName; 9054 9055 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 9056 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists(); 9057 synchronized(mPackages) { 9058 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 9059 // A package with the same name is already installed, though 9060 // it has been renamed to an older name. The package we 9061 // are trying to install should be installed as an update to 9062 // the existing one, but that has not been requested, so bail. 9063 Slog.w(TAG, "Attempt to re-install " + pkgName 9064 + " without first uninstalling package running as " 9065 + mSettings.mRenamedPackages.get(pkgName)); 9066 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 9067 return; 9068 } 9069 if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) { 9070 // Don't allow installation over an existing package with the same name. 9071 Slog.w(TAG, "Attempt to re-install " + pkgName 9072 + " without first uninstalling."); 9073 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 9074 return; 9075 } 9076 } 9077 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 9078 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode, 9079 System.currentTimeMillis(), user); 9080 if (newPackage == null) { 9081 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 9082 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 9083 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 9084 } 9085 } else { 9086 updateSettingsLI(newPackage, 9087 installerPackageName, 9088 null, null, 9089 res); 9090 // delete the partially installed application. the data directory will have to be 9091 // restored if it was already existing 9092 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 9093 // remove package from internal structures. Note that we want deletePackageX to 9094 // delete the package data and cache directories that it created in 9095 // scanPackageLocked, unless those directories existed before we even tried to 9096 // install. 9097 deletePackageLI(pkgName, UserHandle.ALL, false, null, null, 9098 dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0, 9099 res.removedInfo, true); 9100 } 9101 } 9102 } 9103 9104 private void replacePackageLI(PackageParser.Package pkg, 9105 int parseFlags, int scanMode, UserHandle user, 9106 String installerPackageName, PackageInstalledInfo res) { 9107 9108 PackageParser.Package oldPackage; 9109 String pkgName = pkg.packageName; 9110 int[] allUsers; 9111 boolean[] perUserInstalled; 9112 9113 // First find the old package info and check signatures 9114 synchronized(mPackages) { 9115 oldPackage = mPackages.get(pkgName); 9116 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 9117 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 9118 != PackageManager.SIGNATURE_MATCH) { 9119 Slog.w(TAG, "New package has a different signature: " + pkgName); 9120 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 9121 return; 9122 } 9123 9124 // In case of rollback, remember per-user/profile install state 9125 PackageSetting ps = mSettings.mPackages.get(pkgName); 9126 allUsers = sUserManager.getUserIds(); 9127 perUserInstalled = new boolean[allUsers.length]; 9128 for (int i = 0; i < allUsers.length; i++) { 9129 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 9130 } 9131 } 9132 boolean sysPkg = (isSystemApp(oldPackage)); 9133 if (sysPkg) { 9134 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, 9135 user, allUsers, perUserInstalled, installerPackageName, res); 9136 } else { 9137 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, 9138 user, allUsers, perUserInstalled, installerPackageName, res); 9139 } 9140 } 9141 9142 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 9143 PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, 9144 int[] allUsers, boolean[] perUserInstalled, 9145 String installerPackageName, PackageInstalledInfo res) { 9146 PackageParser.Package newPackage = null; 9147 String pkgName = deletedPackage.packageName; 9148 boolean deletedPkg = true; 9149 boolean updatedSettings = false; 9150 9151 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 9152 + deletedPackage); 9153 long origUpdateTime; 9154 if (pkg.mExtras != null) { 9155 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 9156 } else { 9157 origUpdateTime = 0; 9158 } 9159 9160 // First delete the existing package while retaining the data directory 9161 if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA, 9162 res.removedInfo, true)) { 9163 // If the existing package wasn't successfully deleted 9164 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 9165 deletedPkg = false; 9166 } else { 9167 // Successfully deleted the old package. Now proceed with re-installation 9168 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 9169 newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME, 9170 System.currentTimeMillis(), user); 9171 if (newPackage == null) { 9172 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 9173 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 9174 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 9175 } 9176 } else { 9177 updateSettingsLI(newPackage, 9178 installerPackageName, 9179 allUsers, perUserInstalled, 9180 res); 9181 updatedSettings = true; 9182 } 9183 } 9184 9185 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 9186 // remove package from internal structures. Note that we want deletePackageX to 9187 // delete the package data and cache directories that it created in 9188 // scanPackageLocked, unless those directories existed before we even tried to 9189 // install. 9190 if(updatedSettings) { 9191 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 9192 deletePackageLI( 9193 pkgName, null, true, allUsers, perUserInstalled, 9194 PackageManager.DELETE_KEEP_DATA, 9195 res.removedInfo, true); 9196 } 9197 // Since we failed to install the new package we need to restore the old 9198 // package that we deleted. 9199 if(deletedPkg) { 9200 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 9201 File restoreFile = new File(deletedPackage.mPath); 9202 // Parse old package 9203 boolean oldOnSd = isExternal(deletedPackage); 9204 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 9205 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) | 9206 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0); 9207 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE 9208 | SCAN_UPDATE_TIME; 9209 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode, 9210 origUpdateTime, null) == null) { 9211 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade"); 9212 return; 9213 } 9214 // Restore of old package succeeded. Update permissions. 9215 // writer 9216 synchronized (mPackages) { 9217 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 9218 UPDATE_PERMISSIONS_ALL); 9219 // can downgrade to reader 9220 mSettings.writeLPr(); 9221 } 9222 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 9223 } 9224 } 9225 } 9226 9227 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 9228 PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, 9229 int[] allUsers, boolean[] perUserInstalled, 9230 String installerPackageName, PackageInstalledInfo res) { 9231 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 9232 + ", old=" + deletedPackage); 9233 PackageParser.Package newPackage = null; 9234 boolean updatedSettings = false; 9235 parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING | 9236 PackageParser.PARSE_IS_SYSTEM; 9237 if ((deletedPackage.applicationInfo.flags&ApplicationInfo.FLAG_PRIVILEGED) != 0) { 9238 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 9239 } 9240 String packageName = deletedPackage.packageName; 9241 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 9242 if (packageName == null) { 9243 Slog.w(TAG, "Attempt to delete null packageName."); 9244 return; 9245 } 9246 PackageParser.Package oldPkg; 9247 PackageSetting oldPkgSetting; 9248 // reader 9249 synchronized (mPackages) { 9250 oldPkg = mPackages.get(packageName); 9251 oldPkgSetting = mSettings.mPackages.get(packageName); 9252 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 9253 (oldPkgSetting == null)) { 9254 Slog.w(TAG, "Couldn't find package:"+packageName+" information"); 9255 return; 9256 } 9257 } 9258 9259 killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg"); 9260 9261 res.removedInfo.uid = oldPkg.applicationInfo.uid; 9262 res.removedInfo.removedPackage = packageName; 9263 // Remove existing system package 9264 removePackageLI(oldPkgSetting, true); 9265 // writer 9266 synchronized (mPackages) { 9267 if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) { 9268 // We didn't need to disable the .apk as a current system package, 9269 // which means we are replacing another update that is already 9270 // installed. We need to make sure to delete the older one's .apk. 9271 res.removedInfo.args = createInstallArgs(0, 9272 deletedPackage.applicationInfo.sourceDir, 9273 deletedPackage.applicationInfo.publicSourceDir, 9274 deletedPackage.applicationInfo.nativeLibraryDir); 9275 } else { 9276 res.removedInfo.args = null; 9277 } 9278 } 9279 9280 // Successfully disabled the old package. Now proceed with re-installation 9281 res.returnCode = mLastScanError = PackageManager.INSTALL_SUCCEEDED; 9282 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 9283 newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user); 9284 if (newPackage == null) { 9285 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 9286 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 9287 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 9288 } 9289 } else { 9290 if (newPackage.mExtras != null) { 9291 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras; 9292 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 9293 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 9294 9295 // is the update attempting to change shared user? that isn't going to work... 9296 if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) { 9297 Slog.w(TAG, "Forbidding shared user change from " + oldPkgSetting.sharedUser 9298 + " to " + newPkgSetting.sharedUser); 9299 res.returnCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 9300 updatedSettings = true; 9301 } 9302 } 9303 9304 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 9305 updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res); 9306 updatedSettings = true; 9307 } 9308 } 9309 9310 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 9311 // Re installation failed. Restore old information 9312 // Remove new pkg information 9313 if (newPackage != null) { 9314 removeInstalledPackageLI(newPackage, true); 9315 } 9316 // Add back the old system package 9317 scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user); 9318 // Restore the old system information in Settings 9319 synchronized(mPackages) { 9320 if (updatedSettings) { 9321 mSettings.enableSystemPackageLPw(packageName); 9322 mSettings.setInstallerPackageName(packageName, 9323 oldPkgSetting.installerPackageName); 9324 } 9325 mSettings.writeLPr(); 9326 } 9327 } 9328 } 9329 9330 // Utility method used to move dex files during install. 9331 private int moveDexFilesLI(PackageParser.Package newPackage) { 9332 int retCode; 9333 if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 9334 retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath); 9335 if (retCode != 0) { 9336 if (mNoDexOpt) { 9337 /* 9338 * If we're in an engineering build, programs are lazily run 9339 * through dexopt. If the .dex file doesn't exist yet, it 9340 * will be created when the program is run next. 9341 */ 9342 Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath); 9343 } else { 9344 Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath); 9345 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9346 } 9347 } 9348 } 9349 return PackageManager.INSTALL_SUCCEEDED; 9350 } 9351 9352 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 9353 int[] allUsers, boolean[] perUserInstalled, 9354 PackageInstalledInfo res) { 9355 String pkgName = newPackage.packageName; 9356 synchronized (mPackages) { 9357 //write settings. the installStatus will be incomplete at this stage. 9358 //note that the new package setting would have already been 9359 //added to mPackages. It hasn't been persisted yet. 9360 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 9361 mSettings.writeLPr(); 9362 } 9363 9364 if ((res.returnCode = moveDexFilesLI(newPackage)) 9365 != PackageManager.INSTALL_SUCCEEDED) { 9366 // Discontinue if moving dex files failed. 9367 return; 9368 } 9369 9370 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.mPath); 9371 9372 synchronized (mPackages) { 9373 updatePermissionsLPw(newPackage.packageName, newPackage, 9374 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 9375 ? UPDATE_PERMISSIONS_ALL : 0)); 9376 // For system-bundled packages, we assume that installing an upgraded version 9377 // of the package implies that the user actually wants to run that new code, 9378 // so we enable the package. 9379 if (isSystemApp(newPackage)) { 9380 // NB: implicit assumption that system package upgrades apply to all users 9381 if (DEBUG_INSTALL) { 9382 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 9383 } 9384 PackageSetting ps = mSettings.mPackages.get(pkgName); 9385 if (ps != null) { 9386 if (res.origUsers != null) { 9387 for (int userHandle : res.origUsers) { 9388 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 9389 userHandle, installerPackageName); 9390 } 9391 } 9392 // Also convey the prior install/uninstall state 9393 if (allUsers != null && perUserInstalled != null) { 9394 for (int i = 0; i < allUsers.length; i++) { 9395 if (DEBUG_INSTALL) { 9396 Slog.d(TAG, " user " + allUsers[i] 9397 + " => " + perUserInstalled[i]); 9398 } 9399 ps.setInstalled(perUserInstalled[i], allUsers[i]); 9400 } 9401 // these install state changes will be persisted in the 9402 // upcoming call to mSettings.writeLPr(). 9403 } 9404 } 9405 } 9406 res.name = pkgName; 9407 res.uid = newPackage.applicationInfo.uid; 9408 res.pkg = newPackage; 9409 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 9410 mSettings.setInstallerPackageName(pkgName, installerPackageName); 9411 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 9412 //to update install status 9413 mSettings.writeLPr(); 9414 } 9415 } 9416 9417 private void installPackageLI(InstallArgs args, 9418 boolean newInstall, PackageInstalledInfo res) { 9419 int pFlags = args.flags; 9420 String installerPackageName = args.installerPackageName; 9421 File tmpPackageFile = new File(args.getCodePath()); 9422 boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 9423 boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0); 9424 boolean replace = false; 9425 int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE 9426 | (newInstall ? SCAN_NEW_INSTALL : 0); 9427 // Result object to be returned 9428 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 9429 9430 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 9431 // Retrieve PackageSettings and parse package 9432 int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 9433 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 9434 | (onSd ? PackageParser.PARSE_ON_SDCARD : 0); 9435 PackageParser pp = new PackageParser(tmpPackageFile.getPath()); 9436 pp.setSeparateProcesses(mSeparateProcesses); 9437 final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile, 9438 null, mMetrics, parseFlags); 9439 if (pkg == null) { 9440 res.returnCode = pp.getParseError(); 9441 return; 9442 } 9443 String pkgName = res.name = pkg.packageName; 9444 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 9445 if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) { 9446 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY; 9447 return; 9448 } 9449 } 9450 if (!pp.collectCertificates(pkg, parseFlags)) { 9451 res.returnCode = pp.getParseError(); 9452 return; 9453 } 9454 9455 /* If the installer passed in a manifest digest, compare it now. */ 9456 if (args.manifestDigest != null) { 9457 if (DEBUG_INSTALL) { 9458 final String parsedManifest = pkg.manifestDigest == null ? "null" 9459 : pkg.manifestDigest.toString(); 9460 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 9461 + parsedManifest); 9462 } 9463 9464 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 9465 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 9466 return; 9467 } 9468 } else if (DEBUG_INSTALL) { 9469 final String parsedManifest = pkg.manifestDigest == null 9470 ? "null" : pkg.manifestDigest.toString(); 9471 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 9472 } 9473 9474 // Get rid of all references to package scan path via parser. 9475 pp = null; 9476 String oldCodePath = null; 9477 boolean systemApp = false; 9478 synchronized (mPackages) { 9479 // Check whether the newly-scanned package wants to define an already-defined perm 9480 int N = pkg.permissions.size(); 9481 for (int i = 0; i < N; i++) { 9482 PackageParser.Permission perm = pkg.permissions.get(i); 9483 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 9484 if (bp != null) { 9485 // If the defining package is signed with our cert, it's okay. This 9486 // also includes the "updating the same package" case, of course. 9487 if (compareSignatures(bp.packageSetting.signatures.mSignatures, 9488 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 9489 Slog.w(TAG, "Package " + pkg.packageName 9490 + " attempting to redeclare permission " + perm.info.name 9491 + " already owned by " + bp.sourcePackage); 9492 res.returnCode = PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 9493 res.origPermission = perm.info.name; 9494 res.origPackage = bp.sourcePackage; 9495 return; 9496 } 9497 } 9498 } 9499 9500 // Check if installing already existing package 9501 if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 9502 String oldName = mSettings.mRenamedPackages.get(pkgName); 9503 if (pkg.mOriginalPackages != null 9504 && pkg.mOriginalPackages.contains(oldName) 9505 && mPackages.containsKey(oldName)) { 9506 // This package is derived from an original package, 9507 // and this device has been updating from that original 9508 // name. We must continue using the original name, so 9509 // rename the new package here. 9510 pkg.setPackageName(oldName); 9511 pkgName = pkg.packageName; 9512 replace = true; 9513 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 9514 + oldName + " pkgName=" + pkgName); 9515 } else if (mPackages.containsKey(pkgName)) { 9516 // This package, under its official name, already exists 9517 // on the device; we should replace it. 9518 replace = true; 9519 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 9520 } 9521 } 9522 PackageSetting ps = mSettings.mPackages.get(pkgName); 9523 if (ps != null) { 9524 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 9525 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 9526 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 9527 systemApp = (ps.pkg.applicationInfo.flags & 9528 ApplicationInfo.FLAG_SYSTEM) != 0; 9529 } 9530 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 9531 } 9532 } 9533 9534 if (systemApp && onSd) { 9535 // Disable updates to system apps on sdcard 9536 Slog.w(TAG, "Cannot install updates to system apps on sdcard"); 9537 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 9538 return; 9539 } 9540 9541 if (!args.doRename(res.returnCode, pkgName, oldCodePath)) { 9542 res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 9543 return; 9544 } 9545 // Set application objects path explicitly after the rename 9546 setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath()); 9547 pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath(); 9548 if (replace) { 9549 replacePackageLI(pkg, parseFlags, scanMode, args.user, 9550 installerPackageName, res); 9551 } else { 9552 installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user, 9553 installerPackageName, res); 9554 } 9555 synchronized (mPackages) { 9556 final PackageSetting ps = mSettings.mPackages.get(pkgName); 9557 if (ps != null) { 9558 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 9559 } 9560 } 9561 } 9562 9563 private static boolean isForwardLocked(PackageParser.Package pkg) { 9564 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 9565 } 9566 9567 9568 private boolean isForwardLocked(PackageSetting ps) { 9569 return (ps.pkgFlags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 9570 } 9571 9572 private static boolean isExternal(PackageParser.Package pkg) { 9573 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 9574 } 9575 9576 private static boolean isExternal(PackageSetting ps) { 9577 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 9578 } 9579 9580 private static boolean isSystemApp(PackageParser.Package pkg) { 9581 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 9582 } 9583 9584 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 9585 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0; 9586 } 9587 9588 private static boolean isSystemApp(ApplicationInfo info) { 9589 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 9590 } 9591 9592 private static boolean isSystemApp(PackageSetting ps) { 9593 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 9594 } 9595 9596 private static boolean isUpdatedSystemApp(PackageSetting ps) { 9597 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 9598 } 9599 9600 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) { 9601 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 9602 } 9603 9604 private int packageFlagsToInstallFlags(PackageSetting ps) { 9605 int installFlags = 0; 9606 if (isExternal(ps)) { 9607 installFlags |= PackageManager.INSTALL_EXTERNAL; 9608 } 9609 if (isForwardLocked(ps)) { 9610 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 9611 } 9612 return installFlags; 9613 } 9614 9615 private void deleteTempPackageFiles() { 9616 final FilenameFilter filter = new FilenameFilter() { 9617 public boolean accept(File dir, String name) { 9618 return name.startsWith("vmdl") && name.endsWith(".tmp"); 9619 } 9620 }; 9621 deleteTempPackageFilesInDirectory(mAppInstallDir, filter); 9622 deleteTempPackageFilesInDirectory(mDrmAppPrivateInstallDir, filter); 9623 } 9624 9625 private static final void deleteTempPackageFilesInDirectory(File directory, 9626 FilenameFilter filter) { 9627 final String[] tmpFilesList = directory.list(filter); 9628 if (tmpFilesList == null) { 9629 return; 9630 } 9631 for (int i = 0; i < tmpFilesList.length; i++) { 9632 final File tmpFile = new File(directory, tmpFilesList[i]); 9633 tmpFile.delete(); 9634 } 9635 } 9636 9637 private File createTempPackageFile(File installDir) { 9638 File tmpPackageFile; 9639 try { 9640 tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir); 9641 } catch (IOException e) { 9642 Slog.e(TAG, "Couldn't create temp file for downloaded package file."); 9643 return null; 9644 } 9645 try { 9646 FileUtils.setPermissions( 9647 tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR, 9648 -1, -1); 9649 if (!SELinux.restorecon(tmpPackageFile)) { 9650 return null; 9651 } 9652 } catch (IOException e) { 9653 Slog.e(TAG, "Trouble getting the canoncical path for a temp file."); 9654 return null; 9655 } 9656 return tmpPackageFile; 9657 } 9658 9659 @Override 9660 public void deletePackageAsUser(final String packageName, 9661 final IPackageDeleteObserver observer, 9662 final int userId, final int flags) { 9663 mContext.enforceCallingOrSelfPermission( 9664 android.Manifest.permission.DELETE_PACKAGES, null); 9665 final int uid = Binder.getCallingUid(); 9666 if (UserHandle.getUserId(uid) != userId) { 9667 mContext.enforceCallingPermission( 9668 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 9669 "deletePackage for user " + userId); 9670 } 9671 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 9672 try { 9673 observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED); 9674 } catch (RemoteException re) { 9675 } 9676 return; 9677 } 9678 9679 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); 9680 // Queue up an async operation since the package deletion may take a little while. 9681 mHandler.post(new Runnable() { 9682 public void run() { 9683 mHandler.removeCallbacks(this); 9684 final int returnCode = deletePackageX(packageName, userId, flags); 9685 if (observer != null) { 9686 try { 9687 observer.packageDeleted(packageName, returnCode); 9688 } catch (RemoteException e) { 9689 Log.i(TAG, "Observer no longer exists."); 9690 } //end catch 9691 } //end if 9692 } //end run 9693 }); 9694 } 9695 9696 private boolean isPackageDeviceAdmin(String packageName, int userId) { 9697 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 9698 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 9699 try { 9700 if (dpm != null && (dpm.packageHasActiveAdmins(packageName, userId) 9701 || dpm.isDeviceOwner(packageName))) { 9702 return true; 9703 } 9704 } catch (RemoteException e) { 9705 } 9706 return false; 9707 } 9708 9709 /** 9710 * This method is an internal method that could be get invoked either 9711 * to delete an installed package or to clean up a failed installation. 9712 * After deleting an installed package, a broadcast is sent to notify any 9713 * listeners that the package has been installed. For cleaning up a failed 9714 * installation, the broadcast is not necessary since the package's 9715 * installation wouldn't have sent the initial broadcast either 9716 * The key steps in deleting a package are 9717 * deleting the package information in internal structures like mPackages, 9718 * deleting the packages base directories through installd 9719 * updating mSettings to reflect current status 9720 * persisting settings for later use 9721 * sending a broadcast if necessary 9722 */ 9723 private int deletePackageX(String packageName, int userId, int flags) { 9724 final PackageRemovedInfo info = new PackageRemovedInfo(); 9725 final boolean res; 9726 9727 if (isPackageDeviceAdmin(packageName, userId)) { 9728 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 9729 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 9730 } 9731 9732 boolean removedForAllUsers = false; 9733 boolean systemUpdate = false; 9734 9735 // for the uninstall-updates case and restricted profiles, remember the per- 9736 // userhandle installed state 9737 int[] allUsers; 9738 boolean[] perUserInstalled; 9739 synchronized (mPackages) { 9740 PackageSetting ps = mSettings.mPackages.get(packageName); 9741 allUsers = sUserManager.getUserIds(); 9742 perUserInstalled = new boolean[allUsers.length]; 9743 for (int i = 0; i < allUsers.length; i++) { 9744 perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false; 9745 } 9746 } 9747 9748 synchronized (mInstallLock) { 9749 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 9750 res = deletePackageLI(packageName, 9751 (flags & PackageManager.DELETE_ALL_USERS) != 0 9752 ? UserHandle.ALL : new UserHandle(userId), 9753 true, allUsers, perUserInstalled, 9754 flags | REMOVE_CHATTY, info, true); 9755 systemUpdate = info.isRemovedPackageSystemUpdate; 9756 if (res && !systemUpdate && mPackages.get(packageName) == null) { 9757 removedForAllUsers = true; 9758 } 9759 if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate 9760 + " removedForAllUsers=" + removedForAllUsers); 9761 } 9762 9763 if (res) { 9764 info.sendBroadcast(true, systemUpdate, removedForAllUsers); 9765 9766 // If the removed package was a system update, the old system package 9767 // was re-enabled; we need to broadcast this information 9768 if (systemUpdate) { 9769 Bundle extras = new Bundle(1); 9770 extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0 9771 ? info.removedAppId : info.uid); 9772 extras.putBoolean(Intent.EXTRA_REPLACING, true); 9773 9774 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 9775 extras, null, null, null); 9776 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 9777 extras, null, null, null); 9778 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 9779 null, packageName, null, null); 9780 } 9781 } 9782 // Force a gc here. 9783 Runtime.getRuntime().gc(); 9784 // Delete the resources here after sending the broadcast to let 9785 // other processes clean up before deleting resources. 9786 if (info.args != null) { 9787 synchronized (mInstallLock) { 9788 info.args.doPostDeleteLI(true); 9789 } 9790 } 9791 9792 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 9793 } 9794 9795 static class PackageRemovedInfo { 9796 String removedPackage; 9797 int uid = -1; 9798 int removedAppId = -1; 9799 int[] removedUsers = null; 9800 boolean isRemovedPackageSystemUpdate = false; 9801 // Clean up resources deleted packages. 9802 InstallArgs args = null; 9803 9804 void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) { 9805 Bundle extras = new Bundle(1); 9806 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 9807 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 9808 if (replacing) { 9809 extras.putBoolean(Intent.EXTRA_REPLACING, true); 9810 } 9811 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 9812 if (removedPackage != null) { 9813 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 9814 extras, null, null, removedUsers); 9815 if (fullRemove && !replacing) { 9816 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 9817 extras, null, null, removedUsers); 9818 } 9819 } 9820 if (removedAppId >= 0) { 9821 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null, 9822 removedUsers); 9823 } 9824 } 9825 } 9826 9827 /* 9828 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 9829 * flag is not set, the data directory is removed as well. 9830 * make sure this flag is set for partially installed apps. If not its meaningless to 9831 * delete a partially installed application. 9832 */ 9833 private void removePackageDataLI(PackageSetting ps, 9834 int[] allUserHandles, boolean[] perUserInstalled, 9835 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 9836 String packageName = ps.name; 9837 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 9838 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 9839 // Retrieve object to delete permissions for shared user later on 9840 final PackageSetting deletedPs; 9841 // reader 9842 synchronized (mPackages) { 9843 deletedPs = mSettings.mPackages.get(packageName); 9844 if (outInfo != null) { 9845 outInfo.removedPackage = packageName; 9846 outInfo.removedUsers = deletedPs != null 9847 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 9848 : null; 9849 } 9850 } 9851 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 9852 removeDataDirsLI(packageName); 9853 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 9854 } 9855 // writer 9856 synchronized (mPackages) { 9857 if (deletedPs != null) { 9858 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 9859 if (outInfo != null) { 9860 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 9861 } 9862 if (deletedPs != null) { 9863 updatePermissionsLPw(deletedPs.name, null, 0); 9864 if (deletedPs.sharedUser != null) { 9865 // remove permissions associated with package 9866 mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids); 9867 } 9868 } 9869 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 9870 } 9871 // make sure to preserve per-user disabled state if this removal was just 9872 // a downgrade of a system app to the factory package 9873 if (allUserHandles != null && perUserInstalled != null) { 9874 if (DEBUG_REMOVE) { 9875 Slog.d(TAG, "Propagating install state across downgrade"); 9876 } 9877 for (int i = 0; i < allUserHandles.length; i++) { 9878 if (DEBUG_REMOVE) { 9879 Slog.d(TAG, " user " + allUserHandles[i] 9880 + " => " + perUserInstalled[i]); 9881 } 9882 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 9883 } 9884 } 9885 } 9886 // can downgrade to reader 9887 if (writeSettings) { 9888 // Save settings now 9889 mSettings.writeLPr(); 9890 } 9891 } 9892 if (outInfo != null) { 9893 // A user ID was deleted here. Go through all users and remove it 9894 // from KeyStore. 9895 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 9896 } 9897 } 9898 9899 static boolean locationIsPrivileged(File path) { 9900 try { 9901 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 9902 .getCanonicalPath(); 9903 return path.getCanonicalPath().startsWith(privilegedAppDir); 9904 } catch (IOException e) { 9905 Slog.e(TAG, "Unable to access code path " + path); 9906 } 9907 return false; 9908 } 9909 9910 /* 9911 * Tries to delete system package. 9912 */ 9913 private boolean deleteSystemPackageLI(PackageSetting newPs, 9914 int[] allUserHandles, boolean[] perUserInstalled, 9915 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 9916 final boolean applyUserRestrictions 9917 = (allUserHandles != null) && (perUserInstalled != null); 9918 PackageSetting disabledPs = null; 9919 // Confirm if the system package has been updated 9920 // An updated system app can be deleted. This will also have to restore 9921 // the system pkg from system partition 9922 // reader 9923 synchronized (mPackages) { 9924 disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name); 9925 } 9926 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs 9927 + " disabledPs=" + disabledPs); 9928 if (disabledPs == null) { 9929 Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name); 9930 return false; 9931 } else if (DEBUG_REMOVE) { 9932 Slog.d(TAG, "Deleting system pkg from data partition"); 9933 } 9934 if (DEBUG_REMOVE) { 9935 if (applyUserRestrictions) { 9936 Slog.d(TAG, "Remembering install states:"); 9937 for (int i = 0; i < allUserHandles.length; i++) { 9938 Slog.d(TAG, " u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]); 9939 } 9940 } 9941 } 9942 // Delete the updated package 9943 outInfo.isRemovedPackageSystemUpdate = true; 9944 if (disabledPs.versionCode < newPs.versionCode) { 9945 // Delete data for downgrades 9946 flags &= ~PackageManager.DELETE_KEEP_DATA; 9947 } else { 9948 // Preserve data by setting flag 9949 flags |= PackageManager.DELETE_KEEP_DATA; 9950 } 9951 boolean ret = deleteInstalledPackageLI(newPs, true, flags, 9952 allUserHandles, perUserInstalled, outInfo, writeSettings); 9953 if (!ret) { 9954 return false; 9955 } 9956 // writer 9957 synchronized (mPackages) { 9958 // Reinstate the old system package 9959 mSettings.enableSystemPackageLPw(newPs.name); 9960 // Remove any native libraries from the upgraded package. 9961 NativeLibraryHelper.removeNativeBinariesLI(newPs.nativeLibraryPathString); 9962 } 9963 // Install the system package 9964 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 9965 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 9966 if (locationIsPrivileged(disabledPs.codePath)) { 9967 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 9968 } 9969 PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath, 9970 parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null); 9971 9972 if (newPkg == null) { 9973 Slog.w(TAG, "Failed to restore system package:" + newPs.name 9974 + " with error:" + mLastScanError); 9975 return false; 9976 } 9977 // writer 9978 synchronized (mPackages) { 9979 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 9980 setInternalAppNativeLibraryPath(newPkg, ps); 9981 updatePermissionsLPw(newPkg.packageName, newPkg, 9982 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 9983 if (applyUserRestrictions) { 9984 if (DEBUG_REMOVE) { 9985 Slog.d(TAG, "Propagating install state across reinstall"); 9986 } 9987 for (int i = 0; i < allUserHandles.length; i++) { 9988 if (DEBUG_REMOVE) { 9989 Slog.d(TAG, " user " + allUserHandles[i] 9990 + " => " + perUserInstalled[i]); 9991 } 9992 ps.setInstalled(perUserInstalled[i], allUserHandles[i]); 9993 } 9994 // Regardless of writeSettings we need to ensure that this restriction 9995 // state propagation is persisted 9996 mSettings.writeAllUsersPackageRestrictionsLPr(); 9997 } 9998 // can downgrade to reader here 9999 if (writeSettings) { 10000 mSettings.writeLPr(); 10001 } 10002 } 10003 return true; 10004 } 10005 10006 private boolean deleteInstalledPackageLI(PackageSetting ps, 10007 boolean deleteCodeAndResources, int flags, 10008 int[] allUserHandles, boolean[] perUserInstalled, 10009 PackageRemovedInfo outInfo, boolean writeSettings) { 10010 if (outInfo != null) { 10011 outInfo.uid = ps.appId; 10012 } 10013 10014 // Delete package data from internal structures and also remove data if flag is set 10015 removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings); 10016 10017 // Delete application code and resources 10018 if (deleteCodeAndResources && (outInfo != null)) { 10019 outInfo.args = createInstallArgs(packageFlagsToInstallFlags(ps), ps.codePathString, 10020 ps.resourcePathString, ps.nativeLibraryPathString); 10021 } 10022 return true; 10023 } 10024 10025 /* 10026 * This method handles package deletion in general 10027 */ 10028 private boolean deletePackageLI(String packageName, UserHandle user, 10029 boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled, 10030 int flags, PackageRemovedInfo outInfo, 10031 boolean writeSettings) { 10032 if (packageName == null) { 10033 Slog.w(TAG, "Attempt to delete null packageName."); 10034 return false; 10035 } 10036 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 10037 PackageSetting ps; 10038 boolean dataOnly = false; 10039 int removeUser = -1; 10040 int appId = -1; 10041 synchronized (mPackages) { 10042 ps = mSettings.mPackages.get(packageName); 10043 if (ps == null) { 10044 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 10045 return false; 10046 } 10047 if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 10048 && user.getIdentifier() != UserHandle.USER_ALL) { 10049 // The caller is asking that the package only be deleted for a single 10050 // user. To do this, we just mark its uninstalled state and delete 10051 // its data. If this is a system app, we only allow this to happen if 10052 // they have set the special DELETE_SYSTEM_APP which requests different 10053 // semantics than normal for uninstalling system apps. 10054 if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user"); 10055 ps.setUserState(user.getIdentifier(), 10056 COMPONENT_ENABLED_STATE_DEFAULT, 10057 false, //installed 10058 true, //stopped 10059 true, //notLaunched 10060 false, //blocked 10061 null, null, null); 10062 if (!isSystemApp(ps)) { 10063 if (ps.isAnyInstalled(sUserManager.getUserIds())) { 10064 // Other user still have this package installed, so all 10065 // we need to do is clear this user's data and save that 10066 // it is uninstalled. 10067 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 10068 removeUser = user.getIdentifier(); 10069 appId = ps.appId; 10070 mSettings.writePackageRestrictionsLPr(removeUser); 10071 } else { 10072 // We need to set it back to 'installed' so the uninstall 10073 // broadcasts will be sent correctly. 10074 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 10075 ps.setInstalled(true, user.getIdentifier()); 10076 } 10077 } else { 10078 // This is a system app, so we assume that the 10079 // other users still have this package installed, so all 10080 // we need to do is clear this user's data and save that 10081 // it is uninstalled. 10082 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 10083 removeUser = user.getIdentifier(); 10084 appId = ps.appId; 10085 mSettings.writePackageRestrictionsLPr(removeUser); 10086 } 10087 } 10088 } 10089 10090 if (removeUser >= 0) { 10091 // From above, we determined that we are deleting this only 10092 // for a single user. Continue the work here. 10093 if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser); 10094 if (outInfo != null) { 10095 outInfo.removedPackage = packageName; 10096 outInfo.removedAppId = appId; 10097 outInfo.removedUsers = new int[] {removeUser}; 10098 } 10099 mInstaller.clearUserData(packageName, removeUser); 10100 removeKeystoreDataIfNeeded(removeUser, appId); 10101 schedulePackageCleaning(packageName, removeUser, false); 10102 return true; 10103 } 10104 10105 if (dataOnly) { 10106 // Delete application data first 10107 if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only"); 10108 removePackageDataLI(ps, null, null, outInfo, flags, writeSettings); 10109 return true; 10110 } 10111 10112 boolean ret = false; 10113 mSettings.mKeySetManager.removeAppKeySetData(packageName); 10114 if (isSystemApp(ps)) { 10115 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package:" + ps.name); 10116 // When an updated system application is deleted we delete the existing resources as well and 10117 // fall back to existing code in system partition 10118 ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled, 10119 flags, outInfo, writeSettings); 10120 } else { 10121 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package:" + ps.name); 10122 // Kill application pre-emptively especially for apps on sd. 10123 killApplication(packageName, ps.appId, "uninstall pkg"); 10124 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, 10125 allUserHandles, perUserInstalled, 10126 outInfo, writeSettings); 10127 } 10128 10129 return ret; 10130 } 10131 10132 private final class ClearStorageConnection implements ServiceConnection { 10133 IMediaContainerService mContainerService; 10134 10135 @Override 10136 public void onServiceConnected(ComponentName name, IBinder service) { 10137 synchronized (this) { 10138 mContainerService = IMediaContainerService.Stub.asInterface(service); 10139 notifyAll(); 10140 } 10141 } 10142 10143 @Override 10144 public void onServiceDisconnected(ComponentName name) { 10145 } 10146 } 10147 10148 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 10149 final boolean mounted; 10150 if (Environment.isExternalStorageEmulated()) { 10151 mounted = true; 10152 } else { 10153 final String status = Environment.getExternalStorageState(); 10154 10155 mounted = status.equals(Environment.MEDIA_MOUNTED) 10156 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 10157 } 10158 10159 if (!mounted) { 10160 return; 10161 } 10162 10163 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 10164 int[] users; 10165 if (userId == UserHandle.USER_ALL) { 10166 users = sUserManager.getUserIds(); 10167 } else { 10168 users = new int[] { userId }; 10169 } 10170 final ClearStorageConnection conn = new ClearStorageConnection(); 10171 if (mContext.bindServiceAsUser( 10172 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 10173 try { 10174 for (int curUser : users) { 10175 long timeout = SystemClock.uptimeMillis() + 5000; 10176 synchronized (conn) { 10177 long now = SystemClock.uptimeMillis(); 10178 while (conn.mContainerService == null && now < timeout) { 10179 try { 10180 conn.wait(timeout - now); 10181 } catch (InterruptedException e) { 10182 } 10183 } 10184 } 10185 if (conn.mContainerService == null) { 10186 return; 10187 } 10188 10189 final UserEnvironment userEnv = new UserEnvironment(curUser); 10190 clearDirectory(conn.mContainerService, 10191 userEnv.buildExternalStorageAppCacheDirs(packageName)); 10192 if (allData) { 10193 clearDirectory(conn.mContainerService, 10194 userEnv.buildExternalStorageAppDataDirs(packageName)); 10195 clearDirectory(conn.mContainerService, 10196 userEnv.buildExternalStorageAppMediaDirs(packageName)); 10197 } 10198 } 10199 } finally { 10200 mContext.unbindService(conn); 10201 } 10202 } 10203 } 10204 10205 @Override 10206 public void clearApplicationUserData(final String packageName, 10207 final IPackageDataObserver observer, final int userId) { 10208 mContext.enforceCallingOrSelfPermission( 10209 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 10210 enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data"); 10211 // Queue up an async operation since the package deletion may take a little while. 10212 mHandler.post(new Runnable() { 10213 public void run() { 10214 mHandler.removeCallbacks(this); 10215 final boolean succeeded; 10216 synchronized (mInstallLock) { 10217 succeeded = clearApplicationUserDataLI(packageName, userId); 10218 } 10219 clearExternalStorageDataSync(packageName, userId, true); 10220 if (succeeded) { 10221 // invoke DeviceStorageMonitor's update method to clear any notifications 10222 DeviceStorageMonitorInternal 10223 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 10224 if (dsm != null) { 10225 dsm.checkMemory(); 10226 } 10227 } 10228 if(observer != null) { 10229 try { 10230 observer.onRemoveCompleted(packageName, succeeded); 10231 } catch (RemoteException e) { 10232 Log.i(TAG, "Observer no longer exists."); 10233 } 10234 } //end if observer 10235 } //end run 10236 }); 10237 } 10238 10239 private boolean clearApplicationUserDataLI(String packageName, int userId) { 10240 if (packageName == null) { 10241 Slog.w(TAG, "Attempt to delete null packageName."); 10242 return false; 10243 } 10244 PackageParser.Package p; 10245 boolean dataOnly = false; 10246 final int appId; 10247 synchronized (mPackages) { 10248 p = mPackages.get(packageName); 10249 if (p == null) { 10250 dataOnly = true; 10251 PackageSetting ps = mSettings.mPackages.get(packageName); 10252 if ((ps == null) || (ps.pkg == null)) { 10253 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 10254 return false; 10255 } 10256 p = ps.pkg; 10257 } 10258 if (!dataOnly) { 10259 // need to check this only for fully installed applications 10260 if (p == null) { 10261 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 10262 return false; 10263 } 10264 final ApplicationInfo applicationInfo = p.applicationInfo; 10265 if (applicationInfo == null) { 10266 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 10267 return false; 10268 } 10269 } 10270 if (p != null && p.applicationInfo != null) { 10271 appId = p.applicationInfo.uid; 10272 } else { 10273 appId = -1; 10274 } 10275 } 10276 int retCode = mInstaller.clearUserData(packageName, userId); 10277 if (retCode < 0) { 10278 Slog.w(TAG, "Couldn't remove cache files for package: " 10279 + packageName); 10280 return false; 10281 } 10282 removeKeystoreDataIfNeeded(userId, appId); 10283 return true; 10284 } 10285 10286 /** 10287 * Remove entries from the keystore daemon. Will only remove it if the 10288 * {@code appId} is valid. 10289 */ 10290 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 10291 if (appId < 0) { 10292 return; 10293 } 10294 10295 final KeyStore keyStore = KeyStore.getInstance(); 10296 if (keyStore != null) { 10297 if (userId == UserHandle.USER_ALL) { 10298 for (final int individual : sUserManager.getUserIds()) { 10299 keyStore.clearUid(UserHandle.getUid(individual, appId)); 10300 } 10301 } else { 10302 keyStore.clearUid(UserHandle.getUid(userId, appId)); 10303 } 10304 } else { 10305 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 10306 } 10307 } 10308 10309 public void deleteApplicationCacheFiles(final String packageName, 10310 final IPackageDataObserver observer) { 10311 mContext.enforceCallingOrSelfPermission( 10312 android.Manifest.permission.DELETE_CACHE_FILES, null); 10313 // Queue up an async operation since the package deletion may take a little while. 10314 final int userId = UserHandle.getCallingUserId(); 10315 mHandler.post(new Runnable() { 10316 public void run() { 10317 mHandler.removeCallbacks(this); 10318 final boolean succeded; 10319 synchronized (mInstallLock) { 10320 succeded = deleteApplicationCacheFilesLI(packageName, userId); 10321 } 10322 clearExternalStorageDataSync(packageName, userId, false); 10323 if(observer != null) { 10324 try { 10325 observer.onRemoveCompleted(packageName, succeded); 10326 } catch (RemoteException e) { 10327 Log.i(TAG, "Observer no longer exists."); 10328 } 10329 } //end if observer 10330 } //end run 10331 }); 10332 } 10333 10334 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 10335 if (packageName == null) { 10336 Slog.w(TAG, "Attempt to delete null packageName."); 10337 return false; 10338 } 10339 PackageParser.Package p; 10340 synchronized (mPackages) { 10341 p = mPackages.get(packageName); 10342 } 10343 if (p == null) { 10344 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 10345 return false; 10346 } 10347 final ApplicationInfo applicationInfo = p.applicationInfo; 10348 if (applicationInfo == null) { 10349 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 10350 return false; 10351 } 10352 int retCode = mInstaller.deleteCacheFiles(packageName, userId); 10353 if (retCode < 0) { 10354 Slog.w(TAG, "Couldn't remove cache files for package: " 10355 + packageName + " u" + userId); 10356 return false; 10357 } 10358 return true; 10359 } 10360 10361 public void getPackageSizeInfo(final String packageName, int userHandle, 10362 final IPackageStatsObserver observer) { 10363 mContext.enforceCallingOrSelfPermission( 10364 android.Manifest.permission.GET_PACKAGE_SIZE, null); 10365 if (packageName == null) { 10366 throw new IllegalArgumentException("Attempt to get size of null packageName"); 10367 } 10368 10369 PackageStats stats = new PackageStats(packageName, userHandle); 10370 10371 /* 10372 * Queue up an async operation since the package measurement may take a 10373 * little while. 10374 */ 10375 Message msg = mHandler.obtainMessage(INIT_COPY); 10376 msg.obj = new MeasureParams(stats, observer); 10377 mHandler.sendMessage(msg); 10378 } 10379 10380 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 10381 PackageStats pStats) { 10382 if (packageName == null) { 10383 Slog.w(TAG, "Attempt to get size of null packageName."); 10384 return false; 10385 } 10386 PackageParser.Package p; 10387 boolean dataOnly = false; 10388 String libDirPath = null; 10389 String asecPath = null; 10390 synchronized (mPackages) { 10391 p = mPackages.get(packageName); 10392 PackageSetting ps = mSettings.mPackages.get(packageName); 10393 if(p == null) { 10394 dataOnly = true; 10395 if((ps == null) || (ps.pkg == null)) { 10396 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 10397 return false; 10398 } 10399 p = ps.pkg; 10400 } 10401 if (ps != null) { 10402 libDirPath = ps.nativeLibraryPathString; 10403 } 10404 if (p != null && (isExternal(p) || isForwardLocked(p))) { 10405 String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir); 10406 if (secureContainerId != null) { 10407 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 10408 } 10409 } 10410 } 10411 String publicSrcDir = null; 10412 if(!dataOnly) { 10413 final ApplicationInfo applicationInfo = p.applicationInfo; 10414 if (applicationInfo == null) { 10415 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 10416 return false; 10417 } 10418 if (isForwardLocked(p)) { 10419 publicSrcDir = applicationInfo.publicSourceDir; 10420 } 10421 } 10422 int res = mInstaller.getSizeInfo(packageName, userHandle, p.mPath, libDirPath, 10423 publicSrcDir, asecPath, pStats); 10424 if (res < 0) { 10425 return false; 10426 } 10427 10428 // Fix-up for forward-locked applications in ASEC containers. 10429 if (!isExternal(p)) { 10430 pStats.codeSize += pStats.externalCodeSize; 10431 pStats.externalCodeSize = 0L; 10432 } 10433 10434 return true; 10435 } 10436 10437 10438 public void addPackageToPreferred(String packageName) { 10439 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 10440 } 10441 10442 public void removePackageFromPreferred(String packageName) { 10443 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 10444 } 10445 10446 public List<PackageInfo> getPreferredPackages(int flags) { 10447 return new ArrayList<PackageInfo>(); 10448 } 10449 10450 private int getUidTargetSdkVersionLockedLPr(int uid) { 10451 Object obj = mSettings.getUserIdLPr(uid); 10452 if (obj instanceof SharedUserSetting) { 10453 final SharedUserSetting sus = (SharedUserSetting) obj; 10454 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 10455 final Iterator<PackageSetting> it = sus.packages.iterator(); 10456 while (it.hasNext()) { 10457 final PackageSetting ps = it.next(); 10458 if (ps.pkg != null) { 10459 int v = ps.pkg.applicationInfo.targetSdkVersion; 10460 if (v < vers) vers = v; 10461 } 10462 } 10463 return vers; 10464 } else if (obj instanceof PackageSetting) { 10465 final PackageSetting ps = (PackageSetting) obj; 10466 if (ps.pkg != null) { 10467 return ps.pkg.applicationInfo.targetSdkVersion; 10468 } 10469 } 10470 return Build.VERSION_CODES.CUR_DEVELOPMENT; 10471 } 10472 10473 public void addPreferredActivity(IntentFilter filter, int match, 10474 ComponentName[] set, ComponentName activity, int userId) { 10475 addPreferredActivityInternal(filter, match, set, activity, true, userId); 10476 } 10477 10478 private void addPreferredActivityInternal(IntentFilter filter, int match, 10479 ComponentName[] set, ComponentName activity, boolean always, int userId) { 10480 // writer 10481 int callingUid = Binder.getCallingUid(); 10482 enforceCrossUserPermission(callingUid, userId, true, "add preferred activity"); 10483 if (filter.countActions() == 0) { 10484 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 10485 return; 10486 } 10487 synchronized (mPackages) { 10488 if (mContext.checkCallingOrSelfPermission( 10489 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 10490 != PackageManager.PERMISSION_GRANTED) { 10491 if (getUidTargetSdkVersionLockedLPr(callingUid) 10492 < Build.VERSION_CODES.FROYO) { 10493 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 10494 + callingUid); 10495 return; 10496 } 10497 mContext.enforceCallingOrSelfPermission( 10498 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10499 } 10500 10501 Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :"); 10502 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 10503 mSettings.editPreferredActivitiesLPw(userId).addFilter( 10504 new PreferredActivity(filter, match, set, activity, always)); 10505 mSettings.writePackageRestrictionsLPr(userId); 10506 } 10507 } 10508 10509 public void replacePreferredActivity(IntentFilter filter, int match, 10510 ComponentName[] set, ComponentName activity) { 10511 if (filter.countActions() != 1) { 10512 throw new IllegalArgumentException( 10513 "replacePreferredActivity expects filter to have only 1 action."); 10514 } 10515 if (filter.countDataAuthorities() != 0 10516 || filter.countDataPaths() != 0 10517 || filter.countDataSchemes() > 1 10518 || filter.countDataTypes() != 0) { 10519 throw new IllegalArgumentException( 10520 "replacePreferredActivity expects filter to have no data authorities, " + 10521 "paths, or types; and at most one scheme."); 10522 } 10523 synchronized (mPackages) { 10524 if (mContext.checkCallingOrSelfPermission( 10525 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 10526 != PackageManager.PERMISSION_GRANTED) { 10527 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 10528 < Build.VERSION_CODES.FROYO) { 10529 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 10530 + Binder.getCallingUid()); 10531 return; 10532 } 10533 mContext.enforceCallingOrSelfPermission( 10534 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10535 } 10536 10537 final int callingUserId = UserHandle.getCallingUserId(); 10538 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId); 10539 if (pir != null) { 10540 Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0)); 10541 if (filter.countDataSchemes() == 1) { 10542 Uri.Builder builder = new Uri.Builder(); 10543 builder.scheme(filter.getDataScheme(0)); 10544 intent.setData(builder.build()); 10545 } 10546 List<PreferredActivity> matches = pir.queryIntent( 10547 intent, null, true, callingUserId); 10548 if (DEBUG_PREFERRED) { 10549 Slog.i(TAG, matches.size() + " preferred matches for " + intent); 10550 } 10551 for (int i = 0; i < matches.size(); i++) { 10552 PreferredActivity pa = matches.get(i); 10553 if (DEBUG_PREFERRED) { 10554 Slog.i(TAG, "Removing preferred activity " 10555 + pa.mPref.mComponent + ":"); 10556 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 10557 } 10558 pir.removeFilter(pa); 10559 } 10560 } 10561 addPreferredActivityInternal(filter, match, set, activity, true, callingUserId); 10562 } 10563 } 10564 10565 public void clearPackagePreferredActivities(String packageName) { 10566 final int uid = Binder.getCallingUid(); 10567 // writer 10568 synchronized (mPackages) { 10569 PackageParser.Package pkg = mPackages.get(packageName); 10570 if (pkg == null || pkg.applicationInfo.uid != uid) { 10571 if (mContext.checkCallingOrSelfPermission( 10572 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 10573 != PackageManager.PERMISSION_GRANTED) { 10574 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 10575 < Build.VERSION_CODES.FROYO) { 10576 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 10577 + Binder.getCallingUid()); 10578 return; 10579 } 10580 mContext.enforceCallingOrSelfPermission( 10581 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10582 } 10583 } 10584 10585 int user = UserHandle.getCallingUserId(); 10586 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 10587 mSettings.writePackageRestrictionsLPr(user); 10588 scheduleWriteSettingsLocked(); 10589 } 10590 } 10591 } 10592 10593 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 10594 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 10595 ArrayList<PreferredActivity> removed = null; 10596 boolean changed = false; 10597 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 10598 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 10599 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 10600 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 10601 continue; 10602 } 10603 Iterator<PreferredActivity> it = pir.filterIterator(); 10604 while (it.hasNext()) { 10605 PreferredActivity pa = it.next(); 10606 // Mark entry for removal only if it matches the package name 10607 // and the entry is of type "always". 10608 if (packageName == null || 10609 (pa.mPref.mComponent.getPackageName().equals(packageName) 10610 && pa.mPref.mAlways)) { 10611 if (removed == null) { 10612 removed = new ArrayList<PreferredActivity>(); 10613 } 10614 removed.add(pa); 10615 } 10616 } 10617 if (removed != null) { 10618 for (int j=0; j<removed.size(); j++) { 10619 PreferredActivity pa = removed.get(j); 10620 pir.removeFilter(pa); 10621 } 10622 changed = true; 10623 } 10624 } 10625 return changed; 10626 } 10627 10628 public void resetPreferredActivities(int userId) { 10629 mContext.enforceCallingOrSelfPermission( 10630 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 10631 // writer 10632 synchronized (mPackages) { 10633 int user = UserHandle.getCallingUserId(); 10634 clearPackagePreferredActivitiesLPw(null, user); 10635 mSettings.readDefaultPreferredAppsLPw(this, user); 10636 mSettings.writePackageRestrictionsLPr(user); 10637 scheduleWriteSettingsLocked(); 10638 } 10639 } 10640 10641 public int getPreferredActivities(List<IntentFilter> outFilters, 10642 List<ComponentName> outActivities, String packageName) { 10643 10644 int num = 0; 10645 final int userId = UserHandle.getCallingUserId(); 10646 // reader 10647 synchronized (mPackages) { 10648 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 10649 if (pir != null) { 10650 final Iterator<PreferredActivity> it = pir.filterIterator(); 10651 while (it.hasNext()) { 10652 final PreferredActivity pa = it.next(); 10653 if (packageName == null 10654 || (pa.mPref.mComponent.getPackageName().equals(packageName) 10655 && pa.mPref.mAlways)) { 10656 if (outFilters != null) { 10657 outFilters.add(new IntentFilter(pa)); 10658 } 10659 if (outActivities != null) { 10660 outActivities.add(pa.mPref.mComponent); 10661 } 10662 } 10663 } 10664 } 10665 } 10666 10667 return num; 10668 } 10669 10670 @Override 10671 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 10672 int userId) { 10673 int callingUid = Binder.getCallingUid(); 10674 if (callingUid != Process.SYSTEM_UID) { 10675 throw new SecurityException( 10676 "addPersistentPreferredActivity can only be run by the system"); 10677 } 10678 if (filter.countActions() == 0) { 10679 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 10680 return; 10681 } 10682 synchronized (mPackages) { 10683 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 10684 " :"); 10685 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 10686 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 10687 new PersistentPreferredActivity(filter, activity)); 10688 mSettings.writePackageRestrictionsLPr(userId); 10689 } 10690 } 10691 10692 @Override 10693 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 10694 int callingUid = Binder.getCallingUid(); 10695 if (callingUid != Process.SYSTEM_UID) { 10696 throw new SecurityException( 10697 "clearPackagePersistentPreferredActivities can only be run by the system"); 10698 } 10699 ArrayList<PersistentPreferredActivity> removed = null; 10700 boolean changed = false; 10701 synchronized (mPackages) { 10702 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 10703 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 10704 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 10705 .valueAt(i); 10706 if (userId != thisUserId) { 10707 continue; 10708 } 10709 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 10710 while (it.hasNext()) { 10711 PersistentPreferredActivity ppa = it.next(); 10712 // Mark entry for removal only if it matches the package name. 10713 if (ppa.mComponent.getPackageName().equals(packageName)) { 10714 if (removed == null) { 10715 removed = new ArrayList<PersistentPreferredActivity>(); 10716 } 10717 removed.add(ppa); 10718 } 10719 } 10720 if (removed != null) { 10721 for (int j=0; j<removed.size(); j++) { 10722 PersistentPreferredActivity ppa = removed.get(j); 10723 ppir.removeFilter(ppa); 10724 } 10725 changed = true; 10726 } 10727 } 10728 10729 if (changed) { 10730 mSettings.writePackageRestrictionsLPr(userId); 10731 } 10732 } 10733 } 10734 10735 @Override 10736 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 10737 Intent intent = new Intent(Intent.ACTION_MAIN); 10738 intent.addCategory(Intent.CATEGORY_HOME); 10739 10740 final int callingUserId = UserHandle.getCallingUserId(); 10741 List<ResolveInfo> list = queryIntentActivities(intent, null, 10742 PackageManager.GET_META_DATA, callingUserId); 10743 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 10744 true, false, false, callingUserId); 10745 10746 allHomeCandidates.clear(); 10747 if (list != null) { 10748 for (ResolveInfo ri : list) { 10749 allHomeCandidates.add(ri); 10750 } 10751 } 10752 return (preferred == null || preferred.activityInfo == null) 10753 ? null 10754 : new ComponentName(preferred.activityInfo.packageName, 10755 preferred.activityInfo.name); 10756 } 10757 10758 @Override 10759 public void setApplicationEnabledSetting(String appPackageName, 10760 int newState, int flags, int userId, String callingPackage) { 10761 if (!sUserManager.exists(userId)) return; 10762 if (callingPackage == null) { 10763 callingPackage = Integer.toString(Binder.getCallingUid()); 10764 } 10765 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 10766 } 10767 10768 @Override 10769 public void setComponentEnabledSetting(ComponentName componentName, 10770 int newState, int flags, int userId) { 10771 if (!sUserManager.exists(userId)) return; 10772 setEnabledSetting(componentName.getPackageName(), 10773 componentName.getClassName(), newState, flags, userId, null); 10774 } 10775 10776 private void setEnabledSetting(final String packageName, String className, int newState, 10777 final int flags, int userId, String callingPackage) { 10778 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 10779 || newState == COMPONENT_ENABLED_STATE_ENABLED 10780 || newState == COMPONENT_ENABLED_STATE_DISABLED 10781 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 10782 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 10783 throw new IllegalArgumentException("Invalid new component state: " 10784 + newState); 10785 } 10786 PackageSetting pkgSetting; 10787 final int uid = Binder.getCallingUid(); 10788 final int permission = mContext.checkCallingOrSelfPermission( 10789 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 10790 enforceCrossUserPermission(uid, userId, false, "set enabled"); 10791 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 10792 boolean sendNow = false; 10793 boolean isApp = (className == null); 10794 String componentName = isApp ? packageName : className; 10795 int packageUid = -1; 10796 ArrayList<String> components; 10797 10798 // writer 10799 synchronized (mPackages) { 10800 pkgSetting = mSettings.mPackages.get(packageName); 10801 if (pkgSetting == null) { 10802 if (className == null) { 10803 throw new IllegalArgumentException( 10804 "Unknown package: " + packageName); 10805 } 10806 throw new IllegalArgumentException( 10807 "Unknown component: " + packageName 10808 + "/" + className); 10809 } 10810 // Allow root and verify that userId is not being specified by a different user 10811 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 10812 throw new SecurityException( 10813 "Permission Denial: attempt to change component state from pid=" 10814 + Binder.getCallingPid() 10815 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 10816 } 10817 if (className == null) { 10818 // We're dealing with an application/package level state change 10819 if (pkgSetting.getEnabled(userId) == newState) { 10820 // Nothing to do 10821 return; 10822 } 10823 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 10824 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 10825 // Don't care about who enables an app. 10826 callingPackage = null; 10827 } 10828 pkgSetting.setEnabled(newState, userId, callingPackage); 10829 // pkgSetting.pkg.mSetEnabled = newState; 10830 } else { 10831 // We're dealing with a component level state change 10832 // First, verify that this is a valid class name. 10833 PackageParser.Package pkg = pkgSetting.pkg; 10834 if (pkg == null || !pkg.hasComponentClassName(className)) { 10835 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { 10836 throw new IllegalArgumentException("Component class " + className 10837 + " does not exist in " + packageName); 10838 } else { 10839 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 10840 + className + " does not exist in " + packageName); 10841 } 10842 } 10843 switch (newState) { 10844 case COMPONENT_ENABLED_STATE_ENABLED: 10845 if (!pkgSetting.enableComponentLPw(className, userId)) { 10846 return; 10847 } 10848 break; 10849 case COMPONENT_ENABLED_STATE_DISABLED: 10850 if (!pkgSetting.disableComponentLPw(className, userId)) { 10851 return; 10852 } 10853 break; 10854 case COMPONENT_ENABLED_STATE_DEFAULT: 10855 if (!pkgSetting.restoreComponentLPw(className, userId)) { 10856 return; 10857 } 10858 break; 10859 default: 10860 Slog.e(TAG, "Invalid new component state: " + newState); 10861 return; 10862 } 10863 } 10864 mSettings.writePackageRestrictionsLPr(userId); 10865 components = mPendingBroadcasts.get(userId, packageName); 10866 final boolean newPackage = components == null; 10867 if (newPackage) { 10868 components = new ArrayList<String>(); 10869 } 10870 if (!components.contains(componentName)) { 10871 components.add(componentName); 10872 } 10873 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 10874 sendNow = true; 10875 // Purge entry from pending broadcast list if another one exists already 10876 // since we are sending one right away. 10877 mPendingBroadcasts.remove(userId, packageName); 10878 } else { 10879 if (newPackage) { 10880 mPendingBroadcasts.put(userId, packageName, components); 10881 } 10882 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 10883 // Schedule a message 10884 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 10885 } 10886 } 10887 } 10888 10889 long callingId = Binder.clearCallingIdentity(); 10890 try { 10891 if (sendNow) { 10892 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 10893 sendPackageChangedBroadcast(packageName, 10894 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 10895 } 10896 } finally { 10897 Binder.restoreCallingIdentity(callingId); 10898 } 10899 } 10900 10901 private void sendPackageChangedBroadcast(String packageName, 10902 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 10903 if (DEBUG_INSTALL) 10904 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 10905 + componentNames); 10906 Bundle extras = new Bundle(4); 10907 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 10908 String nameList[] = new String[componentNames.size()]; 10909 componentNames.toArray(nameList); 10910 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 10911 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 10912 extras.putInt(Intent.EXTRA_UID, packageUid); 10913 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null, 10914 new int[] {UserHandle.getUserId(packageUid)}); 10915 } 10916 10917 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 10918 if (!sUserManager.exists(userId)) return; 10919 final int uid = Binder.getCallingUid(); 10920 final int permission = mContext.checkCallingOrSelfPermission( 10921 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 10922 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 10923 enforceCrossUserPermission(uid, userId, true, "stop package"); 10924 // writer 10925 synchronized (mPackages) { 10926 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, 10927 uid, userId)) { 10928 scheduleWritePackageRestrictionsLocked(userId); 10929 } 10930 } 10931 } 10932 10933 public String getInstallerPackageName(String packageName) { 10934 // reader 10935 synchronized (mPackages) { 10936 return mSettings.getInstallerPackageNameLPr(packageName); 10937 } 10938 } 10939 10940 @Override 10941 public int getApplicationEnabledSetting(String packageName, int userId) { 10942 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 10943 int uid = Binder.getCallingUid(); 10944 enforceCrossUserPermission(uid, userId, false, "get enabled"); 10945 // reader 10946 synchronized (mPackages) { 10947 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 10948 } 10949 } 10950 10951 @Override 10952 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 10953 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 10954 int uid = Binder.getCallingUid(); 10955 enforceCrossUserPermission(uid, userId, false, "get component enabled"); 10956 // reader 10957 synchronized (mPackages) { 10958 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 10959 } 10960 } 10961 10962 public void enterSafeMode() { 10963 enforceSystemOrRoot("Only the system can request entering safe mode"); 10964 10965 if (!mSystemReady) { 10966 mSafeMode = true; 10967 } 10968 } 10969 10970 public void systemReady() { 10971 mSystemReady = true; 10972 10973 // Read the compatibilty setting when the system is ready. 10974 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 10975 mContext.getContentResolver(), 10976 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 10977 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 10978 if (DEBUG_SETTINGS) { 10979 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 10980 } 10981 10982 synchronized (mPackages) { 10983 // Verify that all of the preferred activity components actually 10984 // exist. It is possible for applications to be updated and at 10985 // that point remove a previously declared activity component that 10986 // had been set as a preferred activity. We try to clean this up 10987 // the next time we encounter that preferred activity, but it is 10988 // possible for the user flow to never be able to return to that 10989 // situation so here we do a sanity check to make sure we haven't 10990 // left any junk around. 10991 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 10992 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 10993 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 10994 removed.clear(); 10995 for (PreferredActivity pa : pir.filterSet()) { 10996 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 10997 removed.add(pa); 10998 } 10999 } 11000 if (removed.size() > 0) { 11001 for (int j=0; j<removed.size(); j++) { 11002 PreferredActivity pa = removed.get(i); 11003 Slog.w(TAG, "Removing dangling preferred activity: " 11004 + pa.mPref.mComponent); 11005 pir.removeFilter(pa); 11006 } 11007 mSettings.writePackageRestrictionsLPr( 11008 mSettings.mPreferredActivities.keyAt(i)); 11009 } 11010 } 11011 } 11012 sUserManager.systemReady(); 11013 } 11014 11015 public boolean isSafeMode() { 11016 return mSafeMode; 11017 } 11018 11019 public boolean hasSystemUidErrors() { 11020 return mHasSystemUidErrors; 11021 } 11022 11023 static String arrayToString(int[] array) { 11024 StringBuffer buf = new StringBuffer(128); 11025 buf.append('['); 11026 if (array != null) { 11027 for (int i=0; i<array.length; i++) { 11028 if (i > 0) buf.append(", "); 11029 buf.append(array[i]); 11030 } 11031 } 11032 buf.append(']'); 11033 return buf.toString(); 11034 } 11035 11036 static class DumpState { 11037 public static final int DUMP_LIBS = 1 << 0; 11038 11039 public static final int DUMP_FEATURES = 1 << 1; 11040 11041 public static final int DUMP_RESOLVERS = 1 << 2; 11042 11043 public static final int DUMP_PERMISSIONS = 1 << 3; 11044 11045 public static final int DUMP_PACKAGES = 1 << 4; 11046 11047 public static final int DUMP_SHARED_USERS = 1 << 5; 11048 11049 public static final int DUMP_MESSAGES = 1 << 6; 11050 11051 public static final int DUMP_PROVIDERS = 1 << 7; 11052 11053 public static final int DUMP_VERIFIERS = 1 << 8; 11054 11055 public static final int DUMP_PREFERRED = 1 << 9; 11056 11057 public static final int DUMP_PREFERRED_XML = 1 << 10; 11058 11059 public static final int DUMP_KEYSETS = 1 << 11; 11060 11061 public static final int OPTION_SHOW_FILTERS = 1 << 0; 11062 11063 private int mTypes; 11064 11065 private int mOptions; 11066 11067 private boolean mTitlePrinted; 11068 11069 private SharedUserSetting mSharedUser; 11070 11071 public boolean isDumping(int type) { 11072 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 11073 return true; 11074 } 11075 11076 return (mTypes & type) != 0; 11077 } 11078 11079 public void setDump(int type) { 11080 mTypes |= type; 11081 } 11082 11083 public boolean isOptionEnabled(int option) { 11084 return (mOptions & option) != 0; 11085 } 11086 11087 public void setOptionEnabled(int option) { 11088 mOptions |= option; 11089 } 11090 11091 public boolean onTitlePrinted() { 11092 final boolean printed = mTitlePrinted; 11093 mTitlePrinted = true; 11094 return printed; 11095 } 11096 11097 public boolean getTitlePrinted() { 11098 return mTitlePrinted; 11099 } 11100 11101 public void setTitlePrinted(boolean enabled) { 11102 mTitlePrinted = enabled; 11103 } 11104 11105 public SharedUserSetting getSharedUser() { 11106 return mSharedUser; 11107 } 11108 11109 public void setSharedUser(SharedUserSetting user) { 11110 mSharedUser = user; 11111 } 11112 } 11113 11114 @Override 11115 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11116 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 11117 != PackageManager.PERMISSION_GRANTED) { 11118 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11119 + Binder.getCallingPid() 11120 + ", uid=" + Binder.getCallingUid() 11121 + " without permission " 11122 + android.Manifest.permission.DUMP); 11123 return; 11124 } 11125 11126 DumpState dumpState = new DumpState(); 11127 boolean fullPreferred = false; 11128 boolean checkin = false; 11129 11130 String packageName = null; 11131 11132 int opti = 0; 11133 while (opti < args.length) { 11134 String opt = args[opti]; 11135 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11136 break; 11137 } 11138 opti++; 11139 if ("-a".equals(opt)) { 11140 // Right now we only know how to print all. 11141 } else if ("-h".equals(opt)) { 11142 pw.println("Package manager dump options:"); 11143 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 11144 pw.println(" --checkin: dump for a checkin"); 11145 pw.println(" -f: print details of intent filters"); 11146 pw.println(" -h: print this help"); 11147 pw.println(" cmd may be one of:"); 11148 pw.println(" l[ibraries]: list known shared libraries"); 11149 pw.println(" f[ibraries]: list device features"); 11150 pw.println(" r[esolvers]: dump intent resolvers"); 11151 pw.println(" perm[issions]: dump permissions"); 11152 pw.println(" pref[erred]: print preferred package settings"); 11153 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 11154 pw.println(" prov[iders]: dump content providers"); 11155 pw.println(" p[ackages]: dump installed packages"); 11156 pw.println(" s[hared-users]: dump shared user IDs"); 11157 pw.println(" m[essages]: print collected runtime messages"); 11158 pw.println(" v[erifiers]: print package verifier info"); 11159 pw.println(" <package.name>: info about given package"); 11160 pw.println(" k[eysets]: print known keysets"); 11161 return; 11162 } else if ("--checkin".equals(opt)) { 11163 checkin = true; 11164 } else if ("-f".equals(opt)) { 11165 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 11166 } else { 11167 pw.println("Unknown argument: " + opt + "; use -h for help"); 11168 } 11169 } 11170 11171 // Is the caller requesting to dump a particular piece of data? 11172 if (opti < args.length) { 11173 String cmd = args[opti]; 11174 opti++; 11175 // Is this a package name? 11176 if ("android".equals(cmd) || cmd.contains(".")) { 11177 packageName = cmd; 11178 // When dumping a single package, we always dump all of its 11179 // filter information since the amount of data will be reasonable. 11180 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 11181 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 11182 dumpState.setDump(DumpState.DUMP_LIBS); 11183 } else if ("f".equals(cmd) || "features".equals(cmd)) { 11184 dumpState.setDump(DumpState.DUMP_FEATURES); 11185 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 11186 dumpState.setDump(DumpState.DUMP_RESOLVERS); 11187 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 11188 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 11189 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 11190 dumpState.setDump(DumpState.DUMP_PREFERRED); 11191 } else if ("preferred-xml".equals(cmd)) { 11192 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 11193 if (opti < args.length && "--full".equals(args[opti])) { 11194 fullPreferred = true; 11195 opti++; 11196 } 11197 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 11198 dumpState.setDump(DumpState.DUMP_PACKAGES); 11199 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 11200 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 11201 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 11202 dumpState.setDump(DumpState.DUMP_PROVIDERS); 11203 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 11204 dumpState.setDump(DumpState.DUMP_MESSAGES); 11205 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 11206 dumpState.setDump(DumpState.DUMP_VERIFIERS); 11207 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 11208 dumpState.setDump(DumpState.DUMP_KEYSETS); 11209 } 11210 } 11211 11212 if (checkin) { 11213 pw.println("vers,1"); 11214 } 11215 11216 // reader 11217 synchronized (mPackages) { 11218 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 11219 if (!checkin) { 11220 if (dumpState.onTitlePrinted()) 11221 pw.println(); 11222 pw.println("Verifiers:"); 11223 pw.print(" Required: "); 11224 pw.print(mRequiredVerifierPackage); 11225 pw.print(" (uid="); 11226 pw.print(getPackageUid(mRequiredVerifierPackage, 0)); 11227 pw.println(")"); 11228 } else if (mRequiredVerifierPackage != null) { 11229 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 11230 pw.print(","); pw.println(getPackageUid(mRequiredVerifierPackage, 0)); 11231 } 11232 } 11233 11234 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 11235 boolean printedHeader = false; 11236 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 11237 while (it.hasNext()) { 11238 String name = it.next(); 11239 SharedLibraryEntry ent = mSharedLibraries.get(name); 11240 if (!checkin) { 11241 if (!printedHeader) { 11242 if (dumpState.onTitlePrinted()) 11243 pw.println(); 11244 pw.println("Libraries:"); 11245 printedHeader = true; 11246 } 11247 pw.print(" "); 11248 } else { 11249 pw.print("lib,"); 11250 } 11251 pw.print(name); 11252 if (!checkin) { 11253 pw.print(" -> "); 11254 } 11255 if (ent.path != null) { 11256 if (!checkin) { 11257 pw.print("(jar) "); 11258 pw.print(ent.path); 11259 } else { 11260 pw.print(",jar,"); 11261 pw.print(ent.path); 11262 } 11263 } else { 11264 if (!checkin) { 11265 pw.print("(apk) "); 11266 pw.print(ent.apk); 11267 } else { 11268 pw.print(",apk,"); 11269 pw.print(ent.apk); 11270 } 11271 } 11272 pw.println(); 11273 } 11274 } 11275 11276 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 11277 if (dumpState.onTitlePrinted()) 11278 pw.println(); 11279 if (!checkin) { 11280 pw.println("Features:"); 11281 } 11282 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 11283 while (it.hasNext()) { 11284 String name = it.next(); 11285 if (!checkin) { 11286 pw.print(" "); 11287 } else { 11288 pw.print("feat,"); 11289 } 11290 pw.println(name); 11291 } 11292 } 11293 11294 if (!checkin && dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 11295 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 11296 : "Activity Resolver Table:", " ", packageName, 11297 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 11298 dumpState.setTitlePrinted(true); 11299 } 11300 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 11301 : "Receiver Resolver Table:", " ", packageName, 11302 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 11303 dumpState.setTitlePrinted(true); 11304 } 11305 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 11306 : "Service Resolver Table:", " ", packageName, 11307 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 11308 dumpState.setTitlePrinted(true); 11309 } 11310 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 11311 : "Provider Resolver Table:", " ", packageName, 11312 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 11313 dumpState.setTitlePrinted(true); 11314 } 11315 } 11316 11317 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 11318 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 11319 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 11320 int user = mSettings.mPreferredActivities.keyAt(i); 11321 if (pir.dump(pw, 11322 dumpState.getTitlePrinted() 11323 ? "\nPreferred Activities User " + user + ":" 11324 : "Preferred Activities User " + user + ":", " ", 11325 packageName, true)) { 11326 dumpState.setTitlePrinted(true); 11327 } 11328 } 11329 } 11330 11331 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 11332 pw.flush(); 11333 FileOutputStream fout = new FileOutputStream(fd); 11334 BufferedOutputStream str = new BufferedOutputStream(fout); 11335 XmlSerializer serializer = new FastXmlSerializer(); 11336 try { 11337 serializer.setOutput(str, "utf-8"); 11338 serializer.startDocument(null, true); 11339 serializer.setFeature( 11340 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 11341 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 11342 serializer.endDocument(); 11343 serializer.flush(); 11344 } catch (IllegalArgumentException e) { 11345 pw.println("Failed writing: " + e); 11346 } catch (IllegalStateException e) { 11347 pw.println("Failed writing: " + e); 11348 } catch (IOException e) { 11349 pw.println("Failed writing: " + e); 11350 } 11351 } 11352 11353 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 11354 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 11355 } 11356 11357 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 11358 boolean printedSomething = false; 11359 for (PackageParser.Provider p : mProviders.mProviders.values()) { 11360 if (packageName != null && !packageName.equals(p.info.packageName)) { 11361 continue; 11362 } 11363 if (!printedSomething) { 11364 if (dumpState.onTitlePrinted()) 11365 pw.println(); 11366 pw.println("Registered ContentProviders:"); 11367 printedSomething = true; 11368 } 11369 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 11370 pw.print(" "); pw.println(p.toString()); 11371 } 11372 printedSomething = false; 11373 for (Map.Entry<String, PackageParser.Provider> entry : 11374 mProvidersByAuthority.entrySet()) { 11375 PackageParser.Provider p = entry.getValue(); 11376 if (packageName != null && !packageName.equals(p.info.packageName)) { 11377 continue; 11378 } 11379 if (!printedSomething) { 11380 if (dumpState.onTitlePrinted()) 11381 pw.println(); 11382 pw.println("ContentProvider Authorities:"); 11383 printedSomething = true; 11384 } 11385 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 11386 pw.print(" "); pw.println(p.toString()); 11387 if (p.info != null && p.info.applicationInfo != null) { 11388 final String appInfo = p.info.applicationInfo.toString(); 11389 pw.print(" applicationInfo="); pw.println(appInfo); 11390 } 11391 } 11392 } 11393 11394 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 11395 mSettings.mKeySetManager.dump(pw, packageName, dumpState); 11396 } 11397 11398 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 11399 mSettings.dumpPackagesLPr(pw, packageName, dumpState, checkin); 11400 } 11401 11402 if (!checkin && dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 11403 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState); 11404 } 11405 11406 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 11407 if (dumpState.onTitlePrinted()) 11408 pw.println(); 11409 mSettings.dumpReadMessagesLPr(pw, dumpState); 11410 11411 pw.println(); 11412 pw.println("Package warning messages:"); 11413 final File fname = getSettingsProblemFile(); 11414 FileInputStream in = null; 11415 try { 11416 in = new FileInputStream(fname); 11417 final int avail = in.available(); 11418 final byte[] data = new byte[avail]; 11419 in.read(data); 11420 pw.print(new String(data)); 11421 } catch (FileNotFoundException e) { 11422 } catch (IOException e) { 11423 } finally { 11424 if (in != null) { 11425 try { 11426 in.close(); 11427 } catch (IOException e) { 11428 } 11429 } 11430 } 11431 } 11432 } 11433 } 11434 11435 // ------- apps on sdcard specific code ------- 11436 static final boolean DEBUG_SD_INSTALL = false; 11437 11438 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 11439 11440 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 11441 11442 private boolean mMediaMounted = false; 11443 11444 private String getEncryptKey() { 11445 try { 11446 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 11447 SD_ENCRYPTION_KEYSTORE_NAME); 11448 if (sdEncKey == null) { 11449 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 11450 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 11451 if (sdEncKey == null) { 11452 Slog.e(TAG, "Failed to create encryption keys"); 11453 return null; 11454 } 11455 } 11456 return sdEncKey; 11457 } catch (NoSuchAlgorithmException nsae) { 11458 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 11459 return null; 11460 } catch (IOException ioe) { 11461 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 11462 return null; 11463 } 11464 11465 } 11466 11467 /* package */static String getTempContainerId() { 11468 int tmpIdx = 1; 11469 String list[] = PackageHelper.getSecureContainerList(); 11470 if (list != null) { 11471 for (final String name : list) { 11472 // Ignore null and non-temporary container entries 11473 if (name == null || !name.startsWith(mTempContainerPrefix)) { 11474 continue; 11475 } 11476 11477 String subStr = name.substring(mTempContainerPrefix.length()); 11478 try { 11479 int cid = Integer.parseInt(subStr); 11480 if (cid >= tmpIdx) { 11481 tmpIdx = cid + 1; 11482 } 11483 } catch (NumberFormatException e) { 11484 } 11485 } 11486 } 11487 return mTempContainerPrefix + tmpIdx; 11488 } 11489 11490 /* 11491 * Update media status on PackageManager. 11492 */ 11493 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 11494 int callingUid = Binder.getCallingUid(); 11495 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 11496 throw new SecurityException("Media status can only be updated by the system"); 11497 } 11498 // reader; this apparently protects mMediaMounted, but should probably 11499 // be a different lock in that case. 11500 synchronized (mPackages) { 11501 Log.i(TAG, "Updating external media status from " 11502 + (mMediaMounted ? "mounted" : "unmounted") + " to " 11503 + (mediaStatus ? "mounted" : "unmounted")); 11504 if (DEBUG_SD_INSTALL) 11505 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 11506 + ", mMediaMounted=" + mMediaMounted); 11507 if (mediaStatus == mMediaMounted) { 11508 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 11509 : 0, -1); 11510 mHandler.sendMessage(msg); 11511 return; 11512 } 11513 mMediaMounted = mediaStatus; 11514 } 11515 // Queue up an async operation since the package installation may take a 11516 // little while. 11517 mHandler.post(new Runnable() { 11518 public void run() { 11519 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 11520 } 11521 }); 11522 } 11523 11524 /** 11525 * Called by MountService when the initial ASECs to scan are available. 11526 * Should block until all the ASEC containers are finished being scanned. 11527 */ 11528 public void scanAvailableAsecs() { 11529 updateExternalMediaStatusInner(true, false, false); 11530 if (mShouldRestoreconData) { 11531 SELinuxMMAC.setRestoreconDone(); 11532 mShouldRestoreconData = false; 11533 } 11534 } 11535 11536 /* 11537 * Collect information of applications on external media, map them against 11538 * existing containers and update information based on current mount status. 11539 * Please note that we always have to report status if reportStatus has been 11540 * set to true especially when unloading packages. 11541 */ 11542 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 11543 boolean externalStorage) { 11544 // Collection of uids 11545 int uidArr[] = null; 11546 // Collection of stale containers 11547 HashSet<String> removeCids = new HashSet<String>(); 11548 // Collection of packages on external media with valid containers. 11549 HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>(); 11550 // Get list of secure containers. 11551 final String list[] = PackageHelper.getSecureContainerList(); 11552 if (list == null || list.length == 0) { 11553 Log.i(TAG, "No secure containers on sdcard"); 11554 } else { 11555 // Process list of secure containers and categorize them 11556 // as active or stale based on their package internal state. 11557 int uidList[] = new int[list.length]; 11558 int num = 0; 11559 // reader 11560 synchronized (mPackages) { 11561 for (String cid : list) { 11562 if (DEBUG_SD_INSTALL) 11563 Log.i(TAG, "Processing container " + cid); 11564 String pkgName = getAsecPackageName(cid); 11565 if (pkgName == null) { 11566 if (DEBUG_SD_INSTALL) 11567 Log.i(TAG, "Container : " + cid + " stale"); 11568 removeCids.add(cid); 11569 continue; 11570 } 11571 if (DEBUG_SD_INSTALL) 11572 Log.i(TAG, "Looking for pkg : " + pkgName); 11573 11574 final PackageSetting ps = mSettings.mPackages.get(pkgName); 11575 if (ps == null) { 11576 Log.i(TAG, "Deleting container with no matching settings " + cid); 11577 removeCids.add(cid); 11578 continue; 11579 } 11580 11581 /* 11582 * Skip packages that are not external if we're unmounting 11583 * external storage. 11584 */ 11585 if (externalStorage && !isMounted && !isExternal(ps)) { 11586 continue; 11587 } 11588 11589 final AsecInstallArgs args = new AsecInstallArgs(cid, isForwardLocked(ps)); 11590 // The package status is changed only if the code path 11591 // matches between settings and the container id. 11592 if (ps.codePathString != null && ps.codePathString.equals(args.getCodePath())) { 11593 if (DEBUG_SD_INSTALL) { 11594 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 11595 + " at code path: " + ps.codePathString); 11596 } 11597 11598 // We do have a valid package installed on sdcard 11599 processCids.put(args, ps.codePathString); 11600 final int uid = ps.appId; 11601 if (uid != -1) { 11602 uidList[num++] = uid; 11603 } 11604 } else { 11605 Log.i(TAG, "Deleting stale container for " + cid); 11606 removeCids.add(cid); 11607 } 11608 } 11609 } 11610 11611 if (num > 0) { 11612 // Sort uid list 11613 Arrays.sort(uidList, 0, num); 11614 // Throw away duplicates 11615 uidArr = new int[num]; 11616 uidArr[0] = uidList[0]; 11617 int di = 0; 11618 for (int i = 1; i < num; i++) { 11619 if (uidList[i - 1] != uidList[i]) { 11620 uidArr[di++] = uidList[i]; 11621 } 11622 } 11623 } 11624 } 11625 // Process packages with valid entries. 11626 if (isMounted) { 11627 if (DEBUG_SD_INSTALL) 11628 Log.i(TAG, "Loading packages"); 11629 loadMediaPackages(processCids, uidArr, removeCids); 11630 startCleaningPackages(); 11631 } else { 11632 if (DEBUG_SD_INSTALL) 11633 Log.i(TAG, "Unloading packages"); 11634 unloadMediaPackages(processCids, uidArr, reportStatus); 11635 } 11636 } 11637 11638 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 11639 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 11640 int size = pkgList.size(); 11641 if (size > 0) { 11642 // Send broadcasts here 11643 Bundle extras = new Bundle(); 11644 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList 11645 .toArray(new String[size])); 11646 if (uidArr != null) { 11647 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 11648 } 11649 if (replacing) { 11650 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 11651 } 11652 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 11653 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 11654 sendPackageBroadcast(action, null, extras, null, finishedReceiver, null); 11655 } 11656 } 11657 11658 /* 11659 * Look at potentially valid container ids from processCids If package 11660 * information doesn't match the one on record or package scanning fails, 11661 * the cid is added to list of removeCids. We currently don't delete stale 11662 * containers. 11663 */ 11664 private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], 11665 HashSet<String> removeCids) { 11666 ArrayList<String> pkgList = new ArrayList<String>(); 11667 Set<AsecInstallArgs> keys = processCids.keySet(); 11668 boolean doGc = false; 11669 for (AsecInstallArgs args : keys) { 11670 String codePath = processCids.get(args); 11671 if (DEBUG_SD_INSTALL) 11672 Log.i(TAG, "Loading container : " + args.cid); 11673 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 11674 try { 11675 // Make sure there are no container errors first. 11676 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 11677 Slog.e(TAG, "Failed to mount cid : " + args.cid 11678 + " when installing from sdcard"); 11679 continue; 11680 } 11681 // Check code path here. 11682 if (codePath == null || !codePath.equals(args.getCodePath())) { 11683 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 11684 + " does not match one in settings " + codePath); 11685 continue; 11686 } 11687 // Parse package 11688 int parseFlags = mDefParseFlags; 11689 if (args.isExternal()) { 11690 parseFlags |= PackageParser.PARSE_ON_SDCARD; 11691 } 11692 if (args.isFwdLocked()) { 11693 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 11694 } 11695 11696 doGc = true; 11697 synchronized (mInstallLock) { 11698 final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags, 11699 0, 0, null); 11700 // Scan the package 11701 if (pkg != null) { 11702 /* 11703 * TODO why is the lock being held? doPostInstall is 11704 * called in other places without the lock. This needs 11705 * to be straightened out. 11706 */ 11707 // writer 11708 synchronized (mPackages) { 11709 retCode = PackageManager.INSTALL_SUCCEEDED; 11710 pkgList.add(pkg.packageName); 11711 // Post process args 11712 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 11713 pkg.applicationInfo.uid); 11714 } 11715 } else { 11716 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 11717 } 11718 } 11719 11720 } finally { 11721 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 11722 // Don't destroy container here. Wait till gc clears things 11723 // up. 11724 removeCids.add(args.cid); 11725 } 11726 } 11727 } 11728 // writer 11729 synchronized (mPackages) { 11730 // If the platform SDK has changed since the last time we booted, 11731 // we need to re-grant app permission to catch any new ones that 11732 // appear. This is really a hack, and means that apps can in some 11733 // cases get permissions that the user didn't initially explicitly 11734 // allow... it would be nice to have some better way to handle 11735 // this situation. 11736 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 11737 if (regrantPermissions) 11738 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 11739 + mSdkVersion + "; regranting permissions for external storage"); 11740 mSettings.mExternalSdkPlatform = mSdkVersion; 11741 11742 // Make sure group IDs have been assigned, and any permission 11743 // changes in other apps are accounted for 11744 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 11745 | (regrantPermissions 11746 ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL) 11747 : 0)); 11748 // can downgrade to reader 11749 // Persist settings 11750 mSettings.writeLPr(); 11751 } 11752 // Send a broadcast to let everyone know we are done processing 11753 if (pkgList.size() > 0) { 11754 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 11755 } 11756 // Force gc to avoid any stale parser references that we might have. 11757 if (doGc) { 11758 Runtime.getRuntime().gc(); 11759 } 11760 // List stale containers and destroy stale temporary containers. 11761 if (removeCids != null) { 11762 for (String cid : removeCids) { 11763 if (cid.startsWith(mTempContainerPrefix)) { 11764 Log.i(TAG, "Destroying stale temporary container " + cid); 11765 PackageHelper.destroySdDir(cid); 11766 } else { 11767 Log.w(TAG, "Container " + cid + " is stale"); 11768 } 11769 } 11770 } 11771 } 11772 11773 /* 11774 * Utility method to unload a list of specified containers 11775 */ 11776 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 11777 // Just unmount all valid containers. 11778 for (AsecInstallArgs arg : cidArgs) { 11779 synchronized (mInstallLock) { 11780 arg.doPostDeleteLI(false); 11781 } 11782 } 11783 } 11784 11785 /* 11786 * Unload packages mounted on external media. This involves deleting package 11787 * data from internal structures, sending broadcasts about diabled packages, 11788 * gc'ing to free up references, unmounting all secure containers 11789 * corresponding to packages on external media, and posting a 11790 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 11791 * that we always have to post this message if status has been requested no 11792 * matter what. 11793 */ 11794 private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], 11795 final boolean reportStatus) { 11796 if (DEBUG_SD_INSTALL) 11797 Log.i(TAG, "unloading media packages"); 11798 ArrayList<String> pkgList = new ArrayList<String>(); 11799 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 11800 final Set<AsecInstallArgs> keys = processCids.keySet(); 11801 for (AsecInstallArgs args : keys) { 11802 String pkgName = args.getPackageName(); 11803 if (DEBUG_SD_INSTALL) 11804 Log.i(TAG, "Trying to unload pkg : " + pkgName); 11805 // Delete package internally 11806 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 11807 synchronized (mInstallLock) { 11808 boolean res = deletePackageLI(pkgName, null, false, null, null, 11809 PackageManager.DELETE_KEEP_DATA, outInfo, false); 11810 if (res) { 11811 pkgList.add(pkgName); 11812 } else { 11813 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 11814 failedList.add(args); 11815 } 11816 } 11817 } 11818 11819 // reader 11820 synchronized (mPackages) { 11821 // We didn't update the settings after removing each package; 11822 // write them now for all packages. 11823 mSettings.writeLPr(); 11824 } 11825 11826 // We have to absolutely send UPDATED_MEDIA_STATUS only 11827 // after confirming that all the receivers processed the ordered 11828 // broadcast when packages get disabled, force a gc to clean things up. 11829 // and unload all the containers. 11830 if (pkgList.size() > 0) { 11831 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 11832 new IIntentReceiver.Stub() { 11833 public void performReceive(Intent intent, int resultCode, String data, 11834 Bundle extras, boolean ordered, boolean sticky, 11835 int sendingUser) throws RemoteException { 11836 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 11837 reportStatus ? 1 : 0, 1, keys); 11838 mHandler.sendMessage(msg); 11839 } 11840 }); 11841 } else { 11842 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 11843 keys); 11844 mHandler.sendMessage(msg); 11845 } 11846 } 11847 11848 /** Binder call */ 11849 @Override 11850 public void movePackage(final String packageName, final IPackageMoveObserver observer, 11851 final int flags) { 11852 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 11853 UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 11854 int returnCode = PackageManager.MOVE_SUCCEEDED; 11855 int currFlags = 0; 11856 int newFlags = 0; 11857 // reader 11858 synchronized (mPackages) { 11859 PackageParser.Package pkg = mPackages.get(packageName); 11860 if (pkg == null) { 11861 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 11862 } else { 11863 // Disable moving fwd locked apps and system packages 11864 if (pkg.applicationInfo != null && isSystemApp(pkg)) { 11865 Slog.w(TAG, "Cannot move system application"); 11866 returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 11867 } else if (pkg.mOperationPending) { 11868 Slog.w(TAG, "Attempt to move package which has pending operations"); 11869 returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING; 11870 } else { 11871 // Find install location first 11872 if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 11873 && (flags & PackageManager.MOVE_INTERNAL) != 0) { 11874 Slog.w(TAG, "Ambigous flags specified for move location."); 11875 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 11876 } else { 11877 newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL 11878 : PackageManager.INSTALL_INTERNAL; 11879 currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL 11880 : PackageManager.INSTALL_INTERNAL; 11881 11882 if (newFlags == currFlags) { 11883 Slog.w(TAG, "No move required. Trying to move to same location"); 11884 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 11885 } else { 11886 if (isForwardLocked(pkg)) { 11887 currFlags |= PackageManager.INSTALL_FORWARD_LOCK; 11888 newFlags |= PackageManager.INSTALL_FORWARD_LOCK; 11889 } 11890 } 11891 } 11892 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 11893 pkg.mOperationPending = true; 11894 } 11895 } 11896 } 11897 11898 /* 11899 * TODO this next block probably shouldn't be inside the lock. We 11900 * can't guarantee these won't change after this is fired off 11901 * anyway. 11902 */ 11903 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 11904 processPendingMove(new MoveParams(null, observer, 0, packageName, 11905 null, -1, user), 11906 returnCode); 11907 } else { 11908 Message msg = mHandler.obtainMessage(INIT_COPY); 11909 InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir, 11910 pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir); 11911 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName, 11912 pkg.applicationInfo.dataDir, pkg.applicationInfo.uid, user); 11913 msg.obj = mp; 11914 mHandler.sendMessage(msg); 11915 } 11916 } 11917 } 11918 11919 private void processPendingMove(final MoveParams mp, final int currentStatus) { 11920 // Queue up an async operation since the package deletion may take a 11921 // little while. 11922 mHandler.post(new Runnable() { 11923 public void run() { 11924 // TODO fix this; this does nothing. 11925 mHandler.removeCallbacks(this); 11926 int returnCode = currentStatus; 11927 if (currentStatus == PackageManager.MOVE_SUCCEEDED) { 11928 int uidArr[] = null; 11929 ArrayList<String> pkgList = null; 11930 synchronized (mPackages) { 11931 PackageParser.Package pkg = mPackages.get(mp.packageName); 11932 if (pkg == null) { 11933 Slog.w(TAG, " Package " + mp.packageName 11934 + " doesn't exist. Aborting move"); 11935 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 11936 } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) { 11937 Slog.w(TAG, "Package " + mp.packageName + " code path changed from " 11938 + mp.srcArgs.getCodePath() + " to " 11939 + pkg.applicationInfo.sourceDir 11940 + " Aborting move and returning error"); 11941 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 11942 } else { 11943 uidArr = new int[] { 11944 pkg.applicationInfo.uid 11945 }; 11946 pkgList = new ArrayList<String>(); 11947 pkgList.add(mp.packageName); 11948 } 11949 } 11950 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 11951 // Send resources unavailable broadcast 11952 sendResourcesChangedBroadcast(false, true, pkgList, uidArr, null); 11953 // Update package code and resource paths 11954 synchronized (mInstallLock) { 11955 synchronized (mPackages) { 11956 PackageParser.Package pkg = mPackages.get(mp.packageName); 11957 // Recheck for package again. 11958 if (pkg == null) { 11959 Slog.w(TAG, " Package " + mp.packageName 11960 + " doesn't exist. Aborting move"); 11961 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 11962 } else if (!mp.srcArgs.getCodePath().equals( 11963 pkg.applicationInfo.sourceDir)) { 11964 Slog.w(TAG, "Package " + mp.packageName 11965 + " code path changed from " + mp.srcArgs.getCodePath() 11966 + " to " + pkg.applicationInfo.sourceDir 11967 + " Aborting move and returning error"); 11968 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 11969 } else { 11970 final String oldCodePath = pkg.mPath; 11971 final String newCodePath = mp.targetArgs.getCodePath(); 11972 final String newResPath = mp.targetArgs.getResourcePath(); 11973 final String newNativePath = mp.targetArgs 11974 .getNativeLibraryPath(); 11975 11976 final File newNativeDir = new File(newNativePath); 11977 11978 if (!isForwardLocked(pkg) && !isExternal(pkg)) { 11979 // NOTE: We do not report any errors from the APK scan and library 11980 // copy at this point. 11981 NativeLibraryHelper.ApkHandle handle = 11982 new NativeLibraryHelper.ApkHandle(newCodePath); 11983 final int abi = NativeLibraryHelper.findSupportedAbi( 11984 handle, Build.SUPPORTED_ABIS); 11985 if (abi >= 0) { 11986 NativeLibraryHelper.copyNativeBinariesIfNeededLI( 11987 handle, newNativeDir, Build.SUPPORTED_ABIS[abi]); 11988 } 11989 handle.close(); 11990 } 11991 final int[] users = sUserManager.getUserIds(); 11992 for (int user : users) { 11993 if (mInstaller.linkNativeLibraryDirectory(pkg.packageName, 11994 newNativePath, user) < 0) { 11995 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 11996 } 11997 } 11998 11999 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 12000 pkg.mPath = newCodePath; 12001 // Move dex files around 12002 if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) { 12003 // Moving of dex files failed. Set 12004 // error code and abort move. 12005 pkg.mPath = pkg.mScanPath; 12006 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 12007 } 12008 } 12009 12010 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 12011 pkg.mScanPath = newCodePath; 12012 pkg.applicationInfo.sourceDir = newCodePath; 12013 pkg.applicationInfo.publicSourceDir = newResPath; 12014 pkg.applicationInfo.nativeLibraryDir = newNativePath; 12015 PackageSetting ps = (PackageSetting) pkg.mExtras; 12016 ps.codePath = new File(pkg.applicationInfo.sourceDir); 12017 ps.codePathString = ps.codePath.getPath(); 12018 ps.resourcePath = new File( 12019 pkg.applicationInfo.publicSourceDir); 12020 ps.resourcePathString = ps.resourcePath.getPath(); 12021 ps.nativeLibraryPathString = newNativePath; 12022 // Set the application info flag 12023 // correctly. 12024 if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) { 12025 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE; 12026 } else { 12027 pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE; 12028 } 12029 ps.setFlags(pkg.applicationInfo.flags); 12030 mAppDirs.remove(oldCodePath); 12031 mAppDirs.put(newCodePath, pkg); 12032 // Persist settings 12033 mSettings.writeLPr(); 12034 } 12035 } 12036 } 12037 } 12038 // Send resources available broadcast 12039 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 12040 } 12041 } 12042 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 12043 // Clean up failed installation 12044 if (mp.targetArgs != null) { 12045 mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, 12046 -1); 12047 } 12048 } else { 12049 // Force a gc to clear things up. 12050 Runtime.getRuntime().gc(); 12051 // Delete older code 12052 synchronized (mInstallLock) { 12053 mp.srcArgs.doPostDeleteLI(true); 12054 } 12055 } 12056 12057 // Allow more operations on this file if we didn't fail because 12058 // an operation was already pending for this package. 12059 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) { 12060 synchronized (mPackages) { 12061 PackageParser.Package pkg = mPackages.get(mp.packageName); 12062 if (pkg != null) { 12063 pkg.mOperationPending = false; 12064 } 12065 } 12066 } 12067 12068 IPackageMoveObserver observer = mp.observer; 12069 if (observer != null) { 12070 try { 12071 observer.packageMoved(mp.packageName, returnCode); 12072 } catch (RemoteException e) { 12073 Log.i(TAG, "Observer no longer exists."); 12074 } 12075 } 12076 } 12077 }); 12078 } 12079 12080 public boolean setInstallLocation(int loc) { 12081 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 12082 null); 12083 if (getInstallLocation() == loc) { 12084 return true; 12085 } 12086 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 12087 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 12088 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 12089 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 12090 return true; 12091 } 12092 return false; 12093 } 12094 12095 public int getInstallLocation() { 12096 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12097 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 12098 PackageHelper.APP_INSTALL_AUTO); 12099 } 12100 12101 /** Called by UserManagerService */ 12102 void cleanUpUserLILPw(int userHandle) { 12103 mDirtyUsers.remove(userHandle); 12104 mSettings.removeUserLPr(userHandle); 12105 mPendingBroadcasts.remove(userHandle); 12106 if (mInstaller != null) { 12107 // Technically, we shouldn't be doing this with the package lock 12108 // held. However, this is very rare, and there is already so much 12109 // other disk I/O going on, that we'll let it slide for now. 12110 mInstaller.removeUserDataDirs(userHandle); 12111 } 12112 } 12113 12114 /** Called by UserManagerService */ 12115 void createNewUserLILPw(int userHandle, File path) { 12116 if (mInstaller != null) { 12117 mSettings.createNewUserLILPw(this, mInstaller, userHandle, path); 12118 } 12119 } 12120 12121 @Override 12122 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 12123 mContext.enforceCallingOrSelfPermission( 12124 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12125 "Only package verification agents can read the verifier device identity"); 12126 12127 synchronized (mPackages) { 12128 return mSettings.getVerifierDeviceIdentityLPw(); 12129 } 12130 } 12131 12132 @Override 12133 public void setPermissionEnforced(String permission, boolean enforced) { 12134 mContext.enforceCallingOrSelfPermission(GRANT_REVOKE_PERMISSIONS, null); 12135 if (READ_EXTERNAL_STORAGE.equals(permission)) { 12136 synchronized (mPackages) { 12137 if (mSettings.mReadExternalStorageEnforced == null 12138 || mSettings.mReadExternalStorageEnforced != enforced) { 12139 mSettings.mReadExternalStorageEnforced = enforced; 12140 mSettings.writeLPr(); 12141 } 12142 } 12143 // kill any non-foreground processes so we restart them and 12144 // grant/revoke the GID. 12145 final IActivityManager am = ActivityManagerNative.getDefault(); 12146 if (am != null) { 12147 final long token = Binder.clearCallingIdentity(); 12148 try { 12149 am.killProcessesBelowForeground("setPermissionEnforcement"); 12150 } catch (RemoteException e) { 12151 } finally { 12152 Binder.restoreCallingIdentity(token); 12153 } 12154 } 12155 } else { 12156 throw new IllegalArgumentException("No selective enforcement for " + permission); 12157 } 12158 } 12159 12160 @Override 12161 @Deprecated 12162 public boolean isPermissionEnforced(String permission) { 12163 return true; 12164 } 12165 12166 @Override 12167 public boolean isStorageLow() { 12168 final long token = Binder.clearCallingIdentity(); 12169 try { 12170 final DeviceStorageMonitorInternal 12171 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 12172 if (dsm != null) { 12173 return dsm.isMemoryLow(); 12174 } else { 12175 return false; 12176 } 12177 } finally { 12178 Binder.restoreCallingIdentity(token); 12179 } 12180 } 12181} 12182