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