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