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