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