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