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