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