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