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; 18 19 import com.android.internal.app.IMediaContainerService; 20 import com.android.internal.app.ResolverActivity; 21 import com.android.internal.content.NativeLibraryHelper; 22 import com.android.internal.content.PackageHelper; 23 import com.android.internal.util.FastXmlSerializer; 24 import com.android.internal.util.JournaledFile; 25 import com.android.internal.util.XmlUtils; 26 27 import org.xmlpull.v1.XmlPullParser; 28 import org.xmlpull.v1.XmlPullParserException; 29 import org.xmlpull.v1.XmlSerializer; 30 31 import android.app.ActivityManagerNative; 32 import android.app.IActivityManager; 33 import android.app.admin.IDevicePolicyManager; 34 import android.app.backup.IBackupManager; 35 import android.content.Context; 36 import android.content.ComponentName; 37 import android.content.IIntentReceiver; 38 import android.content.Intent; 39 import android.content.IntentFilter; 40 import android.content.IntentSender; 41 import android.content.ServiceConnection; 42 import android.content.IntentSender.SendIntentException; 43 import android.content.pm.ActivityInfo; 44 import android.content.pm.ApplicationInfo; 45 import android.content.pm.ComponentInfo; 46 import android.content.pm.FeatureInfo; 47 import android.content.pm.IPackageDataObserver; 48 import android.content.pm.IPackageDeleteObserver; 49 import android.content.pm.IPackageInstallObserver; 50 import android.content.pm.IPackageManager; 51 import android.content.pm.IPackageMoveObserver; 52 import android.content.pm.IPackageStatsObserver; 53 import android.content.pm.InstrumentationInfo; 54 import android.content.pm.PackageInfo; 55 import android.content.pm.PackageInfoLite; 56 import android.content.pm.PackageManager; 57 import android.content.pm.PackageStats; 58 import android.content.pm.ParceledListSlice; 59 60 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 61 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 62 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 63 import android.content.pm.PackageParser; 64 import android.content.pm.PermissionInfo; 65 import android.content.pm.PermissionGroupInfo; 66 import android.content.pm.ProviderInfo; 67 import android.content.pm.ResolveInfo; 68 import android.content.pm.ServiceInfo; 69 import android.content.pm.Signature; 70 import android.net.Uri; 71 import android.os.Binder; 72 import android.os.Build; 73 import android.os.Bundle; 74 import android.os.Debug; 75 import android.os.HandlerThread; 76 import android.os.IBinder; 77 import android.os.Looper; 78 import android.os.Message; 79 import android.os.Parcel; 80 import android.os.Parcelable; 81 import android.os.RemoteException; 82 import android.os.Environment; 83 import android.os.FileObserver; 84 import android.os.FileUtils; 85 import android.os.Handler; 86 import android.os.ParcelFileDescriptor; 87 import android.os.Process; 88 import android.os.ServiceManager; 89 import android.os.SystemClock; 90 import android.os.SystemProperties; 91 import android.provider.Settings; 92 import android.security.SystemKeyStore; 93 import android.util.*; 94 import android.view.Display; 95 import android.view.WindowManager; 96 97 import java.io.BufferedOutputStream; 98 import java.io.File; 99 import java.io.FileDescriptor; 100 import java.io.FileInputStream; 101 import java.io.FileNotFoundException; 102 import java.io.FileOutputStream; 103 import java.io.FileReader; 104 import java.io.FilenameFilter; 105 import java.io.IOException; 106 import java.io.InputStream; 107 import java.io.PrintWriter; 108 import java.security.NoSuchAlgorithmException; 109 import java.text.SimpleDateFormat; 110 import java.util.ArrayList; 111 import java.util.Arrays; 112 import java.util.Collection; 113 import java.util.Collections; 114 import java.util.Comparator; 115 import java.util.Date; 116 import java.util.Enumeration; 117 import java.util.HashMap; 118 import java.util.HashSet; 119 import java.util.Iterator; 120 import java.util.LinkedList; 121 import java.util.List; 122 import java.util.Map; 123 import java.util.Set; 124 import java.util.zip.ZipEntry; 125 import java.util.zip.ZipException; 126 import java.util.zip.ZipFile; 127 import java.util.zip.ZipOutputStream; 128 129 /** 130 * Keep track of all those .apks everywhere. 131 * 132 * This is very central to the platform's security; please run the unit 133 * tests whenever making modifications here: 134 * 135 mmm frameworks/base/tests/AndroidTests 136 adb install -r -f out/target/product/passion/data/app/AndroidTests.apk 137 adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner 138 * 139 */ 140 class PackageManagerService extends IPackageManager.Stub { 141 private static final String TAG = "PackageManager"; 142 private static final boolean DEBUG_SETTINGS = false; 143 private static final boolean DEBUG_PREFERRED = false; 144 private static final boolean DEBUG_UPGRADE = false; 145 private static final boolean DEBUG_INSTALL = false; 146 147 private static final boolean MULTIPLE_APPLICATION_UIDS = true; 148 private static final int RADIO_UID = Process.PHONE_UID; 149 private static final int LOG_UID = Process.LOG_UID; 150 private static final int NFC_UID = Process.NFC_UID; 151 private static final int FIRST_APPLICATION_UID = 152 Process.FIRST_APPLICATION_UID; 153 private static final int MAX_APPLICATION_UIDS = 1000; 154 155 private static final boolean SHOW_INFO = false; 156 157 private static final boolean GET_CERTIFICATES = true; 158 159 private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled"; 160 161 private static final int REMOVE_EVENTS = 162 FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM; 163 private static final int ADD_EVENTS = 164 FileObserver.CLOSE_WRITE /*| FileObserver.CREATE*/ | FileObserver.MOVED_TO; 165 166 private static final int OBSERVER_EVENTS = REMOVE_EVENTS | ADD_EVENTS; 167 // Suffix used during package installation when copying/moving 168 // package apks to install directory. 169 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 170 171 /** 172 * Indicates the state of installation. Used by PackageManager to 173 * figure out incomplete installations. Say a package is being installed 174 * (the state is set to PKG_INSTALL_INCOMPLETE) and remains so till 175 * the package installation is successful or unsuccesful lin which case 176 * the PackageManager will no longer maintain state information associated 177 * with the package. If some exception(like device freeze or battery being 178 * pulled out) occurs during installation of a package, the PackageManager 179 * needs this information to clean up the previously failed installation. 180 */ 181 private static final int PKG_INSTALL_INCOMPLETE = 0; 182 private static final int PKG_INSTALL_COMPLETE = 1; 183 184 static final int SCAN_MONITOR = 1<<0; 185 static final int SCAN_NO_DEX = 1<<1; 186 static final int SCAN_FORCE_DEX = 1<<2; 187 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 188 static final int SCAN_NEW_INSTALL = 1<<4; 189 static final int SCAN_NO_PATHS = 1<<5; 190 static final int SCAN_UPDATE_TIME = 1<<6; 191 192 static final int REMOVE_CHATTY = 1<<16; 193 194 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 195 196 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 197 DEFAULT_CONTAINER_PACKAGE, 198 "com.android.defcontainer.DefaultContainerService"); 199 200 private static final String LIB_DIR_NAME = "lib"; 201 202 static final String mTempContainerPrefix = "smdl2tmp"; 203 204 final HandlerThread mHandlerThread = new HandlerThread("PackageManager", 205 Process.THREAD_PRIORITY_BACKGROUND); 206 final PackageHandler mHandler; 207 208 final int mSdkVersion = Build.VERSION.SDK_INT; 209 final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME) 210 ? null : Build.VERSION.CODENAME; 211 212 final Context mContext; 213 final boolean mFactoryTest; 214 final boolean mNoDexOpt; 215 final DisplayMetrics mMetrics; 216 final int mDefParseFlags; 217 final String[] mSeparateProcesses; 218 219 // This is where all application persistent data goes. 220 final File mAppDataDir; 221 222 // If Encrypted File System feature is enabled, all application persistent data 223 // should go here instead. 224 final File mSecureAppDataDir; 225 226 // This is the object monitoring the framework dir. 227 final FileObserver mFrameworkInstallObserver; 228 229 // This is the object monitoring the system app dir. 230 final FileObserver mSystemInstallObserver; 231 232 // This is the object monitoring the system app dir. 233 final FileObserver mVendorInstallObserver; 234 235 // This is the object monitoring mAppInstallDir. 236 final FileObserver mAppInstallObserver; 237 238 // This is the object monitoring mDrmAppPrivateInstallDir. 239 final FileObserver mDrmAppInstallObserver; 240 241 // Used for priviledge escalation. MUST NOT BE CALLED WITH mPackages 242 // LOCK HELD. Can be called with mInstallLock held. 243 final Installer mInstaller; 244 245 final File mFrameworkDir; 246 final File mSystemAppDir; 247 final File mVendorAppDir; 248 final File mAppInstallDir; 249 final File mDalvikCacheDir; 250 251 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 252 // apps. 253 final File mDrmAppPrivateInstallDir; 254 255 // ---------------------------------------------------------------- 256 257 // Lock for state used when installing and doing other long running 258 // operations. Methods that must be called with this lock held have 259 // the prefix "LI". 260 final Object mInstallLock = new Object(); 261 262 // These are the directories in the 3rd party applications installed dir 263 // that we have currently loaded packages from. Keys are the application's 264 // installed zip file (absolute codePath), and values are Package. 265 final HashMap<String, PackageParser.Package> mAppDirs = 266 new HashMap<String, PackageParser.Package>(); 267 268 // Information for the parser to write more useful error messages. 269 File mScanningPath; 270 int mLastScanError; 271 272 final int[] mOutPermissions = new int[3]; 273 274 // ---------------------------------------------------------------- 275 276 // Keys are String (package name), values are Package. This also serves 277 // as the lock for the global state. Methods that must be called with 278 // this lock held have the prefix "LP". 279 final HashMap<String, PackageParser.Package> mPackages = 280 new HashMap<String, PackageParser.Package>(); 281 282 final Settings mSettings; 283 boolean mRestoredSettings; 284 285 // Group-ids that are given to all packages as read from etc/permissions/*.xml. 286 int[] mGlobalGids; 287 288 // These are the built-in uid -> permission mappings that were read from the 289 // etc/permissions.xml file. 290 final SparseArray<HashSet<String>> mSystemPermissions = 291 new SparseArray<HashSet<String>>(); 292 293 // These are the built-in shared libraries that were read from the 294 // etc/permissions.xml file. 295 final HashMap<String, String> mSharedLibraries = new HashMap<String, String>(); 296 297 // Temporary for building the final shared libraries for an .apk. 298 String[] mTmpSharedLibraries = null; 299 300 // These are the features this devices supports that were read from the 301 // etc/permissions.xml file. 302 final HashMap<String, FeatureInfo> mAvailableFeatures = 303 new HashMap<String, FeatureInfo>(); 304 305 // All available activities, for your resolving pleasure. 306 final ActivityIntentResolver mActivities = 307 new ActivityIntentResolver(); 308 309 // All available receivers, for your resolving pleasure. 310 final ActivityIntentResolver mReceivers = 311 new ActivityIntentResolver(); 312 313 // All available services, for your resolving pleasure. 314 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 315 316 // Keys are String (provider class name), values are Provider. 317 final HashMap<ComponentName, PackageParser.Provider> mProvidersByComponent = 318 new HashMap<ComponentName, PackageParser.Provider>(); 319 320 // Mapping from provider base names (first directory in content URI codePath) 321 // to the provider information. 322 final HashMap<String, PackageParser.Provider> mProviders = 323 new HashMap<String, PackageParser.Provider>(); 324 325 // Mapping from instrumentation class names to info about them. 326 final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 327 new HashMap<ComponentName, PackageParser.Instrumentation>(); 328 329 // Mapping from permission names to info about them. 330 final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups = 331 new HashMap<String, PackageParser.PermissionGroup>(); 332 333 // Packages whose data we have transfered into another package, thus 334 // should no longer exist. 335 final HashSet<String> mTransferedPackages = new HashSet<String>(); 336 337 // Broadcast actions that are only available to the system. 338 final HashSet<String> mProtectedBroadcasts = new HashSet<String>(); 339 340 boolean mSystemReady; 341 boolean mSafeMode; 342 boolean mHasSystemUidErrors; 343 344 ApplicationInfo mAndroidApplication; 345 final ActivityInfo mResolveActivity = new ActivityInfo(); 346 final ResolveInfo mResolveInfo = new ResolveInfo(); 347 ComponentName mResolveComponentName; 348 PackageParser.Package mPlatformPackage; 349 350 // Set of pending broadcasts for aggregating enable/disable of components. 351 final HashMap<String, ArrayList<String>> mPendingBroadcasts 352 = new HashMap<String, ArrayList<String>>(); 353 // Service Connection to remote media container service to copy 354 // package uri's from external media onto secure containers 355 // or internal storage. 356 private IMediaContainerService mContainerService = null; 357 358 static final int SEND_PENDING_BROADCAST = 1; 359 static final int MCS_BOUND = 3; 360 static final int END_COPY = 4; 361 static final int INIT_COPY = 5; 362 static final int MCS_UNBIND = 6; 363 static final int START_CLEANING_PACKAGE = 7; 364 static final int FIND_INSTALL_LOC = 8; 365 static final int POST_INSTALL = 9; 366 static final int MCS_RECONNECT = 10; 367 static final int MCS_GIVE_UP = 11; 368 static final int UPDATED_MEDIA_STATUS = 12; 369 static final int WRITE_SETTINGS = 13; 370 371 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 372 373 // Delay time in millisecs 374 static final int BROADCAST_DELAY = 10 * 1000; 375 final private DefaultContainerConnection mDefContainerConn = 376 new DefaultContainerConnection(); 377 class DefaultContainerConnection implements ServiceConnection { 378 public void onServiceConnected(ComponentName name, IBinder service) { 379 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 380 IMediaContainerService imcs = 381 IMediaContainerService.Stub.asInterface(service); 382 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 383 } 384 385 public void onServiceDisconnected(ComponentName name) { 386 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 387 } 388 }; 389 390 // Recordkeeping of restore-after-install operations that are currently in flight 391 // between the Package Manager and the Backup Manager 392 class PostInstallData { 393 public InstallArgs args; 394 public PackageInstalledInfo res; 395 396 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 397 args = _a; 398 res = _r; 399 } 400 }; 401 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 402 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 403 404 class PackageHandler extends Handler { 405 private boolean mBound = false; 406 final ArrayList<HandlerParams> mPendingInstalls = 407 new ArrayList<HandlerParams>(); 408 409 private boolean connectToService() { 410 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 411 " DefaultContainerService"); 412 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 413 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 414 if (mContext.bindService(service, mDefContainerConn, 415 Context.BIND_AUTO_CREATE)) { 416 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 417 mBound = true; 418 return true; 419 } 420 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 421 return false; 422 } 423 424 private void disconnectService() { 425 mContainerService = null; 426 mBound = false; 427 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 428 mContext.unbindService(mDefContainerConn); 429 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 430 } 431 432 PackageHandler(Looper looper) { 433 super(looper); 434 } 435 436 public void handleMessage(Message msg) { 437 try { 438 doHandleMessage(msg); 439 } finally { 440 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 441 } 442 } 443 444 void doHandleMessage(Message msg) { 445 switch (msg.what) { 446 case INIT_COPY: { 447 if (DEBUG_SD_INSTALL) Log.i(TAG, "init_copy"); 448 HandlerParams params = (HandlerParams) msg.obj; 449 int idx = mPendingInstalls.size(); 450 if (DEBUG_SD_INSTALL) Log.i(TAG, "idx=" + idx); 451 // If a bind was already initiated we dont really 452 // need to do anything. The pending install 453 // will be processed later on. 454 if (!mBound) { 455 // If this is the only one pending we might 456 // have to bind to the service again. 457 if (!connectToService()) { 458 Slog.e(TAG, "Failed to bind to media container service"); 459 params.serviceError(); 460 return; 461 } else { 462 // Once we bind to the service, the first 463 // pending request will be processed. 464 mPendingInstalls.add(idx, params); 465 } 466 } else { 467 mPendingInstalls.add(idx, params); 468 // Already bound to the service. Just make 469 // sure we trigger off processing the first request. 470 if (idx == 0) { 471 mHandler.sendEmptyMessage(MCS_BOUND); 472 } 473 } 474 break; 475 } 476 case MCS_BOUND: { 477 if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_bound"); 478 if (msg.obj != null) { 479 mContainerService = (IMediaContainerService) msg.obj; 480 } 481 if (mContainerService == null) { 482 // Something seriously wrong. Bail out 483 Slog.e(TAG, "Cannot bind to media container service"); 484 for (HandlerParams params : mPendingInstalls) { 485 mPendingInstalls.remove(0); 486 // Indicate service bind error 487 params.serviceError(); 488 } 489 mPendingInstalls.clear(); 490 } else if (mPendingInstalls.size() > 0) { 491 HandlerParams params = mPendingInstalls.get(0); 492 if (params != null) { 493 params.startCopy(); 494 } 495 } else { 496 // Should never happen ideally. 497 Slog.w(TAG, "Empty queue"); 498 } 499 break; 500 } 501 case MCS_RECONNECT : { 502 if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_reconnect"); 503 if (mPendingInstalls.size() > 0) { 504 if (mBound) { 505 disconnectService(); 506 } 507 if (!connectToService()) { 508 Slog.e(TAG, "Failed to bind to media container service"); 509 for (HandlerParams params : mPendingInstalls) { 510 mPendingInstalls.remove(0); 511 // Indicate service bind error 512 params.serviceError(); 513 } 514 mPendingInstalls.clear(); 515 } 516 } 517 break; 518 } 519 case MCS_UNBIND : { 520 if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_unbind"); 521 // Delete pending install 522 if (mPendingInstalls.size() > 0) { 523 mPendingInstalls.remove(0); 524 } 525 if (mPendingInstalls.size() == 0) { 526 if (mBound) { 527 disconnectService(); 528 } 529 } else { 530 // There are more pending requests in queue. 531 // Just post MCS_BOUND message to trigger processing 532 // of next pending install. 533 mHandler.sendEmptyMessage(MCS_BOUND); 534 } 535 break; 536 } 537 case MCS_GIVE_UP: { 538 if (DEBUG_SD_INSTALL) Log.i(TAG, "mcs_giveup too many retries"); 539 HandlerParams params = mPendingInstalls.remove(0); 540 break; 541 } 542 case SEND_PENDING_BROADCAST : { 543 String packages[]; 544 ArrayList components[]; 545 int size = 0; 546 int uids[]; 547 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 548 synchronized (mPackages) { 549 if (mPendingBroadcasts == null) { 550 return; 551 } 552 size = mPendingBroadcasts.size(); 553 if (size <= 0) { 554 // Nothing to be done. Just return 555 return; 556 } 557 packages = new String[size]; 558 components = new ArrayList[size]; 559 uids = new int[size]; 560 Iterator<HashMap.Entry<String, ArrayList<String>>> 561 it = mPendingBroadcasts.entrySet().iterator(); 562 int i = 0; 563 while (it.hasNext() && i < size) { 564 HashMap.Entry<String, ArrayList<String>> ent = it.next(); 565 packages[i] = ent.getKey(); 566 components[i] = ent.getValue(); 567 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 568 uids[i] = (ps != null) ? ps.userId : -1; 569 i++; 570 } 571 size = i; 572 mPendingBroadcasts.clear(); 573 } 574 // Send broadcasts 575 for (int i = 0; i < size; i++) { 576 sendPackageChangedBroadcast(packages[i], true, 577 (ArrayList<String>)components[i], uids[i]); 578 } 579 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 580 break; 581 } 582 case START_CLEANING_PACKAGE: { 583 String packageName = (String)msg.obj; 584 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 585 synchronized (mPackages) { 586 if (!mSettings.mPackagesToBeCleaned.contains(packageName)) { 587 mSettings.mPackagesToBeCleaned.add(packageName); 588 } 589 } 590 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 591 startCleaningPackages(); 592 } break; 593 case POST_INSTALL: { 594 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 595 PostInstallData data = mRunningInstalls.get(msg.arg1); 596 mRunningInstalls.delete(msg.arg1); 597 boolean deleteOld = false; 598 599 if (data != null) { 600 InstallArgs args = data.args; 601 PackageInstalledInfo res = data.res; 602 603 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 604 res.removedInfo.sendBroadcast(false, true); 605 Bundle extras = new Bundle(1); 606 extras.putInt(Intent.EXTRA_UID, res.uid); 607 final boolean update = res.removedInfo.removedPackage != null; 608 if (update) { 609 extras.putBoolean(Intent.EXTRA_REPLACING, true); 610 } 611 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 612 res.pkg.applicationInfo.packageName, 613 extras, null); 614 if (update) { 615 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 616 res.pkg.applicationInfo.packageName, 617 extras, null); 618 } 619 if (res.removedInfo.args != null) { 620 // Remove the replaced package's older resources safely now 621 deleteOld = true; 622 } 623 } 624 // Force a gc to clear up things 625 Runtime.getRuntime().gc(); 626 // We delete after a gc for applications on sdcard. 627 if (deleteOld) { 628 synchronized (mInstallLock) { 629 res.removedInfo.args.doPostDeleteLI(true); 630 } 631 } 632 if (args.observer != null) { 633 try { 634 args.observer.packageInstalled(res.name, res.returnCode); 635 } catch (RemoteException e) { 636 Slog.i(TAG, "Observer no longer exists."); 637 } 638 } 639 } else { 640 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 641 } 642 } break; 643 case UPDATED_MEDIA_STATUS: { 644 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 645 boolean reportStatus = msg.arg1 == 1; 646 boolean doGc = msg.arg2 == 1; 647 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 648 if (doGc) { 649 // Force a gc to clear up stale containers. 650 Runtime.getRuntime().gc(); 651 } 652 if (msg.obj != null) { 653 Set<SdInstallArgs> args = (Set<SdInstallArgs>) msg.obj; 654 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 655 // Unload containers 656 unloadAllContainers(args); 657 } 658 if (reportStatus) { 659 try { 660 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 661 PackageHelper.getMountService().finishMediaUpdate(); 662 } catch (RemoteException e) { 663 Log.e(TAG, "MountService not running?"); 664 } 665 } 666 } break; 667 case WRITE_SETTINGS: { 668 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 669 synchronized (mPackages) { 670 removeMessages(WRITE_SETTINGS); 671 mSettings.writeLP(); 672 } 673 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 674 } break; 675 } 676 } 677 } 678 679 void scheduleWriteSettingsLocked() { 680 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 681 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 682 } 683 } 684 685 static boolean installOnSd(int flags) { 686 if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) || 687 ((flags & PackageManager.INSTALL_INTERNAL) != 0)) { 688 return false; 689 } 690 if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { 691 return true; 692 } 693 return false; 694 } 695 696 public static final IPackageManager main(Context context, boolean factoryTest) { 697 PackageManagerService m = new PackageManagerService(context, factoryTest); 698 ServiceManager.addService("package", m); 699 return m; 700 } 701 702 static String[] splitString(String str, char sep) { 703 int count = 1; 704 int i = 0; 705 while ((i=str.indexOf(sep, i)) >= 0) { 706 count++; 707 i++; 708 } 709 710 String[] res = new String[count]; 711 i=0; 712 count = 0; 713 int lastI=0; 714 while ((i=str.indexOf(sep, i)) >= 0) { 715 res[count] = str.substring(lastI, i); 716 count++; 717 i++; 718 lastI = i; 719 } 720 res[count] = str.substring(lastI, str.length()); 721 return res; 722 } 723 724 public PackageManagerService(Context context, boolean factoryTest) { 725 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 726 SystemClock.uptimeMillis()); 727 728 if (mSdkVersion <= 0) { 729 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 730 } 731 732 mContext = context; 733 mFactoryTest = factoryTest; 734 mNoDexOpt = "eng".equals(SystemProperties.get("ro.build.type")); 735 mMetrics = new DisplayMetrics(); 736 mSettings = new Settings(); 737 mSettings.addSharedUserLP("android.uid.system", 738 Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM); 739 mSettings.addSharedUserLP("android.uid.phone", 740 MULTIPLE_APPLICATION_UIDS 741 ? RADIO_UID : FIRST_APPLICATION_UID, 742 ApplicationInfo.FLAG_SYSTEM); 743 mSettings.addSharedUserLP("android.uid.log", 744 MULTIPLE_APPLICATION_UIDS 745 ? LOG_UID : FIRST_APPLICATION_UID, 746 ApplicationInfo.FLAG_SYSTEM); 747 mSettings.addSharedUserLP("android.uid.nfc", 748 MULTIPLE_APPLICATION_UIDS 749 ? NFC_UID : FIRST_APPLICATION_UID, 750 ApplicationInfo.FLAG_SYSTEM); 751 752 String separateProcesses = SystemProperties.get("debug.separate_processes"); 753 if (separateProcesses != null && separateProcesses.length() > 0) { 754 if ("*".equals(separateProcesses)) { 755 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 756 mSeparateProcesses = null; 757 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 758 } else { 759 mDefParseFlags = 0; 760 mSeparateProcesses = separateProcesses.split(","); 761 Slog.w(TAG, "Running with debug.separate_processes: " 762 + separateProcesses); 763 } 764 } else { 765 mDefParseFlags = 0; 766 mSeparateProcesses = null; 767 } 768 769 Installer installer = new Installer(); 770 // Little hacky thing to check if installd is here, to determine 771 // whether we are running on the simulator and thus need to take 772 // care of building the /data file structure ourself. 773 // (apparently the sim now has a working installer) 774 if (installer.ping() && Process.supportsProcesses()) { 775 mInstaller = installer; 776 } else { 777 mInstaller = null; 778 } 779 780 WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 781 Display d = wm.getDefaultDisplay(); 782 d.getMetrics(mMetrics); 783 784 synchronized (mInstallLock) { 785 synchronized (mPackages) { 786 mHandlerThread.start(); 787 mHandler = new PackageHandler(mHandlerThread.getLooper()); 788 789 File dataDir = Environment.getDataDirectory(); 790 mAppDataDir = new File(dataDir, "data"); 791 mSecureAppDataDir = new File(dataDir, "secure/data"); 792 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 793 794 if (mInstaller == null) { 795 // Make sure these dirs exist, when we are running in 796 // the simulator. 797 // Make a wide-open directory for random misc stuff. 798 File miscDir = new File(dataDir, "misc"); 799 miscDir.mkdirs(); 800 mAppDataDir.mkdirs(); 801 mSecureAppDataDir.mkdirs(); 802 mDrmAppPrivateInstallDir.mkdirs(); 803 } 804 805 readPermissions(); 806 807 mRestoredSettings = mSettings.readLP(); 808 long startTime = SystemClock.uptimeMillis(); 809 810 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 811 startTime); 812 813 // Set flag to monitor and not change apk file paths when 814 // scanning install directories. 815 int scanMode = SCAN_MONITOR | SCAN_NO_PATHS; 816 if (mNoDexOpt) { 817 Slog.w(TAG, "Running ENG build: no pre-dexopt!"); 818 scanMode |= SCAN_NO_DEX; 819 } 820 821 final HashSet<String> libFiles = new HashSet<String>(); 822 823 mFrameworkDir = new File(Environment.getRootDirectory(), "framework"); 824 mDalvikCacheDir = new File(dataDir, "dalvik-cache"); 825 826 if (mInstaller != null) { 827 boolean didDexOpt = false; 828 829 /** 830 * Out of paranoia, ensure that everything in the boot class 831 * path has been dexed. 832 */ 833 String bootClassPath = System.getProperty("java.boot.class.path"); 834 if (bootClassPath != null) { 835 String[] paths = splitString(bootClassPath, ':'); 836 for (int i=0; i<paths.length; i++) { 837 try { 838 if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) { 839 libFiles.add(paths[i]); 840 mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true); 841 didDexOpt = true; 842 } 843 } catch (FileNotFoundException e) { 844 Slog.w(TAG, "Boot class path not found: " + paths[i]); 845 } catch (IOException e) { 846 Slog.w(TAG, "Exception reading boot class path: " + paths[i], e); 847 } 848 } 849 } else { 850 Slog.w(TAG, "No BOOTCLASSPATH found!"); 851 } 852 853 /** 854 * Also ensure all external libraries have had dexopt run on them. 855 */ 856 if (mSharedLibraries.size() > 0) { 857 Iterator<String> libs = mSharedLibraries.values().iterator(); 858 while (libs.hasNext()) { 859 String lib = libs.next(); 860 try { 861 if (dalvik.system.DexFile.isDexOptNeeded(lib)) { 862 libFiles.add(lib); 863 mInstaller.dexopt(lib, Process.SYSTEM_UID, true); 864 didDexOpt = true; 865 } 866 } catch (FileNotFoundException e) { 867 Slog.w(TAG, "Library not found: " + lib); 868 } catch (IOException e) { 869 Slog.w(TAG, "Exception reading library: " + lib, e); 870 } 871 } 872 } 873 874 // Gross hack for now: we know this file doesn't contain any 875 // code, so don't dexopt it to avoid the resulting log spew. 876 libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk"); 877 878 /** 879 * And there are a number of commands implemented in Java, which 880 * we currently need to do the dexopt on so that they can be 881 * run from a non-root shell. 882 */ 883 String[] frameworkFiles = mFrameworkDir.list(); 884 if (frameworkFiles != null) { 885 for (int i=0; i<frameworkFiles.length; i++) { 886 File libPath = new File(mFrameworkDir, frameworkFiles[i]); 887 String path = libPath.getPath(); 888 // Skip the file if we alrady did it. 889 if (libFiles.contains(path)) { 890 continue; 891 } 892 // Skip the file if it is not a type we want to dexopt. 893 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { 894 continue; 895 } 896 try { 897 if (dalvik.system.DexFile.isDexOptNeeded(path)) { 898 mInstaller.dexopt(path, Process.SYSTEM_UID, true); 899 didDexOpt = true; 900 } 901 } catch (FileNotFoundException e) { 902 Slog.w(TAG, "Jar not found: " + path); 903 } catch (IOException e) { 904 Slog.w(TAG, "Exception reading jar: " + path, e); 905 } 906 } 907 } 908 909 if (didDexOpt) { 910 // If we had to do a dexopt of one of the previous 911 // things, then something on the system has changed. 912 // Consider this significant, and wipe away all other 913 // existing dexopt files to ensure we don't leave any 914 // dangling around. 915 String[] files = mDalvikCacheDir.list(); 916 if (files != null) { 917 for (int i=0; i<files.length; i++) { 918 String fn = files[i]; 919 if (fn.startsWith("data@app@") 920 || fn.startsWith("data@app-private@")) { 921 Slog.i(TAG, "Pruning dalvik file: " + fn); 922 (new File(mDalvikCacheDir, fn)).delete(); 923 } 924 } 925 } 926 } 927 } 928 929 // Find base frameworks (resource packages without code). 930 mFrameworkInstallObserver = new AppDirObserver( 931 mFrameworkDir.getPath(), OBSERVER_EVENTS, true); 932 mFrameworkInstallObserver.startWatching(); 933 scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM 934 | PackageParser.PARSE_IS_SYSTEM_DIR, 935 scanMode | SCAN_NO_DEX, 0); 936 937 // Collect all system packages. 938 mSystemAppDir = new File(Environment.getRootDirectory(), "app"); 939 mSystemInstallObserver = new AppDirObserver( 940 mSystemAppDir.getPath(), OBSERVER_EVENTS, true); 941 mSystemInstallObserver.startWatching(); 942 scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM 943 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 944 945 // Collect all vendor packages. 946 mVendorAppDir = new File("/vendor/app"); 947 mVendorInstallObserver = new AppDirObserver( 948 mVendorAppDir.getPath(), OBSERVER_EVENTS, true); 949 mVendorInstallObserver.startWatching(); 950 scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM 951 | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); 952 953 if (mInstaller != null) { 954 if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); 955 mInstaller.moveFiles(); 956 } 957 958 // Prune any system packages that no longer exist. 959 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 960 while (psit.hasNext()) { 961 PackageSetting ps = psit.next(); 962 if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 963 && !mPackages.containsKey(ps.name) 964 && !mSettings.mDisabledSysPackages.containsKey(ps.name)) { 965 psit.remove(); 966 String msg = "System package " + ps.name 967 + " no longer exists; wiping its data"; 968 reportSettingsProblem(Log.WARN, msg); 969 if (mInstaller != null) { 970 // XXX how to set useEncryptedFSDir for packages that 971 // are not encrypted? 972 mInstaller.remove(ps.name, true); 973 } 974 } 975 } 976 977 mAppInstallDir = new File(dataDir, "app"); 978 if (mInstaller == null) { 979 // Make sure these dirs exist, when we are running in 980 // the simulator. 981 mAppInstallDir.mkdirs(); // scanDirLI() assumes this dir exists 982 } 983 //look for any incomplete package installations 984 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackages(); 985 //clean up list 986 for(int i = 0; i < deletePkgsList.size(); i++) { 987 //clean up here 988 cleanupInstallFailedPackage(deletePkgsList.get(i)); 989 } 990 //delete tmp files 991 deleteTempPackageFiles(); 992 993 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 994 SystemClock.uptimeMillis()); 995 mAppInstallObserver = new AppDirObserver( 996 mAppInstallDir.getPath(), OBSERVER_EVENTS, false); 997 mAppInstallObserver.startWatching(); 998 scanDirLI(mAppInstallDir, 0, scanMode, 0); 999 1000 mDrmAppInstallObserver = new AppDirObserver( 1001 mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false); 1002 mDrmAppInstallObserver.startWatching(); 1003 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 1004 scanMode, 0); 1005 1006 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 1007 SystemClock.uptimeMillis()); 1008 Slog.i(TAG, "Time to scan packages: " 1009 + ((SystemClock.uptimeMillis()-startTime)/1000f) 1010 + " seconds"); 1011 1012 // If the platform SDK has changed since the last time we booted, 1013 // we need to re-grant app permission to catch any new ones that 1014 // appear. This is really a hack, and means that apps can in some 1015 // cases get permissions that the user didn't initially explicitly 1016 // allow... it would be nice to have some better way to handle 1017 // this situation. 1018 final boolean regrantPermissions = mSettings.mInternalSdkPlatform 1019 != mSdkVersion; 1020 if (regrantPermissions) Slog.i(TAG, "Platform changed from " 1021 + mSettings.mInternalSdkPlatform + " to " + mSdkVersion 1022 + "; regranting permissions for internal storage"); 1023 mSettings.mInternalSdkPlatform = mSdkVersion; 1024 1025 updatePermissionsLP(null, null, true, regrantPermissions, regrantPermissions); 1026 1027 mSettings.writeLP(); 1028 1029 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 1030 SystemClock.uptimeMillis()); 1031 1032 // Now after opening every single application zip, make sure they 1033 // are all flushed. Not really needed, but keeps things nice and 1034 // tidy. 1035 Runtime.getRuntime().gc(); 1036 } // synchronized (mPackages) 1037 } // synchronized (mInstallLock) 1038 } 1039 1040 @Override 1041 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 1042 throws RemoteException { 1043 try { 1044 return super.onTransact(code, data, reply, flags); 1045 } catch (RuntimeException e) { 1046 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 1047 Slog.e(TAG, "Package Manager Crash", e); 1048 } 1049 throw e; 1050 } 1051 } 1052 1053 void cleanupInstallFailedPackage(PackageSetting ps) { 1054 Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name); 1055 if (mInstaller != null) { 1056 boolean useSecureFS = useEncryptedFilesystemForPackage(ps.pkg); 1057 int retCode = mInstaller.remove(ps.name, useSecureFS); 1058 if (retCode < 0) { 1059 Slog.w(TAG, "Couldn't remove app data directory for package: " 1060 + ps.name + ", retcode=" + retCode); 1061 } 1062 } else { 1063 //for emulator 1064 PackageParser.Package pkg = mPackages.get(ps.name); 1065 File dataDir = new File(pkg.applicationInfo.dataDir); 1066 dataDir.delete(); 1067 } 1068 if (ps.codePath != null) { 1069 if (!ps.codePath.delete()) { 1070 Slog.w(TAG, "Unable to remove old code file: " + ps.codePath); 1071 } 1072 } 1073 if (ps.resourcePath != null) { 1074 if (!ps.resourcePath.delete() && !ps.resourcePath.equals(ps.codePath)) { 1075 Slog.w(TAG, "Unable to remove old code file: " + ps.resourcePath); 1076 } 1077 } 1078 mSettings.removePackageLP(ps.name); 1079 } 1080 1081 void readPermissions() { 1082 // Read permissions from .../etc/permission directory. 1083 File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions"); 1084 if (!libraryDir.exists() || !libraryDir.isDirectory()) { 1085 Slog.w(TAG, "No directory " + libraryDir + ", skipping"); 1086 return; 1087 } 1088 if (!libraryDir.canRead()) { 1089 Slog.w(TAG, "Directory " + libraryDir + " cannot be read"); 1090 return; 1091 } 1092 1093 // Iterate over the files in the directory and scan .xml files 1094 for (File f : libraryDir.listFiles()) { 1095 // We'll read platform.xml last 1096 if (f.getPath().endsWith("etc/permissions/platform.xml")) { 1097 continue; 1098 } 1099 1100 if (!f.getPath().endsWith(".xml")) { 1101 Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring"); 1102 continue; 1103 } 1104 if (!f.canRead()) { 1105 Slog.w(TAG, "Permissions library file " + f + " cannot be read"); 1106 continue; 1107 } 1108 1109 readPermissionsFromXml(f); 1110 } 1111 1112 // Read permissions from .../etc/permissions/platform.xml last so it will take precedence 1113 final File permFile = new File(Environment.getRootDirectory(), 1114 "etc/permissions/platform.xml"); 1115 readPermissionsFromXml(permFile); 1116 } 1117 1118 private void readPermissionsFromXml(File permFile) { 1119 FileReader permReader = null; 1120 try { 1121 permReader = new FileReader(permFile); 1122 } catch (FileNotFoundException e) { 1123 Slog.w(TAG, "Couldn't find or open permissions file " + permFile); 1124 return; 1125 } 1126 1127 try { 1128 XmlPullParser parser = Xml.newPullParser(); 1129 parser.setInput(permReader); 1130 1131 XmlUtils.beginDocument(parser, "permissions"); 1132 1133 while (true) { 1134 XmlUtils.nextElement(parser); 1135 if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { 1136 break; 1137 } 1138 1139 String name = parser.getName(); 1140 if ("group".equals(name)) { 1141 String gidStr = parser.getAttributeValue(null, "gid"); 1142 if (gidStr != null) { 1143 int gid = Integer.parseInt(gidStr); 1144 mGlobalGids = appendInt(mGlobalGids, gid); 1145 } else { 1146 Slog.w(TAG, "<group> without gid at " 1147 + parser.getPositionDescription()); 1148 } 1149 1150 XmlUtils.skipCurrentTag(parser); 1151 continue; 1152 } else if ("permission".equals(name)) { 1153 String perm = parser.getAttributeValue(null, "name"); 1154 if (perm == null) { 1155 Slog.w(TAG, "<permission> without name at " 1156 + parser.getPositionDescription()); 1157 XmlUtils.skipCurrentTag(parser); 1158 continue; 1159 } 1160 perm = perm.intern(); 1161 readPermission(parser, perm); 1162 1163 } else if ("assign-permission".equals(name)) { 1164 String perm = parser.getAttributeValue(null, "name"); 1165 if (perm == null) { 1166 Slog.w(TAG, "<assign-permission> without name at " 1167 + parser.getPositionDescription()); 1168 XmlUtils.skipCurrentTag(parser); 1169 continue; 1170 } 1171 String uidStr = parser.getAttributeValue(null, "uid"); 1172 if (uidStr == null) { 1173 Slog.w(TAG, "<assign-permission> without uid at " 1174 + parser.getPositionDescription()); 1175 XmlUtils.skipCurrentTag(parser); 1176 continue; 1177 } 1178 int uid = Process.getUidForName(uidStr); 1179 if (uid < 0) { 1180 Slog.w(TAG, "<assign-permission> with unknown uid \"" 1181 + uidStr + "\" at " 1182 + parser.getPositionDescription()); 1183 XmlUtils.skipCurrentTag(parser); 1184 continue; 1185 } 1186 perm = perm.intern(); 1187 HashSet<String> perms = mSystemPermissions.get(uid); 1188 if (perms == null) { 1189 perms = new HashSet<String>(); 1190 mSystemPermissions.put(uid, perms); 1191 } 1192 perms.add(perm); 1193 XmlUtils.skipCurrentTag(parser); 1194 1195 } else if ("library".equals(name)) { 1196 String lname = parser.getAttributeValue(null, "name"); 1197 String lfile = parser.getAttributeValue(null, "file"); 1198 if (lname == null) { 1199 Slog.w(TAG, "<library> without name at " 1200 + parser.getPositionDescription()); 1201 } else if (lfile == null) { 1202 Slog.w(TAG, "<library> without file at " 1203 + parser.getPositionDescription()); 1204 } else { 1205 //Log.i(TAG, "Got library " + lname + " in " + lfile); 1206 mSharedLibraries.put(lname, lfile); 1207 } 1208 XmlUtils.skipCurrentTag(parser); 1209 continue; 1210 1211 } else if ("feature".equals(name)) { 1212 String fname = parser.getAttributeValue(null, "name"); 1213 if (fname == null) { 1214 Slog.w(TAG, "<feature> without name at " 1215 + parser.getPositionDescription()); 1216 } else { 1217 //Log.i(TAG, "Got feature " + fname); 1218 FeatureInfo fi = new FeatureInfo(); 1219 fi.name = fname; 1220 mAvailableFeatures.put(fname, fi); 1221 } 1222 XmlUtils.skipCurrentTag(parser); 1223 continue; 1224 1225 } else { 1226 XmlUtils.skipCurrentTag(parser); 1227 continue; 1228 } 1229 1230 } 1231 } catch (XmlPullParserException e) { 1232 Slog.w(TAG, "Got execption parsing permissions.", e); 1233 } catch (IOException e) { 1234 Slog.w(TAG, "Got execption parsing permissions.", e); 1235 } 1236 } 1237 1238 void readPermission(XmlPullParser parser, String name) 1239 throws IOException, XmlPullParserException { 1240 1241 name = name.intern(); 1242 1243 BasePermission bp = mSettings.mPermissions.get(name); 1244 if (bp == null) { 1245 bp = new BasePermission(name, null, BasePermission.TYPE_BUILTIN); 1246 mSettings.mPermissions.put(name, bp); 1247 } 1248 int outerDepth = parser.getDepth(); 1249 int type; 1250 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 1251 && (type != XmlPullParser.END_TAG 1252 || parser.getDepth() > outerDepth)) { 1253 if (type == XmlPullParser.END_TAG 1254 || type == XmlPullParser.TEXT) { 1255 continue; 1256 } 1257 1258 String tagName = parser.getName(); 1259 if ("group".equals(tagName)) { 1260 String gidStr = parser.getAttributeValue(null, "gid"); 1261 if (gidStr != null) { 1262 int gid = Process.getGidForName(gidStr); 1263 bp.gids = appendInt(bp.gids, gid); 1264 } else { 1265 Slog.w(TAG, "<group> without gid at " 1266 + parser.getPositionDescription()); 1267 } 1268 } 1269 XmlUtils.skipCurrentTag(parser); 1270 } 1271 } 1272 1273 static int[] appendInt(int[] cur, int val) { 1274 if (cur == null) { 1275 return new int[] { val }; 1276 } 1277 final int N = cur.length; 1278 for (int i=0; i<N; i++) { 1279 if (cur[i] == val) { 1280 return cur; 1281 } 1282 } 1283 int[] ret = new int[N+1]; 1284 System.arraycopy(cur, 0, ret, 0, N); 1285 ret[N] = val; 1286 return ret; 1287 } 1288 1289 static int[] appendInts(int[] cur, int[] add) { 1290 if (add == null) return cur; 1291 if (cur == null) return add; 1292 final int N = add.length; 1293 for (int i=0; i<N; i++) { 1294 cur = appendInt(cur, add[i]); 1295 } 1296 return cur; 1297 } 1298 1299 static int[] removeInt(int[] cur, int val) { 1300 if (cur == null) { 1301 return null; 1302 } 1303 final int N = cur.length; 1304 for (int i=0; i<N; i++) { 1305 if (cur[i] == val) { 1306 int[] ret = new int[N-1]; 1307 if (i > 0) { 1308 System.arraycopy(cur, 0, ret, 0, i); 1309 } 1310 if (i < (N-1)) { 1311 System.arraycopy(cur, i + 1, ret, i, N - i - 1); 1312 } 1313 return ret; 1314 } 1315 } 1316 return cur; 1317 } 1318 1319 static int[] removeInts(int[] cur, int[] rem) { 1320 if (rem == null) return cur; 1321 if (cur == null) return cur; 1322 final int N = rem.length; 1323 for (int i=0; i<N; i++) { 1324 cur = removeInt(cur, rem[i]); 1325 } 1326 return cur; 1327 } 1328 1329 PackageInfo generatePackageInfo(PackageParser.Package p, int flags) { 1330 if ((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 1331 // The package has been uninstalled but has retained data and resources. 1332 return PackageParser.generatePackageInfo(p, null, flags, 0, 0); 1333 } 1334 final PackageSetting ps = (PackageSetting)p.mExtras; 1335 if (ps == null) { 1336 return null; 1337 } 1338 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 1339 return PackageParser.generatePackageInfo(p, gp.gids, flags, 1340 ps.firstInstallTime, ps.lastUpdateTime); 1341 } 1342 1343 public PackageInfo getPackageInfo(String packageName, int flags) { 1344 synchronized (mPackages) { 1345 PackageParser.Package p = mPackages.get(packageName); 1346 if (Config.LOGV) Log.v( 1347 TAG, "getPackageInfo " + packageName 1348 + ": " + p); 1349 if (p != null) { 1350 return generatePackageInfo(p, flags); 1351 } 1352 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 1353 return generatePackageInfoFromSettingsLP(packageName, flags); 1354 } 1355 } 1356 return null; 1357 } 1358 1359 public String[] currentToCanonicalPackageNames(String[] names) { 1360 String[] out = new String[names.length]; 1361 synchronized (mPackages) { 1362 for (int i=names.length-1; i>=0; i--) { 1363 PackageSetting ps = mSettings.mPackages.get(names[i]); 1364 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 1365 } 1366 } 1367 return out; 1368 } 1369 1370 public String[] canonicalToCurrentPackageNames(String[] names) { 1371 String[] out = new String[names.length]; 1372 synchronized (mPackages) { 1373 for (int i=names.length-1; i>=0; i--) { 1374 String cur = mSettings.mRenamedPackages.get(names[i]); 1375 out[i] = cur != null ? cur : names[i]; 1376 } 1377 } 1378 return out; 1379 } 1380 1381 public int getPackageUid(String packageName) { 1382 synchronized (mPackages) { 1383 PackageParser.Package p = mPackages.get(packageName); 1384 if(p != null) { 1385 return p.applicationInfo.uid; 1386 } 1387 PackageSetting ps = mSettings.mPackages.get(packageName); 1388 if((ps == null) || (ps.pkg == null) || (ps.pkg.applicationInfo == null)) { 1389 return -1; 1390 } 1391 p = ps.pkg; 1392 return p != null ? p.applicationInfo.uid : -1; 1393 } 1394 } 1395 1396 public int[] getPackageGids(String packageName) { 1397 synchronized (mPackages) { 1398 PackageParser.Package p = mPackages.get(packageName); 1399 if (Config.LOGV) Log.v( 1400 TAG, "getPackageGids" + packageName 1401 + ": " + p); 1402 if (p != null) { 1403 final PackageSetting ps = (PackageSetting)p.mExtras; 1404 final SharedUserSetting suid = ps.sharedUser; 1405 return suid != null ? suid.gids : ps.gids; 1406 } 1407 } 1408 // stupid thing to indicate an error. 1409 return new int[0]; 1410 } 1411 1412 static final PermissionInfo generatePermissionInfo( 1413 BasePermission bp, int flags) { 1414 if (bp.perm != null) { 1415 return PackageParser.generatePermissionInfo(bp.perm, flags); 1416 } 1417 PermissionInfo pi = new PermissionInfo(); 1418 pi.name = bp.name; 1419 pi.packageName = bp.sourcePackage; 1420 pi.nonLocalizedLabel = bp.name; 1421 pi.protectionLevel = bp.protectionLevel; 1422 return pi; 1423 } 1424 1425 public PermissionInfo getPermissionInfo(String name, int flags) { 1426 synchronized (mPackages) { 1427 final BasePermission p = mSettings.mPermissions.get(name); 1428 if (p != null) { 1429 return generatePermissionInfo(p, flags); 1430 } 1431 return null; 1432 } 1433 } 1434 1435 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 1436 synchronized (mPackages) { 1437 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 1438 for (BasePermission p : mSettings.mPermissions.values()) { 1439 if (group == null) { 1440 if (p.perm == null || p.perm.info.group == null) { 1441 out.add(generatePermissionInfo(p, flags)); 1442 } 1443 } else { 1444 if (p.perm != null && group.equals(p.perm.info.group)) { 1445 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 1446 } 1447 } 1448 } 1449 1450 if (out.size() > 0) { 1451 return out; 1452 } 1453 return mPermissionGroups.containsKey(group) ? out : null; 1454 } 1455 } 1456 1457 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 1458 synchronized (mPackages) { 1459 return PackageParser.generatePermissionGroupInfo( 1460 mPermissionGroups.get(name), flags); 1461 } 1462 } 1463 1464 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 1465 synchronized (mPackages) { 1466 final int N = mPermissionGroups.size(); 1467 ArrayList<PermissionGroupInfo> out 1468 = new ArrayList<PermissionGroupInfo>(N); 1469 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 1470 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 1471 } 1472 return out; 1473 } 1474 } 1475 1476 private ApplicationInfo generateApplicationInfoFromSettingsLP(String packageName, int flags) { 1477 PackageSetting ps = mSettings.mPackages.get(packageName); 1478 if(ps != null) { 1479 if(ps.pkg == null) { 1480 PackageInfo pInfo = generatePackageInfoFromSettingsLP(packageName, flags); 1481 if(pInfo != null) { 1482 return pInfo.applicationInfo; 1483 } 1484 return null; 1485 } 1486 return PackageParser.generateApplicationInfo(ps.pkg, flags); 1487 } 1488 return null; 1489 } 1490 1491 private PackageInfo generatePackageInfoFromSettingsLP(String packageName, int flags) { 1492 PackageSetting ps = mSettings.mPackages.get(packageName); 1493 if(ps != null) { 1494 if(ps.pkg == null) { 1495 ps.pkg = new PackageParser.Package(packageName); 1496 ps.pkg.applicationInfo.packageName = packageName; 1497 ps.pkg.applicationInfo.flags = ps.pkgFlags; 1498 ps.pkg.applicationInfo.publicSourceDir = ps.resourcePathString; 1499 ps.pkg.applicationInfo.sourceDir = ps.codePathString; 1500 ps.pkg.applicationInfo.dataDir = getDataPathForPackage(ps.pkg).getPath(); 1501 ps.pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString; 1502 ps.pkg.mSetEnabled = ps.enabled; 1503 } 1504 return generatePackageInfo(ps.pkg, flags); 1505 } 1506 return null; 1507 } 1508 1509 public ApplicationInfo getApplicationInfo(String packageName, int flags) { 1510 synchronized (mPackages) { 1511 PackageParser.Package p = mPackages.get(packageName); 1512 if (Config.LOGV) Log.v( 1513 TAG, "getApplicationInfo " + packageName 1514 + ": " + p); 1515 if (p != null) { 1516 // Note: isEnabledLP() does not apply here - always return info 1517 return PackageParser.generateApplicationInfo(p, flags); 1518 } 1519 if ("android".equals(packageName)||"system".equals(packageName)) { 1520 return mAndroidApplication; 1521 } 1522 if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { 1523 return generateApplicationInfoFromSettingsLP(packageName, flags); 1524 } 1525 } 1526 return null; 1527 } 1528 1529 1530 public void freeStorageAndNotify(final long freeStorageSize, final IPackageDataObserver observer) { 1531 mContext.enforceCallingOrSelfPermission( 1532 android.Manifest.permission.CLEAR_APP_CACHE, null); 1533 // Queue up an async operation since clearing cache may take a little while. 1534 mHandler.post(new Runnable() { 1535 public void run() { 1536 mHandler.removeCallbacks(this); 1537 int retCode = -1; 1538 if (mInstaller != null) { 1539 retCode = mInstaller.freeCache(freeStorageSize); 1540 if (retCode < 0) { 1541 Slog.w(TAG, "Couldn't clear application caches"); 1542 } 1543 } //end if mInstaller 1544 if (observer != null) { 1545 try { 1546 observer.onRemoveCompleted(null, (retCode >= 0)); 1547 } catch (RemoteException e) { 1548 Slog.w(TAG, "RemoveException when invoking call back"); 1549 } 1550 } 1551 } 1552 }); 1553 } 1554 1555 public void freeStorage(final long freeStorageSize, final IntentSender pi) { 1556 mContext.enforceCallingOrSelfPermission( 1557 android.Manifest.permission.CLEAR_APP_CACHE, null); 1558 // Queue up an async operation since clearing cache may take a little while. 1559 mHandler.post(new Runnable() { 1560 public void run() { 1561 mHandler.removeCallbacks(this); 1562 int retCode = -1; 1563 if (mInstaller != null) { 1564 retCode = mInstaller.freeCache(freeStorageSize); 1565 if (retCode < 0) { 1566 Slog.w(TAG, "Couldn't clear application caches"); 1567 } 1568 } 1569 if(pi != null) { 1570 try { 1571 // Callback via pending intent 1572 int code = (retCode >= 0) ? 1 : 0; 1573 pi.sendIntent(null, code, null, 1574 null, null); 1575 } catch (SendIntentException e1) { 1576 Slog.i(TAG, "Failed to send pending intent"); 1577 } 1578 } 1579 } 1580 }); 1581 } 1582 1583 public ActivityInfo getActivityInfo(ComponentName component, int flags) { 1584 synchronized (mPackages) { 1585 PackageParser.Activity a = mActivities.mActivities.get(component); 1586 1587 if (Config.LOGV) Log.v(TAG, "getActivityInfo " + component + ": " + a); 1588 if (a != null && mSettings.isEnabledLP(a.info, flags)) { 1589 return PackageParser.generateActivityInfo(a, flags); 1590 } 1591 if (mResolveComponentName.equals(component)) { 1592 return mResolveActivity; 1593 } 1594 } 1595 return null; 1596 } 1597 1598 public ActivityInfo getReceiverInfo(ComponentName component, int flags) { 1599 synchronized (mPackages) { 1600 PackageParser.Activity a = mReceivers.mActivities.get(component); 1601 if (Config.LOGV) Log.v( 1602 TAG, "getReceiverInfo " + component + ": " + a); 1603 if (a != null && mSettings.isEnabledLP(a.info, flags)) { 1604 return PackageParser.generateActivityInfo(a, flags); 1605 } 1606 } 1607 return null; 1608 } 1609 1610 public ServiceInfo getServiceInfo(ComponentName component, int flags) { 1611 synchronized (mPackages) { 1612 PackageParser.Service s = mServices.mServices.get(component); 1613 if (Config.LOGV) Log.v( 1614 TAG, "getServiceInfo " + component + ": " + s); 1615 if (s != null && mSettings.isEnabledLP(s.info, flags)) { 1616 return PackageParser.generateServiceInfo(s, flags); 1617 } 1618 } 1619 return null; 1620 } 1621 1622 public ProviderInfo getProviderInfo(ComponentName component, int flags) { 1623 synchronized (mPackages) { 1624 PackageParser.Provider p = mProvidersByComponent.get(component); 1625 if (Config.LOGV) Log.v( 1626 TAG, "getProviderInfo " + component + ": " + p); 1627 if (p != null && mSettings.isEnabledLP(p.info, flags)) { 1628 return PackageParser.generateProviderInfo(p, flags); 1629 } 1630 } 1631 return null; 1632 } 1633 1634 public String[] getSystemSharedLibraryNames() { 1635 Set<String> libSet; 1636 synchronized (mPackages) { 1637 libSet = mSharedLibraries.keySet(); 1638 int size = libSet.size(); 1639 if (size > 0) { 1640 String[] libs = new String[size]; 1641 libSet.toArray(libs); 1642 return libs; 1643 } 1644 } 1645 return null; 1646 } 1647 1648 public FeatureInfo[] getSystemAvailableFeatures() { 1649 Collection<FeatureInfo> featSet; 1650 synchronized (mPackages) { 1651 featSet = mAvailableFeatures.values(); 1652 int size = featSet.size(); 1653 if (size > 0) { 1654 FeatureInfo[] features = new FeatureInfo[size+1]; 1655 featSet.toArray(features); 1656 FeatureInfo fi = new FeatureInfo(); 1657 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 1658 FeatureInfo.GL_ES_VERSION_UNDEFINED); 1659 features[size] = fi; 1660 return features; 1661 } 1662 } 1663 return null; 1664 } 1665 1666 public boolean hasSystemFeature(String name) { 1667 synchronized (mPackages) { 1668 return mAvailableFeatures.containsKey(name); 1669 } 1670 } 1671 1672 public int checkPermission(String permName, String pkgName) { 1673 synchronized (mPackages) { 1674 PackageParser.Package p = mPackages.get(pkgName); 1675 if (p != null && p.mExtras != null) { 1676 PackageSetting ps = (PackageSetting)p.mExtras; 1677 if (ps.sharedUser != null) { 1678 if (ps.sharedUser.grantedPermissions.contains(permName)) { 1679 return PackageManager.PERMISSION_GRANTED; 1680 } 1681 } else if (ps.grantedPermissions.contains(permName)) { 1682 return PackageManager.PERMISSION_GRANTED; 1683 } 1684 } 1685 } 1686 return PackageManager.PERMISSION_DENIED; 1687 } 1688 1689 public int checkUidPermission(String permName, int uid) { 1690 synchronized (mPackages) { 1691 Object obj = mSettings.getUserIdLP(uid); 1692 if (obj != null) { 1693 GrantedPermissions gp = (GrantedPermissions)obj; 1694 if (gp.grantedPermissions.contains(permName)) { 1695 return PackageManager.PERMISSION_GRANTED; 1696 } 1697 } else { 1698 HashSet<String> perms = mSystemPermissions.get(uid); 1699 if (perms != null && perms.contains(permName)) { 1700 return PackageManager.PERMISSION_GRANTED; 1701 } 1702 } 1703 } 1704 return PackageManager.PERMISSION_DENIED; 1705 } 1706 1707 private BasePermission findPermissionTreeLP(String permName) { 1708 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 1709 if (permName.startsWith(bp.name) && 1710 permName.length() > bp.name.length() && 1711 permName.charAt(bp.name.length()) == '.') { 1712 return bp; 1713 } 1714 } 1715 return null; 1716 } 1717 1718 private BasePermission checkPermissionTreeLP(String permName) { 1719 if (permName != null) { 1720 BasePermission bp = findPermissionTreeLP(permName); 1721 if (bp != null) { 1722 if (bp.uid == Binder.getCallingUid()) { 1723 return bp; 1724 } 1725 throw new SecurityException("Calling uid " 1726 + Binder.getCallingUid() 1727 + " is not allowed to add to permission tree " 1728 + bp.name + " owned by uid " + bp.uid); 1729 } 1730 } 1731 throw new SecurityException("No permission tree found for " + permName); 1732 } 1733 1734 static boolean compareStrings(CharSequence s1, CharSequence s2) { 1735 if (s1 == null) { 1736 return s2 == null; 1737 } 1738 if (s2 == null) { 1739 return false; 1740 } 1741 if (s1.getClass() != s2.getClass()) { 1742 return false; 1743 } 1744 return s1.equals(s2); 1745 } 1746 1747 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 1748 if (pi1.icon != pi2.icon) return false; 1749 if (pi1.logo != pi2.logo) return false; 1750 if (pi1.protectionLevel != pi2.protectionLevel) return false; 1751 if (!compareStrings(pi1.name, pi2.name)) return false; 1752 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 1753 // We'll take care of setting this one. 1754 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 1755 // These are not currently stored in settings. 1756 //if (!compareStrings(pi1.group, pi2.group)) return false; 1757 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 1758 //if (pi1.labelRes != pi2.labelRes) return false; 1759 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 1760 return true; 1761 } 1762 1763 boolean addPermissionLocked(PermissionInfo info, boolean async) { 1764 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 1765 throw new SecurityException("Label must be specified in permission"); 1766 } 1767 BasePermission tree = checkPermissionTreeLP(info.name); 1768 BasePermission bp = mSettings.mPermissions.get(info.name); 1769 boolean added = bp == null; 1770 boolean changed = true; 1771 if (added) { 1772 bp = new BasePermission(info.name, tree.sourcePackage, 1773 BasePermission.TYPE_DYNAMIC); 1774 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 1775 throw new SecurityException( 1776 "Not allowed to modify non-dynamic permission " 1777 + info.name); 1778 } else { 1779 if (bp.protectionLevel == info.protectionLevel 1780 && bp.perm.owner.equals(tree.perm.owner) 1781 && bp.uid == tree.uid 1782 && comparePermissionInfos(bp.perm.info, info)) { 1783 changed = false; 1784 } 1785 } 1786 bp.protectionLevel = info.protectionLevel; 1787 bp.perm = new PackageParser.Permission(tree.perm.owner, 1788 new PermissionInfo(info)); 1789 bp.perm.info.packageName = tree.perm.info.packageName; 1790 bp.uid = tree.uid; 1791 if (added) { 1792 mSettings.mPermissions.put(info.name, bp); 1793 } 1794 if (changed) { 1795 if (!async) { 1796 mSettings.writeLP(); 1797 } else { 1798 scheduleWriteSettingsLocked(); 1799 } 1800 } 1801 return added; 1802 } 1803 1804 public boolean addPermission(PermissionInfo info) { 1805 synchronized (mPackages) { 1806 return addPermissionLocked(info, false); 1807 } 1808 } 1809 1810 public boolean addPermissionAsync(PermissionInfo info) { 1811 synchronized (mPackages) { 1812 return addPermissionLocked(info, true); 1813 } 1814 } 1815 1816 public void removePermission(String name) { 1817 synchronized (mPackages) { 1818 checkPermissionTreeLP(name); 1819 BasePermission bp = mSettings.mPermissions.get(name); 1820 if (bp != null) { 1821 if (bp.type != BasePermission.TYPE_DYNAMIC) { 1822 throw new SecurityException( 1823 "Not allowed to modify non-dynamic permission " 1824 + name); 1825 } 1826 mSettings.mPermissions.remove(name); 1827 mSettings.writeLP(); 1828 } 1829 } 1830 } 1831 1832 public boolean isProtectedBroadcast(String actionName) { 1833 synchronized (mPackages) { 1834 return mProtectedBroadcasts.contains(actionName); 1835 } 1836 } 1837 1838 public int checkSignatures(String pkg1, String pkg2) { 1839 synchronized (mPackages) { 1840 PackageParser.Package p1 = mPackages.get(pkg1); 1841 PackageParser.Package p2 = mPackages.get(pkg2); 1842 if (p1 == null || p1.mExtras == null 1843 || p2 == null || p2.mExtras == null) { 1844 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 1845 } 1846 return checkSignaturesLP(p1.mSignatures, p2.mSignatures); 1847 } 1848 } 1849 1850 public int checkUidSignatures(int uid1, int uid2) { 1851 synchronized (mPackages) { 1852 Signature[] s1; 1853 Signature[] s2; 1854 Object obj = mSettings.getUserIdLP(uid1); 1855 if (obj != null) { 1856 if (obj instanceof SharedUserSetting) { 1857 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 1858 } else if (obj instanceof PackageSetting) { 1859 s1 = ((PackageSetting)obj).signatures.mSignatures; 1860 } else { 1861 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 1862 } 1863 } else { 1864 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 1865 } 1866 obj = mSettings.getUserIdLP(uid2); 1867 if (obj != null) { 1868 if (obj instanceof SharedUserSetting) { 1869 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 1870 } else if (obj instanceof PackageSetting) { 1871 s2 = ((PackageSetting)obj).signatures.mSignatures; 1872 } else { 1873 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 1874 } 1875 } else { 1876 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 1877 } 1878 return checkSignaturesLP(s1, s2); 1879 } 1880 } 1881 1882 int checkSignaturesLP(Signature[] s1, Signature[] s2) { 1883 if (s1 == null) { 1884 return s2 == null 1885 ? PackageManager.SIGNATURE_NEITHER_SIGNED 1886 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 1887 } 1888 if (s2 == null) { 1889 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 1890 } 1891 HashSet<Signature> set1 = new HashSet<Signature>(); 1892 for (Signature sig : s1) { 1893 set1.add(sig); 1894 } 1895 HashSet<Signature> set2 = new HashSet<Signature>(); 1896 for (Signature sig : s2) { 1897 set2.add(sig); 1898 } 1899 // Make sure s2 contains all signatures in s1. 1900 if (set1.equals(set2)) { 1901 return PackageManager.SIGNATURE_MATCH; 1902 } 1903 return PackageManager.SIGNATURE_NO_MATCH; 1904 } 1905 1906 public String[] getPackagesForUid(int uid) { 1907 synchronized (mPackages) { 1908 Object obj = mSettings.getUserIdLP(uid); 1909 if (obj instanceof SharedUserSetting) { 1910 SharedUserSetting sus = (SharedUserSetting)obj; 1911 final int N = sus.packages.size(); 1912 String[] res = new String[N]; 1913 Iterator<PackageSetting> it = sus.packages.iterator(); 1914 int i=0; 1915 while (it.hasNext()) { 1916 res[i++] = it.next().name; 1917 } 1918 return res; 1919 } else if (obj instanceof PackageSetting) { 1920 PackageSetting ps = (PackageSetting)obj; 1921 return new String[] { ps.name }; 1922 } 1923 } 1924 return null; 1925 } 1926 1927 public String getNameForUid(int uid) { 1928 synchronized (mPackages) { 1929 Object obj = mSettings.getUserIdLP(uid); 1930 if (obj instanceof SharedUserSetting) { 1931 SharedUserSetting sus = (SharedUserSetting)obj; 1932 return sus.name + ":" + sus.userId; 1933 } else if (obj instanceof PackageSetting) { 1934 PackageSetting ps = (PackageSetting)obj; 1935 return ps.name; 1936 } 1937 } 1938 return null; 1939 } 1940 1941 public int getUidForSharedUser(String sharedUserName) { 1942 if(sharedUserName == null) { 1943 return -1; 1944 } 1945 synchronized (mPackages) { 1946 SharedUserSetting suid = mSettings.getSharedUserLP(sharedUserName, 0, false); 1947 if(suid == null) { 1948 return -1; 1949 } 1950 return suid.userId; 1951 } 1952 } 1953 1954 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 1955 int flags) { 1956 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags); 1957 return chooseBestActivity(intent, resolvedType, flags, query); 1958 } 1959 1960 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 1961 int flags, List<ResolveInfo> query) { 1962 if (query != null) { 1963 final int N = query.size(); 1964 if (N == 1) { 1965 return query.get(0); 1966 } else if (N > 1) { 1967 // If there is more than one activity with the same priority, 1968 // then let the user decide between them. 1969 ResolveInfo r0 = query.get(0); 1970 ResolveInfo r1 = query.get(1); 1971 if (false) { 1972 System.out.println(r0.activityInfo.name + 1973 "=" + r0.priority + " vs " + 1974 r1.activityInfo.name + 1975 "=" + r1.priority); 1976 } 1977 // If the first activity has a higher priority, or a different 1978 // default, then it is always desireable to pick it. 1979 if (r0.priority != r1.priority 1980 || r0.preferredOrder != r1.preferredOrder 1981 || r0.isDefault != r1.isDefault) { 1982 return query.get(0); 1983 } 1984 // If we have saved a preference for a preferred activity for 1985 // this Intent, use that. 1986 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 1987 flags, query, r0.priority); 1988 if (ri != null) { 1989 return ri; 1990 } 1991 return mResolveInfo; 1992 } 1993 } 1994 return null; 1995 } 1996 1997 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, 1998 int flags, List<ResolveInfo> query, int priority) { 1999 synchronized (mPackages) { 2000 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 2001 List<PreferredActivity> prefs = 2002 mSettings.mPreferredActivities.queryIntent(intent, resolvedType, 2003 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); 2004 if (prefs != null && prefs.size() > 0) { 2005 // First figure out how good the original match set is. 2006 // We will only allow preferred activities that came 2007 // from the same match quality. 2008 int match = 0; 2009 final int N = query.size(); 2010 if (DEBUG_PREFERRED) Log.v(TAG, "Figuring out best match..."); 2011 for (int j=0; j<N; j++) { 2012 ResolveInfo ri = query.get(j); 2013 if (DEBUG_PREFERRED) Log.v(TAG, "Match for " + ri.activityInfo 2014 + ": 0x" + Integer.toHexString(match)); 2015 if (ri.match > match) match = ri.match; 2016 } 2017 if (DEBUG_PREFERRED) Log.v(TAG, "Best match: 0x" 2018 + Integer.toHexString(match)); 2019 match &= IntentFilter.MATCH_CATEGORY_MASK; 2020 final int M = prefs.size(); 2021 for (int i=0; i<M; i++) { 2022 PreferredActivity pa = prefs.get(i); 2023 if (pa.mMatch != match) { 2024 continue; 2025 } 2026 ActivityInfo ai = getActivityInfo(pa.mActivity, flags); 2027 if (DEBUG_PREFERRED) { 2028 Log.v(TAG, "Got preferred activity:"); 2029 if (ai != null) { 2030 ai.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 2031 } else { 2032 Log.v(TAG, " null"); 2033 } 2034 } 2035 if (ai != null) { 2036 for (int j=0; j<N; j++) { 2037 ResolveInfo ri = query.get(j); 2038 if (!ri.activityInfo.applicationInfo.packageName 2039 .equals(ai.applicationInfo.packageName)) { 2040 continue; 2041 } 2042 if (!ri.activityInfo.name.equals(ai.name)) { 2043 continue; 2044 } 2045 2046 // Okay we found a previously set preferred app. 2047 // If the result set is different from when this 2048 // was created, we need to clear it and re-ask the 2049 // user their preference. 2050 if (!pa.sameSet(query, priority)) { 2051 Slog.i(TAG, "Result set changed, dropping preferred activity for " 2052 + intent + " type " + resolvedType); 2053 mSettings.mPreferredActivities.removeFilter(pa); 2054 return null; 2055 } 2056 2057 // Yay! 2058 return ri; 2059 } 2060 } 2061 } 2062 } 2063 } 2064 return null; 2065 } 2066 2067 public List<ResolveInfo> queryIntentActivities(Intent intent, 2068 String resolvedType, int flags) { 2069 ComponentName comp = intent.getComponent(); 2070 if (comp != null) { 2071 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 2072 ActivityInfo ai = getActivityInfo(comp, flags); 2073 if (ai != null) { 2074 ResolveInfo ri = new ResolveInfo(); 2075 ri.activityInfo = ai; 2076 list.add(ri); 2077 } 2078 return list; 2079 } 2080 2081 synchronized (mPackages) { 2082 String pkgName = intent.getPackage(); 2083 if (pkgName == null) { 2084 return (List<ResolveInfo>)mActivities.queryIntent(intent, 2085 resolvedType, flags); 2086 } 2087 PackageParser.Package pkg = mPackages.get(pkgName); 2088 if (pkg != null) { 2089 return (List<ResolveInfo>) mActivities.queryIntentForPackage(intent, 2090 resolvedType, flags, pkg.activities); 2091 } 2092 return null; 2093 } 2094 } 2095 2096 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 2097 Intent[] specifics, String[] specificTypes, Intent intent, 2098 String resolvedType, int flags) { 2099 final String resultsAction = intent.getAction(); 2100 2101 List<ResolveInfo> results = queryIntentActivities( 2102 intent, resolvedType, flags|PackageManager.GET_RESOLVED_FILTER); 2103 if (Config.LOGV) Log.v(TAG, "Query " + intent + ": " + results); 2104 2105 int specificsPos = 0; 2106 int N; 2107 2108 // todo: note that the algorithm used here is O(N^2). This 2109 // isn't a problem in our current environment, but if we start running 2110 // into situations where we have more than 5 or 10 matches then this 2111 // should probably be changed to something smarter... 2112 2113 // First we go through and resolve each of the specific items 2114 // that were supplied, taking care of removing any corresponding 2115 // duplicate items in the generic resolve list. 2116 if (specifics != null) { 2117 for (int i=0; i<specifics.length; i++) { 2118 final Intent sintent = specifics[i]; 2119 if (sintent == null) { 2120 continue; 2121 } 2122 2123 if (Config.LOGV) Log.v(TAG, "Specific #" + i + ": " + sintent); 2124 String action = sintent.getAction(); 2125 if (resultsAction != null && resultsAction.equals(action)) { 2126 // If this action was explicitly requested, then don't 2127 // remove things that have it. 2128 action = null; 2129 } 2130 ComponentName comp = sintent.getComponent(); 2131 ResolveInfo ri = null; 2132 ActivityInfo ai = null; 2133 if (comp == null) { 2134 ri = resolveIntent( 2135 sintent, 2136 specificTypes != null ? specificTypes[i] : null, 2137 flags); 2138 if (ri == null) { 2139 continue; 2140 } 2141 if (ri == mResolveInfo) { 2142 // ACK! Must do something better with this. 2143 } 2144 ai = ri.activityInfo; 2145 comp = new ComponentName(ai.applicationInfo.packageName, 2146 ai.name); 2147 } else { 2148 ai = getActivityInfo(comp, flags); 2149 if (ai == null) { 2150 continue; 2151 } 2152 } 2153 2154 // Look for any generic query activities that are duplicates 2155 // of this specific one, and remove them from the results. 2156 if (Config.LOGV) Log.v(TAG, "Specific #" + i + ": " + ai); 2157 N = results.size(); 2158 int j; 2159 for (j=specificsPos; j<N; j++) { 2160 ResolveInfo sri = results.get(j); 2161 if ((sri.activityInfo.name.equals(comp.getClassName()) 2162 && sri.activityInfo.applicationInfo.packageName.equals( 2163 comp.getPackageName())) 2164 || (action != null && sri.filter.matchAction(action))) { 2165 results.remove(j); 2166 if (Config.LOGV) Log.v( 2167 TAG, "Removing duplicate item from " + j 2168 + " due to specific " + specificsPos); 2169 if (ri == null) { 2170 ri = sri; 2171 } 2172 j--; 2173 N--; 2174 } 2175 } 2176 2177 // Add this specific item to its proper place. 2178 if (ri == null) { 2179 ri = new ResolveInfo(); 2180 ri.activityInfo = ai; 2181 } 2182 results.add(specificsPos, ri); 2183 ri.specificIndex = i; 2184 specificsPos++; 2185 } 2186 } 2187 2188 // Now we go through the remaining generic results and remove any 2189 // duplicate actions that are found here. 2190 N = results.size(); 2191 for (int i=specificsPos; i<N-1; i++) { 2192 final ResolveInfo rii = results.get(i); 2193 if (rii.filter == null) { 2194 continue; 2195 } 2196 2197 // Iterate over all of the actions of this result's intent 2198 // filter... typically this should be just one. 2199 final Iterator<String> it = rii.filter.actionsIterator(); 2200 if (it == null) { 2201 continue; 2202 } 2203 while (it.hasNext()) { 2204 final String action = it.next(); 2205 if (resultsAction != null && resultsAction.equals(action)) { 2206 // If this action was explicitly requested, then don't 2207 // remove things that have it. 2208 continue; 2209 } 2210 for (int j=i+1; j<N; j++) { 2211 final ResolveInfo rij = results.get(j); 2212 if (rij.filter != null && rij.filter.hasAction(action)) { 2213 results.remove(j); 2214 if (Config.LOGV) Log.v( 2215 TAG, "Removing duplicate item from " + j 2216 + " due to action " + action + " at " + i); 2217 j--; 2218 N--; 2219 } 2220 } 2221 } 2222 2223 // If the caller didn't request filter information, drop it now 2224 // so we don't have to marshall/unmarshall it. 2225 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 2226 rii.filter = null; 2227 } 2228 } 2229 2230 // Filter out the caller activity if so requested. 2231 if (caller != null) { 2232 N = results.size(); 2233 for (int i=0; i<N; i++) { 2234 ActivityInfo ainfo = results.get(i).activityInfo; 2235 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 2236 && caller.getClassName().equals(ainfo.name)) { 2237 results.remove(i); 2238 break; 2239 } 2240 } 2241 } 2242 2243 // If the caller didn't request filter information, 2244 // drop them now so we don't have to 2245 // marshall/unmarshall it. 2246 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 2247 N = results.size(); 2248 for (int i=0; i<N; i++) { 2249 results.get(i).filter = null; 2250 } 2251 } 2252 2253 if (Config.LOGV) Log.v(TAG, "Result: " + results); 2254 return results; 2255 } 2256 2257 public List<ResolveInfo> queryIntentReceivers(Intent intent, 2258 String resolvedType, int flags) { 2259 ComponentName comp = intent.getComponent(); 2260 if (comp != null) { 2261 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 2262 ActivityInfo ai = getReceiverInfo(comp, flags); 2263 if (ai != null) { 2264 ResolveInfo ri = new ResolveInfo(); 2265 ri.activityInfo = ai; 2266 list.add(ri); 2267 } 2268 return list; 2269 } 2270 2271 synchronized (mPackages) { 2272 String pkgName = intent.getPackage(); 2273 if (pkgName == null) { 2274 return (List<ResolveInfo>)mReceivers.queryIntent(intent, 2275 resolvedType, flags); 2276 } 2277 PackageParser.Package pkg = mPackages.get(pkgName); 2278 if (pkg != null) { 2279 return (List<ResolveInfo>) mReceivers.queryIntentForPackage(intent, 2280 resolvedType, flags, pkg.receivers); 2281 } 2282 return null; 2283 } 2284 } 2285 2286 public ResolveInfo resolveService(Intent intent, String resolvedType, 2287 int flags) { 2288 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, 2289 flags); 2290 if (query != null) { 2291 if (query.size() >= 1) { 2292 // If there is more than one service with the same priority, 2293 // just arbitrarily pick the first one. 2294 return query.get(0); 2295 } 2296 } 2297 return null; 2298 } 2299 2300 public List<ResolveInfo> queryIntentServices(Intent intent, 2301 String resolvedType, int flags) { 2302 ComponentName comp = intent.getComponent(); 2303 if (comp != null) { 2304 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 2305 ServiceInfo si = getServiceInfo(comp, flags); 2306 if (si != null) { 2307 ResolveInfo ri = new ResolveInfo(); 2308 ri.serviceInfo = si; 2309 list.add(ri); 2310 } 2311 return list; 2312 } 2313 2314 synchronized (mPackages) { 2315 String pkgName = intent.getPackage(); 2316 if (pkgName == null) { 2317 return (List<ResolveInfo>)mServices.queryIntent(intent, 2318 resolvedType, flags); 2319 } 2320 PackageParser.Package pkg = mPackages.get(pkgName); 2321 if (pkg != null) { 2322 return (List<ResolveInfo>)mServices.queryIntentForPackage(intent, 2323 resolvedType, flags, pkg.services); 2324 } 2325 return null; 2326 } 2327 } 2328 2329 private static final int getContinuationPoint(final String[] keys, final String key) { 2330 final int index; 2331 if (key == null) { 2332 index = 0; 2333 } else { 2334 final int insertPoint = Arrays.binarySearch(keys, key); 2335 if (insertPoint < 0) { 2336 index = -insertPoint; 2337 } else { 2338 index = insertPoint + 1; 2339 } 2340 } 2341 return index; 2342 } 2343 2344 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead) { 2345 final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>(); 2346 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 2347 final String[] keys; 2348 2349 synchronized (mPackages) { 2350 if (listUninstalled) { 2351 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]); 2352 } else { 2353 keys = mPackages.keySet().toArray(new String[mPackages.size()]); 2354 } 2355 2356 Arrays.sort(keys); 2357 int i = getContinuationPoint(keys, lastRead); 2358 final int N = keys.length; 2359 2360 while (i < N) { 2361 final String packageName = keys[i++]; 2362 2363 PackageInfo pi = null; 2364 if (listUninstalled) { 2365 final PackageSetting ps = mSettings.mPackages.get(packageName); 2366 if (ps != null) { 2367 pi = generatePackageInfoFromSettingsLP(ps.name, flags); 2368 } 2369 } else { 2370 final PackageParser.Package p = mPackages.get(packageName); 2371 if (p != null) { 2372 pi = generatePackageInfo(p, flags); 2373 } 2374 } 2375 2376 if (pi != null && !list.append(pi)) { 2377 break; 2378 } 2379 } 2380 2381 if (i == N) { 2382 list.setLastSlice(true); 2383 } 2384 } 2385 2386 return list; 2387 } 2388 2389 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, 2390 String lastRead) { 2391 final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>(); 2392 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 2393 final String[] keys; 2394 2395 synchronized (mPackages) { 2396 if (listUninstalled) { 2397 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]); 2398 } else { 2399 keys = mPackages.keySet().toArray(new String[mPackages.size()]); 2400 } 2401 2402 Arrays.sort(keys); 2403 int i = getContinuationPoint(keys, lastRead); 2404 final int N = keys.length; 2405 2406 while (i < N) { 2407 final String packageName = keys[i++]; 2408 2409 ApplicationInfo ai = null; 2410 if (listUninstalled) { 2411 final PackageSetting ps = mSettings.mPackages.get(packageName); 2412 if (ps != null) { 2413 ai = generateApplicationInfoFromSettingsLP(ps.name, flags); 2414 } 2415 } else { 2416 final PackageParser.Package p = mPackages.get(packageName); 2417 if (p != null) { 2418 ai = PackageParser.generateApplicationInfo(p, flags); 2419 } 2420 } 2421 2422 if (ai != null && !list.append(ai)) { 2423 break; 2424 } 2425 } 2426 2427 if (i == N) { 2428 list.setLastSlice(true); 2429 } 2430 } 2431 2432 return list; 2433 } 2434 2435 public List<ApplicationInfo> getPersistentApplications(int flags) { 2436 ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 2437 2438 synchronized (mPackages) { 2439 Iterator<PackageParser.Package> i = mPackages.values().iterator(); 2440 while (i.hasNext()) { 2441 PackageParser.Package p = i.next(); 2442 if (p.applicationInfo != null 2443 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 2444 && (!mSafeMode || isSystemApp(p))) { 2445 finalList.add(PackageParser.generateApplicationInfo(p, flags)); 2446 } 2447 } 2448 } 2449 2450 return finalList; 2451 } 2452 2453 public ProviderInfo resolveContentProvider(String name, int flags) { 2454 synchronized (mPackages) { 2455 final PackageParser.Provider provider = mProviders.get(name); 2456 return provider != null 2457 && mSettings.isEnabledLP(provider.info, flags) 2458 && (!mSafeMode || (provider.info.applicationInfo.flags 2459 &ApplicationInfo.FLAG_SYSTEM) != 0) 2460 ? PackageParser.generateProviderInfo(provider, flags) 2461 : null; 2462 } 2463 } 2464 2465 /** 2466 * @deprecated 2467 */ 2468 public void querySyncProviders(List outNames, List outInfo) { 2469 synchronized (mPackages) { 2470 Iterator<Map.Entry<String, PackageParser.Provider>> i 2471 = mProviders.entrySet().iterator(); 2472 2473 while (i.hasNext()) { 2474 Map.Entry<String, PackageParser.Provider> entry = i.next(); 2475 PackageParser.Provider p = entry.getValue(); 2476 2477 if (p.syncable 2478 && (!mSafeMode || (p.info.applicationInfo.flags 2479 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 2480 outNames.add(entry.getKey()); 2481 outInfo.add(PackageParser.generateProviderInfo(p, 0)); 2482 } 2483 } 2484 } 2485 } 2486 2487 public List<ProviderInfo> queryContentProviders(String processName, 2488 int uid, int flags) { 2489 ArrayList<ProviderInfo> finalList = null; 2490 2491 synchronized (mPackages) { 2492 Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator(); 2493 while (i.hasNext()) { 2494 PackageParser.Provider p = i.next(); 2495 if (p.info.authority != null 2496 && (processName == null || 2497 (p.info.processName.equals(processName) 2498 && p.info.applicationInfo.uid == uid)) 2499 && mSettings.isEnabledLP(p.info, flags) 2500 && (!mSafeMode || (p.info.applicationInfo.flags 2501 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 2502 if (finalList == null) { 2503 finalList = new ArrayList<ProviderInfo>(3); 2504 } 2505 finalList.add(PackageParser.generateProviderInfo(p, 2506 flags)); 2507 } 2508 } 2509 } 2510 2511 if (finalList != null) { 2512 Collections.sort(finalList, mProviderInitOrderSorter); 2513 } 2514 2515 return finalList; 2516 } 2517 2518 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 2519 int flags) { 2520 synchronized (mPackages) { 2521 final PackageParser.Instrumentation i = mInstrumentation.get(name); 2522 return PackageParser.generateInstrumentationInfo(i, flags); 2523 } 2524 } 2525 2526 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 2527 int flags) { 2528 ArrayList<InstrumentationInfo> finalList = 2529 new ArrayList<InstrumentationInfo>(); 2530 2531 synchronized (mPackages) { 2532 Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 2533 while (i.hasNext()) { 2534 PackageParser.Instrumentation p = i.next(); 2535 if (targetPackage == null 2536 || targetPackage.equals(p.info.targetPackage)) { 2537 finalList.add(PackageParser.generateInstrumentationInfo(p, 2538 flags)); 2539 } 2540 } 2541 } 2542 2543 return finalList; 2544 } 2545 2546 private void scanDirLI(File dir, int flags, int scanMode, long currentTime) { 2547 String[] files = dir.list(); 2548 if (files == null) { 2549 Log.d(TAG, "No files in app dir " + dir); 2550 return; 2551 } 2552 2553 if (false) { 2554 Log.d(TAG, "Scanning app dir " + dir); 2555 } 2556 2557 int i; 2558 for (i=0; i<files.length; i++) { 2559 File file = new File(dir, files[i]); 2560 if (!isPackageFilename(files[i])) { 2561 // Ignore entries which are not apk's 2562 continue; 2563 } 2564 PackageParser.Package pkg = scanPackageLI(file, 2565 flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime); 2566 // Don't mess around with apps in system partition. 2567 if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 && 2568 mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) { 2569 // Delete the apk 2570 Slog.w(TAG, "Cleaning up failed install of " + file); 2571 file.delete(); 2572 } 2573 } 2574 } 2575 2576 private static File getSettingsProblemFile() { 2577 File dataDir = Environment.getDataDirectory(); 2578 File systemDir = new File(dataDir, "system"); 2579 File fname = new File(systemDir, "uiderrors.txt"); 2580 return fname; 2581 } 2582 2583 private static void reportSettingsProblem(int priority, String msg) { 2584 try { 2585 File fname = getSettingsProblemFile(); 2586 FileOutputStream out = new FileOutputStream(fname, true); 2587 PrintWriter pw = new PrintWriter(out); 2588 SimpleDateFormat formatter = new SimpleDateFormat(); 2589 String dateString = formatter.format(new Date(System.currentTimeMillis())); 2590 pw.println(dateString + ": " + msg); 2591 pw.close(); 2592 FileUtils.setPermissions( 2593 fname.toString(), 2594 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 2595 -1, -1); 2596 } catch (java.io.IOException e) { 2597 } 2598 Slog.println(priority, TAG, msg); 2599 } 2600 2601 private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps, 2602 PackageParser.Package pkg, File srcFile, int parseFlags) { 2603 if (GET_CERTIFICATES) { 2604 if (ps != null 2605 && ps.codePath.equals(srcFile) 2606 && ps.timeStamp == srcFile.lastModified()) { 2607 if (ps.signatures.mSignatures != null 2608 && ps.signatures.mSignatures.length != 0) { 2609 // Optimization: reuse the existing cached certificates 2610 // if the package appears to be unchanged. 2611 pkg.mSignatures = ps.signatures.mSignatures; 2612 return true; 2613 } 2614 2615 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures. Collecting certs again to recover them."); 2616 } else { 2617 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 2618 } 2619 2620 if (!pp.collectCertificates(pkg, parseFlags)) { 2621 mLastScanError = pp.getParseError(); 2622 return false; 2623 } 2624 } 2625 return true; 2626 } 2627 2628 /* 2629 * Scan a package and return the newly parsed package. 2630 * Returns null in case of errors and the error code is stored in mLastScanError 2631 */ 2632 private PackageParser.Package scanPackageLI(File scanFile, 2633 int parseFlags, int scanMode, long currentTime) { 2634 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 2635 String scanPath = scanFile.getPath(); 2636 parseFlags |= mDefParseFlags; 2637 PackageParser pp = new PackageParser(scanPath); 2638 pp.setSeparateProcesses(mSeparateProcesses); 2639 final PackageParser.Package pkg = pp.parsePackage(scanFile, 2640 scanPath, mMetrics, parseFlags); 2641 if (pkg == null) { 2642 mLastScanError = pp.getParseError(); 2643 return null; 2644 } 2645 PackageSetting ps = null; 2646 PackageSetting updatedPkg; 2647 synchronized (mPackages) { 2648 // Look to see if we already know about this package. 2649 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 2650 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 2651 // This package has been renamed to its original name. Let's 2652 // use that. 2653 ps = mSettings.peekPackageLP(oldName); 2654 } 2655 // If there was no original package, see one for the real package name. 2656 if (ps == null) { 2657 ps = mSettings.peekPackageLP(pkg.packageName); 2658 } 2659 // Check to see if this package could be hiding/updating a system 2660 // package. Must look for it either under the original or real 2661 // package name depending on our state. 2662 updatedPkg = mSettings.mDisabledSysPackages.get( 2663 ps != null ? ps.name : pkg.packageName); 2664 } 2665 // First check if this is a system package that may involve an update 2666 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 2667 if (ps != null && !ps.codePath.equals(scanFile)) { 2668 // The path has changed from what was last scanned... check the 2669 // version of the new path against what we have stored to determine 2670 // what to do. 2671 if (pkg.mVersionCode < ps.versionCode) { 2672 // The system package has been updated and the code path does not match 2673 // Ignore entry. Skip it. 2674 Log.i(TAG, "Package " + ps.name + " at " + scanFile 2675 + " ignored: updated version " + ps.versionCode 2676 + " better than this " + pkg.mVersionCode); 2677 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 2678 return null; 2679 } else { 2680 // The current app on the system partion is better than 2681 // what we have updated to on the data partition; switch 2682 // back to the system partition version. 2683 // At this point, its safely assumed that package installation for 2684 // apps in system partition will go through. If not there won't be a working 2685 // version of the app 2686 synchronized (mPackages) { 2687 // Just remove the loaded entries from package lists. 2688 mPackages.remove(ps.name); 2689 } 2690 Slog.w(TAG, "Package " + ps.name + " at " + scanFile 2691 + "reverting from " + ps.codePathString 2692 + ": new version " + pkg.mVersionCode 2693 + " better than installed " + ps.versionCode); 2694 InstallArgs args = new FileInstallArgs(ps.codePathString, 2695 ps.resourcePathString, ps.nativeLibraryPathString); 2696 args.cleanUpResourcesLI(); 2697 mSettings.enableSystemPackageLP(ps.name); 2698 } 2699 } 2700 } 2701 if (updatedPkg != null) { 2702 // An updated system app will not have the PARSE_IS_SYSTEM flag set initially 2703 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 2704 } 2705 // Verify certificates against what was last scanned 2706 if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) { 2707 Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName); 2708 return null; 2709 } 2710 // The apk is forward locked (not public) if its code and resources 2711 // are kept in different files. 2712 // TODO grab this value from PackageSettings 2713 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 2714 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 2715 } 2716 2717 String codePath = null; 2718 String resPath = null; 2719 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) { 2720 if (ps != null && ps.resourcePathString != null) { 2721 resPath = ps.resourcePathString; 2722 } else { 2723 // Should not happen at all. Just log an error. 2724 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 2725 } 2726 } else { 2727 resPath = pkg.mScanPath; 2728 } 2729 codePath = pkg.mScanPath; 2730 // Set application objects path explicitly. 2731 setApplicationInfoPaths(pkg, codePath, resPath); 2732 // Note that we invoke the following method only if we are about to unpack an application 2733 return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime); 2734 } 2735 2736 private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath, 2737 String destResPath) { 2738 pkg.mPath = pkg.mScanPath = destCodePath; 2739 pkg.applicationInfo.sourceDir = destCodePath; 2740 pkg.applicationInfo.publicSourceDir = destResPath; 2741 } 2742 2743 private static String fixProcessName(String defProcessName, 2744 String processName, int uid) { 2745 if (processName == null) { 2746 return defProcessName; 2747 } 2748 return processName; 2749 } 2750 2751 private boolean verifySignaturesLP(PackageSetting pkgSetting, 2752 PackageParser.Package pkg) { 2753 if (pkgSetting.signatures.mSignatures != null) { 2754 // Already existing package. Make sure signatures match 2755 if (checkSignaturesLP(pkgSetting.signatures.mSignatures, pkg.mSignatures) != 2756 PackageManager.SIGNATURE_MATCH) { 2757 Slog.e(TAG, "Package " + pkg.packageName 2758 + " signatures do not match the previously installed version; ignoring!"); 2759 mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 2760 return false; 2761 } 2762 } 2763 // Check for shared user signatures 2764 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 2765 if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures, 2766 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 2767 Slog.e(TAG, "Package " + pkg.packageName 2768 + " has no signatures that match those in shared user " 2769 + pkgSetting.sharedUser.name + "; ignoring!"); 2770 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 2771 return false; 2772 } 2773 } 2774 return true; 2775 } 2776 2777 public boolean performDexOpt(String packageName) { 2778 if (!mNoDexOpt) { 2779 return false; 2780 } 2781 2782 PackageParser.Package p; 2783 synchronized (mPackages) { 2784 p = mPackages.get(packageName); 2785 if (p == null || p.mDidDexOpt) { 2786 return false; 2787 } 2788 } 2789 synchronized (mInstallLock) { 2790 return performDexOptLI(p, false) == DEX_OPT_PERFORMED; 2791 } 2792 } 2793 2794 static final int DEX_OPT_SKIPPED = 0; 2795 static final int DEX_OPT_PERFORMED = 1; 2796 static final int DEX_OPT_FAILED = -1; 2797 2798 private int performDexOptLI(PackageParser.Package pkg, boolean forceDex) { 2799 boolean performed = false; 2800 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0 && mInstaller != null) { 2801 String path = pkg.mScanPath; 2802 int ret = 0; 2803 try { 2804 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) { 2805 ret = mInstaller.dexopt(path, pkg.applicationInfo.uid, 2806 !isForwardLocked(pkg)); 2807 pkg.mDidDexOpt = true; 2808 performed = true; 2809 } 2810 } catch (FileNotFoundException e) { 2811 Slog.w(TAG, "Apk not found for dexopt: " + path); 2812 ret = -1; 2813 } catch (IOException e) { 2814 Slog.w(TAG, "IOException reading apk: " + path, e); 2815 ret = -1; 2816 } catch (dalvik.system.StaleDexCacheError e) { 2817 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e); 2818 ret = -1; 2819 } catch (Exception e) { 2820 Slog.w(TAG, "Exception when doing dexopt : ", e); 2821 ret = -1; 2822 } 2823 if (ret < 0) { 2824 //error from installer 2825 return DEX_OPT_FAILED; 2826 } 2827 } 2828 2829 return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED; 2830 } 2831 2832 private static boolean useEncryptedFilesystemForPackage(PackageParser.Package pkg) { 2833 return Environment.isEncryptedFilesystemEnabled() && 2834 ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_NEVER_ENCRYPT) == 0); 2835 } 2836 2837 private boolean verifyPackageUpdate(PackageSetting oldPkg, PackageParser.Package newPkg) { 2838 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 2839 Slog.w(TAG, "Unable to update from " + oldPkg.name 2840 + " to " + newPkg.packageName 2841 + ": old package not in system partition"); 2842 return false; 2843 } else if (mPackages.get(oldPkg.name) != null) { 2844 Slog.w(TAG, "Unable to update from " + oldPkg.name 2845 + " to " + newPkg.packageName 2846 + ": old package still exists"); 2847 return false; 2848 } 2849 return true; 2850 } 2851 2852 private File getDataPathForPackage(PackageParser.Package pkg) { 2853 boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg); 2854 File dataPath; 2855 if (useEncryptedFSDir) { 2856 dataPath = new File(mSecureAppDataDir, pkg.packageName); 2857 } else { 2858 dataPath = new File(mAppDataDir, pkg.packageName); 2859 } 2860 return dataPath; 2861 } 2862 2863 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, 2864 int parseFlags, int scanMode, long currentTime) { 2865 File scanFile = new File(pkg.mScanPath); 2866 if (scanFile == null || pkg.applicationInfo.sourceDir == null || 2867 pkg.applicationInfo.publicSourceDir == null) { 2868 // Bail out. The resource and code paths haven't been set. 2869 Slog.w(TAG, " Code and resource paths haven't been set correctly"); 2870 mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK; 2871 return null; 2872 } 2873 mScanningPath = scanFile; 2874 if (pkg == null) { 2875 mLastScanError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; 2876 return null; 2877 } 2878 2879 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 2880 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 2881 } 2882 2883 if (pkg.packageName.equals("android")) { 2884 synchronized (mPackages) { 2885 if (mAndroidApplication != null) { 2886 Slog.w(TAG, "*************************************************"); 2887 Slog.w(TAG, "Core android package being redefined. Skipping."); 2888 Slog.w(TAG, " file=" + mScanningPath); 2889 Slog.w(TAG, "*************************************************"); 2890 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 2891 return null; 2892 } 2893 2894 // Set up information for our fall-back user intent resolution 2895 // activity. 2896 mPlatformPackage = pkg; 2897 pkg.mVersionCode = mSdkVersion; 2898 mAndroidApplication = pkg.applicationInfo; 2899 mResolveActivity.applicationInfo = mAndroidApplication; 2900 mResolveActivity.name = ResolverActivity.class.getName(); 2901 mResolveActivity.packageName = mAndroidApplication.packageName; 2902 mResolveActivity.processName = mAndroidApplication.processName; 2903 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 2904 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 2905 mResolveActivity.theme = com.android.internal.R.style.Theme_Dialog_Alert; 2906 mResolveActivity.exported = true; 2907 mResolveActivity.enabled = true; 2908 mResolveInfo.activityInfo = mResolveActivity; 2909 mResolveInfo.priority = 0; 2910 mResolveInfo.preferredOrder = 0; 2911 mResolveInfo.match = 0; 2912 mResolveComponentName = new ComponentName( 2913 mAndroidApplication.packageName, mResolveActivity.name); 2914 } 2915 } 2916 2917 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) Log.d( 2918 TAG, "Scanning package " + pkg.packageName); 2919 if (mPackages.containsKey(pkg.packageName) 2920 || mSharedLibraries.containsKey(pkg.packageName)) { 2921 Slog.w(TAG, "Application package " + pkg.packageName 2922 + " already installed. Skipping duplicate."); 2923 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 2924 return null; 2925 } 2926 2927 // Initialize package source and resource directories 2928 File destCodeFile = new File(pkg.applicationInfo.sourceDir); 2929 File destResourceFile = new File(pkg.applicationInfo.publicSourceDir); 2930 2931 SharedUserSetting suid = null; 2932 PackageSetting pkgSetting = null; 2933 2934 if (!isSystemApp(pkg)) { 2935 // Only system apps can use these features. 2936 pkg.mOriginalPackages = null; 2937 pkg.mRealPackage = null; 2938 pkg.mAdoptPermissions = null; 2939 } 2940 2941 synchronized (mPackages) { 2942 // Check all shared libraries and map to their actual file path. 2943 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 2944 if (mTmpSharedLibraries == null || 2945 mTmpSharedLibraries.length < mSharedLibraries.size()) { 2946 mTmpSharedLibraries = new String[mSharedLibraries.size()]; 2947 } 2948 int num = 0; 2949 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 2950 for (int i=0; i<N; i++) { 2951 String file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 2952 if (file == null) { 2953 Slog.e(TAG, "Package " + pkg.packageName 2954 + " requires unavailable shared library " 2955 + pkg.usesLibraries.get(i) + "; failing!"); 2956 mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 2957 return null; 2958 } 2959 mTmpSharedLibraries[num] = file; 2960 num++; 2961 } 2962 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 2963 for (int i=0; i<N; i++) { 2964 String file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 2965 if (file == null) { 2966 Slog.w(TAG, "Package " + pkg.packageName 2967 + " desires unavailable shared library " 2968 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 2969 } else { 2970 mTmpSharedLibraries[num] = file; 2971 num++; 2972 } 2973 } 2974 if (num > 0) { 2975 pkg.usesLibraryFiles = new String[num]; 2976 System.arraycopy(mTmpSharedLibraries, 0, 2977 pkg.usesLibraryFiles, 0, num); 2978 } 2979 } 2980 2981 if (pkg.mSharedUserId != null) { 2982 suid = mSettings.getSharedUserLP(pkg.mSharedUserId, 2983 pkg.applicationInfo.flags, true); 2984 if (suid == null) { 2985 Slog.w(TAG, "Creating application package " + pkg.packageName 2986 + " for shared user failed"); 2987 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 2988 return null; 2989 } 2990 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) { 2991 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" 2992 + suid.userId + "): packages=" + suid.packages); 2993 } 2994 } 2995 2996 if (false) { 2997 if (pkg.mOriginalPackages != null) { 2998 Log.w(TAG, "WAITING FOR DEBUGGER"); 2999 Debug.waitForDebugger(); 3000 Log.i(TAG, "Package " + pkg.packageName + " from original packages" 3001 + pkg.mOriginalPackages); 3002 } 3003 } 3004 3005 // Check if we are renaming from an original package name. 3006 PackageSetting origPackage = null; 3007 String realName = null; 3008 if (pkg.mOriginalPackages != null) { 3009 // This package may need to be renamed to a previously 3010 // installed name. Let's check on that... 3011 String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 3012 if (pkg.mOriginalPackages.contains(renamed)) { 3013 // This package had originally been installed as the 3014 // original name, and we have already taken care of 3015 // transitioning to the new one. Just update the new 3016 // one to continue using the old name. 3017 realName = pkg.mRealPackage; 3018 if (!pkg.packageName.equals(renamed)) { 3019 // Callers into this function may have already taken 3020 // care of renaming the package; only do it here if 3021 // it is not already done. 3022 pkg.setPackageName(renamed); 3023 } 3024 3025 } else { 3026 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 3027 if ((origPackage=mSettings.peekPackageLP( 3028 pkg.mOriginalPackages.get(i))) != null) { 3029 // We do have the package already installed under its 3030 // original name... should we use it? 3031 if (!verifyPackageUpdate(origPackage, pkg)) { 3032 // New package is not compatible with original. 3033 origPackage = null; 3034 continue; 3035 } else if (origPackage.sharedUser != null) { 3036 // Make sure uid is compatible between packages. 3037 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 3038 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 3039 + " to " + pkg.packageName + ": old uid " 3040 + origPackage.sharedUser.name 3041 + " differs from " + pkg.mSharedUserId); 3042 origPackage = null; 3043 continue; 3044 } 3045 } else { 3046 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 3047 + pkg.packageName + " to old name " + origPackage.name); 3048 } 3049 break; 3050 } 3051 } 3052 } 3053 } 3054 3055 if (mTransferedPackages.contains(pkg.packageName)) { 3056 Slog.w(TAG, "Package " + pkg.packageName 3057 + " was transferred to another, but its .apk remains"); 3058 } 3059 3060 // Just create the setting, don't add it yet. For already existing packages 3061 // the PkgSetting exists already and doesn't have to be created. 3062 pkgSetting = mSettings.getPackageLP(pkg, origPackage, realName, suid, destCodeFile, 3063 destResourceFile, pkg.applicationInfo.nativeLibraryDir, 3064 pkg.applicationInfo.flags, true, false); 3065 if (pkgSetting == null) { 3066 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed"); 3067 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3068 return null; 3069 } 3070 3071 if (pkgSetting.origPackage != null) { 3072 // If we are first transitioning from an original package, 3073 // fix up the new package's name now. We need to do this after 3074 // looking up the package under its new name, so getPackageLP 3075 // can take care of fiddling things correctly. 3076 pkg.setPackageName(origPackage.name); 3077 3078 // File a report about this. 3079 String msg = "New package " + pkgSetting.realName 3080 + " renamed to replace old package " + pkgSetting.name; 3081 reportSettingsProblem(Log.WARN, msg); 3082 3083 // Make a note of it. 3084 mTransferedPackages.add(origPackage.name); 3085 3086 // No longer need to retain this. 3087 pkgSetting.origPackage = null; 3088 } 3089 3090 if (realName != null) { 3091 // Make a note of it. 3092 mTransferedPackages.add(pkg.packageName); 3093 } 3094 3095 if (mSettings.mDisabledSysPackages.get(pkg.packageName) != null) { 3096 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 3097 } 3098 3099 pkg.applicationInfo.uid = pkgSetting.userId; 3100 pkg.mExtras = pkgSetting; 3101 3102 if (!verifySignaturesLP(pkgSetting, pkg)) { 3103 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 3104 return null; 3105 } 3106 // The signature has changed, but this package is in the system 3107 // image... let's recover! 3108 pkgSetting.signatures.mSignatures = pkg.mSignatures; 3109 // However... if this package is part of a shared user, but it 3110 // doesn't match the signature of the shared user, let's fail. 3111 // What this means is that you can't change the signatures 3112 // associated with an overall shared user, which doesn't seem all 3113 // that unreasonable. 3114 if (pkgSetting.sharedUser != null) { 3115 if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures, 3116 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 3117 Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser); 3118 mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 3119 return null; 3120 } 3121 } 3122 // File a report about this. 3123 String msg = "System package " + pkg.packageName 3124 + " signature changed; retaining data."; 3125 reportSettingsProblem(Log.WARN, msg); 3126 } 3127 3128 // Verify that this new package doesn't have any content providers 3129 // that conflict with existing packages. Only do this if the 3130 // package isn't already installed, since we don't want to break 3131 // things that are installed. 3132 if ((scanMode&SCAN_NEW_INSTALL) != 0) { 3133 int N = pkg.providers.size(); 3134 int i; 3135 for (i=0; i<N; i++) { 3136 PackageParser.Provider p = pkg.providers.get(i); 3137 if (p.info.authority != null) { 3138 String names[] = p.info.authority.split(";"); 3139 for (int j = 0; j < names.length; j++) { 3140 if (mProviders.containsKey(names[j])) { 3141 PackageParser.Provider other = mProviders.get(names[j]); 3142 Slog.w(TAG, "Can't install because provider name " + names[j] + 3143 " (in package " + pkg.applicationInfo.packageName + 3144 ") is already used by " 3145 + ((other != null && other.getComponentName() != null) 3146 ? other.getComponentName().getPackageName() : "?")); 3147 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 3148 return null; 3149 } 3150 } 3151 } 3152 } 3153 } 3154 } 3155 3156 final String pkgName = pkg.packageName; 3157 3158 if (pkg.mAdoptPermissions != null) { 3159 // This package wants to adopt ownership of permissions from 3160 // another package. 3161 for (int i=pkg.mAdoptPermissions.size()-1; i>=0; i--) { 3162 String origName = pkg.mAdoptPermissions.get(i); 3163 PackageSetting orig = mSettings.peekPackageLP(origName); 3164 if (orig != null) { 3165 if (verifyPackageUpdate(orig, pkg)) { 3166 Slog.i(TAG, "Adopting permissions from " 3167 + origName + " to " + pkg.packageName); 3168 mSettings.transferPermissions(origName, pkg.packageName); 3169 } 3170 } 3171 } 3172 } 3173 3174 final long scanFileTime = scanFile.lastModified(); 3175 final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0; 3176 final boolean scanFileNewer = forceDex || scanFileTime != pkgSetting.timeStamp; 3177 pkg.applicationInfo.processName = fixProcessName( 3178 pkg.applicationInfo.packageName, 3179 pkg.applicationInfo.processName, 3180 pkg.applicationInfo.uid); 3181 3182 File dataPath; 3183 if (mPlatformPackage == pkg) { 3184 // The system package is special. 3185 dataPath = new File (Environment.getDataDirectory(), "system"); 3186 pkg.applicationInfo.dataDir = dataPath.getPath(); 3187 } else { 3188 // This is a normal package, need to make its data directory. 3189 boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg); 3190 dataPath = getDataPathForPackage(pkg); 3191 3192 boolean uidError = false; 3193 3194 if (dataPath.exists()) { 3195 mOutPermissions[1] = 0; 3196 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions); 3197 3198 // If we have mismatched owners for the data path, we have a 3199 // problem (unless we're running in the simulator.) 3200 if (mOutPermissions[1] != pkg.applicationInfo.uid && Process.supportsProcesses()) { 3201 boolean recovered = false; 3202 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 3203 // If this is a system app, we can at least delete its 3204 // current data so the application will still work. 3205 if (mInstaller != null) { 3206 int ret = mInstaller.remove(pkgName, useEncryptedFSDir); 3207 if (ret >= 0) { 3208 // Old data gone! 3209 String msg = "System package " + pkg.packageName 3210 + " has changed from uid: " 3211 + mOutPermissions[1] + " to " 3212 + pkg.applicationInfo.uid + "; old data erased"; 3213 reportSettingsProblem(Log.WARN, msg); 3214 recovered = true; 3215 3216 // And now re-install the app. 3217 ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid, 3218 pkg.applicationInfo.uid); 3219 if (ret == -1) { 3220 // Ack should not happen! 3221 msg = "System package " + pkg.packageName 3222 + " could not have data directory re-created after delete."; 3223 reportSettingsProblem(Log.WARN, msg); 3224 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3225 return null; 3226 } 3227 } 3228 } 3229 if (!recovered) { 3230 mHasSystemUidErrors = true; 3231 } 3232 } 3233 if (!recovered) { 3234 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 3235 + pkg.applicationInfo.uid + "/fs_" 3236 + mOutPermissions[1]; 3237 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 3238 String msg = "Package " + pkg.packageName 3239 + " has mismatched uid: " 3240 + mOutPermissions[1] + " on disk, " 3241 + pkg.applicationInfo.uid + " in settings"; 3242 synchronized (mPackages) { 3243 mSettings.mReadMessages.append(msg); 3244 mSettings.mReadMessages.append('\n'); 3245 uidError = true; 3246 if (!pkgSetting.uidError) { 3247 reportSettingsProblem(Log.ERROR, msg); 3248 } 3249 } 3250 } 3251 } 3252 pkg.applicationInfo.dataDir = dataPath.getPath(); 3253 } else { 3254 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGV) 3255 Log.v(TAG, "Want this data dir: " + dataPath); 3256 //invoke installer to do the actual installation 3257 if (mInstaller != null) { 3258 int ret = mInstaller.install(pkgName, useEncryptedFSDir, pkg.applicationInfo.uid, 3259 pkg.applicationInfo.uid); 3260 if(ret < 0) { 3261 // Error from installer 3262 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3263 return null; 3264 } 3265 } else { 3266 dataPath.mkdirs(); 3267 if (dataPath.exists()) { 3268 FileUtils.setPermissions( 3269 dataPath.toString(), 3270 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 3271 pkg.applicationInfo.uid, pkg.applicationInfo.uid); 3272 } 3273 } 3274 if (dataPath.exists()) { 3275 pkg.applicationInfo.dataDir = dataPath.getPath(); 3276 } else { 3277 Slog.w(TAG, "Unable to create data directory: " + dataPath); 3278 pkg.applicationInfo.dataDir = null; 3279 } 3280 } 3281 3282 /* 3283 * Set the data dir to the default "/data/data/<package name>/lib" 3284 * if we got here without anyone telling us different (e.g., apps 3285 * stored on SD card have their native libraries stored in the ASEC 3286 * container with the APK). 3287 * 3288 * This happens during an upgrade from a package settings file that 3289 * doesn't have a native library path attribute at all. 3290 */ 3291 if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) { 3292 if (pkgSetting.nativeLibraryPathString == null) { 3293 final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath(); 3294 pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath; 3295 pkgSetting.nativeLibraryPathString = nativeLibraryPath; 3296 } else { 3297 pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString; 3298 } 3299 } 3300 3301 pkgSetting.uidError = uidError; 3302 } 3303 3304 // If we're running in the simulator, we don't need to unpack anything. 3305 if (mInstaller != null) { 3306 String path = scanFile.getPath(); 3307 /* Note: We don't want to unpack the native binaries for 3308 * system applications, unless they have been updated 3309 * (the binaries are already under /system/lib). 3310 * Also, don't unpack libs for apps on the external card 3311 * since they should have their libraries in the ASEC 3312 * container already. 3313 * 3314 * In other words, we're going to unpack the binaries 3315 * only for non-system apps and system app upgrades. 3316 */ 3317 if (pkg.applicationInfo.nativeLibraryDir != null) { 3318 final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); 3319 final String dataPathString = dataPath.getPath(); 3320 3321 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { 3322 /* 3323 * Upgrading from a previous version of the OS sometimes 3324 * leaves native libraries in the /data/data/<app>/lib 3325 * directory for system apps even when they shouldn't be. 3326 * Recent changes in the JNI library search path 3327 * necessitates we remove those to match previous behavior. 3328 */ 3329 if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) { 3330 Log.i(TAG, "removed obsolete native libraries for system package " + path); 3331 } 3332 } else if (nativeLibraryDir.getParent().equals(dataPathString)) { 3333 /* 3334 * If this is an internal application or our 3335 * nativeLibraryPath points to our data directory, unpack 3336 * the libraries. The native library path pointing to the 3337 * data directory for an application in an ASEC container 3338 * can happen for older apps that existed before an OTA to 3339 * Gingerbread. 3340 */ 3341 Slog.i(TAG, "Unpacking native libraries for " + path); 3342 mInstaller.unlinkNativeLibraryDirectory(dataPathString); 3343 NativeLibraryHelper.copyNativeBinariesLI(scanFile, nativeLibraryDir); 3344 } else { 3345 Slog.i(TAG, "Linking native library dir for " + path); 3346 mInstaller.linkNativeLibraryDirectory(dataPathString, 3347 pkg.applicationInfo.nativeLibraryDir); 3348 } 3349 } 3350 pkg.mScanPath = path; 3351 3352 if ((scanMode&SCAN_NO_DEX) == 0) { 3353 if (performDexOptLI(pkg, forceDex) == DEX_OPT_FAILED) { 3354 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; 3355 return null; 3356 } 3357 } 3358 } 3359 3360 if (mFactoryTest && pkg.requestedPermissions.contains( 3361 android.Manifest.permission.FACTORY_TEST)) { 3362 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 3363 } 3364 3365 // Request the ActivityManager to kill the process(only for existing packages) 3366 // so that we do not end up in a confused state while the user is still using the older 3367 // version of the application while the new one gets installed. 3368 if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 3369 killApplication(pkg.applicationInfo.packageName, 3370 pkg.applicationInfo.uid); 3371 } 3372 3373 synchronized (mPackages) { 3374 // We don't expect installation to fail beyond this point, 3375 if ((scanMode&SCAN_MONITOR) != 0) { 3376 mAppDirs.put(pkg.mPath, pkg); 3377 } 3378 // Add the new setting to mSettings 3379 mSettings.insertPackageSettingLP(pkgSetting, pkg); 3380 // Add the new setting to mPackages 3381 mPackages.put(pkg.applicationInfo.packageName, pkg); 3382 // Make sure we don't accidentally delete its data. 3383 mSettings.mPackagesToBeCleaned.remove(pkgName); 3384 3385 // Take care of first install / last update times. 3386 if (currentTime != 0) { 3387 if (pkgSetting.firstInstallTime == 0) { 3388 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 3389 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) { 3390 pkgSetting.lastUpdateTime = currentTime; 3391 } 3392 } else if (pkgSetting.firstInstallTime == 0) { 3393 // We need *something*. Take time time stamp of the file. 3394 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 3395 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 3396 if (scanFileTime != pkgSetting.timeStamp) { 3397 // A package on the system image has changed; consider this 3398 // to be an update. 3399 pkgSetting.lastUpdateTime = scanFileTime; 3400 } 3401 } 3402 3403 int N = pkg.providers.size(); 3404 StringBuilder r = null; 3405 int i; 3406 for (i=0; i<N; i++) { 3407 PackageParser.Provider p = pkg.providers.get(i); 3408 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 3409 p.info.processName, pkg.applicationInfo.uid); 3410 mProvidersByComponent.put(new ComponentName(p.info.packageName, 3411 p.info.name), p); 3412 p.syncable = p.info.isSyncable; 3413 if (p.info.authority != null) { 3414 String names[] = p.info.authority.split(";"); 3415 p.info.authority = null; 3416 for (int j = 0; j < names.length; j++) { 3417 if (j == 1 && p.syncable) { 3418 // We only want the first authority for a provider to possibly be 3419 // syncable, so if we already added this provider using a different 3420 // authority clear the syncable flag. We copy the provider before 3421 // changing it because the mProviders object contains a reference 3422 // to a provider that we don't want to change. 3423 // Only do this for the second authority since the resulting provider 3424 // object can be the same for all future authorities for this provider. 3425 p = new PackageParser.Provider(p); 3426 p.syncable = false; 3427 } 3428 if (!mProviders.containsKey(names[j])) { 3429 mProviders.put(names[j], p); 3430 if (p.info.authority == null) { 3431 p.info.authority = names[j]; 3432 } else { 3433 p.info.authority = p.info.authority + ";" + names[j]; 3434 } 3435 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0 && Config.LOGD) 3436 Log.d(TAG, "Registered content provider: " + names[j] + 3437 ", className = " + p.info.name + 3438 ", isSyncable = " + p.info.isSyncable); 3439 } else { 3440 PackageParser.Provider other = mProviders.get(names[j]); 3441 Slog.w(TAG, "Skipping provider name " + names[j] + 3442 " (in package " + pkg.applicationInfo.packageName + 3443 "): name already used by " 3444 + ((other != null && other.getComponentName() != null) 3445 ? other.getComponentName().getPackageName() : "?")); 3446 } 3447 } 3448 } 3449 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3450 if (r == null) { 3451 r = new StringBuilder(256); 3452 } else { 3453 r.append(' '); 3454 } 3455 r.append(p.info.name); 3456 } 3457 } 3458 if (r != null) { 3459 if (Config.LOGD) Log.d(TAG, " Providers: " + r); 3460 } 3461 3462 N = pkg.services.size(); 3463 r = null; 3464 for (i=0; i<N; i++) { 3465 PackageParser.Service s = pkg.services.get(i); 3466 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 3467 s.info.processName, pkg.applicationInfo.uid); 3468 mServices.addService(s); 3469 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3470 if (r == null) { 3471 r = new StringBuilder(256); 3472 } else { 3473 r.append(' '); 3474 } 3475 r.append(s.info.name); 3476 } 3477 } 3478 if (r != null) { 3479 if (Config.LOGD) Log.d(TAG, " Services: " + r); 3480 } 3481 3482 N = pkg.receivers.size(); 3483 r = null; 3484 for (i=0; i<N; i++) { 3485 PackageParser.Activity a = pkg.receivers.get(i); 3486 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 3487 a.info.processName, pkg.applicationInfo.uid); 3488 mReceivers.addActivity(a, "receiver"); 3489 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3490 if (r == null) { 3491 r = new StringBuilder(256); 3492 } else { 3493 r.append(' '); 3494 } 3495 r.append(a.info.name); 3496 } 3497 } 3498 if (r != null) { 3499 if (Config.LOGD) Log.d(TAG, " Receivers: " + r); 3500 } 3501 3502 N = pkg.activities.size(); 3503 r = null; 3504 for (i=0; i<N; i++) { 3505 PackageParser.Activity a = pkg.activities.get(i); 3506 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 3507 a.info.processName, pkg.applicationInfo.uid); 3508 mActivities.addActivity(a, "activity"); 3509 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3510 if (r == null) { 3511 r = new StringBuilder(256); 3512 } else { 3513 r.append(' '); 3514 } 3515 r.append(a.info.name); 3516 } 3517 } 3518 if (r != null) { 3519 if (Config.LOGD) Log.d(TAG, " Activities: " + r); 3520 } 3521 3522 N = pkg.permissionGroups.size(); 3523 r = null; 3524 for (i=0; i<N; i++) { 3525 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 3526 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 3527 if (cur == null) { 3528 mPermissionGroups.put(pg.info.name, pg); 3529 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3530 if (r == null) { 3531 r = new StringBuilder(256); 3532 } else { 3533 r.append(' '); 3534 } 3535 r.append(pg.info.name); 3536 } 3537 } else { 3538 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 3539 + pg.info.packageName + " ignored: original from " 3540 + cur.info.packageName); 3541 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3542 if (r == null) { 3543 r = new StringBuilder(256); 3544 } else { 3545 r.append(' '); 3546 } 3547 r.append("DUP:"); 3548 r.append(pg.info.name); 3549 } 3550 } 3551 } 3552 if (r != null) { 3553 if (Config.LOGD) Log.d(TAG, " Permission Groups: " + r); 3554 } 3555 3556 N = pkg.permissions.size(); 3557 r = null; 3558 for (i=0; i<N; i++) { 3559 PackageParser.Permission p = pkg.permissions.get(i); 3560 HashMap<String, BasePermission> permissionMap = 3561 p.tree ? mSettings.mPermissionTrees 3562 : mSettings.mPermissions; 3563 p.group = mPermissionGroups.get(p.info.group); 3564 if (p.info.group == null || p.group != null) { 3565 BasePermission bp = permissionMap.get(p.info.name); 3566 if (bp == null) { 3567 bp = new BasePermission(p.info.name, p.info.packageName, 3568 BasePermission.TYPE_NORMAL); 3569 permissionMap.put(p.info.name, bp); 3570 } 3571 if (bp.perm == null) { 3572 if (bp.sourcePackage == null 3573 || bp.sourcePackage.equals(p.info.packageName)) { 3574 BasePermission tree = findPermissionTreeLP(p.info.name); 3575 if (tree == null 3576 || tree.sourcePackage.equals(p.info.packageName)) { 3577 bp.packageSetting = pkgSetting; 3578 bp.perm = p; 3579 bp.uid = pkg.applicationInfo.uid; 3580 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3581 if (r == null) { 3582 r = new StringBuilder(256); 3583 } else { 3584 r.append(' '); 3585 } 3586 r.append(p.info.name); 3587 } 3588 } else { 3589 Slog.w(TAG, "Permission " + p.info.name + " from package " 3590 + p.info.packageName + " ignored: base tree " 3591 + tree.name + " is from package " 3592 + tree.sourcePackage); 3593 } 3594 } else { 3595 Slog.w(TAG, "Permission " + p.info.name + " from package " 3596 + p.info.packageName + " ignored: original from " 3597 + bp.sourcePackage); 3598 } 3599 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3600 if (r == null) { 3601 r = new StringBuilder(256); 3602 } else { 3603 r.append(' '); 3604 } 3605 r.append("DUP:"); 3606 r.append(p.info.name); 3607 } 3608 if (bp.perm == p) { 3609 bp.protectionLevel = p.info.protectionLevel; 3610 } 3611 } else { 3612 Slog.w(TAG, "Permission " + p.info.name + " from package " 3613 + p.info.packageName + " ignored: no group " 3614 + p.group); 3615 } 3616 } 3617 if (r != null) { 3618 if (Config.LOGD) Log.d(TAG, " Permissions: " + r); 3619 } 3620 3621 N = pkg.instrumentation.size(); 3622 r = null; 3623 for (i=0; i<N; i++) { 3624 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 3625 a.info.packageName = pkg.applicationInfo.packageName; 3626 a.info.sourceDir = pkg.applicationInfo.sourceDir; 3627 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 3628 a.info.dataDir = pkg.applicationInfo.dataDir; 3629 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 3630 mInstrumentation.put(a.getComponentName(), a); 3631 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3632 if (r == null) { 3633 r = new StringBuilder(256); 3634 } else { 3635 r.append(' '); 3636 } 3637 r.append(a.info.name); 3638 } 3639 } 3640 if (r != null) { 3641 if (Config.LOGD) Log.d(TAG, " Instrumentation: " + r); 3642 } 3643 3644 if (pkg.protectedBroadcasts != null) { 3645 N = pkg.protectedBroadcasts.size(); 3646 for (i=0; i<N; i++) { 3647 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 3648 } 3649 } 3650 3651 pkgSetting.setTimeStamp(scanFileTime); 3652 } 3653 3654 return pkg; 3655 } 3656 3657 private void killApplication(String pkgName, int uid) { 3658 // Request the ActivityManager to kill the process(only for existing packages) 3659 // so that we do not end up in a confused state while the user is still using the older 3660 // version of the application while the new one gets installed. 3661 IActivityManager am = ActivityManagerNative.getDefault(); 3662 if (am != null) { 3663 try { 3664 am.killApplicationWithUid(pkgName, uid); 3665 } catch (RemoteException e) { 3666 } 3667 } 3668 } 3669 3670 // Return the path of the directory that will contain the native binaries 3671 // of a given installed package. This is relative to the data path. 3672 // 3673 private File getNativeBinaryDirForPackage(PackageParser.Package pkg) { 3674 final String nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 3675 if (nativeLibraryDir != null) { 3676 return new File(nativeLibraryDir); 3677 } else { 3678 // Fall back for old packages 3679 return new File(pkg.applicationInfo.dataDir, LIB_DIR_NAME); 3680 } 3681 } 3682 3683 void removePackageLI(PackageParser.Package pkg, boolean chatty) { 3684 if (chatty && Config.LOGD) Log.d( 3685 TAG, "Removing package " + pkg.applicationInfo.packageName ); 3686 3687 synchronized (mPackages) { 3688 clearPackagePreferredActivitiesLP(pkg.packageName); 3689 3690 mPackages.remove(pkg.applicationInfo.packageName); 3691 if (pkg.mPath != null) { 3692 mAppDirs.remove(pkg.mPath); 3693 } 3694 3695 int N = pkg.providers.size(); 3696 StringBuilder r = null; 3697 int i; 3698 for (i=0; i<N; i++) { 3699 PackageParser.Provider p = pkg.providers.get(i); 3700 mProvidersByComponent.remove(new ComponentName(p.info.packageName, 3701 p.info.name)); 3702 if (p.info.authority == null) { 3703 3704 /* The is another ContentProvider with this authority when 3705 * this app was installed so this authority is null, 3706 * Ignore it as we don't have to unregister the provider. 3707 */ 3708 continue; 3709 } 3710 String names[] = p.info.authority.split(";"); 3711 for (int j = 0; j < names.length; j++) { 3712 if (mProviders.get(names[j]) == p) { 3713 mProviders.remove(names[j]); 3714 if (chatty && Config.LOGD) Log.d( 3715 TAG, "Unregistered content provider: " + names[j] + 3716 ", className = " + p.info.name + 3717 ", isSyncable = " + p.info.isSyncable); 3718 } 3719 } 3720 if (chatty) { 3721 if (r == null) { 3722 r = new StringBuilder(256); 3723 } else { 3724 r.append(' '); 3725 } 3726 r.append(p.info.name); 3727 } 3728 } 3729 if (r != null) { 3730 if (Config.LOGD) Log.d(TAG, " Providers: " + r); 3731 } 3732 3733 N = pkg.services.size(); 3734 r = null; 3735 for (i=0; i<N; i++) { 3736 PackageParser.Service s = pkg.services.get(i); 3737 mServices.removeService(s); 3738 if (chatty) { 3739 if (r == null) { 3740 r = new StringBuilder(256); 3741 } else { 3742 r.append(' '); 3743 } 3744 r.append(s.info.name); 3745 } 3746 } 3747 if (r != null) { 3748 if (Config.LOGD) Log.d(TAG, " Services: " + r); 3749 } 3750 3751 N = pkg.receivers.size(); 3752 r = null; 3753 for (i=0; i<N; i++) { 3754 PackageParser.Activity a = pkg.receivers.get(i); 3755 mReceivers.removeActivity(a, "receiver"); 3756 if (chatty) { 3757 if (r == null) { 3758 r = new StringBuilder(256); 3759 } else { 3760 r.append(' '); 3761 } 3762 r.append(a.info.name); 3763 } 3764 } 3765 if (r != null) { 3766 if (Config.LOGD) Log.d(TAG, " Receivers: " + r); 3767 } 3768 3769 N = pkg.activities.size(); 3770 r = null; 3771 for (i=0; i<N; i++) { 3772 PackageParser.Activity a = pkg.activities.get(i); 3773 mActivities.removeActivity(a, "activity"); 3774 if (chatty) { 3775 if (r == null) { 3776 r = new StringBuilder(256); 3777 } else { 3778 r.append(' '); 3779 } 3780 r.append(a.info.name); 3781 } 3782 } 3783 if (r != null) { 3784 if (Config.LOGD) Log.d(TAG, " Activities: " + r); 3785 } 3786 3787 N = pkg.permissions.size(); 3788 r = null; 3789 for (i=0; i<N; i++) { 3790 PackageParser.Permission p = pkg.permissions.get(i); 3791 boolean tree = false; 3792 BasePermission bp = mSettings.mPermissions.get(p.info.name); 3793 if (bp == null) { 3794 tree = true; 3795 bp = mSettings.mPermissionTrees.get(p.info.name); 3796 } 3797 if (bp != null && bp.perm == p) { 3798 bp.perm = null; 3799 if (chatty) { 3800 if (r == null) { 3801 r = new StringBuilder(256); 3802 } else { 3803 r.append(' '); 3804 } 3805 r.append(p.info.name); 3806 } 3807 } 3808 } 3809 if (r != null) { 3810 if (Config.LOGD) Log.d(TAG, " Permissions: " + r); 3811 } 3812 3813 N = pkg.instrumentation.size(); 3814 r = null; 3815 for (i=0; i<N; i++) { 3816 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 3817 mInstrumentation.remove(a.getComponentName()); 3818 if (chatty) { 3819 if (r == null) { 3820 r = new StringBuilder(256); 3821 } else { 3822 r.append(' '); 3823 } 3824 r.append(a.info.name); 3825 } 3826 } 3827 if (r != null) { 3828 if (Config.LOGD) Log.d(TAG, " Instrumentation: " + r); 3829 } 3830 } 3831 } 3832 3833 private static final boolean isPackageFilename(String name) { 3834 return name != null && name.endsWith(".apk"); 3835 } 3836 3837 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 3838 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 3839 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 3840 return true; 3841 } 3842 } 3843 return false; 3844 } 3845 3846 private void updatePermissionsLP(String changingPkg, 3847 PackageParser.Package pkgInfo, boolean grantPermissions, 3848 boolean replace, boolean replaceAll) { 3849 // Make sure there are no dangling permission trees. 3850 Iterator<BasePermission> it = mSettings.mPermissionTrees 3851 .values().iterator(); 3852 while (it.hasNext()) { 3853 BasePermission bp = it.next(); 3854 if (bp.packageSetting == null) { 3855 // We may not yet have parsed the package, so just see if 3856 // we still know about its settings. 3857 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 3858 } 3859 if (bp.packageSetting == null) { 3860 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 3861 + " from package " + bp.sourcePackage); 3862 it.remove(); 3863 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 3864 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 3865 Slog.i(TAG, "Removing old permission tree: " + bp.name 3866 + " from package " + bp.sourcePackage); 3867 grantPermissions = true; 3868 it.remove(); 3869 } 3870 } 3871 } 3872 3873 // Make sure all dynamic permissions have been assigned to a package, 3874 // and make sure there are no dangling permissions. 3875 it = mSettings.mPermissions.values().iterator(); 3876 while (it.hasNext()) { 3877 BasePermission bp = it.next(); 3878 if (bp.type == BasePermission.TYPE_DYNAMIC) { 3879 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 3880 + bp.name + " pkg=" + bp.sourcePackage 3881 + " info=" + bp.pendingInfo); 3882 if (bp.packageSetting == null && bp.pendingInfo != null) { 3883 BasePermission tree = findPermissionTreeLP(bp.name); 3884 if (tree != null) { 3885 bp.packageSetting = tree.packageSetting; 3886 bp.perm = new PackageParser.Permission(tree.perm.owner, 3887 new PermissionInfo(bp.pendingInfo)); 3888 bp.perm.info.packageName = tree.perm.info.packageName; 3889 bp.perm.info.name = bp.name; 3890 bp.uid = tree.uid; 3891 } 3892 } 3893 } 3894 if (bp.packageSetting == null) { 3895 // We may not yet have parsed the package, so just see if 3896 // we still know about its settings. 3897 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 3898 } 3899 if (bp.packageSetting == null) { 3900 Slog.w(TAG, "Removing dangling permission: " + bp.name 3901 + " from package " + bp.sourcePackage); 3902 it.remove(); 3903 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 3904 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 3905 Slog.i(TAG, "Removing old permission: " + bp.name 3906 + " from package " + bp.sourcePackage); 3907 grantPermissions = true; 3908 it.remove(); 3909 } 3910 } 3911 } 3912 3913 // Now update the permissions for all packages, in particular 3914 // replace the granted permissions of the system packages. 3915 if (grantPermissions) { 3916 for (PackageParser.Package pkg : mPackages.values()) { 3917 if (pkg != pkgInfo) { 3918 grantPermissionsLP(pkg, replaceAll); 3919 } 3920 } 3921 } 3922 3923 if (pkgInfo != null) { 3924 grantPermissionsLP(pkgInfo, replace); 3925 } 3926 } 3927 3928 private void grantPermissionsLP(PackageParser.Package pkg, boolean replace) { 3929 final PackageSetting ps = (PackageSetting)pkg.mExtras; 3930 if (ps == null) { 3931 return; 3932 } 3933 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 3934 boolean changedPermission = false; 3935 3936 if (replace) { 3937 ps.permissionsFixed = false; 3938 if (gp == ps) { 3939 gp.grantedPermissions.clear(); 3940 gp.gids = mGlobalGids; 3941 } 3942 } 3943 3944 if (gp.gids == null) { 3945 gp.gids = mGlobalGids; 3946 } 3947 3948 final int N = pkg.requestedPermissions.size(); 3949 for (int i=0; i<N; i++) { 3950 String name = pkg.requestedPermissions.get(i); 3951 BasePermission bp = mSettings.mPermissions.get(name); 3952 if (false) { 3953 if (gp != ps) { 3954 Log.i(TAG, "Package " + pkg.packageName + " checking " + name 3955 + ": " + bp); 3956 } 3957 } 3958 if (bp != null && bp.packageSetting != null) { 3959 final String perm = bp.name; 3960 boolean allowed; 3961 boolean allowedSig = false; 3962 if (bp.protectionLevel == PermissionInfo.PROTECTION_NORMAL 3963 || bp.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) { 3964 allowed = true; 3965 } else if (bp.packageSetting == null) { 3966 // This permission is invalid; skip it. 3967 allowed = false; 3968 } else if (bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE 3969 || bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) { 3970 allowed = (checkSignaturesLP( 3971 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 3972 == PackageManager.SIGNATURE_MATCH) 3973 || (checkSignaturesLP(mPlatformPackage.mSignatures, pkg.mSignatures) 3974 == PackageManager.SIGNATURE_MATCH); 3975 if (!allowed && bp.protectionLevel 3976 == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) { 3977 if (isSystemApp(pkg)) { 3978 // For updated system applications, the signatureOrSystem permission 3979 // is granted only if it had been defined by the original application. 3980 if (isUpdatedSystemApp(pkg)) { 3981 PackageSetting sysPs = mSettings.getDisabledSystemPkg( 3982 pkg.packageName); 3983 final GrantedPermissions origGp = sysPs.sharedUser != null 3984 ? sysPs.sharedUser : sysPs; 3985 if (origGp.grantedPermissions.contains(perm)) { 3986 allowed = true; 3987 } else { 3988 allowed = false; 3989 } 3990 } else { 3991 allowed = true; 3992 } 3993 } 3994 } 3995 if (allowed) { 3996 allowedSig = true; 3997 } 3998 } else { 3999 allowed = false; 4000 } 4001 if (false) { 4002 if (gp != ps) { 4003 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 4004 } 4005 } 4006 if (allowed) { 4007 if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 4008 && ps.permissionsFixed) { 4009 // If this is an existing, non-system package, then 4010 // we can't add any new permissions to it. 4011 if (!allowedSig && !gp.grantedPermissions.contains(perm)) { 4012 allowed = false; 4013 // Except... if this is a permission that was added 4014 // to the platform (note: need to only do this when 4015 // updating the platform). 4016 final int NP = PackageParser.NEW_PERMISSIONS.length; 4017 for (int ip=0; ip<NP; ip++) { 4018 final PackageParser.NewPermissionInfo npi 4019 = PackageParser.NEW_PERMISSIONS[ip]; 4020 if (npi.name.equals(perm) 4021 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 4022 allowed = true; 4023 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 4024 + pkg.packageName); 4025 break; 4026 } 4027 } 4028 } 4029 } 4030 if (allowed) { 4031 if (!gp.grantedPermissions.contains(perm)) { 4032 changedPermission = true; 4033 gp.grantedPermissions.add(perm); 4034 gp.gids = appendInts(gp.gids, bp.gids); 4035 } else if (!ps.haveGids) { 4036 gp.gids = appendInts(gp.gids, bp.gids); 4037 } 4038 } else { 4039 Slog.w(TAG, "Not granting permission " + perm 4040 + " to package " + pkg.packageName 4041 + " because it was previously installed without"); 4042 } 4043 } else { 4044 if (gp.grantedPermissions.remove(perm)) { 4045 changedPermission = true; 4046 gp.gids = removeInts(gp.gids, bp.gids); 4047 Slog.i(TAG, "Un-granting permission " + perm 4048 + " from package " + pkg.packageName 4049 + " (protectionLevel=" + bp.protectionLevel 4050 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 4051 + ")"); 4052 } else { 4053 Slog.w(TAG, "Not granting permission " + perm 4054 + " to package " + pkg.packageName 4055 + " (protectionLevel=" + bp.protectionLevel 4056 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 4057 + ")"); 4058 } 4059 } 4060 } else { 4061 Slog.w(TAG, "Unknown permission " + name 4062 + " in package " + pkg.packageName); 4063 } 4064 } 4065 4066 if ((changedPermission || replace) && !ps.permissionsFixed && 4067 ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) || 4068 ((ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)){ 4069 // This is the first that we have heard about this package, so the 4070 // permissions we have now selected are fixed until explicitly 4071 // changed. 4072 ps.permissionsFixed = true; 4073 } 4074 ps.haveGids = true; 4075 } 4076 4077 private final class ActivityIntentResolver 4078 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 4079 public List queryIntent(Intent intent, String resolvedType, boolean defaultOnly) { 4080 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 4081 return super.queryIntent(intent, resolvedType, defaultOnly); 4082 } 4083 4084 public List queryIntent(Intent intent, String resolvedType, int flags) { 4085 mFlags = flags; 4086 return super.queryIntent(intent, resolvedType, 4087 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); 4088 } 4089 4090 public List queryIntentForPackage(Intent intent, String resolvedType, int flags, 4091 ArrayList<PackageParser.Activity> packageActivities) { 4092 if (packageActivities == null) { 4093 return null; 4094 } 4095 mFlags = flags; 4096 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 4097 int N = packageActivities.size(); 4098 ArrayList<ArrayList<PackageParser.ActivityIntentInfo>> listCut = 4099 new ArrayList<ArrayList<PackageParser.ActivityIntentInfo>>(N); 4100 4101 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 4102 for (int i = 0; i < N; ++i) { 4103 intentFilters = packageActivities.get(i).intents; 4104 if (intentFilters != null && intentFilters.size() > 0) { 4105 listCut.add(intentFilters); 4106 } 4107 } 4108 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut); 4109 } 4110 4111 public final void addActivity(PackageParser.Activity a, String type) { 4112 final boolean systemApp = isSystemApp(a.info.applicationInfo); 4113 mActivities.put(a.getComponentName(), a); 4114 if (SHOW_INFO || Config.LOGV) Log.v( 4115 TAG, " " + type + " " + 4116 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 4117 if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name); 4118 int NI = a.intents.size(); 4119 for (int j=0; j<NI; j++) { 4120 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 4121 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 4122 intent.setPriority(0); 4123 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 4124 + a.className + " with priority > 0, forcing to 0"); 4125 } 4126 if (SHOW_INFO || Config.LOGV) { 4127 Log.v(TAG, " IntentFilter:"); 4128 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 4129 } 4130 if (!intent.debugCheck()) { 4131 Log.w(TAG, "==> For Activity " + a.info.name); 4132 } 4133 addFilter(intent); 4134 } 4135 } 4136 4137 public final void removeActivity(PackageParser.Activity a, String type) { 4138 mActivities.remove(a.getComponentName()); 4139 if (SHOW_INFO || Config.LOGV) Log.v( 4140 TAG, " " + type + " " + 4141 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 4142 if (SHOW_INFO || Config.LOGV) Log.v(TAG, " Class=" + a.info.name); 4143 int NI = a.intents.size(); 4144 for (int j=0; j<NI; j++) { 4145 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 4146 if (SHOW_INFO || Config.LOGV) { 4147 Log.v(TAG, " IntentFilter:"); 4148 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 4149 } 4150 removeFilter(intent); 4151 } 4152 } 4153 4154 @Override 4155 protected boolean allowFilterResult( 4156 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 4157 ActivityInfo filterAi = filter.activity.info; 4158 for (int i=dest.size()-1; i>=0; i--) { 4159 ActivityInfo destAi = dest.get(i).activityInfo; 4160 if (destAi.name == filterAi.name 4161 && destAi.packageName == filterAi.packageName) { 4162 return false; 4163 } 4164 } 4165 return true; 4166 } 4167 4168 @Override 4169 protected String packageForFilter(PackageParser.ActivityIntentInfo info) { 4170 return info.activity.owner.packageName; 4171 } 4172 4173 @Override 4174 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 4175 int match) { 4176 if (!mSettings.isEnabledLP(info.activity.info, mFlags)) { 4177 return null; 4178 } 4179 final PackageParser.Activity activity = info.activity; 4180 if (mSafeMode && (activity.info.applicationInfo.flags 4181 &ApplicationInfo.FLAG_SYSTEM) == 0) { 4182 return null; 4183 } 4184 final ResolveInfo res = new ResolveInfo(); 4185 res.activityInfo = PackageParser.generateActivityInfo(activity, 4186 mFlags); 4187 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 4188 res.filter = info; 4189 } 4190 res.priority = info.getPriority(); 4191 res.preferredOrder = activity.owner.mPreferredOrder; 4192 //System.out.println("Result: " + res.activityInfo.className + 4193 // " = " + res.priority); 4194 res.match = match; 4195 res.isDefault = info.hasDefault; 4196 res.labelRes = info.labelRes; 4197 res.nonLocalizedLabel = info.nonLocalizedLabel; 4198 res.icon = info.icon; 4199 return res; 4200 } 4201 4202 @Override 4203 protected void sortResults(List<ResolveInfo> results) { 4204 Collections.sort(results, mResolvePrioritySorter); 4205 } 4206 4207 @Override 4208 protected void dumpFilter(PrintWriter out, String prefix, 4209 PackageParser.ActivityIntentInfo filter) { 4210 out.print(prefix); out.print( 4211 Integer.toHexString(System.identityHashCode(filter.activity))); 4212 out.print(' '); 4213 out.print(filter.activity.getComponentShortName()); 4214 out.print(" filter "); 4215 out.println(Integer.toHexString(System.identityHashCode(filter))); 4216 } 4217 4218 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 4219 // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 4220 // final List<ResolveInfo> retList = Lists.newArrayList(); 4221 // while (i.hasNext()) { 4222 // final ResolveInfo resolveInfo = i.next(); 4223 // if (isEnabledLP(resolveInfo.activityInfo)) { 4224 // retList.add(resolveInfo); 4225 // } 4226 // } 4227 // return retList; 4228 // } 4229 4230 // Keys are String (activity class name), values are Activity. 4231 private final HashMap<ComponentName, PackageParser.Activity> mActivities 4232 = new HashMap<ComponentName, PackageParser.Activity>(); 4233 private int mFlags; 4234 } 4235 4236 private final class ServiceIntentResolver 4237 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 4238 public List queryIntent(Intent intent, String resolvedType, boolean defaultOnly) { 4239 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 4240 return super.queryIntent(intent, resolvedType, defaultOnly); 4241 } 4242 4243 public List queryIntent(Intent intent, String resolvedType, int flags) { 4244 mFlags = flags; 4245 return super.queryIntent(intent, resolvedType, 4246 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); 4247 } 4248 4249 public List queryIntentForPackage(Intent intent, String resolvedType, int flags, 4250 ArrayList<PackageParser.Service> packageServices) { 4251 if (packageServices == null) { 4252 return null; 4253 } 4254 mFlags = flags; 4255 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 4256 int N = packageServices.size(); 4257 ArrayList<ArrayList<PackageParser.ServiceIntentInfo>> listCut = 4258 new ArrayList<ArrayList<PackageParser.ServiceIntentInfo>>(N); 4259 4260 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 4261 for (int i = 0; i < N; ++i) { 4262 intentFilters = packageServices.get(i).intents; 4263 if (intentFilters != null && intentFilters.size() > 0) { 4264 listCut.add(intentFilters); 4265 } 4266 } 4267 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut); 4268 } 4269 4270 public final void addService(PackageParser.Service s) { 4271 mServices.put(s.getComponentName(), s); 4272 if (SHOW_INFO || Config.LOGV) Log.v( 4273 TAG, " " + (s.info.nonLocalizedLabel != null 4274 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 4275 if (SHOW_INFO || Config.LOGV) Log.v( 4276 TAG, " Class=" + s.info.name); 4277 int NI = s.intents.size(); 4278 int j; 4279 for (j=0; j<NI; j++) { 4280 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 4281 if (SHOW_INFO || Config.LOGV) { 4282 Log.v(TAG, " IntentFilter:"); 4283 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 4284 } 4285 if (!intent.debugCheck()) { 4286 Log.w(TAG, "==> For Service " + s.info.name); 4287 } 4288 addFilter(intent); 4289 } 4290 } 4291 4292 public final void removeService(PackageParser.Service s) { 4293 mServices.remove(s.getComponentName()); 4294 if (SHOW_INFO || Config.LOGV) Log.v( 4295 TAG, " " + (s.info.nonLocalizedLabel != null 4296 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 4297 if (SHOW_INFO || Config.LOGV) Log.v( 4298 TAG, " Class=" + s.info.name); 4299 int NI = s.intents.size(); 4300 int j; 4301 for (j=0; j<NI; j++) { 4302 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 4303 if (SHOW_INFO || Config.LOGV) { 4304 Log.v(TAG, " IntentFilter:"); 4305 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 4306 } 4307 removeFilter(intent); 4308 } 4309 } 4310 4311 @Override 4312 protected boolean allowFilterResult( 4313 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 4314 ServiceInfo filterSi = filter.service.info; 4315 for (int i=dest.size()-1; i>=0; i--) { 4316 ServiceInfo destAi = dest.get(i).serviceInfo; 4317 if (destAi.name == filterSi.name 4318 && destAi.packageName == filterSi.packageName) { 4319 return false; 4320 } 4321 } 4322 return true; 4323 } 4324 4325 @Override 4326 protected String packageForFilter(PackageParser.ServiceIntentInfo info) { 4327 return info.service.owner.packageName; 4328 } 4329 4330 @Override 4331 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 4332 int match) { 4333 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 4334 if (!mSettings.isEnabledLP(info.service.info, mFlags)) { 4335 return null; 4336 } 4337 final PackageParser.Service service = info.service; 4338 if (mSafeMode && (service.info.applicationInfo.flags 4339 &ApplicationInfo.FLAG_SYSTEM) == 0) { 4340 return null; 4341 } 4342 final ResolveInfo res = new ResolveInfo(); 4343 res.serviceInfo = PackageParser.generateServiceInfo(service, 4344 mFlags); 4345 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 4346 res.filter = filter; 4347 } 4348 res.priority = info.getPriority(); 4349 res.preferredOrder = service.owner.mPreferredOrder; 4350 //System.out.println("Result: " + res.activityInfo.className + 4351 // " = " + res.priority); 4352 res.match = match; 4353 res.isDefault = info.hasDefault; 4354 res.labelRes = info.labelRes; 4355 res.nonLocalizedLabel = info.nonLocalizedLabel; 4356 res.icon = info.icon; 4357 return res; 4358 } 4359 4360 @Override 4361 protected void sortResults(List<ResolveInfo> results) { 4362 Collections.sort(results, mResolvePrioritySorter); 4363 } 4364 4365 @Override 4366 protected void dumpFilter(PrintWriter out, String prefix, 4367 PackageParser.ServiceIntentInfo filter) { 4368 out.print(prefix); out.print( 4369 Integer.toHexString(System.identityHashCode(filter.service))); 4370 out.print(' '); 4371 out.print(filter.service.getComponentShortName()); 4372 out.print(" filter "); 4373 out.println(Integer.toHexString(System.identityHashCode(filter))); 4374 } 4375 4376 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 4377 // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 4378 // final List<ResolveInfo> retList = Lists.newArrayList(); 4379 // while (i.hasNext()) { 4380 // final ResolveInfo resolveInfo = (ResolveInfo) i; 4381 // if (isEnabledLP(resolveInfo.serviceInfo)) { 4382 // retList.add(resolveInfo); 4383 // } 4384 // } 4385 // return retList; 4386 // } 4387 4388 // Keys are String (activity class name), values are Activity. 4389 private final HashMap<ComponentName, PackageParser.Service> mServices 4390 = new HashMap<ComponentName, PackageParser.Service>(); 4391 private int mFlags; 4392 }; 4393 4394 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 4395 new Comparator<ResolveInfo>() { 4396 public int compare(ResolveInfo r1, ResolveInfo r2) { 4397 int v1 = r1.priority; 4398 int v2 = r2.priority; 4399 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 4400 if (v1 != v2) { 4401 return (v1 > v2) ? -1 : 1; 4402 } 4403 v1 = r1.preferredOrder; 4404 v2 = r2.preferredOrder; 4405 if (v1 != v2) { 4406 return (v1 > v2) ? -1 : 1; 4407 } 4408 if (r1.isDefault != r2.isDefault) { 4409 return r1.isDefault ? -1 : 1; 4410 } 4411 v1 = r1.match; 4412 v2 = r2.match; 4413 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 4414 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 4415 } 4416 }; 4417 4418 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 4419 new Comparator<ProviderInfo>() { 4420 public int compare(ProviderInfo p1, ProviderInfo p2) { 4421 final int v1 = p1.initOrder; 4422 final int v2 = p2.initOrder; 4423 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 4424 } 4425 }; 4426 4427 private static final void sendPackageBroadcast(String action, String pkg, 4428 Bundle extras, IIntentReceiver finishedReceiver) { 4429 IActivityManager am = ActivityManagerNative.getDefault(); 4430 if (am != null) { 4431 try { 4432 final Intent intent = new Intent(action, 4433 pkg != null ? Uri.fromParts("package", pkg, null) : null); 4434 if (extras != null) { 4435 intent.putExtras(extras); 4436 } 4437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4438 am.broadcastIntent(null, intent, null, finishedReceiver, 4439 0, null, null, null, finishedReceiver != null, false); 4440 } catch (RemoteException ex) { 4441 } 4442 } 4443 } 4444 4445 public String nextPackageToClean(String lastPackage) { 4446 synchronized (mPackages) { 4447 if (!mMediaMounted) { 4448 // If the external storage is no longer mounted at this point, 4449 // the caller may not have been able to delete all of this 4450 // packages files and can not delete any more. Bail. 4451 return null; 4452 } 4453 if (lastPackage != null) { 4454 mSettings.mPackagesToBeCleaned.remove(lastPackage); 4455 } 4456 return mSettings.mPackagesToBeCleaned.size() > 0 4457 ? mSettings.mPackagesToBeCleaned.get(0) : null; 4458 } 4459 } 4460 4461 void schedulePackageCleaning(String packageName) { 4462 mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE, packageName)); 4463 } 4464 4465 void startCleaningPackages() { 4466 synchronized (mPackages) { 4467 if (!mMediaMounted) { 4468 return; 4469 } 4470 if (mSettings.mPackagesToBeCleaned.size() <= 0) { 4471 return; 4472 } 4473 } 4474 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 4475 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 4476 IActivityManager am = ActivityManagerNative.getDefault(); 4477 if (am != null) { 4478 try { 4479 am.startService(null, intent, null); 4480 } catch (RemoteException e) { 4481 } 4482 } 4483 } 4484 4485 private final class AppDirObserver extends FileObserver { 4486 public AppDirObserver(String path, int mask, boolean isrom) { 4487 super(path, mask); 4488 mRootDir = path; 4489 mIsRom = isrom; 4490 } 4491 4492 public void onEvent(int event, String path) { 4493 String removedPackage = null; 4494 int removedUid = -1; 4495 String addedPackage = null; 4496 int addedUid = -1; 4497 4498 synchronized (mInstallLock) { 4499 String fullPathStr = null; 4500 File fullPath = null; 4501 if (path != null) { 4502 fullPath = new File(mRootDir, path); 4503 fullPathStr = fullPath.getPath(); 4504 } 4505 4506 if (Config.LOGV) Log.v( 4507 TAG, "File " + fullPathStr + " changed: " 4508 + Integer.toHexString(event)); 4509 4510 if (!isPackageFilename(path)) { 4511 if (Config.LOGV) Log.v( 4512 TAG, "Ignoring change of non-package file: " + fullPathStr); 4513 return; 4514 } 4515 4516 // Ignore packages that are being installed or 4517 // have just been installed. 4518 if (ignoreCodePath(fullPathStr)) { 4519 return; 4520 } 4521 PackageParser.Package p = null; 4522 synchronized (mPackages) { 4523 p = mAppDirs.get(fullPathStr); 4524 } 4525 if ((event&REMOVE_EVENTS) != 0) { 4526 if (p != null) { 4527 removePackageLI(p, true); 4528 removedPackage = p.applicationInfo.packageName; 4529 removedUid = p.applicationInfo.uid; 4530 } 4531 } 4532 4533 if ((event&ADD_EVENTS) != 0) { 4534 if (p == null) { 4535 p = scanPackageLI(fullPath, 4536 (mIsRom ? PackageParser.PARSE_IS_SYSTEM 4537 | PackageParser.PARSE_IS_SYSTEM_DIR: 0) | 4538 PackageParser.PARSE_CHATTY | 4539 PackageParser.PARSE_MUST_BE_APK, 4540 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME, 4541 System.currentTimeMillis()); 4542 if (p != null) { 4543 synchronized (mPackages) { 4544 updatePermissionsLP(p.packageName, p, 4545 p.permissions.size() > 0, false, false); 4546 } 4547 addedPackage = p.applicationInfo.packageName; 4548 addedUid = p.applicationInfo.uid; 4549 } 4550 } 4551 } 4552 4553 synchronized (mPackages) { 4554 mSettings.writeLP(); 4555 } 4556 } 4557 4558 if (removedPackage != null) { 4559 Bundle extras = new Bundle(1); 4560 extras.putInt(Intent.EXTRA_UID, removedUid); 4561 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false); 4562 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 4563 extras, null); 4564 } 4565 if (addedPackage != null) { 4566 Bundle extras = new Bundle(1); 4567 extras.putInt(Intent.EXTRA_UID, addedUid); 4568 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage, 4569 extras, null); 4570 } 4571 } 4572 4573 private final String mRootDir; 4574 private final boolean mIsRom; 4575 } 4576 4577 /* Called when a downloaded package installation has been confirmed by the user */ 4578 public void installPackage( 4579 final Uri packageURI, final IPackageInstallObserver observer, final int flags) { 4580 installPackage(packageURI, observer, flags, null); 4581 } 4582 4583 /* Called when a downloaded package installation has been confirmed by the user */ 4584 public void installPackage( 4585 final Uri packageURI, final IPackageInstallObserver observer, final int flags, 4586 final String installerPackageName) { 4587 mContext.enforceCallingOrSelfPermission( 4588 android.Manifest.permission.INSTALL_PACKAGES, null); 4589 4590 Message msg = mHandler.obtainMessage(INIT_COPY); 4591 msg.obj = new InstallParams(packageURI, observer, flags, 4592 installerPackageName); 4593 mHandler.sendMessage(msg); 4594 } 4595 4596 public void finishPackageInstall(int token) { 4597 if (DEBUG_INSTALL) Log.v(TAG, "BM finishing package install for " + token); 4598 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 4599 mHandler.sendMessage(msg); 4600 } 4601 4602 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 4603 // Queue up an async operation since the package installation may take a little while. 4604 mHandler.post(new Runnable() { 4605 public void run() { 4606 mHandler.removeCallbacks(this); 4607 // Result object to be returned 4608 PackageInstalledInfo res = new PackageInstalledInfo(); 4609 res.returnCode = currentStatus; 4610 res.uid = -1; 4611 res.pkg = null; 4612 res.removedInfo = new PackageRemovedInfo(); 4613 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 4614 args.doPreInstall(res.returnCode); 4615 synchronized (mInstallLock) { 4616 installPackageLI(args, true, res); 4617 } 4618 args.doPostInstall(res.returnCode); 4619 } 4620 4621 // A restore should be performed at this point if (a) the install 4622 // succeeded, (b) the operation is not an update, and (c) the new 4623 // package has a backupAgent defined. 4624 final boolean update = res.removedInfo.removedPackage != null; 4625 boolean doRestore = (!update 4626 && res.pkg != null 4627 && res.pkg.applicationInfo.backupAgentName != null); 4628 4629 // Set up the post-install work request bookkeeping. This will be used 4630 // and cleaned up by the post-install event handling regardless of whether 4631 // there's a restore pass performed. Token values are >= 1. 4632 int token; 4633 if (mNextInstallToken < 0) mNextInstallToken = 1; 4634 token = mNextInstallToken++; 4635 4636 PostInstallData data = new PostInstallData(args, res); 4637 mRunningInstalls.put(token, data); 4638 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 4639 4640 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 4641 // Pass responsibility to the Backup Manager. It will perform a 4642 // restore if appropriate, then pass responsibility back to the 4643 // Package Manager to run the post-install observer callbacks 4644 // and broadcasts. 4645 IBackupManager bm = IBackupManager.Stub.asInterface( 4646 ServiceManager.getService(Context.BACKUP_SERVICE)); 4647 if (bm != null) { 4648 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 4649 + " to BM for possible restore"); 4650 try { 4651 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 4652 } catch (RemoteException e) { 4653 // can't happen; the backup manager is local 4654 } catch (Exception e) { 4655 Slog.e(TAG, "Exception trying to enqueue restore", e); 4656 doRestore = false; 4657 } 4658 } else { 4659 Slog.e(TAG, "Backup Manager not found!"); 4660 doRestore = false; 4661 } 4662 } 4663 4664 if (!doRestore) { 4665 // No restore possible, or the Backup Manager was mysteriously not 4666 // available -- just fire the post-install work request directly. 4667 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 4668 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 4669 mHandler.sendMessage(msg); 4670 } 4671 } 4672 }); 4673 } 4674 4675 abstract class HandlerParams { 4676 final static int MAX_RETRIES = 4; 4677 int retry = 0; 4678 final void startCopy() { 4679 try { 4680 if (DEBUG_SD_INSTALL) Log.i(TAG, "startCopy"); 4681 retry++; 4682 if (retry > MAX_RETRIES) { 4683 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 4684 mHandler.sendEmptyMessage(MCS_GIVE_UP); 4685 handleServiceError(); 4686 return; 4687 } else { 4688 handleStartCopy(); 4689 if (DEBUG_SD_INSTALL) Log.i(TAG, "Posting install MCS_UNBIND"); 4690 mHandler.sendEmptyMessage(MCS_UNBIND); 4691 } 4692 } catch (RemoteException e) { 4693 if (DEBUG_SD_INSTALL) Log.i(TAG, "Posting install MCS_RECONNECT"); 4694 mHandler.sendEmptyMessage(MCS_RECONNECT); 4695 } 4696 handleReturnCode(); 4697 } 4698 4699 final void serviceError() { 4700 if (DEBUG_SD_INSTALL) Log.i(TAG, "serviceError"); 4701 handleServiceError(); 4702 handleReturnCode(); 4703 } 4704 abstract void handleStartCopy() throws RemoteException; 4705 abstract void handleServiceError(); 4706 abstract void handleReturnCode(); 4707 } 4708 4709 class InstallParams extends HandlerParams { 4710 final IPackageInstallObserver observer; 4711 int flags; 4712 final Uri packageURI; 4713 final String installerPackageName; 4714 private InstallArgs mArgs; 4715 private int mRet; 4716 InstallParams(Uri packageURI, 4717 IPackageInstallObserver observer, int flags, 4718 String installerPackageName) { 4719 this.packageURI = packageURI; 4720 this.flags = flags; 4721 this.observer = observer; 4722 this.installerPackageName = installerPackageName; 4723 } 4724 4725 private int installLocationPolicy(PackageInfoLite pkgLite, int flags) { 4726 String packageName = pkgLite.packageName; 4727 int installLocation = pkgLite.installLocation; 4728 boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 4729 synchronized (mPackages) { 4730 PackageParser.Package pkg = mPackages.get(packageName); 4731 if (pkg != null) { 4732 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 4733 // Check for updated system application. 4734 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 4735 if (onSd) { 4736 Slog.w(TAG, "Cannot install update to system app on sdcard"); 4737 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 4738 } 4739 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 4740 } else { 4741 if (onSd) { 4742 // Install flag overrides everything. 4743 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 4744 } 4745 // If current upgrade specifies particular preference 4746 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 4747 // Application explicitly specified internal. 4748 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 4749 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 4750 // App explictly prefers external. Let policy decide 4751 } else { 4752 // Prefer previous location 4753 if (isExternal(pkg)) { 4754 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 4755 } 4756 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 4757 } 4758 } 4759 } else { 4760 // Invalid install. Return error code 4761 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 4762 } 4763 } 4764 } 4765 // All the special cases have been taken care of. 4766 // Return result based on recommended install location. 4767 if (onSd) { 4768 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 4769 } 4770 return pkgLite.recommendedInstallLocation; 4771 } 4772 4773 /* 4774 * Invoke remote method to get package information and install 4775 * location values. Override install location based on default 4776 * policy if needed and then create install arguments based 4777 * on the install location. 4778 */ 4779 public void handleStartCopy() throws RemoteException { 4780 int ret = PackageManager.INSTALL_SUCCEEDED; 4781 boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 4782 boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 4783 boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0; 4784 if (onInt && onSd) { 4785 // Check if both bits are set. 4786 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 4787 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 4788 } else if (fwdLocked && onSd) { 4789 // Check for forward locked apps 4790 Slog.w(TAG, "Cannot install fwd locked apps on sdcard"); 4791 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 4792 } else { 4793 // Remote call to find out default install location 4794 final PackageInfoLite pkgLite; 4795 try { 4796 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 4797 Intent.FLAG_GRANT_READ_URI_PERMISSION); 4798 pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags); 4799 } finally { 4800 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 4801 } 4802 4803 int loc = pkgLite.recommendedInstallLocation; 4804 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION){ 4805 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 4806 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS){ 4807 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 4808 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE){ 4809 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4810 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 4811 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 4812 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 4813 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 4814 } else { 4815 // Override with defaults if needed. 4816 loc = installLocationPolicy(pkgLite, flags); 4817 if (!onSd && !onInt) { 4818 // Override install location with flags 4819 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 4820 // Set the flag to install on external media. 4821 flags |= PackageManager.INSTALL_EXTERNAL; 4822 flags &= ~PackageManager.INSTALL_INTERNAL; 4823 } else { 4824 // Make sure the flag for installing on external 4825 // media is unset 4826 flags |= PackageManager.INSTALL_INTERNAL; 4827 flags &= ~PackageManager.INSTALL_EXTERNAL; 4828 } 4829 } 4830 } 4831 } 4832 // Create the file args now. 4833 mArgs = createInstallArgs(this); 4834 if (ret == PackageManager.INSTALL_SUCCEEDED) { 4835 // Create copy only if we are not in an erroneous state. 4836 // Remote call to initiate copy using temporary file 4837 ret = mArgs.copyApk(mContainerService, true); 4838 } 4839 mRet = ret; 4840 } 4841 4842 @Override 4843 void handleReturnCode() { 4844 // If mArgs is null, then MCS couldn't be reached. When it 4845 // reconnects, it will try again to install. At that point, this 4846 // will succeed. 4847 if (mArgs != null) { 4848 processPendingInstall(mArgs, mRet); 4849 } 4850 } 4851 4852 @Override 4853 void handleServiceError() { 4854 mArgs = createInstallArgs(this); 4855 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 4856 } 4857 } 4858 4859 /* 4860 * Utility class used in movePackage api. 4861 * srcArgs and targetArgs are not set for invalid flags and make 4862 * sure to do null checks when invoking methods on them. 4863 * We probably want to return ErrorPrams for both failed installs 4864 * and moves. 4865 */ 4866 class MoveParams extends HandlerParams { 4867 final IPackageMoveObserver observer; 4868 final int flags; 4869 final String packageName; 4870 final InstallArgs srcArgs; 4871 final InstallArgs targetArgs; 4872 int mRet; 4873 4874 MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, 4875 String packageName, String dataDir) { 4876 this.srcArgs = srcArgs; 4877 this.observer = observer; 4878 this.flags = flags; 4879 this.packageName = packageName; 4880 if (srcArgs != null) { 4881 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath())); 4882 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir); 4883 } else { 4884 targetArgs = null; 4885 } 4886 } 4887 4888 public void handleStartCopy() throws RemoteException { 4889 mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 4890 // Check for storage space on target medium 4891 if (!targetArgs.checkFreeStorage(mContainerService)) { 4892 Log.w(TAG, "Insufficient storage to install"); 4893 return; 4894 } 4895 // Create the file args now. 4896 mRet = targetArgs.copyApk(mContainerService, false); 4897 targetArgs.doPreInstall(mRet); 4898 if (DEBUG_SD_INSTALL) { 4899 StringBuilder builder = new StringBuilder(); 4900 if (srcArgs != null) { 4901 builder.append("src: "); 4902 builder.append(srcArgs.getCodePath()); 4903 } 4904 if (targetArgs != null) { 4905 builder.append(" target : "); 4906 builder.append(targetArgs.getCodePath()); 4907 } 4908 Log.i(TAG, builder.toString()); 4909 } 4910 } 4911 4912 @Override 4913 void handleReturnCode() { 4914 targetArgs.doPostInstall(mRet); 4915 int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 4916 if (mRet == PackageManager.INSTALL_SUCCEEDED) { 4917 currentStatus = PackageManager.MOVE_SUCCEEDED; 4918 } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){ 4919 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 4920 } 4921 processPendingMove(this, currentStatus); 4922 } 4923 4924 @Override 4925 void handleServiceError() { 4926 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 4927 } 4928 } 4929 4930 private InstallArgs createInstallArgs(InstallParams params) { 4931 if (installOnSd(params.flags)) { 4932 return new SdInstallArgs(params); 4933 } else { 4934 return new FileInstallArgs(params); 4935 } 4936 } 4937 4938 private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath, 4939 String nativeLibraryPath) { 4940 if (installOnSd(flags)) { 4941 return new SdInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); 4942 } else { 4943 return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); 4944 } 4945 } 4946 4947 // Used by package mover 4948 private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) { 4949 if (installOnSd(flags)) { 4950 String cid = getNextCodePath(null, pkgName, "/" + SdInstallArgs.RES_FILE_NAME); 4951 return new SdInstallArgs(packageURI, cid); 4952 } else { 4953 return new FileInstallArgs(packageURI, pkgName, dataDir); 4954 } 4955 } 4956 4957 static abstract class InstallArgs { 4958 final IPackageInstallObserver observer; 4959 // Always refers to PackageManager flags only 4960 final int flags; 4961 final Uri packageURI; 4962 final String installerPackageName; 4963 4964 InstallArgs(Uri packageURI, 4965 IPackageInstallObserver observer, int flags, 4966 String installerPackageName) { 4967 this.packageURI = packageURI; 4968 this.flags = flags; 4969 this.observer = observer; 4970 this.installerPackageName = installerPackageName; 4971 } 4972 4973 abstract void createCopyFile(); 4974 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 4975 abstract int doPreInstall(int status); 4976 abstract boolean doRename(int status, String pkgName, String oldCodePath); 4977 abstract int doPostInstall(int status); 4978 abstract String getCodePath(); 4979 abstract String getResourcePath(); 4980 abstract String getNativeLibraryPath(); 4981 // Need installer lock especially for dex file removal. 4982 abstract void cleanUpResourcesLI(); 4983 abstract boolean doPostDeleteLI(boolean delete); 4984 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 4985 } 4986 4987 class FileInstallArgs extends InstallArgs { 4988 File installDir; 4989 String codeFileName; 4990 String resourceFileName; 4991 String libraryPath; 4992 boolean created = false; 4993 4994 FileInstallArgs(InstallParams params) { 4995 super(params.packageURI, params.observer, 4996 params.flags, params.installerPackageName); 4997 } 4998 4999 FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) { 5000 super(null, null, 0, null); 5001 File codeFile = new File(fullCodePath); 5002 installDir = codeFile.getParentFile(); 5003 codeFileName = fullCodePath; 5004 resourceFileName = fullResourcePath; 5005 libraryPath = nativeLibraryPath; 5006 } 5007 5008 FileInstallArgs(Uri packageURI, String pkgName, String dataDir) { 5009 super(packageURI, null, 0, null); 5010 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 5011 String apkName = getNextCodePath(null, pkgName, ".apk"); 5012 codeFileName = new File(installDir, apkName + ".apk").getPath(); 5013 resourceFileName = getResourcePathFromCodePath(); 5014 libraryPath = new File(dataDir, LIB_DIR_NAME).getPath(); 5015 } 5016 5017 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 5018 try { 5019 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5020 Intent.FLAG_GRANT_READ_URI_PERMISSION); 5021 return imcs.checkFreeStorage(false, packageURI); 5022 } finally { 5023 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5024 } 5025 } 5026 5027 String getCodePath() { 5028 return codeFileName; 5029 } 5030 5031 void createCopyFile() { 5032 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 5033 codeFileName = createTempPackageFile(installDir).getPath(); 5034 resourceFileName = getResourcePathFromCodePath(); 5035 created = true; 5036 } 5037 5038 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 5039 if (temp) { 5040 // Generate temp file name 5041 createCopyFile(); 5042 } 5043 // Get a ParcelFileDescriptor to write to the output file 5044 File codeFile = new File(codeFileName); 5045 if (!created) { 5046 try { 5047 codeFile.createNewFile(); 5048 // Set permissions 5049 if (!setPermissions()) { 5050 // Failed setting permissions. 5051 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5052 } 5053 } catch (IOException e) { 5054 Slog.w(TAG, "Failed to create file " + codeFile); 5055 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5056 } 5057 } 5058 ParcelFileDescriptor out = null; 5059 try { 5060 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE); 5061 } catch (FileNotFoundException e) { 5062 Slog.e(TAG, "Failed to create file descritpor for : " + codeFileName); 5063 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5064 } 5065 // Copy the resource now 5066 int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5067 try { 5068 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5069 Intent.FLAG_GRANT_READ_URI_PERMISSION); 5070 if (imcs.copyResource(packageURI, out)) { 5071 ret = PackageManager.INSTALL_SUCCEEDED; 5072 } 5073 } finally { 5074 try { if (out != null) out.close(); } catch (IOException e) {} 5075 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5076 } 5077 5078 return ret; 5079 } 5080 5081 int doPreInstall(int status) { 5082 if (status != PackageManager.INSTALL_SUCCEEDED) { 5083 cleanUp(); 5084 } 5085 return status; 5086 } 5087 5088 boolean doRename(int status, final String pkgName, String oldCodePath) { 5089 if (status != PackageManager.INSTALL_SUCCEEDED) { 5090 cleanUp(); 5091 return false; 5092 } else { 5093 // Rename based on packageName 5094 File codeFile = new File(getCodePath()); 5095 String apkName = getNextCodePath(oldCodePath, pkgName, ".apk"); 5096 File desFile = new File(installDir, apkName + ".apk"); 5097 if (!codeFile.renameTo(desFile)) { 5098 return false; 5099 } 5100 // Reset paths since the file has been renamed. 5101 codeFileName = desFile.getPath(); 5102 resourceFileName = getResourcePathFromCodePath(); 5103 // Set permissions 5104 if (!setPermissions()) { 5105 // Failed setting permissions. 5106 return false; 5107 } 5108 return true; 5109 } 5110 } 5111 5112 int doPostInstall(int status) { 5113 if (status != PackageManager.INSTALL_SUCCEEDED) { 5114 cleanUp(); 5115 } 5116 return status; 5117 } 5118 5119 String getResourcePath() { 5120 return resourceFileName; 5121 } 5122 5123 String getResourcePathFromCodePath() { 5124 String codePath = getCodePath(); 5125 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { 5126 String apkNameOnly = getApkName(codePath); 5127 return mAppInstallDir.getPath() + "/" + apkNameOnly + ".zip"; 5128 } else { 5129 return codePath; 5130 } 5131 } 5132 5133 @Override 5134 String getNativeLibraryPath() { 5135 return libraryPath; 5136 } 5137 5138 private boolean cleanUp() { 5139 boolean ret = true; 5140 String sourceDir = getCodePath(); 5141 String publicSourceDir = getResourcePath(); 5142 if (sourceDir != null) { 5143 File sourceFile = new File(sourceDir); 5144 if (!sourceFile.exists()) { 5145 Slog.w(TAG, "Package source " + sourceDir + " does not exist."); 5146 ret = false; 5147 } 5148 // Delete application's code and resources 5149 sourceFile.delete(); 5150 } 5151 if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) { 5152 final File publicSourceFile = new File(publicSourceDir); 5153 if (!publicSourceFile.exists()) { 5154 Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist."); 5155 } 5156 if (publicSourceFile.exists()) { 5157 publicSourceFile.delete(); 5158 } 5159 } 5160 return ret; 5161 } 5162 5163 void cleanUpResourcesLI() { 5164 String sourceDir = getCodePath(); 5165 if (cleanUp() && mInstaller != null) { 5166 int retCode = mInstaller.rmdex(sourceDir); 5167 if (retCode < 0) { 5168 Slog.w(TAG, "Couldn't remove dex file for package: " 5169 + " at location " 5170 + sourceDir + ", retcode=" + retCode); 5171 // we don't consider this to be a failure of the core package deletion 5172 } 5173 } 5174 } 5175 5176 private boolean setPermissions() { 5177 // TODO Do this in a more elegant way later on. for now just a hack 5178 if (!isFwdLocked()) { 5179 final int filePermissions = 5180 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP 5181 |FileUtils.S_IROTH; 5182 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1); 5183 if (retCode != 0) { 5184 Slog.e(TAG, "Couldn't set new package file permissions for " + 5185 getCodePath() 5186 + ". The return code was: " + retCode); 5187 // TODO Define new internal error 5188 return false; 5189 } 5190 return true; 5191 } 5192 return true; 5193 } 5194 5195 boolean doPostDeleteLI(boolean delete) { 5196 // XXX err, shouldn't we respect the delete flag? 5197 cleanUpResourcesLI(); 5198 return true; 5199 } 5200 5201 private boolean isFwdLocked() { 5202 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 5203 } 5204 } 5205 5206 class SdInstallArgs extends InstallArgs { 5207 static final String RES_FILE_NAME = "pkg.apk"; 5208 5209 String cid; 5210 String packagePath; 5211 String libraryPath; 5212 5213 SdInstallArgs(InstallParams params) { 5214 super(params.packageURI, params.observer, 5215 params.flags, params.installerPackageName); 5216 } 5217 5218 SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) { 5219 super(null, null, PackageManager.INSTALL_EXTERNAL, null); 5220 // Extract cid from fullCodePath 5221 int eidx = fullCodePath.lastIndexOf("/"); 5222 String subStr1 = fullCodePath.substring(0, eidx); 5223 int sidx = subStr1.lastIndexOf("/"); 5224 cid = subStr1.substring(sidx+1, eidx); 5225 setCachePath(subStr1); 5226 } 5227 5228 SdInstallArgs(String cid) { 5229 super(null, null, PackageManager.INSTALL_EXTERNAL, null); 5230 this.cid = cid; 5231 setCachePath(PackageHelper.getSdDir(cid)); 5232 } 5233 5234 SdInstallArgs(Uri packageURI, String cid) { 5235 super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null); 5236 this.cid = cid; 5237 } 5238 5239 void createCopyFile() { 5240 cid = getTempContainerId(); 5241 } 5242 5243 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 5244 try { 5245 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5246 Intent.FLAG_GRANT_READ_URI_PERMISSION); 5247 return imcs.checkFreeStorage(true, packageURI); 5248 } finally { 5249 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5250 } 5251 } 5252 5253 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 5254 if (temp) { 5255 createCopyFile(); 5256 } 5257 5258 final String newCachePath; 5259 try { 5260 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5261 Intent.FLAG_GRANT_READ_URI_PERMISSION); 5262 newCachePath = imcs.copyResourceToContainer(packageURI, cid, 5263 getEncryptKey(), RES_FILE_NAME); 5264 } finally { 5265 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5266 } 5267 5268 if (newCachePath != null) { 5269 setCachePath(newCachePath); 5270 return PackageManager.INSTALL_SUCCEEDED; 5271 } else { 5272 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 5273 } 5274 } 5275 5276 @Override 5277 String getCodePath() { 5278 return packagePath; 5279 } 5280 5281 @Override 5282 String getResourcePath() { 5283 return packagePath; 5284 } 5285 5286 @Override 5287 String getNativeLibraryPath() { 5288 return libraryPath; 5289 } 5290 5291 int doPreInstall(int status) { 5292 if (status != PackageManager.INSTALL_SUCCEEDED) { 5293 // Destroy container 5294 PackageHelper.destroySdDir(cid); 5295 } else { 5296 boolean mounted = PackageHelper.isContainerMounted(cid); 5297 if (!mounted) { 5298 String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(), 5299 Process.SYSTEM_UID); 5300 if (newCachePath != null) { 5301 setCachePath(newCachePath); 5302 } else { 5303 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 5304 } 5305 } 5306 } 5307 return status; 5308 } 5309 5310 boolean doRename(int status, final String pkgName, 5311 String oldCodePath) { 5312 String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME); 5313 String newCachePath = null; 5314 if (PackageHelper.isContainerMounted(cid)) { 5315 // Unmount the container 5316 if (!PackageHelper.unMountSdDir(cid)) { 5317 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 5318 return false; 5319 } 5320 } 5321 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 5322 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 5323 " which might be stale. Will try to clean up."); 5324 // Clean up the stale container and proceed to recreate. 5325 if (!PackageHelper.destroySdDir(newCacheId)) { 5326 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 5327 return false; 5328 } 5329 // Successfully cleaned up stale container. Try to rename again. 5330 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 5331 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 5332 + " inspite of cleaning it up."); 5333 return false; 5334 } 5335 } 5336 if (!PackageHelper.isContainerMounted(newCacheId)) { 5337 Slog.w(TAG, "Mounting container " + newCacheId); 5338 newCachePath = PackageHelper.mountSdDir(newCacheId, 5339 getEncryptKey(), Process.SYSTEM_UID); 5340 } else { 5341 newCachePath = PackageHelper.getSdDir(newCacheId); 5342 } 5343 if (newCachePath == null) { 5344 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 5345 return false; 5346 } 5347 Log.i(TAG, "Succesfully renamed " + cid + 5348 " to " + newCacheId + 5349 " at new path: " + newCachePath); 5350 cid = newCacheId; 5351 setCachePath(newCachePath); 5352 return true; 5353 } 5354 5355 private void setCachePath(String newCachePath) { 5356 File cachePath = new File(newCachePath); 5357 libraryPath = new File(cachePath, LIB_DIR_NAME).getPath(); 5358 packagePath = new File(cachePath, RES_FILE_NAME).getPath(); 5359 } 5360 5361 int doPostInstall(int status) { 5362 if (status != PackageManager.INSTALL_SUCCEEDED) { 5363 cleanUp(); 5364 } else { 5365 boolean mounted = PackageHelper.isContainerMounted(cid); 5366 if (!mounted) { 5367 PackageHelper.mountSdDir(cid, 5368 getEncryptKey(), Process.myUid()); 5369 } 5370 } 5371 return status; 5372 } 5373 5374 private void cleanUp() { 5375 // Destroy secure container 5376 PackageHelper.destroySdDir(cid); 5377 } 5378 5379 void cleanUpResourcesLI() { 5380 String sourceFile = getCodePath(); 5381 // Remove dex file 5382 if (mInstaller != null) { 5383 int retCode = mInstaller.rmdex(sourceFile); 5384 if (retCode < 0) { 5385 Slog.w(TAG, "Couldn't remove dex file for package: " 5386 + " at location " 5387 + sourceFile.toString() + ", retcode=" + retCode); 5388 // we don't consider this to be a failure of the core package deletion 5389 } 5390 } 5391 cleanUp(); 5392 } 5393 5394 boolean matchContainer(String app) { 5395 if (cid.startsWith(app)) { 5396 return true; 5397 } 5398 return false; 5399 } 5400 5401 String getPackageName() { 5402 int idx = cid.lastIndexOf("-"); 5403 if (idx == -1) { 5404 return cid; 5405 } 5406 return cid.substring(0, idx); 5407 } 5408 5409 boolean doPostDeleteLI(boolean delete) { 5410 boolean ret = false; 5411 boolean mounted = PackageHelper.isContainerMounted(cid); 5412 if (mounted) { 5413 // Unmount first 5414 ret = PackageHelper.unMountSdDir(cid); 5415 } 5416 if (ret && delete) { 5417 cleanUpResourcesLI(); 5418 } 5419 return ret; 5420 } 5421 }; 5422 5423 // Utility method used to create code paths based on package name and available index. 5424 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 5425 String idxStr = ""; 5426 int idx = 1; 5427 // Fall back to default value of idx=1 if prefix is not 5428 // part of oldCodePath 5429 if (oldCodePath != null) { 5430 String subStr = oldCodePath; 5431 // Drop the suffix right away 5432 if (subStr.endsWith(suffix)) { 5433 subStr = subStr.substring(0, subStr.length() - suffix.length()); 5434 } 5435 // If oldCodePath already contains prefix find out the 5436 // ending index to either increment or decrement. 5437 int sidx = subStr.lastIndexOf(prefix); 5438 if (sidx != -1) { 5439 subStr = subStr.substring(sidx + prefix.length()); 5440 if (subStr != null) { 5441 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 5442 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 5443 } 5444 try { 5445 idx = Integer.parseInt(subStr); 5446 if (idx <= 1) { 5447 idx++; 5448 } else { 5449 idx--; 5450 } 5451 } catch(NumberFormatException e) { 5452 } 5453 } 5454 } 5455 } 5456 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 5457 return prefix + idxStr; 5458 } 5459 5460 // Utility method used to ignore ADD/REMOVE events 5461 // by directory observer. 5462 private static boolean ignoreCodePath(String fullPathStr) { 5463 String apkName = getApkName(fullPathStr); 5464 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX); 5465 if (idx != -1 && ((idx+1) < apkName.length())) { 5466 // Make sure the package ends with a numeral 5467 String version = apkName.substring(idx+1); 5468 try { 5469 Integer.parseInt(version); 5470 return true; 5471 } catch (NumberFormatException e) {} 5472 } 5473 return false; 5474 } 5475 5476 // Utility method that returns the relative package path with respect 5477 // to the installation directory. Like say for /data/data/com.test-1.apk 5478 // string com.test-1 is returned. 5479 static String getApkName(String codePath) { 5480 if (codePath == null) { 5481 return null; 5482 } 5483 int sidx = codePath.lastIndexOf("/"); 5484 int eidx = codePath.lastIndexOf("."); 5485 if (eidx == -1) { 5486 eidx = codePath.length(); 5487 } else if (eidx == 0) { 5488 Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name"); 5489 return null; 5490 } 5491 return codePath.substring(sidx+1, eidx); 5492 } 5493 5494 class PackageInstalledInfo { 5495 String name; 5496 int uid; 5497 PackageParser.Package pkg; 5498 int returnCode; 5499 PackageRemovedInfo removedInfo; 5500 } 5501 5502 /* 5503 * Install a non-existing package. 5504 */ 5505 private void installNewPackageLI(PackageParser.Package pkg, 5506 int parseFlags, 5507 int scanMode, 5508 String installerPackageName, PackageInstalledInfo res) { 5509 // Remember this for later, in case we need to rollback this install 5510 String pkgName = pkg.packageName; 5511 5512 boolean dataDirExists = getDataPathForPackage(pkg).exists(); 5513 res.name = pkgName; 5514 synchronized(mPackages) { 5515 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 5516 // A package with the same name is already installed, though 5517 // it has been renamed to an older name. The package we 5518 // are trying to install should be installed as an update to 5519 // the existing one, but that has not been requested, so bail. 5520 Slog.w(TAG, "Attempt to re-install " + pkgName 5521 + " without first uninstalling package running as " 5522 + mSettings.mRenamedPackages.get(pkgName)); 5523 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 5524 return; 5525 } 5526 if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) { 5527 // Don't allow installation over an existing package with the same name. 5528 Slog.w(TAG, "Attempt to re-install " + pkgName 5529 + " without first uninstalling."); 5530 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 5531 return; 5532 } 5533 } 5534 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 5535 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode, 5536 System.currentTimeMillis()); 5537 if (newPackage == null) { 5538 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 5539 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 5540 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 5541 } 5542 } else { 5543 updateSettingsLI(newPackage, 5544 installerPackageName, 5545 res); 5546 // delete the partially installed application. the data directory will have to be 5547 // restored if it was already existing 5548 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 5549 // remove package from internal structures. Note that we want deletePackageX to 5550 // delete the package data and cache directories that it created in 5551 // scanPackageLocked, unless those directories existed before we even tried to 5552 // install. 5553 deletePackageLI( 5554 pkgName, false, 5555 dataDirExists ? PackageManager.DONT_DELETE_DATA : 0, 5556 res.removedInfo, true); 5557 } 5558 } 5559 } 5560 5561 private void replacePackageLI(PackageParser.Package pkg, 5562 int parseFlags, 5563 int scanMode, 5564 String installerPackageName, PackageInstalledInfo res) { 5565 5566 PackageParser.Package oldPackage; 5567 String pkgName = pkg.packageName; 5568 // First find the old package info and check signatures 5569 synchronized(mPackages) { 5570 oldPackage = mPackages.get(pkgName); 5571 if (checkSignaturesLP(oldPackage.mSignatures, pkg.mSignatures) 5572 != PackageManager.SIGNATURE_MATCH) { 5573 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 5574 return; 5575 } 5576 } 5577 boolean sysPkg = (isSystemApp(oldPackage)); 5578 if (sysPkg) { 5579 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res); 5580 } else { 5581 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res); 5582 } 5583 } 5584 5585 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 5586 PackageParser.Package pkg, 5587 int parseFlags, int scanMode, 5588 String installerPackageName, PackageInstalledInfo res) { 5589 PackageParser.Package newPackage = null; 5590 String pkgName = deletedPackage.packageName; 5591 boolean deletedPkg = true; 5592 boolean updatedSettings = false; 5593 5594 String oldInstallerPackageName = null; 5595 synchronized (mPackages) { 5596 oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName); 5597 } 5598 5599 long origUpdateTime; 5600 if (pkg.mExtras != null) { 5601 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 5602 } else { 5603 origUpdateTime = 0; 5604 } 5605 5606 // First delete the existing package while retaining the data directory 5607 if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA, 5608 res.removedInfo, true)) { 5609 // If the existing package wasn't successfully deleted 5610 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 5611 deletedPkg = false; 5612 } else { 5613 // Successfully deleted the old package. Now proceed with re-installation 5614 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 5615 newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME, 5616 System.currentTimeMillis()); 5617 if (newPackage == null) { 5618 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 5619 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 5620 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 5621 } 5622 } else { 5623 updateSettingsLI(newPackage, 5624 installerPackageName, 5625 res); 5626 updatedSettings = true; 5627 } 5628 } 5629 5630 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 5631 // remove package from internal structures. Note that we want deletePackageX to 5632 // delete the package data and cache directories that it created in 5633 // scanPackageLocked, unless those directories existed before we even tried to 5634 // install. 5635 if(updatedSettings) { 5636 deletePackageLI( 5637 pkgName, true, 5638 PackageManager.DONT_DELETE_DATA, 5639 res.removedInfo, true); 5640 } 5641 // Since we failed to install the new package we need to restore the old 5642 // package that we deleted. 5643 if(deletedPkg) { 5644 File restoreFile = new File(deletedPackage.mPath); 5645 if (restoreFile == null) { 5646 Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName); 5647 return; 5648 } 5649 // Parse old package 5650 boolean oldOnSd = isExternal(deletedPackage); 5651 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 5652 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) | 5653 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0); 5654 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE 5655 | SCAN_UPDATE_TIME; 5656 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode, 5657 origUpdateTime) == null) { 5658 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade"); 5659 return; 5660 } 5661 // Restore of old package succeeded. Update permissions. 5662 synchronized (mPackages) { 5663 updatePermissionsLP(deletedPackage.packageName, deletedPackage, 5664 true, false, false); 5665 mSettings.writeLP(); 5666 } 5667 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 5668 } 5669 } 5670 } 5671 5672 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 5673 PackageParser.Package pkg, 5674 int parseFlags, int scanMode, 5675 String installerPackageName, PackageInstalledInfo res) { 5676 PackageParser.Package newPackage = null; 5677 boolean updatedSettings = false; 5678 parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING | 5679 PackageParser.PARSE_IS_SYSTEM; 5680 String packageName = deletedPackage.packageName; 5681 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 5682 if (packageName == null) { 5683 Slog.w(TAG, "Attempt to delete null packageName."); 5684 return; 5685 } 5686 PackageParser.Package oldPkg; 5687 PackageSetting oldPkgSetting; 5688 synchronized (mPackages) { 5689 oldPkg = mPackages.get(packageName); 5690 oldPkgSetting = mSettings.mPackages.get(packageName); 5691 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 5692 (oldPkgSetting == null)) { 5693 Slog.w(TAG, "Couldn't find package:"+packageName+" information"); 5694 return; 5695 } 5696 } 5697 5698 killApplication(packageName, oldPkg.applicationInfo.uid); 5699 5700 res.removedInfo.uid = oldPkg.applicationInfo.uid; 5701 res.removedInfo.removedPackage = packageName; 5702 // Remove existing system package 5703 removePackageLI(oldPkg, true); 5704 synchronized (mPackages) { 5705 if (!mSettings.disableSystemPackageLP(packageName) && deletedPackage != null) { 5706 // We didn't need to disable the .apk as a current system package, 5707 // which means we are replacing another update that is already 5708 // installed. We need to make sure to delete the older one's .apk. 5709 res.removedInfo.args = createInstallArgs(isExternal(pkg) 5710 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL, 5711 deletedPackage.applicationInfo.sourceDir, 5712 deletedPackage.applicationInfo.publicSourceDir, 5713 deletedPackage.applicationInfo.nativeLibraryDir); 5714 } else { 5715 res.removedInfo.args = null; 5716 } 5717 } 5718 5719 // Successfully disabled the old package. Now proceed with re-installation 5720 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 5721 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 5722 newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0); 5723 if (newPackage == null) { 5724 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 5725 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 5726 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 5727 } 5728 } else { 5729 if (newPackage.mExtras != null) { 5730 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras; 5731 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 5732 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 5733 } 5734 updateSettingsLI(newPackage, installerPackageName, res); 5735 updatedSettings = true; 5736 } 5737 5738 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 5739 // Re installation failed. Restore old information 5740 // Remove new pkg information 5741 if (newPackage != null) { 5742 removePackageLI(newPackage, true); 5743 } 5744 // Add back the old system package 5745 scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0); 5746 // Restore the old system information in Settings 5747 synchronized(mPackages) { 5748 if (updatedSettings) { 5749 mSettings.enableSystemPackageLP(packageName); 5750 mSettings.setInstallerPackageName(packageName, 5751 oldPkgSetting.installerPackageName); 5752 } 5753 mSettings.writeLP(); 5754 } 5755 } 5756 } 5757 5758 // Utility method used to move dex files during install. 5759 private int moveDexFilesLI(PackageParser.Package newPackage) { 5760 int retCode; 5761 if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 5762 retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath); 5763 if (retCode != 0) { 5764 if (mNoDexOpt) { 5765 /* 5766 * If we're in an engineering build, programs are lazily run 5767 * through dexopt. If the .dex file doesn't exist yet, it 5768 * will be created when the program is run next. 5769 */ 5770 Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath); 5771 } else { 5772 Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath); 5773 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5774 } 5775 } 5776 } 5777 return PackageManager.INSTALL_SUCCEEDED; 5778 } 5779 5780 private void updateSettingsLI(PackageParser.Package newPackage, 5781 String installerPackageName, PackageInstalledInfo res) { 5782 String pkgName = newPackage.packageName; 5783 synchronized (mPackages) { 5784 //write settings. the installStatus will be incomplete at this stage. 5785 //note that the new package setting would have already been 5786 //added to mPackages. It hasn't been persisted yet. 5787 mSettings.setInstallStatus(pkgName, PKG_INSTALL_INCOMPLETE); 5788 mSettings.writeLP(); 5789 } 5790 5791 if ((res.returnCode = moveDexFilesLI(newPackage)) 5792 != PackageManager.INSTALL_SUCCEEDED) { 5793 // Discontinue if moving dex files failed. 5794 return; 5795 } 5796 if((res.returnCode = setPermissionsLI(newPackage)) 5797 != PackageManager.INSTALL_SUCCEEDED) { 5798 if (mInstaller != null) { 5799 mInstaller.rmdex(newPackage.mScanPath); 5800 } 5801 return; 5802 } else { 5803 Log.d(TAG, "New package installed in " + newPackage.mPath); 5804 } 5805 synchronized (mPackages) { 5806 updatePermissionsLP(newPackage.packageName, newPackage, 5807 newPackage.permissions.size() > 0, true, false); 5808 res.name = pkgName; 5809 res.uid = newPackage.applicationInfo.uid; 5810 res.pkg = newPackage; 5811 mSettings.setInstallStatus(pkgName, PKG_INSTALL_COMPLETE); 5812 mSettings.setInstallerPackageName(pkgName, installerPackageName); 5813 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 5814 //to update install status 5815 mSettings.writeLP(); 5816 } 5817 } 5818 5819 private void installPackageLI(InstallArgs args, 5820 boolean newInstall, PackageInstalledInfo res) { 5821 int pFlags = args.flags; 5822 String installerPackageName = args.installerPackageName; 5823 File tmpPackageFile = new File(args.getCodePath()); 5824 boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 5825 boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0); 5826 boolean replace = false; 5827 int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE 5828 | (newInstall ? SCAN_NEW_INSTALL : 0); 5829 // Result object to be returned 5830 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 5831 5832 // Retrieve PackageSettings and parse package 5833 int parseFlags = PackageParser.PARSE_CHATTY | 5834 (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) | 5835 (onSd ? PackageParser.PARSE_ON_SDCARD : 0); 5836 parseFlags |= mDefParseFlags; 5837 PackageParser pp = new PackageParser(tmpPackageFile.getPath()); 5838 pp.setSeparateProcesses(mSeparateProcesses); 5839 final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile, 5840 null, mMetrics, parseFlags); 5841 if (pkg == null) { 5842 res.returnCode = pp.getParseError(); 5843 return; 5844 } 5845 String pkgName = res.name = pkg.packageName; 5846 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 5847 if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) { 5848 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY; 5849 return; 5850 } 5851 } 5852 if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) { 5853 res.returnCode = pp.getParseError(); 5854 return; 5855 } 5856 // Get rid of all references to package scan path via parser. 5857 pp = null; 5858 String oldCodePath = null; 5859 boolean systemApp = false; 5860 synchronized (mPackages) { 5861 // Check if installing already existing package 5862 if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 5863 String oldName = mSettings.mRenamedPackages.get(pkgName); 5864 if (pkg.mOriginalPackages != null 5865 && pkg.mOriginalPackages.contains(oldName) 5866 && mPackages.containsKey(oldName)) { 5867 // This package is derived from an original package, 5868 // and this device has been updating from that original 5869 // name. We must continue using the original name, so 5870 // rename the new package here. 5871 pkg.setPackageName(oldName); 5872 pkgName = pkg.packageName; 5873 replace = true; 5874 } else if (mPackages.containsKey(pkgName)) { 5875 // This package, under its official name, already exists 5876 // on the device; we should replace it. 5877 replace = true; 5878 } 5879 } 5880 PackageSetting ps = mSettings.mPackages.get(pkgName); 5881 if (ps != null) { 5882 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 5883 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 5884 systemApp = (ps.pkg.applicationInfo.flags & 5885 ApplicationInfo.FLAG_SYSTEM) != 0; 5886 } 5887 } 5888 } 5889 5890 if (systemApp && onSd) { 5891 // Disable updates to system apps on sdcard 5892 Slog.w(TAG, "Cannot install updates to system apps on sdcard"); 5893 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 5894 return; 5895 } 5896 5897 if (!args.doRename(res.returnCode, pkgName, oldCodePath)) { 5898 res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5899 return; 5900 } 5901 // Set application objects path explicitly after the rename 5902 setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath()); 5903 pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath(); 5904 if (replace) { 5905 replacePackageLI(pkg, parseFlags, scanMode, 5906 installerPackageName, res); 5907 } else { 5908 installNewPackageLI(pkg, parseFlags, scanMode, 5909 installerPackageName,res); 5910 } 5911 } 5912 5913 private int setPermissionsLI(PackageParser.Package newPackage) { 5914 String pkgName = newPackage.packageName; 5915 int retCode = 0; 5916 // TODO Gross hack but fix later. Ideally move this to be a post installation 5917 // check after alloting uid. 5918 if (isForwardLocked(newPackage)) { 5919 File destResourceFile = new File(newPackage.applicationInfo.publicSourceDir); 5920 try { 5921 extractPublicFiles(newPackage, destResourceFile); 5922 } catch (IOException e) { 5923 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" + 5924 " forward-locked app."); 5925 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5926 } finally { 5927 //TODO clean up the extracted public files 5928 } 5929 if (mInstaller != null) { 5930 retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath), 5931 newPackage.applicationInfo.uid); 5932 } else { 5933 final int filePermissions = 5934 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP; 5935 retCode = FileUtils.setPermissions(newPackage.mPath, filePermissions, -1, 5936 newPackage.applicationInfo.uid); 5937 } 5938 } else { 5939 // The permissions on the resource file was set when it was copied for 5940 // non forward locked apps and apps on sdcard 5941 } 5942 5943 if (retCode != 0) { 5944 Slog.e(TAG, "Couldn't set new package file permissions for " + 5945 newPackage.mPath 5946 + ". The return code was: " + retCode); 5947 // TODO Define new internal error 5948 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5949 } 5950 return PackageManager.INSTALL_SUCCEEDED; 5951 } 5952 5953 private static boolean isForwardLocked(PackageParser.Package pkg) { 5954 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 5955 } 5956 5957 private static boolean isExternal(PackageParser.Package pkg) { 5958 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 5959 } 5960 5961 private static boolean isSystemApp(PackageParser.Package pkg) { 5962 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 5963 } 5964 5965 private static boolean isSystemApp(ApplicationInfo info) { 5966 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 5967 } 5968 5969 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) { 5970 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 5971 } 5972 5973 private void extractPublicFiles(PackageParser.Package newPackage, 5974 File publicZipFile) throws IOException { 5975 final FileOutputStream fstr = new FileOutputStream(publicZipFile); 5976 final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr); 5977 final ZipFile privateZip = new ZipFile(newPackage.mPath); 5978 5979 // Copy manifest, resources.arsc and res directory to public zip 5980 5981 final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries(); 5982 while (privateZipEntries.hasMoreElements()) { 5983 final ZipEntry zipEntry = privateZipEntries.nextElement(); 5984 final String zipEntryName = zipEntry.getName(); 5985 if ("AndroidManifest.xml".equals(zipEntryName) 5986 || "resources.arsc".equals(zipEntryName) 5987 || zipEntryName.startsWith("res/")) { 5988 try { 5989 copyZipEntry(zipEntry, privateZip, publicZipOutStream); 5990 } catch (IOException e) { 5991 try { 5992 publicZipOutStream.close(); 5993 throw e; 5994 } finally { 5995 publicZipFile.delete(); 5996 } 5997 } 5998 } 5999 } 6000 6001 publicZipOutStream.finish(); 6002 publicZipOutStream.flush(); 6003 FileUtils.sync(fstr); 6004 publicZipOutStream.close(); 6005 FileUtils.setPermissions( 6006 publicZipFile.getAbsolutePath(), 6007 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP|FileUtils.S_IROTH, 6008 -1, -1); 6009 } 6010 6011 private static void copyZipEntry(ZipEntry zipEntry, 6012 ZipFile inZipFile, 6013 ZipOutputStream outZipStream) throws IOException { 6014 byte[] buffer = new byte[4096]; 6015 int num; 6016 6017 ZipEntry newEntry; 6018 if (zipEntry.getMethod() == ZipEntry.STORED) { 6019 // Preserve the STORED method of the input entry. 6020 newEntry = new ZipEntry(zipEntry); 6021 } else { 6022 // Create a new entry so that the compressed len is recomputed. 6023 newEntry = new ZipEntry(zipEntry.getName()); 6024 } 6025 outZipStream.putNextEntry(newEntry); 6026 6027 InputStream data = inZipFile.getInputStream(zipEntry); 6028 while ((num = data.read(buffer)) > 0) { 6029 outZipStream.write(buffer, 0, num); 6030 } 6031 outZipStream.flush(); 6032 } 6033 6034 private void deleteTempPackageFiles() { 6035 FilenameFilter filter = new FilenameFilter() { 6036 public boolean accept(File dir, String name) { 6037 return name.startsWith("vmdl") && name.endsWith(".tmp"); 6038 } 6039 }; 6040 String tmpFilesList[] = mAppInstallDir.list(filter); 6041 if(tmpFilesList == null) { 6042 return; 6043 } 6044 for(int i = 0; i < tmpFilesList.length; i++) { 6045 File tmpFile = new File(mAppInstallDir, tmpFilesList[i]); 6046 tmpFile.delete(); 6047 } 6048 } 6049 6050 private File createTempPackageFile(File installDir) { 6051 File tmpPackageFile; 6052 try { 6053 tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir); 6054 } catch (IOException e) { 6055 Slog.e(TAG, "Couldn't create temp file for downloaded package file."); 6056 return null; 6057 } 6058 try { 6059 FileUtils.setPermissions( 6060 tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR, 6061 -1, -1); 6062 } catch (IOException e) { 6063 Slog.e(TAG, "Trouble getting the canoncical path for a temp file."); 6064 return null; 6065 } 6066 return tmpPackageFile; 6067 } 6068 6069 public void deletePackage(final String packageName, 6070 final IPackageDeleteObserver observer, 6071 final int flags) { 6072 mContext.enforceCallingOrSelfPermission( 6073 android.Manifest.permission.DELETE_PACKAGES, null); 6074 // Queue up an async operation since the package deletion may take a little while. 6075 mHandler.post(new Runnable() { 6076 public void run() { 6077 mHandler.removeCallbacks(this); 6078 final boolean succeded = deletePackageX(packageName, true, true, flags); 6079 if (observer != null) { 6080 try { 6081 observer.packageDeleted(succeded); 6082 } catch (RemoteException e) { 6083 Log.i(TAG, "Observer no longer exists."); 6084 } //end catch 6085 } //end if 6086 } //end run 6087 }); 6088 } 6089 6090 /** 6091 * This method is an internal method that could be get invoked either 6092 * to delete an installed package or to clean up a failed installation. 6093 * After deleting an installed package, a broadcast is sent to notify any 6094 * listeners that the package has been installed. For cleaning up a failed 6095 * installation, the broadcast is not necessary since the package's 6096 * installation wouldn't have sent the initial broadcast either 6097 * The key steps in deleting a package are 6098 * deleting the package information in internal structures like mPackages, 6099 * deleting the packages base directories through installd 6100 * updating mSettings to reflect current status 6101 * persisting settings for later use 6102 * sending a broadcast if necessary 6103 */ 6104 private boolean deletePackageX(String packageName, boolean sendBroadCast, 6105 boolean deleteCodeAndResources, int flags) { 6106 PackageRemovedInfo info = new PackageRemovedInfo(); 6107 boolean res; 6108 6109 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 6110 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 6111 try { 6112 if (dpm != null && dpm.packageHasActiveAdmins(packageName)) { 6113 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 6114 return false; 6115 } 6116 } catch (RemoteException e) { 6117 } 6118 6119 synchronized (mInstallLock) { 6120 res = deletePackageLI(packageName, deleteCodeAndResources, 6121 flags | REMOVE_CHATTY, info, true); 6122 } 6123 6124 if(res && sendBroadCast) { 6125 boolean systemUpdate = info.isRemovedPackageSystemUpdate; 6126 info.sendBroadcast(deleteCodeAndResources, systemUpdate); 6127 6128 // If the removed package was a system update, the old system packaged 6129 // was re-enabled; we need to broadcast this information 6130 if (systemUpdate) { 6131 Bundle extras = new Bundle(1); 6132 extras.putInt(Intent.EXTRA_UID, info.removedUid >= 0 ? info.removedUid : info.uid); 6133 extras.putBoolean(Intent.EXTRA_REPLACING, true); 6134 6135 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, extras, null); 6136 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, extras, null); 6137 } 6138 } 6139 // Force a gc here. 6140 Runtime.getRuntime().gc(); 6141 // Delete the resources here after sending the broadcast to let 6142 // other processes clean up before deleting resources. 6143 if (info.args != null) { 6144 synchronized (mInstallLock) { 6145 info.args.doPostDeleteLI(deleteCodeAndResources); 6146 } 6147 } 6148 return res; 6149 } 6150 6151 static class PackageRemovedInfo { 6152 String removedPackage; 6153 int uid = -1; 6154 int removedUid = -1; 6155 boolean isRemovedPackageSystemUpdate = false; 6156 // Clean up resources deleted packages. 6157 InstallArgs args = null; 6158 6159 void sendBroadcast(boolean fullRemove, boolean replacing) { 6160 Bundle extras = new Bundle(1); 6161 extras.putInt(Intent.EXTRA_UID, removedUid >= 0 ? removedUid : uid); 6162 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 6163 if (replacing) { 6164 extras.putBoolean(Intent.EXTRA_REPLACING, true); 6165 } 6166 if (removedPackage != null) { 6167 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, extras, null); 6168 } 6169 if (removedUid >= 0) { 6170 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null); 6171 } 6172 } 6173 } 6174 6175 /* 6176 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 6177 * flag is not set, the data directory is removed as well. 6178 * make sure this flag is set for partially installed apps. If not its meaningless to 6179 * delete a partially installed application. 6180 */ 6181 private void removePackageDataLI(PackageParser.Package p, PackageRemovedInfo outInfo, 6182 int flags, boolean writeSettings) { 6183 String packageName = p.packageName; 6184 if (outInfo != null) { 6185 outInfo.removedPackage = packageName; 6186 } 6187 removePackageLI(p, (flags&REMOVE_CHATTY) != 0); 6188 // Retrieve object to delete permissions for shared user later on 6189 PackageSetting deletedPs; 6190 synchronized (mPackages) { 6191 deletedPs = mSettings.mPackages.get(packageName); 6192 } 6193 if ((flags&PackageManager.DONT_DELETE_DATA) == 0) { 6194 boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p); 6195 if (mInstaller != null) { 6196 int retCode = mInstaller.remove(packageName, useEncryptedFSDir); 6197 if (retCode < 0) { 6198 Slog.w(TAG, "Couldn't remove app data or cache directory for package: " 6199 + packageName + ", retcode=" + retCode); 6200 // we don't consider this to be a failure of the core package deletion 6201 } 6202 } else { 6203 // for simulator 6204 PackageParser.Package pkg = mPackages.get(packageName); 6205 File dataDir = new File(pkg.applicationInfo.dataDir); 6206 dataDir.delete(); 6207 } 6208 schedulePackageCleaning(packageName); 6209 } 6210 synchronized (mPackages) { 6211 if (deletedPs != null) { 6212 if ((flags&PackageManager.DONT_DELETE_DATA) == 0) { 6213 if (outInfo != null) { 6214 outInfo.removedUid = mSettings.removePackageLP(packageName); 6215 } 6216 if (deletedPs != null) { 6217 updatePermissionsLP(deletedPs.name, null, false, false, false); 6218 if (deletedPs.sharedUser != null) { 6219 // remove permissions associated with package 6220 mSettings.updateSharedUserPermsLP(deletedPs, mGlobalGids); 6221 } 6222 } 6223 } 6224 // remove from preferred activities. 6225 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 6226 for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) { 6227 if (pa.mActivity.getPackageName().equals(deletedPs.name)) { 6228 removed.add(pa); 6229 } 6230 } 6231 for (PreferredActivity pa : removed) { 6232 mSettings.mPreferredActivities.removeFilter(pa); 6233 } 6234 } 6235 if (writeSettings) { 6236 // Save settings now 6237 mSettings.writeLP(); 6238 } 6239 } 6240 } 6241 6242 /* 6243 * Tries to delete system package. 6244 */ 6245 private boolean deleteSystemPackageLI(PackageParser.Package p, 6246 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 6247 ApplicationInfo applicationInfo = p.applicationInfo; 6248 //applicable for non-partially installed applications only 6249 if (applicationInfo == null) { 6250 Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo."); 6251 return false; 6252 } 6253 PackageSetting ps = null; 6254 // Confirm if the system package has been updated 6255 // An updated system app can be deleted. This will also have to restore 6256 // the system pkg from system partition 6257 synchronized (mPackages) { 6258 ps = mSettings.getDisabledSystemPkg(p.packageName); 6259 } 6260 if (ps == null) { 6261 Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName); 6262 return false; 6263 } else { 6264 Log.i(TAG, "Deleting system pkg from data partition"); 6265 } 6266 // Delete the updated package 6267 outInfo.isRemovedPackageSystemUpdate = true; 6268 if (ps.versionCode < p.mVersionCode) { 6269 // Delete data for downgrades 6270 flags &= ~PackageManager.DONT_DELETE_DATA; 6271 } else { 6272 // Preserve data by setting flag 6273 flags |= PackageManager.DONT_DELETE_DATA; 6274 } 6275 boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo, 6276 writeSettings); 6277 if (!ret) { 6278 return false; 6279 } 6280 synchronized (mPackages) { 6281 // Reinstate the old system package 6282 mSettings.enableSystemPackageLP(p.packageName); 6283 // Remove any native libraries from the upgraded package. 6284 NativeLibraryHelper.removeNativeBinariesLI(p.applicationInfo.nativeLibraryDir); 6285 } 6286 // Install the system package 6287 PackageParser.Package newPkg = scanPackageLI(ps.codePath, 6288 PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM, 6289 SCAN_MONITOR | SCAN_NO_PATHS, 0); 6290 6291 if (newPkg == null) { 6292 Slog.w(TAG, "Failed to restore system package:"+p.packageName+" with error:" + mLastScanError); 6293 return false; 6294 } 6295 synchronized (mPackages) { 6296 updatePermissionsLP(newPkg.packageName, newPkg, true, true, false); 6297 if (writeSettings) { 6298 mSettings.writeLP(); 6299 } 6300 } 6301 return true; 6302 } 6303 6304 private boolean deleteInstalledPackageLI(PackageParser.Package p, 6305 boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo, 6306 boolean writeSettings) { 6307 ApplicationInfo applicationInfo = p.applicationInfo; 6308 if (applicationInfo == null) { 6309 Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo."); 6310 return false; 6311 } 6312 if (outInfo != null) { 6313 outInfo.uid = applicationInfo.uid; 6314 } 6315 6316 // Delete package data from internal structures and also remove data if flag is set 6317 removePackageDataLI(p, outInfo, flags, writeSettings); 6318 6319 // Delete application code and resources 6320 if (deleteCodeAndResources) { 6321 // TODO can pick up from PackageSettings as well 6322 int installFlags = isExternal(p) ? PackageManager.INSTALL_EXTERNAL : 0; 6323 installFlags |= isForwardLocked(p) ? PackageManager.INSTALL_FORWARD_LOCK : 0; 6324 outInfo.args = createInstallArgs(installFlags, applicationInfo.sourceDir, 6325 applicationInfo.publicSourceDir, applicationInfo.nativeLibraryDir); 6326 } 6327 return true; 6328 } 6329 6330 /* 6331 * This method handles package deletion in general 6332 */ 6333 private boolean deletePackageLI(String packageName, 6334 boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo, 6335 boolean writeSettings) { 6336 if (packageName == null) { 6337 Slog.w(TAG, "Attempt to delete null packageName."); 6338 return false; 6339 } 6340 PackageParser.Package p; 6341 boolean dataOnly = false; 6342 synchronized (mPackages) { 6343 p = mPackages.get(packageName); 6344 if (p == null) { 6345 //this retrieves partially installed apps 6346 dataOnly = true; 6347 PackageSetting ps = mSettings.mPackages.get(packageName); 6348 if (ps == null) { 6349 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 6350 return false; 6351 } 6352 p = ps.pkg; 6353 } 6354 } 6355 if (p == null) { 6356 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 6357 return false; 6358 } 6359 6360 if (dataOnly) { 6361 // Delete application data first 6362 removePackageDataLI(p, outInfo, flags, writeSettings); 6363 return true; 6364 } 6365 // At this point the package should have ApplicationInfo associated with it 6366 if (p.applicationInfo == null) { 6367 Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo."); 6368 return false; 6369 } 6370 boolean ret = false; 6371 if (isSystemApp(p)) { 6372 Log.i(TAG, "Removing system package:"+p.packageName); 6373 // When an updated system application is deleted we delete the existing resources as well and 6374 // fall back to existing code in system partition 6375 ret = deleteSystemPackageLI(p, flags, outInfo, writeSettings); 6376 } else { 6377 Log.i(TAG, "Removing non-system package:"+p.packageName); 6378 // Kill application pre-emptively especially for apps on sd. 6379 killApplication(packageName, p.applicationInfo.uid); 6380 ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo, 6381 writeSettings); 6382 } 6383 return ret; 6384 } 6385 6386 public void clearApplicationUserData(final String packageName, 6387 final IPackageDataObserver observer) { 6388 mContext.enforceCallingOrSelfPermission( 6389 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 6390 // Queue up an async operation since the package deletion may take a little while. 6391 mHandler.post(new Runnable() { 6392 public void run() { 6393 mHandler.removeCallbacks(this); 6394 final boolean succeeded; 6395 synchronized (mInstallLock) { 6396 succeeded = clearApplicationUserDataLI(packageName); 6397 } 6398 if (succeeded) { 6399 // invoke DeviceStorageMonitor's update method to clear any notifications 6400 DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) 6401 ServiceManager.getService(DeviceStorageMonitorService.SERVICE); 6402 if (dsm != null) { 6403 dsm.updateMemory(); 6404 } 6405 } 6406 if(observer != null) { 6407 try { 6408 observer.onRemoveCompleted(packageName, succeeded); 6409 } catch (RemoteException e) { 6410 Log.i(TAG, "Observer no longer exists."); 6411 } 6412 } //end if observer 6413 } //end run 6414 }); 6415 } 6416 6417 private boolean clearApplicationUserDataLI(String packageName) { 6418 if (packageName == null) { 6419 Slog.w(TAG, "Attempt to delete null packageName."); 6420 return false; 6421 } 6422 PackageParser.Package p; 6423 boolean dataOnly = false; 6424 synchronized (mPackages) { 6425 p = mPackages.get(packageName); 6426 if(p == null) { 6427 dataOnly = true; 6428 PackageSetting ps = mSettings.mPackages.get(packageName); 6429 if((ps == null) || (ps.pkg == null)) { 6430 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 6431 return false; 6432 } 6433 p = ps.pkg; 6434 } 6435 } 6436 boolean useEncryptedFSDir = false; 6437 6438 if(!dataOnly) { 6439 //need to check this only for fully installed applications 6440 if (p == null) { 6441 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 6442 return false; 6443 } 6444 final ApplicationInfo applicationInfo = p.applicationInfo; 6445 if (applicationInfo == null) { 6446 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 6447 return false; 6448 } 6449 useEncryptedFSDir = useEncryptedFilesystemForPackage(p); 6450 } 6451 if (mInstaller != null) { 6452 int retCode = mInstaller.clearUserData(packageName, useEncryptedFSDir); 6453 if (retCode < 0) { 6454 Slog.w(TAG, "Couldn't remove cache files for package: " 6455 + packageName); 6456 return false; 6457 } 6458 } 6459 return true; 6460 } 6461 6462 public void deleteApplicationCacheFiles(final String packageName, 6463 final IPackageDataObserver observer) { 6464 mContext.enforceCallingOrSelfPermission( 6465 android.Manifest.permission.DELETE_CACHE_FILES, null); 6466 // Queue up an async operation since the package deletion may take a little while. 6467 mHandler.post(new Runnable() { 6468 public void run() { 6469 mHandler.removeCallbacks(this); 6470 final boolean succeded; 6471 synchronized (mInstallLock) { 6472 succeded = deleteApplicationCacheFilesLI(packageName); 6473 } 6474 if(observer != null) { 6475 try { 6476 observer.onRemoveCompleted(packageName, succeded); 6477 } catch (RemoteException e) { 6478 Log.i(TAG, "Observer no longer exists."); 6479 } 6480 } //end if observer 6481 } //end run 6482 }); 6483 } 6484 6485 private boolean deleteApplicationCacheFilesLI(String packageName) { 6486 if (packageName == null) { 6487 Slog.w(TAG, "Attempt to delete null packageName."); 6488 return false; 6489 } 6490 PackageParser.Package p; 6491 synchronized (mPackages) { 6492 p = mPackages.get(packageName); 6493 } 6494 if (p == null) { 6495 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 6496 return false; 6497 } 6498 final ApplicationInfo applicationInfo = p.applicationInfo; 6499 if (applicationInfo == null) { 6500 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 6501 return false; 6502 } 6503 boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p); 6504 if (mInstaller != null) { 6505 int retCode = mInstaller.deleteCacheFiles(packageName, useEncryptedFSDir); 6506 if (retCode < 0) { 6507 Slog.w(TAG, "Couldn't remove cache files for package: " 6508 + packageName); 6509 return false; 6510 } 6511 } 6512 return true; 6513 } 6514 6515 public void getPackageSizeInfo(final String packageName, 6516 final IPackageStatsObserver observer) { 6517 mContext.enforceCallingOrSelfPermission( 6518 android.Manifest.permission.GET_PACKAGE_SIZE, null); 6519 // Queue up an async operation since the package deletion may take a little while. 6520 mHandler.post(new Runnable() { 6521 public void run() { 6522 mHandler.removeCallbacks(this); 6523 PackageStats lStats = new PackageStats(packageName); 6524 final boolean succeded; 6525 synchronized (mInstallLock) { 6526 succeded = getPackageSizeInfoLI(packageName, lStats); 6527 } 6528 if(observer != null) { 6529 try { 6530 observer.onGetStatsCompleted(lStats, succeded); 6531 } catch (RemoteException e) { 6532 Log.i(TAG, "Observer no longer exists."); 6533 } 6534 } //end if observer 6535 } //end run 6536 }); 6537 } 6538 6539 private boolean getPackageSizeInfoLI(String packageName, PackageStats pStats) { 6540 if (packageName == null) { 6541 Slog.w(TAG, "Attempt to get size of null packageName."); 6542 return false; 6543 } 6544 PackageParser.Package p; 6545 boolean dataOnly = false; 6546 synchronized (mPackages) { 6547 p = mPackages.get(packageName); 6548 if(p == null) { 6549 dataOnly = true; 6550 PackageSetting ps = mSettings.mPackages.get(packageName); 6551 if((ps == null) || (ps.pkg == null)) { 6552 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 6553 return false; 6554 } 6555 p = ps.pkg; 6556 } 6557 } 6558 String publicSrcDir = null; 6559 if(!dataOnly) { 6560 final ApplicationInfo applicationInfo = p.applicationInfo; 6561 if (applicationInfo == null) { 6562 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 6563 return false; 6564 } 6565 publicSrcDir = isForwardLocked(p) ? applicationInfo.publicSourceDir : null; 6566 } 6567 boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p); 6568 if (mInstaller != null) { 6569 int res = mInstaller.getSizeInfo(packageName, p.mPath, 6570 publicSrcDir, pStats, useEncryptedFSDir); 6571 if (res < 0) { 6572 return false; 6573 } else { 6574 return true; 6575 } 6576 } 6577 return true; 6578 } 6579 6580 6581 public void addPackageToPreferred(String packageName) { 6582 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 6583 } 6584 6585 public void removePackageFromPreferred(String packageName) { 6586 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 6587 } 6588 6589 public List<PackageInfo> getPreferredPackages(int flags) { 6590 return new ArrayList<PackageInfo>(); 6591 } 6592 6593 int getUidTargetSdkVersionLockedLP(int uid) { 6594 Object obj = mSettings.getUserIdLP(uid); 6595 if (obj instanceof SharedUserSetting) { 6596 SharedUserSetting sus = (SharedUserSetting)obj; 6597 final int N = sus.packages.size(); 6598 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 6599 Iterator<PackageSetting> it = sus.packages.iterator(); 6600 int i=0; 6601 while (it.hasNext()) { 6602 PackageSetting ps = it.next(); 6603 if (ps.pkg != null) { 6604 int v = ps.pkg.applicationInfo.targetSdkVersion; 6605 if (v < vers) vers = v; 6606 } 6607 } 6608 return vers; 6609 } else if (obj instanceof PackageSetting) { 6610 PackageSetting ps = (PackageSetting)obj; 6611 if (ps.pkg != null) { 6612 return ps.pkg.applicationInfo.targetSdkVersion; 6613 } 6614 } 6615 return Build.VERSION_CODES.CUR_DEVELOPMENT; 6616 } 6617 6618 public void addPreferredActivity(IntentFilter filter, int match, 6619 ComponentName[] set, ComponentName activity) { 6620 synchronized (mPackages) { 6621 if (mContext.checkCallingOrSelfPermission( 6622 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 6623 != PackageManager.PERMISSION_GRANTED) { 6624 if (getUidTargetSdkVersionLockedLP(Binder.getCallingUid()) 6625 < Build.VERSION_CODES.FROYO) { 6626 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 6627 + Binder.getCallingUid()); 6628 return; 6629 } 6630 mContext.enforceCallingOrSelfPermission( 6631 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 6632 } 6633 6634 Slog.i(TAG, "Adding preferred activity " + activity + ":"); 6635 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 6636 mSettings.mPreferredActivities.addFilter( 6637 new PreferredActivity(filter, match, set, activity)); 6638