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