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 (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 2166 List<PreferredActivity> prefs = 2167 mSettings.mPreferredActivities.queryIntent(intent, resolvedType, 2168 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); 2169 if (prefs != null && prefs.size() > 0) { 2170 // First figure out how good the original match set is. 2171 // We will only allow preferred activities that came 2172 // from the same match quality. 2173 int match = 0; 2174 2175 if (DEBUG_PREFERRED) { 2176 Log.v(TAG, "Figuring out best match..."); 2177 } 2178 2179 final int N = query.size(); 2180 for (int j=0; j<N; j++) { 2181 final ResolveInfo ri = query.get(j); 2182 if (DEBUG_PREFERRED) { 2183 Log.v(TAG, "Match for " + ri.activityInfo + ": 0x" 2184 + Integer.toHexString(match)); 2185 } 2186 if (ri.match > match) { 2187 match = ri.match; 2188 } 2189 } 2190 2191 if (DEBUG_PREFERRED) { 2192 Log.v(TAG, "Best match: 0x" + Integer.toHexString(match)); 2193 } 2194 2195 match &= IntentFilter.MATCH_CATEGORY_MASK; 2196 final int M = prefs.size(); 2197 for (int i=0; i<M; i++) { 2198 final PreferredActivity pa = prefs.get(i); 2199 if (pa.mPref.mMatch != match) { 2200 continue; 2201 } 2202 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, flags); 2203 if (DEBUG_PREFERRED) { 2204 Log.v(TAG, "Got preferred activity:"); 2205 if (ai != null) { 2206 ai.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 2207 } else { 2208 Log.v(TAG, " null"); 2209 } 2210 } 2211 if (ai != null) { 2212 for (int j=0; j<N; j++) { 2213 final ResolveInfo ri = query.get(j); 2214 if (!ri.activityInfo.applicationInfo.packageName 2215 .equals(ai.applicationInfo.packageName)) { 2216 continue; 2217 } 2218 if (!ri.activityInfo.name.equals(ai.name)) { 2219 continue; 2220 } 2221 2222 // Okay we found a previously set preferred app. 2223 // If the result set is different from when this 2224 // was created, we need to clear it and re-ask the 2225 // user their preference. 2226 if (!pa.mPref.sameSet(query, priority)) { 2227 Slog.i(TAG, "Result set changed, dropping preferred activity for " 2228 + intent + " type " + resolvedType); 2229 mSettings.mPreferredActivities.removeFilter(pa); 2230 return null; 2231 } 2232 2233 // Yay! 2234 return ri; 2235 } 2236 } 2237 } 2238 } 2239 } 2240 return null; 2241 } 2242 2243 public List<ResolveInfo> queryIntentActivities(Intent intent, 2244 String resolvedType, int flags) { 2245 final ComponentName comp = intent.getComponent(); 2246 if (comp != null) { 2247 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 2248 final ActivityInfo ai = getActivityInfo(comp, flags); 2249 if (ai != null) { 2250 final ResolveInfo ri = new ResolveInfo(); 2251 ri.activityInfo = ai; 2252 list.add(ri); 2253 } 2254 return list; 2255 } 2256 2257 // reader 2258 synchronized (mPackages) { 2259 final String pkgName = intent.getPackage(); 2260 if (pkgName == null) { 2261 return mActivities.queryIntent(intent, resolvedType, flags); 2262 } 2263 final PackageParser.Package pkg = mPackages.get(pkgName); 2264 if (pkg != null) { 2265 return mActivities.queryIntentForPackage(intent, resolvedType, flags, 2266 pkg.activities); 2267 } 2268 return new ArrayList<ResolveInfo>(); 2269 } 2270 } 2271 2272 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 2273 Intent[] specifics, String[] specificTypes, Intent intent, 2274 String resolvedType, int flags) { 2275 final String resultsAction = intent.getAction(); 2276 2277 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 2278 | PackageManager.GET_RESOLVED_FILTER); 2279 2280 if (DEBUG_INTENT_MATCHING) { 2281 Log.v(TAG, "Query " + intent + ": " + results); 2282 } 2283 2284 int specificsPos = 0; 2285 int N; 2286 2287 // todo: note that the algorithm used here is O(N^2). This 2288 // isn't a problem in our current environment, but if we start running 2289 // into situations where we have more than 5 or 10 matches then this 2290 // should probably be changed to something smarter... 2291 2292 // First we go through and resolve each of the specific items 2293 // that were supplied, taking care of removing any corresponding 2294 // duplicate items in the generic resolve list. 2295 if (specifics != null) { 2296 for (int i=0; i<specifics.length; i++) { 2297 final Intent sintent = specifics[i]; 2298 if (sintent == null) { 2299 continue; 2300 } 2301 2302 if (DEBUG_INTENT_MATCHING) { 2303 Log.v(TAG, "Specific #" + i + ": " + sintent); 2304 } 2305 2306 String action = sintent.getAction(); 2307 if (resultsAction != null && resultsAction.equals(action)) { 2308 // If this action was explicitly requested, then don't 2309 // remove things that have it. 2310 action = null; 2311 } 2312 2313 ResolveInfo ri = null; 2314 ActivityInfo ai = null; 2315 2316 ComponentName comp = sintent.getComponent(); 2317 if (comp == null) { 2318 ri = resolveIntent( 2319 sintent, 2320 specificTypes != null ? specificTypes[i] : null, 2321 flags); 2322 if (ri == null) { 2323 continue; 2324 } 2325 if (ri == mResolveInfo) { 2326 // ACK! Must do something better with this. 2327 } 2328 ai = ri.activityInfo; 2329 comp = new ComponentName(ai.applicationInfo.packageName, 2330 ai.name); 2331 } else { 2332 ai = getActivityInfo(comp, flags); 2333 if (ai == null) { 2334 continue; 2335 } 2336 } 2337 2338 // Look for any generic query activities that are duplicates 2339 // of this specific one, and remove them from the results. 2340 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 2341 N = results.size(); 2342 int j; 2343 for (j=specificsPos; j<N; j++) { 2344 ResolveInfo sri = results.get(j); 2345 if ((sri.activityInfo.name.equals(comp.getClassName()) 2346 && sri.activityInfo.applicationInfo.packageName.equals( 2347 comp.getPackageName())) 2348 || (action != null && sri.filter.matchAction(action))) { 2349 results.remove(j); 2350 if (DEBUG_INTENT_MATCHING) Log.v( 2351 TAG, "Removing duplicate item from " + j 2352 + " due to specific " + specificsPos); 2353 if (ri == null) { 2354 ri = sri; 2355 } 2356 j--; 2357 N--; 2358 } 2359 } 2360 2361 // Add this specific item to its proper place. 2362 if (ri == null) { 2363 ri = new ResolveInfo(); 2364 ri.activityInfo = ai; 2365 } 2366 results.add(specificsPos, ri); 2367 ri.specificIndex = i; 2368 specificsPos++; 2369 } 2370 } 2371 2372 // Now we go through the remaining generic results and remove any 2373 // duplicate actions that are found here. 2374 N = results.size(); 2375 for (int i=specificsPos; i<N-1; i++) { 2376 final ResolveInfo rii = results.get(i); 2377 if (rii.filter == null) { 2378 continue; 2379 } 2380 2381 // Iterate over all of the actions of this result's intent 2382 // filter... typically this should be just one. 2383 final Iterator<String> it = rii.filter.actionsIterator(); 2384 if (it == null) { 2385 continue; 2386 } 2387 while (it.hasNext()) { 2388 final String action = it.next(); 2389 if (resultsAction != null && resultsAction.equals(action)) { 2390 // If this action was explicitly requested, then don't 2391 // remove things that have it. 2392 continue; 2393 } 2394 for (int j=i+1; j<N; j++) { 2395 final ResolveInfo rij = results.get(j); 2396 if (rij.filter != null && rij.filter.hasAction(action)) { 2397 results.remove(j); 2398 if (DEBUG_INTENT_MATCHING) Log.v( 2399 TAG, "Removing duplicate item from " + j 2400 + " due to action " + action + " at " + i); 2401 j--; 2402 N--; 2403 } 2404 } 2405 } 2406 2407 // If the caller didn't request filter information, drop it now 2408 // so we don't have to marshall/unmarshall it. 2409 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 2410 rii.filter = null; 2411 } 2412 } 2413 2414 // Filter out the caller activity if so requested. 2415 if (caller != null) { 2416 N = results.size(); 2417 for (int i=0; i<N; i++) { 2418 ActivityInfo ainfo = results.get(i).activityInfo; 2419 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 2420 && caller.getClassName().equals(ainfo.name)) { 2421 results.remove(i); 2422 break; 2423 } 2424 } 2425 } 2426 2427 // If the caller didn't request filter information, 2428 // drop them now so we don't have to 2429 // marshall/unmarshall it. 2430 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 2431 N = results.size(); 2432 for (int i=0; i<N; i++) { 2433 results.get(i).filter = null; 2434 } 2435 } 2436 2437 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 2438 return results; 2439 } 2440 2441 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags) { 2442 ComponentName comp = intent.getComponent(); 2443 if (comp != null) { 2444 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 2445 ActivityInfo ai = getReceiverInfo(comp, flags); 2446 if (ai != null) { 2447 ResolveInfo ri = new ResolveInfo(); 2448 ri.activityInfo = ai; 2449 list.add(ri); 2450 } 2451 return list; 2452 } 2453 2454 // reader 2455 synchronized (mPackages) { 2456 String pkgName = intent.getPackage(); 2457 if (pkgName == null) { 2458 return mReceivers.queryIntent(intent, resolvedType, flags); 2459 } 2460 final PackageParser.Package pkg = mPackages.get(pkgName); 2461 if (pkg != null) { 2462 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers); 2463 } 2464 return null; 2465 } 2466 } 2467 2468 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags) { 2469 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags); 2470 if (query != null) { 2471 if (query.size() >= 1) { 2472 // If there is more than one service with the same priority, 2473 // just arbitrarily pick the first one. 2474 return query.get(0); 2475 } 2476 } 2477 return null; 2478 } 2479 2480 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags) { 2481 final ComponentName comp = intent.getComponent(); 2482 if (comp != null) { 2483 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 2484 final ServiceInfo si = getServiceInfo(comp, flags); 2485 if (si != null) { 2486 final ResolveInfo ri = new ResolveInfo(); 2487 ri.serviceInfo = si; 2488 list.add(ri); 2489 } 2490 return list; 2491 } 2492 2493 // reader 2494 synchronized (mPackages) { 2495 String pkgName = intent.getPackage(); 2496 if (pkgName == null) { 2497 return mServices.queryIntent(intent, resolvedType, flags); 2498 } 2499 final PackageParser.Package pkg = mPackages.get(pkgName); 2500 if (pkg != null) { 2501 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services); 2502 } 2503 return null; 2504 } 2505 } 2506 2507 private static final int getContinuationPoint(final String[] keys, final String key) { 2508 final int index; 2509 if (key == null) { 2510 index = 0; 2511 } else { 2512 final int insertPoint = Arrays.binarySearch(keys, key); 2513 if (insertPoint < 0) { 2514 index = -insertPoint; 2515 } else { 2516 index = insertPoint + 1; 2517 } 2518 } 2519 return index; 2520 } 2521 2522 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead) { 2523 final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>(); 2524 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 2525 final String[] keys; 2526 2527 // writer 2528 synchronized (mPackages) { 2529 if (listUninstalled) { 2530 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]); 2531 } else { 2532 keys = mPackages.keySet().toArray(new String[mPackages.size()]); 2533 } 2534 2535 Arrays.sort(keys); 2536 int i = getContinuationPoint(keys, lastRead); 2537 final int N = keys.length; 2538 2539 while (i < N) { 2540 final String packageName = keys[i++]; 2541 2542 PackageInfo pi = null; 2543 if (listUninstalled) { 2544 final PackageSetting ps = mSettings.mPackages.get(packageName); 2545 if (ps != null) { 2546 pi = generatePackageInfoFromSettingsLPw(ps.name, flags); 2547 } 2548 } else { 2549 final PackageParser.Package p = mPackages.get(packageName); 2550 if (p != null) { 2551 pi = generatePackageInfo(p, flags); 2552 } 2553 } 2554 2555 if (pi != null && !list.append(pi)) { 2556 break; 2557 } 2558 } 2559 2560 if (i == N) { 2561 list.setLastSlice(true); 2562 } 2563 } 2564 2565 return list; 2566 } 2567 2568 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, 2569 String lastRead) { 2570 final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>(); 2571 final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; 2572 final String[] keys; 2573 2574 // writer 2575 synchronized (mPackages) { 2576 if (listUninstalled) { 2577 keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]); 2578 } else { 2579 keys = mPackages.keySet().toArray(new String[mPackages.size()]); 2580 } 2581 2582 Arrays.sort(keys); 2583 int i = getContinuationPoint(keys, lastRead); 2584 final int N = keys.length; 2585 2586 while (i < N) { 2587 final String packageName = keys[i++]; 2588 2589 ApplicationInfo ai = null; 2590 if (listUninstalled) { 2591 final PackageSetting ps = mSettings.mPackages.get(packageName); 2592 if (ps != null) { 2593 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags); 2594 } 2595 } else { 2596 final PackageParser.Package p = mPackages.get(packageName); 2597 if (p != null) { 2598 ai = PackageParser.generateApplicationInfo(p, flags); 2599 } 2600 } 2601 2602 if (ai != null && !list.append(ai)) { 2603 break; 2604 } 2605 } 2606 2607 if (i == N) { 2608 list.setLastSlice(true); 2609 } 2610 } 2611 2612 return list; 2613 } 2614 2615 public List<ApplicationInfo> getPersistentApplications(int flags) { 2616 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 2617 2618 // reader 2619 synchronized (mPackages) { 2620 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 2621 while (i.hasNext()) { 2622 final PackageParser.Package p = i.next(); 2623 if (p.applicationInfo != null 2624 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 2625 && (!mSafeMode || isSystemApp(p))) { 2626 finalList.add(PackageParser.generateApplicationInfo(p, flags)); 2627 } 2628 } 2629 } 2630 2631 return finalList; 2632 } 2633 2634 public ProviderInfo resolveContentProvider(String name, int flags) { 2635 // reader 2636 synchronized (mPackages) { 2637 final PackageParser.Provider provider = mProviders.get(name); 2638 return provider != null 2639 && mSettings.isEnabledLPr(provider.info, flags) 2640 && (!mSafeMode || (provider.info.applicationInfo.flags 2641 &ApplicationInfo.FLAG_SYSTEM) != 0) 2642 ? PackageParser.generateProviderInfo(provider, flags) 2643 : null; 2644 } 2645 } 2646 2647 /** 2648 * @deprecated 2649 */ 2650 @Deprecated 2651 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 2652 // reader 2653 synchronized (mPackages) { 2654 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProviders.entrySet() 2655 .iterator(); 2656 2657 while (i.hasNext()) { 2658 Map.Entry<String, PackageParser.Provider> entry = i.next(); 2659 PackageParser.Provider p = entry.getValue(); 2660 2661 if (p.syncable 2662 && (!mSafeMode || (p.info.applicationInfo.flags 2663 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 2664 outNames.add(entry.getKey()); 2665 outInfo.add(PackageParser.generateProviderInfo(p, 0)); 2666 } 2667 } 2668 } 2669 } 2670 2671 public List<ProviderInfo> queryContentProviders(String processName, 2672 int uid, int flags) { 2673 ArrayList<ProviderInfo> finalList = null; 2674 2675 // reader 2676 synchronized (mPackages) { 2677 final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator(); 2678 while (i.hasNext()) { 2679 final PackageParser.Provider p = i.next(); 2680 if (p.info.authority != null 2681 && (processName == null 2682 || (p.info.processName.equals(processName) 2683 && p.info.applicationInfo.uid == uid)) 2684 && mSettings.isEnabledLPr(p.info, flags) 2685 && (!mSafeMode 2686 || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) { 2687 if (finalList == null) { 2688 finalList = new ArrayList<ProviderInfo>(3); 2689 } 2690 finalList.add(PackageParser.generateProviderInfo(p, flags)); 2691 } 2692 } 2693 } 2694 2695 if (finalList != null) { 2696 Collections.sort(finalList, mProviderInitOrderSorter); 2697 } 2698 2699 return finalList; 2700 } 2701 2702 public InstrumentationInfo getInstrumentationInfo(ComponentName name, 2703 int flags) { 2704 // reader 2705 synchronized (mPackages) { 2706 final PackageParser.Instrumentation i = mInstrumentation.get(name); 2707 return PackageParser.generateInstrumentationInfo(i, flags); 2708 } 2709 } 2710 2711 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 2712 int flags) { 2713 ArrayList<InstrumentationInfo> finalList = 2714 new ArrayList<InstrumentationInfo>(); 2715 2716 // reader 2717 synchronized (mPackages) { 2718 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 2719 while (i.hasNext()) { 2720 final PackageParser.Instrumentation p = i.next(); 2721 if (targetPackage == null 2722 || targetPackage.equals(p.info.targetPackage)) { 2723 finalList.add(PackageParser.generateInstrumentationInfo(p, 2724 flags)); 2725 } 2726 } 2727 } 2728 2729 return finalList; 2730 } 2731 2732 private void scanDirLI(File dir, int flags, int scanMode, long currentTime) { 2733 String[] files = dir.list(); 2734 if (files == null) { 2735 Log.d(TAG, "No files in app dir " + dir); 2736 return; 2737 } 2738 2739 if (DEBUG_PACKAGE_SCANNING) { 2740 Log.d(TAG, "Scanning app dir " + dir); 2741 } 2742 2743 int i; 2744 for (i=0; i<files.length; i++) { 2745 File file = new File(dir, files[i]); 2746 if (!isPackageFilename(files[i])) { 2747 // Ignore entries which are not apk's 2748 continue; 2749 } 2750 PackageParser.Package pkg = scanPackageLI(file, 2751 flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime); 2752 // Don't mess around with apps in system partition. 2753 if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 && 2754 mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) { 2755 // Delete the apk 2756 Slog.w(TAG, "Cleaning up failed install of " + file); 2757 file.delete(); 2758 } 2759 } 2760 } 2761 2762 private static File getSettingsProblemFile() { 2763 File dataDir = Environment.getDataDirectory(); 2764 File systemDir = new File(dataDir, "system"); 2765 File fname = new File(systemDir, "uiderrors.txt"); 2766 return fname; 2767 } 2768 2769 static void reportSettingsProblem(int priority, String msg) { 2770 try { 2771 File fname = getSettingsProblemFile(); 2772 FileOutputStream out = new FileOutputStream(fname, true); 2773 PrintWriter pw = new PrintWriter(out); 2774 SimpleDateFormat formatter = new SimpleDateFormat(); 2775 String dateString = formatter.format(new Date(System.currentTimeMillis())); 2776 pw.println(dateString + ": " + msg); 2777 pw.close(); 2778 FileUtils.setPermissions( 2779 fname.toString(), 2780 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 2781 -1, -1); 2782 } catch (java.io.IOException e) { 2783 } 2784 Slog.println(priority, TAG, msg); 2785 } 2786 2787 private boolean collectCertificatesLI(PackageParser pp, PackageSetting ps, 2788 PackageParser.Package pkg, File srcFile, int parseFlags) { 2789 if (GET_CERTIFICATES) { 2790 if (ps != null 2791 && ps.codePath.equals(srcFile) 2792 && ps.timeStamp == srcFile.lastModified()) { 2793 if (ps.signatures.mSignatures != null 2794 && ps.signatures.mSignatures.length != 0) { 2795 // Optimization: reuse the existing cached certificates 2796 // if the package appears to be unchanged. 2797 pkg.mSignatures = ps.signatures.mSignatures; 2798 return true; 2799 } 2800 2801 Slog.w(TAG, "PackageSetting for " + ps.name + " is missing signatures. Collecting certs again to recover them."); 2802 } else { 2803 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 2804 } 2805 2806 if (!pp.collectCertificates(pkg, parseFlags)) { 2807 mLastScanError = pp.getParseError(); 2808 return false; 2809 } 2810 } 2811 return true; 2812 } 2813 2814 /* 2815 * Scan a package and return the newly parsed package. 2816 * Returns null in case of errors and the error code is stored in mLastScanError 2817 */ 2818 private PackageParser.Package scanPackageLI(File scanFile, 2819 int parseFlags, int scanMode, long currentTime) { 2820 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 2821 String scanPath = scanFile.getPath(); 2822 parseFlags |= mDefParseFlags; 2823 PackageParser pp = new PackageParser(scanPath); 2824 pp.setSeparateProcesses(mSeparateProcesses); 2825 pp.setOnlyCoreApps(mOnlyCore); 2826 final PackageParser.Package pkg = pp.parsePackage(scanFile, 2827 scanPath, mMetrics, parseFlags); 2828 if (pkg == null) { 2829 mLastScanError = pp.getParseError(); 2830 return null; 2831 } 2832 PackageSetting ps = null; 2833 PackageSetting updatedPkg; 2834 // reader 2835 synchronized (mPackages) { 2836 // Look to see if we already know about this package. 2837 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 2838 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 2839 // This package has been renamed to its original name. Let's 2840 // use that. 2841 ps = mSettings.peekPackageLPr(oldName); 2842 } 2843 // If there was no original package, see one for the real package name. 2844 if (ps == null) { 2845 ps = mSettings.peekPackageLPr(pkg.packageName); 2846 } 2847 // Check to see if this package could be hiding/updating a system 2848 // package. Must look for it either under the original or real 2849 // package name depending on our state. 2850 updatedPkg = mSettings.mDisabledSysPackages.get( 2851 ps != null ? ps.name : pkg.packageName); 2852 } 2853 // First check if this is a system package that may involve an update 2854 if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 2855 if (ps != null && !ps.codePath.equals(scanFile)) { 2856 // The path has changed from what was last scanned... check the 2857 // version of the new path against what we have stored to determine 2858 // what to do. 2859 if (pkg.mVersionCode < ps.versionCode) { 2860 // The system package has been updated and the code path does not match 2861 // Ignore entry. Skip it. 2862 Log.i(TAG, "Package " + ps.name + " at " + scanFile 2863 + " ignored: updated version " + ps.versionCode 2864 + " better than this " + pkg.mVersionCode); 2865 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 2866 return null; 2867 } else { 2868 // The current app on the system partion is better than 2869 // what we have updated to on the data partition; switch 2870 // back to the system partition version. 2871 // At this point, its safely assumed that package installation for 2872 // apps in system partition will go through. If not there won't be a working 2873 // version of the app 2874 // writer 2875 synchronized (mPackages) { 2876 // Just remove the loaded entries from package lists. 2877 mPackages.remove(ps.name); 2878 } 2879 Slog.w(TAG, "Package " + ps.name + " at " + scanFile 2880 + "reverting from " + ps.codePathString 2881 + ": new version " + pkg.mVersionCode 2882 + " better than installed " + ps.versionCode); 2883 InstallArgs args = new FileInstallArgs(ps.codePathString, 2884 ps.resourcePathString, ps.nativeLibraryPathString); 2885 args.cleanUpResourcesLI(); 2886 mSettings.enableSystemPackageLPw(ps.name); 2887 } 2888 } 2889 } 2890 if (updatedPkg != null) { 2891 // An updated system app will not have the PARSE_IS_SYSTEM flag set initially 2892 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 2893 } 2894 // Verify certificates against what was last scanned 2895 if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) { 2896 Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName); 2897 return null; 2898 } 2899 // The apk is forward locked (not public) if its code and resources 2900 // are kept in different files. 2901 // TODO grab this value from PackageSettings 2902 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 2903 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 2904 } 2905 2906 String codePath = null; 2907 String resPath = null; 2908 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0) { 2909 if (ps != null && ps.resourcePathString != null) { 2910 resPath = ps.resourcePathString; 2911 } else { 2912 // Should not happen at all. Just log an error. 2913 Slog.e(TAG, "Resource path not set for pkg : " + pkg.packageName); 2914 } 2915 } else { 2916 resPath = pkg.mScanPath; 2917 } 2918 codePath = pkg.mScanPath; 2919 // Set application objects path explicitly. 2920 setApplicationInfoPaths(pkg, codePath, resPath); 2921 // Note that we invoke the following method only if we are about to unpack an application 2922 return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime); 2923 } 2924 2925 private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath, 2926 String destResPath) { 2927 pkg.mPath = pkg.mScanPath = destCodePath; 2928 pkg.applicationInfo.sourceDir = destCodePath; 2929 pkg.applicationInfo.publicSourceDir = destResPath; 2930 } 2931 2932 private static String fixProcessName(String defProcessName, 2933 String processName, int uid) { 2934 if (processName == null) { 2935 return defProcessName; 2936 } 2937 return processName; 2938 } 2939 2940 private boolean verifySignaturesLP(PackageSetting pkgSetting, 2941 PackageParser.Package pkg) { 2942 if (pkgSetting.signatures.mSignatures != null) { 2943 // Already existing package. Make sure signatures match 2944 if (compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) != 2945 PackageManager.SIGNATURE_MATCH) { 2946 Slog.e(TAG, "Package " + pkg.packageName 2947 + " signatures do not match the previously installed version; ignoring!"); 2948 mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 2949 return false; 2950 } 2951 } 2952 // Check for shared user signatures 2953 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 2954 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 2955 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 2956 Slog.e(TAG, "Package " + pkg.packageName 2957 + " has no signatures that match those in shared user " 2958 + pkgSetting.sharedUser.name + "; ignoring!"); 2959 mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 2960 return false; 2961 } 2962 } 2963 return true; 2964 } 2965 2966 /** 2967 * Enforces that only the system UID or root's UID can call a method exposed 2968 * via Binder. 2969 * 2970 * @param message used as message if SecurityException is thrown 2971 * @throws SecurityException if the caller is not system or root 2972 */ 2973 private static final void enforceSystemOrRoot(String message) { 2974 final int uid = Binder.getCallingUid(); 2975 if (uid != Process.SYSTEM_UID && uid != 0) { 2976 throw new SecurityException(message); 2977 } 2978 } 2979 2980 public void performBootDexOpt() { 2981 ArrayList<PackageParser.Package> pkgs = null; 2982 synchronized (mPackages) { 2983 if (mDeferredDexOpt.size() > 0) { 2984 pkgs = new ArrayList<PackageParser.Package>(mDeferredDexOpt); 2985 mDeferredDexOpt.clear(); 2986 } 2987 } 2988 if (pkgs != null) { 2989 for (int i=0; i<pkgs.size(); i++) { 2990 if (!isFirstBoot()) { 2991 try { 2992 ActivityManagerNative.getDefault().showBootMessage( 2993 mContext.getResources().getString( 2994 com.android.internal.R.string.android_upgrading_apk, 2995 i+1, pkgs.size()), true); 2996 } catch (RemoteException e) { 2997 } 2998 } 2999 PackageParser.Package p = pkgs.get(i); 3000 synchronized (mInstallLock) { 3001 if (!p.mDidDexOpt) { 3002 performDexOptLI(p, false, false); 3003 } 3004 } 3005 } 3006 } 3007 } 3008 3009 public boolean performDexOpt(String packageName) { 3010 enforceSystemOrRoot("Only the system can request dexopt be performed"); 3011 3012 if (!mNoDexOpt) { 3013 return false; 3014 } 3015 3016 PackageParser.Package p; 3017 synchronized (mPackages) { 3018 p = mPackages.get(packageName); 3019 if (p == null || p.mDidDexOpt) { 3020 return false; 3021 } 3022 } 3023 synchronized (mInstallLock) { 3024 return performDexOptLI(p, false, false) == DEX_OPT_PERFORMED; 3025 } 3026 } 3027 3028 static final int DEX_OPT_SKIPPED = 0; 3029 static final int DEX_OPT_PERFORMED = 1; 3030 static final int DEX_OPT_DEFERRED = 2; 3031 static final int DEX_OPT_FAILED = -1; 3032 3033 private int performDexOptLI(PackageParser.Package pkg, boolean forceDex, boolean defer) { 3034 boolean performed = false; 3035 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 3036 String path = pkg.mScanPath; 3037 int ret = 0; 3038 try { 3039 if (forceDex || dalvik.system.DexFile.isDexOptNeeded(path)) { 3040 if (!forceDex && defer) { 3041 mDeferredDexOpt.add(pkg); 3042 return DEX_OPT_DEFERRED; 3043 } else { 3044 Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName); 3045 ret = mInstaller.dexopt(path, pkg.applicationInfo.uid, 3046 !isForwardLocked(pkg)); 3047 pkg.mDidDexOpt = true; 3048 performed = true; 3049 } 3050 } 3051 } catch (FileNotFoundException e) { 3052 Slog.w(TAG, "Apk not found for dexopt: " + path); 3053 ret = -1; 3054 } catch (IOException e) { 3055 Slog.w(TAG, "IOException reading apk: " + path, e); 3056 ret = -1; 3057 } catch (dalvik.system.StaleDexCacheError e) { 3058 Slog.w(TAG, "StaleDexCacheError when reading apk: " + path, e); 3059 ret = -1; 3060 } catch (Exception e) { 3061 Slog.w(TAG, "Exception when doing dexopt : ", e); 3062 ret = -1; 3063 } 3064 if (ret < 0) { 3065 //error from installer 3066 return DEX_OPT_FAILED; 3067 } 3068 } 3069 3070 return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED; 3071 } 3072 3073 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 3074 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 3075 Slog.w(TAG, "Unable to update from " + oldPkg.name 3076 + " to " + newPkg.packageName 3077 + ": old package not in system partition"); 3078 return false; 3079 } else if (mPackages.get(oldPkg.name) != null) { 3080 Slog.w(TAG, "Unable to update from " + oldPkg.name 3081 + " to " + newPkg.packageName 3082 + ": old package still exists"); 3083 return false; 3084 } 3085 return true; 3086 } 3087 3088 File getDataPathForUser(int userId) { 3089 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId); 3090 } 3091 3092 private File getDataPathForPackage(String packageName, int userId) { 3093 /* 3094 * Until we fully support multiple users, return the directory we 3095 * previously would have. The PackageManagerTests will need to be 3096 * revised when this is changed back.. 3097 */ 3098 if (userId == 0) { 3099 return new File(mAppDataDir, packageName); 3100 } else { 3101 return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId 3102 + File.separator + packageName); 3103 } 3104 } 3105 3106 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, 3107 int parseFlags, int scanMode, long currentTime) { 3108 File scanFile = new File(pkg.mScanPath); 3109 if (scanFile == null || pkg.applicationInfo.sourceDir == null || 3110 pkg.applicationInfo.publicSourceDir == null) { 3111 // Bail out. The resource and code paths haven't been set. 3112 Slog.w(TAG, " Code and resource paths haven't been set correctly"); 3113 mLastScanError = PackageManager.INSTALL_FAILED_INVALID_APK; 3114 return null; 3115 } 3116 mScanningPath = scanFile; 3117 3118 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 3119 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 3120 } 3121 3122 if (pkg.packageName.equals("android")) { 3123 synchronized (mPackages) { 3124 if (mAndroidApplication != null) { 3125 Slog.w(TAG, "*************************************************"); 3126 Slog.w(TAG, "Core android package being redefined. Skipping."); 3127 Slog.w(TAG, " file=" + mScanningPath); 3128 Slog.w(TAG, "*************************************************"); 3129 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 3130 return null; 3131 } 3132 3133 // Set up information for our fall-back user intent resolution 3134 // activity. 3135 mPlatformPackage = pkg; 3136 pkg.mVersionCode = mSdkVersion; 3137 mAndroidApplication = pkg.applicationInfo; 3138 mResolveActivity.applicationInfo = mAndroidApplication; 3139 mResolveActivity.name = ResolverActivity.class.getName(); 3140 mResolveActivity.packageName = mAndroidApplication.packageName; 3141 mResolveActivity.processName = mAndroidApplication.processName; 3142 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 3143 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 3144 mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert; 3145 mResolveActivity.exported = true; 3146 mResolveActivity.enabled = true; 3147 mResolveInfo.activityInfo = mResolveActivity; 3148 mResolveInfo.priority = 0; 3149 mResolveInfo.preferredOrder = 0; 3150 mResolveInfo.match = 0; 3151 mResolveComponentName = new ComponentName( 3152 mAndroidApplication.packageName, mResolveActivity.name); 3153 } 3154 } 3155 3156 if (DEBUG_PACKAGE_SCANNING) { 3157 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 3158 Log.d(TAG, "Scanning package " + pkg.packageName); 3159 } 3160 3161 if (mPackages.containsKey(pkg.packageName) 3162 || mSharedLibraries.containsKey(pkg.packageName)) { 3163 Slog.w(TAG, "Application package " + pkg.packageName 3164 + " already installed. Skipping duplicate."); 3165 mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 3166 return null; 3167 } 3168 3169 // Initialize package source and resource directories 3170 File destCodeFile = new File(pkg.applicationInfo.sourceDir); 3171 File destResourceFile = new File(pkg.applicationInfo.publicSourceDir); 3172 3173 SharedUserSetting suid = null; 3174 PackageSetting pkgSetting = null; 3175 3176 if (!isSystemApp(pkg)) { 3177 // Only system apps can use these features. 3178 pkg.mOriginalPackages = null; 3179 pkg.mRealPackage = null; 3180 pkg.mAdoptPermissions = null; 3181 } 3182 3183 // writer 3184 synchronized (mPackages) { 3185 // Check all shared libraries and map to their actual file path. 3186 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 3187 if (mTmpSharedLibraries == null || 3188 mTmpSharedLibraries.length < mSharedLibraries.size()) { 3189 mTmpSharedLibraries = new String[mSharedLibraries.size()]; 3190 } 3191 int num = 0; 3192 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 3193 for (int i=0; i<N; i++) { 3194 final String file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 3195 if (file == null) { 3196 Slog.e(TAG, "Package " + pkg.packageName 3197 + " requires unavailable shared library " 3198 + pkg.usesLibraries.get(i) + "; failing!"); 3199 mLastScanError = PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 3200 return null; 3201 } 3202 mTmpSharedLibraries[num] = file; 3203 num++; 3204 } 3205 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 3206 for (int i=0; i<N; i++) { 3207 final String file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 3208 if (file == null) { 3209 Slog.w(TAG, "Package " + pkg.packageName 3210 + " desires unavailable shared library " 3211 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 3212 } else { 3213 mTmpSharedLibraries[num] = file; 3214 num++; 3215 } 3216 } 3217 if (num > 0) { 3218 pkg.usesLibraryFiles = new String[num]; 3219 System.arraycopy(mTmpSharedLibraries, 0, 3220 pkg.usesLibraryFiles, 0, num); 3221 } 3222 } 3223 3224 if (pkg.mSharedUserId != null) { 3225 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 3226 pkg.applicationInfo.flags, true); 3227 if (suid == null) { 3228 Slog.w(TAG, "Creating application package " + pkg.packageName 3229 + " for shared user failed"); 3230 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3231 return null; 3232 } 3233 if (DEBUG_PACKAGE_SCANNING) { 3234 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 3235 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 3236 + "): packages=" + suid.packages); 3237 } 3238 } 3239 3240 // Check if we are renaming from an original package name. 3241 PackageSetting origPackage = null; 3242 String realName = null; 3243 if (pkg.mOriginalPackages != null) { 3244 // This package may need to be renamed to a previously 3245 // installed name. Let's check on that... 3246 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 3247 if (pkg.mOriginalPackages.contains(renamed)) { 3248 // This package had originally been installed as the 3249 // original name, and we have already taken care of 3250 // transitioning to the new one. Just update the new 3251 // one to continue using the old name. 3252 realName = pkg.mRealPackage; 3253 if (!pkg.packageName.equals(renamed)) { 3254 // Callers into this function may have already taken 3255 // care of renaming the package; only do it here if 3256 // it is not already done. 3257 pkg.setPackageName(renamed); 3258 } 3259 3260 } else { 3261 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 3262 if ((origPackage = mSettings.peekPackageLPr( 3263 pkg.mOriginalPackages.get(i))) != null) { 3264 // We do have the package already installed under its 3265 // original name... should we use it? 3266 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 3267 // New package is not compatible with original. 3268 origPackage = null; 3269 continue; 3270 } else if (origPackage.sharedUser != null) { 3271 // Make sure uid is compatible between packages. 3272 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 3273 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 3274 + " to " + pkg.packageName + ": old uid " 3275 + origPackage.sharedUser.name 3276 + " differs from " + pkg.mSharedUserId); 3277 origPackage = null; 3278 continue; 3279 } 3280 } else { 3281 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 3282 + pkg.packageName + " to old name " + origPackage.name); 3283 } 3284 break; 3285 } 3286 } 3287 } 3288 } 3289 3290 if (mTransferedPackages.contains(pkg.packageName)) { 3291 Slog.w(TAG, "Package " + pkg.packageName 3292 + " was transferred to another, but its .apk remains"); 3293 } 3294 3295 // Just create the setting, don't add it yet. For already existing packages 3296 // the PkgSetting exists already and doesn't have to be created. 3297 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 3298 destResourceFile, pkg.applicationInfo.nativeLibraryDir, 3299 pkg.applicationInfo.flags, true, false); 3300 if (pkgSetting == null) { 3301 Slog.w(TAG, "Creating application package " + pkg.packageName + " failed"); 3302 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3303 return null; 3304 } 3305 3306 if (pkgSetting.origPackage != null) { 3307 // If we are first transitioning from an original package, 3308 // fix up the new package's name now. We need to do this after 3309 // looking up the package under its new name, so getPackageLP 3310 // can take care of fiddling things correctly. 3311 pkg.setPackageName(origPackage.name); 3312 3313 // File a report about this. 3314 String msg = "New package " + pkgSetting.realName 3315 + " renamed to replace old package " + pkgSetting.name; 3316 reportSettingsProblem(Log.WARN, msg); 3317 3318 // Make a note of it. 3319 mTransferedPackages.add(origPackage.name); 3320 3321 // No longer need to retain this. 3322 pkgSetting.origPackage = null; 3323 } 3324 3325 if (realName != null) { 3326 // Make a note of it. 3327 mTransferedPackages.add(pkg.packageName); 3328 } 3329 3330 if (mSettings.mDisabledSysPackages.get(pkg.packageName) != null) { 3331 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 3332 } 3333 3334 pkg.applicationInfo.uid = pkgSetting.userId; 3335 pkg.mExtras = pkgSetting; 3336 3337 if (!verifySignaturesLP(pkgSetting, pkg)) { 3338 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 3339 return null; 3340 } 3341 // The signature has changed, but this package is in the system 3342 // image... let's recover! 3343 pkgSetting.signatures.mSignatures = pkg.mSignatures; 3344 // However... if this package is part of a shared user, but it 3345 // doesn't match the signature of the shared user, let's fail. 3346 // What this means is that you can't change the signatures 3347 // associated with an overall shared user, which doesn't seem all 3348 // that unreasonable. 3349 if (pkgSetting.sharedUser != null) { 3350 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 3351 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 3352 Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser); 3353 mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 3354 return null; 3355 } 3356 } 3357 // File a report about this. 3358 String msg = "System package " + pkg.packageName 3359 + " signature changed; retaining data."; 3360 reportSettingsProblem(Log.WARN, msg); 3361 } 3362 3363 // Verify that this new package doesn't have any content providers 3364 // that conflict with existing packages. Only do this if the 3365 // package isn't already installed, since we don't want to break 3366 // things that are installed. 3367 if ((scanMode&SCAN_NEW_INSTALL) != 0) { 3368 final int N = pkg.providers.size(); 3369 int i; 3370 for (i=0; i<N; i++) { 3371 PackageParser.Provider p = pkg.providers.get(i); 3372 if (p.info.authority != null) { 3373 String names[] = p.info.authority.split(";"); 3374 for (int j = 0; j < names.length; j++) { 3375 if (mProviders.containsKey(names[j])) { 3376 PackageParser.Provider other = mProviders.get(names[j]); 3377 Slog.w(TAG, "Can't install because provider name " + names[j] + 3378 " (in package " + pkg.applicationInfo.packageName + 3379 ") is already used by " 3380 + ((other != null && other.getComponentName() != null) 3381 ? other.getComponentName().getPackageName() : "?")); 3382 mLastScanError = PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 3383 return null; 3384 } 3385 } 3386 } 3387 } 3388 } 3389 3390 if (pkg.mAdoptPermissions != null) { 3391 // This package wants to adopt ownership of permissions from 3392 // another package. 3393 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 3394 final String origName = pkg.mAdoptPermissions.get(i); 3395 final PackageSetting orig = mSettings.peekPackageLPr(origName); 3396 if (orig != null) { 3397 if (verifyPackageUpdateLPr(orig, pkg)) { 3398 Slog.i(TAG, "Adopting permissions from " + origName + " to " 3399 + pkg.packageName); 3400 mSettings.transferPermissionsLPw(origName, pkg.packageName); 3401 } 3402 } 3403 } 3404 } 3405 } 3406 3407 final String pkgName = pkg.packageName; 3408 3409 final long scanFileTime = scanFile.lastModified(); 3410 final boolean forceDex = (scanMode&SCAN_FORCE_DEX) != 0; 3411 pkg.applicationInfo.processName = fixProcessName( 3412 pkg.applicationInfo.packageName, 3413 pkg.applicationInfo.processName, 3414 pkg.applicationInfo.uid); 3415 3416 File dataPath; 3417 if (mPlatformPackage == pkg) { 3418 // The system package is special. 3419 dataPath = new File (Environment.getDataDirectory(), "system"); 3420 pkg.applicationInfo.dataDir = dataPath.getPath(); 3421 } else { 3422 // This is a normal package, need to make its data directory. 3423 dataPath = getDataPathForPackage(pkg.packageName, 0); 3424 3425 boolean uidError = false; 3426 3427 if (dataPath.exists()) { 3428 mOutPermissions[1] = 0; 3429 FileUtils.getPermissions(dataPath.getPath(), mOutPermissions); 3430 3431 // If we have mismatched owners for the data path, we have a problem. 3432 if (mOutPermissions[1] != pkg.applicationInfo.uid) { 3433 boolean recovered = false; 3434 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 3435 // If this is a system app, we can at least delete its 3436 // current data so the application will still work. 3437 int ret = mInstaller.remove(pkgName, 0); 3438 if (ret >= 0) { 3439 // TODO: Kill the processes first 3440 // Remove the data directories for all users 3441 mUserManager.removePackageForAllUsers(pkgName); 3442 // Old data gone! 3443 String msg = "System package " + pkg.packageName 3444 + " has changed from uid: " 3445 + mOutPermissions[1] + " to " 3446 + pkg.applicationInfo.uid + "; old data erased"; 3447 reportSettingsProblem(Log.WARN, msg); 3448 recovered = true; 3449 3450 // And now re-install the app. 3451 ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, 3452 pkg.applicationInfo.uid); 3453 if (ret == -1) { 3454 // Ack should not happen! 3455 msg = "System package " + pkg.packageName 3456 + " could not have data directory re-created after delete."; 3457 reportSettingsProblem(Log.WARN, msg); 3458 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3459 return null; 3460 } 3461 // Create data directories for all users 3462 mUserManager.installPackageForAllUsers(pkgName, 3463 pkg.applicationInfo.uid); 3464 } 3465 if (!recovered) { 3466 mHasSystemUidErrors = true; 3467 } 3468 } 3469 if (!recovered) { 3470 pkg.applicationInfo.dataDir = "/mismatched_uid/settings_" 3471 + pkg.applicationInfo.uid + "/fs_" 3472 + mOutPermissions[1]; 3473 pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir; 3474 String msg = "Package " + pkg.packageName 3475 + " has mismatched uid: " 3476 + mOutPermissions[1] + " on disk, " 3477 + pkg.applicationInfo.uid + " in settings"; 3478 // writer 3479 synchronized (mPackages) { 3480 mSettings.mReadMessages.append(msg); 3481 mSettings.mReadMessages.append('\n'); 3482 uidError = true; 3483 if (!pkgSetting.uidError) { 3484 reportSettingsProblem(Log.ERROR, msg); 3485 } 3486 } 3487 } 3488 } 3489 pkg.applicationInfo.dataDir = dataPath.getPath(); 3490 } else { 3491 if (DEBUG_PACKAGE_SCANNING) { 3492 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 3493 Log.v(TAG, "Want this data dir: " + dataPath); 3494 } 3495 //invoke installer to do the actual installation 3496 int ret = mInstaller.install(pkgName, pkg.applicationInfo.uid, 3497 pkg.applicationInfo.uid); 3498 if (ret < 0) { 3499 // Error from installer 3500 mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 3501 return null; 3502 } 3503 // Create data directories for all users 3504 mUserManager.installPackageForAllUsers(pkgName, pkg.applicationInfo.uid); 3505 3506 if (dataPath.exists()) { 3507 pkg.applicationInfo.dataDir = dataPath.getPath(); 3508 } else { 3509 Slog.w(TAG, "Unable to create data directory: " + dataPath); 3510 pkg.applicationInfo.dataDir = null; 3511 } 3512 } 3513 3514 /* 3515 * Set the data dir to the default "/data/data/<package name>/lib" 3516 * if we got here without anyone telling us different (e.g., apps 3517 * stored on SD card have their native libraries stored in the ASEC 3518 * container with the APK). 3519 * 3520 * This happens during an upgrade from a package settings file that 3521 * doesn't have a native library path attribute at all. 3522 */ 3523 if (pkg.applicationInfo.nativeLibraryDir == null && pkg.applicationInfo.dataDir != null) { 3524 if (pkgSetting.nativeLibraryPathString == null) { 3525 final String nativeLibraryPath = new File(dataPath, LIB_DIR_NAME).getPath(); 3526 pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath; 3527 pkgSetting.nativeLibraryPathString = nativeLibraryPath; 3528 } else { 3529 pkg.applicationInfo.nativeLibraryDir = pkgSetting.nativeLibraryPathString; 3530 } 3531 } 3532 3533 pkgSetting.uidError = uidError; 3534 } 3535 3536 String path = scanFile.getPath(); 3537 /* Note: We don't want to unpack the native binaries for 3538 * system applications, unless they have been updated 3539 * (the binaries are already under /system/lib). 3540 * Also, don't unpack libs for apps on the external card 3541 * since they should have their libraries in the ASEC 3542 * container already. 3543 * 3544 * In other words, we're going to unpack the binaries 3545 * only for non-system apps and system app upgrades. 3546 */ 3547 if (pkg.applicationInfo.nativeLibraryDir != null) { 3548 try { 3549 final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); 3550 final String dataPathString = dataPath.getCanonicalPath(); 3551 3552 if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { 3553 /* 3554 * Upgrading from a previous version of the OS sometimes 3555 * leaves native libraries in the /data/data/<app>/lib 3556 * directory for system apps even when they shouldn't be. 3557 * Recent changes in the JNI library search path 3558 * necessitates we remove those to match previous behavior. 3559 */ 3560 if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) { 3561 Log.i(TAG, "removed obsolete native libraries for system package " 3562 + path); 3563 } 3564 } else if (nativeLibraryDir.getParentFile().getCanonicalPath() 3565 .equals(dataPathString)) { 3566 /* 3567 * Make sure the native library dir isn't a symlink to 3568 * something. If it is, ask installd to remove it and create 3569 * a directory so we can copy to it afterwards. 3570 */ 3571 boolean isSymLink; 3572 try { 3573 isSymLink = S_ISLNK(Libcore.os.lstat(nativeLibraryDir.getPath()).st_mode); 3574 } catch (ErrnoException e) { 3575 // This shouldn't happen, but we'll fail-safe. 3576 isSymLink = true; 3577 } 3578 if (isSymLink) { 3579 mInstaller.unlinkNativeLibraryDirectory(dataPathString); 3580 } 3581 3582 /* 3583 * If this is an internal application or our 3584 * nativeLibraryPath points to our data directory, unpack 3585 * the libraries if necessary. 3586 */ 3587 NativeLibraryHelper.copyNativeBinariesIfNeededLI(scanFile, nativeLibraryDir); 3588 } else { 3589 Slog.i(TAG, "Linking native library dir for " + path); 3590 mInstaller.linkNativeLibraryDirectory(dataPathString, 3591 pkg.applicationInfo.nativeLibraryDir); 3592 } 3593 } catch (IOException ioe) { 3594 Log.e(TAG, "Unable to get canonical file " + ioe.toString()); 3595 } 3596 } 3597 pkg.mScanPath = path; 3598 3599 if ((scanMode&SCAN_NO_DEX) == 0) { 3600 if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0) 3601 == DEX_OPT_FAILED) { 3602 mLastScanError = PackageManager.INSTALL_FAILED_DEXOPT; 3603 return null; 3604 } 3605 } 3606 3607 if (mFactoryTest && pkg.requestedPermissions.contains( 3608 android.Manifest.permission.FACTORY_TEST)) { 3609 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 3610 } 3611 3612 // Request the ActivityManager to kill the process(only for existing packages) 3613 // so that we do not end up in a confused state while the user is still using the older 3614 // version of the application while the new one gets installed. 3615 if ((parseFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 3616 killApplication(pkg.applicationInfo.packageName, 3617 pkg.applicationInfo.uid); 3618 } 3619 3620 // writer 3621 synchronized (mPackages) { 3622 // We don't expect installation to fail beyond this point, 3623 if ((scanMode&SCAN_MONITOR) != 0) { 3624 mAppDirs.put(pkg.mPath, pkg); 3625 } 3626 // Add the new setting to mSettings 3627 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 3628 // Add the new setting to mPackages 3629 mPackages.put(pkg.applicationInfo.packageName, pkg); 3630 // Make sure we don't accidentally delete its data. 3631 mSettings.mPackagesToBeCleaned.remove(pkgName); 3632 3633 // Take care of first install / last update times. 3634 if (currentTime != 0) { 3635 if (pkgSetting.firstInstallTime == 0) { 3636 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 3637 } else if ((scanMode&SCAN_UPDATE_TIME) != 0) { 3638 pkgSetting.lastUpdateTime = currentTime; 3639 } 3640 } else if (pkgSetting.firstInstallTime == 0) { 3641 // We need *something*. Take time time stamp of the file. 3642 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 3643 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 3644 if (scanFileTime != pkgSetting.timeStamp) { 3645 // A package on the system image has changed; consider this 3646 // to be an update. 3647 pkgSetting.lastUpdateTime = scanFileTime; 3648 } 3649 } 3650 3651 int N = pkg.providers.size(); 3652 StringBuilder r = null; 3653 int i; 3654 for (i=0; i<N; i++) { 3655 PackageParser.Provider p = pkg.providers.get(i); 3656 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 3657 p.info.processName, pkg.applicationInfo.uid); 3658 mProvidersByComponent.put(new ComponentName(p.info.packageName, 3659 p.info.name), p); 3660 p.syncable = p.info.isSyncable; 3661 if (p.info.authority != null) { 3662 String names[] = p.info.authority.split(";"); 3663 p.info.authority = null; 3664 for (int j = 0; j < names.length; j++) { 3665 if (j == 1 && p.syncable) { 3666 // We only want the first authority for a provider to possibly be 3667 // syncable, so if we already added this provider using a different 3668 // authority clear the syncable flag. We copy the provider before 3669 // changing it because the mProviders object contains a reference 3670 // to a provider that we don't want to change. 3671 // Only do this for the second authority since the resulting provider 3672 // object can be the same for all future authorities for this provider. 3673 p = new PackageParser.Provider(p); 3674 p.syncable = false; 3675 } 3676 if (!mProviders.containsKey(names[j])) { 3677 mProviders.put(names[j], p); 3678 if (p.info.authority == null) { 3679 p.info.authority = names[j]; 3680 } else { 3681 p.info.authority = p.info.authority + ";" + names[j]; 3682 } 3683 if (DEBUG_PACKAGE_SCANNING) { 3684 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 3685 Log.d(TAG, "Registered content provider: " + names[j] 3686 + ", className = " + p.info.name + ", isSyncable = " 3687 + p.info.isSyncable); 3688 } 3689 } else { 3690 PackageParser.Provider other = mProviders.get(names[j]); 3691 Slog.w(TAG, "Skipping provider name " + names[j] + 3692 " (in package " + pkg.applicationInfo.packageName + 3693 "): name already used by " 3694 + ((other != null && other.getComponentName() != null) 3695 ? other.getComponentName().getPackageName() : "?")); 3696 } 3697 } 3698 } 3699 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3700 if (r == null) { 3701 r = new StringBuilder(256); 3702 } else { 3703 r.append(' '); 3704 } 3705 r.append(p.info.name); 3706 } 3707 } 3708 if (r != null) { 3709 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 3710 } 3711 3712 N = pkg.services.size(); 3713 r = null; 3714 for (i=0; i<N; i++) { 3715 PackageParser.Service s = pkg.services.get(i); 3716 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 3717 s.info.processName, pkg.applicationInfo.uid); 3718 mServices.addService(s); 3719 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3720 if (r == null) { 3721 r = new StringBuilder(256); 3722 } else { 3723 r.append(' '); 3724 } 3725 r.append(s.info.name); 3726 } 3727 } 3728 if (r != null) { 3729 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 3730 } 3731 3732 N = pkg.receivers.size(); 3733 r = null; 3734 for (i=0; i<N; i++) { 3735 PackageParser.Activity a = pkg.receivers.get(i); 3736 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 3737 a.info.processName, pkg.applicationInfo.uid); 3738 mReceivers.addActivity(a, "receiver"); 3739 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3740 if (r == null) { 3741 r = new StringBuilder(256); 3742 } else { 3743 r.append(' '); 3744 } 3745 r.append(a.info.name); 3746 } 3747 } 3748 if (r != null) { 3749 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 3750 } 3751 3752 N = pkg.activities.size(); 3753 r = null; 3754 for (i=0; i<N; i++) { 3755 PackageParser.Activity a = pkg.activities.get(i); 3756 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 3757 a.info.processName, pkg.applicationInfo.uid); 3758 mActivities.addActivity(a, "activity"); 3759 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3760 if (r == null) { 3761 r = new StringBuilder(256); 3762 } else { 3763 r.append(' '); 3764 } 3765 r.append(a.info.name); 3766 } 3767 } 3768 if (r != null) { 3769 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 3770 } 3771 3772 N = pkg.permissionGroups.size(); 3773 r = null; 3774 for (i=0; i<N; i++) { 3775 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 3776 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 3777 if (cur == null) { 3778 mPermissionGroups.put(pg.info.name, pg); 3779 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3780 if (r == null) { 3781 r = new StringBuilder(256); 3782 } else { 3783 r.append(' '); 3784 } 3785 r.append(pg.info.name); 3786 } 3787 } else { 3788 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 3789 + pg.info.packageName + " ignored: original from " 3790 + cur.info.packageName); 3791 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3792 if (r == null) { 3793 r = new StringBuilder(256); 3794 } else { 3795 r.append(' '); 3796 } 3797 r.append("DUP:"); 3798 r.append(pg.info.name); 3799 } 3800 } 3801 } 3802 if (r != null) { 3803 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 3804 } 3805 3806 N = pkg.permissions.size(); 3807 r = null; 3808 for (i=0; i<N; i++) { 3809 PackageParser.Permission p = pkg.permissions.get(i); 3810 HashMap<String, BasePermission> permissionMap = 3811 p.tree ? mSettings.mPermissionTrees 3812 : mSettings.mPermissions; 3813 p.group = mPermissionGroups.get(p.info.group); 3814 if (p.info.group == null || p.group != null) { 3815 BasePermission bp = permissionMap.get(p.info.name); 3816 if (bp == null) { 3817 bp = new BasePermission(p.info.name, p.info.packageName, 3818 BasePermission.TYPE_NORMAL); 3819 permissionMap.put(p.info.name, bp); 3820 } 3821 if (bp.perm == null) { 3822 if (bp.sourcePackage == null 3823 || bp.sourcePackage.equals(p.info.packageName)) { 3824 BasePermission tree = findPermissionTreeLP(p.info.name); 3825 if (tree == null 3826 || tree.sourcePackage.equals(p.info.packageName)) { 3827 bp.packageSetting = pkgSetting; 3828 bp.perm = p; 3829 bp.uid = pkg.applicationInfo.uid; 3830 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3831 if (r == null) { 3832 r = new StringBuilder(256); 3833 } else { 3834 r.append(' '); 3835 } 3836 r.append(p.info.name); 3837 } 3838 } else { 3839 Slog.w(TAG, "Permission " + p.info.name + " from package " 3840 + p.info.packageName + " ignored: base tree " 3841 + tree.name + " is from package " 3842 + tree.sourcePackage); 3843 } 3844 } else { 3845 Slog.w(TAG, "Permission " + p.info.name + " from package " 3846 + p.info.packageName + " ignored: original from " 3847 + bp.sourcePackage); 3848 } 3849 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3850 if (r == null) { 3851 r = new StringBuilder(256); 3852 } else { 3853 r.append(' '); 3854 } 3855 r.append("DUP:"); 3856 r.append(p.info.name); 3857 } 3858 if (bp.perm == p) { 3859 bp.protectionLevel = p.info.protectionLevel; 3860 } 3861 } else { 3862 Slog.w(TAG, "Permission " + p.info.name + " from package " 3863 + p.info.packageName + " ignored: no group " 3864 + p.group); 3865 } 3866 } 3867 if (r != null) { 3868 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 3869 } 3870 3871 N = pkg.instrumentation.size(); 3872 r = null; 3873 for (i=0; i<N; i++) { 3874 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 3875 a.info.packageName = pkg.applicationInfo.packageName; 3876 a.info.sourceDir = pkg.applicationInfo.sourceDir; 3877 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 3878 a.info.dataDir = pkg.applicationInfo.dataDir; 3879 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 3880 mInstrumentation.put(a.getComponentName(), a); 3881 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 3882 if (r == null) { 3883 r = new StringBuilder(256); 3884 } else { 3885 r.append(' '); 3886 } 3887 r.append(a.info.name); 3888 } 3889 } 3890 if (r != null) { 3891 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 3892 } 3893 3894 if (pkg.protectedBroadcasts != null) { 3895 N = pkg.protectedBroadcasts.size(); 3896 for (i=0; i<N; i++) { 3897 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 3898 } 3899 } 3900 3901 pkgSetting.setTimeStamp(scanFileTime); 3902 } 3903 3904 return pkg; 3905 } 3906 3907 private void killApplication(String pkgName, int uid) { 3908 // Request the ActivityManager to kill the process(only for existing packages) 3909 // so that we do not end up in a confused state while the user is still using the older 3910 // version of the application while the new one gets installed. 3911 IActivityManager am = ActivityManagerNative.getDefault(); 3912 if (am != null) { 3913 try { 3914 am.killApplicationWithUid(pkgName, uid); 3915 } catch (RemoteException e) { 3916 } 3917 } 3918 } 3919 3920 void removePackageLI(PackageParser.Package pkg, boolean chatty) { 3921 if (DEBUG_INSTALL) { 3922 if (chatty) 3923 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 3924 } 3925 3926 // writer 3927 synchronized (mPackages) { 3928 clearPackagePreferredActivitiesLPw(pkg.packageName); 3929 3930 mPackages.remove(pkg.applicationInfo.packageName); 3931 if (pkg.mPath != null) { 3932 mAppDirs.remove(pkg.mPath); 3933 } 3934 3935 int N = pkg.providers.size(); 3936 StringBuilder r = null; 3937 int i; 3938 for (i=0; i<N; i++) { 3939 PackageParser.Provider p = pkg.providers.get(i); 3940 mProvidersByComponent.remove(new ComponentName(p.info.packageName, 3941 p.info.name)); 3942 if (p.info.authority == null) { 3943 3944 /* The is another ContentProvider with this authority when 3945 * this app was installed so this authority is null, 3946 * Ignore it as we don't have to unregister the provider. 3947 */ 3948 continue; 3949 } 3950 String names[] = p.info.authority.split(";"); 3951 for (int j = 0; j < names.length; j++) { 3952 if (mProviders.get(names[j]) == p) { 3953 mProviders.remove(names[j]); 3954 if (DEBUG_REMOVE) { 3955 if (chatty) 3956 Log.d(TAG, "Unregistered content provider: " + names[j] 3957 + ", className = " + p.info.name + ", isSyncable = " 3958 + p.info.isSyncable); 3959 } 3960 } 3961 } 3962 if (chatty) { 3963 if (r == null) { 3964 r = new StringBuilder(256); 3965 } else { 3966 r.append(' '); 3967 } 3968 r.append(p.info.name); 3969 } 3970 } 3971 if (r != null) { 3972 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 3973 } 3974 3975 N = pkg.services.size(); 3976 r = null; 3977 for (i=0; i<N; i++) { 3978 PackageParser.Service s = pkg.services.get(i); 3979 mServices.removeService(s); 3980 if (chatty) { 3981 if (r == null) { 3982 r = new StringBuilder(256); 3983 } else { 3984 r.append(' '); 3985 } 3986 r.append(s.info.name); 3987 } 3988 } 3989 if (r != null) { 3990 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 3991 } 3992 3993 N = pkg.receivers.size(); 3994 r = null; 3995 for (i=0; i<N; i++) { 3996 PackageParser.Activity a = pkg.receivers.get(i); 3997 mReceivers.removeActivity(a, "receiver"); 3998 if (chatty) { 3999 if (r == null) { 4000 r = new StringBuilder(256); 4001 } else { 4002 r.append(' '); 4003 } 4004 r.append(a.info.name); 4005 } 4006 } 4007 if (r != null) { 4008 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 4009 } 4010 4011 N = pkg.activities.size(); 4012 r = null; 4013 for (i=0; i<N; i++) { 4014 PackageParser.Activity a = pkg.activities.get(i); 4015 mActivities.removeActivity(a, "activity"); 4016 if (chatty) { 4017 if (r == null) { 4018 r = new StringBuilder(256); 4019 } else { 4020 r.append(' '); 4021 } 4022 r.append(a.info.name); 4023 } 4024 } 4025 if (r != null) { 4026 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 4027 } 4028 4029 N = pkg.permissions.size(); 4030 r = null; 4031 for (i=0; i<N; i++) { 4032 PackageParser.Permission p = pkg.permissions.get(i); 4033 BasePermission bp = mSettings.mPermissions.get(p.info.name); 4034 if (bp == null) { 4035 bp = mSettings.mPermissionTrees.get(p.info.name); 4036 } 4037 if (bp != null && bp.perm == p) { 4038 bp.perm = null; 4039 if (chatty) { 4040 if (r == null) { 4041 r = new StringBuilder(256); 4042 } else { 4043 r.append(' '); 4044 } 4045 r.append(p.info.name); 4046 } 4047 } 4048 } 4049 if (r != null) { 4050 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 4051 } 4052 4053 N = pkg.instrumentation.size(); 4054 r = null; 4055 for (i=0; i<N; i++) { 4056 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 4057 mInstrumentation.remove(a.getComponentName()); 4058 if (chatty) { 4059 if (r == null) { 4060 r = new StringBuilder(256); 4061 } else { 4062 r.append(' '); 4063 } 4064 r.append(a.info.name); 4065 } 4066 } 4067 if (r != null) { 4068 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 4069 } 4070 } 4071 } 4072 4073 private static final boolean isPackageFilename(String name) { 4074 return name != null && name.endsWith(".apk"); 4075 } 4076 4077 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 4078 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 4079 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 4080 return true; 4081 } 4082 } 4083 return false; 4084 } 4085 4086 private void updatePermissionsLPw(String changingPkg, 4087 PackageParser.Package pkgInfo, boolean grantPermissions, 4088 boolean replace, boolean replaceAll) { 4089 // Make sure there are no dangling permission trees. 4090 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 4091 while (it.hasNext()) { 4092 final BasePermission bp = it.next(); 4093 if (bp.packageSetting == null) { 4094 // We may not yet have parsed the package, so just see if 4095 // we still know about its settings. 4096 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 4097 } 4098 if (bp.packageSetting == null) { 4099 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 4100 + " from package " + bp.sourcePackage); 4101 it.remove(); 4102 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 4103 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 4104 Slog.i(TAG, "Removing old permission tree: " + bp.name 4105 + " from package " + bp.sourcePackage); 4106 grantPermissions = true; 4107 it.remove(); 4108 } 4109 } 4110 } 4111 4112 // Make sure all dynamic permissions have been assigned to a package, 4113 // and make sure there are no dangling permissions. 4114 it = mSettings.mPermissions.values().iterator(); 4115 while (it.hasNext()) { 4116 final BasePermission bp = it.next(); 4117 if (bp.type == BasePermission.TYPE_DYNAMIC) { 4118 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 4119 + bp.name + " pkg=" + bp.sourcePackage 4120 + " info=" + bp.pendingInfo); 4121 if (bp.packageSetting == null && bp.pendingInfo != null) { 4122 final BasePermission tree = findPermissionTreeLP(bp.name); 4123 if (tree != null && tree.perm != null) { 4124 bp.packageSetting = tree.packageSetting; 4125 bp.perm = new PackageParser.Permission(tree.perm.owner, 4126 new PermissionInfo(bp.pendingInfo)); 4127 bp.perm.info.packageName = tree.perm.info.packageName; 4128 bp.perm.info.name = bp.name; 4129 bp.uid = tree.uid; 4130 } 4131 } 4132 } 4133 if (bp.packageSetting == null) { 4134 // We may not yet have parsed the package, so just see if 4135 // we still know about its settings. 4136 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 4137 } 4138 if (bp.packageSetting == null) { 4139 Slog.w(TAG, "Removing dangling permission: " + bp.name 4140 + " from package " + bp.sourcePackage); 4141 it.remove(); 4142 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 4143 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 4144 Slog.i(TAG, "Removing old permission: " + bp.name 4145 + " from package " + bp.sourcePackage); 4146 grantPermissions = true; 4147 it.remove(); 4148 } 4149 } 4150 } 4151 4152 // Now update the permissions for all packages, in particular 4153 // replace the granted permissions of the system packages. 4154 if (grantPermissions) { 4155 for (PackageParser.Package pkg : mPackages.values()) { 4156 if (pkg != pkgInfo) { 4157 grantPermissionsLPw(pkg, replaceAll); 4158 } 4159 } 4160 } 4161 4162 if (pkgInfo != null) { 4163 grantPermissionsLPw(pkgInfo, replace); 4164 } 4165 } 4166 4167 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace) { 4168 final PackageSetting ps = (PackageSetting) pkg.mExtras; 4169 if (ps == null) { 4170 return; 4171 } 4172 final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; 4173 boolean changedPermission = false; 4174 4175 if (replace) { 4176 ps.permissionsFixed = false; 4177 if (gp == ps) { 4178 gp.grantedPermissions.clear(); 4179 gp.gids = mGlobalGids; 4180 } 4181 } 4182 4183 if (gp.gids == null) { 4184 gp.gids = mGlobalGids; 4185 } 4186 4187 final int N = pkg.requestedPermissions.size(); 4188 for (int i=0; i<N; i++) { 4189 final String name = pkg.requestedPermissions.get(i); 4190 final BasePermission bp = mSettings.mPermissions.get(name); 4191 if (DEBUG_INSTALL) { 4192 if (gp != ps) { 4193 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 4194 } 4195 } 4196 if (bp != null && bp.packageSetting != null) { 4197 final String perm = bp.name; 4198 boolean allowed; 4199 boolean allowedSig = false; 4200 if (bp.protectionLevel == PermissionInfo.PROTECTION_NORMAL 4201 || bp.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) { 4202 allowed = true; 4203 } else if (bp.packageSetting == null) { 4204 // This permission is invalid; skip it. 4205 allowed = false; 4206 } else if (bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE 4207 || bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) { 4208 allowed = (compareSignatures( 4209 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 4210 == PackageManager.SIGNATURE_MATCH) 4211 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 4212 == PackageManager.SIGNATURE_MATCH); 4213 if (!allowed && bp.protectionLevel 4214 == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) { 4215 if (isSystemApp(pkg)) { 4216 // For updated system applications, the signatureOrSystem permission 4217 // is granted only if it had been defined by the original application. 4218 if (isUpdatedSystemApp(pkg)) { 4219 final PackageSetting sysPs = mSettings 4220 .getDisabledSystemPkgLPr(pkg.packageName); 4221 final GrantedPermissions origGp = sysPs.sharedUser != null 4222 ? sysPs.sharedUser : sysPs; 4223 if (origGp.grantedPermissions.contains(perm)) { 4224 allowed = true; 4225 } else { 4226 allowed = false; 4227 } 4228 } else { 4229 allowed = true; 4230 } 4231 } 4232 } 4233 if (allowed) { 4234 allowedSig = true; 4235 } 4236 } else { 4237 allowed = false; 4238 } 4239 if (DEBUG_INSTALL) { 4240 if (gp != ps) { 4241 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 4242 } 4243 } 4244 if (allowed) { 4245 if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 4246 && ps.permissionsFixed) { 4247 // If this is an existing, non-system package, then 4248 // we can't add any new permissions to it. 4249 if (!allowedSig && !gp.grantedPermissions.contains(perm)) { 4250 allowed = false; 4251 // Except... if this is a permission that was added 4252 // to the platform (note: need to only do this when 4253 // updating the platform). 4254 final int NP = PackageParser.NEW_PERMISSIONS.length; 4255 for (int ip=0; ip<NP; ip++) { 4256 final PackageParser.NewPermissionInfo npi 4257 = PackageParser.NEW_PERMISSIONS[ip]; 4258 if (npi.name.equals(perm) 4259 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 4260 allowed = true; 4261 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 4262 + pkg.packageName); 4263 break; 4264 } 4265 } 4266 } 4267 } 4268 if (allowed) { 4269 if (!gp.grantedPermissions.contains(perm)) { 4270 changedPermission = true; 4271 gp.grantedPermissions.add(perm); 4272 gp.gids = appendInts(gp.gids, bp.gids); 4273 } else if (!ps.haveGids) { 4274 gp.gids = appendInts(gp.gids, bp.gids); 4275 } 4276 } else { 4277 Slog.w(TAG, "Not granting permission " + perm 4278 + " to package " + pkg.packageName 4279 + " because it was previously installed without"); 4280 } 4281 } else { 4282 if (gp.grantedPermissions.remove(perm)) { 4283 changedPermission = true; 4284 gp.gids = removeInts(gp.gids, bp.gids); 4285 Slog.i(TAG, "Un-granting permission " + perm 4286 + " from package " + pkg.packageName 4287 + " (protectionLevel=" + bp.protectionLevel 4288 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 4289 + ")"); 4290 } else { 4291 Slog.w(TAG, "Not granting permission " + perm 4292 + " to package " + pkg.packageName 4293 + " (protectionLevel=" + bp.protectionLevel 4294 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 4295 + ")"); 4296 } 4297 } 4298 } else { 4299 Slog.w(TAG, "Unknown permission " + name 4300 + " in package " + pkg.packageName); 4301 } 4302 } 4303 4304 if ((changedPermission || replace) && !ps.permissionsFixed && 4305 ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) || 4306 ((ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)){ 4307 // This is the first that we have heard about this package, so the 4308 // permissions we have now selected are fixed until explicitly 4309 // changed. 4310 ps.permissionsFixed = true; 4311 } 4312 ps.haveGids = true; 4313 } 4314 4315 private final class ActivityIntentResolver 4316 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 4317 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 4318 boolean defaultOnly) { 4319 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 4320 return super.queryIntent(intent, resolvedType, defaultOnly); 4321 } 4322 4323 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags) { 4324 mFlags = flags; 4325 return super.queryIntent(intent, resolvedType, 4326 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); 4327 } 4328 4329 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 4330 int flags, ArrayList<PackageParser.Activity> packageActivities) { 4331 if (packageActivities == null) { 4332 return null; 4333 } 4334 mFlags = flags; 4335 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 4336 final int N = packageActivities.size(); 4337 ArrayList<ArrayList<PackageParser.ActivityIntentInfo>> listCut = 4338 new ArrayList<ArrayList<PackageParser.ActivityIntentInfo>>(N); 4339 4340 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 4341 for (int i = 0; i < N; ++i) { 4342 intentFilters = packageActivities.get(i).intents; 4343 if (intentFilters != null && intentFilters.size() > 0) { 4344 listCut.add(intentFilters); 4345 } 4346 } 4347 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut); 4348 } 4349 4350 public final void addActivity(PackageParser.Activity a, String type) { 4351 final boolean systemApp = isSystemApp(a.info.applicationInfo); 4352 mActivities.put(a.getComponentName(), a); 4353 if (DEBUG_SHOW_INFO) 4354 Log.v( 4355 TAG, " " + type + " " + 4356 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 4357 if (DEBUG_SHOW_INFO) 4358 Log.v(TAG, " Class=" + a.info.name); 4359 final int NI = a.intents.size(); 4360 for (int j=0; j<NI; j++) { 4361 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 4362 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 4363 intent.setPriority(0); 4364 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 4365 + a.className + " with priority > 0, forcing to 0"); 4366 } 4367 if (DEBUG_SHOW_INFO) { 4368 Log.v(TAG, " IntentFilter:"); 4369 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 4370 } 4371 if (!intent.debugCheck()) { 4372 Log.w(TAG, "==> For Activity " + a.info.name); 4373 } 4374 addFilter(intent); 4375 } 4376 } 4377 4378 public final void removeActivity(PackageParser.Activity a, String type) { 4379 mActivities.remove(a.getComponentName()); 4380 if (DEBUG_SHOW_INFO) { 4381 Log.v(TAG, " " + type + " " 4382 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 4383 : a.info.name) + ":"); 4384 Log.v(TAG, " Class=" + a.info.name); 4385 } 4386 final int NI = a.intents.size(); 4387 for (int j=0; j<NI; j++) { 4388 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 4389 if (DEBUG_SHOW_INFO) { 4390 Log.v(TAG, " IntentFilter:"); 4391 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 4392 } 4393 removeFilter(intent); 4394 } 4395 } 4396 4397 @Override 4398 protected boolean allowFilterResult( 4399 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 4400 ActivityInfo filterAi = filter.activity.info; 4401 for (int i=dest.size()-1; i>=0; i--) { 4402 ActivityInfo destAi = dest.get(i).activityInfo; 4403 if (destAi.name == filterAi.name 4404 && destAi.packageName == filterAi.packageName) { 4405 return false; 4406 } 4407 } 4408 return true; 4409 } 4410 4411 @Override 4412 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter) { 4413 PackageParser.Package p = filter.activity.owner; 4414 if (p != null) { 4415 PackageSetting ps = (PackageSetting)p.mExtras; 4416 if (ps != null) { 4417 // System apps are never considered stopped for purposes of 4418 // filtering, because there may be no way for the user to 4419 // actually re-launch them. 4420 return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0; 4421 } 4422 } 4423 return false; 4424 } 4425 4426 @Override 4427 protected String packageForFilter(PackageParser.ActivityIntentInfo info) { 4428 return info.activity.owner.packageName; 4429 } 4430 4431 @Override 4432 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 4433 int match) { 4434 if (!mSettings.isEnabledLPr(info.activity.info, mFlags)) { 4435 return null; 4436 } 4437 final PackageParser.Activity activity = info.activity; 4438 if (mSafeMode && (activity.info.applicationInfo.flags 4439 &ApplicationInfo.FLAG_SYSTEM) == 0) { 4440 return null; 4441 } 4442 final ResolveInfo res = new ResolveInfo(); 4443 res.activityInfo = PackageParser.generateActivityInfo(activity, 4444 mFlags); 4445 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 4446 res.filter = info; 4447 } 4448 res.priority = info.getPriority(); 4449 res.preferredOrder = activity.owner.mPreferredOrder; 4450 //System.out.println("Result: " + res.activityInfo.className + 4451 // " = " + res.priority); 4452 res.match = match; 4453 res.isDefault = info.hasDefault; 4454 res.labelRes = info.labelRes; 4455 res.nonLocalizedLabel = info.nonLocalizedLabel; 4456 res.icon = info.icon; 4457 res.system = isSystemApp(res.activityInfo.applicationInfo); 4458 return res; 4459 } 4460 4461 @Override 4462 protected void sortResults(List<ResolveInfo> results) { 4463 Collections.sort(results, mResolvePrioritySorter); 4464 } 4465 4466 @Override 4467 protected void dumpFilter(PrintWriter out, String prefix, 4468 PackageParser.ActivityIntentInfo filter) { 4469 out.print(prefix); out.print( 4470 Integer.toHexString(System.identityHashCode(filter.activity))); 4471 out.print(' '); 4472 out.print(filter.activity.getComponentShortName()); 4473 out.print(" filter "); 4474 out.println(Integer.toHexString(System.identityHashCode(filter))); 4475 } 4476 4477 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 4478 // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 4479 // final List<ResolveInfo> retList = Lists.newArrayList(); 4480 // while (i.hasNext()) { 4481 // final ResolveInfo resolveInfo = i.next(); 4482 // if (isEnabledLP(resolveInfo.activityInfo)) { 4483 // retList.add(resolveInfo); 4484 // } 4485 // } 4486 // return retList; 4487 // } 4488 4489 // Keys are String (activity class name), values are Activity. 4490 private final HashMap<ComponentName, PackageParser.Activity> mActivities 4491 = new HashMap<ComponentName, PackageParser.Activity>(); 4492 private int mFlags; 4493 } 4494 4495 private final class ServiceIntentResolver 4496 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 4497 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 4498 boolean defaultOnly) { 4499 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 4500 return super.queryIntent(intent, resolvedType, defaultOnly); 4501 } 4502 4503 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags) { 4504 mFlags = flags; 4505 return super.queryIntent(intent, resolvedType, 4506 (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0); 4507 } 4508 4509 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 4510 int flags, ArrayList<PackageParser.Service> packageServices) { 4511 if (packageServices == null) { 4512 return null; 4513 } 4514 mFlags = flags; 4515 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 4516 final int N = packageServices.size(); 4517 ArrayList<ArrayList<PackageParser.ServiceIntentInfo>> listCut = 4518 new ArrayList<ArrayList<PackageParser.ServiceIntentInfo>>(N); 4519 4520 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 4521 for (int i = 0; i < N; ++i) { 4522 intentFilters = packageServices.get(i).intents; 4523 if (intentFilters != null && intentFilters.size() > 0) { 4524 listCut.add(intentFilters); 4525 } 4526 } 4527 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut); 4528 } 4529 4530 public final void addService(PackageParser.Service s) { 4531 mServices.put(s.getComponentName(), s); 4532 if (DEBUG_SHOW_INFO) { 4533 Log.v(TAG, " " 4534 + (s.info.nonLocalizedLabel != null 4535 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 4536 Log.v(TAG, " Class=" + s.info.name); 4537 } 4538 final int NI = s.intents.size(); 4539 int j; 4540 for (j=0; j<NI; j++) { 4541 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 4542 if (DEBUG_SHOW_INFO) { 4543 Log.v(TAG, " IntentFilter:"); 4544 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 4545 } 4546 if (!intent.debugCheck()) { 4547 Log.w(TAG, "==> For Service " + s.info.name); 4548 } 4549 addFilter(intent); 4550 } 4551 } 4552 4553 public final void removeService(PackageParser.Service s) { 4554 mServices.remove(s.getComponentName()); 4555 if (DEBUG_SHOW_INFO) { 4556 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 4557 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 4558 Log.v(TAG, " Class=" + s.info.name); 4559 } 4560 final int NI = s.intents.size(); 4561 int j; 4562 for (j=0; j<NI; j++) { 4563 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 4564 if (DEBUG_SHOW_INFO) { 4565 Log.v(TAG, " IntentFilter:"); 4566 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 4567 } 4568 removeFilter(intent); 4569 } 4570 } 4571 4572 @Override 4573 protected boolean allowFilterResult( 4574 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 4575 ServiceInfo filterSi = filter.service.info; 4576 for (int i=dest.size()-1; i>=0; i--) { 4577 ServiceInfo destAi = dest.get(i).serviceInfo; 4578 if (destAi.name == filterSi.name 4579 && destAi.packageName == filterSi.packageName) { 4580 return false; 4581 } 4582 } 4583 return true; 4584 } 4585 4586 @Override 4587 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter) { 4588 PackageParser.Package p = filter.service.owner; 4589 if (p != null) { 4590 PackageSetting ps = (PackageSetting)p.mExtras; 4591 if (ps != null) { 4592 // System apps are never considered stopped for purposes of 4593 // filtering, because there may be no way for the user to 4594 // actually re-launch them. 4595 return ps.stopped && (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0; 4596 } 4597 } 4598 return false; 4599 } 4600 4601 @Override 4602 protected String packageForFilter(PackageParser.ServiceIntentInfo info) { 4603 return info.service.owner.packageName; 4604 } 4605 4606 @Override 4607 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 4608 int match) { 4609 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 4610 if (!mSettings.isEnabledLPr(info.service.info, mFlags)) { 4611 return null; 4612 } 4613 final PackageParser.Service service = info.service; 4614 if (mSafeMode && (service.info.applicationInfo.flags 4615 &ApplicationInfo.FLAG_SYSTEM) == 0) { 4616 return null; 4617 } 4618 final ResolveInfo res = new ResolveInfo(); 4619 res.serviceInfo = PackageParser.generateServiceInfo(service, 4620 mFlags); 4621 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 4622 res.filter = filter; 4623 } 4624 res.priority = info.getPriority(); 4625 res.preferredOrder = service.owner.mPreferredOrder; 4626 //System.out.println("Result: " + res.activityInfo.className + 4627 // " = " + res.priority); 4628 res.match = match; 4629 res.isDefault = info.hasDefault; 4630 res.labelRes = info.labelRes; 4631 res.nonLocalizedLabel = info.nonLocalizedLabel; 4632 res.icon = info.icon; 4633 res.system = isSystemApp(res.serviceInfo.applicationInfo); 4634 return res; 4635 } 4636 4637 @Override 4638 protected void sortResults(List<ResolveInfo> results) { 4639 Collections.sort(results, mResolvePrioritySorter); 4640 } 4641 4642 @Override 4643 protected void dumpFilter(PrintWriter out, String prefix, 4644 PackageParser.ServiceIntentInfo filter) { 4645 out.print(prefix); out.print( 4646 Integer.toHexString(System.identityHashCode(filter.service))); 4647 out.print(' '); 4648 out.print(filter.service.getComponentShortName()); 4649 out.print(" filter "); 4650 out.println(Integer.toHexString(System.identityHashCode(filter))); 4651 } 4652 4653 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 4654 // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 4655 // final List<ResolveInfo> retList = Lists.newArrayList(); 4656 // while (i.hasNext()) { 4657 // final ResolveInfo resolveInfo = (ResolveInfo) i; 4658 // if (isEnabledLP(resolveInfo.serviceInfo)) { 4659 // retList.add(resolveInfo); 4660 // } 4661 // } 4662 // return retList; 4663 // } 4664 4665 // Keys are String (activity class name), values are Activity. 4666 private final HashMap<ComponentName, PackageParser.Service> mServices 4667 = new HashMap<ComponentName, PackageParser.Service>(); 4668 private int mFlags; 4669 }; 4670 4671 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 4672 new Comparator<ResolveInfo>() { 4673 public int compare(ResolveInfo r1, ResolveInfo r2) { 4674 int v1 = r1.priority; 4675 int v2 = r2.priority; 4676 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 4677 if (v1 != v2) { 4678 return (v1 > v2) ? -1 : 1; 4679 } 4680 v1 = r1.preferredOrder; 4681 v2 = r2.preferredOrder; 4682 if (v1 != v2) { 4683 return (v1 > v2) ? -1 : 1; 4684 } 4685 if (r1.isDefault != r2.isDefault) { 4686 return r1.isDefault ? -1 : 1; 4687 } 4688 v1 = r1.match; 4689 v2 = r2.match; 4690 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 4691 if (v1 != v2) { 4692 return (v1 > v2) ? -1 : 1; 4693 } 4694 if (r1.system != r2.system) { 4695 return r1.system ? -1 : 1; 4696 } 4697 return 0; 4698 } 4699 }; 4700 4701 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 4702 new Comparator<ProviderInfo>() { 4703 public int compare(ProviderInfo p1, ProviderInfo p2) { 4704 final int v1 = p1.initOrder; 4705 final int v2 = p2.initOrder; 4706 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 4707 } 4708 }; 4709 4710 static final void sendPackageBroadcast(String action, String pkg, 4711 Bundle extras, String targetPkg, IIntentReceiver finishedReceiver) { 4712 IActivityManager am = ActivityManagerNative.getDefault(); 4713 if (am != null) { 4714 try { 4715 final Intent intent = new Intent(action, 4716 pkg != null ? Uri.fromParts("package", pkg, null) : null); 4717 if (extras != null) { 4718 intent.putExtras(extras); 4719 } 4720 if (targetPkg != null) { 4721 intent.setPackage(targetPkg); 4722 } 4723 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 4724 am.broadcastIntent(null, intent, null, finishedReceiver, 4725 0, null, null, null, finishedReceiver != null, false); 4726 } catch (RemoteException ex) { 4727 } 4728 } 4729 } 4730 4731 /** 4732 * Check if the external storage media is available. This is true if there 4733 * is a mounted external storage medium or if the external storage is 4734 * emulated. 4735 */ 4736 private boolean isExternalMediaAvailable() { 4737 return mMediaMounted || Environment.isExternalStorageEmulated(); 4738 } 4739 4740 public String nextPackageToClean(String lastPackage) { 4741 // writer 4742 synchronized (mPackages) { 4743 if (!isExternalMediaAvailable()) { 4744 // If the external storage is no longer mounted at this point, 4745 // the caller may not have been able to delete all of this 4746 // packages files and can not delete any more. Bail. 4747 return null; 4748 } 4749 if (lastPackage != null) { 4750 mSettings.mPackagesToBeCleaned.remove(lastPackage); 4751 } 4752 return mSettings.mPackagesToBeCleaned.size() > 0 4753 ? mSettings.mPackagesToBeCleaned.get(0) : null; 4754 } 4755 } 4756 4757 void schedulePackageCleaning(String packageName) { 4758 mHandler.sendMessage(mHandler.obtainMessage(START_CLEANING_PACKAGE, packageName)); 4759 } 4760 4761 void startCleaningPackages() { 4762 // reader 4763 synchronized (mPackages) { 4764 if (!isExternalMediaAvailable()) { 4765 return; 4766 } 4767 if (mSettings.mPackagesToBeCleaned.size() <= 0) { 4768 return; 4769 } 4770 } 4771 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 4772 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 4773 IActivityManager am = ActivityManagerNative.getDefault(); 4774 if (am != null) { 4775 try { 4776 am.startService(null, intent, null); 4777 } catch (RemoteException e) { 4778 } 4779 } 4780 } 4781 4782 private final class AppDirObserver extends FileObserver { 4783 public AppDirObserver(String path, int mask, boolean isrom) { 4784 super(path, mask); 4785 mRootDir = path; 4786 mIsRom = isrom; 4787 } 4788 4789 public void onEvent(int event, String path) { 4790 String removedPackage = null; 4791 int removedUid = -1; 4792 String addedPackage = null; 4793 int addedUid = -1; 4794 4795 // TODO post a message to the handler to obtain serial ordering 4796 synchronized (mInstallLock) { 4797 String fullPathStr = null; 4798 File fullPath = null; 4799 if (path != null) { 4800 fullPath = new File(mRootDir, path); 4801 fullPathStr = fullPath.getPath(); 4802 } 4803 4804 if (DEBUG_APP_DIR_OBSERVER) 4805 Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event)); 4806 4807 if (!isPackageFilename(path)) { 4808 if (DEBUG_APP_DIR_OBSERVER) 4809 Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr); 4810 return; 4811 } 4812 4813 // Ignore packages that are being installed or 4814 // have just been installed. 4815 if (ignoreCodePath(fullPathStr)) { 4816 return; 4817 } 4818 PackageParser.Package p = null; 4819 // reader 4820 synchronized (mPackages) { 4821 p = mAppDirs.get(fullPathStr); 4822 } 4823 if ((event&REMOVE_EVENTS) != 0) { 4824 if (p != null) { 4825 removePackageLI(p, true); 4826 removedPackage = p.applicationInfo.packageName; 4827 removedUid = p.applicationInfo.uid; 4828 } 4829 } 4830 4831 if ((event&ADD_EVENTS) != 0) { 4832 if (p == null) { 4833 p = scanPackageLI(fullPath, 4834 (mIsRom ? PackageParser.PARSE_IS_SYSTEM 4835 | PackageParser.PARSE_IS_SYSTEM_DIR: 0) | 4836 PackageParser.PARSE_CHATTY | 4837 PackageParser.PARSE_MUST_BE_APK, 4838 SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME, 4839 System.currentTimeMillis()); 4840 if (p != null) { 4841 /* 4842 * TODO this seems dangerous as the package may have 4843 * changed since we last acquired the mPackages 4844 * lock. 4845 */ 4846 // writer 4847 synchronized (mPackages) { 4848 updatePermissionsLPw(p.packageName, p, 4849 p.permissions.size() > 0, false, false); 4850 } 4851 addedPackage = p.applicationInfo.packageName; 4852 addedUid = p.applicationInfo.uid; 4853 } 4854 } 4855 } 4856 4857 // reader 4858 synchronized (mPackages) { 4859 mSettings.writeLPr(); 4860 } 4861 } 4862 4863 if (removedPackage != null) { 4864 Bundle extras = new Bundle(1); 4865 extras.putInt(Intent.EXTRA_UID, removedUid); 4866 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, false); 4867 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 4868 extras, null, null); 4869 } 4870 if (addedPackage != null) { 4871 Bundle extras = new Bundle(1); 4872 extras.putInt(Intent.EXTRA_UID, addedUid); 4873 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, addedPackage, 4874 extras, null, null); 4875 } 4876 } 4877 4878 private final String mRootDir; 4879 private final boolean mIsRom; 4880 } 4881 4882 /* Called when a downloaded package installation has been confirmed by the user */ 4883 public void installPackage( 4884 final Uri packageURI, final IPackageInstallObserver observer, final int flags) { 4885 installPackage(packageURI, observer, flags, null); 4886 } 4887 4888 /* Called when a downloaded package installation has been confirmed by the user */ 4889 public void installPackage( 4890 final Uri packageURI, final IPackageInstallObserver observer, final int flags, 4891 final String installerPackageName) { 4892 installPackageWithVerification(packageURI, observer, flags, installerPackageName, null, 4893 null); 4894 } 4895 4896 @Override 4897 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, 4898 int flags, String installerPackageName, Uri verificationURI, 4899 ManifestDigest manifestDigest) { 4900 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 4901 4902 final int uid = Binder.getCallingUid(); 4903 4904 final int filteredFlags; 4905 4906 if (uid == Process.SHELL_UID || uid == 0) { 4907 if (DEBUG_INSTALL) { 4908 Slog.v(TAG, "Install from ADB"); 4909 } 4910 filteredFlags = flags | PackageManager.INSTALL_FROM_ADB; 4911 } else { 4912 filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB; 4913 } 4914 4915 final Message msg = mHandler.obtainMessage(INIT_COPY); 4916 msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName, 4917 verificationURI, manifestDigest); 4918 mHandler.sendMessage(msg); 4919 } 4920 4921 @Override 4922 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 4923 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 4924 final PackageVerificationResponse response = new PackageVerificationResponse( 4925 verificationCode, Binder.getCallingUid()); 4926 msg.arg1 = id; 4927 msg.obj = response; 4928 mHandler.sendMessage(msg); 4929 } 4930 4931 private ComponentName matchComponentForVerifier(String packageName, 4932 List<ResolveInfo> receivers) { 4933 ActivityInfo targetReceiver = null; 4934 4935 final int NR = receivers.size(); 4936 for (int i = 0; i < NR; i++) { 4937 final ResolveInfo info = receivers.get(i); 4938 if (info.activityInfo == null) { 4939 continue; 4940 } 4941 4942 if (packageName.equals(info.activityInfo.packageName)) { 4943 targetReceiver = info.activityInfo; 4944 break; 4945 } 4946 } 4947 4948 if (targetReceiver == null) { 4949 return null; 4950 } 4951 4952 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 4953 } 4954 4955 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 4956 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 4957 if (pkgInfo.verifiers.length == 0) { 4958 return null; 4959 } 4960 4961 final int N = pkgInfo.verifiers.length; 4962 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 4963 for (int i = 0; i < N; i++) { 4964 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 4965 4966 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 4967 receivers); 4968 if (comp == null) { 4969 continue; 4970 } 4971 4972 final int verifierUid = getUidForVerifier(verifierInfo); 4973 if (verifierUid == -1) { 4974 continue; 4975 } 4976 4977 if (DEBUG_VERIFY) { 4978 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 4979 + " with the correct signature"); 4980 } 4981 sufficientVerifiers.add(comp); 4982 verificationState.addSufficientVerifier(verifierUid); 4983 } 4984 4985 return sufficientVerifiers; 4986 } 4987 4988 private int getUidForVerifier(VerifierInfo verifierInfo) { 4989 synchronized (mPackages) { 4990 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 4991 if (pkg == null) { 4992 return -1; 4993 } else if (pkg.mSignatures.length != 1) { 4994 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 4995 + " has more than one signature; ignoring"); 4996 return -1; 4997 } 4998 4999 /* 5000 * If the public key of the package's signature does not match 5001 * our expected public key, then this is a different package and 5002 * we should skip. 5003 */ 5004 5005 final byte[] expectedPublicKey; 5006 try { 5007 final Signature verifierSig = pkg.mSignatures[0]; 5008 final PublicKey publicKey = verifierSig.getPublicKey(); 5009 expectedPublicKey = publicKey.getEncoded(); 5010 } catch (CertificateException e) { 5011 return -1; 5012 } 5013 5014 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 5015 5016 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 5017 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 5018 + " does not have the expected public key; ignoring"); 5019 return -1; 5020 } 5021 5022 return pkg.applicationInfo.uid; 5023 } 5024 } 5025 5026 public void finishPackageInstall(int token) { 5027 enforceSystemOrRoot("Only the system is allowed to finish installs"); 5028 5029 if (DEBUG_INSTALL) { 5030 Slog.v(TAG, "BM finishing package install for " + token); 5031 } 5032 5033 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 5034 mHandler.sendMessage(msg); 5035 } 5036 5037 /** 5038 * Get the verification agent timeout. 5039 * 5040 * @return verification timeout in milliseconds 5041 */ 5042 private long getVerificationTimeout() { 5043 return android.provider.Settings.Secure.getLong(mContext.getContentResolver(), 5044 android.provider.Settings.Secure.PACKAGE_VERIFIER_TIMEOUT, 5045 DEFAULT_VERIFICATION_TIMEOUT); 5046 } 5047 5048 /** 5049 * Check whether or not package verification has been enabled. 5050 * 5051 * @return true if verification should be performed 5052 */ 5053 private boolean isVerificationEnabled() { 5054 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 5055 android.provider.Settings.Secure.PACKAGE_VERIFIER_ENABLE, 5056 DEFAULT_VERIFY_ENABLE ? 1 : 0) == 1 ? true : false; 5057 } 5058 5059 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 5060 final int uid = Binder.getCallingUid(); 5061 // writer 5062 synchronized (mPackages) { 5063 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 5064 if (targetPackageSetting == null) { 5065 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 5066 } 5067 5068 PackageSetting installerPackageSetting; 5069 if (installerPackageName != null) { 5070 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 5071 if (installerPackageSetting == null) { 5072 throw new IllegalArgumentException("Unknown installer package: " 5073 + installerPackageName); 5074 } 5075 } else { 5076 installerPackageSetting = null; 5077 } 5078 5079 Signature[] callerSignature; 5080 Object obj = mSettings.getUserIdLPr(uid); 5081 if (obj != null) { 5082 if (obj instanceof SharedUserSetting) { 5083 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 5084 } else if (obj instanceof PackageSetting) { 5085 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 5086 } else { 5087 throw new SecurityException("Bad object " + obj + " for uid " + uid); 5088 } 5089 } else { 5090 throw new SecurityException("Unknown calling uid " + uid); 5091 } 5092 5093 // Verify: can't set installerPackageName to a package that is 5094 // not signed with the same cert as the caller. 5095 if (installerPackageSetting != null) { 5096 if (compareSignatures(callerSignature, 5097 installerPackageSetting.signatures.mSignatures) 5098 != PackageManager.SIGNATURE_MATCH) { 5099 throw new SecurityException( 5100 "Caller does not have same cert as new installer package " 5101 + installerPackageName); 5102 } 5103 } 5104 5105 // Verify: if target already has an installer package, it must 5106 // be signed with the same cert as the caller. 5107 if (targetPackageSetting.installerPackageName != null) { 5108 PackageSetting setting = mSettings.mPackages.get( 5109 targetPackageSetting.installerPackageName); 5110 // If the currently set package isn't valid, then it's always 5111 // okay to change it. 5112 if (setting != null) { 5113 if (compareSignatures(callerSignature, 5114 setting.signatures.mSignatures) 5115 != PackageManager.SIGNATURE_MATCH) { 5116 throw new SecurityException( 5117 "Caller does not have same cert as old installer package " 5118 + targetPackageSetting.installerPackageName); 5119 } 5120 } 5121 } 5122 5123 // Okay! 5124 targetPackageSetting.installerPackageName = installerPackageName; 5125 scheduleWriteSettingsLocked(); 5126 } 5127 } 5128 5129 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 5130 // Queue up an async operation since the package installation may take a little while. 5131 mHandler.post(new Runnable() { 5132 public void run() { 5133 mHandler.removeCallbacks(this); 5134 // Result object to be returned 5135 PackageInstalledInfo res = new PackageInstalledInfo(); 5136 res.returnCode = currentStatus; 5137 res.uid = -1; 5138 res.pkg = null; 5139 res.removedInfo = new PackageRemovedInfo(); 5140 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 5141 args.doPreInstall(res.returnCode); 5142 synchronized (mInstallLock) { 5143 installPackageLI(args, true, res); 5144 } 5145 args.doPostInstall(res.returnCode); 5146 } 5147 5148 // A restore should be performed at this point if (a) the install 5149 // succeeded, (b) the operation is not an update, and (c) the new 5150 // package has a backupAgent defined. 5151 final boolean update = res.removedInfo.removedPackage != null; 5152 boolean doRestore = (!update 5153 && res.pkg != null 5154 && res.pkg.applicationInfo.backupAgentName != null); 5155 5156 // Set up the post-install work request bookkeeping. This will be used 5157 // and cleaned up by the post-install event handling regardless of whether 5158 // there's a restore pass performed. Token values are >= 1. 5159 int token; 5160 if (mNextInstallToken < 0) mNextInstallToken = 1; 5161 token = mNextInstallToken++; 5162 5163 PostInstallData data = new PostInstallData(args, res); 5164 mRunningInstalls.put(token, data); 5165 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 5166 5167 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 5168 // Pass responsibility to the Backup Manager. It will perform a 5169 // restore if appropriate, then pass responsibility back to the 5170 // Package Manager to run the post-install observer callbacks 5171 // and broadcasts. 5172 IBackupManager bm = IBackupManager.Stub.asInterface( 5173 ServiceManager.getService(Context.BACKUP_SERVICE)); 5174 if (bm != null) { 5175 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 5176 + " to BM for possible restore"); 5177 try { 5178 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 5179 } catch (RemoteException e) { 5180 // can't happen; the backup manager is local 5181 } catch (Exception e) { 5182 Slog.e(TAG, "Exception trying to enqueue restore", e); 5183 doRestore = false; 5184 } 5185 } else { 5186 Slog.e(TAG, "Backup Manager not found!"); 5187 doRestore = false; 5188 } 5189 } 5190 5191 if (!doRestore) { 5192 // No restore possible, or the Backup Manager was mysteriously not 5193 // available -- just fire the post-install work request directly. 5194 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 5195 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 5196 mHandler.sendMessage(msg); 5197 } 5198 } 5199 }); 5200 } 5201 5202 private abstract class HandlerParams { 5203 private static final int MAX_RETRIES = 4; 5204 5205 /** 5206 * Number of times startCopy() has been attempted and had a non-fatal 5207 * error. 5208 */ 5209 private int mRetries = 0; 5210 5211 final boolean startCopy() { 5212 boolean res; 5213 try { 5214 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy"); 5215 5216 if (++mRetries > MAX_RETRIES) { 5217 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 5218 mHandler.sendEmptyMessage(MCS_GIVE_UP); 5219 handleServiceError(); 5220 return false; 5221 } else { 5222 handleStartCopy(); 5223 res = true; 5224 } 5225 } catch (RemoteException e) { 5226 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 5227 mHandler.sendEmptyMessage(MCS_RECONNECT); 5228 res = false; 5229 } 5230 handleReturnCode(); 5231 return res; 5232 } 5233 5234 final void serviceError() { 5235 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 5236 handleServiceError(); 5237 handleReturnCode(); 5238 } 5239 5240 abstract void handleStartCopy() throws RemoteException; 5241 abstract void handleServiceError(); 5242 abstract void handleReturnCode(); 5243 } 5244 5245 class MeasureParams extends HandlerParams { 5246 private final PackageStats mStats; 5247 private boolean mSuccess; 5248 5249 private final IPackageStatsObserver mObserver; 5250 5251 public MeasureParams(PackageStats stats, boolean success, IPackageStatsObserver observer) { 5252 mObserver = observer; 5253 mStats = stats; 5254 mSuccess = success; 5255 } 5256 5257 @Override 5258 void handleStartCopy() throws RemoteException { 5259 final boolean mounted; 5260 5261 if (Environment.isExternalStorageEmulated()) { 5262 mounted = true; 5263 } else { 5264 final String status = Environment.getExternalStorageState(); 5265 5266 mounted = status.equals(Environment.MEDIA_MOUNTED) 5267 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 5268 } 5269 5270 if (mounted) { 5271 final File externalCacheDir = Environment 5272 .getExternalStorageAppCacheDirectory(mStats.packageName); 5273 final long externalCacheSize = mContainerService 5274 .calculateDirectorySize(externalCacheDir.getPath()); 5275 mStats.externalCacheSize = externalCacheSize; 5276 5277 final File externalDataDir = Environment 5278 .getExternalStorageAppDataDirectory(mStats.packageName); 5279 long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir 5280 .getPath()); 5281 5282 if (externalCacheDir.getParentFile().equals(externalDataDir)) { 5283 externalDataSize -= externalCacheSize; 5284 } 5285 mStats.externalDataSize = externalDataSize; 5286 5287 final File externalMediaDir = Environment 5288 .getExternalStorageAppMediaDirectory(mStats.packageName); 5289 mStats.externalMediaSize = mContainerService 5290 .calculateDirectorySize(externalMediaDir.getPath()); 5291 5292 final File externalObbDir = Environment 5293 .getExternalStorageAppObbDirectory(mStats.packageName); 5294 mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir 5295 .getPath()); 5296 } 5297 } 5298 5299 @Override 5300 void handleReturnCode() { 5301 if (mObserver != null) { 5302 try { 5303 mObserver.onGetStatsCompleted(mStats, mSuccess); 5304 } catch (RemoteException e) { 5305 Slog.i(TAG, "Observer no longer exists."); 5306 } 5307 } 5308 } 5309 5310 @Override 5311 void handleServiceError() { 5312 Slog.e(TAG, "Could not measure application " + mStats.packageName 5313 + " external storage"); 5314 } 5315 } 5316 5317 class InstallParams extends HandlerParams { 5318 final IPackageInstallObserver observer; 5319 int flags; 5320 final Uri packageURI; 5321 final String installerPackageName; 5322 final Uri verificationURI; 5323 final ManifestDigest manifestDigest; 5324 private InstallArgs mArgs; 5325 private int mRet; 5326 5327 InstallParams(Uri packageURI, 5328 IPackageInstallObserver observer, int flags, 5329 String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest) { 5330 this.packageURI = packageURI; 5331 this.flags = flags; 5332 this.observer = observer; 5333 this.installerPackageName = installerPackageName; 5334 this.verificationURI = verificationURI; 5335 this.manifestDigest = manifestDigest; 5336 } 5337 5338 private int installLocationPolicy(PackageInfoLite pkgLite, int flags) { 5339 String packageName = pkgLite.packageName; 5340 int installLocation = pkgLite.installLocation; 5341 boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 5342 // reader 5343 synchronized (mPackages) { 5344 PackageParser.Package pkg = mPackages.get(packageName); 5345 if (pkg != null) { 5346 if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 5347 // Check for updated system application. 5348 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 5349 if (onSd) { 5350 Slog.w(TAG, "Cannot install update to system app on sdcard"); 5351 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 5352 } 5353 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 5354 } else { 5355 if (onSd) { 5356 // Install flag overrides everything. 5357 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 5358 } 5359 // If current upgrade specifies particular preference 5360 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 5361 // Application explicitly specified internal. 5362 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 5363 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 5364 // App explictly prefers external. Let policy decide 5365 } else { 5366 // Prefer previous location 5367 if (isExternal(pkg)) { 5368 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 5369 } 5370 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 5371 } 5372 } 5373 } else { 5374 // Invalid install. Return error code 5375 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 5376 } 5377 } 5378 } 5379 // All the special cases have been taken care of. 5380 // Return result based on recommended install location. 5381 if (onSd) { 5382 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 5383 } 5384 return pkgLite.recommendedInstallLocation; 5385 } 5386 5387 /* 5388 * Invoke remote method to get package information and install 5389 * location values. Override install location based on default 5390 * policy if needed and then create install arguments based 5391 * on the install location. 5392 */ 5393 public void handleStartCopy() throws RemoteException { 5394 int ret = PackageManager.INSTALL_SUCCEEDED; 5395 final boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 5396 final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; 5397 final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0; 5398 PackageInfoLite pkgLite = null; 5399 5400 if (onInt && onSd) { 5401 // Check if both bits are set. 5402 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 5403 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 5404 } else if (fwdLocked && onSd) { 5405 // Check for forward locked apps 5406 Slog.w(TAG, "Cannot install fwd locked apps on sdcard"); 5407 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 5408 } else { 5409 final long lowThreshold; 5410 5411 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager 5412 .getService(DeviceStorageMonitorService.SERVICE); 5413 if (dsm == null) { 5414 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 5415 lowThreshold = 0L; 5416 } else { 5417 lowThreshold = dsm.getMemoryLowThreshold(); 5418 } 5419 5420 // Remote call to find out default install location 5421 try { 5422 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5423 Intent.FLAG_GRANT_READ_URI_PERMISSION); 5424 pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags, 5425 lowThreshold); 5426 } finally { 5427 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5428 } 5429 5430 int loc = pkgLite.recommendedInstallLocation; 5431 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 5432 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 5433 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 5434 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 5435 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 5436 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5437 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 5438 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 5439 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 5440 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 5441 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 5442 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 5443 } else { 5444 // Override with defaults if needed. 5445 loc = installLocationPolicy(pkgLite, flags); 5446 if (!onSd && !onInt) { 5447 // Override install location with flags 5448 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 5449 // Set the flag to install on external media. 5450 flags |= PackageManager.INSTALL_EXTERNAL; 5451 flags &= ~PackageManager.INSTALL_INTERNAL; 5452 } else { 5453 // Make sure the flag for installing on external 5454 // media is unset 5455 flags |= PackageManager.INSTALL_INTERNAL; 5456 flags &= ~PackageManager.INSTALL_EXTERNAL; 5457 } 5458 } 5459 } 5460 } 5461 5462 final InstallArgs args = createInstallArgs(this); 5463 mArgs = args; 5464 5465 if (ret == PackageManager.INSTALL_SUCCEEDED) { 5466 /* 5467 * Determine if we have any installed package verifiers. If we 5468 * do, then we'll defer to them to verify the packages. 5469 */ 5470 final int requiredUid = mRequiredVerifierPackage == null ? -1 5471 : getPackageUid(mRequiredVerifierPackage); 5472 if (requiredUid != -1 && isVerificationEnabled()) { 5473 final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 5474 verification.setDataAndType(packageURI, PACKAGE_MIME_TYPE); 5475 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 5476 5477 final List<ResolveInfo> receivers = queryIntentReceivers(verification, null, 5478 PackageManager.GET_DISABLED_COMPONENTS); 5479 5480 if (DEBUG_VERIFY) { 5481 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 5482 + verification.toString() + " with " + pkgLite.verifiers.length 5483 + " optional verifiers"); 5484 } 5485 5486 final int verificationId = mPendingVerificationToken++; 5487 5488 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 5489 5490 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 5491 installerPackageName); 5492 5493 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags); 5494 5495 if (verificationURI != null) { 5496 verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI, 5497 verificationURI); 5498 } 5499 5500 final PackageVerificationState verificationState = new PackageVerificationState( 5501 requiredUid, args); 5502 5503 mPendingVerification.append(verificationId, verificationState); 5504 5505 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 5506 receivers, verificationState); 5507 5508 /* 5509 * If any sufficient verifiers were listed in the package 5510 * manifest, attempt to ask them. 5511 */ 5512 if (sufficientVerifiers != null) { 5513 final int N = sufficientVerifiers.size(); 5514 if (N == 0) { 5515 Slog.i(TAG, "Additional verifiers required, but none installed."); 5516 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 5517 } else { 5518 for (int i = 0; i < N; i++) { 5519 final ComponentName verifierComponent = sufficientVerifiers.get(i); 5520 5521 final Intent sufficientIntent = new Intent(verification); 5522 sufficientIntent.setComponent(verifierComponent); 5523 5524 mContext.sendBroadcast(sufficientIntent); 5525 } 5526 } 5527 } 5528 5529 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 5530 mRequiredVerifierPackage, receivers); 5531 if (ret == PackageManager.INSTALL_SUCCEEDED 5532 && mRequiredVerifierPackage != null) { 5533 /* 5534 * Send the intent to the required verification agent, 5535 * but only start the verification timeout after the 5536 * target BroadcastReceivers have run. 5537 */ 5538 verification.setComponent(requiredVerifierComponent); 5539 mContext.sendOrderedBroadcast(verification, 5540 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 5541 new BroadcastReceiver() { 5542 @Override 5543 public void onReceive(Context context, Intent intent) { 5544 final Message msg = mHandler 5545 .obtainMessage(CHECK_PENDING_VERIFICATION); 5546 msg.arg1 = verificationId; 5547 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 5548 } 5549 }, null, 0, null, null); 5550 5551 /* 5552 * We don't want the copy to proceed until verification 5553 * succeeds, so null out this field. 5554 */ 5555 mArgs = null; 5556 } 5557 } else { 5558 /* 5559 * No package verification is enabled, so immediately start 5560 * the remote call to initiate copy using temporary file. 5561 */ 5562 ret = args.copyApk(mContainerService, true); 5563 } 5564 } 5565 5566 mRet = ret; 5567 } 5568 5569 @Override 5570 void handleReturnCode() { 5571 // If mArgs is null, then MCS couldn't be reached. When it 5572 // reconnects, it will try again to install. At that point, this 5573 // will succeed. 5574 if (mArgs != null) { 5575 processPendingInstall(mArgs, mRet); 5576 } 5577 } 5578 5579 @Override 5580 void handleServiceError() { 5581 mArgs = createInstallArgs(this); 5582 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 5583 } 5584 } 5585 5586 /* 5587 * Utility class used in movePackage api. 5588 * srcArgs and targetArgs are not set for invalid flags and make 5589 * sure to do null checks when invoking methods on them. 5590 * We probably want to return ErrorPrams for both failed installs 5591 * and moves. 5592 */ 5593 class MoveParams extends HandlerParams { 5594 final IPackageMoveObserver observer; 5595 final int flags; 5596 final String packageName; 5597 final InstallArgs srcArgs; 5598 final InstallArgs targetArgs; 5599 int mRet; 5600 5601 MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, 5602 String packageName, String dataDir) { 5603 this.srcArgs = srcArgs; 5604 this.observer = observer; 5605 this.flags = flags; 5606 this.packageName = packageName; 5607 if (srcArgs != null) { 5608 Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath())); 5609 targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir); 5610 } else { 5611 targetArgs = null; 5612 } 5613 } 5614 5615 public void handleStartCopy() throws RemoteException { 5616 mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5617 // Check for storage space on target medium 5618 if (!targetArgs.checkFreeStorage(mContainerService)) { 5619 Log.w(TAG, "Insufficient storage to install"); 5620 return; 5621 } 5622 // Create the file args now. 5623 mRet = targetArgs.copyApk(mContainerService, false); 5624 targetArgs.doPreInstall(mRet); 5625 if (DEBUG_SD_INSTALL) { 5626 StringBuilder builder = new StringBuilder(); 5627 if (srcArgs != null) { 5628 builder.append("src: "); 5629 builder.append(srcArgs.getCodePath()); 5630 } 5631 if (targetArgs != null) { 5632 builder.append(" target : "); 5633 builder.append(targetArgs.getCodePath()); 5634 } 5635 Log.i(TAG, builder.toString()); 5636 } 5637 } 5638 5639 @Override 5640 void handleReturnCode() { 5641 targetArgs.doPostInstall(mRet); 5642 int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 5643 if (mRet == PackageManager.INSTALL_SUCCEEDED) { 5644 currentStatus = PackageManager.MOVE_SUCCEEDED; 5645 } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){ 5646 currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 5647 } 5648 processPendingMove(this, currentStatus); 5649 } 5650 5651 @Override 5652 void handleServiceError() { 5653 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 5654 } 5655 } 5656 5657 private InstallArgs createInstallArgs(InstallParams params) { 5658 if (installOnSd(params.flags)) { 5659 return new SdInstallArgs(params); 5660 } else { 5661 return new FileInstallArgs(params); 5662 } 5663 } 5664 5665 private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath, 5666 String nativeLibraryPath) { 5667 if (installOnSd(flags)) { 5668 return new SdInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); 5669 } else { 5670 return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); 5671 } 5672 } 5673 5674 // Used by package mover 5675 private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) { 5676 if (installOnSd(flags)) { 5677 String cid = getNextCodePath(null, pkgName, "/" + SdInstallArgs.RES_FILE_NAME); 5678 return new SdInstallArgs(packageURI, cid); 5679 } else { 5680 return new FileInstallArgs(packageURI, pkgName, dataDir); 5681 } 5682 } 5683 5684 static abstract class InstallArgs { 5685 final IPackageInstallObserver observer; 5686 // Always refers to PackageManager flags only 5687 final int flags; 5688 final Uri packageURI; 5689 final String installerPackageName; 5690 final ManifestDigest manifestDigest; 5691 5692 InstallArgs(Uri packageURI, IPackageInstallObserver observer, int flags, 5693 String installerPackageName, ManifestDigest manifestDigest) { 5694 this.packageURI = packageURI; 5695 this.flags = flags; 5696 this.observer = observer; 5697 this.installerPackageName = installerPackageName; 5698 this.manifestDigest = manifestDigest; 5699 } 5700 5701 abstract void createCopyFile(); 5702 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 5703 abstract int doPreInstall(int status); 5704 abstract boolean doRename(int status, String pkgName, String oldCodePath); 5705 abstract int doPostInstall(int status); 5706 abstract String getCodePath(); 5707 abstract String getResourcePath(); 5708 abstract String getNativeLibraryPath(); 5709 // Need installer lock especially for dex file removal. 5710 abstract void cleanUpResourcesLI(); 5711 abstract boolean doPostDeleteLI(boolean delete); 5712 abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; 5713 } 5714 5715 class FileInstallArgs extends InstallArgs { 5716 File installDir; 5717 String codeFileName; 5718 String resourceFileName; 5719 String libraryPath; 5720 boolean created = false; 5721 5722 FileInstallArgs(InstallParams params) { 5723 super(params.packageURI, params.observer, params.flags, params.installerPackageName, 5724 params.manifestDigest); 5725 } 5726 5727 FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) { 5728 super(null, null, 0, null, null); 5729 File codeFile = new File(fullCodePath); 5730 installDir = codeFile.getParentFile(); 5731 codeFileName = fullCodePath; 5732 resourceFileName = fullResourcePath; 5733 libraryPath = nativeLibraryPath; 5734 } 5735 5736 FileInstallArgs(Uri packageURI, String pkgName, String dataDir) { 5737 super(packageURI, null, 0, null, null); 5738 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 5739 String apkName = getNextCodePath(null, pkgName, ".apk"); 5740 codeFileName = new File(installDir, apkName + ".apk").getPath(); 5741 resourceFileName = getResourcePathFromCodePath(); 5742 libraryPath = new File(dataDir, LIB_DIR_NAME).getPath(); 5743 } 5744 5745 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 5746 final long lowThreshold; 5747 5748 final DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) ServiceManager 5749 .getService(DeviceStorageMonitorService.SERVICE); 5750 if (dsm == null) { 5751 Log.w(TAG, "Couldn't get low memory threshold; no free limit imposed"); 5752 lowThreshold = 0L; 5753 } else { 5754 if (dsm.isMemoryLow()) { 5755 Log.w(TAG, "Memory is reported as being too low; aborting package install"); 5756 return false; 5757 } 5758 5759 lowThreshold = dsm.getMemoryLowThreshold(); 5760 } 5761 5762 try { 5763 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5764 Intent.FLAG_GRANT_READ_URI_PERMISSION); 5765 return imcs.checkInternalFreeStorage(packageURI, lowThreshold); 5766 } finally { 5767 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5768 } 5769 } 5770 5771 String getCodePath() { 5772 return codeFileName; 5773 } 5774 5775 void createCopyFile() { 5776 installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; 5777 codeFileName = createTempPackageFile(installDir).getPath(); 5778 resourceFileName = getResourcePathFromCodePath(); 5779 created = true; 5780 } 5781 5782 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 5783 if (temp) { 5784 // Generate temp file name 5785 createCopyFile(); 5786 } 5787 // Get a ParcelFileDescriptor to write to the output file 5788 File codeFile = new File(codeFileName); 5789 if (!created) { 5790 try { 5791 codeFile.createNewFile(); 5792 // Set permissions 5793 if (!setPermissions()) { 5794 // Failed setting permissions. 5795 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5796 } 5797 } catch (IOException e) { 5798 Slog.w(TAG, "Failed to create file " + codeFile); 5799 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5800 } 5801 } 5802 ParcelFileDescriptor out = null; 5803 try { 5804 out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE); 5805 } catch (FileNotFoundException e) { 5806 Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName); 5807 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5808 } 5809 // Copy the resource now 5810 int ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 5811 try { 5812 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5813 Intent.FLAG_GRANT_READ_URI_PERMISSION); 5814 ret = imcs.copyResource(packageURI, out); 5815 } finally { 5816 try { if (out != null) out.close(); } catch (IOException e) {} 5817 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 5818 } 5819 5820 return ret; 5821 } 5822 5823 int doPreInstall(int status) { 5824 if (status != PackageManager.INSTALL_SUCCEEDED) { 5825 cleanUp(); 5826 } 5827 return status; 5828 } 5829 5830 boolean doRename(int status, final String pkgName, String oldCodePath) { 5831 if (status != PackageManager.INSTALL_SUCCEEDED) { 5832 cleanUp(); 5833 return false; 5834 } else { 5835 // Rename based on packageName 5836 File codeFile = new File(getCodePath()); 5837 String apkName = getNextCodePath(oldCodePath, pkgName, ".apk"); 5838 File desFile = new File(installDir, apkName + ".apk"); 5839 if (!codeFile.renameTo(desFile)) { 5840 return false; 5841 } 5842 // Reset paths since the file has been renamed. 5843 codeFileName = desFile.getPath(); 5844 resourceFileName = getResourcePathFromCodePath(); 5845 // Set permissions 5846 if (!setPermissions()) { 5847 // Failed setting permissions. 5848 return false; 5849 } 5850 return true; 5851 } 5852 } 5853 5854 int doPostInstall(int status) { 5855 if (status != PackageManager.INSTALL_SUCCEEDED) { 5856 cleanUp(); 5857 } 5858 return status; 5859 } 5860 5861 String getResourcePath() { 5862 return resourceFileName; 5863 } 5864 5865 String getResourcePathFromCodePath() { 5866 String codePath = getCodePath(); 5867 if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { 5868 String apkNameOnly = getApkName(codePath); 5869 return mAppInstallDir.getPath() + "/" + apkNameOnly + ".zip"; 5870 } else { 5871 return codePath; 5872 } 5873 } 5874 5875 @Override 5876 String getNativeLibraryPath() { 5877 return libraryPath; 5878 } 5879 5880 private boolean cleanUp() { 5881 boolean ret = true; 5882 String sourceDir = getCodePath(); 5883 String publicSourceDir = getResourcePath(); 5884 if (sourceDir != null) { 5885 File sourceFile = new File(sourceDir); 5886 if (!sourceFile.exists()) { 5887 Slog.w(TAG, "Package source " + sourceDir + " does not exist."); 5888 ret = false; 5889 } 5890 // Delete application's code and resources 5891 sourceFile.delete(); 5892 } 5893 if (publicSourceDir != null && !publicSourceDir.equals(sourceDir)) { 5894 final File publicSourceFile = new File(publicSourceDir); 5895 if (!publicSourceFile.exists()) { 5896 Slog.w(TAG, "Package public source " + publicSourceFile + " does not exist."); 5897 } 5898 if (publicSourceFile.exists()) { 5899 publicSourceFile.delete(); 5900 } 5901 } 5902 return ret; 5903 } 5904 5905 void cleanUpResourcesLI() { 5906 String sourceDir = getCodePath(); 5907 if (cleanUp()) { 5908 int retCode = mInstaller.rmdex(sourceDir); 5909 if (retCode < 0) { 5910 Slog.w(TAG, "Couldn't remove dex file for package: " 5911 + " at location " 5912 + sourceDir + ", retcode=" + retCode); 5913 // we don't consider this to be a failure of the core package deletion 5914 } 5915 } 5916 } 5917 5918 private boolean setPermissions() { 5919 // TODO Do this in a more elegant way later on. for now just a hack 5920 if (!isFwdLocked()) { 5921 final int filePermissions = 5922 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP 5923 |FileUtils.S_IROTH; 5924 int retCode = FileUtils.setPermissions(getCodePath(), filePermissions, -1, -1); 5925 if (retCode != 0) { 5926 Slog.e(TAG, "Couldn't set new package file permissions for " + 5927 getCodePath() 5928 + ". The return code was: " + retCode); 5929 // TODO Define new internal error 5930 return false; 5931 } 5932 return true; 5933 } 5934 return true; 5935 } 5936 5937 boolean doPostDeleteLI(boolean delete) { 5938 // XXX err, shouldn't we respect the delete flag? 5939 cleanUpResourcesLI(); 5940 return true; 5941 } 5942 5943 private boolean isFwdLocked() { 5944 return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 5945 } 5946 } 5947 5948 /** 5949 * Extract the MountService "container ID" from the full code path of an 5950 * .apk. 5951 */ 5952 static String cidFromCodePath(String fullCodePath) { 5953 int eidx = fullCodePath.lastIndexOf("/"); 5954 String subStr1 = fullCodePath.substring(0, eidx); 5955 int sidx = subStr1.lastIndexOf("/"); 5956 return subStr1.substring(sidx+1, eidx); 5957 } 5958 5959 class SdInstallArgs extends InstallArgs { 5960 static final String RES_FILE_NAME = "pkg.apk"; 5961 5962 String cid; 5963 String packagePath; 5964 String libraryPath; 5965 5966 SdInstallArgs(InstallParams params) { 5967 super(params.packageURI, params.observer, params.flags, params.installerPackageName, 5968 params.manifestDigest); 5969 } 5970 5971 SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) { 5972 super(null, null, PackageManager.INSTALL_EXTERNAL, null, null); 5973 // Extract cid from fullCodePath 5974 int eidx = fullCodePath.lastIndexOf("/"); 5975 String subStr1 = fullCodePath.substring(0, eidx); 5976 int sidx = subStr1.lastIndexOf("/"); 5977 cid = subStr1.substring(sidx+1, eidx); 5978 setCachePath(subStr1); 5979 } 5980 5981 SdInstallArgs(String cid) { 5982 super(null, null, PackageManager.INSTALL_EXTERNAL, null, null); 5983 this.cid = cid; 5984 setCachePath(PackageHelper.getSdDir(cid)); 5985 } 5986 5987 SdInstallArgs(Uri packageURI, String cid) { 5988 super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null, null); 5989 this.cid = cid; 5990 } 5991 5992 void createCopyFile() { 5993 cid = getTempContainerId(); 5994 } 5995 5996 boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { 5997 try { 5998 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 5999 Intent.FLAG_GRANT_READ_URI_PERMISSION); 6000 return imcs.checkExternalFreeStorage(packageURI); 6001 } finally { 6002 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 6003 } 6004 } 6005 6006 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 6007 if (temp) { 6008 createCopyFile(); 6009 } else { 6010 /* 6011 * Pre-emptively destroy the container since it's destroyed if 6012 * copying fails due to it existing anyway. 6013 */ 6014 PackageHelper.destroySdDir(cid); 6015 } 6016 6017 final String newCachePath; 6018 try { 6019 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, 6020 Intent.FLAG_GRANT_READ_URI_PERMISSION); 6021 newCachePath = imcs.copyResourceToContainer(packageURI, cid, 6022 getEncryptKey(), RES_FILE_NAME); 6023 } finally { 6024 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); 6025 } 6026 6027 if (newCachePath != null) { 6028 setCachePath(newCachePath); 6029 return PackageManager.INSTALL_SUCCEEDED; 6030 } else { 6031 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 6032 } 6033 } 6034 6035 @Override 6036 String getCodePath() { 6037 return packagePath; 6038 } 6039 6040 @Override 6041 String getResourcePath() { 6042 return packagePath; 6043 } 6044 6045 @Override 6046 String getNativeLibraryPath() { 6047 return libraryPath; 6048 } 6049 6050 int doPreInstall(int status) { 6051 if (status != PackageManager.INSTALL_SUCCEEDED) { 6052 // Destroy container 6053 PackageHelper.destroySdDir(cid); 6054 } else { 6055 boolean mounted = PackageHelper.isContainerMounted(cid); 6056 if (!mounted) { 6057 String newCachePath = PackageHelper.mountSdDir(cid, getEncryptKey(), 6058 Process.SYSTEM_UID); 6059 if (newCachePath != null) { 6060 setCachePath(newCachePath); 6061 } else { 6062 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 6063 } 6064 } 6065 } 6066 return status; 6067 } 6068 6069 boolean doRename(int status, final String pkgName, 6070 String oldCodePath) { 6071 String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME); 6072 String newCachePath = null; 6073 if (PackageHelper.isContainerMounted(cid)) { 6074 // Unmount the container 6075 if (!PackageHelper.unMountSdDir(cid)) { 6076 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 6077 return false; 6078 } 6079 } 6080 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 6081 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 6082 " which might be stale. Will try to clean up."); 6083 // Clean up the stale container and proceed to recreate. 6084 if (!PackageHelper.destroySdDir(newCacheId)) { 6085 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 6086 return false; 6087 } 6088 // Successfully cleaned up stale container. Try to rename again. 6089 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 6090 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 6091 + " inspite of cleaning it up."); 6092 return false; 6093 } 6094 } 6095 if (!PackageHelper.isContainerMounted(newCacheId)) { 6096 Slog.w(TAG, "Mounting container " + newCacheId); 6097 newCachePath = PackageHelper.mountSdDir(newCacheId, 6098 getEncryptKey(), Process.SYSTEM_UID); 6099 } else { 6100 newCachePath = PackageHelper.getSdDir(newCacheId); 6101 } 6102 if (newCachePath == null) { 6103 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 6104 return false; 6105 } 6106 Log.i(TAG, "Succesfully renamed " + cid + 6107 " to " + newCacheId + 6108 " at new path: " + newCachePath); 6109 cid = newCacheId; 6110 setCachePath(newCachePath); 6111 return true; 6112 } 6113 6114 private void setCachePath(String newCachePath) { 6115 File cachePath = new File(newCachePath); 6116 libraryPath = new File(cachePath, LIB_DIR_NAME).getPath(); 6117 packagePath = new File(cachePath, RES_FILE_NAME).getPath(); 6118 } 6119 6120 int doPostInstall(int status) { 6121 if (status != PackageManager.INSTALL_SUCCEEDED) { 6122 cleanUp(); 6123 } else { 6124 boolean mounted = PackageHelper.isContainerMounted(cid); 6125 if (!mounted) { 6126 PackageHelper.mountSdDir(cid, 6127 getEncryptKey(), Process.myUid()); 6128 } 6129 } 6130 return status; 6131 } 6132 6133 private void cleanUp() { 6134 // Destroy secure container 6135 PackageHelper.destroySdDir(cid); 6136 } 6137 6138 void cleanUpResourcesLI() { 6139 String sourceFile = getCodePath(); 6140 // Remove dex file 6141 int retCode = mInstaller.rmdex(sourceFile); 6142 if (retCode < 0) { 6143 Slog.w(TAG, "Couldn't remove dex file for package: " 6144 + " at location " 6145 + sourceFile.toString() + ", retcode=" + retCode); 6146 // we don't consider this to be a failure of the core package deletion 6147 } 6148 cleanUp(); 6149 } 6150 6151 boolean matchContainer(String app) { 6152 if (cid.startsWith(app)) { 6153 return true; 6154 } 6155 return false; 6156 } 6157 6158 String getPackageName() { 6159 int idx = cid.lastIndexOf("-"); 6160 if (idx == -1) { 6161 return cid; 6162 } 6163 return cid.substring(0, idx); 6164 } 6165 6166 boolean doPostDeleteLI(boolean delete) { 6167 boolean ret = false; 6168 boolean mounted = PackageHelper.isContainerMounted(cid); 6169 if (mounted) { 6170 // Unmount first 6171 ret = PackageHelper.unMountSdDir(cid); 6172 } 6173 if (ret && delete) { 6174 cleanUpResourcesLI(); 6175 } 6176 return ret; 6177 } 6178 }; 6179 6180 // Utility method used to create code paths based on package name and available index. 6181 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 6182 String idxStr = ""; 6183 int idx = 1; 6184 // Fall back to default value of idx=1 if prefix is not 6185 // part of oldCodePath 6186 if (oldCodePath != null) { 6187 String subStr = oldCodePath; 6188 // Drop the suffix right away 6189 if (subStr.endsWith(suffix)) { 6190 subStr = subStr.substring(0, subStr.length() - suffix.length()); 6191 } 6192 // If oldCodePath already contains prefix find out the 6193 // ending index to either increment or decrement. 6194 int sidx = subStr.lastIndexOf(prefix); 6195 if (sidx != -1) { 6196 subStr = subStr.substring(sidx + prefix.length()); 6197 if (subStr != null) { 6198 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 6199 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 6200 } 6201 try { 6202 idx = Integer.parseInt(subStr); 6203 if (idx <= 1) { 6204 idx++; 6205 } else { 6206 idx--; 6207 } 6208 } catch(NumberFormatException e) { 6209 } 6210 } 6211 } 6212 } 6213 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 6214 return prefix + idxStr; 6215 } 6216 6217 // Utility method used to ignore ADD/REMOVE events 6218 // by directory observer. 6219 private static boolean ignoreCodePath(String fullPathStr) { 6220 String apkName = getApkName(fullPathStr); 6221 int idx = apkName.lastIndexOf(INSTALL_PACKAGE_SUFFIX); 6222 if (idx != -1 && ((idx+1) < apkName.length())) { 6223 // Make sure the package ends with a numeral 6224 String version = apkName.substring(idx+1); 6225 try { 6226 Integer.parseInt(version); 6227 return true; 6228 } catch (NumberFormatException e) {} 6229 } 6230 return false; 6231 } 6232 6233 // Utility method that returns the relative package path with respect 6234 // to the installation directory. Like say for /data/data/com.test-1.apk 6235 // string com.test-1 is returned. 6236 static String getApkName(String codePath) { 6237 if (codePath == null) { 6238 return null; 6239 } 6240 int sidx = codePath.lastIndexOf("/"); 6241 int eidx = codePath.lastIndexOf("."); 6242 if (eidx == -1) { 6243 eidx = codePath.length(); 6244 } else if (eidx == 0) { 6245 Slog.w(TAG, " Invalid code path, "+ codePath + " Not a valid apk name"); 6246 return null; 6247 } 6248 return codePath.substring(sidx+1, eidx); 6249 } 6250 6251 class PackageInstalledInfo { 6252 String name; 6253 int uid; 6254 PackageParser.Package pkg; 6255 int returnCode; 6256 PackageRemovedInfo removedInfo; 6257 } 6258 6259 /* 6260 * Install a non-existing package. 6261 */ 6262 private void installNewPackageLI(PackageParser.Package pkg, 6263 int parseFlags, 6264 int scanMode, 6265 String installerPackageName, PackageInstalledInfo res) { 6266 // Remember this for later, in case we need to rollback this install 6267 String pkgName = pkg.packageName; 6268 6269 boolean dataDirExists = getDataPathForPackage(pkg.packageName, 0).exists(); 6270 res.name = pkgName; 6271 synchronized(mPackages) { 6272 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 6273 // A package with the same name is already installed, though 6274 // it has been renamed to an older name. The package we 6275 // are trying to install should be installed as an update to 6276 // the existing one, but that has not been requested, so bail. 6277 Slog.w(TAG, "Attempt to re-install " + pkgName 6278 + " without first uninstalling package running as " 6279 + mSettings.mRenamedPackages.get(pkgName)); 6280 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 6281 return; 6282 } 6283 if (mPackages.containsKey(pkgName) || mAppDirs.containsKey(pkg.mPath)) { 6284 // Don't allow installation over an existing package with the same name. 6285 Slog.w(TAG, "Attempt to re-install " + pkgName 6286 + " without first uninstalling."); 6287 res.returnCode = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 6288 return; 6289 } 6290 } 6291 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 6292 PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode, 6293 System.currentTimeMillis()); 6294 if (newPackage == null) { 6295 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 6296 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 6297 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 6298 } 6299 } else { 6300 updateSettingsLI(newPackage, 6301 installerPackageName, 6302 res); 6303 // delete the partially installed application. the data directory will have to be 6304 // restored if it was already existing 6305 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 6306 // remove package from internal structures. Note that we want deletePackageX to 6307 // delete the package data and cache directories that it created in 6308 // scanPackageLocked, unless those directories existed before we even tried to 6309 // install. 6310 deletePackageLI( 6311 pkgName, false, 6312 dataDirExists ? PackageManager.DONT_DELETE_DATA : 0, 6313 res.removedInfo, true); 6314 } 6315 } 6316 } 6317 6318 private void replacePackageLI(PackageParser.Package pkg, 6319 int parseFlags, 6320 int scanMode, 6321 String installerPackageName, PackageInstalledInfo res) { 6322 6323 PackageParser.Package oldPackage; 6324 String pkgName = pkg.packageName; 6325 // First find the old package info and check signatures 6326 synchronized(mPackages) { 6327 oldPackage = mPackages.get(pkgName); 6328 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 6329 != PackageManager.SIGNATURE_MATCH) { 6330 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 6331 return; 6332 } 6333 } 6334 boolean sysPkg = (isSystemApp(oldPackage)); 6335 if (sysPkg) { 6336 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res); 6337 } else { 6338 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, installerPackageName, res); 6339 } 6340 } 6341 6342 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 6343 PackageParser.Package pkg, 6344 int parseFlags, int scanMode, 6345 String installerPackageName, PackageInstalledInfo res) { 6346 PackageParser.Package newPackage = null; 6347 String pkgName = deletedPackage.packageName; 6348 boolean deletedPkg = true; 6349 boolean updatedSettings = false; 6350 6351 long origUpdateTime; 6352 if (pkg.mExtras != null) { 6353 origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime; 6354 } else { 6355 origUpdateTime = 0; 6356 } 6357 6358 // First delete the existing package while retaining the data directory 6359 if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA, 6360 res.removedInfo, true)) { 6361 // If the existing package wasn't successfully deleted 6362 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 6363 deletedPkg = false; 6364 } else { 6365 // Successfully deleted the old package. Now proceed with re-installation 6366 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 6367 newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME, 6368 System.currentTimeMillis()); 6369 if (newPackage == null) { 6370 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 6371 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 6372 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 6373 } 6374 } else { 6375 updateSettingsLI(newPackage, 6376 installerPackageName, 6377 res); 6378 updatedSettings = true; 6379 } 6380 } 6381 6382 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 6383 // remove package from internal structures. Note that we want deletePackageX to 6384 // delete the package data and cache directories that it created in 6385 // scanPackageLocked, unless those directories existed before we even tried to 6386 // install. 6387 if(updatedSettings) { 6388 deletePackageLI( 6389 pkgName, true, 6390 PackageManager.DONT_DELETE_DATA, 6391 res.removedInfo, true); 6392 } 6393 // Since we failed to install the new package we need to restore the old 6394 // package that we deleted. 6395 if(deletedPkg) { 6396 File restoreFile = new File(deletedPackage.mPath); 6397 if (restoreFile == null) { 6398 Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName); 6399 return; 6400 } 6401 // Parse old package 6402 boolean oldOnSd = isExternal(deletedPackage); 6403 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 6404 (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) | 6405 (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0); 6406 int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE 6407 | SCAN_UPDATE_TIME; 6408 if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode, 6409 origUpdateTime) == null) { 6410 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade"); 6411 return; 6412 } 6413 // Restore of old package succeeded. Update permissions. 6414 // writer 6415 synchronized (mPackages) { 6416 updatePermissionsLPw(deletedPackage.packageName, deletedPackage, 6417 true, false, false); 6418 // can downgrade to reader 6419 mSettings.writeLPr(); 6420 } 6421 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 6422 } 6423 } 6424 } 6425 6426 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 6427 PackageParser.Package pkg, 6428 int parseFlags, int scanMode, 6429 String installerPackageName, PackageInstalledInfo res) { 6430 PackageParser.Package newPackage = null; 6431 boolean updatedSettings = false; 6432 parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING | 6433 PackageParser.PARSE_IS_SYSTEM; 6434 String packageName = deletedPackage.packageName; 6435 res.returnCode = PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 6436 if (packageName == null) { 6437 Slog.w(TAG, "Attempt to delete null packageName."); 6438 return; 6439 } 6440 PackageParser.Package oldPkg; 6441 PackageSetting oldPkgSetting; 6442 // reader 6443 synchronized (mPackages) { 6444 oldPkg = mPackages.get(packageName); 6445 oldPkgSetting = mSettings.mPackages.get(packageName); 6446 if((oldPkg == null) || (oldPkg.applicationInfo == null) || 6447 (oldPkgSetting == null)) { 6448 Slog.w(TAG, "Couldn't find package:"+packageName+" information"); 6449 return; 6450 } 6451 } 6452 6453 killApplication(packageName, oldPkg.applicationInfo.uid); 6454 6455 res.removedInfo.uid = oldPkg.applicationInfo.uid; 6456 res.removedInfo.removedPackage = packageName; 6457 // Remove existing system package 6458 removePackageLI(oldPkg, true); 6459 // writer 6460 synchronized (mPackages) { 6461 if (!mSettings.disableSystemPackageLPw(packageName) && deletedPackage != null) { 6462 // We didn't need to disable the .apk as a current system package, 6463 // which means we are replacing another update that is already 6464 // installed. We need to make sure to delete the older one's .apk. 6465 res.removedInfo.args = createInstallArgs(isExternal(pkg) 6466 ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL, 6467 deletedPackage.applicationInfo.sourceDir, 6468 deletedPackage.applicationInfo.publicSourceDir, 6469 deletedPackage.applicationInfo.nativeLibraryDir); 6470 } else { 6471 res.removedInfo.args = null; 6472 } 6473 } 6474 6475 // Successfully disabled the old package. Now proceed with re-installation 6476 mLastScanError = PackageManager.INSTALL_SUCCEEDED; 6477 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 6478 newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0); 6479 if (newPackage == null) { 6480 Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); 6481 if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { 6482 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_APK; 6483 } 6484 } else { 6485 if (newPackage.mExtras != null) { 6486 final PackageSetting newPkgSetting = (PackageSetting)newPackage.mExtras; 6487 newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime; 6488 newPkgSetting.lastUpdateTime = System.currentTimeMillis(); 6489 } 6490 updateSettingsLI(newPackage, installerPackageName, res); 6491 updatedSettings = true; 6492 } 6493 6494 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 6495 // Re installation failed. Restore old information 6496 // Remove new pkg information 6497 if (newPackage != null) { 6498 removePackageLI(newPackage, true); 6499 } 6500 // Add back the old system package 6501 scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0); 6502 // Restore the old system information in Settings 6503 synchronized(mPackages) { 6504 if (updatedSettings) { 6505 mSettings.enableSystemPackageLPw(packageName); 6506 mSettings.setInstallerPackageName(packageName, 6507 oldPkgSetting.installerPackageName); 6508 } 6509 mSettings.writeLPr(); 6510 } 6511 } 6512 } 6513 6514 // Utility method used to move dex files during install. 6515 private int moveDexFilesLI(PackageParser.Package newPackage) { 6516 int retCode; 6517 if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) { 6518 retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath); 6519 if (retCode != 0) { 6520 if (mNoDexOpt) { 6521 /* 6522 * If we're in an engineering build, programs are lazily run 6523 * through dexopt. If the .dex file doesn't exist yet, it 6524 * will be created when the program is run next. 6525 */ 6526 Slog.i(TAG, "dex file doesn't exist, skipping move: " + newPackage.mPath); 6527 } else { 6528 Slog.e(TAG, "Couldn't rename dex file: " + newPackage.mPath); 6529 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 6530 } 6531 } 6532 } 6533 return PackageManager.INSTALL_SUCCEEDED; 6534 } 6535 6536 private void updateSettingsLI(PackageParser.Package newPackage, 6537 String installerPackageName, PackageInstalledInfo res) { 6538 String pkgName = newPackage.packageName; 6539 synchronized (mPackages) { 6540 //write settings. the installStatus will be incomplete at this stage. 6541 //note that the new package setting would have already been 6542 //added to mPackages. It hasn't been persisted yet. 6543 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 6544 mSettings.writeLPr(); 6545 } 6546 6547 if ((res.returnCode = moveDexFilesLI(newPackage)) 6548 != PackageManager.INSTALL_SUCCEEDED) { 6549 // Discontinue if moving dex files failed. 6550 return; 6551 } 6552 if((res.returnCode = setPermissionsLI(newPackage)) 6553 != PackageManager.INSTALL_SUCCEEDED) { 6554 mInstaller.rmdex(newPackage.mScanPath); 6555 return; 6556 } else { 6557 Log.d(TAG, "New package installed in " + newPackage.mPath); 6558 } 6559 synchronized (mPackages) { 6560 updatePermissionsLPw(newPackage.packageName, newPackage, 6561 newPackage.permissions.size() > 0, true, false); 6562 res.name = pkgName; 6563 res.uid = newPackage.applicationInfo.uid; 6564 res.pkg = newPackage; 6565 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 6566 mSettings.setInstallerPackageName(pkgName, installerPackageName); 6567 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 6568 //to update install status 6569 mSettings.writeLPr(); 6570 } 6571 } 6572 6573 private void installPackageLI(InstallArgs args, 6574 boolean newInstall, PackageInstalledInfo res) { 6575 int pFlags = args.flags; 6576 String installerPackageName = args.installerPackageName; 6577 File tmpPackageFile = new File(args.getCodePath()); 6578 boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 6579 boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0); 6580 boolean replace = false; 6581 int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE 6582 | (newInstall ? SCAN_NEW_INSTALL : 0); 6583 // Result object to be returned 6584 res.returnCode = PackageManager.INSTALL_SUCCEEDED; 6585 6586 // Retrieve PackageSettings and parse package 6587 int parseFlags = PackageParser.PARSE_CHATTY | 6588 (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) | 6589 (onSd ? PackageParser.PARSE_ON_SDCARD : 0); 6590 parseFlags |= mDefParseFlags; 6591 PackageParser pp = new PackageParser(tmpPackageFile.getPath()); 6592 pp.setSeparateProcesses(mSeparateProcesses); 6593 final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile, 6594 null, mMetrics, parseFlags); 6595 if (pkg == null) { 6596 res.returnCode = pp.getParseError(); 6597 return; 6598 } 6599 String pkgName = res.name = pkg.packageName; 6600 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 6601 if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) { 6602 res.returnCode = PackageManager.INSTALL_FAILED_TEST_ONLY; 6603 return; 6604 } 6605 } 6606 if (GET_CERTIFICATES && !pp.collectCertificates(pkg, parseFlags)) { 6607 res.returnCode = pp.getParseError(); 6608 return; 6609 } 6610 6611 /* If the installer passed in a manifest digest, compare it now. */ 6612 if (args.manifestDigest != null) { 6613 if (DEBUG_INSTALL) { 6614 final String parsedManifest = pkg.manifestDigest == null ? "null" 6615 : pkg.manifestDigest.toString(); 6616 Slog.d(TAG, "Comparing manifests: " + args.manifestDigest.toString() + " vs. " 6617 + parsedManifest); 6618 } 6619 6620 if (!args.manifestDigest.equals(pkg.manifestDigest)) { 6621 res.returnCode = PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 6622 return; 6623 } 6624 } else if (DEBUG_INSTALL) { 6625 final String parsedManifest = pkg.manifestDigest == null 6626 ? "null" : pkg.manifestDigest.toString(); 6627 Slog.d(TAG, "manifestDigest was not present, but parser got: " + parsedManifest); 6628 } 6629 6630 // Get rid of all references to package scan path via parser. 6631 pp = null; 6632 String oldCodePath = null; 6633 boolean systemApp = false; 6634 synchronized (mPackages) { 6635 // Check if installing already existing package 6636 if ((pFlags&PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 6637 String oldName = mSettings.mRenamedPackages.get(pkgName); 6638 if (pkg.mOriginalPackages != null 6639 && pkg.mOriginalPackages.contains(oldName) 6640 && mPackages.containsKey(oldName)) { 6641 // This package is derived from an original package, 6642 // and this device has been updating from that original 6643 // name. We must continue using the original name, so 6644 // rename the new package here. 6645 pkg.setPackageName(oldName); 6646 pkgName = pkg.packageName; 6647 replace = true; 6648 } else if (mPackages.containsKey(pkgName)) { 6649 // This package, under its official name, already exists 6650 // on the device; we should replace it. 6651 replace = true; 6652 } 6653 } 6654 PackageSetting ps = mSettings.mPackages.get(pkgName); 6655 if (ps != null) { 6656 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 6657 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 6658 systemApp = (ps.pkg.applicationInfo.flags & 6659 ApplicationInfo.FLAG_SYSTEM) != 0; 6660 } 6661 } 6662 } 6663 6664 if (systemApp && onSd) { 6665 // Disable updates to system apps on sdcard 6666 Slog.w(TAG, "Cannot install updates to system apps on sdcard"); 6667 res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 6668 return; 6669 } 6670 6671 if (!args.doRename(res.returnCode, pkgName, oldCodePath)) { 6672 res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 6673 return; 6674 } 6675 // Set application objects path explicitly after the rename 6676 setApplicationInfoPaths(pkg, args.getCodePath(), args.getResourcePath()); 6677 pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath(); 6678 if (replace) { 6679 replacePackageLI(pkg, parseFlags, scanMode, 6680 installerPackageName, res); 6681 } else { 6682 installNewPackageLI(pkg, parseFlags, scanMode, 6683 installerPackageName,res); 6684 } 6685 } 6686 6687 private int setPermissionsLI(PackageParser.Package newPackage) { 6688 int retCode = 0; 6689 // TODO Gross hack but fix later. Ideally move this to be a post installation 6690 // check after alloting uid. 6691 if (isForwardLocked(newPackage)) { 6692 File destResourceFile = new File(newPackage.applicationInfo.publicSourceDir); 6693 try { 6694 extractPublicFiles(newPackage, destResourceFile); 6695 } catch (IOException e) { 6696 Slog.e(TAG, "Couldn't create a new zip file for the public parts of a" + 6697 " forward-locked app."); 6698 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 6699 } finally { 6700 //TODO clean up the extracted public files 6701 } 6702 retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath), 6703 newPackage.applicationInfo.uid); 6704 } else { 6705 // The permissions on the resource file was set when it was copied for 6706 // non forward locked apps and apps on sdcard 6707 } 6708 6709 if (retCode != 0) { 6710 Slog.e(TAG, "Couldn't set new package file permissions for " + newPackage.mPath 6711 + ". The return code was: " + retCode); 6712 // TODO Define new internal error 6713 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 6714 } 6715 return PackageManager.INSTALL_SUCCEEDED; 6716 } 6717 6718 private static boolean isForwardLocked(PackageParser.Package pkg) { 6719 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; 6720 } 6721 6722 private static boolean isExternal(PackageParser.Package pkg) { 6723 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 6724 } 6725 6726 private static boolean isSystemApp(PackageParser.Package pkg) { 6727 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 6728 } 6729 6730 private static boolean isSystemApp(ApplicationInfo info) { 6731 return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 6732 } 6733 6734 private static boolean isUpdatedSystemApp(PackageParser.Package pkg) { 6735 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 6736 } 6737 6738 private void extractPublicFiles(PackageParser.Package newPackage, 6739 File publicZipFile) throws IOException { 6740 final FileOutputStream fstr = new FileOutputStream(publicZipFile); 6741 final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr); 6742 final ZipFile privateZip = new ZipFile(newPackage.mPath); 6743 6744 // Copy manifest, resources.arsc and res directory to public zip 6745 6746 final Enumeration<? extends ZipEntry> privateZipEntries = privateZip.entries(); 6747 while (privateZipEntries.hasMoreElements()) { 6748 final ZipEntry zipEntry = privateZipEntries.nextElement(); 6749 final String zipEntryName = zipEntry.getName(); 6750 if ("AndroidManifest.xml".equals(zipEntryName) 6751 || "resources.arsc".equals(zipEntryName) 6752 || zipEntryName.startsWith("res/")) { 6753 try { 6754 copyZipEntry(zipEntry, privateZip, publicZipOutStream); 6755 } catch (IOException e) { 6756 try { 6757 publicZipOutStream.close(); 6758 throw e; 6759 } finally { 6760 publicZipFile.delete(); 6761 } 6762 } 6763 } 6764 } 6765 6766 publicZipOutStream.finish(); 6767 publicZipOutStream.flush(); 6768 FileUtils.sync(fstr); 6769 publicZipOutStream.close(); 6770 FileUtils.setPermissions( 6771 publicZipFile.getAbsolutePath(), 6772 FileUtils.S_IRUSR|FileUtils.S_IWUSR|FileUtils.S_IRGRP|FileUtils.S_IROTH, 6773 -1, -1); 6774 } 6775 6776 private static void copyZipEntry(ZipEntry zipEntry, 6777 ZipFile inZipFile, 6778 ZipOutputStream outZipStream) throws IOException { 6779 byte[] buffer = new byte[4096]; 6780 int num; 6781 6782 ZipEntry newEntry; 6783 if (zipEntry.getMethod() == ZipEntry.STORED) { 6784 // Preserve the STORED method of the input entry. 6785 newEntry = new ZipEntry(zipEntry); 6786 } else { 6787 // Create a new entry so that the compressed len is recomputed. 6788 newEntry = new ZipEntry(zipEntry.getName()); 6789 } 6790 outZipStream.putNextEntry(newEntry); 6791 6792 InputStream data = inZipFile.getInputStream(zipEntry); 6793 while ((num = data.read(buffer)) > 0) { 6794 outZipStream.write(buffer, 0, num); 6795 } 6796 outZipStream.flush(); 6797 } 6798 6799 private void deleteTempPackageFiles() { 6800 FilenameFilter filter = new FilenameFilter() { 6801 public boolean accept(File dir, String name) { 6802 return name.startsWith("vmdl") && name.endsWith(".tmp"); 6803 } 6804 }; 6805 String tmpFilesList[] = mAppInstallDir.list(filter); 6806 if(tmpFilesList == null) { 6807 return; 6808 } 6809 for(int i = 0; i < tmpFilesList.length; i++) { 6810 File tmpFile = new File(mAppInstallDir, tmpFilesList[i]); 6811 tmpFile.delete(); 6812 } 6813 } 6814 6815 private File createTempPackageFile(File installDir) { 6816 File tmpPackageFile; 6817 try { 6818 tmpPackageFile = File.createTempFile("vmdl", ".tmp", installDir); 6819 } catch (IOException e) { 6820 Slog.e(TAG, "Couldn't create temp file for downloaded package file."); 6821 return null; 6822 } 6823 try { 6824 FileUtils.setPermissions( 6825 tmpPackageFile.getCanonicalPath(), FileUtils.S_IRUSR|FileUtils.S_IWUSR, 6826 -1, -1); 6827 } catch (IOException e) { 6828 Slog.e(TAG, "Trouble getting the canoncical path for a temp file."); 6829 return null; 6830 } 6831 return tmpPackageFile; 6832 } 6833 6834 public void deletePackage(final String packageName, 6835 final IPackageDeleteObserver observer, 6836 final int flags) { 6837 mContext.enforceCallingOrSelfPermission( 6838 android.Manifest.permission.DELETE_PACKAGES, null); 6839 // Queue up an async operation since the package deletion may take a little while. 6840 mHandler.post(new Runnable() { 6841 public void run() { 6842 mHandler.removeCallbacks(this); 6843 final int returnCode = deletePackageX(packageName, true, true, flags); 6844 if (observer != null) { 6845 try { 6846 observer.packageDeleted(packageName, returnCode); 6847 } catch (RemoteException e) { 6848 Log.i(TAG, "Observer no longer exists."); 6849 } //end catch 6850 } //end if 6851 } //end run 6852 }); 6853 } 6854 6855 /** 6856 * This method is an internal method that could be get invoked either 6857 * to delete an installed package or to clean up a failed installation. 6858 * After deleting an installed package, a broadcast is sent to notify any 6859 * listeners that the package has been installed. For cleaning up a failed 6860 * installation, the broadcast is not necessary since the package's 6861 * installation wouldn't have sent the initial broadcast either 6862 * The key steps in deleting a package are 6863 * deleting the package information in internal structures like mPackages, 6864 * deleting the packages base directories through installd 6865 * updating mSettings to reflect current status 6866 * persisting settings for later use 6867 * sending a broadcast if necessary 6868 */ 6869 private int deletePackageX(String packageName, boolean sendBroadCast, 6870 boolean deleteCodeAndResources, int flags) { 6871 final PackageRemovedInfo info = new PackageRemovedInfo(); 6872 final boolean res; 6873 6874 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 6875 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 6876 try { 6877 if (dpm != null && dpm.packageHasActiveAdmins(packageName)) { 6878 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 6879 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 6880 } 6881 } catch (RemoteException e) { 6882 } 6883 6884 synchronized (mInstallLock) { 6885 res = deletePackageLI(packageName, deleteCodeAndResources, 6886 flags | REMOVE_CHATTY, info, true); 6887 } 6888 6889 if (res && sendBroadCast) { 6890 boolean systemUpdate = info.isRemovedPackageSystemUpdate; 6891 info.sendBroadcast(deleteCodeAndResources, systemUpdate); 6892 6893 // If the removed package was a system update, the old system packaged 6894 // was re-enabled; we need to broadcast this information 6895 if (systemUpdate) { 6896 Bundle extras = new Bundle(1); 6897 extras.putInt(Intent.EXTRA_UID, info.removedUid >= 0 ? info.removedUid : info.uid); 6898 extras.putBoolean(Intent.EXTRA_REPLACING, true); 6899 6900 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 6901 extras, null, null); 6902 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName, 6903 extras, null, null); 6904 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 6905 null, packageName, null); 6906 } 6907 } 6908 // Force a gc here. 6909 Runtime.getRuntime().gc(); 6910 // Delete the resources here after sending the broadcast to let 6911 // other processes clean up before deleting resources. 6912 if (info.args != null) { 6913 synchronized (mInstallLock) { 6914 info.args.doPostDeleteLI(deleteCodeAndResources); 6915 } 6916 } 6917 6918 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 6919 } 6920 6921 static class PackageRemovedInfo { 6922 String removedPackage; 6923 int uid = -1; 6924 int removedUid = -1; 6925 boolean isRemovedPackageSystemUpdate = false; 6926 // Clean up resources deleted packages. 6927 InstallArgs args = null; 6928 6929 void sendBroadcast(boolean fullRemove, boolean replacing) { 6930 Bundle extras = new Bundle(1); 6931 extras.putInt(Intent.EXTRA_UID, removedUid >= 0 ? removedUid : uid); 6932 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove); 6933 if (replacing) { 6934 extras.putBoolean(Intent.EXTRA_REPLACING, true); 6935 } 6936 if (removedPackage != null) { 6937 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 6938 extras, null, null); 6939 if (fullRemove && !replacing) { 6940 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage, 6941 extras, null, null); 6942 } 6943 } 6944 if (removedUid >= 0) { 6945 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, null, null); 6946 } 6947 } 6948 } 6949 6950 /* 6951 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 6952 * flag is not set, the data directory is removed as well. 6953 * make sure this flag is set for partially installed apps. If not its meaningless to 6954 * delete a partially installed application. 6955 */ 6956 private void removePackageDataLI(PackageParser.Package p, PackageRemovedInfo outInfo, 6957 int flags, boolean writeSettings) { 6958 String packageName = p.packageName; 6959 if (outInfo != null) { 6960 outInfo.removedPackage = packageName; 6961 } 6962 removePackageLI(p, (flags&REMOVE_CHATTY) != 0); 6963 // Retrieve object to delete permissions for shared user later on 6964 final PackageSetting deletedPs; 6965 // reader 6966 synchronized (mPackages) { 6967 deletedPs = mSettings.mPackages.get(packageName); 6968 } 6969 if ((flags&PackageManager.DONT_DELETE_DATA) == 0) { 6970 int retCode = mInstaller.remove(packageName, 0); 6971 if (retCode < 0) { 6972 Slog.w(TAG, "Couldn't remove app data or cache directory for package: " 6973 + packageName + ", retcode=" + retCode); 6974 // we don't consider this to be a failure of the core package deletion 6975 } else { 6976 // TODO: Kill the processes first 6977 mUserManager.removePackageForAllUsers(packageName); 6978 } 6979 schedulePackageCleaning(packageName); 6980 } 6981 // writer 6982 synchronized (mPackages) { 6983 if (deletedPs != null) { 6984 if ((flags&PackageManager.DONT_DELETE_DATA) == 0) { 6985 if (outInfo != null) { 6986 outInfo.removedUid = mSettings.removePackageLPw(packageName); 6987 } 6988 if (deletedPs != null) { 6989 updatePermissionsLPw(deletedPs.name, null, false, false, false); 6990 if (deletedPs.sharedUser != null) { 6991 // remove permissions associated with package 6992 mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids); 6993 } 6994 } 6995 } 6996 // remove from preferred activities. 6997 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 6998 for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) { 6999 if (pa.mPref.mComponent.getPackageName().equals(deletedPs.name)) { 7000 removed.add(pa); 7001 } 7002 } 7003 for (PreferredActivity pa : removed) { 7004 mSettings.mPreferredActivities.removeFilter(pa); 7005 } 7006 } 7007 // can downgrade to reader 7008 if (writeSettings) { 7009 // Save settings now 7010 mSettings.writeLPr(); 7011 } 7012 } 7013 } 7014 7015 /* 7016 * Tries to delete system package. 7017 */ 7018 private boolean deleteSystemPackageLI(PackageParser.Package p, 7019 int flags, PackageRemovedInfo outInfo, boolean writeSettings) { 7020 ApplicationInfo applicationInfo = p.applicationInfo; 7021 //applicable for non-partially installed applications only 7022 if (applicationInfo == null) { 7023 Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo."); 7024 return false; 7025 } 7026 PackageSetting ps = null; 7027 // Confirm if the system package has been updated 7028 // An updated system app can be deleted. This will also have to restore 7029 // the system pkg from system partition 7030 // reader 7031 synchronized (mPackages) { 7032 ps = mSettings.getDisabledSystemPkgLPr(p.packageName); 7033 } 7034 if (ps == null) { 7035 Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName); 7036 return false; 7037 } else { 7038 Log.i(TAG, "Deleting system pkg from data partition"); 7039 } 7040 // Delete the updated package 7041 outInfo.isRemovedPackageSystemUpdate = true; 7042 if (ps.versionCode < p.mVersionCode) { 7043 // Delete data for downgrades 7044 flags &= ~PackageManager.DONT_DELETE_DATA; 7045 } else { 7046 // Preserve data by setting flag 7047 flags |= PackageManager.DONT_DELETE_DATA; 7048 } 7049 boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo, 7050 writeSettings); 7051 if (!ret) { 7052 return false; 7053 } 7054 // writer 7055 synchronized (mPackages) { 7056 // Reinstate the old system package 7057 mSettings.enableSystemPackageLPw(p.packageName); 7058 // Remove any native libraries from the upgraded package. 7059 NativeLibraryHelper.removeNativeBinariesLI(p.applicationInfo.nativeLibraryDir); 7060 } 7061 // Install the system package 7062 PackageParser.Package newPkg = scanPackageLI(ps.codePath, 7063 PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM, 7064 SCAN_MONITOR | SCAN_NO_PATHS, 0); 7065 7066 if (newPkg == null) { 7067 Slog.w(TAG, "Failed to restore system package:"+p.packageName+" with error:" + mLastScanError); 7068 return false; 7069 } 7070 // writer 7071 synchronized (mPackages) { 7072 updatePermissionsLPw(newPkg.packageName, newPkg, true, true, false); 7073 // can downgrade to reader here 7074 if (writeSettings) { 7075 mSettings.writeLPr(); 7076 } 7077 } 7078 return true; 7079 } 7080 7081 private boolean deleteInstalledPackageLI(PackageParser.Package p, 7082 boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo, 7083 boolean writeSettings) { 7084 ApplicationInfo applicationInfo = p.applicationInfo; 7085 if (applicationInfo == null) { 7086 Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo."); 7087 return false; 7088 } 7089 if (outInfo != null) { 7090 outInfo.uid = applicationInfo.uid; 7091 } 7092 7093 // Delete package data from internal structures and also remove data if flag is set 7094 removePackageDataLI(p, outInfo, flags, writeSettings); 7095 7096 // Delete application code and resources 7097 if (deleteCodeAndResources) { 7098 // TODO can pick up from PackageSettings as well 7099 int installFlags = isExternal(p) ? PackageManager.INSTALL_EXTERNAL : 0; 7100 installFlags |= isForwardLocked(p) ? PackageManager.INSTALL_FORWARD_LOCK : 0; 7101 outInfo.args = createInstallArgs(installFlags, applicationInfo.sourceDir, 7102 applicationInfo.publicSourceDir, applicationInfo.nativeLibraryDir); 7103 } 7104 return true; 7105 } 7106 7107 /* 7108 * This method handles package deletion in general 7109 */ 7110 private boolean deletePackageLI(String packageName, 7111 boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo, 7112 boolean writeSettings) { 7113 if (packageName == null) { 7114 Slog.w(TAG, "Attempt to delete null packageName."); 7115 return false; 7116 } 7117 PackageParser.Package p; 7118 boolean dataOnly = false; 7119 synchronized (mPackages) { 7120 p = mPackages.get(packageName); 7121 if (p == null) { 7122 //this retrieves partially installed apps 7123 dataOnly = true; 7124 PackageSetting ps = mSettings.mPackages.get(packageName); 7125 if (ps == null) { 7126 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 7127 return false; 7128 } 7129 p = ps.pkg; 7130 } 7131 } 7132 if (p == null) { 7133 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 7134 return false; 7135 } 7136 7137 if (dataOnly) { 7138 // Delete application data first 7139 removePackageDataLI(p, outInfo, flags, writeSettings); 7140 return true; 7141 } 7142 // At this point the package should have ApplicationInfo associated with it 7143 if (p.applicationInfo == null) { 7144 Slog.w(TAG, "Package " + p.packageName + " has no applicationInfo."); 7145 return false; 7146 } 7147 boolean ret = false; 7148 if (isSystemApp(p)) { 7149 Log.i(TAG, "Removing system package:"+p.packageName); 7150 // When an updated system application is deleted we delete the existing resources as well and 7151 // fall back to existing code in system partition 7152 ret = deleteSystemPackageLI(p, flags, outInfo, writeSettings); 7153 } else { 7154 Log.i(TAG, "Removing non-system package:"+p.packageName); 7155 // Kill application pre-emptively especially for apps on sd. 7156 killApplication(packageName, p.applicationInfo.uid); 7157 ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo, 7158 writeSettings); 7159 } 7160 return ret; 7161 } 7162 7163 public void clearApplicationUserData(final String packageName, 7164 final IPackageDataObserver observer) { 7165 mContext.enforceCallingOrSelfPermission( 7166 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 7167 // Queue up an async operation since the package deletion may take a little while. 7168 mHandler.post(new Runnable() { 7169 public void run() { 7170 mHandler.removeCallbacks(this); 7171 final boolean succeeded; 7172 synchronized (mInstallLock) { 7173 succeeded = clearApplicationUserDataLI(packageName); 7174 } 7175 if (succeeded) { 7176 // invoke DeviceStorageMonitor's update method to clear any notifications 7177 DeviceStorageMonitorService dsm = (DeviceStorageMonitorService) 7178 ServiceManager.getService(DeviceStorageMonitorService.SERVICE); 7179 if (dsm != null) { 7180 dsm.updateMemory(); 7181 } 7182 } 7183 if(observer != null) { 7184 try { 7185 observer.onRemoveCompleted(packageName, succeeded); 7186 } catch (RemoteException e) { 7187 Log.i(TAG, "Observer no longer exists."); 7188 } 7189 } //end if observer 7190 } //end run 7191 }); 7192 } 7193 7194 private boolean clearApplicationUserDataLI(String packageName) { 7195 if (packageName == null) { 7196 Slog.w(TAG, "Attempt to delete null packageName."); 7197 return false; 7198 } 7199 PackageParser.Package p; 7200 boolean dataOnly = false; 7201 synchronized (mPackages) { 7202 p = mPackages.get(packageName); 7203 if(p == null) { 7204 dataOnly = true; 7205 PackageSetting ps = mSettings.mPackages.get(packageName); 7206 if((ps == null) || (ps.pkg == null)) { 7207 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 7208 return false; 7209 } 7210 p = ps.pkg; 7211 } 7212 } 7213 7214 if (!dataOnly) { 7215 //need to check this only for fully installed applications 7216 if (p == null) { 7217 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 7218 return false; 7219 } 7220 final ApplicationInfo applicationInfo = p.applicationInfo; 7221 if (applicationInfo == null) { 7222 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 7223 return false; 7224 } 7225 } 7226 int retCode = mInstaller.clearUserData(packageName, 0); // TODO - correct userId 7227 if (retCode < 0) { 7228 Slog.w(TAG, "Couldn't remove cache files for package: " 7229 + packageName); 7230 return false; 7231 } 7232 return true; 7233 } 7234 7235 public void deleteApplicationCacheFiles(final String packageName, 7236 final IPackageDataObserver observer) { 7237 mContext.enforceCallingOrSelfPermission( 7238 android.Manifest.permission.DELETE_CACHE_FILES, null); 7239 // Queue up an async operation since the package deletion may take a little while. 7240 mHandler.post(new Runnable() { 7241 public void run() { 7242 mHandler.removeCallbacks(this); 7243 final boolean succeded; 7244 synchronized (mInstallLock) { 7245 succeded = deleteApplicationCacheFilesLI(packageName); 7246 } 7247 if(observer != null) { 7248 try { 7249 observer.onRemoveCompleted(packageName, succeded); 7250 } catch (RemoteException e) { 7251 Log.i(TAG, "Observer no longer exists."); 7252 } 7253 } //end if observer 7254 } //end run 7255 }); 7256 } 7257 7258 private boolean deleteApplicationCacheFilesLI(String packageName) { 7259 if (packageName == null) { 7260 Slog.w(TAG, "Attempt to delete null packageName."); 7261 return false; 7262 } 7263 PackageParser.Package p; 7264 synchronized (mPackages) { 7265 p = mPackages.get(packageName); 7266 } 7267 if (p == null) { 7268 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 7269 return false; 7270 } 7271 final ApplicationInfo applicationInfo = p.applicationInfo; 7272 if (applicationInfo == null) { 7273 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 7274 return false; 7275 } 7276 int retCode = mInstaller.deleteCacheFiles(packageName); 7277 if (retCode < 0) { 7278 Slog.w(TAG, "Couldn't remove cache files for package: " 7279 + packageName); 7280 return false; 7281 } 7282 return true; 7283 } 7284 7285 public void getPackageSizeInfo(final String packageName, 7286 final IPackageStatsObserver observer) { 7287 mContext.enforceCallingOrSelfPermission( 7288 android.Manifest.permission.GET_PACKAGE_SIZE, null); 7289 // Queue up an async operation since the package deletion may take a little while. 7290 mHandler.post(new Runnable() { 7291 public void run() { 7292 mHandler.removeCallbacks(this); 7293 PackageStats stats = new PackageStats(packageName); 7294 7295 final boolean success; 7296 synchronized (mInstallLock) { 7297 success = getPackageSizeInfoLI(packageName, stats); 7298 } 7299 7300 Message msg = mHandler.obtainMessage(INIT_COPY); 7301 msg.obj = new MeasureParams(stats, success, observer); 7302 mHandler.sendMessage(msg); 7303 } //end run 7304 }); 7305 } 7306 7307 private boolean getPackageSizeInfoLI(String packageName, PackageStats pStats) { 7308 if (packageName == null) { 7309 Slog.w(TAG, "Attempt to get size of null packageName."); 7310 return false; 7311 } 7312 PackageParser.Package p; 7313 boolean dataOnly = false; 7314 String asecPath = null; 7315 synchronized (mPackages) { 7316 p = mPackages.get(packageName); 7317 if(p == null) { 7318 dataOnly = true; 7319 PackageSetting ps = mSettings.mPackages.get(packageName); 7320 if((ps == null) || (ps.pkg == null)) { 7321 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 7322 return false; 7323 } 7324 p = ps.pkg; 7325 } 7326 if (p != null && isExternal(p)) { 7327 String secureContainerId = cidFromCodePath(p.applicationInfo.sourceDir); 7328 if (secureContainerId != null) { 7329 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 7330 } 7331 } 7332 } 7333 String publicSrcDir = null; 7334 if(!dataOnly) { 7335 final ApplicationInfo applicationInfo = p.applicationInfo; 7336 if (applicationInfo == null) { 7337 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 7338 return false; 7339 } 7340 if (isForwardLocked(p)) { 7341 publicSrcDir = applicationInfo.publicSourceDir; 7342 } 7343 } 7344 int res = mInstaller.getSizeInfo(packageName, p.mPath, publicSrcDir, 7345 asecPath, pStats); 7346 if (res < 0) { 7347 return false; 7348 } 7349 return true; 7350 } 7351 7352 7353 public void addPackageToPreferred(String packageName) { 7354 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 7355 } 7356 7357 public void removePackageFromPreferred(String packageName) { 7358 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 7359 } 7360 7361 public List<PackageInfo> getPreferredPackages(int flags) { 7362 return new ArrayList<PackageInfo>(); 7363 } 7364 7365 private int getUidTargetSdkVersionLockedLPr(int uid) { 7366 Object obj = mSettings.getUserIdLPr(uid); 7367 if (obj instanceof SharedUserSetting) { 7368 final SharedUserSetting sus = (SharedUserSetting) obj; 7369 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 7370 final Iterator<PackageSetting> it = sus.packages.iterator(); 7371 while (it.hasNext()) { 7372 final PackageSetting ps = it.next(); 7373 if (ps.pkg != null) { 7374 int v = ps.pkg.applicationInfo.targetSdkVersion; 7375 if (v < vers) vers = v; 7376 } 7377 } 7378 return vers; 7379 } else if (obj instanceof PackageSetting) { 7380 final PackageSetting ps = (PackageSetting) obj; 7381 if (ps.pkg != null) { 7382 return ps.pkg.applicationInfo.targetSdkVersion; 7383 } 7384 } 7385 return Build.VERSION_CODES.CUR_DEVELOPMENT; 7386 } 7387 7388 public void addPreferredActivity(IntentFilter filter, int match, 7389 ComponentName[] set, ComponentName activity) { 7390 // writer 7391 synchronized (mPackages) { 7392 if (mContext.checkCallingOrSelfPermission( 7393 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 7394 != PackageManager.PERMISSION_GRANTED) { 7395 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 7396 < Build.VERSION_CODES.FROYO) { 7397 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 7398 + Binder.getCallingUid()); 7399 return; 7400 } 7401 mContext.enforceCallingOrSelfPermission( 7402 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 7403 } 7404 7405 Slog.i(TAG, "Adding preferred activity " + activity + ":"); 7406 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 7407 mSettings.mPreferredActivities.addFilter( 7408 new PreferredActivity(filter, match, set, activity)); 7409 scheduleWriteSettingsLocked(); 7410 } 7411 } 7412 7413 public void replacePreferredActivity(IntentFilter filter, int match, 7414 ComponentName[] set, ComponentName activity) { 7415 if (filter.countActions() != 1) { 7416 throw new IllegalArgumentException( 7417 "replacePreferredActivity expects filter to have only 1 action."); 7418 } 7419 if (filter.countCategories() != 1) { 7420 throw new IllegalArgumentException( 7421 "replacePreferredActivity expects filter to have only 1 category."); 7422 } 7423 if (filter.countDataAuthorities() != 0 7424 || filter.countDataPaths() != 0 7425 || filter.countDataSchemes() != 0 7426 || filter.countDataTypes() != 0) { 7427 throw new IllegalArgumentException( 7428 "replacePreferredActivity expects filter to have no data authorities, " + 7429 "paths, schemes or types."); 7430 } 7431 synchronized (mPackages) { 7432 if (mContext.checkCallingOrSelfPermission( 7433 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 7434 != PackageManager.PERMISSION_GRANTED) { 7435 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 7436 < Build.VERSION_CODES.FROYO) { 7437 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 7438 + Binder.getCallingUid()); 7439 return; 7440 } 7441 mContext.enforceCallingOrSelfPermission( 7442 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 7443 } 7444 7445 Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator(); 7446 String action = filter.getAction(0); 7447 String category = filter.getCategory(0); 7448 while (it.hasNext()) { 7449 PreferredActivity pa = it.next(); 7450 if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) { 7451 it.remove(); 7452 Log.i(TAG, "Removed preferred activity " + pa.mPref.mComponent + ":"); 7453 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 7454 } 7455 } 7456 addPreferredActivity(filter, match, set, activity); 7457 } 7458 } 7459 7460 public void clearPackagePreferredActivities(String packageName) { 7461 final int uid = Binder.getCallingUid(); 7462 // writer 7463 synchronized (mPackages) { 7464 PackageParser.Package pkg = mPackages.get(packageName); 7465 if (pkg == null || pkg.applicationInfo.uid != uid) { 7466 if (mContext.checkCallingOrSelfPermission( 7467 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 7468 != PackageManager.PERMISSION_GRANTED) { 7469 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 7470 < Build.VERSION_CODES.FROYO) { 7471 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 7472 + Binder.getCallingUid()); 7473 return; 7474 } 7475 mContext.enforceCallingOrSelfPermission( 7476 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 7477 } 7478 } 7479 7480 if (clearPackagePreferredActivitiesLPw(packageName)) { 7481 scheduleWriteSettingsLocked(); 7482 } 7483 } 7484 } 7485 7486 boolean clearPackagePreferredActivitiesLPw(String packageName) { 7487 boolean changed = false; 7488 Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator(); 7489 while (it.hasNext()) { 7490 PreferredActivity pa = it.next(); 7491 if (pa.mPref.mComponent.getPackageName().equals(packageName)) { 7492 it.remove(); 7493 changed = true; 7494 } 7495 } 7496 return changed; 7497 } 7498 7499 public int getPreferredActivities(List<IntentFilter> outFilters, 7500 List<ComponentName> outActivities, String packageName) { 7501 7502 int num = 0; 7503 // reader 7504 synchronized (mPackages) { 7505 final Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator(); 7506 while (it.hasNext()) { 7507 final PreferredActivity pa = it.next(); 7508 if (packageName == null 7509 || pa.mPref.mComponent.getPackageName().equals(packageName)) { 7510 if (outFilters != null) { 7511 outFilters.add(new IntentFilter(pa)); 7512 } 7513 if (outActivities != null) { 7514 outActivities.add(pa.mPref.mComponent); 7515 } 7516 } 7517 } 7518 } 7519 7520 return num; 7521 } 7522 7523 public void setApplicationEnabledSetting(String appPackageName, 7524 int newState, int flags) { 7525 setEnabledSetting(appPackageName, null, newState, flags); 7526 } 7527 7528 public void setComponentEnabledSetting(ComponentName componentName, 7529 int newState, int flags) { 7530 setEnabledSetting(componentName.getPackageName(), 7531 componentName.getClassName(), newState, flags); 7532 } 7533 7534 private void setEnabledSetting( 7535 final String packageName, String className, int newState, final int flags) { 7536 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 7537 || newState == COMPONENT_ENABLED_STATE_ENABLED 7538 || newState == COMPONENT_ENABLED_STATE_DISABLED 7539 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER)) { 7540 throw new IllegalArgumentException("Invalid new component state: " 7541 + newState); 7542 } 7543 PackageSetting pkgSetting; 7544 final int uid = Binder.getCallingUid(); 7545 final int permission = mContext.checkCallingPermission( 7546 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 7547 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 7548 boolean sendNow = false; 7549 boolean isApp = (className == null); 7550 String componentName = isApp ? packageName : className; 7551 int packageUid = -1; 7552 ArrayList<String> components; 7553 7554 // writer 7555 synchronized (mPackages) { 7556 pkgSetting = mSettings.mPackages.get(packageName); 7557 if (pkgSetting == null) { 7558 if (className == null) { 7559 throw new IllegalArgumentException( 7560 "Unknown package: " + packageName); 7561 } 7562 throw new IllegalArgumentException( 7563 "Unknown component: " + packageName 7564 + "/" + className); 7565 } 7566 if (!allowedByPermission && (uid != pkgSetting.userId)) { 7567 throw new SecurityException( 7568 "Permission Denial: attempt to change component state from pid=" 7569 + Binder.getCallingPid() 7570 + ", uid=" + uid + ", package uid=" + pkgSetting.userId); 7571 } 7572 if (className == null) { 7573 // We're dealing with an application/package level state change 7574 if (pkgSetting.enabled == newState) { 7575 // Nothing to do 7576 return; 7577 } 7578 pkgSetting.enabled = newState; 7579 pkgSetting.pkg.mSetEnabled = newState; 7580 } else { 7581 // We're dealing with a component level state change 7582 switch (newState) { 7583 case COMPONENT_ENABLED_STATE_ENABLED: 7584 if (!pkgSetting.enableComponentLPw(className)) { 7585 return; 7586 } 7587 break; 7588 case COMPONENT_ENABLED_STATE_DISABLED: 7589 if (!pkgSetting.disableComponentLPw(className)) { 7590 return; 7591 } 7592 break; 7593 case COMPONENT_ENABLED_STATE_DEFAULT: 7594 if (!pkgSetting.restoreComponentLPw(className)) { 7595 return; 7596 } 7597 break; 7598 default: 7599 Slog.e(TAG, "Invalid new component state: " + newState); 7600 return; 7601 } 7602 } 7603 mSettings.writeLPr(); 7604 packageUid = pkgSetting.userId; 7605 components = mPendingBroadcasts.get(packageName); 7606 final boolean newPackage = components == null; 7607 if (newPackage) { 7608 components = new ArrayList<String>(); 7609 } 7610 if (!components.contains(componentName)) { 7611 components.add(componentName); 7612 } 7613 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 7614 sendNow = true; 7615 // Purge entry from pending broadcast list if another one exists already 7616 // since we are sending one right away. 7617 mPendingBroadcasts.remove(packageName); 7618 } else { 7619 if (newPackage) { 7620 mPendingBroadcasts.put(packageName, components); 7621 } 7622 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 7623 // Schedule a message 7624 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 7625 } 7626 } 7627 } 7628 7629 long callingId = Binder.clearCallingIdentity(); 7630 try { 7631 if (sendNow) { 7632 sendPackageChangedBroadcast(packageName, 7633 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 7634 } 7635 } finally { 7636 Binder.restoreCallingIdentity(callingId); 7637 } 7638 } 7639 7640 private void sendPackageChangedBroadcast(String packageName, 7641 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 7642 if (DEBUG_INSTALL) 7643 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 7644 + componentNames); 7645 Bundle extras = new Bundle(4); 7646 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 7647 String nameList[] = new String[componentNames.size()]; 7648 componentNames.toArray(nameList); 7649 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 7650 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 7651 extras.putInt(Intent.EXTRA_UID, packageUid); 7652 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, null, null); 7653 } 7654 7655 public void setPackageStoppedState(String packageName, boolean stopped) { 7656 final int uid = Binder.getCallingUid(); 7657 final int permission = mContext.checkCallingOrSelfPermission( 7658 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 7659 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 7660 // writer 7661 synchronized (mPackages) { 7662 if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission, 7663 uid)) { 7664 scheduleWriteStoppedPackagesLocked(); 7665 } 7666 } 7667 } 7668 7669 public String getInstallerPackageName(String packageName) { 7670 // reader 7671 synchronized (mPackages) { 7672 return mSettings.getInstallerPackageNameLPr(packageName); 7673 } 7674 } 7675 7676 public int getApplicationEnabledSetting(String packageName) { 7677 // reader 7678 synchronized (mPackages) { 7679 return mSettings.getApplicationEnabledSettingLPr(packageName); 7680 } 7681 } 7682 7683 public int getComponentEnabledSetting(ComponentName componentName) { 7684 // reader 7685 synchronized (mPackages) { 7686 return mSettings.getComponentEnabledSettingLPr(componentName); 7687 } 7688 } 7689 7690 public void enterSafeMode() { 7691 enforceSystemOrRoot("Only the system can request entering safe mode"); 7692 7693 if (!mSystemReady) { 7694 mSafeMode = true; 7695 } 7696 } 7697 7698 public void systemReady() { 7699 mSystemReady = true; 7700 7701 // Read the compatibilty setting when the system is ready. 7702 boolean compatibilityModeEnabled = android.provider.Settings.System.getInt( 7703 mContext.getContentResolver(), 7704 android.provider.Settings.System.COMPATIBILITY_MODE, 1) == 1; 7705 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 7706 if (DEBUG_SETTINGS) { 7707 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 7708 } 7709 } 7710 7711 public boolean isSafeMode() { 7712 return mSafeMode; 7713 } 7714 7715 public boolean hasSystemUidErrors() { 7716 return mHasSystemUidErrors; 7717 } 7718 7719 static String arrayToString(int[] array) { 7720 StringBuffer buf = new StringBuffer(128); 7721 buf.append('['); 7722 if (array != null) { 7723 for (int i=0; i<array.length; i++) { 7724 if (i > 0) buf.append(", "); 7725 buf.append(array[i]); 7726 } 7727 } 7728 buf.append(']'); 7729 return buf.toString(); 7730 } 7731 7732 static class DumpState { 7733 public static final int DUMP_LIBS = 1 << 0; 7734 7735 public static final int DUMP_FEATURES = 1 << 1; 7736 7737 public static final int DUMP_RESOLVERS = 1 << 2; 7738 7739 public static final int DUMP_PERMISSIONS = 1 << 3; 7740 7741 public static final int DUMP_PACKAGES = 1 << 4; 7742 7743 public static final int DUMP_SHARED_USERS = 1 << 5; 7744 7745 public static final int DUMP_MESSAGES = 1 << 6; 7746 7747 public static final int DUMP_PROVIDERS = 1 << 7; 7748 7749 public static final int DUMP_VERIFIERS = 1 << 8; 7750 7751 public static final int OPTION_SHOW_FILTERS = 1 << 0; 7752 7753 private int mTypes; 7754 7755 private int mOptions; 7756 7757 private boolean mTitlePrinted; 7758 7759 private SharedUserSetting mSharedUser; 7760 7761 public boolean isDumping(int type) { 7762 if (mTypes == 0) { 7763 return true; 7764 } 7765 7766 return (mTypes & type) != 0; 7767 } 7768 7769 public void setDump(int type) { 7770 mTypes |= type; 7771 } 7772 7773 public boolean isOptionEnabled(int option) { 7774 return (mOptions & option) != 0; 7775 } 7776 7777 public void setOptionEnabled(int option) { 7778 mOptions |= option; 7779 } 7780 7781 public boolean onTitlePrinted() { 7782 final boolean printed = mTitlePrinted; 7783 mTitlePrinted = true; 7784 return printed; 7785 } 7786 7787 public boolean getTitlePrinted() { 7788 return mTitlePrinted; 7789 } 7790 7791 public void setTitlePrinted(boolean enabled) { 7792 mTitlePrinted = enabled; 7793 } 7794 7795 public SharedUserSetting getSharedUser() { 7796 return mSharedUser; 7797 } 7798 7799 public void setSharedUser(SharedUserSetting user) { 7800 mSharedUser = user; 7801 } 7802 } 7803 7804 @Override 7805 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 7806 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 7807 != PackageManager.PERMISSION_GRANTED) { 7808 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 7809 + Binder.getCallingPid() 7810 + ", uid=" + Binder.getCallingUid() 7811 + " without permission " 7812 + android.Manifest.permission.DUMP); 7813 return; 7814 } 7815 7816 DumpState dumpState = new DumpState(); 7817 7818 String packageName = null; 7819 7820 int opti = 0; 7821 while (opti < args.length) { 7822 String opt = args[opti]; 7823 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 7824 break; 7825 } 7826 opti++; 7827 if ("-a".equals(opt)) { 7828 // Right now we only know how to print all. 7829 } else if ("-h".equals(opt)) { 7830 pw.println("Package manager dump options:"); 7831 pw.println(" [-h] [-f] [cmd] ..."); 7832 pw.println(" -f: print details of intent filters"); 7833 pw.println(" -h: print this help"); 7834 pw.println(" cmd may be one of:"); 7835 pw.println(" l[ibraries]: list known shared libraries"); 7836 pw.println(" f[ibraries]: list device features"); 7837 pw.println(" r[esolvers]: dump intent resolvers"); 7838 pw.println(" perm[issions]: dump permissions"); 7839 pw.println(" prov[iders]: dump content providers"); 7840 pw.println(" p[ackages]: dump installed packages"); 7841 pw.println(" s[hared-users]: dump shared user IDs"); 7842 pw.println(" m[essages]: print collected runtime messages"); 7843 pw.println(" v[erifiers]: print package verifier info"); 7844 pw.println(" <package.name>: info about given package"); 7845 return; 7846 } else if ("-f".equals(opt)) { 7847 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 7848 } else { 7849 pw.println("Unknown argument: " + opt + "; use -h for help"); 7850 } 7851 } 7852 7853 // Is the caller requesting to dump a particular piece of data? 7854 if (opti < args.length) { 7855 String cmd = args[opti]; 7856 opti++; 7857 // Is this a package name? 7858 if ("android".equals(cmd) || cmd.contains(".")) { 7859 packageName = cmd; 7860 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 7861 dumpState.setDump(DumpState.DUMP_LIBS); 7862 } else if ("f".equals(cmd) || "features".equals(cmd)) { 7863 dumpState.setDump(DumpState.DUMP_FEATURES); 7864 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 7865 dumpState.setDump(DumpState.DUMP_RESOLVERS); 7866 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 7867 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 7868 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 7869 dumpState.setDump(DumpState.DUMP_PACKAGES); 7870 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 7871 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 7872 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 7873 dumpState.setDump(DumpState.DUMP_PROVIDERS); 7874 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 7875 dumpState.setDump(DumpState.DUMP_MESSAGES); 7876 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 7877 dumpState.setDump(DumpState.DUMP_VERIFIERS); 7878 } 7879 } 7880 7881 // reader 7882 synchronized (mPackages) { 7883 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 7884 if (dumpState.onTitlePrinted()) 7885 pw.println(" "); 7886 pw.println("Verifiers:"); 7887 pw.print(" Required: "); 7888 pw.print(mRequiredVerifierPackage); 7889 pw.print(" (uid="); 7890 pw.print(getPackageUid(mRequiredVerifierPackage)); 7891 pw.println(")"); 7892 } 7893 7894 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 7895 if (dumpState.onTitlePrinted()) 7896 pw.println(" "); 7897 pw.println("Libraries:"); 7898 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 7899 while (it.hasNext()) { 7900 String name = it.next(); 7901 pw.print(" "); 7902 pw.print(name); 7903 pw.print(" -> "); 7904 pw.println(mSharedLibraries.get(name)); 7905 } 7906 } 7907 7908 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 7909 if (dumpState.onTitlePrinted()) 7910 pw.println(" "); 7911 pw.println("Features:"); 7912 Iterator<String> it = mAvailableFeatures.keySet().iterator(); 7913 while (it.hasNext()) { 7914 String name = it.next(); 7915 pw.print(" "); 7916 pw.println(name); 7917 } 7918 } 7919 7920 if (dumpState.isDumping(DumpState.DUMP_RESOLVERS)) { 7921 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 7922 : "Activity Resolver Table:", " ", packageName, 7923 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 7924 dumpState.setTitlePrinted(true); 7925 } 7926 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 7927 : "Receiver Resolver Table:", " ", packageName, 7928 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 7929 dumpState.setTitlePrinted(true); 7930 } 7931 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 7932 : "Service Resolver Table:", " ", packageName, 7933 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 7934 dumpState.setTitlePrinted(true); 7935 } 7936 if (mSettings.mPreferredActivities.dump(pw, 7937 dumpState.getTitlePrinted() ? "\nPreferred Activities:" 7938 : "Preferred Activities:", " ", 7939 packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) { 7940 dumpState.setTitlePrinted(true); 7941 } 7942 } 7943 7944 if (dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 7945 mSettings.dumpPermissionsLPr(pw, packageName, dumpState); 7946 } 7947 7948 if (dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 7949 boolean printedSomething = false; 7950 for (PackageParser.Provider p : mProviders.values()) { 7951 if (packageName != null && !packageName.equals(p.info.packageName)) { 7952 continue; 7953 } 7954 if (!printedSomething) { 7955 if (dumpState.onTitlePrinted()) 7956 pw.println(" "); 7957 pw.println("Registered ContentProviders:"); 7958 printedSomething = true; 7959 } 7960 pw.print(" ["); pw.print(p.info.authority); pw.print("]: "); 7961 pw.println(p.toString()); 7962 } 7963 } 7964 7965 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 7966 mSettings.dumpPackagesLPr(pw, packageName, dumpState); 7967 } 7968 7969 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 7970 mSettings.dumpSharedUsersLPr(pw, packageName, dumpState); 7971 } 7972 7973 if (dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 7974 if (dumpState.onTitlePrinted()) 7975 pw.println(" "); 7976 mSettings.dumpReadMessagesLPr(pw, dumpState); 7977 7978 pw.println(" "); 7979 pw.println("Package warning messages:"); 7980 final File fname = getSettingsProblemFile(); 7981 FileInputStream in = null; 7982 try { 7983 in = new FileInputStream(fname); 7984 final int avail = in.available(); 7985 final byte[] data = new byte[avail]; 7986 in.read(data); 7987 pw.print(new String(data)); 7988 } catch (FileNotFoundException e) { 7989 } catch (IOException e) { 7990 } finally { 7991 if (in != null) { 7992 try { 7993 in.close(); 7994 } catch (IOException e) { 7995 } 7996 } 7997 } 7998 } 7999 } 8000 } 8001 8002 // ------- apps on sdcard specific code ------- 8003 static final boolean DEBUG_SD_INSTALL = false; 8004 8005 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 8006 8007 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 8008 8009 private boolean mMediaMounted = false; 8010 8011 private String getEncryptKey() { 8012 try { 8013 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 8014 SD_ENCRYPTION_KEYSTORE_NAME); 8015 if (sdEncKey == null) { 8016 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 8017 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 8018 if (sdEncKey == null) { 8019 Slog.e(TAG, "Failed to create encryption keys"); 8020 return null; 8021 } 8022 } 8023 return sdEncKey; 8024 } catch (NoSuchAlgorithmException nsae) { 8025 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 8026 return null; 8027 } catch (IOException ioe) { 8028 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 8029 return null; 8030 } 8031 8032 } 8033 8034 /* package */static String getTempContainerId() { 8035 int tmpIdx = 1; 8036 String list[] = PackageHelper.getSecureContainerList(); 8037 if (list != null) { 8038 for (final String name : list) { 8039 // Ignore null and non-temporary container entries 8040 if (name == null || !name.startsWith(mTempContainerPrefix)) { 8041 continue; 8042 } 8043 8044 String subStr = name.substring(mTempContainerPrefix.length()); 8045 try { 8046 int cid = Integer.parseInt(subStr); 8047 if (cid >= tmpIdx) { 8048 tmpIdx = cid + 1; 8049 } 8050 } catch (NumberFormatException e) { 8051 } 8052 } 8053 } 8054 return mTempContainerPrefix + tmpIdx; 8055 } 8056 8057 /* 8058 * Update media status on PackageManager. 8059 */ 8060 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 8061 int callingUid = Binder.getCallingUid(); 8062 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 8063 throw new SecurityException("Media status can only be updated by the system"); 8064 } 8065 // reader; this apparently protects mMediaMounted, but should probably 8066 // be a different lock in that case. 8067 synchronized (mPackages) { 8068 Log.i(TAG, "Updating external media status from " 8069 + (mMediaMounted ? "mounted" : "unmounted") + " to " 8070 + (mediaStatus ? "mounted" : "unmounted")); 8071 if (DEBUG_SD_INSTALL) 8072 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 8073 + ", mMediaMounted=" + mMediaMounted); 8074 if (mediaStatus == mMediaMounted) { 8075 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 8076 : 0, -1); 8077 mHandler.sendMessage(msg); 8078 return; 8079 } 8080 mMediaMounted = mediaStatus; 8081 } 8082 // Queue up an async operation since the package installation may take a 8083 // little while. 8084 mHandler.post(new Runnable() { 8085 public void run() { 8086 // TODO fix this; this does nothing. 8087 mHandler.removeCallbacks(this); 8088 updateExternalMediaStatusInner(mediaStatus, reportStatus); 8089 } 8090 }); 8091 } 8092 8093 /* 8094 * Collect information of applications on external media, map them against 8095 * existing containers and update information based on current mount status. 8096 * Please note that we always have to report status if reportStatus has been 8097 * set to true especially when unloading packages. 8098 */ 8099 private void updateExternalMediaStatusInner(boolean mediaStatus, boolean reportStatus) { 8100 // Collection of uids 8101 int uidArr[] = null; 8102 // Collection of stale containers 8103 HashSet<String> removeCids = new HashSet<String>(); 8104 // Collection of packages on external media with valid containers. 8105 HashMap<SdInstallArgs, String> processCids = new HashMap<SdInstallArgs, String>(); 8106 // Get list of secure containers. 8107 final String list[] = PackageHelper.getSecureContainerList(); 8108 if (list == null || list.length == 0) { 8109 Log.i(TAG, "No secure containers on sdcard"); 8110 } else { 8111 // Process list of secure containers and categorize them 8112 // as active or stale based on their package internal state. 8113 int uidList[] = new int[list.length]; 8114 int num = 0; 8115 // reader 8116 synchronized (mPackages) { 8117 for (String cid : list) { 8118 SdInstallArgs args = new SdInstallArgs(cid); 8119 if (DEBUG_SD_INSTALL) 8120 Log.i(TAG, "Processing container " + cid); 8121 String pkgName = args.getPackageName(); 8122 if (pkgName == null) { 8123 if (DEBUG_SD_INSTALL) 8124 Log.i(TAG, "Container : " + cid + " stale"); 8125 removeCids.add(cid); 8126 continue; 8127 } 8128 if (DEBUG_SD_INSTALL) 8129 Log.i(TAG, "Looking for pkg : " + pkgName); 8130 PackageSetting ps = mSettings.mPackages.get(pkgName); 8131 // The package status is changed only if the code path 8132 // matches between settings and the container id. 8133 if (ps != null && ps.codePathString != null 8134 && ps.codePathString.equals(args.getCodePath())) { 8135 if (DEBUG_SD_INSTALL) 8136 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 8137 + " at code path: " + ps.codePathString); 8138 // We do have a valid package installed on sdcard 8139 processCids.put(args, ps.codePathString); 8140 int uid = ps.userId; 8141 if (uid != -1) { 8142 uidList[num++] = uid; 8143 } 8144 } else { 8145 // Stale container on sdcard. Just delete 8146 if (DEBUG_SD_INSTALL) 8147 Log.i(TAG, "Container : " + cid + " stale"); 8148 removeCids.add(cid); 8149 } 8150 } 8151 } 8152 8153 if (num > 0) { 8154 // Sort uid list 8155 Arrays.sort(uidList, 0, num); 8156 // Throw away duplicates 8157 uidArr = new int[num]; 8158 uidArr[0] = uidList[0]; 8159 int di = 0; 8160 for (int i = 1; i < num; i++) { 8161 if (uidList[i - 1] != uidList[i]) { 8162 uidArr[di++] = uidList[i]; 8163 } 8164 } 8165 } 8166 } 8167 // Process packages with valid entries. 8168 if (mediaStatus) { 8169 if (DEBUG_SD_INSTALL) 8170 Log.i(TAG, "Loading packages"); 8171 loadMediaPackages(processCids, uidArr, removeCids); 8172 startCleaningPackages(); 8173 } else { 8174 if (DEBUG_SD_INSTALL) 8175 Log.i(TAG, "Unloading packages"); 8176 unloadMediaPackages(processCids, uidArr, reportStatus); 8177 } 8178 } 8179 8180 private void sendResourcesChangedBroadcast(boolean mediaStatus, ArrayList<String> pkgList, 8181 int uidArr[], IIntentReceiver finishedReceiver) { 8182 int size = pkgList.size(); 8183 if (size > 0) { 8184 // Send broadcasts here 8185 Bundle extras = new Bundle(); 8186 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList 8187 .toArray(new String[size])); 8188 if (uidArr != null) { 8189 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 8190 } 8191 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 8192 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 8193 sendPackageBroadcast(action, null, extras, null, finishedReceiver); 8194 } 8195 } 8196 8197 /* 8198 * Look at potentially valid container ids from processCids If package 8199 * information doesn't match the one on record or package scanning fails, 8200 * the cid is added to list of removeCids. We currently don't delete stale 8201 * containers. 8202 */ 8203 private void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[], 8204 HashSet<String> removeCids) { 8205 ArrayList<String> pkgList = new ArrayList<String>(); 8206 Set<SdInstallArgs> keys = processCids.keySet(); 8207 boolean doGc = false; 8208 for (SdInstallArgs args : keys) { 8209 String codePath = processCids.get(args); 8210 if (DEBUG_SD_INSTALL) 8211 Log.i(TAG, "Loading container : " + args.cid); 8212 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 8213 try { 8214 // Make sure there are no container errors first. 8215 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 8216 Slog.e(TAG, "Failed to mount cid : " + args.cid 8217 + " when installing from sdcard"); 8218 continue; 8219 } 8220 // Check code path here. 8221 if (codePath == null || !codePath.equals(args.getCodePath())) { 8222 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 8223 + " does not match one in settings " + codePath); 8224 continue; 8225 } 8226 // Parse package 8227 int parseFlags = PackageParser.PARSE_ON_SDCARD | mDefParseFlags; 8228 doGc = true; 8229 synchronized (mInstallLock) { 8230 final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags, 8231 0, 0); 8232 // Scan the package 8233 if (pkg != null) { 8234 /* 8235 * TODO why is the lock being held? doPostInstall is 8236 * called in other places without the lock. This needs 8237 * to be straightened out. 8238 */ 8239 // writer 8240 synchronized (mPackages) { 8241 retCode = PackageManager.INSTALL_SUCCEEDED; 8242 pkgList.add(pkg.packageName); 8243 // Post process args 8244 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED); 8245 } 8246 } else { 8247 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 8248 } 8249 } 8250 8251 } finally { 8252 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 8253 // Don't destroy container here. Wait till gc clears things 8254 // up. 8255 removeCids.add(args.cid); 8256 } 8257 } 8258 } 8259 // writer 8260 synchronized (mPackages) { 8261 // If the platform SDK has changed since the last time we booted, 8262 // we need to re-grant app permission to catch any new ones that 8263 // appear. This is really a hack, and means that apps can in some 8264 // cases get permissions that the user didn't initially explicitly 8265 // allow... it would be nice to have some better way to handle 8266 // this situation. 8267 final boolean regrantPermissions = mSettings.mExternalSdkPlatform != mSdkVersion; 8268 if (regrantPermissions) 8269 Slog.i(TAG, "Platform changed from " + mSettings.mExternalSdkPlatform + " to " 8270 + mSdkVersion + "; regranting permissions for external storage"); 8271 mSettings.mExternalSdkPlatform = mSdkVersion; 8272 8273 // Make sure group IDs have been assigned, and any permission 8274 // changes in other apps are accounted for 8275 updatePermissionsLPw(null, null, true, regrantPermissions, regrantPermissions); 8276 // can downgrade to reader 8277 // Persist settings 8278 mSettings.writeLPr(); 8279 } 8280 // Send a broadcast to let everyone know we are done processing 8281 if (pkgList.size() > 0) { 8282 sendResourcesChangedBroadcast(true, pkgList, uidArr, null); 8283 } 8284 // Force gc to avoid any stale parser references that we might have. 8285 if (doGc) { 8286 Runtime.getRuntime().gc(); 8287 } 8288 // List stale containers and destroy stale temporary containers. 8289 if (removeCids != null) { 8290 for (String cid : removeCids) { 8291 if (cid.startsWith(mTempContainerPrefix)) { 8292 Log.i(TAG, "Destroying stale temporary container " + cid); 8293 PackageHelper.destroySdDir(cid); 8294 } else { 8295 Log.w(TAG, "Container " + cid + " is stale"); 8296 } 8297 } 8298 } 8299 } 8300 8301 /* 8302 * Utility method to unload a list of specified containers 8303 */ 8304 private void unloadAllContainers(Set<SdInstallArgs> cidArgs) { 8305 // Just unmount all valid containers. 8306 for (SdInstallArgs arg : cidArgs) { 8307 synchronized (mInstallLock) { 8308 arg.doPostDeleteLI(false); 8309 } 8310 } 8311 } 8312 8313 /* 8314 * Unload packages mounted on external media. This involves deleting package 8315 * data from internal structures, sending broadcasts about diabled packages, 8316 * gc'ing to free up references, unmounting all secure containers 8317 * corresponding to packages on external media, and posting a 8318 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 8319 * that we always have to post this message if status has been requested no 8320 * matter what. 8321 */ 8322 private void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[], 8323 final boolean reportStatus) { 8324 if (DEBUG_SD_INSTALL) 8325 Log.i(TAG, "unloading media packages"); 8326 ArrayList<String> pkgList = new ArrayList<String>(); 8327 ArrayList<SdInstallArgs> failedList = new ArrayList<SdInstallArgs>(); 8328 final Set<SdInstallArgs> keys = processCids.keySet(); 8329 for (SdInstallArgs args : keys) { 8330 String pkgName = args.getPackageName(); 8331 if (DEBUG_SD_INSTALL) 8332 Log.i(TAG, "Trying to unload pkg : " + pkgName); 8333 // Delete package internally 8334 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 8335 synchronized (mInstallLock) { 8336 boolean res = deletePackageLI(pkgName, false, PackageManager.DONT_DELETE_DATA, 8337 outInfo, false); 8338 if (res) { 8339 pkgList.add(pkgName); 8340 } else { 8341 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 8342 failedList.add(args); 8343 } 8344 } 8345 } 8346 8347 // reader 8348 synchronized (mPackages) { 8349 // We didn't update the settings after removing each package; 8350 // write them now for all packages. 8351 mSettings.writeLPr(); 8352 } 8353 8354 // We have to absolutely send UPDATED_MEDIA_STATUS only 8355 // after confirming that all the receivers processed the ordered 8356 // broadcast when packages get disabled, force a gc to clean things up. 8357 // and unload all the containers. 8358 if (pkgList.size() > 0) { 8359 sendResourcesChangedBroadcast(false, pkgList, uidArr, new IIntentReceiver.Stub() { 8360 public void performReceive(Intent intent, int resultCode, String data, 8361 Bundle extras, boolean ordered, boolean sticky) throws RemoteException { 8362 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 8363 reportStatus ? 1 : 0, 1, keys); 8364 mHandler.sendMessage(msg); 8365 } 8366 }); 8367 } else { 8368 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 8369 keys); 8370 mHandler.sendMessage(msg); 8371 } 8372 } 8373 8374 public void movePackage(final String packageName, final IPackageMoveObserver observer, 8375 final int flags) { 8376 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 8377 int returnCode = PackageManager.MOVE_SUCCEEDED; 8378 int currFlags = 0; 8379 int newFlags = 0; 8380 // reader 8381 synchronized (mPackages) { 8382 PackageParser.Package pkg = mPackages.get(packageName); 8383 if (pkg == null) { 8384 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 8385 } else { 8386 // Disable moving fwd locked apps and system packages 8387 if (pkg.applicationInfo != null && isSystemApp(pkg)) { 8388 Slog.w(TAG, "Cannot move system application"); 8389 returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 8390 } else if (pkg.applicationInfo != null && isForwardLocked(pkg)) { 8391 Slog.w(TAG, "Cannot move forward locked app."); 8392 returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED; 8393 } else if (pkg.mOperationPending) { 8394 Slog.w(TAG, "Attempt to move package which has pending operations"); 8395 returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING; 8396 } else { 8397 // Find install location first 8398 if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 8399 && (flags & PackageManager.MOVE_INTERNAL) != 0) { 8400 Slog.w(TAG, "Ambigous flags specified for move location."); 8401 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 8402 } else { 8403 newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ? PackageManager.INSTALL_EXTERNAL 8404 : PackageManager.INSTALL_INTERNAL; 8405 currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL 8406 : PackageManager.INSTALL_INTERNAL; 8407 if (newFlags == currFlags) { 8408 Slog.w(TAG, "No move required. Trying to move to same location"); 8409 returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; 8410 } 8411 } 8412 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 8413 pkg.mOperationPending = true; 8414 } 8415 } 8416 } 8417 8418 /* 8419 * TODO this next block probably shouldn't be inside the lock. We 8420 * can't guarantee these won't change after this is fired off 8421 * anyway. 8422 */ 8423 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 8424 processPendingMove(new MoveParams(null, observer, 0, packageName, null), returnCode); 8425 } else { 8426 Message msg = mHandler.obtainMessage(INIT_COPY); 8427 InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir, 8428 pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir); 8429 MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName, 8430 pkg.applicationInfo.dataDir); 8431 msg.obj = mp; 8432 mHandler.sendMessage(msg); 8433 } 8434 } 8435 } 8436 8437 private void processPendingMove(final MoveParams mp, final int currentStatus) { 8438 // Queue up an async operation since the package deletion may take a 8439 // little while. 8440 mHandler.post(new Runnable() { 8441 public void run() { 8442 // TODO fix this; this does nothing. 8443 mHandler.removeCallbacks(this); 8444 int returnCode = currentStatus; 8445 if (currentStatus == PackageManager.MOVE_SUCCEEDED) { 8446 int uidArr[] = null; 8447 ArrayList<String> pkgList = null; 8448 synchronized (mPackages) { 8449 PackageParser.Package pkg = mPackages.get(mp.packageName); 8450 if (pkg == null) { 8451 Slog.w(TAG, " Package " + mp.packageName 8452 + " doesn't exist. Aborting move"); 8453 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 8454 } else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) { 8455 Slog.w(TAG, "Package " + mp.packageName + " code path changed from " 8456 + mp.srcArgs.getCodePath() + " to " 8457 + pkg.applicationInfo.sourceDir 8458 + " Aborting move and returning error"); 8459 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 8460 } else { 8461 uidArr = new int[] { 8462 pkg.applicationInfo.uid 8463 }; 8464 pkgList = new ArrayList<String>(); 8465 pkgList.add(mp.packageName); 8466 } 8467 } 8468 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 8469 // Send resources unavailable broadcast 8470 sendResourcesChangedBroadcast(false, pkgList, uidArr, null); 8471 // Update package code and resource paths 8472 synchronized (mInstallLock) { 8473 synchronized (mPackages) { 8474 PackageParser.Package pkg = mPackages.get(mp.packageName); 8475 // Recheck for package again. 8476 if (pkg == null) { 8477 Slog.w(TAG, " Package " + mp.packageName 8478 + " doesn't exist. Aborting move"); 8479 returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST; 8480 } else if (!mp.srcArgs.getCodePath().equals( 8481 pkg.applicationInfo.sourceDir)) { 8482 Slog.w(TAG, "Package " + mp.packageName 8483 + " code path changed from " + mp.srcArgs.getCodePath() 8484 + " to " + pkg.applicationInfo.sourceDir 8485 + " Aborting move and returning error"); 8486 returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR; 8487 } else { 8488 final String oldCodePath = pkg.mPath; 8489 final String newCodePath = mp.targetArgs.getCodePath(); 8490 final String newResPath = mp.targetArgs.getResourcePath(); 8491 final String newNativePath = mp.targetArgs 8492 .getNativeLibraryPath(); 8493 8494 if ((mp.flags & PackageManager.INSTALL_EXTERNAL) == 0) { 8495 if (mInstaller 8496 .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) { 8497 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 8498 } else { 8499 NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File( 8500 newCodePath), new File(newNativePath)); 8501 } 8502 } else { 8503 if (mInstaller.linkNativeLibraryDirectory( 8504 pkg.applicationInfo.dataDir, newNativePath) < 0) { 8505 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 8506 } 8507 } 8508 8509 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 8510 pkg.mPath = newCodePath; 8511 // Move dex files around 8512 if (moveDexFilesLI(pkg) != PackageManager.INSTALL_SUCCEEDED) { 8513 // Moving of dex files failed. Set 8514 // error code and abort move. 8515 pkg.mPath = pkg.mScanPath; 8516 returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; 8517 } 8518 } 8519 8520 if (returnCode == PackageManager.MOVE_SUCCEEDED) { 8521 pkg.mScanPath = newCodePath; 8522 pkg.applicationInfo.sourceDir = newCodePath; 8523 pkg.applicationInfo.publicSourceDir = newResPath; 8524 pkg.applicationInfo.nativeLibraryDir = newNativePath; 8525 PackageSetting ps = (PackageSetting) pkg.mExtras; 8526 ps.codePath = new File(pkg.applicationInfo.sourceDir); 8527 ps.codePathString = ps.codePath.getPath(); 8528 ps.resourcePath = new File( 8529 pkg.applicationInfo.publicSourceDir); 8530 ps.resourcePathString = ps.resourcePath.getPath(); 8531 ps.nativeLibraryPathString = newNativePath; 8532 // Set the application info flag 8533 // correctly. 8534 if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) { 8535 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE; 8536 } else { 8537 pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE; 8538 } 8539 ps.setFlags(pkg.applicationInfo.flags); 8540 mAppDirs.remove(oldCodePath); 8541 mAppDirs.put(newCodePath, pkg); 8542 // Persist settings 8543 mSettings.writeLPr(); 8544 } 8545 } 8546 } 8547 } 8548 // Send resources available broadcast 8549 sendResourcesChangedBroadcast(true, pkgList, uidArr, null); 8550 } 8551 } 8552 if (returnCode != PackageManager.MOVE_SUCCEEDED) { 8553 // Clean up failed installation 8554 if (mp.targetArgs != null) { 8555 mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR); 8556 } 8557 } else { 8558 // Force a gc to clear things up. 8559 Runtime.getRuntime().gc(); 8560 // Delete older code 8561 synchronized (mInstallLock) { 8562 mp.srcArgs.doPostDeleteLI(true); 8563 } 8564 } 8565 8566 // Allow more operations on this file if we didn't fail because 8567 // an operation was already pending for this package. 8568 if (returnCode != PackageManager.MOVE_FAILED_OPERATION_PENDING) { 8569 synchronized (mPackages) { 8570 PackageParser.Package pkg = mPackages.get(mp.packageName); 8571 if (pkg != null) { 8572 pkg.mOperationPending = false; 8573 } 8574 } 8575 } 8576 8577 IPackageMoveObserver observer = mp.observer; 8578 if (observer != null) { 8579 try { 8580 observer.packageMoved(mp.packageName, returnCode); 8581 } catch (RemoteException e) { 8582 Log.i(TAG, "Observer no longer exists."); 8583 } 8584 } 8585 } 8586 }); 8587 } 8588 8589 public boolean setInstallLocation(int loc) { 8590 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 8591 null); 8592 if (getInstallLocation() == loc) { 8593 return true; 8594 } 8595 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 8596 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 8597 android.provider.Settings.System.putInt(mContext.getContentResolver(), 8598 android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION, loc); 8599 return true; 8600 } 8601 return false; 8602 } 8603 8604 public int getInstallLocation() { 8605 return android.provider.Settings.System.getInt(mContext.getContentResolver(), 8606 android.provider.Settings.Secure.DEFAULT_INSTALL_LOCATION, 8607 PackageHelper.APP_INSTALL_AUTO); 8608 } 8609 8610 public UserInfo createUser(String name, int flags) { 8611 // TODO(kroot): Add a real permission for creating users 8612 enforceSystemOrRoot("Only the system can create users"); 8613 8614 // TODO(kroot): fix this API 8615 UserInfo userInfo = mUserManager.createUser(name, flags, new ArrayList<ApplicationInfo>()); 8616 return userInfo; 8617 } 8618 8619 public boolean removeUser(int userId) { 8620 // TODO(kroot): Add a real permission for removing users 8621 enforceSystemOrRoot("Only the system can remove users"); 8622 8623 if (userId == 0) { 8624 return false; 8625 } 8626 mUserManager.removeUser(userId); 8627 return true; 8628 } 8629 8630 @Override 8631 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 8632 mContext.enforceCallingOrSelfPermission( 8633 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 8634 "Only package verification agents can read the verifier device identity"); 8635 8636 synchronized (mPackages) { 8637 return mSettings.getVerifierDeviceIdentityLPw(); 8638 } 8639 } 8640 } 8641