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.READ_EXTERNAL_STORAGE; 20 import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 21 import static android.Manifest.permission.WRITE_MEDIA_STORAGE; 22 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 23 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 24 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 25 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 26 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 27 import static android.content.pm.PackageManager.DELETE_KEEP_DATA; 28 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 29 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 30 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 31 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 32 import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 33 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 34 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 35 import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 36 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 37 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 38 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 39 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 40 import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID; 41 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 42 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 43 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 44 import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 45 import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 46 import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 47 import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 48 import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 49 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 50 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 51 import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 52 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 53 import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 54 import static android.content.pm.PackageManager.INSTALL_INTERNAL; 55 import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 56 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 57 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 58 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 59 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 60 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 61 import static android.content.pm.PackageManager.MATCH_ALL; 62 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 63 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 64 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 65 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 66 import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; 67 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 68 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 69 import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN; 70 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 71 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 72 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 73 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 74 import static android.content.pm.PackageManager.PERMISSION_DENIED; 75 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 76 import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; 77 import static android.content.pm.PackageParser.isApkFile; 78 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 79 import static android.system.OsConstants.O_CREAT; 80 import static android.system.OsConstants.O_RDWR; 81 82 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 83 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 84 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 85 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 86 import static com.android.internal.util.ArrayUtils.appendInt; 87 import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 88 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 89 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 90 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 91 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 92 import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 93 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; 94 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; 95 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter; 96 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 97 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 98 import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 99 100 import android.Manifest; 101 import android.annotation.NonNull; 102 import android.annotation.Nullable; 103 import android.app.ActivityManager; 104 import android.app.ActivityManagerNative; 105 import android.app.IActivityManager; 106 import android.app.ResourcesManager; 107 import android.app.admin.IDevicePolicyManager; 108 import android.app.admin.SecurityLog; 109 import android.app.backup.IBackupManager; 110 import android.content.BroadcastReceiver; 111 import android.content.ComponentName; 112 import android.content.Context; 113 import android.content.IIntentReceiver; 114 import android.content.Intent; 115 import android.content.IntentFilter; 116 import android.content.IntentSender; 117 import android.content.IntentSender.SendIntentException; 118 import android.content.ServiceConnection; 119 import android.content.pm.ActivityInfo; 120 import android.content.pm.ApplicationInfo; 121 import android.content.pm.AppsQueryHelper; 122 import android.content.pm.ComponentInfo; 123 import android.content.pm.EphemeralApplicationInfo; 124 import android.content.pm.EphemeralResolveInfo; 125 import android.content.pm.EphemeralResolveInfo.EphemeralDigest; 126 import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; 127 import android.content.pm.FeatureInfo; 128 import android.content.pm.IOnPermissionsChangeListener; 129 import android.content.pm.IPackageDataObserver; 130 import android.content.pm.IPackageDeleteObserver; 131 import android.content.pm.IPackageDeleteObserver2; 132 import android.content.pm.IPackageInstallObserver2; 133 import android.content.pm.IPackageInstaller; 134 import android.content.pm.IPackageManager; 135 import android.content.pm.IPackageMoveObserver; 136 import android.content.pm.IPackageStatsObserver; 137 import android.content.pm.InstrumentationInfo; 138 import android.content.pm.IntentFilterVerificationInfo; 139 import android.content.pm.KeySet; 140 import android.content.pm.PackageCleanItem; 141 import android.content.pm.PackageInfo; 142 import android.content.pm.PackageInfoLite; 143 import android.content.pm.PackageInstaller; 144 import android.content.pm.PackageManager; 145 import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 146 import android.content.pm.PackageManagerInternal; 147 import android.content.pm.PackageParser; 148 import android.content.pm.PackageParser.ActivityIntentInfo; 149 import android.content.pm.PackageParser.PackageLite; 150 import android.content.pm.PackageParser.PackageParserException; 151 import android.content.pm.PackageStats; 152 import android.content.pm.PackageUserState; 153 import android.content.pm.ParceledListSlice; 154 import android.content.pm.PermissionGroupInfo; 155 import android.content.pm.PermissionInfo; 156 import android.content.pm.ProviderInfo; 157 import android.content.pm.ResolveInfo; 158 import android.content.pm.ServiceInfo; 159 import android.content.pm.Signature; 160 import android.content.pm.UserInfo; 161 import android.content.pm.VerifierDeviceIdentity; 162 import android.content.pm.VerifierInfo; 163 import android.content.res.Resources; 164 import android.graphics.Bitmap; 165 import android.hardware.display.DisplayManager; 166 import android.net.Uri; 167 import android.os.Binder; 168 import android.os.Build; 169 import android.os.Bundle; 170 import android.os.Debug; 171 import android.os.Environment; 172 import android.os.Environment.UserEnvironment; 173 import android.os.FileUtils; 174 import android.os.Handler; 175 import android.os.IBinder; 176 import android.os.Looper; 177 import android.os.Message; 178 import android.os.Parcel; 179 import android.os.ParcelFileDescriptor; 180 import android.os.Process; 181 import android.os.RemoteCallbackList; 182 import android.os.RemoteException; 183 import android.os.ResultReceiver; 184 import android.os.SELinux; 185 import android.os.ServiceManager; 186 import android.os.SystemClock; 187 import android.os.SystemProperties; 188 import android.os.Trace; 189 import android.os.UserHandle; 190 import android.os.UserManager; 191 import android.os.UserManagerInternal; 192 import android.os.storage.IMountService; 193 import android.os.storage.MountServiceInternal; 194 import android.os.storage.StorageEventListener; 195 import android.os.storage.StorageManager; 196 import android.os.storage.VolumeInfo; 197 import android.os.storage.VolumeRecord; 198 import android.provider.Settings.Global; 199 import android.security.KeyStore; 200 import android.security.SystemKeyStore; 201 import android.system.ErrnoException; 202 import android.system.Os; 203 import android.text.TextUtils; 204 import android.text.format.DateUtils; 205 import android.util.ArrayMap; 206 import android.util.ArraySet; 207 import android.util.DisplayMetrics; 208 import android.util.EventLog; 209 import android.util.ExceptionUtils; 210 import android.util.Log; 211 import android.util.LogPrinter; 212 import android.util.MathUtils; 213 import android.util.PrintStreamPrinter; 214 import android.util.Slog; 215 import android.util.SparseArray; 216 import android.util.SparseBooleanArray; 217 import android.util.SparseIntArray; 218 import android.util.Xml; 219 import android.util.jar.StrictJarFile; 220 import android.view.Display; 221 222 import com.android.internal.R; 223 import com.android.internal.annotations.GuardedBy; 224 import com.android.internal.app.IMediaContainerService; 225 import com.android.internal.app.ResolverActivity; 226 import com.android.internal.content.NativeLibraryHelper; 227 import com.android.internal.content.PackageHelper; 228 import com.android.internal.logging.MetricsLogger; 229 import com.android.internal.os.IParcelFileDescriptorFactory; 230 import com.android.internal.os.InstallerConnection.InstallerException; 231 import com.android.internal.os.SomeArgs; 232 import com.android.internal.os.Zygote; 233 import com.android.internal.telephony.CarrierAppUtils; 234 import com.android.internal.util.ArrayUtils; 235 import com.android.internal.util.FastPrintWriter; 236 import com.android.internal.util.FastXmlSerializer; 237 import com.android.internal.util.IndentingPrintWriter; 238 import com.android.internal.util.Preconditions; 239 import com.android.internal.util.XmlUtils; 240 import com.android.server.AttributeCache; 241 import com.android.server.EventLogTags; 242 import com.android.server.FgThread; 243 import com.android.server.IntentResolver; 244 import com.android.server.LocalServices; 245 import com.android.server.ServiceThread; 246 import com.android.server.SystemConfig; 247 import com.android.server.Watchdog; 248 import com.android.server.net.NetworkPolicyManagerInternal; 249 import com.android.server.pm.PermissionsState.PermissionState; 250 import com.android.server.pm.Settings.DatabaseVersion; 251 import com.android.server.pm.Settings.VersionInfo; 252 import com.android.server.storage.DeviceStorageMonitorInternal; 253 254 import dalvik.system.CloseGuard; 255 import dalvik.system.DexFile; 256 import dalvik.system.VMRuntime; 257 258 import libcore.io.IoUtils; 259 import libcore.util.EmptyArray; 260 261 import org.xmlpull.v1.XmlPullParser; 262 import org.xmlpull.v1.XmlPullParserException; 263 import org.xmlpull.v1.XmlSerializer; 264 265 import java.io.BufferedOutputStream; 266 import java.io.BufferedReader; 267 import java.io.ByteArrayInputStream; 268 import java.io.ByteArrayOutputStream; 269 import java.io.File; 270 import java.io.FileDescriptor; 271 import java.io.FileInputStream; 272 import java.io.FileNotFoundException; 273 import java.io.FileOutputStream; 274 import java.io.FileReader; 275 import java.io.FilenameFilter; 276 import java.io.IOException; 277 import java.io.PrintWriter; 278 import java.nio.charset.StandardCharsets; 279 import java.security.DigestInputStream; 280 import java.security.MessageDigest; 281 import java.security.NoSuchAlgorithmException; 282 import java.security.PublicKey; 283 import java.security.cert.Certificate; 284 import java.security.cert.CertificateEncodingException; 285 import java.security.cert.CertificateException; 286 import java.text.SimpleDateFormat; 287 import java.util.ArrayList; 288 import java.util.Arrays; 289 import java.util.Collection; 290 import java.util.Collections; 291 import java.util.Comparator; 292 import java.util.Date; 293 import java.util.HashSet; 294 import java.util.Iterator; 295 import java.util.List; 296 import java.util.Map; 297 import java.util.Objects; 298 import java.util.Set; 299 import java.util.concurrent.CountDownLatch; 300 import java.util.concurrent.TimeUnit; 301 import java.util.concurrent.atomic.AtomicBoolean; 302 import java.util.concurrent.atomic.AtomicInteger; 303 304 /** 305 * Keep track of all those APKs everywhere. 306 * <p> 307 * Internally there are two important locks: 308 * <ul> 309 * <li>{@link #mPackages} is used to guard all in-memory parsed package details 310 * and other related state. It is a fine-grained lock that should only be held 311 * momentarily, as it's one of the most contended locks in the system. 312 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose 313 * operations typically involve heavy lifting of application data on disk. Since 314 * {@code installd} is single-threaded, and it's operations can often be slow, 315 * this lock should never be acquired while already holding {@link #mPackages}. 316 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already 317 * holding {@link #mInstallLock}. 318 * </ul> 319 * Many internal methods rely on the caller to hold the appropriate locks, and 320 * this contract is expressed through method name suffixes: 321 * <ul> 322 * <li>fooLI(): the caller must hold {@link #mInstallLock} 323 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package 324 * being modified must be frozen 325 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading 326 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing 327 * </ul> 328 * <p> 329 * Because this class is very central to the platform's security; please run all 330 * CTS and unit tests whenever making modifications: 331 * 332 * <pre> 333 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core 334 * $ cts-tradefed run commandAndExit cts -m AppSecurityTests 335 * </pre> 336 */ 337 public class PackageManagerService extends IPackageManager.Stub { 338 static final String TAG = "PackageManager"; 339 static final boolean DEBUG_SETTINGS = false; 340 static final boolean DEBUG_PREFERRED = false; 341 static final boolean DEBUG_UPGRADE = false; 342 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 343 private static final boolean DEBUG_BACKUP = false; 344 private static final boolean DEBUG_INSTALL = false; 345 private static final boolean DEBUG_REMOVE = false; 346 private static final boolean DEBUG_BROADCASTS = false; 347 private static final boolean DEBUG_SHOW_INFO = false; 348 private static final boolean DEBUG_PACKAGE_INFO = false; 349 private static final boolean DEBUG_INTENT_MATCHING = false; 350 private static final boolean DEBUG_PACKAGE_SCANNING = false; 351 private static final boolean DEBUG_VERIFY = false; 352 private static final boolean DEBUG_FILTERS = false; 353 354 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 355 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 356 // user, but by default initialize to this. 357 static final boolean DEBUG_DEXOPT = false; 358 359 private static final boolean DEBUG_ABI_SELECTION = false; 360 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; 361 private static final boolean DEBUG_TRIAGED_MISSING = false; 362 private static final boolean DEBUG_APP_DATA = false; 363 364 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 365 366 private static final boolean DISABLE_EPHEMERAL_APPS = !Build.IS_DEBUGGABLE; 367 368 private static final int RADIO_UID = Process.PHONE_UID; 369 private static final int LOG_UID = Process.LOG_UID; 370 private static final int NFC_UID = Process.NFC_UID; 371 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 372 private static final int SHELL_UID = Process.SHELL_UID; 373 374 // Cap the size of permission trees that 3rd party apps can define 375 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 376 377 // Suffix used during package installation when copying/moving 378 // package apks to install directory. 379 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 380 381 static final int SCAN_NO_DEX = 1<<1; 382 static final int SCAN_FORCE_DEX = 1<<2; 383 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 384 static final int SCAN_NEW_INSTALL = 1<<4; 385 static final int SCAN_NO_PATHS = 1<<5; 386 static final int SCAN_UPDATE_TIME = 1<<6; 387 static final int SCAN_DEFER_DEX = 1<<7; 388 static final int SCAN_BOOTING = 1<<8; 389 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 390 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 391 static final int SCAN_REPLACING = 1<<11; 392 static final int SCAN_REQUIRE_KNOWN = 1<<12; 393 static final int SCAN_MOVE = 1<<13; 394 static final int SCAN_INITIAL = 1<<14; 395 static final int SCAN_CHECK_ONLY = 1<<15; 396 static final int SCAN_DONT_KILL_APP = 1<<17; 397 static final int SCAN_IGNORE_FROZEN = 1<<18; 398 399 static final int REMOVE_CHATTY = 1<<16; 400 401 private static final int[] EMPTY_INT_ARRAY = new int[0]; 402 403 /** 404 * Timeout (in milliseconds) after which the watchdog should declare that 405 * our handler thread is wedged. The usual default for such things is one 406 * minute but we sometimes do very lengthy I/O operations on this thread, 407 * such as installing multi-gigabyte applications, so ours needs to be longer. 408 */ 409 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 410 411 /** 412 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 413 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 414 * settings entry if available, otherwise we use the hardcoded default. If it's been 415 * more than this long since the last fstrim, we force one during the boot sequence. 416 * 417 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 418 * one gets run at the next available charging+idle time. This final mandatory 419 * no-fstrim check kicks in only of the other scheduling criteria is never met. 420 */ 421 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 422 423 /** 424 * Whether verification is enabled by default. 425 */ 426 private static final boolean DEFAULT_VERIFY_ENABLE = true; 427 428 /** 429 * The default maximum time to wait for the verification agent to return in 430 * milliseconds. 431 */ 432 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 433 434 /** 435 * The default response for package verification timeout. 436 * 437 * This can be either PackageManager.VERIFICATION_ALLOW or 438 * PackageManager.VERIFICATION_REJECT. 439 */ 440 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 441 442 static final String PLATFORM_PACKAGE_NAME = "android"; 443 444 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 445 446 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 447 DEFAULT_CONTAINER_PACKAGE, 448 "com.android.defcontainer.DefaultContainerService"); 449 450 private static final String KILL_APP_REASON_GIDS_CHANGED = 451 "permission grant or revoke changed gids"; 452 453 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 454 "permissions revoked"; 455 456 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 457 458 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 459 460 private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000; 461 private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5; 462 463 /** Permission grant: not grant the permission. */ 464 private static final int GRANT_DENIED = 1; 465 466 /** Permission grant: grant the permission as an install permission. */ 467 private static final int GRANT_INSTALL = 2; 468 469 /** Permission grant: grant the permission as a runtime one. */ 470 private static final int GRANT_RUNTIME = 3; 471 472 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 473 private static final int GRANT_UPGRADE = 4; 474 475 /** Canonical intent used to identify what counts as a "web browser" app */ 476 private static final Intent sBrowserIntent; 477 static { 478 sBrowserIntent = new Intent(); 479 sBrowserIntent.setAction(Intent.ACTION_VIEW); 480 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 481 sBrowserIntent.setData(Uri.parse("http:")); 482 } 483 484 /** 485 * The set of all protected actions [i.e. those actions for which a high priority 486 * intent filter is disallowed]. 487 */ 488 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 489 static { 490 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 491 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 492 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 493 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 494 } 495 496 // Compilation reasons. 497 public static final int REASON_FIRST_BOOT = 0; 498 public static final int REASON_BOOT = 1; 499 public static final int REASON_INSTALL = 2; 500 public static final int REASON_BACKGROUND_DEXOPT = 3; 501 public static final int REASON_AB_OTA = 4; 502 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 503 public static final int REASON_SHARED_APK = 6; 504 public static final int REASON_FORCED_DEXOPT = 7; 505 public static final int REASON_CORE_APP = 8; 506 507 public static final int REASON_LAST = REASON_CORE_APP; 508 509 /** Special library name that skips shared libraries check during compilation. */ 510 private static final String SKIP_SHARED_LIBRARY_CHECK = "&"; 511 512 final ServiceThread mHandlerThread; 513 514 final PackageHandler mHandler; 515 516 private final ProcessLoggingHandler mProcessLoggingHandler; 517 518 /** 519 * Messages for {@link #mHandler} that need to wait for system ready before 520 * being dispatched. 521 */ 522 private ArrayList<Message> mPostSystemReadyMessages; 523 524 final int mSdkVersion = Build.VERSION.SDK_INT; 525 526 final Context mContext; 527 final boolean mFactoryTest; 528 final boolean mOnlyCore; 529 final DisplayMetrics mMetrics; 530 final int mDefParseFlags; 531 final String[] mSeparateProcesses; 532 final boolean mIsUpgrade; 533 final boolean mIsPreNUpgrade; 534 535 /** The location for ASEC container files on internal storage. */ 536 final String mAsecInternalPath; 537 538 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 539 // LOCK HELD. Can be called with mInstallLock held. 540 @GuardedBy("mInstallLock") 541 final Installer mInstaller; 542 543 /** Directory where installed third-party apps stored */ 544 final File mAppInstallDir; 545 final File mEphemeralInstallDir; 546 547 /** 548 * Directory to which applications installed internally have their 549 * 32 bit native libraries copied. 550 */ 551 private File mAppLib32InstallDir; 552 553 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 554 // apps. 555 final File mDrmAppPrivateInstallDir; 556 557 // ---------------------------------------------------------------- 558 559 // Lock for state used when installing and doing other long running 560 // operations. Methods that must be called with this lock held have 561 // the suffix "LI". 562 final Object mInstallLock = new Object(); 563 564 // ---------------------------------------------------------------- 565 566 // Keys are String (package name), values are Package. This also serves 567 // as the lock for the global state. Methods that must be called with 568 // this lock held have the prefix "LP". 569 @GuardedBy("mPackages") 570 final ArrayMap<String, PackageParser.Package> mPackages = 571 new ArrayMap<String, PackageParser.Package>(); 572 573 final ArrayMap<String, Set<String>> mKnownCodebase = 574 new ArrayMap<String, Set<String>>(); 575 576 // Tracks available target package names -> overlay package paths. 577 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 578 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 579 580 /** 581 * Tracks new system packages [received in an OTA] that we expect to 582 * find updated user-installed versions. Keys are package name, values 583 * are package location. 584 */ 585 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 586 /** 587 * Tracks high priority intent filters for protected actions. During boot, certain 588 * filter actions are protected and should never be allowed to have a high priority 589 * intent filter for them. However, there is one, and only one exception -- the 590 * setup wizard. It must be able to define a high priority intent filter for these 591 * actions to ensure there are no escapes from the wizard. We need to delay processing 592 * of these during boot as we need to look at all of the system packages in order 593 * to know which component is the setup wizard. 594 */ 595 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 596 /** 597 * Whether or not processing protected filters should be deferred. 598 */ 599 private boolean mDeferProtectedFilters = true; 600 601 /** 602 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 603 */ 604 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 605 /** 606 * Whether or not system app permissions should be promoted from install to runtime. 607 */ 608 boolean mPromoteSystemApps; 609 610 @GuardedBy("mPackages") 611 final Settings mSettings; 612 613 /** 614 * Set of package names that are currently "frozen", which means active 615 * surgery is being done on the code/data for that package. The platform 616 * will refuse to launch frozen packages to avoid race conditions. 617 * 618 * @see PackageFreezer 619 */ 620 @GuardedBy("mPackages") 621 final ArraySet<String> mFrozenPackages = new ArraySet<>(); 622 623 final ProtectedPackages mProtectedPackages; 624 625 boolean mFirstBoot; 626 627 // System configuration read by SystemConfig. 628 final int[] mGlobalGids; 629 final SparseArray<ArraySet<String>> mSystemPermissions; 630 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 631 632 // If mac_permissions.xml was found for seinfo labeling. 633 boolean mFoundPolicyFile; 634 635 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 636 637 public static final class SharedLibraryEntry { 638 public final String path; 639 public final String apk; 640 SharedLibraryEntry(String _path, String _apk)641 SharedLibraryEntry(String _path, String _apk) { 642 path = _path; 643 apk = _apk; 644 } 645 } 646 647 // Currently known shared libraries. 648 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 649 new ArrayMap<String, SharedLibraryEntry>(); 650 651 // All available activities, for your resolving pleasure. 652 final ActivityIntentResolver mActivities = 653 new ActivityIntentResolver(); 654 655 // All available receivers, for your resolving pleasure. 656 final ActivityIntentResolver mReceivers = 657 new ActivityIntentResolver(); 658 659 // All available services, for your resolving pleasure. 660 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 661 662 // All available providers, for your resolving pleasure. 663 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 664 665 // Mapping from provider base names (first directory in content URI codePath) 666 // to the provider information. 667 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 668 new ArrayMap<String, PackageParser.Provider>(); 669 670 // Mapping from instrumentation class names to info about them. 671 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 672 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 673 674 // Mapping from permission names to info about them. 675 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 676 new ArrayMap<String, PackageParser.PermissionGroup>(); 677 678 // Packages whose data we have transfered into another package, thus 679 // should no longer exist. 680 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 681 682 // Broadcast actions that are only available to the system. 683 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 684 685 /** List of packages waiting for verification. */ 686 final SparseArray<PackageVerificationState> mPendingVerification 687 = new SparseArray<PackageVerificationState>(); 688 689 /** Set of packages associated with each app op permission. */ 690 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 691 692 final PackageInstallerService mInstallerService; 693 694 private final PackageDexOptimizer mPackageDexOptimizer; 695 696 private AtomicInteger mNextMoveId = new AtomicInteger(); 697 private final MoveCallbacks mMoveCallbacks; 698 699 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 700 701 // Cache of users who need badging. 702 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 703 704 /** Token for keys in mPendingVerification. */ 705 private int mPendingVerificationToken = 0; 706 707 volatile boolean mSystemReady; 708 volatile boolean mSafeMode; 709 volatile boolean mHasSystemUidErrors; 710 711 ApplicationInfo mAndroidApplication; 712 final ActivityInfo mResolveActivity = new ActivityInfo(); 713 final ResolveInfo mResolveInfo = new ResolveInfo(); 714 ComponentName mResolveComponentName; 715 PackageParser.Package mPlatformPackage; 716 ComponentName mCustomResolverComponentName; 717 718 boolean mResolverReplaced = false; 719 720 private final @Nullable ComponentName mIntentFilterVerifierComponent; 721 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 722 723 private int mIntentFilterVerificationToken = 0; 724 725 /** Component that knows whether or not an ephemeral application exists */ 726 final ComponentName mEphemeralResolverComponent; 727 /** The service connection to the ephemeral resolver */ 728 final EphemeralResolverConnection mEphemeralResolverConnection; 729 730 /** Component used to install ephemeral applications */ 731 final ComponentName mEphemeralInstallerComponent; 732 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 733 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 734 735 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 736 = new SparseArray<IntentFilterVerificationState>(); 737 738 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; 739 740 // List of packages names to keep cached, even if they are uninstalled for all users 741 private List<String> mKeepUninstalledPackages; 742 743 private UserManagerInternal mUserManagerInternal; 744 745 private static class IFVerificationParams { 746 PackageParser.Package pkg; 747 boolean replacing; 748 int userId; 749 int verifierUid; 750 IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, int _userId, int _verifierUid)751 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 752 int _userId, int _verifierUid) { 753 pkg = _pkg; 754 replacing = _replacing; 755 userId = _userId; 756 replacing = _replacing; 757 verifierUid = _verifierUid; 758 } 759 } 760 761 private interface IntentFilterVerifier<T extends IntentFilter> { addOneIntentFilterVerification(int verifierId, int userId, int verificationId, T filter, String packageName)762 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 763 T filter, String packageName); startVerifications(int userId)764 void startVerifications(int userId); receiveVerificationResponse(int verificationId)765 void receiveVerificationResponse(int verificationId); 766 } 767 768 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 769 private Context mContext; 770 private ComponentName mIntentFilterVerifierComponent; 771 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 772 IntentVerifierProxy(Context context, ComponentName verifierComponent)773 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 774 mContext = context; 775 mIntentFilterVerifierComponent = verifierComponent; 776 } 777 getDefaultScheme()778 private String getDefaultScheme() { 779 return IntentFilter.SCHEME_HTTPS; 780 } 781 782 @Override startVerifications(int userId)783 public void startVerifications(int userId) { 784 // Launch verifications requests 785 int count = mCurrentIntentFilterVerifications.size(); 786 for (int n=0; n<count; n++) { 787 int verificationId = mCurrentIntentFilterVerifications.get(n); 788 final IntentFilterVerificationState ivs = 789 mIntentFilterVerificationStates.get(verificationId); 790 791 String packageName = ivs.getPackageName(); 792 793 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 794 final int filterCount = filters.size(); 795 ArraySet<String> domainsSet = new ArraySet<>(); 796 for (int m=0; m<filterCount; m++) { 797 PackageParser.ActivityIntentInfo filter = filters.get(m); 798 domainsSet.addAll(filter.getHostsList()); 799 } 800 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 801 synchronized (mPackages) { 802 if (mSettings.createIntentFilterVerificationIfNeededLPw( 803 packageName, domainsList) != null) { 804 scheduleWriteSettingsLocked(); 805 } 806 } 807 sendVerificationRequest(userId, verificationId, ivs); 808 } 809 mCurrentIntentFilterVerifications.clear(); 810 } 811 sendVerificationRequest(int userId, int verificationId, IntentFilterVerificationState ivs)812 private void sendVerificationRequest(int userId, int verificationId, 813 IntentFilterVerificationState ivs) { 814 815 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 816 verificationIntent.putExtra( 817 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 818 verificationId); 819 verificationIntent.putExtra( 820 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 821 getDefaultScheme()); 822 verificationIntent.putExtra( 823 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 824 ivs.getHostsString()); 825 verificationIntent.putExtra( 826 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 827 ivs.getPackageName()); 828 verificationIntent.setComponent(mIntentFilterVerifierComponent); 829 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 830 831 UserHandle user = new UserHandle(userId); 832 mContext.sendBroadcastAsUser(verificationIntent, user); 833 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 834 "Sending IntentFilter verification broadcast"); 835 } 836 receiveVerificationResponse(int verificationId)837 public void receiveVerificationResponse(int verificationId) { 838 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 839 840 final boolean verified = ivs.isVerified(); 841 842 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 843 final int count = filters.size(); 844 if (DEBUG_DOMAIN_VERIFICATION) { 845 Slog.i(TAG, "Received verification response " + verificationId 846 + " for " + count + " filters, verified=" + verified); 847 } 848 for (int n=0; n<count; n++) { 849 PackageParser.ActivityIntentInfo filter = filters.get(n); 850 filter.setVerified(verified); 851 852 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 853 + " verified with result:" + verified + " and hosts:" 854 + ivs.getHostsString()); 855 } 856 857 mIntentFilterVerificationStates.remove(verificationId); 858 859 final String packageName = ivs.getPackageName(); 860 IntentFilterVerificationInfo ivi = null; 861 862 synchronized (mPackages) { 863 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 864 } 865 if (ivi == null) { 866 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 867 + verificationId + " packageName:" + packageName); 868 return; 869 } 870 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 871 "Updating IntentFilterVerificationInfo for package " + packageName 872 +" verificationId:" + verificationId); 873 874 synchronized (mPackages) { 875 if (verified) { 876 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 877 } else { 878 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 879 } 880 scheduleWriteSettingsLocked(); 881 882 final int userId = ivs.getUserId(); 883 if (userId != UserHandle.USER_ALL) { 884 final int userStatus = 885 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 886 887 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 888 boolean needUpdate = false; 889 890 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 891 // already been set by the User thru the Disambiguation dialog 892 switch (userStatus) { 893 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 894 if (verified) { 895 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 896 } else { 897 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 898 } 899 needUpdate = true; 900 break; 901 902 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 903 if (verified) { 904 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 905 needUpdate = true; 906 } 907 break; 908 909 default: 910 // Nothing to do 911 } 912 913 if (needUpdate) { 914 mSettings.updateIntentFilterVerificationStatusLPw( 915 packageName, updatedStatus, userId); 916 scheduleWritePackageRestrictionsLocked(userId); 917 } 918 } 919 } 920 } 921 922 @Override addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, ActivityIntentInfo filter, String packageName)923 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 924 ActivityIntentInfo filter, String packageName) { 925 if (!hasValidDomains(filter)) { 926 return false; 927 } 928 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 929 if (ivs == null) { 930 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 931 packageName); 932 } 933 if (DEBUG_DOMAIN_VERIFICATION) { 934 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 935 } 936 ivs.addFilter(filter); 937 return true; 938 } 939 createDomainVerificationState(int verifierUid, int userId, int verificationId, String packageName)940 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 941 int userId, int verificationId, String packageName) { 942 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 943 verifierUid, userId, packageName); 944 ivs.setPendingState(); 945 synchronized (mPackages) { 946 mIntentFilterVerificationStates.append(verificationId, ivs); 947 mCurrentIntentFilterVerifications.add(verificationId); 948 } 949 return ivs; 950 } 951 } 952 hasValidDomains(ActivityIntentInfo filter)953 private static boolean hasValidDomains(ActivityIntentInfo filter) { 954 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 955 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 956 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 957 } 958 959 // Set of pending broadcasts for aggregating enable/disable of components. 960 static class PendingPackageBroadcasts { 961 // for each user id, a map of <package name -> components within that package> 962 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 963 PendingPackageBroadcasts()964 public PendingPackageBroadcasts() { 965 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 966 } 967 get(int userId, String packageName)968 public ArrayList<String> get(int userId, String packageName) { 969 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 970 return packages.get(packageName); 971 } 972 put(int userId, String packageName, ArrayList<String> components)973 public void put(int userId, String packageName, ArrayList<String> components) { 974 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 975 packages.put(packageName, components); 976 } 977 remove(int userId, String packageName)978 public void remove(int userId, String packageName) { 979 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 980 if (packages != null) { 981 packages.remove(packageName); 982 } 983 } 984 remove(int userId)985 public void remove(int userId) { 986 mUidMap.remove(userId); 987 } 988 userIdCount()989 public int userIdCount() { 990 return mUidMap.size(); 991 } 992 userIdAt(int n)993 public int userIdAt(int n) { 994 return mUidMap.keyAt(n); 995 } 996 packagesForUserId(int userId)997 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 998 return mUidMap.get(userId); 999 } 1000 size()1001 public int size() { 1002 // total number of pending broadcast entries across all userIds 1003 int num = 0; 1004 for (int i = 0; i< mUidMap.size(); i++) { 1005 num += mUidMap.valueAt(i).size(); 1006 } 1007 return num; 1008 } 1009 clear()1010 public void clear() { 1011 mUidMap.clear(); 1012 } 1013 getOrAllocate(int userId)1014 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 1015 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 1016 if (map == null) { 1017 map = new ArrayMap<String, ArrayList<String>>(); 1018 mUidMap.put(userId, map); 1019 } 1020 return map; 1021 } 1022 } 1023 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 1024 1025 // Service Connection to remote media container service to copy 1026 // package uri's from external media onto secure containers 1027 // or internal storage. 1028 private IMediaContainerService mContainerService = null; 1029 1030 static final int SEND_PENDING_BROADCAST = 1; 1031 static final int MCS_BOUND = 3; 1032 static final int END_COPY = 4; 1033 static final int INIT_COPY = 5; 1034 static final int MCS_UNBIND = 6; 1035 static final int START_CLEANING_PACKAGE = 7; 1036 static final int FIND_INSTALL_LOC = 8; 1037 static final int POST_INSTALL = 9; 1038 static final int MCS_RECONNECT = 10; 1039 static final int MCS_GIVE_UP = 11; 1040 static final int UPDATED_MEDIA_STATUS = 12; 1041 static final int WRITE_SETTINGS = 13; 1042 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 1043 static final int PACKAGE_VERIFIED = 15; 1044 static final int CHECK_PENDING_VERIFICATION = 16; 1045 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 1046 static final int INTENT_FILTER_VERIFIED = 18; 1047 static final int WRITE_PACKAGE_LIST = 19; 1048 1049 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 1050 1051 // Delay time in millisecs 1052 static final int BROADCAST_DELAY = 10 * 1000; 1053 1054 static UserManagerService sUserManager; 1055 1056 // Stores a list of users whose package restrictions file needs to be updated 1057 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1058 1059 final private DefaultContainerConnection mDefContainerConn = 1060 new DefaultContainerConnection(); 1061 class DefaultContainerConnection implements ServiceConnection { onServiceConnected(ComponentName name, IBinder service)1062 public void onServiceConnected(ComponentName name, IBinder service) { 1063 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1064 IMediaContainerService imcs = 1065 IMediaContainerService.Stub.asInterface(service); 1066 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1067 } 1068 onServiceDisconnected(ComponentName name)1069 public void onServiceDisconnected(ComponentName name) { 1070 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1071 } 1072 } 1073 1074 // Recordkeeping of restore-after-install operations that are currently in flight 1075 // between the Package Manager and the Backup Manager 1076 static class PostInstallData { 1077 public InstallArgs args; 1078 public PackageInstalledInfo res; 1079 PostInstallData(InstallArgs _a, PackageInstalledInfo _r)1080 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1081 args = _a; 1082 res = _r; 1083 } 1084 } 1085 1086 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1087 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1088 1089 // XML tags for backup/restore of various bits of state 1090 private static final String TAG_PREFERRED_BACKUP = "pa"; 1091 private static final String TAG_DEFAULT_APPS = "da"; 1092 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1093 1094 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1095 private static final String TAG_ALL_GRANTS = "rt-grants"; 1096 private static final String TAG_GRANT = "grant"; 1097 private static final String ATTR_PACKAGE_NAME = "pkg"; 1098 1099 private static final String TAG_PERMISSION = "perm"; 1100 private static final String ATTR_PERMISSION_NAME = "name"; 1101 private static final String ATTR_IS_GRANTED = "g"; 1102 private static final String ATTR_USER_SET = "set"; 1103 private static final String ATTR_USER_FIXED = "fixed"; 1104 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1105 1106 // System/policy permission grants are not backed up 1107 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1108 FLAG_PERMISSION_POLICY_FIXED 1109 | FLAG_PERMISSION_SYSTEM_FIXED 1110 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1111 1112 // And we back up these user-adjusted states 1113 private static final int USER_RUNTIME_GRANT_MASK = 1114 FLAG_PERMISSION_USER_SET 1115 | FLAG_PERMISSION_USER_FIXED 1116 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1117 1118 final @Nullable String mRequiredVerifierPackage; 1119 final @NonNull String mRequiredInstallerPackage; 1120 final @Nullable String mSetupWizardPackage; 1121 final @NonNull String mServicesSystemSharedLibraryPackageName; 1122 final @NonNull String mSharedSystemSharedLibraryPackageName; 1123 1124 private final PackageUsage mPackageUsage = new PackageUsage(); 1125 private final CompilerStats mCompilerStats = new CompilerStats(); 1126 1127 class PackageHandler extends Handler { 1128 private boolean mBound = false; 1129 final ArrayList<HandlerParams> mPendingInstalls = 1130 new ArrayList<HandlerParams>(); 1131 connectToService()1132 private boolean connectToService() { 1133 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1134 " DefaultContainerService"); 1135 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1136 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1137 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1138 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1139 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1140 mBound = true; 1141 return true; 1142 } 1143 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1144 return false; 1145 } 1146 disconnectService()1147 private void disconnectService() { 1148 mContainerService = null; 1149 mBound = false; 1150 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1151 mContext.unbindService(mDefContainerConn); 1152 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1153 } 1154 PackageHandler(Looper looper)1155 PackageHandler(Looper looper) { 1156 super(looper); 1157 } 1158 handleMessage(Message msg)1159 public void handleMessage(Message msg) { 1160 try { 1161 doHandleMessage(msg); 1162 } finally { 1163 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1164 } 1165 } 1166 doHandleMessage(Message msg)1167 void doHandleMessage(Message msg) { 1168 switch (msg.what) { 1169 case INIT_COPY: { 1170 HandlerParams params = (HandlerParams) msg.obj; 1171 int idx = mPendingInstalls.size(); 1172 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1173 // If a bind was already initiated we dont really 1174 // need to do anything. The pending install 1175 // will be processed later on. 1176 if (!mBound) { 1177 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1178 System.identityHashCode(mHandler)); 1179 // If this is the only one pending we might 1180 // have to bind to the service again. 1181 if (!connectToService()) { 1182 Slog.e(TAG, "Failed to bind to media container service"); 1183 params.serviceError(); 1184 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1185 System.identityHashCode(mHandler)); 1186 if (params.traceMethod != null) { 1187 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1188 params.traceCookie); 1189 } 1190 return; 1191 } else { 1192 // Once we bind to the service, the first 1193 // pending request will be processed. 1194 mPendingInstalls.add(idx, params); 1195 } 1196 } else { 1197 mPendingInstalls.add(idx, params); 1198 // Already bound to the service. Just make 1199 // sure we trigger off processing the first request. 1200 if (idx == 0) { 1201 mHandler.sendEmptyMessage(MCS_BOUND); 1202 } 1203 } 1204 break; 1205 } 1206 case MCS_BOUND: { 1207 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1208 if (msg.obj != null) { 1209 mContainerService = (IMediaContainerService) msg.obj; 1210 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1211 System.identityHashCode(mHandler)); 1212 } 1213 if (mContainerService == null) { 1214 if (!mBound) { 1215 // Something seriously wrong since we are not bound and we are not 1216 // waiting for connection. Bail out. 1217 Slog.e(TAG, "Cannot bind to media container service"); 1218 for (HandlerParams params : mPendingInstalls) { 1219 // Indicate service bind error 1220 params.serviceError(); 1221 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1222 System.identityHashCode(params)); 1223 if (params.traceMethod != null) { 1224 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1225 params.traceMethod, params.traceCookie); 1226 } 1227 return; 1228 } 1229 mPendingInstalls.clear(); 1230 } else { 1231 Slog.w(TAG, "Waiting to connect to media container service"); 1232 } 1233 } else if (mPendingInstalls.size() > 0) { 1234 HandlerParams params = mPendingInstalls.get(0); 1235 if (params != null) { 1236 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1237 System.identityHashCode(params)); 1238 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1239 if (params.startCopy()) { 1240 // We are done... look for more work or to 1241 // go idle. 1242 if (DEBUG_SD_INSTALL) Log.i(TAG, 1243 "Checking for more work or unbind..."); 1244 // Delete pending install 1245 if (mPendingInstalls.size() > 0) { 1246 mPendingInstalls.remove(0); 1247 } 1248 if (mPendingInstalls.size() == 0) { 1249 if (mBound) { 1250 if (DEBUG_SD_INSTALL) Log.i(TAG, 1251 "Posting delayed MCS_UNBIND"); 1252 removeMessages(MCS_UNBIND); 1253 Message ubmsg = obtainMessage(MCS_UNBIND); 1254 // Unbind after a little delay, to avoid 1255 // continual thrashing. 1256 sendMessageDelayed(ubmsg, 10000); 1257 } 1258 } else { 1259 // There are more pending requests in queue. 1260 // Just post MCS_BOUND message to trigger processing 1261 // of next pending install. 1262 if (DEBUG_SD_INSTALL) Log.i(TAG, 1263 "Posting MCS_BOUND for next work"); 1264 mHandler.sendEmptyMessage(MCS_BOUND); 1265 } 1266 } 1267 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1268 } 1269 } else { 1270 // Should never happen ideally. 1271 Slog.w(TAG, "Empty queue"); 1272 } 1273 break; 1274 } 1275 case MCS_RECONNECT: { 1276 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1277 if (mPendingInstalls.size() > 0) { 1278 if (mBound) { 1279 disconnectService(); 1280 } 1281 if (!connectToService()) { 1282 Slog.e(TAG, "Failed to bind to media container service"); 1283 for (HandlerParams params : mPendingInstalls) { 1284 // Indicate service bind error 1285 params.serviceError(); 1286 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1287 System.identityHashCode(params)); 1288 } 1289 mPendingInstalls.clear(); 1290 } 1291 } 1292 break; 1293 } 1294 case MCS_UNBIND: { 1295 // If there is no actual work left, then time to unbind. 1296 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1297 1298 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1299 if (mBound) { 1300 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1301 1302 disconnectService(); 1303 } 1304 } else if (mPendingInstalls.size() > 0) { 1305 // There are more pending requests in queue. 1306 // Just post MCS_BOUND message to trigger processing 1307 // of next pending install. 1308 mHandler.sendEmptyMessage(MCS_BOUND); 1309 } 1310 1311 break; 1312 } 1313 case MCS_GIVE_UP: { 1314 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1315 HandlerParams params = mPendingInstalls.remove(0); 1316 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1317 System.identityHashCode(params)); 1318 break; 1319 } 1320 case SEND_PENDING_BROADCAST: { 1321 String packages[]; 1322 ArrayList<String> components[]; 1323 int size = 0; 1324 int uids[]; 1325 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1326 synchronized (mPackages) { 1327 if (mPendingBroadcasts == null) { 1328 return; 1329 } 1330 size = mPendingBroadcasts.size(); 1331 if (size <= 0) { 1332 // Nothing to be done. Just return 1333 return; 1334 } 1335 packages = new String[size]; 1336 components = new ArrayList[size]; 1337 uids = new int[size]; 1338 int i = 0; // filling out the above arrays 1339 1340 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1341 int packageUserId = mPendingBroadcasts.userIdAt(n); 1342 Iterator<Map.Entry<String, ArrayList<String>>> it 1343 = mPendingBroadcasts.packagesForUserId(packageUserId) 1344 .entrySet().iterator(); 1345 while (it.hasNext() && i < size) { 1346 Map.Entry<String, ArrayList<String>> ent = it.next(); 1347 packages[i] = ent.getKey(); 1348 components[i] = ent.getValue(); 1349 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1350 uids[i] = (ps != null) 1351 ? UserHandle.getUid(packageUserId, ps.appId) 1352 : -1; 1353 i++; 1354 } 1355 } 1356 size = i; 1357 mPendingBroadcasts.clear(); 1358 } 1359 // Send broadcasts 1360 for (int i = 0; i < size; i++) { 1361 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1362 } 1363 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1364 break; 1365 } 1366 case START_CLEANING_PACKAGE: { 1367 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1368 final String packageName = (String)msg.obj; 1369 final int userId = msg.arg1; 1370 final boolean andCode = msg.arg2 != 0; 1371 synchronized (mPackages) { 1372 if (userId == UserHandle.USER_ALL) { 1373 int[] users = sUserManager.getUserIds(); 1374 for (int user : users) { 1375 mSettings.addPackageToCleanLPw( 1376 new PackageCleanItem(user, packageName, andCode)); 1377 } 1378 } else { 1379 mSettings.addPackageToCleanLPw( 1380 new PackageCleanItem(userId, packageName, andCode)); 1381 } 1382 } 1383 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1384 startCleaningPackages(); 1385 } break; 1386 case POST_INSTALL: { 1387 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1388 1389 PostInstallData data = mRunningInstalls.get(msg.arg1); 1390 final boolean didRestore = (msg.arg2 != 0); 1391 mRunningInstalls.delete(msg.arg1); 1392 1393 if (data != null) { 1394 InstallArgs args = data.args; 1395 PackageInstalledInfo parentRes = data.res; 1396 1397 final boolean grantPermissions = (args.installFlags 1398 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1399 final boolean killApp = (args.installFlags 1400 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1401 final String[] grantedPermissions = args.installGrantPermissions; 1402 1403 // Handle the parent package 1404 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1405 grantedPermissions, didRestore, args.installerPackageName, 1406 args.observer); 1407 1408 // Handle the child packages 1409 final int childCount = (parentRes.addedChildPackages != null) 1410 ? parentRes.addedChildPackages.size() : 0; 1411 for (int i = 0; i < childCount; i++) { 1412 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1413 handlePackagePostInstall(childRes, grantPermissions, killApp, 1414 grantedPermissions, false, args.installerPackageName, 1415 args.observer); 1416 } 1417 1418 // Log tracing if needed 1419 if (args.traceMethod != null) { 1420 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1421 args.traceCookie); 1422 } 1423 } else { 1424 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1425 } 1426 1427 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1428 } break; 1429 case UPDATED_MEDIA_STATUS: { 1430 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1431 boolean reportStatus = msg.arg1 == 1; 1432 boolean doGc = msg.arg2 == 1; 1433 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1434 if (doGc) { 1435 // Force a gc to clear up stale containers. 1436 Runtime.getRuntime().gc(); 1437 } 1438 if (msg.obj != null) { 1439 @SuppressWarnings("unchecked") 1440 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1441 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1442 // Unload containers 1443 unloadAllContainers(args); 1444 } 1445 if (reportStatus) { 1446 try { 1447 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1448 PackageHelper.getMountService().finishMediaUpdate(); 1449 } catch (RemoteException e) { 1450 Log.e(TAG, "MountService not running?"); 1451 } 1452 } 1453 } break; 1454 case WRITE_SETTINGS: { 1455 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1456 synchronized (mPackages) { 1457 removeMessages(WRITE_SETTINGS); 1458 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1459 mSettings.writeLPr(); 1460 mDirtyUsers.clear(); 1461 } 1462 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1463 } break; 1464 case WRITE_PACKAGE_RESTRICTIONS: { 1465 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1466 synchronized (mPackages) { 1467 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1468 for (int userId : mDirtyUsers) { 1469 mSettings.writePackageRestrictionsLPr(userId); 1470 } 1471 mDirtyUsers.clear(); 1472 } 1473 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1474 } break; 1475 case WRITE_PACKAGE_LIST: { 1476 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1477 synchronized (mPackages) { 1478 removeMessages(WRITE_PACKAGE_LIST); 1479 mSettings.writePackageListLPr(msg.arg1); 1480 } 1481 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1482 } break; 1483 case CHECK_PENDING_VERIFICATION: { 1484 final int verificationId = msg.arg1; 1485 final PackageVerificationState state = mPendingVerification.get(verificationId); 1486 1487 if ((state != null) && !state.timeoutExtended()) { 1488 final InstallArgs args = state.getInstallArgs(); 1489 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1490 1491 Slog.i(TAG, "Verification timed out for " + originUri); 1492 mPendingVerification.remove(verificationId); 1493 1494 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1495 1496 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1497 Slog.i(TAG, "Continuing with installation of " + originUri); 1498 state.setVerifierResponse(Binder.getCallingUid(), 1499 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1500 broadcastPackageVerified(verificationId, originUri, 1501 PackageManager.VERIFICATION_ALLOW, 1502 state.getInstallArgs().getUser()); 1503 try { 1504 ret = args.copyApk(mContainerService, true); 1505 } catch (RemoteException e) { 1506 Slog.e(TAG, "Could not contact the ContainerService"); 1507 } 1508 } else { 1509 broadcastPackageVerified(verificationId, originUri, 1510 PackageManager.VERIFICATION_REJECT, 1511 state.getInstallArgs().getUser()); 1512 } 1513 1514 Trace.asyncTraceEnd( 1515 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1516 1517 processPendingInstall(args, ret); 1518 mHandler.sendEmptyMessage(MCS_UNBIND); 1519 } 1520 break; 1521 } 1522 case PACKAGE_VERIFIED: { 1523 final int verificationId = msg.arg1; 1524 1525 final PackageVerificationState state = mPendingVerification.get(verificationId); 1526 if (state == null) { 1527 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1528 break; 1529 } 1530 1531 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1532 1533 state.setVerifierResponse(response.callerUid, response.code); 1534 1535 if (state.isVerificationComplete()) { 1536 mPendingVerification.remove(verificationId); 1537 1538 final InstallArgs args = state.getInstallArgs(); 1539 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1540 1541 int ret; 1542 if (state.isInstallAllowed()) { 1543 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1544 broadcastPackageVerified(verificationId, originUri, 1545 response.code, state.getInstallArgs().getUser()); 1546 try { 1547 ret = args.copyApk(mContainerService, true); 1548 } catch (RemoteException e) { 1549 Slog.e(TAG, "Could not contact the ContainerService"); 1550 } 1551 } else { 1552 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1553 } 1554 1555 Trace.asyncTraceEnd( 1556 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1557 1558 processPendingInstall(args, ret); 1559 mHandler.sendEmptyMessage(MCS_UNBIND); 1560 } 1561 1562 break; 1563 } 1564 case START_INTENT_FILTER_VERIFICATIONS: { 1565 IFVerificationParams params = (IFVerificationParams) msg.obj; 1566 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1567 params.replacing, params.pkg); 1568 break; 1569 } 1570 case INTENT_FILTER_VERIFIED: { 1571 final int verificationId = msg.arg1; 1572 1573 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1574 verificationId); 1575 if (state == null) { 1576 Slog.w(TAG, "Invalid IntentFilter verification token " 1577 + verificationId + " received"); 1578 break; 1579 } 1580 1581 final int userId = state.getUserId(); 1582 1583 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1584 "Processing IntentFilter verification with token:" 1585 + verificationId + " and userId:" + userId); 1586 1587 final IntentFilterVerificationResponse response = 1588 (IntentFilterVerificationResponse) msg.obj; 1589 1590 state.setVerifierResponse(response.callerUid, response.code); 1591 1592 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1593 "IntentFilter verification with token:" + verificationId 1594 + " and userId:" + userId 1595 + " is settings verifier response with response code:" 1596 + response.code); 1597 1598 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1599 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1600 + response.getFailedDomainsString()); 1601 } 1602 1603 if (state.isVerificationComplete()) { 1604 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1605 } else { 1606 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1607 "IntentFilter verification with token:" + verificationId 1608 + " was not said to be complete"); 1609 } 1610 1611 break; 1612 } 1613 } 1614 } 1615 } 1616 handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, boolean killApp, String[] grantedPermissions, boolean launchedForRestore, String installerPackage, IPackageInstallObserver2 installObserver)1617 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1618 boolean killApp, String[] grantedPermissions, 1619 boolean launchedForRestore, String installerPackage, 1620 IPackageInstallObserver2 installObserver) { 1621 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1622 // Send the removed broadcasts 1623 if (res.removedInfo != null) { 1624 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1625 } 1626 1627 // Now that we successfully installed the package, grant runtime 1628 // permissions if requested before broadcasting the install. 1629 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1630 >= Build.VERSION_CODES.M) { 1631 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1632 } 1633 1634 final boolean update = res.removedInfo != null 1635 && res.removedInfo.removedPackage != null; 1636 1637 // If this is the first time we have child packages for a disabled privileged 1638 // app that had no children, we grant requested runtime permissions to the new 1639 // children if the parent on the system image had them already granted. 1640 if (res.pkg.parentPackage != null) { 1641 synchronized (mPackages) { 1642 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1643 } 1644 } 1645 1646 synchronized (mPackages) { 1647 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1648 } 1649 1650 final String packageName = res.pkg.applicationInfo.packageName; 1651 Bundle extras = new Bundle(1); 1652 extras.putInt(Intent.EXTRA_UID, res.uid); 1653 1654 // Determine the set of users who are adding this package for 1655 // the first time vs. those who are seeing an update. 1656 int[] firstUsers = EMPTY_INT_ARRAY; 1657 int[] updateUsers = EMPTY_INT_ARRAY; 1658 if (res.origUsers == null || res.origUsers.length == 0) { 1659 firstUsers = res.newUsers; 1660 } else { 1661 for (int newUser : res.newUsers) { 1662 boolean isNew = true; 1663 for (int origUser : res.origUsers) { 1664 if (origUser == newUser) { 1665 isNew = false; 1666 break; 1667 } 1668 } 1669 if (isNew) { 1670 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1671 } else { 1672 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1673 } 1674 } 1675 } 1676 1677 // Send installed broadcasts if the install/update is not ephemeral 1678 if (!isEphemeral(res.pkg)) { 1679 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1680 1681 // Send added for users that see the package for the first time 1682 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1683 extras, 0 /*flags*/, null /*targetPackage*/, 1684 null /*finishedReceiver*/, firstUsers); 1685 1686 // Send added for users that don't see the package for the first time 1687 if (update) { 1688 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1689 } 1690 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1691 extras, 0 /*flags*/, null /*targetPackage*/, 1692 null /*finishedReceiver*/, updateUsers); 1693 1694 // Send replaced for users that don't see the package for the first time 1695 if (update) { 1696 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1697 packageName, extras, 0 /*flags*/, 1698 null /*targetPackage*/, null /*finishedReceiver*/, 1699 updateUsers); 1700 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1701 null /*package*/, null /*extras*/, 0 /*flags*/, 1702 packageName /*targetPackage*/, 1703 null /*finishedReceiver*/, updateUsers); 1704 } else if (launchedForRestore && !isSystemApp(res.pkg)) { 1705 // First-install and we did a restore, so we're responsible for the 1706 // first-launch broadcast. 1707 if (DEBUG_BACKUP) { 1708 Slog.i(TAG, "Post-restore of " + packageName 1709 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers)); 1710 } 1711 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers); 1712 } 1713 1714 // Send broadcast package appeared if forward locked/external for all users 1715 // treat asec-hosted packages like removable media on upgrade 1716 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1717 if (DEBUG_INSTALL) { 1718 Slog.i(TAG, "upgrading pkg " + res.pkg 1719 + " is ASEC-hosted -> AVAILABLE"); 1720 } 1721 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1722 ArrayList<String> pkgList = new ArrayList<>(1); 1723 pkgList.add(packageName); 1724 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1725 } 1726 } 1727 1728 // Work that needs to happen on first install within each user 1729 if (firstUsers != null && firstUsers.length > 0) { 1730 synchronized (mPackages) { 1731 for (int userId : firstUsers) { 1732 // If this app is a browser and it's newly-installed for some 1733 // users, clear any default-browser state in those users. The 1734 // app's nature doesn't depend on the user, so we can just check 1735 // its browser nature in any user and generalize. 1736 if (packageIsBrowser(packageName, userId)) { 1737 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1738 } 1739 1740 // We may also need to apply pending (restored) runtime 1741 // permission grants within these users. 1742 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1743 } 1744 } 1745 } 1746 1747 // Log current value of "unknown sources" setting 1748 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1749 getUnknownSourcesSettings()); 1750 1751 // Force a gc to clear up things 1752 Runtime.getRuntime().gc(); 1753 1754 // Remove the replaced package's older resources safely now 1755 // We delete after a gc for applications on sdcard. 1756 if (res.removedInfo != null && res.removedInfo.args != null) { 1757 synchronized (mInstallLock) { 1758 res.removedInfo.args.doPostDeleteLI(true); 1759 } 1760 } 1761 } 1762 1763 // If someone is watching installs - notify them 1764 if (installObserver != null) { 1765 try { 1766 Bundle extras = extrasForInstallResult(res); 1767 installObserver.onPackageInstalled(res.name, res.returnCode, 1768 res.returnMsg, extras); 1769 } catch (RemoteException e) { 1770 Slog.i(TAG, "Observer no longer exists."); 1771 } 1772 } 1773 } 1774 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( PackageParser.Package pkg)1775 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1776 PackageParser.Package pkg) { 1777 if (pkg.parentPackage == null) { 1778 return; 1779 } 1780 if (pkg.requestedPermissions == null) { 1781 return; 1782 } 1783 final PackageSetting disabledSysParentPs = mSettings 1784 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1785 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1786 || !disabledSysParentPs.isPrivileged() 1787 || (disabledSysParentPs.childPackageNames != null 1788 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1789 return; 1790 } 1791 final int[] allUserIds = sUserManager.getUserIds(); 1792 final int permCount = pkg.requestedPermissions.size(); 1793 for (int i = 0; i < permCount; i++) { 1794 String permission = pkg.requestedPermissions.get(i); 1795 BasePermission bp = mSettings.mPermissions.get(permission); 1796 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1797 continue; 1798 } 1799 for (int userId : allUserIds) { 1800 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1801 permission, userId)) { 1802 grantRuntimePermission(pkg.packageName, permission, userId); 1803 } 1804 } 1805 } 1806 } 1807 1808 private StorageEventListener mStorageListener = new StorageEventListener() { 1809 @Override 1810 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1811 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1812 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1813 final String volumeUuid = vol.getFsUuid(); 1814 1815 // Clean up any users or apps that were removed or recreated 1816 // while this volume was missing 1817 reconcileUsers(volumeUuid); 1818 reconcileApps(volumeUuid); 1819 1820 // Clean up any install sessions that expired or were 1821 // cancelled while this volume was missing 1822 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1823 1824 loadPrivatePackages(vol); 1825 1826 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1827 unloadPrivatePackages(vol); 1828 } 1829 } 1830 1831 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1832 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1833 updateExternalMediaStatus(true, false); 1834 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1835 updateExternalMediaStatus(false, false); 1836 } 1837 } 1838 } 1839 1840 @Override 1841 public void onVolumeForgotten(String fsUuid) { 1842 if (TextUtils.isEmpty(fsUuid)) { 1843 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1844 return; 1845 } 1846 1847 // Remove any apps installed on the forgotten volume 1848 synchronized (mPackages) { 1849 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1850 for (PackageSetting ps : packages) { 1851 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1852 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1853 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1854 } 1855 1856 mSettings.onVolumeForgotten(fsUuid); 1857 mSettings.writeLPr(); 1858 } 1859 } 1860 }; 1861 grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, String[] grantedPermissions)1862 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1863 String[] grantedPermissions) { 1864 for (int userId : userIds) { 1865 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1866 } 1867 1868 // We could have touched GID membership, so flush out packages.list 1869 synchronized (mPackages) { 1870 mSettings.writePackageListLPr(); 1871 } 1872 } 1873 grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, String[] grantedPermissions)1874 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1875 String[] grantedPermissions) { 1876 SettingBase sb = (SettingBase) pkg.mExtras; 1877 if (sb == null) { 1878 return; 1879 } 1880 1881 PermissionsState permissionsState = sb.getPermissionsState(); 1882 1883 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1884 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1885 1886 for (String permission : pkg.requestedPermissions) { 1887 final BasePermission bp; 1888 synchronized (mPackages) { 1889 bp = mSettings.mPermissions.get(permission); 1890 } 1891 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1892 && (grantedPermissions == null 1893 || ArrayUtils.contains(grantedPermissions, permission))) { 1894 final int flags = permissionsState.getPermissionFlags(permission, userId); 1895 // Installer cannot change immutable permissions. 1896 if ((flags & immutableFlags) == 0) { 1897 grantRuntimePermission(pkg.packageName, permission, userId); 1898 } 1899 } 1900 } 1901 } 1902 extrasForInstallResult(PackageInstalledInfo res)1903 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1904 Bundle extras = null; 1905 switch (res.returnCode) { 1906 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1907 extras = new Bundle(); 1908 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1909 res.origPermission); 1910 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1911 res.origPackage); 1912 break; 1913 } 1914 case PackageManager.INSTALL_SUCCEEDED: { 1915 extras = new Bundle(); 1916 extras.putBoolean(Intent.EXTRA_REPLACING, 1917 res.removedInfo != null && res.removedInfo.removedPackage != null); 1918 break; 1919 } 1920 } 1921 return extras; 1922 } 1923 scheduleWriteSettingsLocked()1924 void scheduleWriteSettingsLocked() { 1925 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1926 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1927 } 1928 } 1929 scheduleWritePackageListLocked(int userId)1930 void scheduleWritePackageListLocked(int userId) { 1931 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) { 1932 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST); 1933 msg.arg1 = userId; 1934 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); 1935 } 1936 } 1937 scheduleWritePackageRestrictionsLocked(UserHandle user)1938 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 1939 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 1940 scheduleWritePackageRestrictionsLocked(userId); 1941 } 1942 scheduleWritePackageRestrictionsLocked(int userId)1943 void scheduleWritePackageRestrictionsLocked(int userId) { 1944 final int[] userIds = (userId == UserHandle.USER_ALL) 1945 ? sUserManager.getUserIds() : new int[]{userId}; 1946 for (int nextUserId : userIds) { 1947 if (!sUserManager.exists(nextUserId)) return; 1948 mDirtyUsers.add(nextUserId); 1949 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1950 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1951 } 1952 } 1953 } 1954 main(Context context, Installer installer, boolean factoryTest, boolean onlyCore)1955 public static PackageManagerService main(Context context, Installer installer, 1956 boolean factoryTest, boolean onlyCore) { 1957 // Self-check for initial settings. 1958 PackageManagerServiceCompilerMapping.checkProperties(); 1959 1960 PackageManagerService m = new PackageManagerService(context, installer, 1961 factoryTest, onlyCore); 1962 m.enableSystemUserPackages(); 1963 ServiceManager.addService("package", m); 1964 return m; 1965 } 1966 enableSystemUserPackages()1967 private void enableSystemUserPackages() { 1968 if (!UserManager.isSplitSystemUser()) { 1969 return; 1970 } 1971 // For system user, enable apps based on the following conditions: 1972 // - app is whitelisted or belong to one of these groups: 1973 // -- system app which has no launcher icons 1974 // -- system app which has INTERACT_ACROSS_USERS permission 1975 // -- system IME app 1976 // - app is not in the blacklist 1977 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 1978 Set<String> enableApps = new ArraySet<>(); 1979 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 1980 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 1981 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 1982 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 1983 enableApps.addAll(wlApps); 1984 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 1985 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 1986 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 1987 enableApps.removeAll(blApps); 1988 Log.i(TAG, "Applications installed for system user: " + enableApps); 1989 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 1990 UserHandle.SYSTEM); 1991 final int allAppsSize = allAps.size(); 1992 synchronized (mPackages) { 1993 for (int i = 0; i < allAppsSize; i++) { 1994 String pName = allAps.get(i); 1995 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 1996 // Should not happen, but we shouldn't be failing if it does 1997 if (pkgSetting == null) { 1998 continue; 1999 } 2000 boolean install = enableApps.contains(pName); 2001 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2002 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2003 + " for system user"); 2004 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2005 } 2006 } 2007 } 2008 } 2009 getDefaultDisplayMetrics(Context context, DisplayMetrics metrics)2010 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2011 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2012 Context.DISPLAY_SERVICE); 2013 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2014 } 2015 2016 /** 2017 * Requests that files preopted on a secondary system partition be copied to the data partition 2018 * if possible. Note that the actual copying of the files is accomplished by init for security 2019 * reasons. This simply requests that the copy takes place and awaits confirmation of its 2020 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy. 2021 */ requestCopyPreoptedFiles()2022 private static void requestCopyPreoptedFiles() { 2023 final int WAIT_TIME_MS = 100; 2024 final String CP_PREOPT_PROPERTY = "sys.cppreopt"; 2025 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) { 2026 SystemProperties.set(CP_PREOPT_PROPERTY, "requested"); 2027 // We will wait for up to 100 seconds. 2028 final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000; 2029 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) { 2030 try { 2031 Thread.sleep(WAIT_TIME_MS); 2032 } catch (InterruptedException e) { 2033 // Do nothing 2034 } 2035 if (SystemClock.uptimeMillis() > timeEnd) { 2036 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out"); 2037 Slog.wtf(TAG, "cppreopt did not finish!"); 2038 break; 2039 } 2040 } 2041 } 2042 } 2043 PackageManagerService(Context context, Installer installer, boolean factoryTest, boolean onlyCore)2044 public PackageManagerService(Context context, Installer installer, 2045 boolean factoryTest, boolean onlyCore) { 2046 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2047 SystemClock.uptimeMillis()); 2048 2049 if (mSdkVersion <= 0) { 2050 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2051 } 2052 2053 mContext = context; 2054 mFactoryTest = factoryTest; 2055 mOnlyCore = onlyCore; 2056 mMetrics = new DisplayMetrics(); 2057 mSettings = new Settings(mPackages); 2058 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2059 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2060 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2061 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2062 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2063 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2064 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2065 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2066 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2067 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2068 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2069 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2070 2071 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2072 if (separateProcesses != null && separateProcesses.length() > 0) { 2073 if ("*".equals(separateProcesses)) { 2074 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2075 mSeparateProcesses = null; 2076 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2077 } else { 2078 mDefParseFlags = 0; 2079 mSeparateProcesses = separateProcesses.split(","); 2080 Slog.w(TAG, "Running with debug.separate_processes: " 2081 + separateProcesses); 2082 } 2083 } else { 2084 mDefParseFlags = 0; 2085 mSeparateProcesses = null; 2086 } 2087 2088 mInstaller = installer; 2089 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2090 "*dexopt*"); 2091 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2092 2093 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2094 FgThread.get().getLooper()); 2095 2096 getDefaultDisplayMetrics(context, mMetrics); 2097 2098 SystemConfig systemConfig = SystemConfig.getInstance(); 2099 mGlobalGids = systemConfig.getGlobalGids(); 2100 mSystemPermissions = systemConfig.getSystemPermissions(); 2101 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2102 2103 mProtectedPackages = new ProtectedPackages(mContext); 2104 2105 synchronized (mInstallLock) { 2106 // writer 2107 synchronized (mPackages) { 2108 mHandlerThread = new ServiceThread(TAG, 2109 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2110 mHandlerThread.start(); 2111 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2112 mProcessLoggingHandler = new ProcessLoggingHandler(); 2113 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2114 2115 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); 2116 2117 File dataDir = Environment.getDataDirectory(); 2118 mAppInstallDir = new File(dataDir, "app"); 2119 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2120 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2121 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2122 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2123 2124 sUserManager = new UserManagerService(context, this, mPackages); 2125 2126 // Propagate permission configuration in to package manager. 2127 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2128 = systemConfig.getPermissions(); 2129 for (int i=0; i<permConfig.size(); i++) { 2130 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2131 BasePermission bp = mSettings.mPermissions.get(perm.name); 2132 if (bp == null) { 2133 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2134 mSettings.mPermissions.put(perm.name, bp); 2135 } 2136 if (perm.gids != null) { 2137 bp.setGids(perm.gids, perm.perUser); 2138 } 2139 } 2140 2141 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2142 for (int i=0; i<libConfig.size(); i++) { 2143 mSharedLibraries.put(libConfig.keyAt(i), 2144 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2145 } 2146 2147 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2148 2149 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); 2150 2151 if (mFirstBoot) { 2152 requestCopyPreoptedFiles(); 2153 } 2154 2155 String customResolverActivity = Resources.getSystem().getString( 2156 R.string.config_customResolverActivity); 2157 if (TextUtils.isEmpty(customResolverActivity)) { 2158 customResolverActivity = null; 2159 } else { 2160 mCustomResolverComponentName = ComponentName.unflattenFromString( 2161 customResolverActivity); 2162 } 2163 2164 long startTime = SystemClock.uptimeMillis(); 2165 2166 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2167 startTime); 2168 2169 // Set flag to monitor and not change apk file paths when 2170 // scanning install directories. 2171 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 2172 2173 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2174 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2175 2176 if (bootClassPath == null) { 2177 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2178 } 2179 2180 if (systemServerClassPath == null) { 2181 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2182 } 2183 2184 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2185 final String[] dexCodeInstructionSets = 2186 getDexCodeInstructionSets( 2187 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2188 2189 /** 2190 * Ensure all external libraries have had dexopt run on them. 2191 */ 2192 if (mSharedLibraries.size() > 0) { 2193 // NOTE: For now, we're compiling these system "shared libraries" 2194 // (and framework jars) into all available architectures. It's possible 2195 // to compile them only when we come across an app that uses them (there's 2196 // already logic for that in scanPackageLI) but that adds some complexity. 2197 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2198 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2199 final String lib = libEntry.path; 2200 if (lib == null) { 2201 continue; 2202 } 2203 2204 try { 2205 // Shared libraries do not have profiles so we perform a full 2206 // AOT compilation (if needed). 2207 int dexoptNeeded = DexFile.getDexOptNeeded( 2208 lib, dexCodeInstructionSet, 2209 getCompilerFilterForReason(REASON_SHARED_APK), 2210 false /* newProfile */); 2211 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2212 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2213 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, 2214 getCompilerFilterForReason(REASON_SHARED_APK), 2215 StorageManager.UUID_PRIVATE_INTERNAL, 2216 SKIP_SHARED_LIBRARY_CHECK); 2217 } 2218 } catch (FileNotFoundException e) { 2219 Slog.w(TAG, "Library not found: " + lib); 2220 } catch (IOException | InstallerException e) { 2221 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2222 + e.getMessage()); 2223 } 2224 } 2225 } 2226 } 2227 2228 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2229 2230 final VersionInfo ver = mSettings.getInternalVersion(); 2231 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2232 2233 // when upgrading from pre-M, promote system app permissions from install to runtime 2234 mPromoteSystemApps = 2235 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2236 2237 // When upgrading from pre-N, we need to handle package extraction like first boot, 2238 // as there is no profiling data available. 2239 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; 2240 2241 // save off the names of pre-existing system packages prior to scanning; we don't 2242 // want to automatically grant runtime permissions for new system apps 2243 if (mPromoteSystemApps) { 2244 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2245 while (pkgSettingIter.hasNext()) { 2246 PackageSetting ps = pkgSettingIter.next(); 2247 if (isSystemApp(ps)) { 2248 mExistingSystemPackages.add(ps.name); 2249 } 2250 } 2251 } 2252 2253 // Collect vendor overlay packages. 2254 // (Do this before scanning any apps.) 2255 // For security and version matching reason, only consider 2256 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2257 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2258 scanDirTracedLI(vendorOverlayDir, mDefParseFlags 2259 | PackageParser.PARSE_IS_SYSTEM 2260 | PackageParser.PARSE_IS_SYSTEM_DIR 2261 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2262 2263 // Find base frameworks (resource packages without code). 2264 scanDirTracedLI(frameworkDir, mDefParseFlags 2265 | PackageParser.PARSE_IS_SYSTEM 2266 | PackageParser.PARSE_IS_SYSTEM_DIR 2267 | PackageParser.PARSE_IS_PRIVILEGED, 2268 scanFlags | SCAN_NO_DEX, 0); 2269 2270 // Collected privileged system packages. 2271 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2272 scanDirTracedLI(privilegedAppDir, mDefParseFlags 2273 | PackageParser.PARSE_IS_SYSTEM 2274 | PackageParser.PARSE_IS_SYSTEM_DIR 2275 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2276 2277 // Collect ordinary system packages. 2278 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2279 scanDirTracedLI(systemAppDir, mDefParseFlags 2280 | PackageParser.PARSE_IS_SYSTEM 2281 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2282 2283 // Collect all vendor packages. 2284 File vendorAppDir = new File("/vendor/app"); 2285 try { 2286 vendorAppDir = vendorAppDir.getCanonicalFile(); 2287 } catch (IOException e) { 2288 // failed to look up canonical path, continue with original one 2289 } 2290 scanDirTracedLI(vendorAppDir, mDefParseFlags 2291 | PackageParser.PARSE_IS_SYSTEM 2292 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2293 2294 // Collect all OEM packages. 2295 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2296 scanDirTracedLI(oemAppDir, mDefParseFlags 2297 | PackageParser.PARSE_IS_SYSTEM 2298 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2299 2300 // Prune any system packages that no longer exist. 2301 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2302 if (!mOnlyCore) { 2303 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2304 while (psit.hasNext()) { 2305 PackageSetting ps = psit.next(); 2306 2307 /* 2308 * If this is not a system app, it can't be a 2309 * disable system app. 2310 */ 2311 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2312 continue; 2313 } 2314 2315 /* 2316 * If the package is scanned, it's not erased. 2317 */ 2318 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2319 if (scannedPkg != null) { 2320 /* 2321 * If the system app is both scanned and in the 2322 * disabled packages list, then it must have been 2323 * added via OTA. Remove it from the currently 2324 * scanned package so the previously user-installed 2325 * application can be scanned. 2326 */ 2327 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2328 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2329 + ps.name + "; removing system app. Last known codePath=" 2330 + ps.codePathString + ", installStatus=" + ps.installStatus 2331 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2332 + scannedPkg.mVersionCode); 2333 removePackageLI(scannedPkg, true); 2334 mExpectingBetter.put(ps.name, ps.codePath); 2335 } 2336 2337 continue; 2338 } 2339 2340 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2341 psit.remove(); 2342 logCriticalInfo(Log.WARN, "System package " + ps.name 2343 + " no longer exists; it's data will be wiped"); 2344 // Actual deletion of code and data will be handled by later 2345 // reconciliation step 2346 } else { 2347 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2348 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2349 possiblyDeletedUpdatedSystemApps.add(ps.name); 2350 } 2351 } 2352 } 2353 } 2354 2355 //look for any incomplete package installations 2356 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2357 for (int i = 0; i < deletePkgsList.size(); i++) { 2358 // Actual deletion of code and data will be handled by later 2359 // reconciliation step 2360 final String packageName = deletePkgsList.get(i).name; 2361 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); 2362 synchronized (mPackages) { 2363 mSettings.removePackageLPw(packageName); 2364 } 2365 } 2366 2367 //delete tmp files 2368 deleteTempPackageFiles(); 2369 2370 // Remove any shared userIDs that have no associated packages 2371 mSettings.pruneSharedUsersLPw(); 2372 2373 if (!mOnlyCore) { 2374 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2375 SystemClock.uptimeMillis()); 2376 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2377 2378 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 2379 | PackageParser.PARSE_FORWARD_LOCK, 2380 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2381 2382 scanDirLI(mEphemeralInstallDir, mDefParseFlags 2383 | PackageParser.PARSE_IS_EPHEMERAL, 2384 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2385 2386 /** 2387 * Remove disable package settings for any updated system 2388 * apps that were removed via an OTA. If they're not a 2389 * previously-updated app, remove them completely. 2390 * Otherwise, just revoke their system-level permissions. 2391 */ 2392 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2393 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2394 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2395 2396 String msg; 2397 if (deletedPkg == null) { 2398 msg = "Updated system package " + deletedAppName 2399 + " no longer exists; it's data will be wiped"; 2400 // Actual deletion of code and data will be handled by later 2401 // reconciliation step 2402 } else { 2403 msg = "Updated system app + " + deletedAppName 2404 + " no longer present; removing system privileges for " 2405 + deletedAppName; 2406 2407 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2408 2409 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2410 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2411 } 2412 logCriticalInfo(Log.WARN, msg); 2413 } 2414 2415 /** 2416 * Make sure all system apps that we expected to appear on 2417 * the userdata partition actually showed up. If they never 2418 * appeared, crawl back and revive the system version. 2419 */ 2420 for (int i = 0; i < mExpectingBetter.size(); i++) { 2421 final String packageName = mExpectingBetter.keyAt(i); 2422 if (!mPackages.containsKey(packageName)) { 2423 final File scanFile = mExpectingBetter.valueAt(i); 2424 2425 logCriticalInfo(Log.WARN, "Expected better " + packageName 2426 + " but never showed up; reverting to system"); 2427 2428 int reparseFlags = mDefParseFlags; 2429 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2430 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2431 | PackageParser.PARSE_IS_SYSTEM_DIR 2432 | PackageParser.PARSE_IS_PRIVILEGED; 2433 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2434 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2435 | PackageParser.PARSE_IS_SYSTEM_DIR; 2436 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2437 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2438 | PackageParser.PARSE_IS_SYSTEM_DIR; 2439 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2440 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2441 | PackageParser.PARSE_IS_SYSTEM_DIR; 2442 } else { 2443 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2444 continue; 2445 } 2446 2447 mSettings.enableSystemPackageLPw(packageName); 2448 2449 try { 2450 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2451 } catch (PackageManagerException e) { 2452 Slog.e(TAG, "Failed to parse original system package: " 2453 + e.getMessage()); 2454 } 2455 } 2456 } 2457 } 2458 mExpectingBetter.clear(); 2459 2460 // Resolve protected action filters. Only the setup wizard is allowed to 2461 // have a high priority filter for these actions. 2462 mSetupWizardPackage = getSetupWizardPackageName(); 2463 if (mProtectedFilters.size() > 0) { 2464 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2465 Slog.i(TAG, "No setup wizard;" 2466 + " All protected intents capped to priority 0"); 2467 } 2468 for (ActivityIntentInfo filter : mProtectedFilters) { 2469 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2470 if (DEBUG_FILTERS) { 2471 Slog.i(TAG, "Found setup wizard;" 2472 + " allow priority " + filter.getPriority() + ";" 2473 + " package: " + filter.activity.info.packageName 2474 + " activity: " + filter.activity.className 2475 + " priority: " + filter.getPriority()); 2476 } 2477 // skip setup wizard; allow it to keep the high priority filter 2478 continue; 2479 } 2480 Slog.w(TAG, "Protected action; cap priority to 0;" 2481 + " package: " + filter.activity.info.packageName 2482 + " activity: " + filter.activity.className 2483 + " origPrio: " + filter.getPriority()); 2484 filter.setPriority(0); 2485 } 2486 } 2487 mDeferProtectedFilters = false; 2488 mProtectedFilters.clear(); 2489 2490 // Now that we know all of the shared libraries, update all clients to have 2491 // the correct library paths. 2492 updateAllSharedLibrariesLPw(); 2493 2494 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2495 // NOTE: We ignore potential failures here during a system scan (like 2496 // the rest of the commands above) because there's precious little we 2497 // can do about it. A settings error is reported, though. 2498 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2499 false /* boot complete */); 2500 } 2501 2502 // Now that we know all the packages we are keeping, 2503 // read and update their last usage times. 2504 mPackageUsage.read(mPackages); 2505 mCompilerStats.read(); 2506 2507 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2508 SystemClock.uptimeMillis()); 2509 Slog.i(TAG, "Time to scan packages: " 2510 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2511 + " seconds"); 2512 2513 // If the platform SDK has changed since the last time we booted, 2514 // we need to re-grant app permission to catch any new ones that 2515 // appear. This is really a hack, and means that apps can in some 2516 // cases get permissions that the user didn't initially explicitly 2517 // allow... it would be nice to have some better way to handle 2518 // this situation. 2519 int updateFlags = UPDATE_PERMISSIONS_ALL; 2520 if (ver.sdkVersion != mSdkVersion) { 2521 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2522 + mSdkVersion + "; regranting permissions for internal storage"); 2523 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2524 } 2525 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2526 ver.sdkVersion = mSdkVersion; 2527 2528 // If this is the first boot or an update from pre-M, and it is a normal 2529 // boot, then we need to initialize the default preferred apps across 2530 // all defined users. 2531 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 2532 for (UserInfo user : sUserManager.getUsers(true)) { 2533 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2534 applyFactoryDefaultBrowserLPw(user.id); 2535 primeDomainVerificationsLPw(user.id); 2536 } 2537 } 2538 2539 // Prepare storage for system user really early during boot, 2540 // since core system apps like SettingsProvider and SystemUI 2541 // can't wait for user to start 2542 final int storageFlags; 2543 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2544 storageFlags = StorageManager.FLAG_STORAGE_DE; 2545 } else { 2546 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2547 } 2548 reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2549 storageFlags); 2550 2551 // If this is first boot after an OTA, and a normal boot, then 2552 // we need to clear code cache directories. 2553 // Note that we do *not* clear the application profiles. These remain valid 2554 // across OTAs and are used to drive profile verification (post OTA) and 2555 // profile compilation (without waiting to collect a fresh set of profiles). 2556 if (mIsUpgrade && !onlyCore) { 2557 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2558 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2559 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2560 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2561 // No apps are running this early, so no need to freeze 2562 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 2563 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 2564 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2565 } 2566 } 2567 ver.fingerprint = Build.FINGERPRINT; 2568 } 2569 2570 checkDefaultBrowser(); 2571 2572 // clear only after permissions and other defaults have been updated 2573 mExistingSystemPackages.clear(); 2574 mPromoteSystemApps = false; 2575 2576 // All the changes are done during package scanning. 2577 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2578 2579 // can downgrade to reader 2580 mSettings.writeLPr(); 2581 2582 // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty 2583 // early on (before the package manager declares itself as early) because other 2584 // components in the system server might ask for package contexts for these apps. 2585 // 2586 // Note that "onlyCore" in this context means the system is encrypted or encrypting 2587 // (i.e, that the data partition is unavailable). 2588 if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { 2589 long start = System.nanoTime(); 2590 List<PackageParser.Package> coreApps = new ArrayList<>(); 2591 for (PackageParser.Package pkg : mPackages.values()) { 2592 if (pkg.coreApp) { 2593 coreApps.add(pkg); 2594 } 2595 } 2596 2597 int[] stats = performDexOptUpgrade(coreApps, false, 2598 getCompilerFilterForReason(REASON_CORE_APP)); 2599 2600 final int elapsedTimeSeconds = 2601 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); 2602 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); 2603 2604 if (DEBUG_DEXOPT) { 2605 Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + 2606 stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); 2607 } 2608 2609 2610 // TODO: Should we log these stats to tron too ? 2611 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); 2612 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); 2613 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); 2614 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); 2615 } 2616 2617 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2618 SystemClock.uptimeMillis()); 2619 2620 if (!mOnlyCore) { 2621 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2622 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2623 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2624 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2625 mIntentFilterVerifierComponent); 2626 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2627 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 2628 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2629 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED); 2630 } else { 2631 mRequiredVerifierPackage = null; 2632 mRequiredInstallerPackage = null; 2633 mIntentFilterVerifierComponent = null; 2634 mIntentFilterVerifier = null; 2635 mServicesSystemSharedLibraryPackageName = null; 2636 mSharedSystemSharedLibraryPackageName = null; 2637 } 2638 2639 mInstallerService = new PackageInstallerService(context, this); 2640 2641 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2642 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2643 // both the installer and resolver must be present to enable ephemeral 2644 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2645 if (DEBUG_EPHEMERAL) { 2646 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2647 + " installer:" + ephemeralInstallerComponent); 2648 } 2649 mEphemeralResolverComponent = ephemeralResolverComponent; 2650 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2651 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2652 mEphemeralResolverConnection = 2653 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2654 } else { 2655 if (DEBUG_EPHEMERAL) { 2656 final String missingComponent = 2657 (ephemeralResolverComponent == null) 2658 ? (ephemeralInstallerComponent == null) 2659 ? "resolver and installer" 2660 : "resolver" 2661 : "installer"; 2662 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2663 } 2664 mEphemeralResolverComponent = null; 2665 mEphemeralInstallerComponent = null; 2666 mEphemeralResolverConnection = null; 2667 } 2668 2669 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2670 } // synchronized (mPackages) 2671 } // synchronized (mInstallLock) 2672 2673 // Now after opening every single application zip, make sure they 2674 // are all flushed. Not really needed, but keeps things nice and 2675 // tidy. 2676 Runtime.getRuntime().gc(); 2677 2678 // The initial scanning above does many calls into installd while 2679 // holding the mPackages lock, but we're mostly interested in yelling 2680 // once we have a booted system. 2681 mInstaller.setWarnIfHeld(mPackages); 2682 2683 // Expose private service for system components to use. 2684 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2685 } 2686 2687 @Override 2688 public boolean isFirstBoot() { 2689 return mFirstBoot; 2690 } 2691 2692 @Override 2693 public boolean isOnlyCoreApps() { 2694 return mOnlyCore; 2695 } 2696 2697 @Override 2698 public boolean isUpgrade() { 2699 return mIsUpgrade; 2700 } 2701 2702 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2703 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2704 2705 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2706 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2707 UserHandle.USER_SYSTEM); 2708 if (matches.size() == 1) { 2709 return matches.get(0).getComponentInfo().packageName; 2710 } else { 2711 Log.e(TAG, "There should probably be exactly one verifier; found " + matches); 2712 return null; 2713 } 2714 } 2715 2716 private @NonNull String getRequiredSharedLibraryLPr(String libraryName) { 2717 synchronized (mPackages) { 2718 SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName); 2719 if (libraryEntry == null) { 2720 throw new IllegalStateException("Missing required shared library:" + libraryName); 2721 } 2722 return libraryEntry.apk; 2723 } 2724 } 2725 2726 private @NonNull String getRequiredInstallerLPr() { 2727 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2728 intent.addCategory(Intent.CATEGORY_DEFAULT); 2729 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2730 2731 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2732 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2733 UserHandle.USER_SYSTEM); 2734 if (matches.size() == 1) { 2735 ResolveInfo resolveInfo = matches.get(0); 2736 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 2737 throw new RuntimeException("The installer must be a privileged app"); 2738 } 2739 return matches.get(0).getComponentInfo().packageName; 2740 } else { 2741 throw new RuntimeException("There must be exactly one installer; found " + matches); 2742 } 2743 } 2744 2745 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2746 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2747 2748 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2749 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2750 UserHandle.USER_SYSTEM); 2751 ResolveInfo best = null; 2752 final int N = matches.size(); 2753 for (int i = 0; i < N; i++) { 2754 final ResolveInfo cur = matches.get(i); 2755 final String packageName = cur.getComponentInfo().packageName; 2756 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2757 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2758 continue; 2759 } 2760 2761 if (best == null || cur.priority > best.priority) { 2762 best = cur; 2763 } 2764 } 2765 2766 if (best != null) { 2767 return best.getComponentInfo().getComponentName(); 2768 } else { 2769 throw new RuntimeException("There must be at least one intent filter verifier"); 2770 } 2771 } 2772 2773 private @Nullable ComponentName getEphemeralResolverLPr() { 2774 final String[] packageArray = 2775 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2776 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) { 2777 if (DEBUG_EPHEMERAL) { 2778 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2779 } 2780 return null; 2781 } 2782 2783 final int resolveFlags = 2784 MATCH_DIRECT_BOOT_AWARE 2785 | MATCH_DIRECT_BOOT_UNAWARE 2786 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2787 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2788 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 2789 resolveFlags, UserHandle.USER_SYSTEM); 2790 2791 final int N = resolvers.size(); 2792 if (N == 0) { 2793 if (DEBUG_EPHEMERAL) { 2794 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2795 } 2796 return null; 2797 } 2798 2799 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2800 for (int i = 0; i < N; i++) { 2801 final ResolveInfo info = resolvers.get(i); 2802 2803 if (info.serviceInfo == null) { 2804 continue; 2805 } 2806 2807 final String packageName = info.serviceInfo.packageName; 2808 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) { 2809 if (DEBUG_EPHEMERAL) { 2810 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2811 + " pkg: " + packageName + ", info:" + info); 2812 } 2813 continue; 2814 } 2815 2816 if (DEBUG_EPHEMERAL) { 2817 Slog.v(TAG, "Ephemeral resolver found;" 2818 + " pkg: " + packageName + ", info:" + info); 2819 } 2820 return new ComponentName(packageName, info.serviceInfo.name); 2821 } 2822 if (DEBUG_EPHEMERAL) { 2823 Slog.v(TAG, "Ephemeral resolver NOT found"); 2824 } 2825 return null; 2826 } 2827 2828 private @Nullable ComponentName getEphemeralInstallerLPr() { 2829 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2830 intent.addCategory(Intent.CATEGORY_DEFAULT); 2831 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2832 2833 final int resolveFlags = 2834 MATCH_DIRECT_BOOT_AWARE 2835 | MATCH_DIRECT_BOOT_UNAWARE 2836 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2837 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2838 resolveFlags, UserHandle.USER_SYSTEM); 2839 if (matches.size() == 0) { 2840 return null; 2841 } else if (matches.size() == 1) { 2842 return matches.get(0).getComponentInfo().getComponentName(); 2843 } else { 2844 throw new RuntimeException( 2845 "There must be at most one ephemeral installer; found " + matches); 2846 } 2847 } 2848 2849 private void primeDomainVerificationsLPw(int userId) { 2850 if (DEBUG_DOMAIN_VERIFICATION) { 2851 Slog.d(TAG, "Priming domain verifications in user " + userId); 2852 } 2853 2854 SystemConfig systemConfig = SystemConfig.getInstance(); 2855 ArraySet<String> packages = systemConfig.getLinkedApps(); 2856 ArraySet<String> domains = new ArraySet<String>(); 2857 2858 for (String packageName : packages) { 2859 PackageParser.Package pkg = mPackages.get(packageName); 2860 if (pkg != null) { 2861 if (!pkg.isSystemApp()) { 2862 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2863 continue; 2864 } 2865 2866 domains.clear(); 2867 for (PackageParser.Activity a : pkg.activities) { 2868 for (ActivityIntentInfo filter : a.intents) { 2869 if (hasValidDomains(filter)) { 2870 domains.addAll(filter.getHostsList()); 2871 } 2872 } 2873 } 2874 2875 if (domains.size() > 0) { 2876 if (DEBUG_DOMAIN_VERIFICATION) { 2877 Slog.v(TAG, " + " + packageName); 2878 } 2879 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2880 // state w.r.t. the formal app-linkage "no verification attempted" state; 2881 // and then 'always' in the per-user state actually used for intent resolution. 2882 final IntentFilterVerificationInfo ivi; 2883 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2884 new ArrayList<String>(domains)); 2885 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2886 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2887 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2888 } else { 2889 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2890 + "' does not handle web links"); 2891 } 2892 } else { 2893 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2894 } 2895 } 2896 2897 scheduleWritePackageRestrictionsLocked(userId); 2898 scheduleWriteSettingsLocked(); 2899 } 2900 2901 private void applyFactoryDefaultBrowserLPw(int userId) { 2902 // The default browser app's package name is stored in a string resource, 2903 // with a product-specific overlay used for vendor customization. 2904 String browserPkg = mContext.getResources().getString( 2905 com.android.internal.R.string.default_browser); 2906 if (!TextUtils.isEmpty(browserPkg)) { 2907 // non-empty string => required to be a known package 2908 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2909 if (ps == null) { 2910 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2911 browserPkg = null; 2912 } else { 2913 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2914 } 2915 } 2916 2917 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2918 // default. If there's more than one, just leave everything alone. 2919 if (browserPkg == null) { 2920 calculateDefaultBrowserLPw(userId); 2921 } 2922 } 2923 2924 private void calculateDefaultBrowserLPw(int userId) { 2925 List<String> allBrowsers = resolveAllBrowserApps(userId); 2926 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2927 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2928 } 2929 2930 private List<String> resolveAllBrowserApps(int userId) { 2931 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2932 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2933 PackageManager.MATCH_ALL, userId); 2934 2935 final int count = list.size(); 2936 List<String> result = new ArrayList<String>(count); 2937 for (int i=0; i<count; i++) { 2938 ResolveInfo info = list.get(i); 2939 if (info.activityInfo == null 2940 || !info.handleAllWebDataURI 2941 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2942 || result.contains(info.activityInfo.packageName)) { 2943 continue; 2944 } 2945 result.add(info.activityInfo.packageName); 2946 } 2947 2948 return result; 2949 } 2950 2951 private boolean packageIsBrowser(String packageName, int userId) { 2952 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2953 PackageManager.MATCH_ALL, userId); 2954 final int N = list.size(); 2955 for (int i = 0; i < N; i++) { 2956 ResolveInfo info = list.get(i); 2957 if (packageName.equals(info.activityInfo.packageName)) { 2958 return true; 2959 } 2960 } 2961 return false; 2962 } 2963 2964 private void checkDefaultBrowser() { 2965 final int myUserId = UserHandle.myUserId(); 2966 final String packageName = getDefaultBrowserPackageName(myUserId); 2967 if (packageName != null) { 2968 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2969 if (info == null) { 2970 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2971 synchronized (mPackages) { 2972 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2973 } 2974 } 2975 } 2976 } 2977 2978 @Override 2979 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2980 throws RemoteException { 2981 try { 2982 return super.onTransact(code, data, reply, flags); 2983 } catch (RuntimeException e) { 2984 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2985 Slog.wtf(TAG, "Package Manager Crash", e); 2986 } 2987 throw e; 2988 } 2989 } 2990 2991 static int[] appendInts(int[] cur, int[] add) { 2992 if (add == null) return cur; 2993 if (cur == null) return add; 2994 final int N = add.length; 2995 for (int i=0; i<N; i++) { 2996 cur = appendInt(cur, add[i]); 2997 } 2998 return cur; 2999 } 3000 3001 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 3002 if (!sUserManager.exists(userId)) return null; 3003 if (ps == null) { 3004 return null; 3005 } 3006 final PackageParser.Package p = ps.pkg; 3007 if (p == null) { 3008 return null; 3009 } 3010 3011 final PermissionsState permissionsState = ps.getPermissionsState(); 3012 3013 // Compute GIDs only if requested 3014 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 3015 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); 3016 // Compute granted permissions only if package has requested permissions 3017 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) 3018 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId); 3019 final PackageUserState state = ps.readUserState(userId); 3020 3021 return PackageParser.generatePackageInfo(p, gids, flags, 3022 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 3023 } 3024 3025 @Override 3026 public void checkPackageStartable(String packageName, int userId) { 3027 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); 3028 3029 synchronized (mPackages) { 3030 final PackageSetting ps = mSettings.mPackages.get(packageName); 3031 if (ps == null) { 3032 throw new SecurityException("Package " + packageName + " was not found!"); 3033 } 3034 3035 if (!ps.getInstalled(userId)) { 3036 throw new SecurityException( 3037 "Package " + packageName + " was not installed for user " + userId + "!"); 3038 } 3039 3040 if (mSafeMode && !ps.isSystem()) { 3041 throw new SecurityException("Package " + packageName + " not a system app!"); 3042 } 3043 3044 if (mFrozenPackages.contains(packageName)) { 3045 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3046 } 3047 3048 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3049 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3050 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3051 } 3052 } 3053 } 3054 3055 @Override 3056 public boolean isPackageAvailable(String packageName, int userId) { 3057 if (!sUserManager.exists(userId)) return false; 3058 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3059 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3060 synchronized (mPackages) { 3061 PackageParser.Package p = mPackages.get(packageName); 3062 if (p != null) { 3063 final PackageSetting ps = (PackageSetting) p.mExtras; 3064 if (ps != null) { 3065 final PackageUserState state = ps.readUserState(userId); 3066 if (state != null) { 3067 return PackageParser.isAvailable(state); 3068 } 3069 } 3070 } 3071 } 3072 return false; 3073 } 3074 3075 @Override 3076 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3077 if (!sUserManager.exists(userId)) return null; 3078 flags = updateFlagsForPackage(flags, userId, packageName); 3079 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3080 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3081 // reader 3082 synchronized (mPackages) { 3083 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3084 PackageParser.Package p = null; 3085 if (matchFactoryOnly) { 3086 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3087 if (ps != null) { 3088 return generatePackageInfo(ps, flags, userId); 3089 } 3090 } 3091 if (p == null) { 3092 p = mPackages.get(packageName); 3093 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3094 return null; 3095 } 3096 } 3097 if (DEBUG_PACKAGE_INFO) 3098 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3099 if (p != null) { 3100 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3101 } 3102 if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3103 final PackageSetting ps = mSettings.mPackages.get(packageName); 3104 return generatePackageInfo(ps, flags, userId); 3105 } 3106 } 3107 return null; 3108 } 3109 3110 @Override 3111 public String[] currentToCanonicalPackageNames(String[] names) { 3112 String[] out = new String[names.length]; 3113 // reader 3114 synchronized (mPackages) { 3115 for (int i=names.length-1; i>=0; i--) { 3116 PackageSetting ps = mSettings.mPackages.get(names[i]); 3117 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3118 } 3119 } 3120 return out; 3121 } 3122 3123 @Override 3124 public String[] canonicalToCurrentPackageNames(String[] names) { 3125 String[] out = new String[names.length]; 3126 // reader 3127 synchronized (mPackages) { 3128 for (int i=names.length-1; i>=0; i--) { 3129 String cur = mSettings.mRenamedPackages.get(names[i]); 3130 out[i] = cur != null ? cur : names[i]; 3131 } 3132 } 3133 return out; 3134 } 3135 3136 @Override 3137 public int getPackageUid(String packageName, int flags, int userId) { 3138 if (!sUserManager.exists(userId)) return -1; 3139 flags = updateFlagsForPackage(flags, userId, packageName); 3140 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3141 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3142 3143 // reader 3144 synchronized (mPackages) { 3145 final PackageParser.Package p = mPackages.get(packageName); 3146 if (p != null && p.isMatch(flags)) { 3147 return UserHandle.getUid(userId, p.applicationInfo.uid); 3148 } 3149 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3150 final PackageSetting ps = mSettings.mPackages.get(packageName); 3151 if (ps != null && ps.isMatch(flags)) { 3152 return UserHandle.getUid(userId, ps.appId); 3153 } 3154 } 3155 } 3156 3157 return -1; 3158 } 3159 3160 @Override 3161 public int[] getPackageGids(String packageName, int flags, int userId) { 3162 if (!sUserManager.exists(userId)) return null; 3163 flags = updateFlagsForPackage(flags, userId, packageName); 3164 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3165 false /* requireFullPermission */, false /* checkShell */, 3166 "getPackageGids"); 3167 3168 // reader 3169 synchronized (mPackages) { 3170 final PackageParser.Package p = mPackages.get(packageName); 3171 if (p != null && p.isMatch(flags)) { 3172 PackageSetting ps = (PackageSetting) p.mExtras; 3173 return ps.getPermissionsState().computeGids(userId); 3174 } 3175 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3176 final PackageSetting ps = mSettings.mPackages.get(packageName); 3177 if (ps != null && ps.isMatch(flags)) { 3178 return ps.getPermissionsState().computeGids(userId); 3179 } 3180 } 3181 } 3182 3183 return null; 3184 } 3185 3186 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3187 if (bp.perm != null) { 3188 return PackageParser.generatePermissionInfo(bp.perm, flags); 3189 } 3190 PermissionInfo pi = new PermissionInfo(); 3191 pi.name = bp.name; 3192 pi.packageName = bp.sourcePackage; 3193 pi.nonLocalizedLabel = bp.name; 3194 pi.protectionLevel = bp.protectionLevel; 3195 return pi; 3196 } 3197 3198 @Override 3199 public PermissionInfo getPermissionInfo(String name, int flags) { 3200 // reader 3201 synchronized (mPackages) { 3202 final BasePermission p = mSettings.mPermissions.get(name); 3203 if (p != null) { 3204 return generatePermissionInfo(p, flags); 3205 } 3206 return null; 3207 } 3208 } 3209 3210 @Override 3211 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3212 int flags) { 3213 // reader 3214 synchronized (mPackages) { 3215 if (group != null && !mPermissionGroups.containsKey(group)) { 3216 // This is thrown as NameNotFoundException 3217 return null; 3218 } 3219 3220 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3221 for (BasePermission p : mSettings.mPermissions.values()) { 3222 if (group == null) { 3223 if (p.perm == null || p.perm.info.group == null) { 3224 out.add(generatePermissionInfo(p, flags)); 3225 } 3226 } else { 3227 if (p.perm != null && group.equals(p.perm.info.group)) { 3228 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3229 } 3230 } 3231 } 3232 return new ParceledListSlice<>(out); 3233 } 3234 } 3235 3236 @Override 3237 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3238 // reader 3239 synchronized (mPackages) { 3240 return PackageParser.generatePermissionGroupInfo( 3241 mPermissionGroups.get(name), flags); 3242 } 3243 } 3244 3245 @Override 3246 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3247 // reader 3248 synchronized (mPackages) { 3249 final int N = mPermissionGroups.size(); 3250 ArrayList<PermissionGroupInfo> out 3251 = new ArrayList<PermissionGroupInfo>(N); 3252 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3253 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3254 } 3255 return new ParceledListSlice<>(out); 3256 } 3257 } 3258 3259 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3260 int userId) { 3261 if (!sUserManager.exists(userId)) return null; 3262 PackageSetting ps = mSettings.mPackages.get(packageName); 3263 if (ps != null) { 3264 if (ps.pkg == null) { 3265 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3266 if (pInfo != null) { 3267 return pInfo.applicationInfo; 3268 } 3269 return null; 3270 } 3271 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3272 ps.readUserState(userId), userId); 3273 } 3274 return null; 3275 } 3276 3277 @Override 3278 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3279 if (!sUserManager.exists(userId)) return null; 3280 flags = updateFlagsForApplication(flags, userId, packageName); 3281 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3282 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3283 // writer 3284 synchronized (mPackages) { 3285 PackageParser.Package p = mPackages.get(packageName); 3286 if (DEBUG_PACKAGE_INFO) Log.v( 3287 TAG, "getApplicationInfo " + packageName 3288 + ": " + p); 3289 if (p != null) { 3290 PackageSetting ps = mSettings.mPackages.get(packageName); 3291 if (ps == null) return null; 3292 // Note: isEnabledLP() does not apply here - always return info 3293 return PackageParser.generateApplicationInfo( 3294 p, flags, ps.readUserState(userId), userId); 3295 } 3296 if ("android".equals(packageName)||"system".equals(packageName)) { 3297 return mAndroidApplication; 3298 } 3299 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3300 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3301 } 3302 } 3303 return null; 3304 } 3305 3306 @Override 3307 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3308 final IPackageDataObserver observer) { 3309 mContext.enforceCallingOrSelfPermission( 3310 android.Manifest.permission.CLEAR_APP_CACHE, null); 3311 // Queue up an async operation since clearing cache may take a little while. 3312 mHandler.post(new Runnable() { 3313 public void run() { 3314 mHandler.removeCallbacks(this); 3315 boolean success = true; 3316 synchronized (mInstallLock) { 3317 try { 3318 mInstaller.freeCache(volumeUuid, freeStorageSize); 3319 } catch (InstallerException e) { 3320 Slog.w(TAG, "Couldn't clear application caches: " + e); 3321 success = false; 3322 } 3323 } 3324 if (observer != null) { 3325 try { 3326 observer.onRemoveCompleted(null, success); 3327 } catch (RemoteException e) { 3328 Slog.w(TAG, "RemoveException when invoking call back"); 3329 } 3330 } 3331 } 3332 }); 3333 } 3334 3335 @Override 3336 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3337 final IntentSender pi) { 3338 mContext.enforceCallingOrSelfPermission( 3339 android.Manifest.permission.CLEAR_APP_CACHE, null); 3340 // Queue up an async operation since clearing cache may take a little while. 3341 mHandler.post(new Runnable() { 3342 public void run() { 3343 mHandler.removeCallbacks(this); 3344 boolean success = true; 3345 synchronized (mInstallLock) { 3346 try { 3347 mInstaller.freeCache(volumeUuid, freeStorageSize); 3348 } catch (InstallerException e) { 3349 Slog.w(TAG, "Couldn't clear application caches: " + e); 3350 success = false; 3351 } 3352 } 3353 if(pi != null) { 3354 try { 3355 // Callback via pending intent 3356 int code = success ? 1 : 0; 3357 pi.sendIntent(null, code, null, 3358 null, null); 3359 } catch (SendIntentException e1) { 3360 Slog.i(TAG, "Failed to send pending intent"); 3361 } 3362 } 3363 } 3364 }); 3365 } 3366 3367 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3368 synchronized (mInstallLock) { 3369 try { 3370 mInstaller.freeCache(volumeUuid, freeStorageSize); 3371 } catch (InstallerException e) { 3372 throw new IOException("Failed to free enough space", e); 3373 } 3374 } 3375 } 3376 3377 /** 3378 * Update given flags based on encryption status of current user. 3379 */ 3380 private int updateFlags(int flags, int userId) { 3381 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3382 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3383 // Caller expressed an explicit opinion about what encryption 3384 // aware/unaware components they want to see, so fall through and 3385 // give them what they want 3386 } else { 3387 // Caller expressed no opinion, so match based on user state 3388 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) { 3389 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3390 } else { 3391 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3392 } 3393 } 3394 return flags; 3395 } 3396 3397 private UserManagerInternal getUserManagerInternal() { 3398 if (mUserManagerInternal == null) { 3399 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 3400 } 3401 return mUserManagerInternal; 3402 } 3403 3404 /** 3405 * Update given flags when being used to request {@link PackageInfo}. 3406 */ 3407 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3408 boolean triaged = true; 3409 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3410 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3411 // Caller is asking for component details, so they'd better be 3412 // asking for specific encryption matching behavior, or be triaged 3413 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3414 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3415 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3416 triaged = false; 3417 } 3418 } 3419 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3420 | PackageManager.MATCH_SYSTEM_ONLY 3421 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3422 triaged = false; 3423 } 3424 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3425 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3426 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3427 } 3428 return updateFlags(flags, userId); 3429 } 3430 3431 /** 3432 * Update given flags when being used to request {@link ApplicationInfo}. 3433 */ 3434 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3435 return updateFlagsForPackage(flags, userId, cookie); 3436 } 3437 3438 /** 3439 * Update given flags when being used to request {@link ComponentInfo}. 3440 */ 3441 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3442 if (cookie instanceof Intent) { 3443 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3444 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3445 } 3446 } 3447 3448 boolean triaged = true; 3449 // Caller is asking for component details, so they'd better be 3450 // asking for specific encryption matching behavior, or be triaged 3451 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3452 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3453 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3454 triaged = false; 3455 } 3456 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3457 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3458 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3459 } 3460 3461 return updateFlags(flags, userId); 3462 } 3463 3464 /** 3465 * Update given flags when being used to request {@link ResolveInfo}. 3466 */ 3467 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3468 // Safe mode means we shouldn't match any third-party components 3469 if (mSafeMode) { 3470 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3471 } 3472 3473 return updateFlagsForComponent(flags, userId, cookie); 3474 } 3475 3476 @Override 3477 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3478 if (!sUserManager.exists(userId)) return null; 3479 flags = updateFlagsForComponent(flags, userId, component); 3480 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3481 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3482 synchronized (mPackages) { 3483 PackageParser.Activity a = mActivities.mActivities.get(component); 3484 3485 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3486 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3487 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3488 if (ps == null) return null; 3489 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3490 userId); 3491 } 3492 if (mResolveComponentName.equals(component)) { 3493 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3494 new PackageUserState(), userId); 3495 } 3496 } 3497 return null; 3498 } 3499 3500 @Override 3501 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3502 String resolvedType) { 3503 synchronized (mPackages) { 3504 if (component.equals(mResolveComponentName)) { 3505 // The resolver supports EVERYTHING! 3506 return true; 3507 } 3508 PackageParser.Activity a = mActivities.mActivities.get(component); 3509 if (a == null) { 3510 return false; 3511 } 3512 for (int i=0; i<a.intents.size(); i++) { 3513 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3514 intent.getData(), intent.getCategories(), TAG) >= 0) { 3515 return true; 3516 } 3517 } 3518 return false; 3519 } 3520 } 3521 3522 @Override 3523 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3524 if (!sUserManager.exists(userId)) return null; 3525 flags = updateFlagsForComponent(flags, userId, component); 3526 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3527 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3528 synchronized (mPackages) { 3529 PackageParser.Activity a = mReceivers.mActivities.get(component); 3530 if (DEBUG_PACKAGE_INFO) Log.v( 3531 TAG, "getReceiverInfo " + component + ": " + a); 3532 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3533 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3534 if (ps == null) return null; 3535 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3536 userId); 3537 } 3538 } 3539 return null; 3540 } 3541 3542 @Override 3543 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3544 if (!sUserManager.exists(userId)) return null; 3545 flags = updateFlagsForComponent(flags, userId, component); 3546 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3547 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3548 synchronized (mPackages) { 3549 PackageParser.Service s = mServices.mServices.get(component); 3550 if (DEBUG_PACKAGE_INFO) Log.v( 3551 TAG, "getServiceInfo " + component + ": " + s); 3552 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3553 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3554 if (ps == null) return null; 3555 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3556 userId); 3557 } 3558 } 3559 return null; 3560 } 3561 3562 @Override 3563 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3564 if (!sUserManager.exists(userId)) return null; 3565 flags = updateFlagsForComponent(flags, userId, component); 3566 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3567 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3568 synchronized (mPackages) { 3569 PackageParser.Provider p = mProviders.mProviders.get(component); 3570 if (DEBUG_PACKAGE_INFO) Log.v( 3571 TAG, "getProviderInfo " + component + ": " + p); 3572 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3573 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3574 if (ps == null) return null; 3575 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3576 userId); 3577 } 3578 } 3579 return null; 3580 } 3581 3582 @Override 3583 public String[] getSystemSharedLibraryNames() { 3584 Set<String> libSet; 3585 synchronized (mPackages) { 3586 libSet = mSharedLibraries.keySet(); 3587 int size = libSet.size(); 3588 if (size > 0) { 3589 String[] libs = new String[size]; 3590 libSet.toArray(libs); 3591 return libs; 3592 } 3593 } 3594 return null; 3595 } 3596 3597 @Override 3598 public @NonNull String getServicesSystemSharedLibraryPackageName() { 3599 synchronized (mPackages) { 3600 return mServicesSystemSharedLibraryPackageName; 3601 } 3602 } 3603 3604 @Override 3605 public @NonNull String getSharedSystemSharedLibraryPackageName() { 3606 synchronized (mPackages) { 3607 return mSharedSystemSharedLibraryPackageName; 3608 } 3609 } 3610 3611 @Override 3612 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3613 synchronized (mPackages) { 3614 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3615 3616 final FeatureInfo fi = new FeatureInfo(); 3617 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3618 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3619 res.add(fi); 3620 3621 return new ParceledListSlice<>(res); 3622 } 3623 } 3624 3625 @Override 3626 public boolean hasSystemFeature(String name, int version) { 3627 synchronized (mPackages) { 3628 final FeatureInfo feat = mAvailableFeatures.get(name); 3629 if (feat == null) { 3630 return false; 3631 } else { 3632 return feat.version >= version; 3633 } 3634 } 3635 } 3636 3637 @Override 3638 public int checkPermission(String permName, String pkgName, int userId) { 3639 if (!sUserManager.exists(userId)) { 3640 return PackageManager.PERMISSION_DENIED; 3641 } 3642 3643 synchronized (mPackages) { 3644 final PackageParser.Package p = mPackages.get(pkgName); 3645 if (p != null && p.mExtras != null) { 3646 final PackageSetting ps = (PackageSetting) p.mExtras; 3647 final PermissionsState permissionsState = ps.getPermissionsState(); 3648 if (permissionsState.hasPermission(permName, userId)) { 3649 return PackageManager.PERMISSION_GRANTED; 3650 } 3651 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3652 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3653 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3654 return PackageManager.PERMISSION_GRANTED; 3655 } 3656 } 3657 } 3658 3659 return PackageManager.PERMISSION_DENIED; 3660 } 3661 3662 @Override 3663 public int checkUidPermission(String permName, int uid) { 3664 final int userId = UserHandle.getUserId(uid); 3665 3666 if (!sUserManager.exists(userId)) { 3667 return PackageManager.PERMISSION_DENIED; 3668 } 3669 3670 synchronized (mPackages) { 3671 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3672 if (obj != null) { 3673 final SettingBase ps = (SettingBase) obj; 3674 final PermissionsState permissionsState = ps.getPermissionsState(); 3675 if (permissionsState.hasPermission(permName, userId)) { 3676 return PackageManager.PERMISSION_GRANTED; 3677 } 3678 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3679 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3680 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3681 return PackageManager.PERMISSION_GRANTED; 3682 } 3683 } else { 3684 ArraySet<String> perms = mSystemPermissions.get(uid); 3685 if (perms != null) { 3686 if (perms.contains(permName)) { 3687 return PackageManager.PERMISSION_GRANTED; 3688 } 3689 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3690 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3691 return PackageManager.PERMISSION_GRANTED; 3692 } 3693 } 3694 } 3695 } 3696 3697 return PackageManager.PERMISSION_DENIED; 3698 } 3699 3700 @Override 3701 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3702 if (UserHandle.getCallingUserId() != userId) { 3703 mContext.enforceCallingPermission( 3704 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3705 "isPermissionRevokedByPolicy for user " + userId); 3706 } 3707 3708 if (checkPermission(permission, packageName, userId) 3709 == PackageManager.PERMISSION_GRANTED) { 3710 return false; 3711 } 3712 3713 final long identity = Binder.clearCallingIdentity(); 3714 try { 3715 final int flags = getPermissionFlags(permission, packageName, userId); 3716 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3717 } finally { 3718 Binder.restoreCallingIdentity(identity); 3719 } 3720 } 3721 3722 @Override 3723 public String getPermissionControllerPackageName() { 3724 synchronized (mPackages) { 3725 return mRequiredInstallerPackage; 3726 } 3727 } 3728 3729 /** 3730 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3731 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3732 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3733 * @param message the message to log on security exception 3734 */ 3735 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3736 boolean checkShell, String message) { 3737 if (userId < 0) { 3738 throw new IllegalArgumentException("Invalid userId " + userId); 3739 } 3740 if (checkShell) { 3741 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3742 } 3743 if (userId == UserHandle.getUserId(callingUid)) return; 3744 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3745 if (requireFullPermission) { 3746 mContext.enforceCallingOrSelfPermission( 3747 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3748 } else { 3749 try { 3750 mContext.enforceCallingOrSelfPermission( 3751 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3752 } catch (SecurityException se) { 3753 mContext.enforceCallingOrSelfPermission( 3754 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3755 } 3756 } 3757 } 3758 } 3759 3760 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3761 if (callingUid == Process.SHELL_UID) { 3762 if (userHandle >= 0 3763 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3764 throw new SecurityException("Shell does not have permission to access user " 3765 + userHandle); 3766 } else if (userHandle < 0) { 3767 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3768 + Debug.getCallers(3)); 3769 } 3770 } 3771 } 3772 3773 private BasePermission findPermissionTreeLP(String permName) { 3774 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3775 if (permName.startsWith(bp.name) && 3776 permName.length() > bp.name.length() && 3777 permName.charAt(bp.name.length()) == '.') { 3778 return bp; 3779 } 3780 } 3781 return null; 3782 } 3783 3784 private BasePermission checkPermissionTreeLP(String permName) { 3785 if (permName != null) { 3786 BasePermission bp = findPermissionTreeLP(permName); 3787 if (bp != null) { 3788 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3789 return bp; 3790 } 3791 throw new SecurityException("Calling uid " 3792 + Binder.getCallingUid() 3793 + " is not allowed to add to permission tree " 3794 + bp.name + " owned by uid " + bp.uid); 3795 } 3796 } 3797 throw new SecurityException("No permission tree found for " + permName); 3798 } 3799 3800 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3801 if (s1 == null) { 3802 return s2 == null; 3803 } 3804 if (s2 == null) { 3805 return false; 3806 } 3807 if (s1.getClass() != s2.getClass()) { 3808 return false; 3809 } 3810 return s1.equals(s2); 3811 } 3812 3813 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3814 if (pi1.icon != pi2.icon) return false; 3815 if (pi1.logo != pi2.logo) return false; 3816 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3817 if (!compareStrings(pi1.name, pi2.name)) return false; 3818 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3819 // We'll take care of setting this one. 3820 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3821 // These are not currently stored in settings. 3822 //if (!compareStrings(pi1.group, pi2.group)) return false; 3823 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3824 //if (pi1.labelRes != pi2.labelRes) return false; 3825 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3826 return true; 3827 } 3828 3829 int permissionInfoFootprint(PermissionInfo info) { 3830 int size = info.name.length(); 3831 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3832 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3833 return size; 3834 } 3835 3836 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3837 int size = 0; 3838 for (BasePermission perm : mSettings.mPermissions.values()) { 3839 if (perm.uid == tree.uid) { 3840 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3841 } 3842 } 3843 return size; 3844 } 3845 3846 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3847 // We calculate the max size of permissions defined by this uid and throw 3848 // if that plus the size of 'info' would exceed our stated maximum. 3849 if (tree.uid != Process.SYSTEM_UID) { 3850 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3851 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3852 throw new SecurityException("Permission tree size cap exceeded"); 3853 } 3854 } 3855 } 3856 3857 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3858 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3859 throw new SecurityException("Label must be specified in permission"); 3860 } 3861 BasePermission tree = checkPermissionTreeLP(info.name); 3862 BasePermission bp = mSettings.mPermissions.get(info.name); 3863 boolean added = bp == null; 3864 boolean changed = true; 3865 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3866 if (added) { 3867 enforcePermissionCapLocked(info, tree); 3868 bp = new BasePermission(info.name, tree.sourcePackage, 3869 BasePermission.TYPE_DYNAMIC); 3870 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3871 throw new SecurityException( 3872 "Not allowed to modify non-dynamic permission " 3873 + info.name); 3874 } else { 3875 if (bp.protectionLevel == fixedLevel 3876 && bp.perm.owner.equals(tree.perm.owner) 3877 && bp.uid == tree.uid 3878 && comparePermissionInfos(bp.perm.info, info)) { 3879 changed = false; 3880 } 3881 } 3882 bp.protectionLevel = fixedLevel; 3883 info = new PermissionInfo(info); 3884 info.protectionLevel = fixedLevel; 3885 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3886 bp.perm.info.packageName = tree.perm.info.packageName; 3887 bp.uid = tree.uid; 3888 if (added) { 3889 mSettings.mPermissions.put(info.name, bp); 3890 } 3891 if (changed) { 3892 if (!async) { 3893 mSettings.writeLPr(); 3894 } else { 3895 scheduleWriteSettingsLocked(); 3896 } 3897 } 3898 return added; 3899 } 3900 3901 @Override 3902 public boolean addPermission(PermissionInfo info) { 3903 synchronized (mPackages) { 3904 return addPermissionLocked(info, false); 3905 } 3906 } 3907 3908 @Override 3909 public boolean addPermissionAsync(PermissionInfo info) { 3910 synchronized (mPackages) { 3911 return addPermissionLocked(info, true); 3912 } 3913 } 3914 3915 @Override 3916 public void removePermission(String name) { 3917 synchronized (mPackages) { 3918 checkPermissionTreeLP(name); 3919 BasePermission bp = mSettings.mPermissions.get(name); 3920 if (bp != null) { 3921 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3922 throw new SecurityException( 3923 "Not allowed to modify non-dynamic permission " 3924 + name); 3925 } 3926 mSettings.mPermissions.remove(name); 3927 mSettings.writeLPr(); 3928 } 3929 } 3930 } 3931 3932 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3933 BasePermission bp) { 3934 int index = pkg.requestedPermissions.indexOf(bp.name); 3935 if (index == -1) { 3936 throw new SecurityException("Package " + pkg.packageName 3937 + " has not requested permission " + bp.name); 3938 } 3939 if (!bp.isRuntime() && !bp.isDevelopment()) { 3940 throw new SecurityException("Permission " + bp.name 3941 + " is not a changeable permission type"); 3942 } 3943 } 3944 3945 @Override 3946 public void grantRuntimePermission(String packageName, String name, final int userId) { 3947 if (!sUserManager.exists(userId)) { 3948 Log.e(TAG, "No such user:" + userId); 3949 return; 3950 } 3951 3952 mContext.enforceCallingOrSelfPermission( 3953 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3954 "grantRuntimePermission"); 3955 3956 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3957 true /* requireFullPermission */, true /* checkShell */, 3958 "grantRuntimePermission"); 3959 3960 final int uid; 3961 final SettingBase sb; 3962 3963 synchronized (mPackages) { 3964 final PackageParser.Package pkg = mPackages.get(packageName); 3965 if (pkg == null) { 3966 throw new IllegalArgumentException("Unknown package: " + packageName); 3967 } 3968 3969 final BasePermission bp = mSettings.mPermissions.get(name); 3970 if (bp == null) { 3971 throw new IllegalArgumentException("Unknown permission: " + name); 3972 } 3973 3974 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3975 3976 // If a permission review is required for legacy apps we represent 3977 // their permissions as always granted runtime ones since we need 3978 // to keep the review required permission flag per user while an 3979 // install permission's state is shared across all users. 3980 if (Build.PERMISSIONS_REVIEW_REQUIRED 3981 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3982 && bp.isRuntime()) { 3983 return; 3984 } 3985 3986 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3987 sb = (SettingBase) pkg.mExtras; 3988 if (sb == null) { 3989 throw new IllegalArgumentException("Unknown package: " + packageName); 3990 } 3991 3992 final PermissionsState permissionsState = sb.getPermissionsState(); 3993 3994 final int flags = permissionsState.getPermissionFlags(name, userId); 3995 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3996 throw new SecurityException("Cannot grant system fixed permission " 3997 + name + " for package " + packageName); 3998 } 3999 4000 if (bp.isDevelopment()) { 4001 // Development permissions must be handled specially, since they are not 4002 // normal runtime permissions. For now they apply to all users. 4003 if (permissionsState.grantInstallPermission(bp) != 4004 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4005 scheduleWriteSettingsLocked(); 4006 } 4007 return; 4008 } 4009 4010 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4011 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 4012 return; 4013 } 4014 4015 final int result = permissionsState.grantRuntimePermission(bp, userId); 4016 switch (result) { 4017 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 4018 return; 4019 } 4020 4021 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 4022 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4023 mHandler.post(new Runnable() { 4024 @Override 4025 public void run() { 4026 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4027 } 4028 }); 4029 } 4030 break; 4031 } 4032 4033 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4034 4035 // Not critical if that is lost - app has to request again. 4036 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4037 } 4038 4039 // Only need to do this if user is initialized. Otherwise it's a new user 4040 // and there are no processes running as the user yet and there's no need 4041 // to make an expensive call to remount processes for the changed permissions. 4042 if (READ_EXTERNAL_STORAGE.equals(name) 4043 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4044 final long token = Binder.clearCallingIdentity(); 4045 try { 4046 if (sUserManager.isInitialized(userId)) { 4047 MountServiceInternal mountServiceInternal = LocalServices.getService( 4048 MountServiceInternal.class); 4049 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 4050 } 4051 } finally { 4052 Binder.restoreCallingIdentity(token); 4053 } 4054 } 4055 } 4056 4057 @Override 4058 public void revokeRuntimePermission(String packageName, String name, int userId) { 4059 if (!sUserManager.exists(userId)) { 4060 Log.e(TAG, "No such user:" + userId); 4061 return; 4062 } 4063 4064 mContext.enforceCallingOrSelfPermission( 4065 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4066 "revokeRuntimePermission"); 4067 4068 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4069 true /* requireFullPermission */, true /* checkShell */, 4070 "revokeRuntimePermission"); 4071 4072 final int appId; 4073 4074 synchronized (mPackages) { 4075 final PackageParser.Package pkg = mPackages.get(packageName); 4076 if (pkg == null) { 4077 throw new IllegalArgumentException("Unknown package: " + packageName); 4078 } 4079 4080 final BasePermission bp = mSettings.mPermissions.get(name); 4081 if (bp == null) { 4082 throw new IllegalArgumentException("Unknown permission: " + name); 4083 } 4084 4085 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4086 4087 // If a permission review is required for legacy apps we represent 4088 // their permissions as always granted runtime ones since we need 4089 // to keep the review required permission flag per user while an 4090 // install permission's state is shared across all users. 4091 if (Build.PERMISSIONS_REVIEW_REQUIRED 4092 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4093 && bp.isRuntime()) { 4094 return; 4095 } 4096 4097 SettingBase sb = (SettingBase) pkg.mExtras; 4098 if (sb == null) { 4099 throw new IllegalArgumentException("Unknown package: " + packageName); 4100 } 4101 4102 final PermissionsState permissionsState = sb.getPermissionsState(); 4103 4104 final int flags = permissionsState.getPermissionFlags(name, userId); 4105 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4106 throw new SecurityException("Cannot revoke system fixed permission " 4107 + name + " for package " + packageName); 4108 } 4109 4110 if (bp.isDevelopment()) { 4111 // Development permissions must be handled specially, since they are not 4112 // normal runtime permissions. For now they apply to all users. 4113 if (permissionsState.revokeInstallPermission(bp) != 4114 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4115 scheduleWriteSettingsLocked(); 4116 } 4117 return; 4118 } 4119 4120 if (permissionsState.revokeRuntimePermission(bp, userId) == 4121 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4122 return; 4123 } 4124 4125 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4126 4127 // Critical, after this call app should never have the permission. 4128 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4129 4130 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4131 } 4132 4133 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4134 } 4135 4136 @Override 4137 public void resetRuntimePermissions() { 4138 mContext.enforceCallingOrSelfPermission( 4139 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4140 "revokeRuntimePermission"); 4141 4142 int callingUid = Binder.getCallingUid(); 4143 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4144 mContext.enforceCallingOrSelfPermission( 4145 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4146 "resetRuntimePermissions"); 4147 } 4148 4149 synchronized (mPackages) { 4150 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4151 for (int userId : UserManagerService.getInstance().getUserIds()) { 4152 final int packageCount = mPackages.size(); 4153 for (int i = 0; i < packageCount; i++) { 4154 PackageParser.Package pkg = mPackages.valueAt(i); 4155 if (!(pkg.mExtras instanceof PackageSetting)) { 4156 continue; 4157 } 4158 PackageSetting ps = (PackageSetting) pkg.mExtras; 4159 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4160 } 4161 } 4162 } 4163 } 4164 4165 @Override 4166 public int getPermissionFlags(String name, String packageName, int userId) { 4167 if (!sUserManager.exists(userId)) { 4168 return 0; 4169 } 4170 4171 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4172 4173 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4174 true /* requireFullPermission */, false /* checkShell */, 4175 "getPermissionFlags"); 4176 4177 synchronized (mPackages) { 4178 final PackageParser.Package pkg = mPackages.get(packageName); 4179 if (pkg == null) { 4180 return 0; 4181 } 4182 4183 final BasePermission bp = mSettings.mPermissions.get(name); 4184 if (bp == null) { 4185 return 0; 4186 } 4187 4188 SettingBase sb = (SettingBase) pkg.mExtras; 4189 if (sb == null) { 4190 return 0; 4191 } 4192 4193 PermissionsState permissionsState = sb.getPermissionsState(); 4194 return permissionsState.getPermissionFlags(name, userId); 4195 } 4196 } 4197 4198 @Override 4199 public void updatePermissionFlags(String name, String packageName, int flagMask, 4200 int flagValues, int userId) { 4201 if (!sUserManager.exists(userId)) { 4202 return; 4203 } 4204 4205 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4206 4207 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4208 true /* requireFullPermission */, true /* checkShell */, 4209 "updatePermissionFlags"); 4210 4211 // Only the system can change these flags and nothing else. 4212 if (getCallingUid() != Process.SYSTEM_UID) { 4213 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4214 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4215 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4216 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4217 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4218 } 4219 4220 synchronized (mPackages) { 4221 final PackageParser.Package pkg = mPackages.get(packageName); 4222 if (pkg == null) { 4223 throw new IllegalArgumentException("Unknown package: " + packageName); 4224 } 4225 4226 final BasePermission bp = mSettings.mPermissions.get(name); 4227 if (bp == null) { 4228 throw new IllegalArgumentException("Unknown permission: " + name); 4229 } 4230 4231 SettingBase sb = (SettingBase) pkg.mExtras; 4232 if (sb == null) { 4233 throw new IllegalArgumentException("Unknown package: " + packageName); 4234 } 4235 4236 PermissionsState permissionsState = sb.getPermissionsState(); 4237 4238 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4239 4240 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4241 // Install and runtime permissions are stored in different places, 4242 // so figure out what permission changed and persist the change. 4243 if (permissionsState.getInstallPermissionState(name) != null) { 4244 scheduleWriteSettingsLocked(); 4245 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4246 || hadState) { 4247 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4248 } 4249 } 4250 } 4251 } 4252 4253 /** 4254 * Update the permission flags for all packages and runtime permissions of a user in order 4255 * to allow device or profile owner to remove POLICY_FIXED. 4256 */ 4257 @Override 4258 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4259 if (!sUserManager.exists(userId)) { 4260 return; 4261 } 4262 4263 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4264 4265 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4266 true /* requireFullPermission */, true /* checkShell */, 4267 "updatePermissionFlagsForAllApps"); 4268 4269 // Only the system can change system fixed flags. 4270 if (getCallingUid() != Process.SYSTEM_UID) { 4271 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4272 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4273 } 4274 4275 synchronized (mPackages) { 4276 boolean changed = false; 4277 final int packageCount = mPackages.size(); 4278 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4279 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4280 SettingBase sb = (SettingBase) pkg.mExtras; 4281 if (sb == null) { 4282 continue; 4283 } 4284 PermissionsState permissionsState = sb.getPermissionsState(); 4285 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4286 userId, flagMask, flagValues); 4287 } 4288 if (changed) { 4289 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4290 } 4291 } 4292 } 4293 4294 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4295 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4296 != PackageManager.PERMISSION_GRANTED 4297 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4298 != PackageManager.PERMISSION_GRANTED) { 4299 throw new SecurityException(message + " requires " 4300 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4301 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4302 } 4303 } 4304 4305 @Override 4306 public boolean shouldShowRequestPermissionRationale(String permissionName, 4307 String packageName, int userId) { 4308 if (UserHandle.getCallingUserId() != userId) { 4309 mContext.enforceCallingPermission( 4310 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4311 "canShowRequestPermissionRationale for user " + userId); 4312 } 4313 4314 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4315 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4316 return false; 4317 } 4318 4319 if (checkPermission(permissionName, packageName, userId) 4320 == PackageManager.PERMISSION_GRANTED) { 4321 return false; 4322 } 4323 4324 final int flags; 4325 4326 final long identity = Binder.clearCallingIdentity(); 4327 try { 4328 flags = getPermissionFlags(permissionName, 4329 packageName, userId); 4330 } finally { 4331 Binder.restoreCallingIdentity(identity); 4332 } 4333 4334 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4335 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4336 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4337 4338 if ((flags & fixedFlags) != 0) { 4339 return false; 4340 } 4341 4342 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4343 } 4344 4345 @Override 4346 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4347 mContext.enforceCallingOrSelfPermission( 4348 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4349 "addOnPermissionsChangeListener"); 4350 4351 synchronized (mPackages) { 4352 mOnPermissionChangeListeners.addListenerLocked(listener); 4353 } 4354 } 4355 4356 @Override 4357 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4358 synchronized (mPackages) { 4359 mOnPermissionChangeListeners.removeListenerLocked(listener); 4360 } 4361 } 4362 4363 @Override 4364 public boolean isProtectedBroadcast(String actionName) { 4365 synchronized (mPackages) { 4366 if (mProtectedBroadcasts.contains(actionName)) { 4367 return true; 4368 } else if (actionName != null) { 4369 // TODO: remove these terrible hacks 4370 if (actionName.startsWith("android.net.netmon.lingerExpired") 4371 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4372 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4373 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4374 return true; 4375 } 4376 } 4377 } 4378 return false; 4379 } 4380 4381 @Override 4382 public int checkSignatures(String pkg1, String pkg2) { 4383 synchronized (mPackages) { 4384 final PackageParser.Package p1 = mPackages.get(pkg1); 4385 final PackageParser.Package p2 = mPackages.get(pkg2); 4386 if (p1 == null || p1.mExtras == null 4387 || p2 == null || p2.mExtras == null) { 4388 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4389 } 4390 return compareSignatures(p1.mSignatures, p2.mSignatures); 4391 } 4392 } 4393 4394 @Override 4395 public int checkUidSignatures(int uid1, int uid2) { 4396 // Map to base uids. 4397 uid1 = UserHandle.getAppId(uid1); 4398 uid2 = UserHandle.getAppId(uid2); 4399 // reader 4400 synchronized (mPackages) { 4401 Signature[] s1; 4402 Signature[] s2; 4403 Object obj = mSettings.getUserIdLPr(uid1); 4404 if (obj != null) { 4405 if (obj instanceof SharedUserSetting) { 4406 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4407 } else if (obj instanceof PackageSetting) { 4408 s1 = ((PackageSetting)obj).signatures.mSignatures; 4409 } else { 4410 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4411 } 4412 } else { 4413 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4414 } 4415 obj = mSettings.getUserIdLPr(uid2); 4416 if (obj != null) { 4417 if (obj instanceof SharedUserSetting) { 4418 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4419 } else if (obj instanceof PackageSetting) { 4420 s2 = ((PackageSetting)obj).signatures.mSignatures; 4421 } else { 4422 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4423 } 4424 } else { 4425 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4426 } 4427 return compareSignatures(s1, s2); 4428 } 4429 } 4430 4431 /** 4432 * This method should typically only be used when granting or revoking 4433 * permissions, since the app may immediately restart after this call. 4434 * <p> 4435 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 4436 * guard your work against the app being relaunched. 4437 */ 4438 private void killUid(int appId, int userId, String reason) { 4439 final long identity = Binder.clearCallingIdentity(); 4440 try { 4441 IActivityManager am = ActivityManagerNative.getDefault(); 4442 if (am != null) { 4443 try { 4444 am.killUid(appId, userId, reason); 4445 } catch (RemoteException e) { 4446 /* ignore - same process */ 4447 } 4448 } 4449 } finally { 4450 Binder.restoreCallingIdentity(identity); 4451 } 4452 } 4453 4454 /** 4455 * Compares two sets of signatures. Returns: 4456 * <br /> 4457 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4458 * <br /> 4459 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4460 * <br /> 4461 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4462 * <br /> 4463 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4464 * <br /> 4465 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4466 */ 4467 static int compareSignatures(Signature[] s1, Signature[] s2) { 4468 if (s1 == null) { 4469 return s2 == null 4470 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4471 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4472 } 4473 4474 if (s2 == null) { 4475 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4476 } 4477 4478 if (s1.length != s2.length) { 4479 return PackageManager.SIGNATURE_NO_MATCH; 4480 } 4481 4482 // Since both signature sets are of size 1, we can compare without HashSets. 4483 if (s1.length == 1) { 4484 return s1[0].equals(s2[0]) ? 4485 PackageManager.SIGNATURE_MATCH : 4486 PackageManager.SIGNATURE_NO_MATCH; 4487 } 4488 4489 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4490 for (Signature sig : s1) { 4491 set1.add(sig); 4492 } 4493 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4494 for (Signature sig : s2) { 4495 set2.add(sig); 4496 } 4497 // Make sure s2 contains all signatures in s1. 4498 if (set1.equals(set2)) { 4499 return PackageManager.SIGNATURE_MATCH; 4500 } 4501 return PackageManager.SIGNATURE_NO_MATCH; 4502 } 4503 4504 /** 4505 * If the database version for this type of package (internal storage or 4506 * external storage) is less than the version where package signatures 4507 * were updated, return true. 4508 */ 4509 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4510 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4511 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4512 } 4513 4514 /** 4515 * Used for backward compatibility to make sure any packages with 4516 * certificate chains get upgraded to the new style. {@code existingSigs} 4517 * will be in the old format (since they were stored on disk from before the 4518 * system upgrade) and {@code scannedSigs} will be in the newer format. 4519 */ 4520 private int compareSignaturesCompat(PackageSignatures existingSigs, 4521 PackageParser.Package scannedPkg) { 4522 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4523 return PackageManager.SIGNATURE_NO_MATCH; 4524 } 4525 4526 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4527 for (Signature sig : existingSigs.mSignatures) { 4528 existingSet.add(sig); 4529 } 4530 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4531 for (Signature sig : scannedPkg.mSignatures) { 4532 try { 4533 Signature[] chainSignatures = sig.getChainSignatures(); 4534 for (Signature chainSig : chainSignatures) { 4535 scannedCompatSet.add(chainSig); 4536 } 4537 } catch (CertificateEncodingException e) { 4538 scannedCompatSet.add(sig); 4539 } 4540 } 4541 /* 4542 * Make sure the expanded scanned set contains all signatures in the 4543 * existing one. 4544 */ 4545 if (scannedCompatSet.equals(existingSet)) { 4546 // Migrate the old signatures to the new scheme. 4547 existingSigs.assignSignatures(scannedPkg.mSignatures); 4548 // The new KeySets will be re-added later in the scanning process. 4549 synchronized (mPackages) { 4550 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4551 } 4552 return PackageManager.SIGNATURE_MATCH; 4553 } 4554 return PackageManager.SIGNATURE_NO_MATCH; 4555 } 4556 4557 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4558 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4559 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4560 } 4561 4562 private int compareSignaturesRecover(PackageSignatures existingSigs, 4563 PackageParser.Package scannedPkg) { 4564 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4565 return PackageManager.SIGNATURE_NO_MATCH; 4566 } 4567 4568 String msg = null; 4569 try { 4570 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4571 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4572 + scannedPkg.packageName); 4573 return PackageManager.SIGNATURE_MATCH; 4574 } 4575 } catch (CertificateException e) { 4576 msg = e.getMessage(); 4577 } 4578 4579 logCriticalInfo(Log.INFO, 4580 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4581 return PackageManager.SIGNATURE_NO_MATCH; 4582 } 4583 4584 @Override 4585 public List<String> getAllPackages() { 4586 synchronized (mPackages) { 4587 return new ArrayList<String>(mPackages.keySet()); 4588 } 4589 } 4590 4591 @Override 4592 public String[] getPackagesForUid(int uid) { 4593 uid = UserHandle.getAppId(uid); 4594 // reader 4595 synchronized (mPackages) { 4596 Object obj = mSettings.getUserIdLPr(uid); 4597 if (obj instanceof SharedUserSetting) { 4598 final SharedUserSetting sus = (SharedUserSetting) obj; 4599 final int N = sus.packages.size(); 4600 final String[] res = new String[N]; 4601 for (int i = 0; i < N; i++) { 4602 res[i] = sus.packages.valueAt(i).name; 4603 } 4604 return res; 4605 } else if (obj instanceof PackageSetting) { 4606 final PackageSetting ps = (PackageSetting) obj; 4607 return new String[] { ps.name }; 4608 } 4609 } 4610 return null; 4611 } 4612 4613 @Override 4614 public String getNameForUid(int uid) { 4615 // reader 4616 synchronized (mPackages) { 4617 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4618 if (obj instanceof SharedUserSetting) { 4619 final SharedUserSetting sus = (SharedUserSetting) obj; 4620 return sus.name + ":" + sus.userId; 4621 } else if (obj instanceof PackageSetting) { 4622 final PackageSetting ps = (PackageSetting) obj; 4623 return ps.name; 4624 } 4625 } 4626 return null; 4627 } 4628 4629 @Override 4630 public int getUidForSharedUser(String sharedUserName) { 4631 if(sharedUserName == null) { 4632 return -1; 4633 } 4634 // reader 4635 synchronized (mPackages) { 4636 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4637 if (suid == null) { 4638 return -1; 4639 } 4640 return suid.userId; 4641 } 4642 } 4643 4644 @Override 4645 public int getFlagsForUid(int uid) { 4646 synchronized (mPackages) { 4647 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4648 if (obj instanceof SharedUserSetting) { 4649 final SharedUserSetting sus = (SharedUserSetting) obj; 4650 return sus.pkgFlags; 4651 } else if (obj instanceof PackageSetting) { 4652 final PackageSetting ps = (PackageSetting) obj; 4653 return ps.pkgFlags; 4654 } 4655 } 4656 return 0; 4657 } 4658 4659 @Override 4660 public int getPrivateFlagsForUid(int uid) { 4661 synchronized (mPackages) { 4662 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4663 if (obj instanceof SharedUserSetting) { 4664 final SharedUserSetting sus = (SharedUserSetting) obj; 4665 return sus.pkgPrivateFlags; 4666 } else if (obj instanceof PackageSetting) { 4667 final PackageSetting ps = (PackageSetting) obj; 4668 return ps.pkgPrivateFlags; 4669 } 4670 } 4671 return 0; 4672 } 4673 4674 @Override 4675 public boolean isUidPrivileged(int uid) { 4676 uid = UserHandle.getAppId(uid); 4677 // reader 4678 synchronized (mPackages) { 4679 Object obj = mSettings.getUserIdLPr(uid); 4680 if (obj instanceof SharedUserSetting) { 4681 final SharedUserSetting sus = (SharedUserSetting) obj; 4682 final Iterator<PackageSetting> it = sus.packages.iterator(); 4683 while (it.hasNext()) { 4684 if (it.next().isPrivileged()) { 4685 return true; 4686 } 4687 } 4688 } else if (obj instanceof PackageSetting) { 4689 final PackageSetting ps = (PackageSetting) obj; 4690 return ps.isPrivileged(); 4691 } 4692 } 4693 return false; 4694 } 4695 4696 @Override 4697 public String[] getAppOpPermissionPackages(String permissionName) { 4698 synchronized (mPackages) { 4699 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4700 if (pkgs == null) { 4701 return null; 4702 } 4703 return pkgs.toArray(new String[pkgs.size()]); 4704 } 4705 } 4706 4707 @Override 4708 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4709 int flags, int userId) { 4710 try { 4711 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); 4712 4713 if (!sUserManager.exists(userId)) return null; 4714 flags = updateFlagsForResolve(flags, userId, intent); 4715 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4716 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); 4717 4718 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 4719 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, 4720 flags, userId); 4721 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4722 4723 final ResolveInfo bestChoice = 4724 chooseBestActivity(intent, resolvedType, flags, query, userId); 4725 4726 if (isEphemeralAllowed(intent, query, userId)) { 4727 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); 4728 final EphemeralResolveInfo ai = 4729 getEphemeralResolveInfo(intent, resolvedType, userId); 4730 if (ai != null) { 4731 if (DEBUG_EPHEMERAL) { 4732 Slog.v(TAG, "Returning an EphemeralResolveInfo"); 4733 } 4734 bestChoice.ephemeralInstaller = mEphemeralInstallerInfo; 4735 bestChoice.ephemeralResolveInfo = ai; 4736 } 4737 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4738 } 4739 return bestChoice; 4740 } finally { 4741 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4742 } 4743 } 4744 4745 @Override 4746 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4747 IntentFilter filter, int match, ComponentName activity) { 4748 final int userId = UserHandle.getCallingUserId(); 4749 if (DEBUG_PREFERRED) { 4750 Log.v(TAG, "setLastChosenActivity intent=" + intent 4751 + " resolvedType=" + resolvedType 4752 + " flags=" + flags 4753 + " filter=" + filter 4754 + " match=" + match 4755 + " activity=" + activity); 4756 filter.dump(new PrintStreamPrinter(System.out), " "); 4757 } 4758 intent.setComponent(null); 4759 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4760 userId); 4761 // Find any earlier preferred or last chosen entries and nuke them 4762 findPreferredActivity(intent, resolvedType, 4763 flags, query, 0, false, true, false, userId); 4764 // Add the new activity as the last chosen for this filter 4765 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4766 "Setting last chosen"); 4767 } 4768 4769 @Override 4770 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4771 final int userId = UserHandle.getCallingUserId(); 4772 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4773 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4774 userId); 4775 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4776 false, false, false, userId); 4777 } 4778 4779 4780 private boolean isEphemeralAllowed( 4781 Intent intent, List<ResolveInfo> resolvedActivites, int userId) { 4782 // Short circuit and return early if possible. 4783 if (DISABLE_EPHEMERAL_APPS) { 4784 return false; 4785 } 4786 final int callingUser = UserHandle.getCallingUserId(); 4787 if (callingUser != UserHandle.USER_SYSTEM) { 4788 return false; 4789 } 4790 if (mEphemeralResolverConnection == null) { 4791 return false; 4792 } 4793 if (intent.getComponent() != null) { 4794 return false; 4795 } 4796 if (intent.getPackage() != null) { 4797 return false; 4798 } 4799 final boolean isWebUri = hasWebURI(intent); 4800 if (!isWebUri) { 4801 return false; 4802 } 4803 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4804 synchronized (mPackages) { 4805 final int count = resolvedActivites.size(); 4806 for (int n = 0; n < count; n++) { 4807 ResolveInfo info = resolvedActivites.get(n); 4808 String packageName = info.activityInfo.packageName; 4809 PackageSetting ps = mSettings.mPackages.get(packageName); 4810 if (ps != null) { 4811 // Try to get the status from User settings first 4812 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4813 int status = (int) (packedStatus >> 32); 4814 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4815 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4816 if (DEBUG_EPHEMERAL) { 4817 Slog.v(TAG, "DENY ephemeral apps;" 4818 + " pkg: " + packageName + ", status: " + status); 4819 } 4820 return false; 4821 } 4822 } 4823 } 4824 } 4825 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4826 return true; 4827 } 4828 4829 private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType, 4830 int userId) { 4831 final int ephemeralPrefixMask = Global.getInt(mContext.getContentResolver(), 4832 Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK); 4833 final int ephemeralPrefixCount = Global.getInt(mContext.getContentResolver(), 4834 Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT); 4835 final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask, 4836 ephemeralPrefixCount); 4837 final int[] shaPrefix = digest.getDigestPrefix(); 4838 final byte[][] digestBytes = digest.getDigestBytes(); 4839 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4840 mEphemeralResolverConnection.getEphemeralResolveInfoList( 4841 shaPrefix, ephemeralPrefixMask); 4842 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4843 // No hash prefix match; there are no ephemeral apps for this domain. 4844 return null; 4845 } 4846 4847 // Go in reverse order so we match the narrowest scope first. 4848 for (int i = shaPrefix.length - 1; i >= 0 ; --i) { 4849 for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) { 4850 if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) { 4851 continue; 4852 } 4853 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4854 // No filters; this should never happen. 4855 if (filters.isEmpty()) { 4856 continue; 4857 } 4858 // We have a domain match; resolve the filters to see if anything matches. 4859 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4860 for (int j = filters.size() - 1; j >= 0; --j) { 4861 final EphemeralResolveIntentInfo intentInfo = 4862 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4863 ephemeralResolver.addFilter(intentInfo); 4864 } 4865 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4866 intent, resolvedType, false /*defaultOnly*/, userId); 4867 if (!matchedResolveInfoList.isEmpty()) { 4868 return matchedResolveInfoList.get(0); 4869 } 4870 } 4871 } 4872 // Hash or filter mis-match; no ephemeral apps for this domain. 4873 return null; 4874 } 4875 4876 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4877 int flags, List<ResolveInfo> query, int userId) { 4878 if (query != null) { 4879 final int N = query.size(); 4880 if (N == 1) { 4881 return query.get(0); 4882 } else if (N > 1) { 4883 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4884 // If there is more than one activity with the same priority, 4885 // then let the user decide between them. 4886 ResolveInfo r0 = query.get(0); 4887 ResolveInfo r1 = query.get(1); 4888 if (DEBUG_INTENT_MATCHING || debug) { 4889 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4890 + r1.activityInfo.name + "=" + r1.priority); 4891 } 4892 // If the first activity has a higher priority, or a different 4893 // default, then it is always desirable to pick it. 4894 if (r0.priority != r1.priority 4895 || r0.preferredOrder != r1.preferredOrder 4896 || r0.isDefault != r1.isDefault) { 4897 return query.get(0); 4898 } 4899 // If we have saved a preference for a preferred activity for 4900 // this Intent, use that. 4901 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4902 flags, query, r0.priority, true, false, debug, userId); 4903 if (ri != null) { 4904 return ri; 4905 } 4906 ri = new ResolveInfo(mResolveInfo); 4907 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4908 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); 4909 // If all of the options come from the same package, show the application's 4910 // label and icon instead of the generic resolver's. 4911 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here 4912 // and then throw away the ResolveInfo itself, meaning that the caller loses 4913 // the resolvePackageName. Therefore the activityInfo.labelRes above provides 4914 // a fallback for this case; we only set the target package's resources on 4915 // the ResolveInfo, not the ActivityInfo. 4916 final String intentPackage = intent.getPackage(); 4917 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { 4918 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; 4919 ri.resolvePackageName = intentPackage; 4920 if (userNeedsBadging(userId)) { 4921 ri.noResourceId = true; 4922 } else { 4923 ri.icon = appi.icon; 4924 } 4925 ri.iconResourceId = appi.icon; 4926 ri.labelRes = appi.labelRes; 4927 } 4928 ri.activityInfo.applicationInfo = new ApplicationInfo( 4929 ri.activityInfo.applicationInfo); 4930 if (userId != 0) { 4931 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4932 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4933 } 4934 // Make sure that the resolver is displayable in car mode 4935 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4936 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4937 return ri; 4938 } 4939 } 4940 return null; 4941 } 4942 4943 /** 4944 * Return true if the given list is not empty and all of its contents have 4945 * an activityInfo with the given package name. 4946 */ 4947 private boolean allHavePackage(List<ResolveInfo> list, String packageName) { 4948 if (ArrayUtils.isEmpty(list)) { 4949 return false; 4950 } 4951 for (int i = 0, N = list.size(); i < N; i++) { 4952 final ResolveInfo ri = list.get(i); 4953 final ActivityInfo ai = ri != null ? ri.activityInfo : null; 4954 if (ai == null || !packageName.equals(ai.packageName)) { 4955 return false; 4956 } 4957 } 4958 return true; 4959 } 4960 4961 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4962 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4963 final int N = query.size(); 4964 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4965 .get(userId); 4966 // Get the list of persistent preferred activities that handle the intent 4967 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4968 List<PersistentPreferredActivity> pprefs = ppir != null 4969 ? ppir.queryIntent(intent, resolvedType, 4970 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4971 : null; 4972 if (pprefs != null && pprefs.size() > 0) { 4973 final int M = pprefs.size(); 4974 for (int i=0; i<M; i++) { 4975 final PersistentPreferredActivity ppa = pprefs.get(i); 4976 if (DEBUG_PREFERRED || debug) { 4977 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4978 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4979 + "\n component=" + ppa.mComponent); 4980 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4981 } 4982 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4983 flags | MATCH_DISABLED_COMPONENTS, userId); 4984 if (DEBUG_PREFERRED || debug) { 4985 Slog.v(TAG, "Found persistent preferred activity:"); 4986 if (ai != null) { 4987 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4988 } else { 4989 Slog.v(TAG, " null"); 4990 } 4991 } 4992 if (ai == null) { 4993 // This previously registered persistent preferred activity 4994 // component is no longer known. Ignore it and do NOT remove it. 4995 continue; 4996 } 4997 for (int j=0; j<N; j++) { 4998 final ResolveInfo ri = query.get(j); 4999 if (!ri.activityInfo.applicationInfo.packageName 5000 .equals(ai.applicationInfo.packageName)) { 5001 continue; 5002 } 5003 if (!ri.activityInfo.name.equals(ai.name)) { 5004 continue; 5005 } 5006 // Found a persistent preference that can handle the intent. 5007 if (DEBUG_PREFERRED || debug) { 5008 Slog.v(TAG, "Returning persistent preferred activity: " + 5009 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5010 } 5011 return ri; 5012 } 5013 } 5014 } 5015 return null; 5016 } 5017 5018 // TODO: handle preferred activities missing while user has amnesia 5019 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 5020 List<ResolveInfo> query, int priority, boolean always, 5021 boolean removeMatches, boolean debug, int userId) { 5022 if (!sUserManager.exists(userId)) return null; 5023 flags = updateFlagsForResolve(flags, userId, intent); 5024 // writer 5025 synchronized (mPackages) { 5026 if (intent.getSelector() != null) { 5027 intent = intent.getSelector(); 5028 } 5029 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 5030 5031 // Try to find a matching persistent preferred activity. 5032 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 5033 debug, userId); 5034 5035 // If a persistent preferred activity matched, use it. 5036 if (pri != null) { 5037 return pri; 5038 } 5039 5040 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 5041 // Get the list of preferred activities that handle the intent 5042 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 5043 List<PreferredActivity> prefs = pir != null 5044 ? pir.queryIntent(intent, resolvedType, 5045 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 5046 : null; 5047 if (prefs != null && prefs.size() > 0) { 5048 boolean changed = false; 5049 try { 5050 // First figure out how good the original match set is. 5051 // We will only allow preferred activities that came 5052 // from the same match quality. 5053 int match = 0; 5054 5055 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 5056 5057 final int N = query.size(); 5058 for (int j=0; j<N; j++) { 5059 final ResolveInfo ri = query.get(j); 5060 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 5061 + ": 0x" + Integer.toHexString(match)); 5062 if (ri.match > match) { 5063 match = ri.match; 5064 } 5065 } 5066 5067 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 5068 + Integer.toHexString(match)); 5069 5070 match &= IntentFilter.MATCH_CATEGORY_MASK; 5071 final int M = prefs.size(); 5072 for (int i=0; i<M; i++) { 5073 final PreferredActivity pa = prefs.get(i); 5074 if (DEBUG_PREFERRED || debug) { 5075 Slog.v(TAG, "Checking PreferredActivity ds=" 5076 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 5077 + "\n component=" + pa.mPref.mComponent); 5078 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5079 } 5080 if (pa.mPref.mMatch != match) { 5081 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 5082 + Integer.toHexString(pa.mPref.mMatch)); 5083 continue; 5084 } 5085 // If it's not an "always" type preferred activity and that's what we're 5086 // looking for, skip it. 5087 if (always && !pa.mPref.mAlways) { 5088 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 5089 continue; 5090 } 5091 final ActivityInfo ai = getActivityInfo( 5092 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 5093 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 5094 userId); 5095 if (DEBUG_PREFERRED || debug) { 5096 Slog.v(TAG, "Found preferred activity:"); 5097 if (ai != null) { 5098 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5099 } else { 5100 Slog.v(TAG, " null"); 5101 } 5102 } 5103 if (ai == null) { 5104 // This previously registered preferred activity 5105 // component is no longer known. Most likely an update 5106 // to the app was installed and in the new version this 5107 // component no longer exists. Clean it up by removing 5108 // it from the preferred activities list, and skip it. 5109 Slog.w(TAG, "Removing dangling preferred activity: " 5110 + pa.mPref.mComponent); 5111 pir.removeFilter(pa); 5112 changed = true; 5113 continue; 5114 } 5115 for (int j=0; j<N; j++) { 5116 final ResolveInfo ri = query.get(j); 5117 if (!ri.activityInfo.applicationInfo.packageName 5118 .equals(ai.applicationInfo.packageName)) { 5119 continue; 5120 } 5121 if (!ri.activityInfo.name.equals(ai.name)) { 5122 continue; 5123 } 5124 5125 if (removeMatches) { 5126 pir.removeFilter(pa); 5127 changed = true; 5128 if (DEBUG_PREFERRED) { 5129 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 5130 } 5131 break; 5132 } 5133 5134 // Okay we found a previously set preferred or last chosen app. 5135 // If the result set is different from when this 5136 // was created, we need to clear it and re-ask the 5137 // user their preference, if we're looking for an "always" type entry. 5138 if (always && !pa.mPref.sameSet(query)) { 5139 Slog.i(TAG, "Result set changed, dropping preferred activity for " 5140 + intent + " type " + resolvedType); 5141 if (DEBUG_PREFERRED) { 5142 Slog.v(TAG, "Removing preferred activity since set changed " 5143 + pa.mPref.mComponent); 5144 } 5145 pir.removeFilter(pa); 5146 // Re-add the filter as a "last chosen" entry (!always) 5147 PreferredActivity lastChosen = new PreferredActivity( 5148 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 5149 pir.addFilter(lastChosen); 5150 changed = true; 5151 return null; 5152 } 5153 5154 // Yay! Either the set matched or we're looking for the last chosen 5155 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 5156 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5157 return ri; 5158 } 5159 } 5160 } finally { 5161 if (changed) { 5162 if (DEBUG_PREFERRED) { 5163 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5164 } 5165 scheduleWritePackageRestrictionsLocked(userId); 5166 } 5167 } 5168 } 5169 } 5170 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5171 return null; 5172 } 5173 5174 /* 5175 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5176 */ 5177 @Override 5178 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5179 int targetUserId) { 5180 mContext.enforceCallingOrSelfPermission( 5181 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5182 List<CrossProfileIntentFilter> matches = 5183 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5184 if (matches != null) { 5185 int size = matches.size(); 5186 for (int i = 0; i < size; i++) { 5187 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5188 } 5189 } 5190 if (hasWebURI(intent)) { 5191 // cross-profile app linking works only towards the parent. 5192 final UserInfo parent = getProfileParent(sourceUserId); 5193 synchronized(mPackages) { 5194 int flags = updateFlagsForResolve(0, parent.id, intent); 5195 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5196 intent, resolvedType, flags, sourceUserId, parent.id); 5197 return xpDomainInfo != null; 5198 } 5199 } 5200 return false; 5201 } 5202 5203 private UserInfo getProfileParent(int userId) { 5204 final long identity = Binder.clearCallingIdentity(); 5205 try { 5206 return sUserManager.getProfileParent(userId); 5207 } finally { 5208 Binder.restoreCallingIdentity(identity); 5209 } 5210 } 5211 5212 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5213 String resolvedType, int userId) { 5214 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5215 if (resolver != null) { 5216 return resolver.queryIntent(intent, resolvedType, false, userId); 5217 } 5218 return null; 5219 } 5220 5221 @Override 5222 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5223 String resolvedType, int flags, int userId) { 5224 try { 5225 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5226 5227 return new ParceledListSlice<>( 5228 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5229 } finally { 5230 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5231 } 5232 } 5233 5234 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5235 String resolvedType, int flags, int userId) { 5236 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5237 flags = updateFlagsForResolve(flags, userId, intent); 5238 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5239 false /* requireFullPermission */, false /* checkShell */, 5240 "query intent activities"); 5241 ComponentName comp = intent.getComponent(); 5242 if (comp == null) { 5243 if (intent.getSelector() != null) { 5244 intent = intent.getSelector(); 5245 comp = intent.getComponent(); 5246 } 5247 } 5248 5249 if (comp != null) { 5250 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5251 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5252 if (ai != null) { 5253 final ResolveInfo ri = new ResolveInfo(); 5254 ri.activityInfo = ai; 5255 list.add(ri); 5256 } 5257 return list; 5258 } 5259 5260 // reader 5261 synchronized (mPackages) { 5262 final String pkgName = intent.getPackage(); 5263 if (pkgName == null) { 5264 List<CrossProfileIntentFilter> matchingFilters = 5265 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5266 // Check for results that need to skip the current profile. 5267 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5268 resolvedType, flags, userId); 5269 if (xpResolveInfo != null) { 5270 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 5271 result.add(xpResolveInfo); 5272 return filterIfNotSystemUser(result, userId); 5273 } 5274 5275 // Check for results in the current profile. 5276 List<ResolveInfo> result = mActivities.queryIntent( 5277 intent, resolvedType, flags, userId); 5278 result = filterIfNotSystemUser(result, userId); 5279 5280 // Check for cross profile results. 5281 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5282 xpResolveInfo = queryCrossProfileIntents( 5283 matchingFilters, intent, resolvedType, flags, userId, 5284 hasNonNegativePriorityResult); 5285 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5286 boolean isVisibleToUser = filterIfNotSystemUser( 5287 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5288 if (isVisibleToUser) { 5289 result.add(xpResolveInfo); 5290 Collections.sort(result, mResolvePrioritySorter); 5291 } 5292 } 5293 if (hasWebURI(intent)) { 5294 CrossProfileDomainInfo xpDomainInfo = null; 5295 final UserInfo parent = getProfileParent(userId); 5296 if (parent != null) { 5297 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5298 flags, userId, parent.id); 5299 } 5300 if (xpDomainInfo != null) { 5301 if (xpResolveInfo != null) { 5302 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5303 // in the result. 5304 result.remove(xpResolveInfo); 5305 } 5306 if (result.size() == 0) { 5307 result.add(xpDomainInfo.resolveInfo); 5308 return result; 5309 } 5310 } else if (result.size() <= 1) { 5311 return result; 5312 } 5313 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 5314 xpDomainInfo, userId); 5315 Collections.sort(result, mResolvePrioritySorter); 5316 } 5317 return result; 5318 } 5319 final PackageParser.Package pkg = mPackages.get(pkgName); 5320 if (pkg != null) { 5321 return filterIfNotSystemUser( 5322 mActivities.queryIntentForPackage( 5323 intent, resolvedType, flags, pkg.activities, userId), 5324 userId); 5325 } 5326 return new ArrayList<ResolveInfo>(); 5327 } 5328 } 5329 5330 private static class CrossProfileDomainInfo { 5331 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5332 ResolveInfo resolveInfo; 5333 /* Best domain verification status of the activities found in the other profile */ 5334 int bestDomainVerificationStatus; 5335 } 5336 5337 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5338 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5339 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5340 sourceUserId)) { 5341 return null; 5342 } 5343 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5344 resolvedType, flags, parentUserId); 5345 5346 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5347 return null; 5348 } 5349 CrossProfileDomainInfo result = null; 5350 int size = resultTargetUser.size(); 5351 for (int i = 0; i < size; i++) { 5352 ResolveInfo riTargetUser = resultTargetUser.get(i); 5353 // Intent filter verification is only for filters that specify a host. So don't return 5354 // those that handle all web uris. 5355 if (riTargetUser.handleAllWebDataURI) { 5356 continue; 5357 } 5358 String packageName = riTargetUser.activityInfo.packageName; 5359 PackageSetting ps = mSettings.mPackages.get(packageName); 5360 if (ps == null) { 5361 continue; 5362 } 5363 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5364 int status = (int)(verificationState >> 32); 5365 if (result == null) { 5366 result = new CrossProfileDomainInfo(); 5367 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5368 sourceUserId, parentUserId); 5369 result.bestDomainVerificationStatus = status; 5370 } else { 5371 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5372 result.bestDomainVerificationStatus); 5373 } 5374 } 5375 // Don't consider matches with status NEVER across profiles. 5376 if (result != null && result.bestDomainVerificationStatus 5377 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5378 return null; 5379 } 5380 return result; 5381 } 5382 5383 /** 5384 * Verification statuses are ordered from the worse to the best, except for 5385 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5386 */ 5387 private int bestDomainVerificationStatus(int status1, int status2) { 5388 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5389 return status2; 5390 } 5391 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5392 return status1; 5393 } 5394 return (int) MathUtils.max(status1, status2); 5395 } 5396 5397 private boolean isUserEnabled(int userId) { 5398 long callingId = Binder.clearCallingIdentity(); 5399 try { 5400 UserInfo userInfo = sUserManager.getUserInfo(userId); 5401 return userInfo != null && userInfo.isEnabled(); 5402 } finally { 5403 Binder.restoreCallingIdentity(callingId); 5404 } 5405 } 5406 5407 /** 5408 * Filter out activities with systemUserOnly flag set, when current user is not System. 5409 * 5410 * @return filtered list 5411 */ 5412 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5413 if (userId == UserHandle.USER_SYSTEM) { 5414 return resolveInfos; 5415 } 5416 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5417 ResolveInfo info = resolveInfos.get(i); 5418 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5419 resolveInfos.remove(i); 5420 } 5421 } 5422 return resolveInfos; 5423 } 5424 5425 /** 5426 * @param resolveInfos list of resolve infos in descending priority order 5427 * @return if the list contains a resolve info with non-negative priority 5428 */ 5429 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5430 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5431 } 5432 5433 private static boolean hasWebURI(Intent intent) { 5434 if (intent.getData() == null) { 5435 return false; 5436 } 5437 final String scheme = intent.getScheme(); 5438 if (TextUtils.isEmpty(scheme)) { 5439 return false; 5440 } 5441 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5442 } 5443 5444 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5445 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5446 int userId) { 5447 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5448 5449 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5450 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5451 candidates.size()); 5452 } 5453 5454 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5455 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5456 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5457 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5458 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5459 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5460 5461 synchronized (mPackages) { 5462 final int count = candidates.size(); 5463 // First, try to use linked apps. Partition the candidates into four lists: 5464 // one for the final results, one for the "do not use ever", one for "undefined status" 5465 // and finally one for "browser app type". 5466 for (int n=0; n<count; n++) { 5467 ResolveInfo info = candidates.get(n); 5468 String packageName = info.activityInfo.packageName; 5469 PackageSetting ps = mSettings.mPackages.get(packageName); 5470 if (ps != null) { 5471 // Add to the special match all list (Browser use case) 5472 if (info.handleAllWebDataURI) { 5473 matchAllList.add(info); 5474 continue; 5475 } 5476 // Try to get the status from User settings first 5477 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5478 int status = (int)(packedStatus >> 32); 5479 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5480 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5481 if (DEBUG_DOMAIN_VERIFICATION) { 5482 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5483 + " : linkgen=" + linkGeneration); 5484 } 5485 // Use link-enabled generation as preferredOrder, i.e. 5486 // prefer newly-enabled over earlier-enabled. 5487 info.preferredOrder = linkGeneration; 5488 alwaysList.add(info); 5489 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5490 if (DEBUG_DOMAIN_VERIFICATION) { 5491 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5492 } 5493 neverList.add(info); 5494 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5495 if (DEBUG_DOMAIN_VERIFICATION) { 5496 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5497 } 5498 alwaysAskList.add(info); 5499 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5500 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5501 if (DEBUG_DOMAIN_VERIFICATION) { 5502 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5503 } 5504 undefinedList.add(info); 5505 } 5506 } 5507 } 5508 5509 // We'll want to include browser possibilities in a few cases 5510 boolean includeBrowser = false; 5511 5512 // First try to add the "always" resolution(s) for the current user, if any 5513 if (alwaysList.size() > 0) { 5514 result.addAll(alwaysList); 5515 } else { 5516 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5517 result.addAll(undefinedList); 5518 // Maybe add one for the other profile. 5519 if (xpDomainInfo != null && ( 5520 xpDomainInfo.bestDomainVerificationStatus 5521 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5522 result.add(xpDomainInfo.resolveInfo); 5523 } 5524 includeBrowser = true; 5525 } 5526 5527 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5528 // If there were 'always' entries their preferred order has been set, so we also 5529 // back that off to make the alternatives equivalent 5530 if (alwaysAskList.size() > 0) { 5531 for (ResolveInfo i : result) { 5532 i.preferredOrder = 0; 5533 } 5534 result.addAll(alwaysAskList); 5535 includeBrowser = true; 5536 } 5537 5538 if (includeBrowser) { 5539 // Also add browsers (all of them or only the default one) 5540 if (DEBUG_DOMAIN_VERIFICATION) { 5541 Slog.v(TAG, " ...including browsers in candidate set"); 5542 } 5543 if ((matchFlags & MATCH_ALL) != 0) { 5544 result.addAll(matchAllList); 5545 } else { 5546 // Browser/generic handling case. If there's a default browser, go straight 5547 // to that (but only if there is no other higher-priority match). 5548 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5549 int maxMatchPrio = 0; 5550 ResolveInfo defaultBrowserMatch = null; 5551 final int numCandidates = matchAllList.size(); 5552 for (int n = 0; n < numCandidates; n++) { 5553 ResolveInfo info = matchAllList.get(n); 5554 // track the highest overall match priority... 5555 if (info.priority > maxMatchPrio) { 5556 maxMatchPrio = info.priority; 5557 } 5558 // ...and the highest-priority default browser match 5559 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5560 if (defaultBrowserMatch == null 5561 || (defaultBrowserMatch.priority < info.priority)) { 5562 if (debug) { 5563 Slog.v(TAG, "Considering default browser match " + info); 5564 } 5565 defaultBrowserMatch = info; 5566 } 5567 } 5568 } 5569 if (defaultBrowserMatch != null 5570 && defaultBrowserMatch.priority >= maxMatchPrio 5571 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5572 { 5573 if (debug) { 5574 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5575 } 5576 result.add(defaultBrowserMatch); 5577 } else { 5578 result.addAll(matchAllList); 5579 } 5580 } 5581 5582 // If there is nothing selected, add all candidates and remove the ones that the user 5583 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5584 if (result.size() == 0) { 5585 result.addAll(candidates); 5586 result.removeAll(neverList); 5587 } 5588 } 5589 } 5590 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5591 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5592 result.size()); 5593 for (ResolveInfo info : result) { 5594 Slog.v(TAG, " + " + info.activityInfo); 5595 } 5596 } 5597 return result; 5598 } 5599 5600 // Returns a packed value as a long: 5601 // 5602 // high 'int'-sized word: link status: undefined/ask/never/always. 5603 // low 'int'-sized word: relative priority among 'always' results. getDomainVerificationStatusLPr(PackageSetting ps, int userId)5604 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5605 long result = ps.getDomainVerificationStatusForUser(userId); 5606 // if none available, get the master status 5607 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5608 if (ps.getIntentFilterVerificationInfo() != null) { 5609 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5610 } 5611 } 5612 return result; 5613 } 5614 querySkipCurrentProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId)5615 private ResolveInfo querySkipCurrentProfileIntents( 5616 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5617 int flags, int sourceUserId) { 5618 if (matchingFilters != null) { 5619 int size = matchingFilters.size(); 5620 for (int i = 0; i < size; i ++) { 5621 CrossProfileIntentFilter filter = matchingFilters.get(i); 5622 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5623 // Checking if there are activities in the target user that can handle the 5624 // intent. 5625 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5626 resolvedType, flags, sourceUserId); 5627 if (resolveInfo != null) { 5628 return resolveInfo; 5629 } 5630 } 5631 } 5632 } 5633 return null; 5634 } 5635 5636 // Return matching ResolveInfo in target user if any. queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, int flags, int sourceUserId, boolean matchInCurrentProfile)5637 private ResolveInfo queryCrossProfileIntents( 5638 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5639 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5640 if (matchingFilters != null) { 5641 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5642 // match the same intent. For performance reasons, it is better not to 5643 // run queryIntent twice for the same userId 5644 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5645 int size = matchingFilters.size(); 5646 for (int i = 0; i < size; i++) { 5647 CrossProfileIntentFilter filter = matchingFilters.get(i); 5648 int targetUserId = filter.getTargetUserId(); 5649 boolean skipCurrentProfile = 5650 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5651 boolean skipCurrentProfileIfNoMatchFound = 5652 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5653 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5654 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5655 // Checking if there are activities in the target user that can handle the 5656 // intent. 5657 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5658 resolvedType, flags, sourceUserId); 5659 if (resolveInfo != null) return resolveInfo; 5660 alreadyTriedUserIds.put(targetUserId, true); 5661 } 5662 } 5663 } 5664 return null; 5665 } 5666 5667 /** 5668 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5669 * will forward the intent to the filter's target user. 5670 * Otherwise, returns null. 5671 */ createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, String resolvedType, int flags, int sourceUserId)5672 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5673 String resolvedType, int flags, int sourceUserId) { 5674 int targetUserId = filter.getTargetUserId(); 5675 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5676 resolvedType, flags, targetUserId); 5677 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5678 // If all the matches in the target profile are suspended, return null. 5679 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5680 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5681 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5682 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5683 targetUserId); 5684 } 5685 } 5686 } 5687 return null; 5688 } 5689 createForwardingResolveInfoUnchecked(IntentFilter filter, int sourceUserId, int targetUserId)5690 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5691 int sourceUserId, int targetUserId) { 5692 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5693 long ident = Binder.clearCallingIdentity(); 5694 boolean targetIsProfile; 5695 try { 5696 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5697 } finally { 5698 Binder.restoreCallingIdentity(ident); 5699 } 5700 String className; 5701 if (targetIsProfile) { 5702 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5703 } else { 5704 className = FORWARD_INTENT_TO_PARENT; 5705 } 5706 ComponentName forwardingActivityComponentName = new ComponentName( 5707 mAndroidApplication.packageName, className); 5708 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5709 sourceUserId); 5710 if (!targetIsProfile) { 5711 forwardingActivityInfo.showUserIcon = targetUserId; 5712 forwardingResolveInfo.noResourceId = true; 5713 } 5714 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5715 forwardingResolveInfo.priority = 0; 5716 forwardingResolveInfo.preferredOrder = 0; 5717 forwardingResolveInfo.match = 0; 5718 forwardingResolveInfo.isDefault = true; 5719 forwardingResolveInfo.filter = filter; 5720 forwardingResolveInfo.targetUserId = targetUserId; 5721 return forwardingResolveInfo; 5722 } 5723 5724 @Override queryIntentActivityOptions(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)5725 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5726 Intent[] specifics, String[] specificTypes, Intent intent, 5727 String resolvedType, int flags, int userId) { 5728 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 5729 specificTypes, intent, resolvedType, flags, userId)); 5730 } 5731 queryIntentActivityOptionsInternal(ComponentName caller, Intent[] specifics, String[] specificTypes, Intent intent, String resolvedType, int flags, int userId)5732 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 5733 Intent[] specifics, String[] specificTypes, Intent intent, 5734 String resolvedType, int flags, int userId) { 5735 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5736 flags = updateFlagsForResolve(flags, userId, intent); 5737 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5738 false /* requireFullPermission */, false /* checkShell */, 5739 "query intent activity options"); 5740 final String resultsAction = intent.getAction(); 5741 5742 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 5743 | PackageManager.GET_RESOLVED_FILTER, userId); 5744 5745 if (DEBUG_INTENT_MATCHING) { 5746 Log.v(TAG, "Query " + intent + ": " + results); 5747 } 5748 5749 int specificsPos = 0; 5750 int N; 5751 5752 // todo: note that the algorithm used here is O(N^2). This 5753 // isn't a problem in our current environment, but if we start running 5754 // into situations where we have more than 5 or 10 matches then this 5755 // should probably be changed to something smarter... 5756 5757 // First we go through and resolve each of the specific items 5758 // that were supplied, taking care of removing any corresponding 5759 // duplicate items in the generic resolve list. 5760 if (specifics != null) { 5761 for (int i=0; i<specifics.length; i++) { 5762 final Intent sintent = specifics[i]; 5763 if (sintent == null) { 5764 continue; 5765 } 5766 5767 if (DEBUG_INTENT_MATCHING) { 5768 Log.v(TAG, "Specific #" + i + ": " + sintent); 5769 } 5770 5771 String action = sintent.getAction(); 5772 if (resultsAction != null && resultsAction.equals(action)) { 5773 // If this action was explicitly requested, then don't 5774 // remove things that have it. 5775 action = null; 5776 } 5777 5778 ResolveInfo ri = null; 5779 ActivityInfo ai = null; 5780 5781 ComponentName comp = sintent.getComponent(); 5782 if (comp == null) { 5783 ri = resolveIntent( 5784 sintent, 5785 specificTypes != null ? specificTypes[i] : null, 5786 flags, userId); 5787 if (ri == null) { 5788 continue; 5789 } 5790 if (ri == mResolveInfo) { 5791 // ACK! Must do something better with this. 5792 } 5793 ai = ri.activityInfo; 5794 comp = new ComponentName(ai.applicationInfo.packageName, 5795 ai.name); 5796 } else { 5797 ai = getActivityInfo(comp, flags, userId); 5798 if (ai == null) { 5799 continue; 5800 } 5801 } 5802 5803 // Look for any generic query activities that are duplicates 5804 // of this specific one, and remove them from the results. 5805 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5806 N = results.size(); 5807 int j; 5808 for (j=specificsPos; j<N; j++) { 5809 ResolveInfo sri = results.get(j); 5810 if ((sri.activityInfo.name.equals(comp.getClassName()) 5811 && sri.activityInfo.applicationInfo.packageName.equals( 5812 comp.getPackageName())) 5813 || (action != null && sri.filter.matchAction(action))) { 5814 results.remove(j); 5815 if (DEBUG_INTENT_MATCHING) Log.v( 5816 TAG, "Removing duplicate item from " + j 5817 + " due to specific " + specificsPos); 5818 if (ri == null) { 5819 ri = sri; 5820 } 5821 j--; 5822 N--; 5823 } 5824 } 5825 5826 // Add this specific item to its proper place. 5827 if (ri == null) { 5828 ri = new ResolveInfo(); 5829 ri.activityInfo = ai; 5830 } 5831 results.add(specificsPos, ri); 5832 ri.specificIndex = i; 5833 specificsPos++; 5834 } 5835 } 5836 5837 // Now we go through the remaining generic results and remove any 5838 // duplicate actions that are found here. 5839 N = results.size(); 5840 for (int i=specificsPos; i<N-1; i++) { 5841 final ResolveInfo rii = results.get(i); 5842 if (rii.filter == null) { 5843 continue; 5844 } 5845 5846 // Iterate over all of the actions of this result's intent 5847 // filter... typically this should be just one. 5848 final Iterator<String> it = rii.filter.actionsIterator(); 5849 if (it == null) { 5850 continue; 5851 } 5852 while (it.hasNext()) { 5853 final String action = it.next(); 5854 if (resultsAction != null && resultsAction.equals(action)) { 5855 // If this action was explicitly requested, then don't 5856 // remove things that have it. 5857 continue; 5858 } 5859 for (int j=i+1; j<N; j++) { 5860 final ResolveInfo rij = results.get(j); 5861 if (rij.filter != null && rij.filter.hasAction(action)) { 5862 results.remove(j); 5863 if (DEBUG_INTENT_MATCHING) Log.v( 5864 TAG, "Removing duplicate item from " + j 5865 + " due to action " + action + " at " + i); 5866 j--; 5867 N--; 5868 } 5869 } 5870 } 5871 5872 // If the caller didn't request filter information, drop it now 5873 // so we don't have to marshall/unmarshall it. 5874 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5875 rii.filter = null; 5876 } 5877 } 5878 5879 // Filter out the caller activity if so requested. 5880 if (caller != null) { 5881 N = results.size(); 5882 for (int i=0; i<N; i++) { 5883 ActivityInfo ainfo = results.get(i).activityInfo; 5884 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5885 && caller.getClassName().equals(ainfo.name)) { 5886 results.remove(i); 5887 break; 5888 } 5889 } 5890 } 5891 5892 // If the caller didn't request filter information, 5893 // drop them now so we don't have to 5894 // marshall/unmarshall it. 5895 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5896 N = results.size(); 5897 for (int i=0; i<N; i++) { 5898 results.get(i).filter = null; 5899 } 5900 } 5901 5902 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5903 return results; 5904 } 5905 5906 @Override queryIntentReceivers(Intent intent, String resolvedType, int flags, int userId)5907 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 5908 String resolvedType, int flags, int userId) { 5909 return new ParceledListSlice<>( 5910 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 5911 } 5912 queryIntentReceiversInternal(Intent intent, String resolvedType, int flags, int userId)5913 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 5914 String resolvedType, int flags, int userId) { 5915 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5916 flags = updateFlagsForResolve(flags, userId, intent); 5917 ComponentName comp = intent.getComponent(); 5918 if (comp == null) { 5919 if (intent.getSelector() != null) { 5920 intent = intent.getSelector(); 5921 comp = intent.getComponent(); 5922 } 5923 } 5924 if (comp != null) { 5925 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5926 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5927 if (ai != null) { 5928 ResolveInfo ri = new ResolveInfo(); 5929 ri.activityInfo = ai; 5930 list.add(ri); 5931 } 5932 return list; 5933 } 5934 5935 // reader 5936 synchronized (mPackages) { 5937 String pkgName = intent.getPackage(); 5938 if (pkgName == null) { 5939 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5940 } 5941 final PackageParser.Package pkg = mPackages.get(pkgName); 5942 if (pkg != null) { 5943 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5944 userId); 5945 } 5946 return Collections.emptyList(); 5947 } 5948 } 5949 5950 @Override resolveService(Intent intent, String resolvedType, int flags, int userId)5951 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5952 if (!sUserManager.exists(userId)) return null; 5953 flags = updateFlagsForResolve(flags, userId, intent); 5954 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 5955 if (query != null) { 5956 if (query.size() >= 1) { 5957 // If there is more than one service with the same priority, 5958 // just arbitrarily pick the first one. 5959 return query.get(0); 5960 } 5961 } 5962 return null; 5963 } 5964 5965 @Override queryIntentServices(Intent intent, String resolvedType, int flags, int userId)5966 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 5967 String resolvedType, int flags, int userId) { 5968 return new ParceledListSlice<>( 5969 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 5970 } 5971 queryIntentServicesInternal(Intent intent, String resolvedType, int flags, int userId)5972 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 5973 String resolvedType, int flags, int userId) { 5974 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5975 flags = updateFlagsForResolve(flags, userId, intent); 5976 ComponentName comp = intent.getComponent(); 5977 if (comp == null) { 5978 if (intent.getSelector() != null) { 5979 intent = intent.getSelector(); 5980 comp = intent.getComponent(); 5981 } 5982 } 5983 if (comp != null) { 5984 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5985 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5986 if (si != null) { 5987 final ResolveInfo ri = new ResolveInfo(); 5988 ri.serviceInfo = si; 5989 list.add(ri); 5990 } 5991 return list; 5992 } 5993 5994 // reader 5995 synchronized (mPackages) { 5996 String pkgName = intent.getPackage(); 5997 if (pkgName == null) { 5998 return mServices.queryIntent(intent, resolvedType, flags, userId); 5999 } 6000 final PackageParser.Package pkg = mPackages.get(pkgName); 6001 if (pkg != null) { 6002 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 6003 userId); 6004 } 6005 return Collections.emptyList(); 6006 } 6007 } 6008 6009 @Override queryIntentContentProviders(Intent intent, String resolvedType, int flags, int userId)6010 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 6011 String resolvedType, int flags, int userId) { 6012 return new ParceledListSlice<>( 6013 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 6014 } 6015 queryIntentContentProvidersInternal( Intent intent, String resolvedType, int flags, int userId)6016 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 6017 Intent intent, String resolvedType, int flags, int userId) { 6018 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6019 flags = updateFlagsForResolve(flags, userId, intent); 6020 ComponentName comp = intent.getComponent(); 6021 if (comp == null) { 6022 if (intent.getSelector() != null) { 6023 intent = intent.getSelector(); 6024 comp = intent.getComponent(); 6025 } 6026 } 6027 if (comp != null) { 6028 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6029 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 6030 if (pi != null) { 6031 final ResolveInfo ri = new ResolveInfo(); 6032 ri.providerInfo = pi; 6033 list.add(ri); 6034 } 6035 return list; 6036 } 6037 6038 // reader 6039 synchronized (mPackages) { 6040 String pkgName = intent.getPackage(); 6041 if (pkgName == null) { 6042 return mProviders.queryIntent(intent, resolvedType, flags, userId); 6043 } 6044 final PackageParser.Package pkg = mPackages.get(pkgName); 6045 if (pkg != null) { 6046 return mProviders.queryIntentForPackage( 6047 intent, resolvedType, flags, pkg.providers, userId); 6048 } 6049 return Collections.emptyList(); 6050 } 6051 } 6052 6053 @Override getInstalledPackages(int flags, int userId)6054 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 6055 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6056 flags = updateFlagsForPackage(flags, userId, null); 6057 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6058 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6059 true /* requireFullPermission */, false /* checkShell */, 6060 "get installed packages"); 6061 6062 // writer 6063 synchronized (mPackages) { 6064 ArrayList<PackageInfo> list; 6065 if (listUninstalled) { 6066 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 6067 for (PackageSetting ps : mSettings.mPackages.values()) { 6068 final PackageInfo pi; 6069 if (ps.pkg != null) { 6070 pi = generatePackageInfo(ps, flags, userId); 6071 } else { 6072 pi = generatePackageInfo(ps, flags, userId); 6073 } 6074 if (pi != null) { 6075 list.add(pi); 6076 } 6077 } 6078 } else { 6079 list = new ArrayList<PackageInfo>(mPackages.size()); 6080 for (PackageParser.Package p : mPackages.values()) { 6081 final PackageInfo pi = 6082 generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 6083 if (pi != null) { 6084 list.add(pi); 6085 } 6086 } 6087 } 6088 6089 return new ParceledListSlice<PackageInfo>(list); 6090 } 6091 } 6092 addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, String[] permissions, boolean[] tmp, int flags, int userId)6093 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 6094 String[] permissions, boolean[] tmp, int flags, int userId) { 6095 int numMatch = 0; 6096 final PermissionsState permissionsState = ps.getPermissionsState(); 6097 for (int i=0; i<permissions.length; i++) { 6098 final String permission = permissions[i]; 6099 if (permissionsState.hasPermission(permission, userId)) { 6100 tmp[i] = true; 6101 numMatch++; 6102 } else { 6103 tmp[i] = false; 6104 } 6105 } 6106 if (numMatch == 0) { 6107 return; 6108 } 6109 final PackageInfo pi; 6110 if (ps.pkg != null) { 6111 pi = generatePackageInfo(ps, flags, userId); 6112 } else { 6113 pi = generatePackageInfo(ps, flags, userId); 6114 } 6115 // The above might return null in cases of uninstalled apps or install-state 6116 // skew across users/profiles. 6117 if (pi != null) { 6118 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 6119 if (numMatch == permissions.length) { 6120 pi.requestedPermissions = permissions; 6121 } else { 6122 pi.requestedPermissions = new String[numMatch]; 6123 numMatch = 0; 6124 for (int i=0; i<permissions.length; i++) { 6125 if (tmp[i]) { 6126 pi.requestedPermissions[numMatch] = permissions[i]; 6127 numMatch++; 6128 } 6129 } 6130 } 6131 } 6132 list.add(pi); 6133 } 6134 } 6135 6136 @Override getPackagesHoldingPermissions( String[] permissions, int flags, int userId)6137 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 6138 String[] permissions, int flags, int userId) { 6139 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6140 flags = updateFlagsForPackage(flags, userId, permissions); 6141 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6142 6143 // writer 6144 synchronized (mPackages) { 6145 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 6146 boolean[] tmpBools = new boolean[permissions.length]; 6147 if (listUninstalled) { 6148 for (PackageSetting ps : mSettings.mPackages.values()) { 6149 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 6150 } 6151 } else { 6152 for (PackageParser.Package pkg : mPackages.values()) { 6153 PackageSetting ps = (PackageSetting)pkg.mExtras; 6154 if (ps != null) { 6155 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6156 userId); 6157 } 6158 } 6159 } 6160 6161 return new ParceledListSlice<PackageInfo>(list); 6162 } 6163 } 6164 6165 @Override getInstalledApplications(int flags, int userId)6166 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6167 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6168 flags = updateFlagsForApplication(flags, userId, null); 6169 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6170 6171 // writer 6172 synchronized (mPackages) { 6173 ArrayList<ApplicationInfo> list; 6174 if (listUninstalled) { 6175 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6176 for (PackageSetting ps : mSettings.mPackages.values()) { 6177 ApplicationInfo ai; 6178 if (ps.pkg != null) { 6179 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 6180 ps.readUserState(userId), userId); 6181 } else { 6182 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 6183 } 6184 if (ai != null) { 6185 list.add(ai); 6186 } 6187 } 6188 } else { 6189 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6190 for (PackageParser.Package p : mPackages.values()) { 6191 if (p.mExtras != null) { 6192 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6193 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6194 if (ai != null) { 6195 list.add(ai); 6196 } 6197 } 6198 } 6199 } 6200 6201 return new ParceledListSlice<ApplicationInfo>(list); 6202 } 6203 } 6204 6205 @Override getEphemeralApplications(int userId)6206 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6207 if (DISABLE_EPHEMERAL_APPS) { 6208 return null; 6209 } 6210 6211 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6212 "getEphemeralApplications"); 6213 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6214 true /* requireFullPermission */, false /* checkShell */, 6215 "getEphemeralApplications"); 6216 synchronized (mPackages) { 6217 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6218 .getEphemeralApplicationsLPw(userId); 6219 if (ephemeralApps != null) { 6220 return new ParceledListSlice<>(ephemeralApps); 6221 } 6222 } 6223 return null; 6224 } 6225 6226 @Override isEphemeralApplication(String packageName, int userId)6227 public boolean isEphemeralApplication(String packageName, int userId) { 6228 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6229 true /* requireFullPermission */, false /* checkShell */, 6230 "isEphemeral"); 6231 if (DISABLE_EPHEMERAL_APPS) { 6232 return false; 6233 } 6234 6235 if (!isCallerSameApp(packageName)) { 6236 return false; 6237 } 6238 synchronized (mPackages) { 6239 PackageParser.Package pkg = mPackages.get(packageName); 6240 if (pkg != null) { 6241 return pkg.applicationInfo.isEphemeralApp(); 6242 } 6243 } 6244 return false; 6245 } 6246 6247 @Override getEphemeralApplicationCookie(String packageName, int userId)6248 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6249 if (DISABLE_EPHEMERAL_APPS) { 6250 return null; 6251 } 6252 6253 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6254 true /* requireFullPermission */, false /* checkShell */, 6255 "getCookie"); 6256 if (!isCallerSameApp(packageName)) { 6257 return null; 6258 } 6259 synchronized (mPackages) { 6260 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6261 packageName, userId); 6262 } 6263 } 6264 6265 @Override setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId)6266 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6267 if (DISABLE_EPHEMERAL_APPS) { 6268 return true; 6269 } 6270 6271 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6272 true /* requireFullPermission */, true /* checkShell */, 6273 "setCookie"); 6274 if (!isCallerSameApp(packageName)) { 6275 return false; 6276 } 6277 synchronized (mPackages) { 6278 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6279 packageName, cookie, userId); 6280 } 6281 } 6282 6283 @Override getEphemeralApplicationIcon(String packageName, int userId)6284 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6285 if (DISABLE_EPHEMERAL_APPS) { 6286 return null; 6287 } 6288 6289 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6290 "getEphemeralApplicationIcon"); 6291 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6292 true /* requireFullPermission */, false /* checkShell */, 6293 "getEphemeralApplicationIcon"); 6294 synchronized (mPackages) { 6295 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6296 packageName, userId); 6297 } 6298 } 6299 isCallerSameApp(String packageName)6300 private boolean isCallerSameApp(String packageName) { 6301 PackageParser.Package pkg = mPackages.get(packageName); 6302 return pkg != null 6303 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6304 } 6305 6306 @Override getPersistentApplications(int flags)6307 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6308 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6309 } 6310 getPersistentApplicationsInternal(int flags)6311 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6312 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6313 6314 // reader 6315 synchronized (mPackages) { 6316 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6317 final int userId = UserHandle.getCallingUserId(); 6318 while (i.hasNext()) { 6319 final PackageParser.Package p = i.next(); 6320 if (p.applicationInfo == null) continue; 6321 6322 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6323 && !p.applicationInfo.isDirectBootAware(); 6324 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6325 && p.applicationInfo.isDirectBootAware(); 6326 6327 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6328 && (!mSafeMode || isSystemApp(p)) 6329 && (matchesUnaware || matchesAware)) { 6330 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6331 if (ps != null) { 6332 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6333 ps.readUserState(userId), userId); 6334 if (ai != null) { 6335 finalList.add(ai); 6336 } 6337 } 6338 } 6339 } 6340 } 6341 6342 return finalList; 6343 } 6344 6345 @Override resolveContentProvider(String name, int flags, int userId)6346 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6347 if (!sUserManager.exists(userId)) return null; 6348 flags = updateFlagsForComponent(flags, userId, name); 6349 // reader 6350 synchronized (mPackages) { 6351 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6352 PackageSetting ps = provider != null 6353 ? mSettings.mPackages.get(provider.owner.packageName) 6354 : null; 6355 return ps != null 6356 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6357 ? PackageParser.generateProviderInfo(provider, flags, 6358 ps.readUserState(userId), userId) 6359 : null; 6360 } 6361 } 6362 6363 /** 6364 * @deprecated 6365 */ 6366 @Deprecated querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo)6367 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6368 // reader 6369 synchronized (mPackages) { 6370 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6371 .entrySet().iterator(); 6372 final int userId = UserHandle.getCallingUserId(); 6373 while (i.hasNext()) { 6374 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6375 PackageParser.Provider p = entry.getValue(); 6376 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6377 6378 if (ps != null && p.syncable 6379 && (!mSafeMode || (p.info.applicationInfo.flags 6380 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6381 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6382 ps.readUserState(userId), userId); 6383 if (info != null) { 6384 outNames.add(entry.getKey()); 6385 outInfo.add(info); 6386 } 6387 } 6388 } 6389 } 6390 } 6391 6392 @Override queryContentProviders(String processName, int uid, int flags)6393 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6394 int uid, int flags) { 6395 final int userId = processName != null ? UserHandle.getUserId(uid) 6396 : UserHandle.getCallingUserId(); 6397 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6398 flags = updateFlagsForComponent(flags, userId, processName); 6399 6400 ArrayList<ProviderInfo> finalList = null; 6401 // reader 6402 synchronized (mPackages) { 6403 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6404 while (i.hasNext()) { 6405 final PackageParser.Provider p = i.next(); 6406 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6407 if (ps != null && p.info.authority != null 6408 && (processName == null 6409 || (p.info.processName.equals(processName) 6410 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6411 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6412 if (finalList == null) { 6413 finalList = new ArrayList<ProviderInfo>(3); 6414 } 6415 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6416 ps.readUserState(userId), userId); 6417 if (info != null) { 6418 finalList.add(info); 6419 } 6420 } 6421 } 6422 } 6423 6424 if (finalList != null) { 6425 Collections.sort(finalList, mProviderInitOrderSorter); 6426 return new ParceledListSlice<ProviderInfo>(finalList); 6427 } 6428 6429 return ParceledListSlice.emptyList(); 6430 } 6431 6432 @Override getInstrumentationInfo(ComponentName name, int flags)6433 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6434 // reader 6435 synchronized (mPackages) { 6436 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6437 return PackageParser.generateInstrumentationInfo(i, flags); 6438 } 6439 } 6440 6441 @Override queryInstrumentation( String targetPackage, int flags)6442 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6443 String targetPackage, int flags) { 6444 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6445 } 6446 queryInstrumentationInternal(String targetPackage, int flags)6447 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6448 int flags) { 6449 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6450 6451 // reader 6452 synchronized (mPackages) { 6453 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6454 while (i.hasNext()) { 6455 final PackageParser.Instrumentation p = i.next(); 6456 if (targetPackage == null 6457 || targetPackage.equals(p.info.targetPackage)) { 6458 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6459 flags); 6460 if (ii != null) { 6461 finalList.add(ii); 6462 } 6463 } 6464 } 6465 } 6466 6467 return finalList; 6468 } 6469 createIdmapsForPackageLI(PackageParser.Package pkg)6470 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6471 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6472 if (overlays == null) { 6473 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6474 return; 6475 } 6476 for (PackageParser.Package opkg : overlays.values()) { 6477 // Not much to do if idmap fails: we already logged the error 6478 // and we certainly don't want to abort installation of pkg simply 6479 // because an overlay didn't fit properly. For these reasons, 6480 // ignore the return value of createIdmapForPackagePairLI. 6481 createIdmapForPackagePairLI(pkg, opkg); 6482 } 6483 } 6484 createIdmapForPackagePairLI(PackageParser.Package pkg, PackageParser.Package opkg)6485 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6486 PackageParser.Package opkg) { 6487 if (!opkg.mTrustedOverlay) { 6488 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6489 opkg.baseCodePath + ": overlay not trusted"); 6490 return false; 6491 } 6492 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6493 if (overlaySet == null) { 6494 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6495 opkg.baseCodePath + " but target package has no known overlays"); 6496 return false; 6497 } 6498 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6499 // TODO: generate idmap for split APKs 6500 try { 6501 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6502 } catch (InstallerException e) { 6503 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6504 + opkg.baseCodePath); 6505 return false; 6506 } 6507 PackageParser.Package[] overlayArray = 6508 overlaySet.values().toArray(new PackageParser.Package[0]); 6509 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6510 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6511 return p1.mOverlayPriority - p2.mOverlayPriority; 6512 } 6513 }; 6514 Arrays.sort(overlayArray, cmp); 6515 6516 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6517 int i = 0; 6518 for (PackageParser.Package p : overlayArray) { 6519 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6520 } 6521 return true; 6522 } 6523 scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime)6524 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6525 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 6526 try { 6527 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6528 } finally { 6529 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6530 } 6531 } 6532 scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime)6533 private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6534 final File[] files = dir.listFiles(); 6535 if (ArrayUtils.isEmpty(files)) { 6536 Log.d(TAG, "No files in app dir " + dir); 6537 return; 6538 } 6539 6540 if (DEBUG_PACKAGE_SCANNING) { 6541 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6542 + " flags=0x" + Integer.toHexString(parseFlags)); 6543 } 6544 6545 for (File file : files) { 6546 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6547 && !PackageInstallerService.isStageName(file.getName()); 6548 if (!isPackage) { 6549 // Ignore entries which are not packages 6550 continue; 6551 } 6552 try { 6553 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6554 scanFlags, currentTime, null); 6555 } catch (PackageManagerException e) { 6556 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6557 6558 // Delete invalid userdata apps 6559 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6560 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6561 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6562 removeCodePathLI(file); 6563 } 6564 } 6565 } 6566 } 6567 getSettingsProblemFile()6568 private static File getSettingsProblemFile() { 6569 File dataDir = Environment.getDataDirectory(); 6570 File systemDir = new File(dataDir, "system"); 6571 File fname = new File(systemDir, "uiderrors.txt"); 6572 return fname; 6573 } 6574 reportSettingsProblem(int priority, String msg)6575 static void reportSettingsProblem(int priority, String msg) { 6576 logCriticalInfo(priority, msg); 6577 } 6578 logCriticalInfo(int priority, String msg)6579 static void logCriticalInfo(int priority, String msg) { 6580 Slog.println(priority, TAG, msg); 6581 EventLogTags.writePmCriticalInfo(msg); 6582 try { 6583 File fname = getSettingsProblemFile(); 6584 FileOutputStream out = new FileOutputStream(fname, true); 6585 PrintWriter pw = new FastPrintWriter(out); 6586 SimpleDateFormat formatter = new SimpleDateFormat(); 6587 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6588 pw.println(dateString + ": " + msg); 6589 pw.close(); 6590 FileUtils.setPermissions( 6591 fname.toString(), 6592 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6593 -1, -1); 6594 } catch (java.io.IOException e) { 6595 } 6596 } 6597 getLastModifiedTime(PackageParser.Package pkg, File srcFile)6598 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) { 6599 if (srcFile.isDirectory()) { 6600 final File baseFile = new File(pkg.baseCodePath); 6601 long maxModifiedTime = baseFile.lastModified(); 6602 if (pkg.splitCodePaths != null) { 6603 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { 6604 final File splitFile = new File(pkg.splitCodePaths[i]); 6605 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); 6606 } 6607 } 6608 return maxModifiedTime; 6609 } 6610 return srcFile.lastModified(); 6611 } 6612 collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, final int policyFlags)6613 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6614 final int policyFlags) throws PackageManagerException { 6615 if (ps != null 6616 && ps.codePath.equals(srcFile) 6617 && ps.timeStamp == getLastModifiedTime(pkg, srcFile) 6618 && !isCompatSignatureUpdateNeeded(pkg) 6619 && !isRecoverSignatureUpdateNeeded(pkg)) { 6620 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6621 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6622 ArraySet<PublicKey> signingKs; 6623 synchronized (mPackages) { 6624 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6625 } 6626 if (ps.signatures.mSignatures != null 6627 && ps.signatures.mSignatures.length != 0 6628 && signingKs != null) { 6629 // Optimization: reuse the existing cached certificates 6630 // if the package appears to be unchanged. 6631 pkg.mSignatures = ps.signatures.mSignatures; 6632 pkg.mSigningKeys = signingKs; 6633 return; 6634 } 6635 6636 Slog.w(TAG, "PackageSetting for " + ps.name 6637 + " is missing signatures. Collecting certs again to recover them."); 6638 } else { 6639 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 6640 } 6641 6642 try { 6643 PackageParser.collectCertificates(pkg, policyFlags); 6644 } catch (PackageParserException e) { 6645 throw PackageManagerException.from(e); 6646 } 6647 } 6648 6649 /** 6650 * Traces a package scan. 6651 * @see #scanPackageLI(File, int, int, long, UserHandle) 6652 */ scanPackageTracedLI(File scanFile, final int parseFlags, int scanFlags, long currentTime, UserHandle user)6653 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, 6654 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6655 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6656 try { 6657 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6658 } finally { 6659 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6660 } 6661 } 6662 6663 /** 6664 * Scans a package and returns the newly parsed package. 6665 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6666 */ scanPackageLI(File scanFile, int parseFlags, int scanFlags, long currentTime, UserHandle user)6667 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6668 long currentTime, UserHandle user) throws PackageManagerException { 6669 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6670 PackageParser pp = new PackageParser(); 6671 pp.setSeparateProcesses(mSeparateProcesses); 6672 pp.setOnlyCoreApps(mOnlyCore); 6673 pp.setDisplayMetrics(mMetrics); 6674 6675 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6676 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6677 } 6678 6679 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 6680 final PackageParser.Package pkg; 6681 try { 6682 pkg = pp.parsePackage(scanFile, parseFlags); 6683 } catch (PackageParserException e) { 6684 throw PackageManagerException.from(e); 6685 } finally { 6686 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6687 } 6688 6689 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6690 } 6691 6692 /** 6693 * Scans a package and returns the newly parsed package. 6694 * @throws PackageManagerException on a parse error. 6695 */ scanPackageLI(PackageParser.Package pkg, File scanFile, final int policyFlags, int scanFlags, long currentTime, UserHandle user)6696 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6697 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 6698 throws PackageManagerException { 6699 // If the package has children and this is the first dive in the function 6700 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6701 // packages (parent and children) would be successfully scanned before the 6702 // actual scan since scanning mutates internal state and we want to atomically 6703 // install the package and its children. 6704 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6705 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6706 scanFlags |= SCAN_CHECK_ONLY; 6707 } 6708 } else { 6709 scanFlags &= ~SCAN_CHECK_ONLY; 6710 } 6711 6712 // Scan the parent 6713 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags, 6714 scanFlags, currentTime, user); 6715 6716 // Scan the children 6717 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6718 for (int i = 0; i < childCount; i++) { 6719 PackageParser.Package childPackage = pkg.childPackages.get(i); 6720 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags, 6721 currentTime, user); 6722 } 6723 6724 6725 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6726 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user); 6727 } 6728 6729 return scannedPkg; 6730 } 6731 6732 /** 6733 * Scans a package and returns the newly parsed package. 6734 * @throws PackageManagerException on a parse error. 6735 */ scanPackageInternalLI(PackageParser.Package pkg, File scanFile, int policyFlags, int scanFlags, long currentTime, UserHandle user)6736 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6737 int policyFlags, int scanFlags, long currentTime, UserHandle user) 6738 throws PackageManagerException { 6739 PackageSetting ps = null; 6740 PackageSetting updatedPkg; 6741 // reader 6742 synchronized (mPackages) { 6743 // Look to see if we already know about this package. 6744 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 6745 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6746 // This package has been renamed to its original name. Let's 6747 // use that. 6748 ps = mSettings.peekPackageLPr(oldName); 6749 } 6750 // If there was no original package, see one for the real package name. 6751 if (ps == null) { 6752 ps = mSettings.peekPackageLPr(pkg.packageName); 6753 } 6754 // Check to see if this package could be hiding/updating a system 6755 // package. Must look for it either under the original or real 6756 // package name depending on our state. 6757 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6758 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6759 6760 // If this is a package we don't know about on the system partition, we 6761 // may need to remove disabled child packages on the system partition 6762 // or may need to not add child packages if the parent apk is updated 6763 // on the data partition and no longer defines this child package. 6764 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6765 // If this is a parent package for an updated system app and this system 6766 // app got an OTA update which no longer defines some of the child packages 6767 // we have to prune them from the disabled system packages. 6768 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6769 if (disabledPs != null) { 6770 final int scannedChildCount = (pkg.childPackages != null) 6771 ? pkg.childPackages.size() : 0; 6772 final int disabledChildCount = disabledPs.childPackageNames != null 6773 ? disabledPs.childPackageNames.size() : 0; 6774 for (int i = 0; i < disabledChildCount; i++) { 6775 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6776 boolean disabledPackageAvailable = false; 6777 for (int j = 0; j < scannedChildCount; j++) { 6778 PackageParser.Package childPkg = pkg.childPackages.get(j); 6779 if (childPkg.packageName.equals(disabledChildPackageName)) { 6780 disabledPackageAvailable = true; 6781 break; 6782 } 6783 } 6784 if (!disabledPackageAvailable) { 6785 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6786 } 6787 } 6788 } 6789 } 6790 } 6791 6792 boolean updatedPkgBetter = false; 6793 // First check if this is a system package that may involve an update 6794 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6795 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6796 // it needs to drop FLAG_PRIVILEGED. 6797 if (locationIsPrivileged(scanFile)) { 6798 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6799 } else { 6800 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6801 } 6802 6803 if (ps != null && !ps.codePath.equals(scanFile)) { 6804 // The path has changed from what was last scanned... check the 6805 // version of the new path against what we have stored to determine 6806 // what to do. 6807 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6808 if (pkg.mVersionCode <= ps.versionCode) { 6809 // The system package has been updated and the code path does not match 6810 // Ignore entry. Skip it. 6811 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6812 + " ignored: updated version " + ps.versionCode 6813 + " better than this " + pkg.mVersionCode); 6814 if (!updatedPkg.codePath.equals(scanFile)) { 6815 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6816 + ps.name + " changing from " + updatedPkg.codePathString 6817 + " to " + scanFile); 6818 updatedPkg.codePath = scanFile; 6819 updatedPkg.codePathString = scanFile.toString(); 6820 updatedPkg.resourcePath = scanFile; 6821 updatedPkg.resourcePathString = scanFile.toString(); 6822 } 6823 updatedPkg.pkg = pkg; 6824 updatedPkg.versionCode = pkg.mVersionCode; 6825 6826 // Update the disabled system child packages to point to the package too. 6827 final int childCount = updatedPkg.childPackageNames != null 6828 ? updatedPkg.childPackageNames.size() : 0; 6829 for (int i = 0; i < childCount; i++) { 6830 String childPackageName = updatedPkg.childPackageNames.get(i); 6831 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6832 childPackageName); 6833 if (updatedChildPkg != null) { 6834 updatedChildPkg.pkg = pkg; 6835 updatedChildPkg.versionCode = pkg.mVersionCode; 6836 } 6837 } 6838 6839 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6840 + scanFile + " ignored: updated version " + ps.versionCode 6841 + " better than this " + pkg.mVersionCode); 6842 } else { 6843 // The current app on the system partition is better than 6844 // what we have updated to on the data partition; switch 6845 // back to the system partition version. 6846 // At this point, its safely assumed that package installation for 6847 // apps in system partition will go through. If not there won't be a working 6848 // version of the app 6849 // writer 6850 synchronized (mPackages) { 6851 // Just remove the loaded entries from package lists. 6852 mPackages.remove(ps.name); 6853 } 6854 6855 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6856 + " reverting from " + ps.codePathString 6857 + ": new version " + pkg.mVersionCode 6858 + " better than installed " + ps.versionCode); 6859 6860 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6861 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6862 synchronized (mInstallLock) { 6863 args.cleanUpResourcesLI(); 6864 } 6865 synchronized (mPackages) { 6866 mSettings.enableSystemPackageLPw(ps.name); 6867 } 6868 updatedPkgBetter = true; 6869 } 6870 } 6871 } 6872 6873 if (updatedPkg != null) { 6874 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6875 // initially 6876 policyFlags |= PackageParser.PARSE_IS_SYSTEM; 6877 6878 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6879 // flag set initially 6880 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6881 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6882 } 6883 } 6884 6885 // Verify certificates against what was last scanned 6886 collectCertificatesLI(ps, pkg, scanFile, policyFlags); 6887 6888 /* 6889 * A new system app appeared, but we already had a non-system one of the 6890 * same name installed earlier. 6891 */ 6892 boolean shouldHideSystemApp = false; 6893 if (updatedPkg == null && ps != null 6894 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 6895 /* 6896 * Check to make sure the signatures match first. If they don't, 6897 * wipe the installed application and its data. 6898 */ 6899 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 6900 != PackageManager.SIGNATURE_MATCH) { 6901 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 6902 + " signatures don't match existing userdata copy; removing"); 6903 try (PackageFreezer freezer = freezePackage(pkg.packageName, 6904 "scanPackageInternalLI")) { 6905 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); 6906 } 6907 ps = null; 6908 } else { 6909 /* 6910 * If the newly-added system app is an older version than the 6911 * already installed version, hide it. It will be scanned later 6912 * and re-added like an update. 6913 */ 6914 if (pkg.mVersionCode <= ps.versionCode) { 6915 shouldHideSystemApp = true; 6916 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 6917 + " but new version " + pkg.mVersionCode + " better than installed " 6918 + ps.versionCode + "; hiding system"); 6919 } else { 6920 /* 6921 * The newly found system app is a newer version that the 6922 * one previously installed. Simply remove the 6923 * already-installed application and replace it with our own 6924 * while keeping the application data. 6925 */ 6926 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6927 + " reverting from " + ps.codePathString + ": new version " 6928 + pkg.mVersionCode + " better than installed " + ps.versionCode); 6929 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6930 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6931 synchronized (mInstallLock) { 6932 args.cleanUpResourcesLI(); 6933 } 6934 } 6935 } 6936 } 6937 6938 // The apk is forward locked (not public) if its code and resources 6939 // are kept in different files. (except for app in either system or 6940 // vendor path). 6941 // TODO grab this value from PackageSettings 6942 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6943 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6944 policyFlags |= PackageParser.PARSE_FORWARD_LOCK; 6945 } 6946 } 6947 6948 // TODO: extend to support forward-locked splits 6949 String resourcePath = null; 6950 String baseResourcePath = null; 6951 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 6952 if (ps != null && ps.resourcePathString != null) { 6953 resourcePath = ps.resourcePathString; 6954 baseResourcePath = ps.resourcePathString; 6955 } else { 6956 // Should not happen at all. Just log an error. 6957 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 6958 } 6959 } else { 6960 resourcePath = pkg.codePath; 6961 baseResourcePath = pkg.baseCodePath; 6962 } 6963 6964 // Set application objects path explicitly. 6965 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 6966 pkg.setApplicationInfoCodePath(pkg.codePath); 6967 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 6968 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 6969 pkg.setApplicationInfoResourcePath(resourcePath); 6970 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 6971 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 6972 6973 // Note that we invoke the following method only if we are about to unpack an application 6974 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags 6975 | SCAN_UPDATE_SIGNATURE, currentTime, user); 6976 6977 /* 6978 * If the system app should be overridden by a previously installed 6979 * data, hide the system app now and let the /data/app scan pick it up 6980 * again. 6981 */ 6982 if (shouldHideSystemApp) { 6983 synchronized (mPackages) { 6984 mSettings.disableSystemPackageLPw(pkg.packageName, true); 6985 } 6986 } 6987 6988 return scannedPkg; 6989 } 6990 fixProcessName(String defProcessName, String processName, int uid)6991 private static String fixProcessName(String defProcessName, 6992 String processName, int uid) { 6993 if (processName == null) { 6994 return defProcessName; 6995 } 6996 return processName; 6997 } 6998 verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)6999 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 7000 throws PackageManagerException { 7001 if (pkgSetting.signatures.mSignatures != null) { 7002 // Already existing package. Make sure signatures match 7003 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 7004 == PackageManager.SIGNATURE_MATCH; 7005 if (!match) { 7006 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 7007 == PackageManager.SIGNATURE_MATCH; 7008 } 7009 if (!match) { 7010 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 7011 == PackageManager.SIGNATURE_MATCH; 7012 } 7013 if (!match) { 7014 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 7015 + pkg.packageName + " signatures do not match the " 7016 + "previously installed version; ignoring!"); 7017 } 7018 } 7019 7020 // Check for shared user signatures 7021 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 7022 // Already existing package. Make sure signatures match 7023 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7024 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 7025 if (!match) { 7026 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 7027 == PackageManager.SIGNATURE_MATCH; 7028 } 7029 if (!match) { 7030 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 7031 == PackageManager.SIGNATURE_MATCH; 7032 } 7033 if (!match) { 7034 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 7035 "Package " + pkg.packageName 7036 + " has no signatures that match those in shared user " 7037 + pkgSetting.sharedUser.name + "; ignoring!"); 7038 } 7039 } 7040 } 7041 7042 /** 7043 * Enforces that only the system UID or root's UID can call a method exposed 7044 * via Binder. 7045 * 7046 * @param message used as message if SecurityException is thrown 7047 * @throws SecurityException if the caller is not system or root 7048 */ enforceSystemOrRoot(String message)7049 private static final void enforceSystemOrRoot(String message) { 7050 final int uid = Binder.getCallingUid(); 7051 if (uid != Process.SYSTEM_UID && uid != 0) { 7052 throw new SecurityException(message); 7053 } 7054 } 7055 7056 @Override performFstrimIfNeeded()7057 public void performFstrimIfNeeded() { 7058 enforceSystemOrRoot("Only the system can request fstrim"); 7059 7060 // Before everything else, see whether we need to fstrim. 7061 try { 7062 IMountService ms = PackageHelper.getMountService(); 7063 if (ms != null) { 7064 boolean doTrim = false; 7065 final long interval = android.provider.Settings.Global.getLong( 7066 mContext.getContentResolver(), 7067 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 7068 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 7069 if (interval > 0) { 7070 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 7071 if (timeSinceLast > interval) { 7072 doTrim = true; 7073 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 7074 + "; running immediately"); 7075 } 7076 } 7077 if (doTrim) { 7078 if (!isFirstBoot()) { 7079 try { 7080 ActivityManagerNative.getDefault().showBootMessage( 7081 mContext.getResources().getString( 7082 R.string.android_upgrading_fstrim), true); 7083 } catch (RemoteException e) { 7084 } 7085 } 7086 ms.runMaintenance(); 7087 } 7088 } else { 7089 Slog.e(TAG, "Mount service unavailable!"); 7090 } 7091 } catch (RemoteException e) { 7092 // Can't happen; MountService is local 7093 } 7094 } 7095 7096 @Override updatePackagesIfNeeded()7097 public void updatePackagesIfNeeded() { 7098 enforceSystemOrRoot("Only the system can request package update"); 7099 7100 // We need to re-extract after an OTA. 7101 boolean causeUpgrade = isUpgrade(); 7102 7103 // First boot or factory reset. 7104 // Note: we also handle devices that are upgrading to N right now as if it is their 7105 // first boot, as they do not have profile data. 7106 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 7107 7108 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 7109 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 7110 7111 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 7112 return; 7113 } 7114 7115 List<PackageParser.Package> pkgs; 7116 synchronized (mPackages) { 7117 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 7118 } 7119 7120 final long startTime = System.nanoTime(); 7121 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, 7122 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); 7123 7124 final int elapsedTimeSeconds = 7125 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); 7126 7127 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); 7128 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); 7129 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); 7130 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); 7131 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); 7132 } 7133 7134 /** 7135 * Performs dexopt on the set of packages in {@code packages} and returns an int array 7136 * containing statistics about the invocation. The array consists of three elements, 7137 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} 7138 * and {@code numberOfPackagesFailed}. 7139 */ performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, String compilerFilter)7140 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, 7141 String compilerFilter) { 7142 7143 int numberOfPackagesVisited = 0; 7144 int numberOfPackagesOptimized = 0; 7145 int numberOfPackagesSkipped = 0; 7146 int numberOfPackagesFailed = 0; 7147 final int numberOfPackagesToDexopt = pkgs.size(); 7148 7149 for (PackageParser.Package pkg : pkgs) { 7150 numberOfPackagesVisited++; 7151 7152 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 7153 if (DEBUG_DEXOPT) { 7154 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 7155 } 7156 numberOfPackagesSkipped++; 7157 continue; 7158 } 7159 7160 if (DEBUG_DEXOPT) { 7161 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + 7162 numberOfPackagesToDexopt + ": " + pkg.packageName); 7163 } 7164 7165 if (showDialog) { 7166 try { 7167 ActivityManagerNative.getDefault().showBootMessage( 7168 mContext.getResources().getString(R.string.android_upgrading_apk, 7169 numberOfPackagesVisited, numberOfPackagesToDexopt), true); 7170 } catch (RemoteException e) { 7171 } 7172 } 7173 7174 // If the OTA updates a system app which was previously preopted to a non-preopted state 7175 // the app might end up being verified at runtime. That's because by default the apps 7176 // are verify-profile but for preopted apps there's no profile. 7177 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 7178 // that before the OTA the app was preopted) the app gets compiled with a non-profile 7179 // filter (by default interpret-only). 7180 // Note that at this stage unused apps are already filtered. 7181 if (isSystemApp(pkg) && 7182 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 7183 !Environment.getReferenceProfile(pkg.packageName).exists()) { 7184 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 7185 } 7186 7187 // checkProfiles is false to avoid merging profiles during boot which 7188 // might interfere with background compilation (b/28612421). 7189 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will 7190 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a 7191 // trade-off worth doing to save boot time work. 7192 int dexOptStatus = performDexOptTraced(pkg.packageName, 7193 false /* checkProfiles */, 7194 compilerFilter, 7195 false /* force */); 7196 switch (dexOptStatus) { 7197 case PackageDexOptimizer.DEX_OPT_PERFORMED: 7198 numberOfPackagesOptimized++; 7199 break; 7200 case PackageDexOptimizer.DEX_OPT_SKIPPED: 7201 numberOfPackagesSkipped++; 7202 break; 7203 case PackageDexOptimizer.DEX_OPT_FAILED: 7204 numberOfPackagesFailed++; 7205 break; 7206 default: 7207 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus); 7208 break; 7209 } 7210 } 7211 7212 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped, 7213 numberOfPackagesFailed }; 7214 } 7215 7216 @Override notifyPackageUse(String packageName, int reason)7217 public void notifyPackageUse(String packageName, int reason) { 7218 synchronized (mPackages) { 7219 PackageParser.Package p = mPackages.get(packageName); 7220 if (p == null) { 7221 return; 7222 } 7223 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); 7224 } 7225 } 7226 7227 // TODO: this is not used nor needed. Delete it. 7228 @Override performDexOptIfNeeded(String packageName)7229 public boolean performDexOptIfNeeded(String packageName) { 7230 int dexOptStatus = performDexOptTraced(packageName, 7231 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 7232 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7233 } 7234 7235 @Override performDexOpt(String packageName, boolean checkProfiles, int compileReason, boolean force)7236 public boolean performDexOpt(String packageName, 7237 boolean checkProfiles, int compileReason, boolean force) { 7238 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7239 getCompilerFilterForReason(compileReason), force); 7240 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7241 } 7242 7243 @Override performDexOptMode(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force)7244 public boolean performDexOptMode(String packageName, 7245 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7246 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7247 targetCompilerFilter, force); 7248 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7249 } 7250 performDexOptTraced(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force)7251 private int performDexOptTraced(String packageName, 7252 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7253 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7254 try { 7255 return performDexOptInternal(packageName, checkProfiles, 7256 targetCompilerFilter, force); 7257 } finally { 7258 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7259 } 7260 } 7261 7262 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 7263 // if the package can now be considered up to date for the given filter. performDexOptInternal(String packageName, boolean checkProfiles, String targetCompilerFilter, boolean force)7264 private int performDexOptInternal(String packageName, 7265 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7266 PackageParser.Package p; 7267 synchronized (mPackages) { 7268 p = mPackages.get(packageName); 7269 if (p == null) { 7270 // Package could not be found. Report failure. 7271 return PackageDexOptimizer.DEX_OPT_FAILED; 7272 } 7273 mPackageUsage.maybeWriteAsync(mPackages); 7274 mCompilerStats.maybeWriteAsync(); 7275 } 7276 long callingId = Binder.clearCallingIdentity(); 7277 try { 7278 synchronized (mInstallLock) { 7279 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 7280 targetCompilerFilter, force); 7281 } 7282 } finally { 7283 Binder.restoreCallingIdentity(callingId); 7284 } 7285 } 7286 getOptimizablePackages()7287 public ArraySet<String> getOptimizablePackages() { 7288 ArraySet<String> pkgs = new ArraySet<String>(); 7289 synchronized (mPackages) { 7290 for (PackageParser.Package p : mPackages.values()) { 7291 if (PackageDexOptimizer.canOptimizePackage(p)) { 7292 pkgs.add(p.packageName); 7293 } 7294 } 7295 } 7296 return pkgs; 7297 } 7298 performDexOptInternalWithDependenciesLI(PackageParser.Package p, boolean checkProfiles, String targetCompilerFilter, boolean force)7299 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7300 boolean checkProfiles, String targetCompilerFilter, 7301 boolean force) { 7302 // Select the dex optimizer based on the force parameter. 7303 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7304 // allocate an object here. 7305 PackageDexOptimizer pdo = force 7306 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7307 : mPackageDexOptimizer; 7308 7309 // Optimize all dependencies first. Note: we ignore the return value and march on 7310 // on errors. 7311 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7312 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 7313 if (!deps.isEmpty()) { 7314 for (PackageParser.Package depPackage : deps) { 7315 // TODO: Analyze and investigate if we (should) profile libraries. 7316 // Currently this will do a full compilation of the library by default. 7317 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 7318 false /* checkProfiles */, 7319 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 7320 getOrCreateCompilerPackageStats(depPackage)); 7321 } 7322 } 7323 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 7324 targetCompilerFilter, getOrCreateCompilerPackageStats(p)); 7325 } 7326 findSharedNonSystemLibraries(PackageParser.Package p)7327 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7328 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7329 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7330 Set<String> collectedNames = new HashSet<>(); 7331 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7332 7333 retValue.remove(p); 7334 7335 return retValue; 7336 } else { 7337 return Collections.emptyList(); 7338 } 7339 } 7340 findSharedNonSystemLibrariesRecursive(PackageParser.Package p, Collection<PackageParser.Package> collected, Set<String> collectedNames)7341 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7342 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7343 if (!collectedNames.contains(p.packageName)) { 7344 collectedNames.add(p.packageName); 7345 collected.add(p); 7346 7347 if (p.usesLibraries != null) { 7348 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7349 } 7350 if (p.usesOptionalLibraries != null) { 7351 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7352 collectedNames); 7353 } 7354 } 7355 } 7356 findSharedNonSystemLibrariesRecursive(Collection<String> libs, Collection<PackageParser.Package> collected, Set<String> collectedNames)7357 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7358 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7359 for (String libName : libs) { 7360 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7361 if (libPkg != null) { 7362 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7363 } 7364 } 7365 } 7366 findSharedNonSystemLibrary(String libName)7367 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7368 synchronized (mPackages) { 7369 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7370 if (lib != null && lib.apk != null) { 7371 return mPackages.get(lib.apk); 7372 } 7373 } 7374 return null; 7375 } 7376 shutdown()7377 public void shutdown() { 7378 mPackageUsage.writeNow(mPackages); 7379 mCompilerStats.writeNow(); 7380 } 7381 7382 @Override dumpProfiles(String packageName)7383 public void dumpProfiles(String packageName) { 7384 PackageParser.Package pkg; 7385 synchronized (mPackages) { 7386 pkg = mPackages.get(packageName); 7387 if (pkg == null) { 7388 throw new IllegalArgumentException("Unknown package: " + packageName); 7389 } 7390 } 7391 /* Only the shell, root, or the app user should be able to dump profiles. */ 7392 int callingUid = Binder.getCallingUid(); 7393 if (callingUid != Process.SHELL_UID && 7394 callingUid != Process.ROOT_UID && 7395 callingUid != pkg.applicationInfo.uid) { 7396 throw new SecurityException("dumpProfiles"); 7397 } 7398 7399 synchronized (mInstallLock) { 7400 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 7401 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 7402 try { 7403 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 7404 String gid = Integer.toString(sharedGid); 7405 String codePaths = TextUtils.join(";", allCodePaths); 7406 mInstaller.dumpProfiles(gid, packageName, codePaths); 7407 } catch (InstallerException e) { 7408 Slog.w(TAG, "Failed to dump profiles", e); 7409 } 7410 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7411 } 7412 } 7413 7414 @Override forceDexOpt(String packageName)7415 public void forceDexOpt(String packageName) { 7416 enforceSystemOrRoot("forceDexOpt"); 7417 7418 PackageParser.Package pkg; 7419 synchronized (mPackages) { 7420 pkg = mPackages.get(packageName); 7421 if (pkg == null) { 7422 throw new IllegalArgumentException("Unknown package: " + packageName); 7423 } 7424 } 7425 7426 synchronized (mInstallLock) { 7427 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7428 7429 // Whoever is calling forceDexOpt wants a fully compiled package. 7430 // Don't use profiles since that may cause compilation to be skipped. 7431 final int res = performDexOptInternalWithDependenciesLI(pkg, 7432 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7433 true /* force */); 7434 7435 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7436 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7437 throw new IllegalStateException("Failed to dexopt: " + res); 7438 } 7439 } 7440 } 7441 verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg)7442 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7443 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7444 Slog.w(TAG, "Unable to update from " + oldPkg.name 7445 + " to " + newPkg.packageName 7446 + ": old package not in system partition"); 7447 return false; 7448 } else if (mPackages.get(oldPkg.name) != null) { 7449 Slog.w(TAG, "Unable to update from " + oldPkg.name 7450 + " to " + newPkg.packageName 7451 + ": old package still exists"); 7452 return false; 7453 } 7454 return true; 7455 } 7456 removeCodePathLI(File codePath)7457 void removeCodePathLI(File codePath) { 7458 if (codePath.isDirectory()) { 7459 try { 7460 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7461 } catch (InstallerException e) { 7462 Slog.w(TAG, "Failed to remove code path", e); 7463 } 7464 } else { 7465 codePath.delete(); 7466 } 7467 } 7468 resolveUserIds(int userId)7469 private int[] resolveUserIds(int userId) { 7470 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 7471 } 7472 clearAppDataLIF(PackageParser.Package pkg, int userId, int flags)7473 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7474 if (pkg == null) { 7475 Slog.wtf(TAG, "Package was null!", new Throwable()); 7476 return; 7477 } 7478 clearAppDataLeafLIF(pkg, userId, flags); 7479 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7480 for (int i = 0; i < childCount; i++) { 7481 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7482 } 7483 } 7484 clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags)7485 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7486 final PackageSetting ps; 7487 synchronized (mPackages) { 7488 ps = mSettings.mPackages.get(pkg.packageName); 7489 } 7490 for (int realUserId : resolveUserIds(userId)) { 7491 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7492 try { 7493 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7494 ceDataInode); 7495 } catch (InstallerException e) { 7496 Slog.w(TAG, String.valueOf(e)); 7497 } 7498 } 7499 } 7500 destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags)7501 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7502 if (pkg == null) { 7503 Slog.wtf(TAG, "Package was null!", new Throwable()); 7504 return; 7505 } 7506 destroyAppDataLeafLIF(pkg, userId, flags); 7507 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7508 for (int i = 0; i < childCount; i++) { 7509 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7510 } 7511 } 7512 destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags)7513 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7514 final PackageSetting ps; 7515 synchronized (mPackages) { 7516 ps = mSettings.mPackages.get(pkg.packageName); 7517 } 7518 for (int realUserId : resolveUserIds(userId)) { 7519 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7520 try { 7521 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7522 ceDataInode); 7523 } catch (InstallerException e) { 7524 Slog.w(TAG, String.valueOf(e)); 7525 } 7526 } 7527 } 7528 destroyAppProfilesLIF(PackageParser.Package pkg, int userId)7529 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 7530 if (pkg == null) { 7531 Slog.wtf(TAG, "Package was null!", new Throwable()); 7532 return; 7533 } 7534 destroyAppProfilesLeafLIF(pkg); 7535 destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */); 7536 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7537 for (int i = 0; i < childCount; i++) { 7538 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 7539 destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId, 7540 true /* removeBaseMarker */); 7541 } 7542 } 7543 destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, boolean removeBaseMarker)7544 private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, 7545 boolean removeBaseMarker) { 7546 if (pkg.isForwardLocked()) { 7547 return; 7548 } 7549 7550 for (String path : pkg.getAllCodePathsExcludingResourceOnly()) { 7551 try { 7552 path = PackageManagerServiceUtils.realpath(new File(path)); 7553 } catch (IOException e) { 7554 // TODO: Should we return early here ? 7555 Slog.w(TAG, "Failed to get canonical path", e); 7556 continue; 7557 } 7558 7559 final String useMarker = path.replace('/', '@'); 7560 for (int realUserId : resolveUserIds(userId)) { 7561 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId); 7562 if (removeBaseMarker) { 7563 File foreignUseMark = new File(profileDir, useMarker); 7564 if (foreignUseMark.exists()) { 7565 if (!foreignUseMark.delete()) { 7566 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7567 + pkg.packageName); 7568 } 7569 } 7570 } 7571 7572 File[] markers = profileDir.listFiles(); 7573 if (markers != null) { 7574 final String searchString = "@" + pkg.packageName + "@"; 7575 // We also delete all markers that contain the package name we're 7576 // uninstalling. These are associated with secondary dex-files belonging 7577 // to the package. Reconstructing the path of these dex files is messy 7578 // in general. 7579 for (File marker : markers) { 7580 if (marker.getName().indexOf(searchString) > 0) { 7581 if (!marker.delete()) { 7582 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7583 + pkg.packageName); 7584 } 7585 } 7586 } 7587 } 7588 } 7589 } 7590 } 7591 destroyAppProfilesLeafLIF(PackageParser.Package pkg)7592 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 7593 try { 7594 mInstaller.destroyAppProfiles(pkg.packageName); 7595 } catch (InstallerException e) { 7596 Slog.w(TAG, String.valueOf(e)); 7597 } 7598 } 7599 clearAppProfilesLIF(PackageParser.Package pkg, int userId)7600 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 7601 if (pkg == null) { 7602 Slog.wtf(TAG, "Package was null!", new Throwable()); 7603 return; 7604 } 7605 clearAppProfilesLeafLIF(pkg); 7606 // We don't remove the base foreign use marker when clearing profiles because 7607 // we will rename it when the app is updated. Unlike the actual profile contents, 7608 // the foreign use marker is good across installs. 7609 destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */); 7610 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7611 for (int i = 0; i < childCount; i++) { 7612 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 7613 } 7614 } 7615 clearAppProfilesLeafLIF(PackageParser.Package pkg)7616 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 7617 try { 7618 mInstaller.clearAppProfiles(pkg.packageName); 7619 } catch (InstallerException e) { 7620 Slog.w(TAG, String.valueOf(e)); 7621 } 7622 } 7623 setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, long lastUpdateTime)7624 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7625 long lastUpdateTime) { 7626 // Set parent install/update time 7627 PackageSetting ps = (PackageSetting) pkg.mExtras; 7628 if (ps != null) { 7629 ps.firstInstallTime = firstInstallTime; 7630 ps.lastUpdateTime = lastUpdateTime; 7631 } 7632 // Set children install/update time 7633 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7634 for (int i = 0; i < childCount; i++) { 7635 PackageParser.Package childPkg = pkg.childPackages.get(i); 7636 ps = (PackageSetting) childPkg.mExtras; 7637 if (ps != null) { 7638 ps.firstInstallTime = firstInstallTime; 7639 ps.lastUpdateTime = lastUpdateTime; 7640 } 7641 } 7642 } 7643 addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, PackageParser.Package changingLib)7644 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7645 PackageParser.Package changingLib) { 7646 if (file.path != null) { 7647 usesLibraryFiles.add(file.path); 7648 return; 7649 } 7650 PackageParser.Package p = mPackages.get(file.apk); 7651 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7652 // If we are doing this while in the middle of updating a library apk, 7653 // then we need to make sure to use that new apk for determining the 7654 // dependencies here. (We haven't yet finished committing the new apk 7655 // to the package manager state.) 7656 if (p == null || p.packageName.equals(changingLib.packageName)) { 7657 p = changingLib; 7658 } 7659 } 7660 if (p != null) { 7661 usesLibraryFiles.addAll(p.getAllCodePaths()); 7662 } 7663 } 7664 updateSharedLibrariesLPw(PackageParser.Package pkg, PackageParser.Package changingLib)7665 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7666 PackageParser.Package changingLib) throws PackageManagerException { 7667 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7668 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7669 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7670 for (int i=0; i<N; i++) { 7671 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7672 if (file == null) { 7673 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7674 "Package " + pkg.packageName + " requires unavailable shared library " 7675 + pkg.usesLibraries.get(i) + "; failing!"); 7676 } 7677 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7678 } 7679 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7680 for (int i=0; i<N; i++) { 7681 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7682 if (file == null) { 7683 Slog.w(TAG, "Package " + pkg.packageName 7684 + " desires unavailable shared library " 7685 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7686 } else { 7687 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7688 } 7689 } 7690 N = usesLibraryFiles.size(); 7691 if (N > 0) { 7692 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7693 } else { 7694 pkg.usesLibraryFiles = null; 7695 } 7696 } 7697 } 7698 hasString(List<String> list, List<String> which)7699 private static boolean hasString(List<String> list, List<String> which) { 7700 if (list == null) { 7701 return false; 7702 } 7703 for (int i=list.size()-1; i>=0; i--) { 7704 for (int j=which.size()-1; j>=0; j--) { 7705 if (which.get(j).equals(list.get(i))) { 7706 return true; 7707 } 7708 } 7709 } 7710 return false; 7711 } 7712 updateAllSharedLibrariesLPw()7713 private void updateAllSharedLibrariesLPw() { 7714 for (PackageParser.Package pkg : mPackages.values()) { 7715 try { 7716 updateSharedLibrariesLPw(pkg, null); 7717 } catch (PackageManagerException e) { 7718 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7719 } 7720 } 7721 } 7722 updateAllSharedLibrariesLPw( PackageParser.Package changingPkg)7723 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7724 PackageParser.Package changingPkg) { 7725 ArrayList<PackageParser.Package> res = null; 7726 for (PackageParser.Package pkg : mPackages.values()) { 7727 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7728 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7729 if (res == null) { 7730 res = new ArrayList<PackageParser.Package>(); 7731 } 7732 res.add(pkg); 7733 try { 7734 updateSharedLibrariesLPw(pkg, changingPkg); 7735 } catch (PackageManagerException e) { 7736 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7737 } 7738 } 7739 } 7740 return res; 7741 } 7742 7743 /** 7744 * Derive the value of the {@code cpuAbiOverride} based on the provided 7745 * value and an optional stored value from the package settings. 7746 */ deriveAbiOverride(String abiOverride, PackageSetting settings)7747 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7748 String cpuAbiOverride = null; 7749 7750 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7751 cpuAbiOverride = null; 7752 } else if (abiOverride != null) { 7753 cpuAbiOverride = abiOverride; 7754 } else if (settings != null) { 7755 cpuAbiOverride = settings.cpuAbiOverrideString; 7756 } 7757 7758 return cpuAbiOverride; 7759 } 7760 scanPackageTracedLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user)7761 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 7762 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 7763 throws PackageManagerException { 7764 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7765 // If the package has children and this is the first dive in the function 7766 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7767 // whether all packages (parent and children) would be successfully scanned 7768 // before the actual scan since scanning mutates internal state and we want 7769 // to atomically install the package and its children. 7770 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7771 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7772 scanFlags |= SCAN_CHECK_ONLY; 7773 } 7774 } else { 7775 scanFlags &= ~SCAN_CHECK_ONLY; 7776 } 7777 7778 final PackageParser.Package scannedPkg; 7779 try { 7780 // Scan the parent 7781 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 7782 // Scan the children 7783 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7784 for (int i = 0; i < childCount; i++) { 7785 PackageParser.Package childPkg = pkg.childPackages.get(i); 7786 scanPackageLI(childPkg, policyFlags, 7787 scanFlags, currentTime, user); 7788 } 7789 } finally { 7790 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7791 } 7792 7793 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7794 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 7795 } 7796 7797 return scannedPkg; 7798 } 7799 scanPackageLI(PackageParser.Package pkg, final int policyFlags, int scanFlags, long currentTime, UserHandle user)7800 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 7801 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7802 boolean success = false; 7803 try { 7804 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 7805 currentTime, user); 7806 success = true; 7807 return res; 7808 } finally { 7809 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7810 // DELETE_DATA_ON_FAILURES is only used by frozen paths 7811 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 7812 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 7813 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 7814 } 7815 } 7816 } 7817 7818 /** 7819 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 7820 */ apkHasCode(String fileName)7821 private static boolean apkHasCode(String fileName) { 7822 StrictJarFile jarFile = null; 7823 try { 7824 jarFile = new StrictJarFile(fileName, 7825 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 7826 return jarFile.findEntry("classes.dex") != null; 7827 } catch (IOException ignore) { 7828 } finally { 7829 try { 7830 if (jarFile != null) { 7831 jarFile.close(); 7832 } 7833 } catch (IOException ignore) {} 7834 } 7835 return false; 7836 } 7837 7838 /** 7839 * Enforces code policy for the package. This ensures that if an APK has 7840 * declared hasCode="true" in its manifest that the APK actually contains 7841 * code. 7842 * 7843 * @throws PackageManagerException If bytecode could not be found when it should exist 7844 */ enforceCodePolicy(PackageParser.Package pkg)7845 private static void enforceCodePolicy(PackageParser.Package pkg) 7846 throws PackageManagerException { 7847 final boolean shouldHaveCode = 7848 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 7849 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 7850 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7851 "Package " + pkg.baseCodePath + " code is missing"); 7852 } 7853 7854 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 7855 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 7856 final boolean splitShouldHaveCode = 7857 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 7858 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 7859 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7860 "Package " + pkg.splitCodePaths[i] + " code is missing"); 7861 } 7862 } 7863 } 7864 } 7865 scanPackageDirtyLI(PackageParser.Package pkg, final int policyFlags, final int scanFlags, long currentTime, UserHandle user)7866 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 7867 final int policyFlags, final int scanFlags, long currentTime, UserHandle user) 7868 throws PackageManagerException { 7869 final File scanFile = new File(pkg.codePath); 7870 if (pkg.applicationInfo.getCodePath() == null || 7871 pkg.applicationInfo.getResourcePath() == null) { 7872 // Bail out. The resource and code paths haven't been set. 7873 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7874 "Code and resource paths haven't been set correctly"); 7875 } 7876 7877 // Apply policy 7878 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 7879 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 7880 if (pkg.applicationInfo.isDirectBootAware()) { 7881 // we're direct boot aware; set for all components 7882 for (PackageParser.Service s : pkg.services) { 7883 s.info.encryptionAware = s.info.directBootAware = true; 7884 } 7885 for (PackageParser.Provider p : pkg.providers) { 7886 p.info.encryptionAware = p.info.directBootAware = true; 7887 } 7888 for (PackageParser.Activity a : pkg.activities) { 7889 a.info.encryptionAware = a.info.directBootAware = true; 7890 } 7891 for (PackageParser.Activity r : pkg.receivers) { 7892 r.info.encryptionAware = r.info.directBootAware = true; 7893 } 7894 } 7895 } else { 7896 // Only allow system apps to be flagged as core apps. 7897 pkg.coreApp = false; 7898 // clear flags not applicable to regular apps 7899 pkg.applicationInfo.privateFlags &= 7900 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 7901 pkg.applicationInfo.privateFlags &= 7902 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 7903 } 7904 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 7905 7906 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 7907 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7908 } 7909 7910 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 7911 enforceCodePolicy(pkg); 7912 } 7913 7914 if (mCustomResolverComponentName != null && 7915 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 7916 setUpCustomResolverActivity(pkg); 7917 } 7918 7919 if (pkg.packageName.equals("android")) { 7920 synchronized (mPackages) { 7921 if (mAndroidApplication != null) { 7922 Slog.w(TAG, "*************************************************"); 7923 Slog.w(TAG, "Core android package being redefined. Skipping."); 7924 Slog.w(TAG, " file=" + scanFile); 7925 Slog.w(TAG, "*************************************************"); 7926 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7927 "Core android package being redefined. Skipping."); 7928 } 7929 7930 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7931 // Set up information for our fall-back user intent resolution activity. 7932 mPlatformPackage = pkg; 7933 pkg.mVersionCode = mSdkVersion; 7934 mAndroidApplication = pkg.applicationInfo; 7935 7936 if (!mResolverReplaced) { 7937 mResolveActivity.applicationInfo = mAndroidApplication; 7938 mResolveActivity.name = ResolverActivity.class.getName(); 7939 mResolveActivity.packageName = mAndroidApplication.packageName; 7940 mResolveActivity.processName = "system:ui"; 7941 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7942 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 7943 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 7944 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 7945 mResolveActivity.exported = true; 7946 mResolveActivity.enabled = true; 7947 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 7948 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 7949 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 7950 | ActivityInfo.CONFIG_SCREEN_LAYOUT 7951 | ActivityInfo.CONFIG_ORIENTATION 7952 | ActivityInfo.CONFIG_KEYBOARD 7953 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 7954 mResolveInfo.activityInfo = mResolveActivity; 7955 mResolveInfo.priority = 0; 7956 mResolveInfo.preferredOrder = 0; 7957 mResolveInfo.match = 0; 7958 mResolveComponentName = new ComponentName( 7959 mAndroidApplication.packageName, mResolveActivity.name); 7960 } 7961 } 7962 } 7963 } 7964 7965 if (DEBUG_PACKAGE_SCANNING) { 7966 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 7967 Log.d(TAG, "Scanning package " + pkg.packageName); 7968 } 7969 7970 synchronized (mPackages) { 7971 if (mPackages.containsKey(pkg.packageName) 7972 || mSharedLibraries.containsKey(pkg.packageName)) { 7973 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7974 "Application package " + pkg.packageName 7975 + " already installed. Skipping duplicate."); 7976 } 7977 7978 // If we're only installing presumed-existing packages, require that the 7979 // scanned APK is both already known and at the path previously established 7980 // for it. Previously unknown packages we pick up normally, but if we have an 7981 // a priori expectation about this package's install presence, enforce it. 7982 // With a singular exception for new system packages. When an OTA contains 7983 // a new system package, we allow the codepath to change from a system location 7984 // to the user-installed location. If we don't allow this change, any newer, 7985 // user-installed version of the application will be ignored. 7986 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 7987 if (mExpectingBetter.containsKey(pkg.packageName)) { 7988 logCriticalInfo(Log.WARN, 7989 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 7990 } else { 7991 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 7992 if (known != null) { 7993 if (DEBUG_PACKAGE_SCANNING) { 7994 Log.d(TAG, "Examining " + pkg.codePath 7995 + " and requiring known paths " + known.codePathString 7996 + " & " + known.resourcePathString); 7997 } 7998 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 7999 || !pkg.applicationInfo.getResourcePath().equals( 8000 known.resourcePathString)) { 8001 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 8002 "Application package " + pkg.packageName 8003 + " found at " + pkg.applicationInfo.getCodePath() 8004 + " but expected at " + known.codePathString 8005 + "; ignoring."); 8006 } 8007 } 8008 } 8009 } 8010 } 8011 8012 // Initialize package source and resource directories 8013 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 8014 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 8015 8016 SharedUserSetting suid = null; 8017 PackageSetting pkgSetting = null; 8018 8019 if (!isSystemApp(pkg)) { 8020 // Only system apps can use these features. 8021 pkg.mOriginalPackages = null; 8022 pkg.mRealPackage = null; 8023 pkg.mAdoptPermissions = null; 8024 } 8025 8026 // Getting the package setting may have a side-effect, so if we 8027 // are only checking if scan would succeed, stash a copy of the 8028 // old setting to restore at the end. 8029 PackageSetting nonMutatedPs = null; 8030 8031 // writer 8032 synchronized (mPackages) { 8033 if (pkg.mSharedUserId != null) { 8034 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 8035 if (suid == null) { 8036 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 8037 "Creating application package " + pkg.packageName 8038 + " for shared user failed"); 8039 } 8040 if (DEBUG_PACKAGE_SCANNING) { 8041 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8042 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 8043 + "): packages=" + suid.packages); 8044 } 8045 } 8046 8047 // Check if we are renaming from an original package name. 8048 PackageSetting origPackage = null; 8049 String realName = null; 8050 if (pkg.mOriginalPackages != null) { 8051 // This package may need to be renamed to a previously 8052 // installed name. Let's check on that... 8053 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 8054 if (pkg.mOriginalPackages.contains(renamed)) { 8055 // This package had originally been installed as the 8056 // original name, and we have already taken care of 8057 // transitioning to the new one. Just update the new 8058 // one to continue using the old name. 8059 realName = pkg.mRealPackage; 8060 if (!pkg.packageName.equals(renamed)) { 8061 // Callers into this function may have already taken 8062 // care of renaming the package; only do it here if 8063 // it is not already done. 8064 pkg.setPackageName(renamed); 8065 } 8066 8067 } else { 8068 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 8069 if ((origPackage = mSettings.peekPackageLPr( 8070 pkg.mOriginalPackages.get(i))) != null) { 8071 // We do have the package already installed under its 8072 // original name... should we use it? 8073 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 8074 // New package is not compatible with original. 8075 origPackage = null; 8076 continue; 8077 } else if (origPackage.sharedUser != null) { 8078 // Make sure uid is compatible between packages. 8079 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 8080 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 8081 + " to " + pkg.packageName + ": old uid " 8082 + origPackage.sharedUser.name 8083 + " differs from " + pkg.mSharedUserId); 8084 origPackage = null; 8085 continue; 8086 } 8087 // TODO: Add case when shared user id is added [b/28144775] 8088 } else { 8089 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 8090 + pkg.packageName + " to old name " + origPackage.name); 8091 } 8092 break; 8093 } 8094 } 8095 } 8096 } 8097 8098 if (mTransferedPackages.contains(pkg.packageName)) { 8099 Slog.w(TAG, "Package " + pkg.packageName 8100 + " was transferred to another, but its .apk remains"); 8101 } 8102 8103 // See comments in nonMutatedPs declaration 8104 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8105 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 8106 if (foundPs != null) { 8107 nonMutatedPs = new PackageSetting(foundPs); 8108 } 8109 } 8110 8111 // Just create the setting, don't add it yet. For already existing packages 8112 // the PkgSetting exists already and doesn't have to be created. 8113 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 8114 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 8115 pkg.applicationInfo.primaryCpuAbi, 8116 pkg.applicationInfo.secondaryCpuAbi, 8117 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 8118 user, false); 8119 if (pkgSetting == null) { 8120 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 8121 "Creating application package " + pkg.packageName + " failed"); 8122 } 8123 8124 if (pkgSetting.origPackage != null) { 8125 // If we are first transitioning from an original package, 8126 // fix up the new package's name now. We need to do this after 8127 // looking up the package under its new name, so getPackageLP 8128 // can take care of fiddling things correctly. 8129 pkg.setPackageName(origPackage.name); 8130 8131 // File a report about this. 8132 String msg = "New package " + pkgSetting.realName 8133 + " renamed to replace old package " + pkgSetting.name; 8134 reportSettingsProblem(Log.WARN, msg); 8135 8136 // Make a note of it. 8137 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8138 mTransferedPackages.add(origPackage.name); 8139 } 8140 8141 // No longer need to retain this. 8142 pkgSetting.origPackage = null; 8143 } 8144 8145 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 8146 // Make a note of it. 8147 mTransferedPackages.add(pkg.packageName); 8148 } 8149 8150 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 8151 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 8152 } 8153 8154 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8155 // Check all shared libraries and map to their actual file path. 8156 // We only do this here for apps not on a system dir, because those 8157 // are the only ones that can fail an install due to this. We 8158 // will take care of the system apps by updating all of their 8159 // library paths after the scan is done. 8160 updateSharedLibrariesLPw(pkg, null); 8161 } 8162 8163 if (mFoundPolicyFile) { 8164 SELinuxMMAC.assignSeinfoValue(pkg); 8165 } 8166 8167 pkg.applicationInfo.uid = pkgSetting.appId; 8168 pkg.mExtras = pkgSetting; 8169 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 8170 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 8171 // We just determined the app is signed correctly, so bring 8172 // over the latest parsed certs. 8173 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8174 } else { 8175 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8176 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8177 "Package " + pkg.packageName + " upgrade keys do not match the " 8178 + "previously installed version"); 8179 } else { 8180 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8181 String msg = "System package " + pkg.packageName 8182 + " signature changed; retaining data."; 8183 reportSettingsProblem(Log.WARN, msg); 8184 } 8185 } 8186 } else { 8187 try { 8188 verifySignaturesLP(pkgSetting, pkg); 8189 // We just determined the app is signed correctly, so bring 8190 // over the latest parsed certs. 8191 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8192 } catch (PackageManagerException e) { 8193 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8194 throw e; 8195 } 8196 // The signature has changed, but this package is in the system 8197 // image... let's recover! 8198 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8199 // However... if this package is part of a shared user, but it 8200 // doesn't match the signature of the shared user, let's fail. 8201 // What this means is that you can't change the signatures 8202 // associated with an overall shared user, which doesn't seem all 8203 // that unreasonable. 8204 if (pkgSetting.sharedUser != null) { 8205 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 8206 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 8207 throw new PackageManagerException( 8208 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 8209 "Signature mismatch for shared user: " 8210 + pkgSetting.sharedUser); 8211 } 8212 } 8213 // File a report about this. 8214 String msg = "System package " + pkg.packageName 8215 + " signature changed; retaining data."; 8216 reportSettingsProblem(Log.WARN, msg); 8217 } 8218 } 8219 // Verify that this new package doesn't have any content providers 8220 // that conflict with existing packages. Only do this if the 8221 // package isn't already installed, since we don't want to break 8222 // things that are installed. 8223 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 8224 final int N = pkg.providers.size(); 8225 int i; 8226 for (i=0; i<N; i++) { 8227 PackageParser.Provider p = pkg.providers.get(i); 8228 if (p.info.authority != null) { 8229 String names[] = p.info.authority.split(";"); 8230 for (int j = 0; j < names.length; j++) { 8231 if (mProvidersByAuthority.containsKey(names[j])) { 8232 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8233 final String otherPackageName = 8234 ((other != null && other.getComponentName() != null) ? 8235 other.getComponentName().getPackageName() : "?"); 8236 throw new PackageManagerException( 8237 INSTALL_FAILED_CONFLICTING_PROVIDER, 8238 "Can't install because provider name " + names[j] 8239 + " (in package " + pkg.applicationInfo.packageName 8240 + ") is already used by " + otherPackageName); 8241 } 8242 } 8243 } 8244 } 8245 } 8246 8247 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 8248 // This package wants to adopt ownership of permissions from 8249 // another package. 8250 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 8251 final String origName = pkg.mAdoptPermissions.get(i); 8252 final PackageSetting orig = mSettings.peekPackageLPr(origName); 8253 if (orig != null) { 8254 if (verifyPackageUpdateLPr(orig, pkg)) { 8255 Slog.i(TAG, "Adopting permissions from " + origName + " to " 8256 + pkg.packageName); 8257 mSettings.transferPermissionsLPw(origName, pkg.packageName); 8258 } 8259 } 8260 } 8261 } 8262 } 8263 8264 final String pkgName = pkg.packageName; 8265 8266 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 8267 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 8268 pkg.applicationInfo.processName = fixProcessName( 8269 pkg.applicationInfo.packageName, 8270 pkg.applicationInfo.processName, 8271 pkg.applicationInfo.uid); 8272 8273 if (pkg != mPlatformPackage) { 8274 // Get all of our default paths setup 8275 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 8276 } 8277 8278 final String path = scanFile.getPath(); 8279 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 8280 8281 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 8282 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 8283 8284 // Some system apps still use directory structure for native libraries 8285 // in which case we might end up not detecting abi solely based on apk 8286 // structure. Try to detect abi based on directory structure. 8287 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 8288 pkg.applicationInfo.primaryCpuAbi == null) { 8289 setBundledAppAbisAndRoots(pkg, pkgSetting); 8290 setNativeLibraryPaths(pkg); 8291 } 8292 8293 } else { 8294 if ((scanFlags & SCAN_MOVE) != 0) { 8295 // We haven't run dex-opt for this move (since we've moved the compiled output too) 8296 // but we already have this packages package info in the PackageSetting. We just 8297 // use that and derive the native library path based on the new codepath. 8298 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 8299 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 8300 } 8301 8302 // Set native library paths again. For moves, the path will be updated based on the 8303 // ABIs we've determined above. For non-moves, the path will be updated based on the 8304 // ABIs we determined during compilation, but the path will depend on the final 8305 // package path (after the rename away from the stage path). 8306 setNativeLibraryPaths(pkg); 8307 } 8308 8309 // This is a special case for the "system" package, where the ABI is 8310 // dictated by the zygote configuration (and init.rc). We should keep track 8311 // of this ABI so that we can deal with "normal" applications that run under 8312 // the same UID correctly. 8313 if (mPlatformPackage == pkg) { 8314 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 8315 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 8316 } 8317 8318 // If there's a mismatch between the abi-override in the package setting 8319 // and the abiOverride specified for the install. Warn about this because we 8320 // would've already compiled the app without taking the package setting into 8321 // account. 8322 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 8323 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 8324 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 8325 " for package " + pkg.packageName); 8326 } 8327 } 8328 8329 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8330 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8331 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 8332 8333 // Copy the derived override back to the parsed package, so that we can 8334 // update the package settings accordingly. 8335 pkg.cpuAbiOverride = cpuAbiOverride; 8336 8337 if (DEBUG_ABI_SELECTION) { 8338 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 8339 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 8340 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 8341 } 8342 8343 // Push the derived path down into PackageSettings so we know what to 8344 // clean up at uninstall time. 8345 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 8346 8347 if (DEBUG_ABI_SELECTION) { 8348 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 8349 " primary=" + pkg.applicationInfo.primaryCpuAbi + 8350 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 8351 } 8352 8353 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 8354 // We don't do this here during boot because we can do it all 8355 // at once after scanning all existing packages. 8356 // 8357 // We also do this *before* we perform dexopt on this package, so that 8358 // we can avoid redundant dexopts, and also to make sure we've got the 8359 // code and package path correct. 8360 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 8361 pkg, true /* boot complete */); 8362 } 8363 8364 if (mFactoryTest && pkg.requestedPermissions.contains( 8365 android.Manifest.permission.FACTORY_TEST)) { 8366 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 8367 } 8368 8369 ArrayList<PackageParser.Package> clientLibPkgs = null; 8370 8371 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8372 if (nonMutatedPs != null) { 8373 synchronized (mPackages) { 8374 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 8375 } 8376 } 8377 return pkg; 8378 } 8379 8380 // Only privileged apps and updated privileged apps can add child packages. 8381 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 8382 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 8383 throw new PackageManagerException("Only privileged apps and updated " 8384 + "privileged apps can add child packages. Ignoring package " 8385 + pkg.packageName); 8386 } 8387 final int childCount = pkg.childPackages.size(); 8388 for (int i = 0; i < childCount; i++) { 8389 PackageParser.Package childPkg = pkg.childPackages.get(i); 8390 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 8391 childPkg.packageName)) { 8392 throw new PackageManagerException("Cannot override a child package of " 8393 + "another disabled system app. Ignoring package " + pkg.packageName); 8394 } 8395 } 8396 } 8397 8398 // writer 8399 synchronized (mPackages) { 8400 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8401 // Only system apps can add new shared libraries. 8402 if (pkg.libraryNames != null) { 8403 for (int i=0; i<pkg.libraryNames.size(); i++) { 8404 String name = pkg.libraryNames.get(i); 8405 boolean allowed = false; 8406 if (pkg.isUpdatedSystemApp()) { 8407 // New library entries can only be added through the 8408 // system image. This is important to get rid of a lot 8409 // of nasty edge cases: for example if we allowed a non- 8410 // system update of the app to add a library, then uninstalling 8411 // the update would make the library go away, and assumptions 8412 // we made such as through app install filtering would now 8413 // have allowed apps on the device which aren't compatible 8414 // with it. Better to just have the restriction here, be 8415 // conservative, and create many fewer cases that can negatively 8416 // impact the user experience. 8417 final PackageSetting sysPs = mSettings 8418 .getDisabledSystemPkgLPr(pkg.packageName); 8419 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 8420 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 8421 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 8422 allowed = true; 8423 break; 8424 } 8425 } 8426 } 8427 } else { 8428 allowed = true; 8429 } 8430 if (allowed) { 8431 if (!mSharedLibraries.containsKey(name)) { 8432 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 8433 } else if (!name.equals(pkg.packageName)) { 8434 Slog.w(TAG, "Package " + pkg.packageName + " library " 8435 + name + " already exists; skipping"); 8436 } 8437 } else { 8438 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 8439 + name + " that is not declared on system image; skipping"); 8440 } 8441 } 8442 if ((scanFlags & SCAN_BOOTING) == 0) { 8443 // If we are not booting, we need to update any applications 8444 // that are clients of our shared library. If we are booting, 8445 // this will all be done once the scan is complete. 8446 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 8447 } 8448 } 8449 } 8450 } 8451 8452 if ((scanFlags & SCAN_BOOTING) != 0) { 8453 // No apps can run during boot scan, so they don't need to be frozen 8454 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 8455 // Caller asked to not kill app, so it's probably not frozen 8456 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 8457 // Caller asked us to ignore frozen check for some reason; they 8458 // probably didn't know the package name 8459 } else { 8460 // We're doing major surgery on this package, so it better be frozen 8461 // right now to keep it from launching 8462 checkPackageFrozen(pkgName); 8463 } 8464 8465 // Also need to kill any apps that are dependent on the library. 8466 if (clientLibPkgs != null) { 8467 for (int i=0; i<clientLibPkgs.size(); i++) { 8468 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8469 killApplication(clientPkg.applicationInfo.packageName, 8470 clientPkg.applicationInfo.uid, "update lib"); 8471 } 8472 } 8473 8474 // Make sure we're not adding any bogus keyset info 8475 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8476 ksms.assertScannedPackageValid(pkg); 8477 8478 // writer 8479 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8480 8481 boolean createIdmapFailed = false; 8482 synchronized (mPackages) { 8483 // We don't expect installation to fail beyond this point 8484 8485 if (pkgSetting.pkg != null) { 8486 // Note that |user| might be null during the initial boot scan. If a codePath 8487 // for an app has changed during a boot scan, it's due to an app update that's 8488 // part of the system partition and marker changes must be applied to all users. 8489 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, 8490 (user != null) ? user : UserHandle.ALL); 8491 } 8492 8493 // Add the new setting to mSettings 8494 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8495 // Add the new setting to mPackages 8496 mPackages.put(pkg.applicationInfo.packageName, pkg); 8497 // Make sure we don't accidentally delete its data. 8498 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8499 while (iter.hasNext()) { 8500 PackageCleanItem item = iter.next(); 8501 if (pkgName.equals(item.packageName)) { 8502 iter.remove(); 8503 } 8504 } 8505 8506 // Take care of first install / last update times. 8507 if (currentTime != 0) { 8508 if (pkgSetting.firstInstallTime == 0) { 8509 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8510 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 8511 pkgSetting.lastUpdateTime = currentTime; 8512 } 8513 } else if (pkgSetting.firstInstallTime == 0) { 8514 // We need *something*. Take time time stamp of the file. 8515 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8516 } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8517 if (scanFileTime != pkgSetting.timeStamp) { 8518 // A package on the system image has changed; consider this 8519 // to be an update. 8520 pkgSetting.lastUpdateTime = scanFileTime; 8521 } 8522 } 8523 8524 // Add the package's KeySets to the global KeySetManagerService 8525 ksms.addScannedPackageLPw(pkg); 8526 8527 int N = pkg.providers.size(); 8528 StringBuilder r = null; 8529 int i; 8530 for (i=0; i<N; i++) { 8531 PackageParser.Provider p = pkg.providers.get(i); 8532 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8533 p.info.processName, pkg.applicationInfo.uid); 8534 mProviders.addProvider(p); 8535 p.syncable = p.info.isSyncable; 8536 if (p.info.authority != null) { 8537 String names[] = p.info.authority.split(";"); 8538 p.info.authority = null; 8539 for (int j = 0; j < names.length; j++) { 8540 if (j == 1 && p.syncable) { 8541 // We only want the first authority for a provider to possibly be 8542 // syncable, so if we already added this provider using a different 8543 // authority clear the syncable flag. We copy the provider before 8544 // changing it because the mProviders object contains a reference 8545 // to a provider that we don't want to change. 8546 // Only do this for the second authority since the resulting provider 8547 // object can be the same for all future authorities for this provider. 8548 p = new PackageParser.Provider(p); 8549 p.syncable = false; 8550 } 8551 if (!mProvidersByAuthority.containsKey(names[j])) { 8552 mProvidersByAuthority.put(names[j], p); 8553 if (p.info.authority == null) { 8554 p.info.authority = names[j]; 8555 } else { 8556 p.info.authority = p.info.authority + ";" + names[j]; 8557 } 8558 if (DEBUG_PACKAGE_SCANNING) { 8559 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8560 Log.d(TAG, "Registered content provider: " + names[j] 8561 + ", className = " + p.info.name + ", isSyncable = " 8562 + p.info.isSyncable); 8563 } 8564 } else { 8565 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8566 Slog.w(TAG, "Skipping provider name " + names[j] + 8567 " (in package " + pkg.applicationInfo.packageName + 8568 "): name already used by " 8569 + ((other != null && other.getComponentName() != null) 8570 ? other.getComponentName().getPackageName() : "?")); 8571 } 8572 } 8573 } 8574 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8575 if (r == null) { 8576 r = new StringBuilder(256); 8577 } else { 8578 r.append(' '); 8579 } 8580 r.append(p.info.name); 8581 } 8582 } 8583 if (r != null) { 8584 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8585 } 8586 8587 N = pkg.services.size(); 8588 r = null; 8589 for (i=0; i<N; i++) { 8590 PackageParser.Service s = pkg.services.get(i); 8591 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8592 s.info.processName, pkg.applicationInfo.uid); 8593 mServices.addService(s); 8594 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8595 if (r == null) { 8596 r = new StringBuilder(256); 8597 } else { 8598 r.append(' '); 8599 } 8600 r.append(s.info.name); 8601 } 8602 } 8603 if (r != null) { 8604 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8605 } 8606 8607 N = pkg.receivers.size(); 8608 r = null; 8609 for (i=0; i<N; i++) { 8610 PackageParser.Activity a = pkg.receivers.get(i); 8611 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8612 a.info.processName, pkg.applicationInfo.uid); 8613 mReceivers.addActivity(a, "receiver"); 8614 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8615 if (r == null) { 8616 r = new StringBuilder(256); 8617 } else { 8618 r.append(' '); 8619 } 8620 r.append(a.info.name); 8621 } 8622 } 8623 if (r != null) { 8624 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8625 } 8626 8627 N = pkg.activities.size(); 8628 r = null; 8629 for (i=0; i<N; i++) { 8630 PackageParser.Activity a = pkg.activities.get(i); 8631 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8632 a.info.processName, pkg.applicationInfo.uid); 8633 mActivities.addActivity(a, "activity"); 8634 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8635 if (r == null) { 8636 r = new StringBuilder(256); 8637 } else { 8638 r.append(' '); 8639 } 8640 r.append(a.info.name); 8641 } 8642 } 8643 if (r != null) { 8644 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8645 } 8646 8647 N = pkg.permissionGroups.size(); 8648 r = null; 8649 for (i=0; i<N; i++) { 8650 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8651 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8652 if (cur == null) { 8653 mPermissionGroups.put(pg.info.name, pg); 8654 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8655 if (r == null) { 8656 r = new StringBuilder(256); 8657 } else { 8658 r.append(' '); 8659 } 8660 r.append(pg.info.name); 8661 } 8662 } else { 8663 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8664 + pg.info.packageName + " ignored: original from " 8665 + cur.info.packageName); 8666 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8667 if (r == null) { 8668 r = new StringBuilder(256); 8669 } else { 8670 r.append(' '); 8671 } 8672 r.append("DUP:"); 8673 r.append(pg.info.name); 8674 } 8675 } 8676 } 8677 if (r != null) { 8678 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8679 } 8680 8681 N = pkg.permissions.size(); 8682 r = null; 8683 for (i=0; i<N; i++) { 8684 PackageParser.Permission p = pkg.permissions.get(i); 8685 8686 // Assume by default that we did not install this permission into the system. 8687 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8688 8689 // Now that permission groups have a special meaning, we ignore permission 8690 // groups for legacy apps to prevent unexpected behavior. In particular, 8691 // permissions for one app being granted to someone just becase they happen 8692 // to be in a group defined by another app (before this had no implications). 8693 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8694 p.group = mPermissionGroups.get(p.info.group); 8695 // Warn for a permission in an unknown group. 8696 if (p.info.group != null && p.group == null) { 8697 Slog.w(TAG, "Permission " + p.info.name + " from package " 8698 + p.info.packageName + " in an unknown group " + p.info.group); 8699 } 8700 } 8701 8702 ArrayMap<String, BasePermission> permissionMap = 8703 p.tree ? mSettings.mPermissionTrees 8704 : mSettings.mPermissions; 8705 BasePermission bp = permissionMap.get(p.info.name); 8706 8707 // Allow system apps to redefine non-system permissions 8708 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8709 final boolean currentOwnerIsSystem = (bp.perm != null 8710 && isSystemApp(bp.perm.owner)); 8711 if (isSystemApp(p.owner)) { 8712 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8713 // It's a built-in permission and no owner, take ownership now 8714 bp.packageSetting = pkgSetting; 8715 bp.perm = p; 8716 bp.uid = pkg.applicationInfo.uid; 8717 bp.sourcePackage = p.info.packageName; 8718 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8719 } else if (!currentOwnerIsSystem) { 8720 String msg = "New decl " + p.owner + " of permission " 8721 + p.info.name + " is system; overriding " + bp.sourcePackage; 8722 reportSettingsProblem(Log.WARN, msg); 8723 bp = null; 8724 } 8725 } 8726 } 8727 8728 if (bp == null) { 8729 bp = new BasePermission(p.info.name, p.info.packageName, 8730 BasePermission.TYPE_NORMAL); 8731 permissionMap.put(p.info.name, bp); 8732 } 8733 8734 if (bp.perm == null) { 8735 if (bp.sourcePackage == null 8736 || bp.sourcePackage.equals(p.info.packageName)) { 8737 BasePermission tree = findPermissionTreeLP(p.info.name); 8738 if (tree == null 8739 || tree.sourcePackage.equals(p.info.packageName)) { 8740 bp.packageSetting = pkgSetting; 8741 bp.perm = p; 8742 bp.uid = pkg.applicationInfo.uid; 8743 bp.sourcePackage = p.info.packageName; 8744 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8745 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8746 if (r == null) { 8747 r = new StringBuilder(256); 8748 } else { 8749 r.append(' '); 8750 } 8751 r.append(p.info.name); 8752 } 8753 } else { 8754 Slog.w(TAG, "Permission " + p.info.name + " from package " 8755 + p.info.packageName + " ignored: base tree " 8756 + tree.name + " is from package " 8757 + tree.sourcePackage); 8758 } 8759 } else { 8760 Slog.w(TAG, "Permission " + p.info.name + " from package " 8761 + p.info.packageName + " ignored: original from " 8762 + bp.sourcePackage); 8763 } 8764 } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8765 if (r == null) { 8766 r = new StringBuilder(256); 8767 } else { 8768 r.append(' '); 8769 } 8770 r.append("DUP:"); 8771 r.append(p.info.name); 8772 } 8773 if (bp.perm == p) { 8774 bp.protectionLevel = p.info.protectionLevel; 8775 } 8776 } 8777 8778 if (r != null) { 8779 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8780 } 8781 8782 N = pkg.instrumentation.size(); 8783 r = null; 8784 for (i=0; i<N; i++) { 8785 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8786 a.info.packageName = pkg.applicationInfo.packageName; 8787 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8788 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8789 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8790 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8791 a.info.dataDir = pkg.applicationInfo.dataDir; 8792 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 8793 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 8794 8795 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8796 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 8797 mInstrumentation.put(a.getComponentName(), a); 8798 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8799 if (r == null) { 8800 r = new StringBuilder(256); 8801 } else { 8802 r.append(' '); 8803 } 8804 r.append(a.info.name); 8805 } 8806 } 8807 if (r != null) { 8808 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8809 } 8810 8811 if (pkg.protectedBroadcasts != null) { 8812 N = pkg.protectedBroadcasts.size(); 8813 for (i=0; i<N; i++) { 8814 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8815 } 8816 } 8817 8818 pkgSetting.setTimeStamp(scanFileTime); 8819 8820 // Create idmap files for pairs of (packages, overlay packages). 8821 // Note: "android", ie framework-res.apk, is handled by native layers. 8822 if (pkg.mOverlayTarget != null) { 8823 // This is an overlay package. 8824 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8825 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8826 mOverlays.put(pkg.mOverlayTarget, 8827 new ArrayMap<String, PackageParser.Package>()); 8828 } 8829 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8830 map.put(pkg.packageName, pkg); 8831 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8832 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8833 createIdmapFailed = true; 8834 } 8835 } 8836 } else if (mOverlays.containsKey(pkg.packageName) && 8837 !pkg.packageName.equals("android")) { 8838 // This is a regular package, with one or more known overlay packages. 8839 createIdmapsForPackageLI(pkg); 8840 } 8841 } 8842 8843 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8844 8845 if (createIdmapFailed) { 8846 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8847 "scanPackageLI failed to createIdmap"); 8848 } 8849 return pkg; 8850 } 8851 maybeRenameForeignDexMarkers(PackageParser.Package existing, PackageParser.Package update, UserHandle user)8852 private void maybeRenameForeignDexMarkers(PackageParser.Package existing, 8853 PackageParser.Package update, UserHandle user) { 8854 if (existing.applicationInfo == null || update.applicationInfo == null) { 8855 // This isn't due to an app installation. 8856 return; 8857 } 8858 8859 final File oldCodePath = new File(existing.applicationInfo.getCodePath()); 8860 final File newCodePath = new File(update.applicationInfo.getCodePath()); 8861 8862 // The codePath hasn't changed, so there's nothing for us to do. 8863 if (Objects.equals(oldCodePath, newCodePath)) { 8864 return; 8865 } 8866 8867 File canonicalNewCodePath; 8868 try { 8869 canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath)); 8870 } catch (IOException e) { 8871 Slog.w(TAG, "Failed to get canonical path.", e); 8872 return; 8873 } 8874 8875 // This is a bit of a hack. The oldCodePath doesn't exist at this point (because 8876 // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume 8877 // that the last component of the path (i.e, the name) doesn't need canonicalization 8878 // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now 8879 // but may change in the future. Hopefully this function won't exist at that point. 8880 final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(), 8881 oldCodePath.getName()); 8882 8883 // Calculate the prefixes of the markers. These are just the paths with "/" replaced 8884 // with "@". 8885 String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@'); 8886 if (!oldMarkerPrefix.endsWith("@")) { 8887 oldMarkerPrefix += "@"; 8888 } 8889 String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@'); 8890 if (!newMarkerPrefix.endsWith("@")) { 8891 newMarkerPrefix += "@"; 8892 } 8893 8894 List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly(); 8895 List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size()); 8896 for (String updatedPath : updatedPaths) { 8897 String updatedPathName = new File(updatedPath).getName(); 8898 markerSuffixes.add(updatedPathName.replace('/', '@')); 8899 } 8900 8901 for (int userId : resolveUserIds(user.getIdentifier())) { 8902 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId); 8903 8904 for (String markerSuffix : markerSuffixes) { 8905 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix); 8906 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix); 8907 if (oldForeignUseMark.exists()) { 8908 try { 8909 Os.rename(oldForeignUseMark.getAbsolutePath(), 8910 newForeignUseMark.getAbsolutePath()); 8911 } catch (ErrnoException e) { 8912 Slog.w(TAG, "Failed to rename foreign use marker", e); 8913 oldForeignUseMark.delete(); 8914 } 8915 } 8916 } 8917 } 8918 } 8919 8920 /** 8921 * Derive the ABI of a non-system package located at {@code scanFile}. This information 8922 * is derived purely on the basis of the contents of {@code scanFile} and 8923 * {@code cpuAbiOverride}. 8924 * 8925 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 8926 */ derivePackageAbi(PackageParser.Package pkg, File scanFile, String cpuAbiOverride, boolean extractLibs)8927 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 8928 String cpuAbiOverride, boolean extractLibs) 8929 throws PackageManagerException { 8930 // TODO: We can probably be smarter about this stuff. For installed apps, 8931 // we can calculate this information at install time once and for all. For 8932 // system apps, we can probably assume that this information doesn't change 8933 // after the first boot scan. As things stand, we do lots of unnecessary work. 8934 8935 // Give ourselves some initial paths; we'll come back for another 8936 // pass once we've determined ABI below. 8937 setNativeLibraryPaths(pkg); 8938 8939 // We would never need to extract libs for forward-locked and external packages, 8940 // since the container service will do it for us. We shouldn't attempt to 8941 // extract libs from system app when it was not updated. 8942 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 8943 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 8944 extractLibs = false; 8945 } 8946 8947 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 8948 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 8949 8950 NativeLibraryHelper.Handle handle = null; 8951 try { 8952 handle = NativeLibraryHelper.Handle.create(pkg); 8953 // TODO(multiArch): This can be null for apps that didn't go through the 8954 // usual installation process. We can calculate it again, like we 8955 // do during install time. 8956 // 8957 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 8958 // unnecessary. 8959 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 8960 8961 // Null out the abis so that they can be recalculated. 8962 pkg.applicationInfo.primaryCpuAbi = null; 8963 pkg.applicationInfo.secondaryCpuAbi = null; 8964 if (isMultiArch(pkg.applicationInfo)) { 8965 // Warn if we've set an abiOverride for multi-lib packages.. 8966 // By definition, we need to copy both 32 and 64 bit libraries for 8967 // such packages. 8968 if (pkg.cpuAbiOverride != null 8969 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 8970 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 8971 } 8972 8973 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 8974 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 8975 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 8976 if (extractLibs) { 8977 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8978 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 8979 useIsaSpecificSubdirs); 8980 } else { 8981 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 8982 } 8983 } 8984 8985 maybeThrowExceptionForMultiArchCopy( 8986 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 8987 8988 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 8989 if (extractLibs) { 8990 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8991 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 8992 useIsaSpecificSubdirs); 8993 } else { 8994 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 8995 } 8996 } 8997 8998 maybeThrowExceptionForMultiArchCopy( 8999 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 9000 9001 if (abi64 >= 0) { 9002 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 9003 } 9004 9005 if (abi32 >= 0) { 9006 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 9007 if (abi64 >= 0) { 9008 if (pkg.use32bitAbi) { 9009 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 9010 pkg.applicationInfo.primaryCpuAbi = abi; 9011 } else { 9012 pkg.applicationInfo.secondaryCpuAbi = abi; 9013 } 9014 } else { 9015 pkg.applicationInfo.primaryCpuAbi = abi; 9016 } 9017 } 9018 9019 } else { 9020 String[] abiList = (cpuAbiOverride != null) ? 9021 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 9022 9023 // Enable gross and lame hacks for apps that are built with old 9024 // SDK tools. We must scan their APKs for renderscript bitcode and 9025 // not launch them if it's present. Don't bother checking on devices 9026 // that don't have 64 bit support. 9027 boolean needsRenderScriptOverride = false; 9028 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 9029 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 9030 abiList = Build.SUPPORTED_32_BIT_ABIS; 9031 needsRenderScriptOverride = true; 9032 } 9033 9034 final int copyRet; 9035 if (extractLibs) { 9036 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9037 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 9038 } else { 9039 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 9040 } 9041 9042 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 9043 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 9044 "Error unpackaging native libs for app, errorCode=" + copyRet); 9045 } 9046 9047 if (copyRet >= 0) { 9048 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 9049 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 9050 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 9051 } else if (needsRenderScriptOverride) { 9052 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 9053 } 9054 } 9055 } catch (IOException ioe) { 9056 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 9057 } finally { 9058 IoUtils.closeQuietly(handle); 9059 } 9060 9061 // Now that we've calculated the ABIs and determined if it's an internal app, 9062 // we will go ahead and populate the nativeLibraryPath. 9063 setNativeLibraryPaths(pkg); 9064 } 9065 9066 /** 9067 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 9068 * i.e, so that all packages can be run inside a single process if required. 9069 * 9070 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 9071 * this function will either try and make the ABI for all packages in {@code packagesForUser} 9072 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 9073 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 9074 * updating a package that belongs to a shared user. 9075 * 9076 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 9077 * adds unnecessary complexity. 9078 */ adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage, boolean bootComplete)9079 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 9080 PackageParser.Package scannedPackage, boolean bootComplete) { 9081 String requiredInstructionSet = null; 9082 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 9083 requiredInstructionSet = VMRuntime.getInstructionSet( 9084 scannedPackage.applicationInfo.primaryCpuAbi); 9085 } 9086 9087 PackageSetting requirer = null; 9088 for (PackageSetting ps : packagesForUser) { 9089 // If packagesForUser contains scannedPackage, we skip it. This will happen 9090 // when scannedPackage is an update of an existing package. Without this check, 9091 // we will never be able to change the ABI of any package belonging to a shared 9092 // user, even if it's compatible with other packages. 9093 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9094 if (ps.primaryCpuAbiString == null) { 9095 continue; 9096 } 9097 9098 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 9099 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 9100 // We have a mismatch between instruction sets (say arm vs arm64) warn about 9101 // this but there's not much we can do. 9102 String errorMessage = "Instruction set mismatch, " 9103 + ((requirer == null) ? "[caller]" : requirer) 9104 + " requires " + requiredInstructionSet + " whereas " + ps 9105 + " requires " + instructionSet; 9106 Slog.w(TAG, errorMessage); 9107 } 9108 9109 if (requiredInstructionSet == null) { 9110 requiredInstructionSet = instructionSet; 9111 requirer = ps; 9112 } 9113 } 9114 } 9115 9116 if (requiredInstructionSet != null) { 9117 String adjustedAbi; 9118 if (requirer != null) { 9119 // requirer != null implies that either scannedPackage was null or that scannedPackage 9120 // did not require an ABI, in which case we have to adjust scannedPackage to match 9121 // the ABI of the set (which is the same as requirer's ABI) 9122 adjustedAbi = requirer.primaryCpuAbiString; 9123 if (scannedPackage != null) { 9124 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 9125 } 9126 } else { 9127 // requirer == null implies that we're updating all ABIs in the set to 9128 // match scannedPackage. 9129 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 9130 } 9131 9132 for (PackageSetting ps : packagesForUser) { 9133 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9134 if (ps.primaryCpuAbiString != null) { 9135 continue; 9136 } 9137 9138 ps.primaryCpuAbiString = adjustedAbi; 9139 if (ps.pkg != null && ps.pkg.applicationInfo != null && 9140 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 9141 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 9142 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 9143 + " (requirer=" 9144 + (requirer == null ? "null" : requirer.pkg.packageName) 9145 + ", scannedPackage=" 9146 + (scannedPackage != null ? scannedPackage.packageName : "null") 9147 + ")"); 9148 try { 9149 mInstaller.rmdex(ps.codePathString, 9150 getDexCodeInstructionSet(getPreferredInstructionSet())); 9151 } catch (InstallerException ignored) { 9152 } 9153 } 9154 } 9155 } 9156 } 9157 } 9158 setUpCustomResolverActivity(PackageParser.Package pkg)9159 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 9160 synchronized (mPackages) { 9161 mResolverReplaced = true; 9162 // Set up information for custom user intent resolution activity. 9163 mResolveActivity.applicationInfo = pkg.applicationInfo; 9164 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 9165 mResolveActivity.packageName = pkg.applicationInfo.packageName; 9166 mResolveActivity.processName = pkg.applicationInfo.packageName; 9167 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9168 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 9169 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9170 mResolveActivity.theme = 0; 9171 mResolveActivity.exported = true; 9172 mResolveActivity.enabled = true; 9173 mResolveInfo.activityInfo = mResolveActivity; 9174 mResolveInfo.priority = 0; 9175 mResolveInfo.preferredOrder = 0; 9176 mResolveInfo.match = 0; 9177 mResolveComponentName = mCustomResolverComponentName; 9178 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 9179 mResolveComponentName); 9180 } 9181 } 9182 setUpEphemeralInstallerActivityLP(ComponentName installerComponent)9183 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 9184 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 9185 9186 // Set up information for ephemeral installer activity 9187 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 9188 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 9189 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 9190 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 9191 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9192 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 9193 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9194 mEphemeralInstallerActivity.theme = 0; 9195 mEphemeralInstallerActivity.exported = true; 9196 mEphemeralInstallerActivity.enabled = true; 9197 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 9198 mEphemeralInstallerInfo.priority = 0; 9199 mEphemeralInstallerInfo.preferredOrder = 0; 9200 mEphemeralInstallerInfo.match = 0; 9201 9202 if (DEBUG_EPHEMERAL) { 9203 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 9204 } 9205 } 9206 calculateBundledApkRoot(final String codePathString)9207 private static String calculateBundledApkRoot(final String codePathString) { 9208 final File codePath = new File(codePathString); 9209 final File codeRoot; 9210 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 9211 codeRoot = Environment.getRootDirectory(); 9212 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 9213 codeRoot = Environment.getOemDirectory(); 9214 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 9215 codeRoot = Environment.getVendorDirectory(); 9216 } else { 9217 // Unrecognized code path; take its top real segment as the apk root: 9218 // e.g. /something/app/blah.apk => /something 9219 try { 9220 File f = codePath.getCanonicalFile(); 9221 File parent = f.getParentFile(); // non-null because codePath is a file 9222 File tmp; 9223 while ((tmp = parent.getParentFile()) != null) { 9224 f = parent; 9225 parent = tmp; 9226 } 9227 codeRoot = f; 9228 Slog.w(TAG, "Unrecognized code path " 9229 + codePath + " - using " + codeRoot); 9230 } catch (IOException e) { 9231 // Can't canonicalize the code path -- shenanigans? 9232 Slog.w(TAG, "Can't canonicalize code path " + codePath); 9233 return Environment.getRootDirectory().getPath(); 9234 } 9235 } 9236 return codeRoot.getPath(); 9237 } 9238 9239 /** 9240 * Derive and set the location of native libraries for the given package, 9241 * which varies depending on where and how the package was installed. 9242 */ setNativeLibraryPaths(PackageParser.Package pkg)9243 private void setNativeLibraryPaths(PackageParser.Package pkg) { 9244 final ApplicationInfo info = pkg.applicationInfo; 9245 final String codePath = pkg.codePath; 9246 final File codeFile = new File(codePath); 9247 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 9248 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 9249 9250 info.nativeLibraryRootDir = null; 9251 info.nativeLibraryRootRequiresIsa = false; 9252 info.nativeLibraryDir = null; 9253 info.secondaryNativeLibraryDir = null; 9254 9255 if (isApkFile(codeFile)) { 9256 // Monolithic install 9257 if (bundledApp) { 9258 // If "/system/lib64/apkname" exists, assume that is the per-package 9259 // native library directory to use; otherwise use "/system/lib/apkname". 9260 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 9261 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 9262 getPrimaryInstructionSet(info)); 9263 9264 // This is a bundled system app so choose the path based on the ABI. 9265 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 9266 // is just the default path. 9267 final String apkName = deriveCodePathName(codePath); 9268 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 9269 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 9270 apkName).getAbsolutePath(); 9271 9272 if (info.secondaryCpuAbi != null) { 9273 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 9274 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 9275 secondaryLibDir, apkName).getAbsolutePath(); 9276 } 9277 } else if (asecApp) { 9278 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 9279 .getAbsolutePath(); 9280 } else { 9281 final String apkName = deriveCodePathName(codePath); 9282 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 9283 .getAbsolutePath(); 9284 } 9285 9286 info.nativeLibraryRootRequiresIsa = false; 9287 info.nativeLibraryDir = info.nativeLibraryRootDir; 9288 } else { 9289 // Cluster install 9290 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 9291 info.nativeLibraryRootRequiresIsa = true; 9292 9293 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 9294 getPrimaryInstructionSet(info)).getAbsolutePath(); 9295 9296 if (info.secondaryCpuAbi != null) { 9297 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 9298 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 9299 } 9300 } 9301 } 9302 9303 /** 9304 * Calculate the abis and roots for a bundled app. These can uniquely 9305 * be determined from the contents of the system partition, i.e whether 9306 * it contains 64 or 32 bit shared libraries etc. We do not validate any 9307 * of this information, and instead assume that the system was built 9308 * sensibly. 9309 */ setBundledAppAbisAndRoots(PackageParser.Package pkg, PackageSetting pkgSetting)9310 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 9311 PackageSetting pkgSetting) { 9312 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 9313 9314 // If "/system/lib64/apkname" exists, assume that is the per-package 9315 // native library directory to use; otherwise use "/system/lib/apkname". 9316 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 9317 setBundledAppAbi(pkg, apkRoot, apkName); 9318 // pkgSetting might be null during rescan following uninstall of updates 9319 // to a bundled app, so accommodate that possibility. The settings in 9320 // that case will be established later from the parsed package. 9321 // 9322 // If the settings aren't null, sync them up with what we've just derived. 9323 // note that apkRoot isn't stored in the package settings. 9324 if (pkgSetting != null) { 9325 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9326 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9327 } 9328 } 9329 9330 /** 9331 * Deduces the ABI of a bundled app and sets the relevant fields on the 9332 * parsed pkg object. 9333 * 9334 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 9335 * under which system libraries are installed. 9336 * @param apkName the name of the installed package. 9337 */ setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName)9338 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 9339 final File codeFile = new File(pkg.codePath); 9340 9341 final boolean has64BitLibs; 9342 final boolean has32BitLibs; 9343 if (isApkFile(codeFile)) { 9344 // Monolithic install 9345 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 9346 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 9347 } else { 9348 // Cluster install 9349 final File rootDir = new File(codeFile, LIB_DIR_NAME); 9350 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 9351 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 9352 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 9353 has64BitLibs = (new File(rootDir, isa)).exists(); 9354 } else { 9355 has64BitLibs = false; 9356 } 9357 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 9358 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 9359 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 9360 has32BitLibs = (new File(rootDir, isa)).exists(); 9361 } else { 9362 has32BitLibs = false; 9363 } 9364 } 9365 9366 if (has64BitLibs && !has32BitLibs) { 9367 // The package has 64 bit libs, but not 32 bit libs. Its primary 9368 // ABI should be 64 bit. We can safely assume here that the bundled 9369 // native libraries correspond to the most preferred ABI in the list. 9370 9371 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9372 pkg.applicationInfo.secondaryCpuAbi = null; 9373 } else if (has32BitLibs && !has64BitLibs) { 9374 // The package has 32 bit libs but not 64 bit libs. Its primary 9375 // ABI should be 32 bit. 9376 9377 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9378 pkg.applicationInfo.secondaryCpuAbi = null; 9379 } else if (has32BitLibs && has64BitLibs) { 9380 // The application has both 64 and 32 bit bundled libraries. We check 9381 // here that the app declares multiArch support, and warn if it doesn't. 9382 // 9383 // We will be lenient here and record both ABIs. The primary will be the 9384 // ABI that's higher on the list, i.e, a device that's configured to prefer 9385 // 64 bit apps will see a 64 bit primary ABI, 9386 9387 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 9388 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 9389 } 9390 9391 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 9392 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9393 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9394 } else { 9395 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9396 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9397 } 9398 } else { 9399 pkg.applicationInfo.primaryCpuAbi = null; 9400 pkg.applicationInfo.secondaryCpuAbi = null; 9401 } 9402 } 9403 killApplication(String pkgName, int appId, String reason)9404 private void killApplication(String pkgName, int appId, String reason) { 9405 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 9406 } 9407 killApplication(String pkgName, int appId, int userId, String reason)9408 private void killApplication(String pkgName, int appId, int userId, String reason) { 9409 // Request the ActivityManager to kill the process(only for existing packages) 9410 // so that we do not end up in a confused state while the user is still using the older 9411 // version of the application while the new one gets installed. 9412 final long token = Binder.clearCallingIdentity(); 9413 try { 9414 IActivityManager am = ActivityManagerNative.getDefault(); 9415 if (am != null) { 9416 try { 9417 am.killApplication(pkgName, appId, userId, reason); 9418 } catch (RemoteException e) { 9419 } 9420 } 9421 } finally { 9422 Binder.restoreCallingIdentity(token); 9423 } 9424 } 9425 removePackageLI(PackageParser.Package pkg, boolean chatty)9426 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 9427 // Remove the parent package setting 9428 PackageSetting ps = (PackageSetting) pkg.mExtras; 9429 if (ps != null) { 9430 removePackageLI(ps, chatty); 9431 } 9432 // Remove the child package setting 9433 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9434 for (int i = 0; i < childCount; i++) { 9435 PackageParser.Package childPkg = pkg.childPackages.get(i); 9436 ps = (PackageSetting) childPkg.mExtras; 9437 if (ps != null) { 9438 removePackageLI(ps, chatty); 9439 } 9440 } 9441 } 9442 removePackageLI(PackageSetting ps, boolean chatty)9443 void removePackageLI(PackageSetting ps, boolean chatty) { 9444 if (DEBUG_INSTALL) { 9445 if (chatty) 9446 Log.d(TAG, "Removing package " + ps.name); 9447 } 9448 9449 // writer 9450 synchronized (mPackages) { 9451 mPackages.remove(ps.name); 9452 final PackageParser.Package pkg = ps.pkg; 9453 if (pkg != null) { 9454 cleanPackageDataStructuresLILPw(pkg, chatty); 9455 } 9456 } 9457 } 9458 removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty)9459 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 9460 if (DEBUG_INSTALL) { 9461 if (chatty) 9462 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 9463 } 9464 9465 // writer 9466 synchronized (mPackages) { 9467 // Remove the parent package 9468 mPackages.remove(pkg.applicationInfo.packageName); 9469 cleanPackageDataStructuresLILPw(pkg, chatty); 9470 9471 // Remove the child packages 9472 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9473 for (int i = 0; i < childCount; i++) { 9474 PackageParser.Package childPkg = pkg.childPackages.get(i); 9475 mPackages.remove(childPkg.applicationInfo.packageName); 9476 cleanPackageDataStructuresLILPw(childPkg, chatty); 9477 } 9478 } 9479 } 9480 cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty)9481 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 9482 int N = pkg.providers.size(); 9483 StringBuilder r = null; 9484 int i; 9485 for (i=0; i<N; i++) { 9486 PackageParser.Provider p = pkg.providers.get(i); 9487 mProviders.removeProvider(p); 9488 if (p.info.authority == null) { 9489 9490 /* There was another ContentProvider with this authority when 9491 * this app was installed so this authority is null, 9492 * Ignore it as we don't have to unregister the provider. 9493 */ 9494 continue; 9495 } 9496 String names[] = p.info.authority.split(";"); 9497 for (int j = 0; j < names.length; j++) { 9498 if (mProvidersByAuthority.get(names[j]) == p) { 9499 mProvidersByAuthority.remove(names[j]); 9500 if (DEBUG_REMOVE) { 9501 if (chatty) 9502 Log.d(TAG, "Unregistered content provider: " + names[j] 9503 + ", className = " + p.info.name + ", isSyncable = " 9504 + p.info.isSyncable); 9505 } 9506 } 9507 } 9508 if (DEBUG_REMOVE && chatty) { 9509 if (r == null) { 9510 r = new StringBuilder(256); 9511 } else { 9512 r.append(' '); 9513 } 9514 r.append(p.info.name); 9515 } 9516 } 9517 if (r != null) { 9518 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 9519 } 9520 9521 N = pkg.services.size(); 9522 r = null; 9523 for (i=0; i<N; i++) { 9524 PackageParser.Service s = pkg.services.get(i); 9525 mServices.removeService(s); 9526 if (chatty) { 9527 if (r == null) { 9528 r = new StringBuilder(256); 9529 } else { 9530 r.append(' '); 9531 } 9532 r.append(s.info.name); 9533 } 9534 } 9535 if (r != null) { 9536 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9537 } 9538 9539 N = pkg.receivers.size(); 9540 r = null; 9541 for (i=0; i<N; i++) { 9542 PackageParser.Activity a = pkg.receivers.get(i); 9543 mReceivers.removeActivity(a, "receiver"); 9544 if (DEBUG_REMOVE && chatty) { 9545 if (r == null) { 9546 r = new StringBuilder(256); 9547 } else { 9548 r.append(' '); 9549 } 9550 r.append(a.info.name); 9551 } 9552 } 9553 if (r != null) { 9554 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9555 } 9556 9557 N = pkg.activities.size(); 9558 r = null; 9559 for (i=0; i<N; i++) { 9560 PackageParser.Activity a = pkg.activities.get(i); 9561 mActivities.removeActivity(a, "activity"); 9562 if (DEBUG_REMOVE && chatty) { 9563 if (r == null) { 9564 r = new StringBuilder(256); 9565 } else { 9566 r.append(' '); 9567 } 9568 r.append(a.info.name); 9569 } 9570 } 9571 if (r != null) { 9572 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9573 } 9574 9575 N = pkg.permissions.size(); 9576 r = null; 9577 for (i=0; i<N; i++) { 9578 PackageParser.Permission p = pkg.permissions.get(i); 9579 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9580 if (bp == null) { 9581 bp = mSettings.mPermissionTrees.get(p.info.name); 9582 } 9583 if (bp != null && bp.perm == p) { 9584 bp.perm = null; 9585 if (DEBUG_REMOVE && chatty) { 9586 if (r == null) { 9587 r = new StringBuilder(256); 9588 } else { 9589 r.append(' '); 9590 } 9591 r.append(p.info.name); 9592 } 9593 } 9594 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9595 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9596 if (appOpPkgs != null) { 9597 appOpPkgs.remove(pkg.packageName); 9598 } 9599 } 9600 } 9601 if (r != null) { 9602 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9603 } 9604 9605 N = pkg.requestedPermissions.size(); 9606 r = null; 9607 for (i=0; i<N; i++) { 9608 String perm = pkg.requestedPermissions.get(i); 9609 BasePermission bp = mSettings.mPermissions.get(perm); 9610 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9611 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9612 if (appOpPkgs != null) { 9613 appOpPkgs.remove(pkg.packageName); 9614 if (appOpPkgs.isEmpty()) { 9615 mAppOpPermissionPackages.remove(perm); 9616 } 9617 } 9618 } 9619 } 9620 if (r != null) { 9621 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9622 } 9623 9624 N = pkg.instrumentation.size(); 9625 r = null; 9626 for (i=0; i<N; i++) { 9627 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9628 mInstrumentation.remove(a.getComponentName()); 9629 if (DEBUG_REMOVE && chatty) { 9630 if (r == null) { 9631 r = new StringBuilder(256); 9632 } else { 9633 r.append(' '); 9634 } 9635 r.append(a.info.name); 9636 } 9637 } 9638 if (r != null) { 9639 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9640 } 9641 9642 r = null; 9643 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9644 // Only system apps can hold shared libraries. 9645 if (pkg.libraryNames != null) { 9646 for (i=0; i<pkg.libraryNames.size(); i++) { 9647 String name = pkg.libraryNames.get(i); 9648 SharedLibraryEntry cur = mSharedLibraries.get(name); 9649 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9650 mSharedLibraries.remove(name); 9651 if (DEBUG_REMOVE && chatty) { 9652 if (r == null) { 9653 r = new StringBuilder(256); 9654 } else { 9655 r.append(' '); 9656 } 9657 r.append(name); 9658 } 9659 } 9660 } 9661 } 9662 } 9663 if (r != null) { 9664 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9665 } 9666 } 9667 hasPermission(PackageParser.Package pkgInfo, String perm)9668 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9669 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9670 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9671 return true; 9672 } 9673 } 9674 return false; 9675 } 9676 9677 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9678 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9679 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9680 updatePermissionsLPw(PackageParser.Package pkg, int flags)9681 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9682 // Update the parent permissions 9683 updatePermissionsLPw(pkg.packageName, pkg, flags); 9684 // Update the child permissions 9685 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9686 for (int i = 0; i < childCount; i++) { 9687 PackageParser.Package childPkg = pkg.childPackages.get(i); 9688 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9689 } 9690 } 9691 updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, int flags)9692 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9693 int flags) { 9694 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9695 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9696 } 9697 updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags)9698 private void updatePermissionsLPw(String changingPkg, 9699 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9700 // Make sure there are no dangling permission trees. 9701 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9702 while (it.hasNext()) { 9703 final BasePermission bp = it.next(); 9704 if (bp.packageSetting == null) { 9705 // We may not yet have parsed the package, so just see if 9706 // we still know about its settings. 9707 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9708 } 9709 if (bp.packageSetting == null) { 9710 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9711 + " from package " + bp.sourcePackage); 9712 it.remove(); 9713 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9714 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9715 Slog.i(TAG, "Removing old permission tree: " + bp.name 9716 + " from package " + bp.sourcePackage); 9717 flags |= UPDATE_PERMISSIONS_ALL; 9718 it.remove(); 9719 } 9720 } 9721 } 9722 9723 // Make sure all dynamic permissions have been assigned to a package, 9724 // and make sure there are no dangling permissions. 9725 it = mSettings.mPermissions.values().iterator(); 9726 while (it.hasNext()) { 9727 final BasePermission bp = it.next(); 9728 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9729 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9730 + bp.name + " pkg=" + bp.sourcePackage 9731 + " info=" + bp.pendingInfo); 9732 if (bp.packageSetting == null && bp.pendingInfo != null) { 9733 final BasePermission tree = findPermissionTreeLP(bp.name); 9734 if (tree != null && tree.perm != null) { 9735 bp.packageSetting = tree.packageSetting; 9736 bp.perm = new PackageParser.Permission(tree.perm.owner, 9737 new PermissionInfo(bp.pendingInfo)); 9738 bp.perm.info.packageName = tree.perm.info.packageName; 9739 bp.perm.info.name = bp.name; 9740 bp.uid = tree.uid; 9741 } 9742 } 9743 } 9744 if (bp.packageSetting == null) { 9745 // We may not yet have parsed the package, so just see if 9746 // we still know about its settings. 9747 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9748 } 9749 if (bp.packageSetting == null) { 9750 Slog.w(TAG, "Removing dangling permission: " + bp.name 9751 + " from package " + bp.sourcePackage); 9752 it.remove(); 9753 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9754 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9755 Slog.i(TAG, "Removing old permission: " + bp.name 9756 + " from package " + bp.sourcePackage); 9757 flags |= UPDATE_PERMISSIONS_ALL; 9758 it.remove(); 9759 } 9760 } 9761 } 9762 9763 // Now update the permissions for all packages, in particular 9764 // replace the granted permissions of the system packages. 9765 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9766 for (PackageParser.Package pkg : mPackages.values()) { 9767 if (pkg != pkgInfo) { 9768 // Only replace for packages on requested volume 9769 final String volumeUuid = getVolumeUuidForPackage(pkg); 9770 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9771 && Objects.equals(replaceVolumeUuid, volumeUuid); 9772 grantPermissionsLPw(pkg, replace, changingPkg); 9773 } 9774 } 9775 } 9776 9777 if (pkgInfo != null) { 9778 // Only replace for packages on requested volume 9779 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9780 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9781 && Objects.equals(replaceVolumeUuid, volumeUuid); 9782 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9783 } 9784 } 9785 grantPermissionsLPw(PackageParser.Package pkg, boolean replace, String packageOfInterest)9786 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9787 String packageOfInterest) { 9788 // IMPORTANT: There are two types of permissions: install and runtime. 9789 // Install time permissions are granted when the app is installed to 9790 // all device users and users added in the future. Runtime permissions 9791 // are granted at runtime explicitly to specific users. Normal and signature 9792 // protected permissions are install time permissions. Dangerous permissions 9793 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9794 // otherwise they are runtime permissions. This function does not manage 9795 // runtime permissions except for the case an app targeting Lollipop MR1 9796 // being upgraded to target a newer SDK, in which case dangerous permissions 9797 // are transformed from install time to runtime ones. 9798 9799 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9800 if (ps == null) { 9801 return; 9802 } 9803 9804 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9805 9806 PermissionsState permissionsState = ps.getPermissionsState(); 9807 PermissionsState origPermissions = permissionsState; 9808 9809 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9810 9811 boolean runtimePermissionsRevoked = false; 9812 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9813 9814 boolean changedInstallPermission = false; 9815 9816 if (replace) { 9817 ps.installPermissionsFixed = false; 9818 if (!ps.isSharedUser()) { 9819 origPermissions = new PermissionsState(permissionsState); 9820 permissionsState.reset(); 9821 } else { 9822 // We need to know only about runtime permission changes since the 9823 // calling code always writes the install permissions state but 9824 // the runtime ones are written only if changed. The only cases of 9825 // changed runtime permissions here are promotion of an install to 9826 // runtime and revocation of a runtime from a shared user. 9827 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9828 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9829 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9830 runtimePermissionsRevoked = true; 9831 } 9832 } 9833 } 9834 9835 permissionsState.setGlobalGids(mGlobalGids); 9836 9837 final int N = pkg.requestedPermissions.size(); 9838 for (int i=0; i<N; i++) { 9839 final String name = pkg.requestedPermissions.get(i); 9840 final BasePermission bp = mSettings.mPermissions.get(name); 9841 9842 if (DEBUG_INSTALL) { 9843 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9844 } 9845 9846 if (bp == null || bp.packageSetting == null) { 9847 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9848 Slog.w(TAG, "Unknown permission " + name 9849 + " in package " + pkg.packageName); 9850 } 9851 continue; 9852 } 9853 9854 final String perm = bp.name; 9855 boolean allowedSig = false; 9856 int grant = GRANT_DENIED; 9857 9858 // Keep track of app op permissions. 9859 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9860 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 9861 if (pkgs == null) { 9862 pkgs = new ArraySet<>(); 9863 mAppOpPermissionPackages.put(bp.name, pkgs); 9864 } 9865 pkgs.add(pkg.packageName); 9866 } 9867 9868 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 9869 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 9870 >= Build.VERSION_CODES.M; 9871 switch (level) { 9872 case PermissionInfo.PROTECTION_NORMAL: { 9873 // For all apps normal permissions are install time ones. 9874 grant = GRANT_INSTALL; 9875 } break; 9876 9877 case PermissionInfo.PROTECTION_DANGEROUS: { 9878 // If a permission review is required for legacy apps we represent 9879 // their permissions as always granted runtime ones since we need 9880 // to keep the review required permission flag per user while an 9881 // install permission's state is shared across all users. 9882 if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) { 9883 // For legacy apps dangerous permissions are install time ones. 9884 grant = GRANT_INSTALL; 9885 } else if (origPermissions.hasInstallPermission(bp.name)) { 9886 // For legacy apps that became modern, install becomes runtime. 9887 grant = GRANT_UPGRADE; 9888 } else if (mPromoteSystemApps 9889 && isSystemApp(ps) 9890 && mExistingSystemPackages.contains(ps.name)) { 9891 // For legacy system apps, install becomes runtime. 9892 // We cannot check hasInstallPermission() for system apps since those 9893 // permissions were granted implicitly and not persisted pre-M. 9894 grant = GRANT_UPGRADE; 9895 } else { 9896 // For modern apps keep runtime permissions unchanged. 9897 grant = GRANT_RUNTIME; 9898 } 9899 } break; 9900 9901 case PermissionInfo.PROTECTION_SIGNATURE: { 9902 // For all apps signature permissions are install time ones. 9903 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 9904 if (allowedSig) { 9905 grant = GRANT_INSTALL; 9906 } 9907 } break; 9908 } 9909 9910 if (DEBUG_INSTALL) { 9911 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 9912 } 9913 9914 if (grant != GRANT_DENIED) { 9915 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 9916 // If this is an existing, non-system package, then 9917 // we can't add any new permissions to it. 9918 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 9919 // Except... if this is a permission that was added 9920 // to the platform (note: need to only do this when 9921 // updating the platform). 9922 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 9923 grant = GRANT_DENIED; 9924 } 9925 } 9926 } 9927 9928 switch (grant) { 9929 case GRANT_INSTALL: { 9930 // Revoke this as runtime permission to handle the case of 9931 // a runtime permission being downgraded to an install one. 9932 // Also in permission review mode we keep dangerous permissions 9933 // for legacy apps 9934 for (int userId : UserManagerService.getInstance().getUserIds()) { 9935 if (origPermissions.getRuntimePermissionState( 9936 bp.name, userId) != null) { 9937 // Revoke the runtime permission and clear the flags. 9938 origPermissions.revokeRuntimePermission(bp, userId); 9939 origPermissions.updatePermissionFlags(bp, userId, 9940 PackageManager.MASK_PERMISSION_FLAGS, 0); 9941 // If we revoked a permission permission, we have to write. 9942 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9943 changedRuntimePermissionUserIds, userId); 9944 } 9945 } 9946 // Grant an install permission. 9947 if (permissionsState.grantInstallPermission(bp) != 9948 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9949 changedInstallPermission = true; 9950 } 9951 } break; 9952 9953 case GRANT_RUNTIME: { 9954 // Grant previously granted runtime permissions. 9955 for (int userId : UserManagerService.getInstance().getUserIds()) { 9956 PermissionState permissionState = origPermissions 9957 .getRuntimePermissionState(bp.name, userId); 9958 int flags = permissionState != null 9959 ? permissionState.getFlags() : 0; 9960 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 9961 if (permissionsState.grantRuntimePermission(bp, userId) == 9962 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9963 // If we cannot put the permission as it was, we have to write. 9964 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9965 changedRuntimePermissionUserIds, userId); 9966 } 9967 // If the app supports runtime permissions no need for a review. 9968 if (Build.PERMISSIONS_REVIEW_REQUIRED 9969 && appSupportsRuntimePermissions 9970 && (flags & PackageManager 9971 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 9972 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 9973 // Since we changed the flags, we have to write. 9974 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9975 changedRuntimePermissionUserIds, userId); 9976 } 9977 } else if (Build.PERMISSIONS_REVIEW_REQUIRED 9978 && !appSupportsRuntimePermissions) { 9979 // For legacy apps that need a permission review, every new 9980 // runtime permission is granted but it is pending a review. 9981 // We also need to review only platform defined runtime 9982 // permissions as these are the only ones the platform knows 9983 // how to disable the API to simulate revocation as legacy 9984 // apps don't expect to run with revoked permissions. 9985 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 9986 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 9987 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 9988 // We changed the flags, hence have to write. 9989 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9990 changedRuntimePermissionUserIds, userId); 9991 } 9992 } 9993 if (permissionsState.grantRuntimePermission(bp, userId) 9994 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 9995 // We changed the permission, hence have to write. 9996 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9997 changedRuntimePermissionUserIds, userId); 9998 } 9999 } 10000 // Propagate the permission flags. 10001 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 10002 } 10003 } break; 10004 10005 case GRANT_UPGRADE: { 10006 // Grant runtime permissions for a previously held install permission. 10007 PermissionState permissionState = origPermissions 10008 .getInstallPermissionState(bp.name); 10009 final int flags = permissionState != null ? permissionState.getFlags() : 0; 10010 10011 if (origPermissions.revokeInstallPermission(bp) 10012 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10013 // We will be transferring the permission flags, so clear them. 10014 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 10015 PackageManager.MASK_PERMISSION_FLAGS, 0); 10016 changedInstallPermission = true; 10017 } 10018 10019 // If the permission is not to be promoted to runtime we ignore it and 10020 // also its other flags as they are not applicable to install permissions. 10021 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 10022 for (int userId : currentUserIds) { 10023 if (permissionsState.grantRuntimePermission(bp, userId) != 10024 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10025 // Transfer the permission flags. 10026 permissionsState.updatePermissionFlags(bp, userId, 10027 flags, flags); 10028 // If we granted the permission, we have to write. 10029 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10030 changedRuntimePermissionUserIds, userId); 10031 } 10032 } 10033 } 10034 } break; 10035 10036 default: { 10037 if (packageOfInterest == null 10038 || packageOfInterest.equals(pkg.packageName)) { 10039 Slog.w(TAG, "Not granting permission " + perm 10040 + " to package " + pkg.packageName 10041 + " because it was previously installed without"); 10042 } 10043 } break; 10044 } 10045 } else { 10046 if (permissionsState.revokeInstallPermission(bp) != 10047 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10048 // Also drop the permission flags. 10049 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 10050 PackageManager.MASK_PERMISSION_FLAGS, 0); 10051 changedInstallPermission = true; 10052 Slog.i(TAG, "Un-granting permission " + perm 10053 + " from package " + pkg.packageName 10054 + " (protectionLevel=" + bp.protectionLevel 10055 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10056 + ")"); 10057 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 10058 // Don't print warning for app op permissions, since it is fine for them 10059 // not to be granted, there is a UI for the user to decide. 10060 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 10061 Slog.w(TAG, "Not granting permission " + perm 10062 + " to package " + pkg.packageName 10063 + " (protectionLevel=" + bp.protectionLevel 10064 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10065 + ")"); 10066 } 10067 } 10068 } 10069 } 10070 10071 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 10072 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 10073 // This is the first that we have heard about this package, so the 10074 // permissions we have now selected are fixed until explicitly 10075 // changed. 10076 ps.installPermissionsFixed = true; 10077 } 10078 10079 // Persist the runtime permissions state for users with changes. If permissions 10080 // were revoked because no app in the shared user declares them we have to 10081 // write synchronously to avoid losing runtime permissions state. 10082 for (int userId : changedRuntimePermissionUserIds) { 10083 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 10084 } 10085 10086 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10087 } 10088 isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg)10089 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 10090 boolean allowed = false; 10091 final int NP = PackageParser.NEW_PERMISSIONS.length; 10092 for (int ip=0; ip<NP; ip++) { 10093 final PackageParser.NewPermissionInfo npi 10094 = PackageParser.NEW_PERMISSIONS[ip]; 10095 if (npi.name.equals(perm) 10096 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 10097 allowed = true; 10098 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 10099 + pkg.packageName); 10100 break; 10101 } 10102 } 10103 return allowed; 10104 } 10105 grantSignaturePermission(String perm, PackageParser.Package pkg, BasePermission bp, PermissionsState origPermissions)10106 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 10107 BasePermission bp, PermissionsState origPermissions) { 10108 boolean allowed; 10109 allowed = (compareSignatures( 10110 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 10111 == PackageManager.SIGNATURE_MATCH) 10112 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 10113 == PackageManager.SIGNATURE_MATCH); 10114 if (!allowed && (bp.protectionLevel 10115 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 10116 if (isSystemApp(pkg)) { 10117 // For updated system applications, a system permission 10118 // is granted only if it had been defined by the original application. 10119 if (pkg.isUpdatedSystemApp()) { 10120 final PackageSetting sysPs = mSettings 10121 .getDisabledSystemPkgLPr(pkg.packageName); 10122 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 10123 // If the original was granted this permission, we take 10124 // that grant decision as read and propagate it to the 10125 // update. 10126 if (sysPs.isPrivileged()) { 10127 allowed = true; 10128 } 10129 } else { 10130 // The system apk may have been updated with an older 10131 // version of the one on the data partition, but which 10132 // granted a new system permission that it didn't have 10133 // before. In this case we do want to allow the app to 10134 // now get the new permission if the ancestral apk is 10135 // privileged to get it. 10136 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 10137 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 10138 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 10139 allowed = true; 10140 break; 10141 } 10142 } 10143 } 10144 // Also if a privileged parent package on the system image or any of 10145 // its children requested a privileged permission, the updated child 10146 // packages can also get the permission. 10147 if (pkg.parentPackage != null) { 10148 final PackageSetting disabledSysParentPs = mSettings 10149 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 10150 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 10151 && disabledSysParentPs.isPrivileged()) { 10152 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 10153 allowed = true; 10154 } else if (disabledSysParentPs.pkg.childPackages != null) { 10155 final int count = disabledSysParentPs.pkg.childPackages.size(); 10156 for (int i = 0; i < count; i++) { 10157 PackageParser.Package disabledSysChildPkg = 10158 disabledSysParentPs.pkg.childPackages.get(i); 10159 if (isPackageRequestingPermission(disabledSysChildPkg, 10160 perm)) { 10161 allowed = true; 10162 break; 10163 } 10164 } 10165 } 10166 } 10167 } 10168 } 10169 } else { 10170 allowed = isPrivilegedApp(pkg); 10171 } 10172 } 10173 } 10174 if (!allowed) { 10175 if (!allowed && (bp.protectionLevel 10176 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 10177 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 10178 // If this was a previously normal/dangerous permission that got moved 10179 // to a system permission as part of the runtime permission redesign, then 10180 // we still want to blindly grant it to old apps. 10181 allowed = true; 10182 } 10183 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 10184 && pkg.packageName.equals(mRequiredInstallerPackage)) { 10185 // If this permission is to be granted to the system installer and 10186 // this app is an installer, then it gets the permission. 10187 allowed = true; 10188 } 10189 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 10190 && pkg.packageName.equals(mRequiredVerifierPackage)) { 10191 // If this permission is to be granted to the system verifier and 10192 // this app is a verifier, then it gets the permission. 10193 allowed = true; 10194 } 10195 if (!allowed && (bp.protectionLevel 10196 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 10197 && isSystemApp(pkg)) { 10198 // Any pre-installed system app is allowed to get this permission. 10199 allowed = true; 10200 } 10201 if (!allowed && (bp.protectionLevel 10202 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 10203 // For development permissions, a development permission 10204 // is granted only if it was already granted. 10205 allowed = origPermissions.hasInstallPermission(perm); 10206 } 10207 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 10208 && pkg.packageName.equals(mSetupWizardPackage)) { 10209 // If this permission is to be granted to the system setup wizard and 10210 // this app is a setup wizard, then it gets the permission. 10211 allowed = true; 10212 } 10213 } 10214 return allowed; 10215 } 10216 isPackageRequestingPermission(PackageParser.Package pkg, String permission)10217 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 10218 final int permCount = pkg.requestedPermissions.size(); 10219 for (int j = 0; j < permCount; j++) { 10220 String requestedPermission = pkg.requestedPermissions.get(j); 10221 if (permission.equals(requestedPermission)) { 10222 return true; 10223 } 10224 } 10225 return false; 10226 } 10227 10228 final class ActivityIntentResolver 10229 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)10230 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10231 boolean defaultOnly, int userId) { 10232 if (!sUserManager.exists(userId)) return null; 10233 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10234 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10235 } 10236 queryIntent(Intent intent, String resolvedType, int flags, int userId)10237 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10238 int userId) { 10239 if (!sUserManager.exists(userId)) return null; 10240 mFlags = flags; 10241 return super.queryIntent(intent, resolvedType, 10242 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10243 } 10244 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Activity> packageActivities, int userId)10245 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10246 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 10247 if (!sUserManager.exists(userId)) return null; 10248 if (packageActivities == null) { 10249 return null; 10250 } 10251 mFlags = flags; 10252 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10253 final int N = packageActivities.size(); 10254 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 10255 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 10256 10257 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 10258 for (int i = 0; i < N; ++i) { 10259 intentFilters = packageActivities.get(i).intents; 10260 if (intentFilters != null && intentFilters.size() > 0) { 10261 PackageParser.ActivityIntentInfo[] array = 10262 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 10263 intentFilters.toArray(array); 10264 listCut.add(array); 10265 } 10266 } 10267 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10268 } 10269 10270 /** 10271 * Finds a privileged activity that matches the specified activity names. 10272 */ findMatchingActivity( List<PackageParser.Activity> activityList, ActivityInfo activityInfo)10273 private PackageParser.Activity findMatchingActivity( 10274 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 10275 for (PackageParser.Activity sysActivity : activityList) { 10276 if (sysActivity.info.name.equals(activityInfo.name)) { 10277 return sysActivity; 10278 } 10279 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 10280 return sysActivity; 10281 } 10282 if (sysActivity.info.targetActivity != null) { 10283 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 10284 return sysActivity; 10285 } 10286 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 10287 return sysActivity; 10288 } 10289 } 10290 } 10291 return null; 10292 } 10293 10294 public class IterGenerator<E> { generate(ActivityIntentInfo info)10295 public Iterator<E> generate(ActivityIntentInfo info) { 10296 return null; 10297 } 10298 } 10299 10300 public class ActionIterGenerator extends IterGenerator<String> { 10301 @Override generate(ActivityIntentInfo info)10302 public Iterator<String> generate(ActivityIntentInfo info) { 10303 return info.actionsIterator(); 10304 } 10305 } 10306 10307 public class CategoriesIterGenerator extends IterGenerator<String> { 10308 @Override generate(ActivityIntentInfo info)10309 public Iterator<String> generate(ActivityIntentInfo info) { 10310 return info.categoriesIterator(); 10311 } 10312 } 10313 10314 public class SchemesIterGenerator extends IterGenerator<String> { 10315 @Override generate(ActivityIntentInfo info)10316 public Iterator<String> generate(ActivityIntentInfo info) { 10317 return info.schemesIterator(); 10318 } 10319 } 10320 10321 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 10322 @Override generate(ActivityIntentInfo info)10323 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 10324 return info.authoritiesIterator(); 10325 } 10326 } 10327 10328 /** 10329 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 10330 * MODIFIED. Do not pass in a list that should not be changed. 10331 */ getIntentListSubset(List<ActivityIntentInfo> intentList, IterGenerator<T> generator, Iterator<T> searchIterator)10332 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 10333 IterGenerator<T> generator, Iterator<T> searchIterator) { 10334 // loop through the set of actions; every one must be found in the intent filter 10335 while (searchIterator.hasNext()) { 10336 // we must have at least one filter in the list to consider a match 10337 if (intentList.size() == 0) { 10338 break; 10339 } 10340 10341 final T searchAction = searchIterator.next(); 10342 10343 // loop through the set of intent filters 10344 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 10345 while (intentIter.hasNext()) { 10346 final ActivityIntentInfo intentInfo = intentIter.next(); 10347 boolean selectionFound = false; 10348 10349 // loop through the intent filter's selection criteria; at least one 10350 // of them must match the searched criteria 10351 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 10352 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 10353 final T intentSelection = intentSelectionIter.next(); 10354 if (intentSelection != null && intentSelection.equals(searchAction)) { 10355 selectionFound = true; 10356 break; 10357 } 10358 } 10359 10360 // the selection criteria wasn't found in this filter's set; this filter 10361 // is not a potential match 10362 if (!selectionFound) { 10363 intentIter.remove(); 10364 } 10365 } 10366 } 10367 } 10368 isProtectedAction(ActivityIntentInfo filter)10369 private boolean isProtectedAction(ActivityIntentInfo filter) { 10370 final Iterator<String> actionsIter = filter.actionsIterator(); 10371 while (actionsIter != null && actionsIter.hasNext()) { 10372 final String filterAction = actionsIter.next(); 10373 if (PROTECTED_ACTIONS.contains(filterAction)) { 10374 return true; 10375 } 10376 } 10377 return false; 10378 } 10379 10380 /** 10381 * Adjusts the priority of the given intent filter according to policy. 10382 * <p> 10383 * <ul> 10384 * <li>The priority for non privileged applications is capped to '0'</li> 10385 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 10386 * <li>The priority for unbundled updates to privileged applications is capped to the 10387 * priority defined on the system partition</li> 10388 * </ul> 10389 * <p> 10390 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 10391 * allowed to obtain any priority on any action. 10392 */ adjustPriority( List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent)10393 private void adjustPriority( 10394 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 10395 // nothing to do; priority is fine as-is 10396 if (intent.getPriority() <= 0) { 10397 return; 10398 } 10399 10400 final ActivityInfo activityInfo = intent.activity.info; 10401 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 10402 10403 final boolean privilegedApp = 10404 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 10405 if (!privilegedApp) { 10406 // non-privileged applications can never define a priority >0 10407 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 10408 + " package: " + applicationInfo.packageName 10409 + " activity: " + intent.activity.className 10410 + " origPrio: " + intent.getPriority()); 10411 intent.setPriority(0); 10412 return; 10413 } 10414 10415 if (systemActivities == null) { 10416 // the system package is not disabled; we're parsing the system partition 10417 if (isProtectedAction(intent)) { 10418 if (mDeferProtectedFilters) { 10419 // We can't deal with these just yet. No component should ever obtain a 10420 // >0 priority for a protected actions, with ONE exception -- the setup 10421 // wizard. The setup wizard, however, cannot be known until we're able to 10422 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 10423 // until all intent filters have been processed. Chicken, meet egg. 10424 // Let the filter temporarily have a high priority and rectify the 10425 // priorities after all system packages have been scanned. 10426 mProtectedFilters.add(intent); 10427 if (DEBUG_FILTERS) { 10428 Slog.i(TAG, "Protected action; save for later;" 10429 + " package: " + applicationInfo.packageName 10430 + " activity: " + intent.activity.className 10431 + " origPrio: " + intent.getPriority()); 10432 } 10433 return; 10434 } else { 10435 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 10436 Slog.i(TAG, "No setup wizard;" 10437 + " All protected intents capped to priority 0"); 10438 } 10439 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 10440 if (DEBUG_FILTERS) { 10441 Slog.i(TAG, "Found setup wizard;" 10442 + " allow priority " + intent.getPriority() + ";" 10443 + " package: " + intent.activity.info.packageName 10444 + " activity: " + intent.activity.className 10445 + " priority: " + intent.getPriority()); 10446 } 10447 // setup wizard gets whatever it wants 10448 return; 10449 } 10450 Slog.w(TAG, "Protected action; cap priority to 0;" 10451 + " package: " + intent.activity.info.packageName 10452 + " activity: " + intent.activity.className 10453 + " origPrio: " + intent.getPriority()); 10454 intent.setPriority(0); 10455 return; 10456 } 10457 } 10458 // privileged apps on the system image get whatever priority they request 10459 return; 10460 } 10461 10462 // privileged app unbundled update ... try to find the same activity 10463 final PackageParser.Activity foundActivity = 10464 findMatchingActivity(systemActivities, activityInfo); 10465 if (foundActivity == null) { 10466 // this is a new activity; it cannot obtain >0 priority 10467 if (DEBUG_FILTERS) { 10468 Slog.i(TAG, "New activity; cap priority to 0;" 10469 + " package: " + applicationInfo.packageName 10470 + " activity: " + intent.activity.className 10471 + " origPrio: " + intent.getPriority()); 10472 } 10473 intent.setPriority(0); 10474 return; 10475 } 10476 10477 // found activity, now check for filter equivalence 10478 10479 // a shallow copy is enough; we modify the list, not its contents 10480 final List<ActivityIntentInfo> intentListCopy = 10481 new ArrayList<>(foundActivity.intents); 10482 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 10483 10484 // find matching action subsets 10485 final Iterator<String> actionsIterator = intent.actionsIterator(); 10486 if (actionsIterator != null) { 10487 getIntentListSubset( 10488 intentListCopy, new ActionIterGenerator(), actionsIterator); 10489 if (intentListCopy.size() == 0) { 10490 // no more intents to match; we're not equivalent 10491 if (DEBUG_FILTERS) { 10492 Slog.i(TAG, "Mismatched action; cap priority to 0;" 10493 + " package: " + applicationInfo.packageName 10494 + " activity: " + intent.activity.className 10495 + " origPrio: " + intent.getPriority()); 10496 } 10497 intent.setPriority(0); 10498 return; 10499 } 10500 } 10501 10502 // find matching category subsets 10503 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 10504 if (categoriesIterator != null) { 10505 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 10506 categoriesIterator); 10507 if (intentListCopy.size() == 0) { 10508 // no more intents to match; we're not equivalent 10509 if (DEBUG_FILTERS) { 10510 Slog.i(TAG, "Mismatched category; cap priority to 0;" 10511 + " package: " + applicationInfo.packageName 10512 + " activity: " + intent.activity.className 10513 + " origPrio: " + intent.getPriority()); 10514 } 10515 intent.setPriority(0); 10516 return; 10517 } 10518 } 10519 10520 // find matching schemes subsets 10521 final Iterator<String> schemesIterator = intent.schemesIterator(); 10522 if (schemesIterator != null) { 10523 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 10524 schemesIterator); 10525 if (intentListCopy.size() == 0) { 10526 // no more intents to match; we're not equivalent 10527 if (DEBUG_FILTERS) { 10528 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 10529 + " package: " + applicationInfo.packageName 10530 + " activity: " + intent.activity.className 10531 + " origPrio: " + intent.getPriority()); 10532 } 10533 intent.setPriority(0); 10534 return; 10535 } 10536 } 10537 10538 // find matching authorities subsets 10539 final Iterator<IntentFilter.AuthorityEntry> 10540 authoritiesIterator = intent.authoritiesIterator(); 10541 if (authoritiesIterator != null) { 10542 getIntentListSubset(intentListCopy, 10543 new AuthoritiesIterGenerator(), 10544 authoritiesIterator); 10545 if (intentListCopy.size() == 0) { 10546 // no more intents to match; we're not equivalent 10547 if (DEBUG_FILTERS) { 10548 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 10549 + " package: " + applicationInfo.packageName 10550 + " activity: " + intent.activity.className 10551 + " origPrio: " + intent.getPriority()); 10552 } 10553 intent.setPriority(0); 10554 return; 10555 } 10556 } 10557 10558 // we found matching filter(s); app gets the max priority of all intents 10559 int cappedPriority = 0; 10560 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 10561 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 10562 } 10563 if (intent.getPriority() > cappedPriority) { 10564 if (DEBUG_FILTERS) { 10565 Slog.i(TAG, "Found matching filter(s);" 10566 + " cap priority to " + cappedPriority + ";" 10567 + " package: " + applicationInfo.packageName 10568 + " activity: " + intent.activity.className 10569 + " origPrio: " + intent.getPriority()); 10570 } 10571 intent.setPriority(cappedPriority); 10572 return; 10573 } 10574 // all this for nothing; the requested priority was <= what was on the system 10575 } 10576 addActivity(PackageParser.Activity a, String type)10577 public final void addActivity(PackageParser.Activity a, String type) { 10578 mActivities.put(a.getComponentName(), a); 10579 if (DEBUG_SHOW_INFO) 10580 Log.v( 10581 TAG, " " + type + " " + 10582 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 10583 if (DEBUG_SHOW_INFO) 10584 Log.v(TAG, " Class=" + a.info.name); 10585 final int NI = a.intents.size(); 10586 for (int j=0; j<NI; j++) { 10587 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10588 if ("activity".equals(type)) { 10589 final PackageSetting ps = 10590 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 10591 final List<PackageParser.Activity> systemActivities = 10592 ps != null && ps.pkg != null ? ps.pkg.activities : null; 10593 adjustPriority(systemActivities, intent); 10594 } 10595 if (DEBUG_SHOW_INFO) { 10596 Log.v(TAG, " IntentFilter:"); 10597 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10598 } 10599 if (!intent.debugCheck()) { 10600 Log.w(TAG, "==> For Activity " + a.info.name); 10601 } 10602 addFilter(intent); 10603 } 10604 } 10605 removeActivity(PackageParser.Activity a, String type)10606 public final void removeActivity(PackageParser.Activity a, String type) { 10607 mActivities.remove(a.getComponentName()); 10608 if (DEBUG_SHOW_INFO) { 10609 Log.v(TAG, " " + type + " " 10610 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 10611 : a.info.name) + ":"); 10612 Log.v(TAG, " Class=" + a.info.name); 10613 } 10614 final int NI = a.intents.size(); 10615 for (int j=0; j<NI; j++) { 10616 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10617 if (DEBUG_SHOW_INFO) { 10618 Log.v(TAG, " IntentFilter:"); 10619 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10620 } 10621 removeFilter(intent); 10622 } 10623 } 10624 10625 @Override allowFilterResult( PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest)10626 protected boolean allowFilterResult( 10627 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 10628 ActivityInfo filterAi = filter.activity.info; 10629 for (int i=dest.size()-1; i>=0; i--) { 10630 ActivityInfo destAi = dest.get(i).activityInfo; 10631 if (destAi.name == filterAi.name 10632 && destAi.packageName == filterAi.packageName) { 10633 return false; 10634 } 10635 } 10636 return true; 10637 } 10638 10639 @Override newArray(int size)10640 protected ActivityIntentInfo[] newArray(int size) { 10641 return new ActivityIntentInfo[size]; 10642 } 10643 10644 @Override isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId)10645 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 10646 if (!sUserManager.exists(userId)) return true; 10647 PackageParser.Package p = filter.activity.owner; 10648 if (p != null) { 10649 PackageSetting ps = (PackageSetting)p.mExtras; 10650 if (ps != null) { 10651 // System apps are never considered stopped for purposes of 10652 // filtering, because there may be no way for the user to 10653 // actually re-launch them. 10654 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 10655 && ps.getStopped(userId); 10656 } 10657 } 10658 return false; 10659 } 10660 10661 @Override isPackageForFilter(String packageName, PackageParser.ActivityIntentInfo info)10662 protected boolean isPackageForFilter(String packageName, 10663 PackageParser.ActivityIntentInfo info) { 10664 return packageName.equals(info.activity.owner.packageName); 10665 } 10666 10667 @Override newResult(PackageParser.ActivityIntentInfo info, int match, int userId)10668 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 10669 int match, int userId) { 10670 if (!sUserManager.exists(userId)) return null; 10671 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 10672 return null; 10673 } 10674 final PackageParser.Activity activity = info.activity; 10675 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 10676 if (ps == null) { 10677 return null; 10678 } 10679 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 10680 ps.readUserState(userId), userId); 10681 if (ai == null) { 10682 return null; 10683 } 10684 final ResolveInfo res = new ResolveInfo(); 10685 res.activityInfo = ai; 10686 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10687 res.filter = info; 10688 } 10689 if (info != null) { 10690 res.handleAllWebDataURI = info.handleAllWebDataURI(); 10691 } 10692 res.priority = info.getPriority(); 10693 res.preferredOrder = activity.owner.mPreferredOrder; 10694 //System.out.println("Result: " + res.activityInfo.className + 10695 // " = " + res.priority); 10696 res.match = match; 10697 res.isDefault = info.hasDefault; 10698 res.labelRes = info.labelRes; 10699 res.nonLocalizedLabel = info.nonLocalizedLabel; 10700 if (userNeedsBadging(userId)) { 10701 res.noResourceId = true; 10702 } else { 10703 res.icon = info.icon; 10704 } 10705 res.iconResourceId = info.icon; 10706 res.system = res.activityInfo.applicationInfo.isSystemApp(); 10707 return res; 10708 } 10709 10710 @Override sortResults(List<ResolveInfo> results)10711 protected void sortResults(List<ResolveInfo> results) { 10712 Collections.sort(results, mResolvePrioritySorter); 10713 } 10714 10715 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ActivityIntentInfo filter)10716 protected void dumpFilter(PrintWriter out, String prefix, 10717 PackageParser.ActivityIntentInfo filter) { 10718 out.print(prefix); out.print( 10719 Integer.toHexString(System.identityHashCode(filter.activity))); 10720 out.print(' '); 10721 filter.activity.printComponentShortName(out); 10722 out.print(" filter "); 10723 out.println(Integer.toHexString(System.identityHashCode(filter))); 10724 } 10725 10726 @Override filterToLabel(PackageParser.ActivityIntentInfo filter)10727 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 10728 return filter.activity; 10729 } 10730 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)10731 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10732 PackageParser.Activity activity = (PackageParser.Activity)label; 10733 out.print(prefix); out.print( 10734 Integer.toHexString(System.identityHashCode(activity))); 10735 out.print(' '); 10736 activity.printComponentShortName(out); 10737 if (count > 1) { 10738 out.print(" ("); out.print(count); out.print(" filters)"); 10739 } 10740 out.println(); 10741 } 10742 10743 // Keys are String (activity class name), values are Activity. 10744 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 10745 = new ArrayMap<ComponentName, PackageParser.Activity>(); 10746 private int mFlags; 10747 } 10748 10749 private final class ServiceIntentResolver 10750 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)10751 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10752 boolean defaultOnly, int userId) { 10753 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10754 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10755 } 10756 queryIntent(Intent intent, String resolvedType, int flags, int userId)10757 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10758 int userId) { 10759 if (!sUserManager.exists(userId)) return null; 10760 mFlags = flags; 10761 return super.queryIntent(intent, resolvedType, 10762 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10763 } 10764 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Service> packageServices, int userId)10765 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10766 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 10767 if (!sUserManager.exists(userId)) return null; 10768 if (packageServices == null) { 10769 return null; 10770 } 10771 mFlags = flags; 10772 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10773 final int N = packageServices.size(); 10774 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 10775 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 10776 10777 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 10778 for (int i = 0; i < N; ++i) { 10779 intentFilters = packageServices.get(i).intents; 10780 if (intentFilters != null && intentFilters.size() > 0) { 10781 PackageParser.ServiceIntentInfo[] array = 10782 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 10783 intentFilters.toArray(array); 10784 listCut.add(array); 10785 } 10786 } 10787 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10788 } 10789 addService(PackageParser.Service s)10790 public final void addService(PackageParser.Service s) { 10791 mServices.put(s.getComponentName(), s); 10792 if (DEBUG_SHOW_INFO) { 10793 Log.v(TAG, " " 10794 + (s.info.nonLocalizedLabel != null 10795 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10796 Log.v(TAG, " Class=" + s.info.name); 10797 } 10798 final int NI = s.intents.size(); 10799 int j; 10800 for (j=0; j<NI; j++) { 10801 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10802 if (DEBUG_SHOW_INFO) { 10803 Log.v(TAG, " IntentFilter:"); 10804 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10805 } 10806 if (!intent.debugCheck()) { 10807 Log.w(TAG, "==> For Service " + s.info.name); 10808 } 10809 addFilter(intent); 10810 } 10811 } 10812 removeService(PackageParser.Service s)10813 public final void removeService(PackageParser.Service s) { 10814 mServices.remove(s.getComponentName()); 10815 if (DEBUG_SHOW_INFO) { 10816 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 10817 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10818 Log.v(TAG, " Class=" + s.info.name); 10819 } 10820 final int NI = s.intents.size(); 10821 int j; 10822 for (j=0; j<NI; j++) { 10823 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10824 if (DEBUG_SHOW_INFO) { 10825 Log.v(TAG, " IntentFilter:"); 10826 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10827 } 10828 removeFilter(intent); 10829 } 10830 } 10831 10832 @Override allowFilterResult( PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest)10833 protected boolean allowFilterResult( 10834 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 10835 ServiceInfo filterSi = filter.service.info; 10836 for (int i=dest.size()-1; i>=0; i--) { 10837 ServiceInfo destAi = dest.get(i).serviceInfo; 10838 if (destAi.name == filterSi.name 10839 && destAi.packageName == filterSi.packageName) { 10840 return false; 10841 } 10842 } 10843 return true; 10844 } 10845 10846 @Override newArray(int size)10847 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 10848 return new PackageParser.ServiceIntentInfo[size]; 10849 } 10850 10851 @Override isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId)10852 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 10853 if (!sUserManager.exists(userId)) return true; 10854 PackageParser.Package p = filter.service.owner; 10855 if (p != null) { 10856 PackageSetting ps = (PackageSetting)p.mExtras; 10857 if (ps != null) { 10858 // System apps are never considered stopped for purposes of 10859 // filtering, because there may be no way for the user to 10860 // actually re-launch them. 10861 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10862 && ps.getStopped(userId); 10863 } 10864 } 10865 return false; 10866 } 10867 10868 @Override isPackageForFilter(String packageName, PackageParser.ServiceIntentInfo info)10869 protected boolean isPackageForFilter(String packageName, 10870 PackageParser.ServiceIntentInfo info) { 10871 return packageName.equals(info.service.owner.packageName); 10872 } 10873 10874 @Override newResult(PackageParser.ServiceIntentInfo filter, int match, int userId)10875 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 10876 int match, int userId) { 10877 if (!sUserManager.exists(userId)) return null; 10878 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 10879 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 10880 return null; 10881 } 10882 final PackageParser.Service service = info.service; 10883 PackageSetting ps = (PackageSetting) service.owner.mExtras; 10884 if (ps == null) { 10885 return null; 10886 } 10887 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 10888 ps.readUserState(userId), userId); 10889 if (si == null) { 10890 return null; 10891 } 10892 final ResolveInfo res = new ResolveInfo(); 10893 res.serviceInfo = si; 10894 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10895 res.filter = filter; 10896 } 10897 res.priority = info.getPriority(); 10898 res.preferredOrder = service.owner.mPreferredOrder; 10899 res.match = match; 10900 res.isDefault = info.hasDefault; 10901 res.labelRes = info.labelRes; 10902 res.nonLocalizedLabel = info.nonLocalizedLabel; 10903 res.icon = info.icon; 10904 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 10905 return res; 10906 } 10907 10908 @Override sortResults(List<ResolveInfo> results)10909 protected void sortResults(List<ResolveInfo> results) { 10910 Collections.sort(results, mResolvePrioritySorter); 10911 } 10912 10913 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ServiceIntentInfo filter)10914 protected void dumpFilter(PrintWriter out, String prefix, 10915 PackageParser.ServiceIntentInfo filter) { 10916 out.print(prefix); out.print( 10917 Integer.toHexString(System.identityHashCode(filter.service))); 10918 out.print(' '); 10919 filter.service.printComponentShortName(out); 10920 out.print(" filter "); 10921 out.println(Integer.toHexString(System.identityHashCode(filter))); 10922 } 10923 10924 @Override filterToLabel(PackageParser.ServiceIntentInfo filter)10925 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 10926 return filter.service; 10927 } 10928 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)10929 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10930 PackageParser.Service service = (PackageParser.Service)label; 10931 out.print(prefix); out.print( 10932 Integer.toHexString(System.identityHashCode(service))); 10933 out.print(' '); 10934 service.printComponentShortName(out); 10935 if (count > 1) { 10936 out.print(" ("); out.print(count); out.print(" filters)"); 10937 } 10938 out.println(); 10939 } 10940 10941 // List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 10942 // final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 10943 // final List<ResolveInfo> retList = Lists.newArrayList(); 10944 // while (i.hasNext()) { 10945 // final ResolveInfo resolveInfo = (ResolveInfo) i; 10946 // if (isEnabledLP(resolveInfo.serviceInfo)) { 10947 // retList.add(resolveInfo); 10948 // } 10949 // } 10950 // return retList; 10951 // } 10952 10953 // Keys are String (activity class name), values are Activity. 10954 private final ArrayMap<ComponentName, PackageParser.Service> mServices 10955 = new ArrayMap<ComponentName, PackageParser.Service>(); 10956 private int mFlags; 10957 }; 10958 10959 private final class ProviderIntentResolver 10960 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { queryIntent(Intent intent, String resolvedType, boolean defaultOnly, int userId)10961 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10962 boolean defaultOnly, int userId) { 10963 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10964 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10965 } 10966 queryIntent(Intent intent, String resolvedType, int flags, int userId)10967 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10968 int userId) { 10969 if (!sUserManager.exists(userId)) 10970 return null; 10971 mFlags = flags; 10972 return super.queryIntent(intent, resolvedType, 10973 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10974 } 10975 queryIntentForPackage(Intent intent, String resolvedType, int flags, ArrayList<PackageParser.Provider> packageProviders, int userId)10976 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10977 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 10978 if (!sUserManager.exists(userId)) 10979 return null; 10980 if (packageProviders == null) { 10981 return null; 10982 } 10983 mFlags = flags; 10984 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 10985 final int N = packageProviders.size(); 10986 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 10987 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 10988 10989 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 10990 for (int i = 0; i < N; ++i) { 10991 intentFilters = packageProviders.get(i).intents; 10992 if (intentFilters != null && intentFilters.size() > 0) { 10993 PackageParser.ProviderIntentInfo[] array = 10994 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 10995 intentFilters.toArray(array); 10996 listCut.add(array); 10997 } 10998 } 10999 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11000 } 11001 addProvider(PackageParser.Provider p)11002 public final void addProvider(PackageParser.Provider p) { 11003 if (mProviders.containsKey(p.getComponentName())) { 11004 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 11005 return; 11006 } 11007 11008 mProviders.put(p.getComponentName(), p); 11009 if (DEBUG_SHOW_INFO) { 11010 Log.v(TAG, " " 11011 + (p.info.nonLocalizedLabel != null 11012 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11013 Log.v(TAG, " Class=" + p.info.name); 11014 } 11015 final int NI = p.intents.size(); 11016 int j; 11017 for (j = 0; j < NI; j++) { 11018 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11019 if (DEBUG_SHOW_INFO) { 11020 Log.v(TAG, " IntentFilter:"); 11021 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11022 } 11023 if (!intent.debugCheck()) { 11024 Log.w(TAG, "==> For Provider " + p.info.name); 11025 } 11026 addFilter(intent); 11027 } 11028 } 11029 removeProvider(PackageParser.Provider p)11030 public final void removeProvider(PackageParser.Provider p) { 11031 mProviders.remove(p.getComponentName()); 11032 if (DEBUG_SHOW_INFO) { 11033 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 11034 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11035 Log.v(TAG, " Class=" + p.info.name); 11036 } 11037 final int NI = p.intents.size(); 11038 int j; 11039 for (j = 0; j < NI; j++) { 11040 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11041 if (DEBUG_SHOW_INFO) { 11042 Log.v(TAG, " IntentFilter:"); 11043 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11044 } 11045 removeFilter(intent); 11046 } 11047 } 11048 11049 @Override allowFilterResult( PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest)11050 protected boolean allowFilterResult( 11051 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 11052 ProviderInfo filterPi = filter.provider.info; 11053 for (int i = dest.size() - 1; i >= 0; i--) { 11054 ProviderInfo destPi = dest.get(i).providerInfo; 11055 if (destPi.name == filterPi.name 11056 && destPi.packageName == filterPi.packageName) { 11057 return false; 11058 } 11059 } 11060 return true; 11061 } 11062 11063 @Override newArray(int size)11064 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 11065 return new PackageParser.ProviderIntentInfo[size]; 11066 } 11067 11068 @Override isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId)11069 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 11070 if (!sUserManager.exists(userId)) 11071 return true; 11072 PackageParser.Package p = filter.provider.owner; 11073 if (p != null) { 11074 PackageSetting ps = (PackageSetting) p.mExtras; 11075 if (ps != null) { 11076 // System apps are never considered stopped for purposes of 11077 // filtering, because there may be no way for the user to 11078 // actually re-launch them. 11079 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11080 && ps.getStopped(userId); 11081 } 11082 } 11083 return false; 11084 } 11085 11086 @Override isPackageForFilter(String packageName, PackageParser.ProviderIntentInfo info)11087 protected boolean isPackageForFilter(String packageName, 11088 PackageParser.ProviderIntentInfo info) { 11089 return packageName.equals(info.provider.owner.packageName); 11090 } 11091 11092 @Override newResult(PackageParser.ProviderIntentInfo filter, int match, int userId)11093 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 11094 int match, int userId) { 11095 if (!sUserManager.exists(userId)) 11096 return null; 11097 final PackageParser.ProviderIntentInfo info = filter; 11098 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 11099 return null; 11100 } 11101 final PackageParser.Provider provider = info.provider; 11102 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 11103 if (ps == null) { 11104 return null; 11105 } 11106 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 11107 ps.readUserState(userId), userId); 11108 if (pi == null) { 11109 return null; 11110 } 11111 final ResolveInfo res = new ResolveInfo(); 11112 res.providerInfo = pi; 11113 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 11114 res.filter = filter; 11115 } 11116 res.priority = info.getPriority(); 11117 res.preferredOrder = provider.owner.mPreferredOrder; 11118 res.match = match; 11119 res.isDefault = info.hasDefault; 11120 res.labelRes = info.labelRes; 11121 res.nonLocalizedLabel = info.nonLocalizedLabel; 11122 res.icon = info.icon; 11123 res.system = res.providerInfo.applicationInfo.isSystemApp(); 11124 return res; 11125 } 11126 11127 @Override sortResults(List<ResolveInfo> results)11128 protected void sortResults(List<ResolveInfo> results) { 11129 Collections.sort(results, mResolvePrioritySorter); 11130 } 11131 11132 @Override dumpFilter(PrintWriter out, String prefix, PackageParser.ProviderIntentInfo filter)11133 protected void dumpFilter(PrintWriter out, String prefix, 11134 PackageParser.ProviderIntentInfo filter) { 11135 out.print(prefix); 11136 out.print( 11137 Integer.toHexString(System.identityHashCode(filter.provider))); 11138 out.print(' '); 11139 filter.provider.printComponentShortName(out); 11140 out.print(" filter "); 11141 out.println(Integer.toHexString(System.identityHashCode(filter))); 11142 } 11143 11144 @Override filterToLabel(PackageParser.ProviderIntentInfo filter)11145 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 11146 return filter.provider; 11147 } 11148 dumpFilterLabel(PrintWriter out, String prefix, Object label, int count)11149 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11150 PackageParser.Provider provider = (PackageParser.Provider)label; 11151 out.print(prefix); out.print( 11152 Integer.toHexString(System.identityHashCode(provider))); 11153 out.print(' '); 11154 provider.printComponentShortName(out); 11155 if (count > 1) { 11156 out.print(" ("); out.print(count); out.print(" filters)"); 11157 } 11158 out.println(); 11159 } 11160 11161 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 11162 = new ArrayMap<ComponentName, PackageParser.Provider>(); 11163 private int mFlags; 11164 } 11165 11166 private static final class EphemeralIntentResolver 11167 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 11168 @Override newArray(int size)11169 protected EphemeralResolveIntentInfo[] newArray(int size) { 11170 return new EphemeralResolveIntentInfo[size]; 11171 } 11172 11173 @Override isPackageForFilter(String packageName, EphemeralResolveIntentInfo info)11174 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 11175 return true; 11176 } 11177 11178 @Override newResult(EphemeralResolveIntentInfo info, int match, int userId)11179 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 11180 int userId) { 11181 if (!sUserManager.exists(userId)) { 11182 return null; 11183 } 11184 return info.getEphemeralResolveInfo(); 11185 } 11186 } 11187 11188 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 11189 new Comparator<ResolveInfo>() { 11190 public int compare(ResolveInfo r1, ResolveInfo r2) { 11191 int v1 = r1.priority; 11192 int v2 = r2.priority; 11193 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 11194 if (v1 != v2) { 11195 return (v1 > v2) ? -1 : 1; 11196 } 11197 v1 = r1.preferredOrder; 11198 v2 = r2.preferredOrder; 11199 if (v1 != v2) { 11200 return (v1 > v2) ? -1 : 1; 11201 } 11202 if (r1.isDefault != r2.isDefault) { 11203 return r1.isDefault ? -1 : 1; 11204 } 11205 v1 = r1.match; 11206 v2 = r2.match; 11207 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 11208 if (v1 != v2) { 11209 return (v1 > v2) ? -1 : 1; 11210 } 11211 if (r1.system != r2.system) { 11212 return r1.system ? -1 : 1; 11213 } 11214 if (r1.activityInfo != null) { 11215 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 11216 } 11217 if (r1.serviceInfo != null) { 11218 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 11219 } 11220 if (r1.providerInfo != null) { 11221 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 11222 } 11223 return 0; 11224 } 11225 }; 11226 11227 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 11228 new Comparator<ProviderInfo>() { 11229 public int compare(ProviderInfo p1, ProviderInfo p2) { 11230 final int v1 = p1.initOrder; 11231 final int v2 = p2.initOrder; 11232 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 11233 } 11234 }; 11235 sendPackageBroadcast(final String action, final String pkg, final Bundle extras, final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, final int[] userIds)11236 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 11237 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 11238 final int[] userIds) { 11239 mHandler.post(new Runnable() { 11240 @Override 11241 public void run() { 11242 try { 11243 final IActivityManager am = ActivityManagerNative.getDefault(); 11244 if (am == null) return; 11245 final int[] resolvedUserIds; 11246 if (userIds == null) { 11247 resolvedUserIds = am.getRunningUserIds(); 11248 } else { 11249 resolvedUserIds = userIds; 11250 } 11251 for (int id : resolvedUserIds) { 11252 final Intent intent = new Intent(action, 11253 pkg != null ? Uri.fromParts("package", pkg, null) : null); 11254 if (extras != null) { 11255 intent.putExtras(extras); 11256 } 11257 if (targetPkg != null) { 11258 intent.setPackage(targetPkg); 11259 } 11260 // Modify the UID when posting to other users 11261 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 11262 if (uid > 0 && UserHandle.getUserId(uid) != id) { 11263 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 11264 intent.putExtra(Intent.EXTRA_UID, uid); 11265 } 11266 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 11267 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 11268 if (DEBUG_BROADCASTS) { 11269 RuntimeException here = new RuntimeException("here"); 11270 here.fillInStackTrace(); 11271 Slog.d(TAG, "Sending to user " + id + ": " 11272 + intent.toShortString(false, true, false, false) 11273 + " " + intent.getExtras(), here); 11274 } 11275 am.broadcastIntent(null, intent, null, finishedReceiver, 11276 0, null, null, null, android.app.AppOpsManager.OP_NONE, 11277 null, finishedReceiver != null, false, id); 11278 } 11279 } catch (RemoteException ex) { 11280 } 11281 } 11282 }); 11283 } 11284 11285 /** 11286 * Check if the external storage media is available. This is true if there 11287 * is a mounted external storage medium or if the external storage is 11288 * emulated. 11289 */ isExternalMediaAvailable()11290 private boolean isExternalMediaAvailable() { 11291 return mMediaMounted || Environment.isExternalStorageEmulated(); 11292 } 11293 11294 @Override nextPackageToClean(PackageCleanItem lastPackage)11295 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 11296 // writer 11297 synchronized (mPackages) { 11298 if (!isExternalMediaAvailable()) { 11299 // If the external storage is no longer mounted at this point, 11300 // the caller may not have been able to delete all of this 11301 // packages files and can not delete any more. Bail. 11302 return null; 11303 } 11304 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 11305 if (lastPackage != null) { 11306 pkgs.remove(lastPackage); 11307 } 11308 if (pkgs.size() > 0) { 11309 return pkgs.get(0); 11310 } 11311 } 11312 return null; 11313 } 11314 schedulePackageCleaning(String packageName, int userId, boolean andCode)11315 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 11316 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 11317 userId, andCode ? 1 : 0, packageName); 11318 if (mSystemReady) { 11319 msg.sendToTarget(); 11320 } else { 11321 if (mPostSystemReadyMessages == null) { 11322 mPostSystemReadyMessages = new ArrayList<>(); 11323 } 11324 mPostSystemReadyMessages.add(msg); 11325 } 11326 } 11327 startCleaningPackages()11328 void startCleaningPackages() { 11329 // reader 11330 if (!isExternalMediaAvailable()) { 11331 return; 11332 } 11333 synchronized (mPackages) { 11334 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 11335 return; 11336 } 11337 } 11338 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 11339 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 11340 IActivityManager am = ActivityManagerNative.getDefault(); 11341 if (am != null) { 11342 try { 11343 am.startService(null, intent, null, mContext.getOpPackageName(), 11344 UserHandle.USER_SYSTEM); 11345 } catch (RemoteException e) { 11346 } 11347 } 11348 } 11349 11350 @Override installPackageAsUser(String originPath, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, int userId)11351 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 11352 int installFlags, String installerPackageName, int userId) { 11353 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 11354 11355 final int callingUid = Binder.getCallingUid(); 11356 enforceCrossUserPermission(callingUid, userId, 11357 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 11358 11359 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11360 try { 11361 if (observer != null) { 11362 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 11363 } 11364 } catch (RemoteException re) { 11365 } 11366 return; 11367 } 11368 11369 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 11370 installFlags |= PackageManager.INSTALL_FROM_ADB; 11371 11372 } else { 11373 // Caller holds INSTALL_PACKAGES permission, so we're less strict 11374 // about installerPackageName. 11375 11376 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 11377 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 11378 } 11379 11380 UserHandle user; 11381 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 11382 user = UserHandle.ALL; 11383 } else { 11384 user = new UserHandle(userId); 11385 } 11386 11387 // Only system components can circumvent runtime permissions when installing. 11388 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 11389 && mContext.checkCallingOrSelfPermission(Manifest.permission 11390 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 11391 throw new SecurityException("You need the " 11392 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 11393 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 11394 } 11395 11396 final File originFile = new File(originPath); 11397 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 11398 11399 final Message msg = mHandler.obtainMessage(INIT_COPY); 11400 final VerificationInfo verificationInfo = new VerificationInfo( 11401 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 11402 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 11403 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 11404 null /*packageAbiOverride*/, null /*grantedPermissions*/, 11405 null /*certificates*/); 11406 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 11407 msg.obj = params; 11408 11409 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 11410 System.identityHashCode(msg.obj)); 11411 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11412 System.identityHashCode(msg.obj)); 11413 11414 mHandler.sendMessage(msg); 11415 } 11416 installStage(String packageName, File stagedDir, String stagedCid, IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, String installerPackageName, int installerUid, UserHandle user, Certificate[][] certificates)11417 void installStage(String packageName, File stagedDir, String stagedCid, 11418 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 11419 String installerPackageName, int installerUid, UserHandle user, 11420 Certificate[][] certificates) { 11421 if (DEBUG_EPHEMERAL) { 11422 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11423 Slog.d(TAG, "Ephemeral install of " + packageName); 11424 } 11425 } 11426 final VerificationInfo verificationInfo = new VerificationInfo( 11427 sessionParams.originatingUri, sessionParams.referrerUri, 11428 sessionParams.originatingUid, installerUid); 11429 11430 final OriginInfo origin; 11431 if (stagedDir != null) { 11432 origin = OriginInfo.fromStagedFile(stagedDir); 11433 } else { 11434 origin = OriginInfo.fromStagedContainer(stagedCid); 11435 } 11436 11437 final Message msg = mHandler.obtainMessage(INIT_COPY); 11438 final InstallParams params = new InstallParams(origin, null, observer, 11439 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 11440 verificationInfo, user, sessionParams.abiOverride, 11441 sessionParams.grantedRuntimePermissions, certificates); 11442 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 11443 msg.obj = params; 11444 11445 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 11446 System.identityHashCode(msg.obj)); 11447 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11448 System.identityHashCode(msg.obj)); 11449 11450 mHandler.sendMessage(msg); 11451 } 11452 sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId)11453 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 11454 int userId) { 11455 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 11456 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 11457 } 11458 sendPackageAddedForUser(String packageName, boolean isSystem, int appId, int userId)11459 private void sendPackageAddedForUser(String packageName, boolean isSystem, 11460 int appId, int userId) { 11461 Bundle extras = new Bundle(1); 11462 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 11463 11464 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 11465 packageName, extras, 0, null, null, new int[] {userId}); 11466 try { 11467 IActivityManager am = ActivityManagerNative.getDefault(); 11468 if (isSystem && am.isUserRunning(userId, 0)) { 11469 // The just-installed/enabled app is bundled on the system, so presumed 11470 // to be able to run automatically without needing an explicit launch. 11471 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 11472 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 11473 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 11474 .setPackage(packageName); 11475 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 11476 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 11477 } 11478 } catch (RemoteException e) { 11479 // shouldn't happen 11480 Slog.w(TAG, "Unable to bootstrap installed package", e); 11481 } 11482 } 11483 11484 @Override setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId)11485 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 11486 int userId) { 11487 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11488 PackageSetting pkgSetting; 11489 final int uid = Binder.getCallingUid(); 11490 enforceCrossUserPermission(uid, userId, 11491 true /* requireFullPermission */, true /* checkShell */, 11492 "setApplicationHiddenSetting for user " + userId); 11493 11494 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 11495 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 11496 return false; 11497 } 11498 11499 long callingId = Binder.clearCallingIdentity(); 11500 try { 11501 boolean sendAdded = false; 11502 boolean sendRemoved = false; 11503 // writer 11504 synchronized (mPackages) { 11505 pkgSetting = mSettings.mPackages.get(packageName); 11506 if (pkgSetting == null) { 11507 return false; 11508 } 11509 // Do not allow "android" is being disabled 11510 if ("android".equals(packageName)) { 11511 Slog.w(TAG, "Cannot hide package: android"); 11512 return false; 11513 } 11514 // Only allow protected packages to hide themselves. 11515 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 11516 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11517 Slog.w(TAG, "Not hiding protected package: " + packageName); 11518 return false; 11519 } 11520 11521 if (pkgSetting.getHidden(userId) != hidden) { 11522 pkgSetting.setHidden(hidden, userId); 11523 mSettings.writePackageRestrictionsLPr(userId); 11524 if (hidden) { 11525 sendRemoved = true; 11526 } else { 11527 sendAdded = true; 11528 } 11529 } 11530 } 11531 if (sendAdded) { 11532 sendPackageAddedForUser(packageName, pkgSetting, userId); 11533 return true; 11534 } 11535 if (sendRemoved) { 11536 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 11537 "hiding pkg"); 11538 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 11539 return true; 11540 } 11541 } finally { 11542 Binder.restoreCallingIdentity(callingId); 11543 } 11544 return false; 11545 } 11546 sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, int userId)11547 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 11548 int userId) { 11549 final PackageRemovedInfo info = new PackageRemovedInfo(); 11550 info.removedPackage = packageName; 11551 info.removedUsers = new int[] {userId}; 11552 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 11553 info.sendPackageRemovedBroadcasts(true /*killApp*/); 11554 } 11555 sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended)11556 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 11557 if (pkgList.length > 0) { 11558 Bundle extras = new Bundle(1); 11559 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 11560 11561 sendPackageBroadcast( 11562 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 11563 : Intent.ACTION_PACKAGES_UNSUSPENDED, 11564 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 11565 new int[] {userId}); 11566 } 11567 } 11568 11569 /** 11570 * Returns true if application is not found or there was an error. Otherwise it returns 11571 * the hidden state of the package for the given user. 11572 */ 11573 @Override getApplicationHiddenSettingAsUser(String packageName, int userId)11574 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 11575 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11576 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11577 true /* requireFullPermission */, false /* checkShell */, 11578 "getApplicationHidden for user " + userId); 11579 PackageSetting pkgSetting; 11580 long callingId = Binder.clearCallingIdentity(); 11581 try { 11582 // writer 11583 synchronized (mPackages) { 11584 pkgSetting = mSettings.mPackages.get(packageName); 11585 if (pkgSetting == null) { 11586 return true; 11587 } 11588 return pkgSetting.getHidden(userId); 11589 } 11590 } finally { 11591 Binder.restoreCallingIdentity(callingId); 11592 } 11593 } 11594 11595 /** 11596 * @hide 11597 */ 11598 @Override installExistingPackageAsUser(String packageName, int userId)11599 public int installExistingPackageAsUser(String packageName, int userId) { 11600 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 11601 null); 11602 PackageSetting pkgSetting; 11603 final int uid = Binder.getCallingUid(); 11604 enforceCrossUserPermission(uid, userId, 11605 true /* requireFullPermission */, true /* checkShell */, 11606 "installExistingPackage for user " + userId); 11607 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11608 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 11609 } 11610 11611 long callingId = Binder.clearCallingIdentity(); 11612 try { 11613 boolean installed = false; 11614 11615 // writer 11616 synchronized (mPackages) { 11617 pkgSetting = mSettings.mPackages.get(packageName); 11618 if (pkgSetting == null) { 11619 return PackageManager.INSTALL_FAILED_INVALID_URI; 11620 } 11621 if (!pkgSetting.getInstalled(userId)) { 11622 pkgSetting.setInstalled(true, userId); 11623 pkgSetting.setHidden(false, userId); 11624 mSettings.writePackageRestrictionsLPr(userId); 11625 installed = true; 11626 } 11627 } 11628 11629 if (installed) { 11630 if (pkgSetting.pkg != null) { 11631 synchronized (mInstallLock) { 11632 // We don't need to freeze for a brand new install 11633 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 11634 } 11635 } 11636 sendPackageAddedForUser(packageName, pkgSetting, userId); 11637 } 11638 } finally { 11639 Binder.restoreCallingIdentity(callingId); 11640 } 11641 11642 return PackageManager.INSTALL_SUCCEEDED; 11643 } 11644 isUserRestricted(int userId, String restrictionKey)11645 boolean isUserRestricted(int userId, String restrictionKey) { 11646 Bundle restrictions = sUserManager.getUserRestrictions(userId); 11647 if (restrictions.getBoolean(restrictionKey, false)) { 11648 Log.w(TAG, "User is restricted: " + restrictionKey); 11649 return true; 11650 } 11651 return false; 11652 } 11653 11654 @Override setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, int userId)11655 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 11656 int userId) { 11657 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11658 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11659 true /* requireFullPermission */, true /* checkShell */, 11660 "setPackagesSuspended for user " + userId); 11661 11662 if (ArrayUtils.isEmpty(packageNames)) { 11663 return packageNames; 11664 } 11665 11666 // List of package names for whom the suspended state has changed. 11667 List<String> changedPackages = new ArrayList<>(packageNames.length); 11668 // List of package names for whom the suspended state is not set as requested in this 11669 // method. 11670 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 11671 long callingId = Binder.clearCallingIdentity(); 11672 try { 11673 for (int i = 0; i < packageNames.length; i++) { 11674 String packageName = packageNames[i]; 11675 boolean changed = false; 11676 final int appId; 11677 synchronized (mPackages) { 11678 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11679 if (pkgSetting == null) { 11680 Slog.w(TAG, "Could not find package setting for package \"" + packageName 11681 + "\". Skipping suspending/un-suspending."); 11682 unactionedPackages.add(packageName); 11683 continue; 11684 } 11685 appId = pkgSetting.appId; 11686 if (pkgSetting.getSuspended(userId) != suspended) { 11687 if (!canSuspendPackageForUserLocked(packageName, userId)) { 11688 unactionedPackages.add(packageName); 11689 continue; 11690 } 11691 pkgSetting.setSuspended(suspended, userId); 11692 mSettings.writePackageRestrictionsLPr(userId); 11693 changed = true; 11694 changedPackages.add(packageName); 11695 } 11696 } 11697 11698 if (changed && suspended) { 11699 killApplication(packageName, UserHandle.getUid(userId, appId), 11700 "suspending package"); 11701 } 11702 } 11703 } finally { 11704 Binder.restoreCallingIdentity(callingId); 11705 } 11706 11707 if (!changedPackages.isEmpty()) { 11708 sendPackagesSuspendedForUser(changedPackages.toArray( 11709 new String[changedPackages.size()]), userId, suspended); 11710 } 11711 11712 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 11713 } 11714 11715 @Override isPackageSuspendedForUser(String packageName, int userId)11716 public boolean isPackageSuspendedForUser(String packageName, int userId) { 11717 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11718 true /* requireFullPermission */, false /* checkShell */, 11719 "isPackageSuspendedForUser for user " + userId); 11720 synchronized (mPackages) { 11721 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11722 if (pkgSetting == null) { 11723 throw new IllegalArgumentException("Unknown target package: " + packageName); 11724 } 11725 return pkgSetting.getSuspended(userId); 11726 } 11727 } 11728 canSuspendPackageForUserLocked(String packageName, int userId)11729 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 11730 if (isPackageDeviceAdmin(packageName, userId)) { 11731 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11732 + "\": has an active device admin"); 11733 return false; 11734 } 11735 11736 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 11737 if (packageName.equals(activeLauncherPackageName)) { 11738 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11739 + "\": contains the active launcher"); 11740 return false; 11741 } 11742 11743 if (packageName.equals(mRequiredInstallerPackage)) { 11744 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11745 + "\": required for package installation"); 11746 return false; 11747 } 11748 11749 if (packageName.equals(mRequiredVerifierPackage)) { 11750 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11751 + "\": required for package verification"); 11752 return false; 11753 } 11754 11755 if (packageName.equals(getDefaultDialerPackageName(userId))) { 11756 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11757 + "\": is the default dialer"); 11758 return false; 11759 } 11760 11761 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11762 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11763 + "\": protected package"); 11764 return false; 11765 } 11766 11767 return true; 11768 } 11769 getActiveLauncherPackageName(int userId)11770 private String getActiveLauncherPackageName(int userId) { 11771 Intent intent = new Intent(Intent.ACTION_MAIN); 11772 intent.addCategory(Intent.CATEGORY_HOME); 11773 ResolveInfo resolveInfo = resolveIntent( 11774 intent, 11775 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 11776 PackageManager.MATCH_DEFAULT_ONLY, 11777 userId); 11778 11779 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 11780 } 11781 getDefaultDialerPackageName(int userId)11782 private String getDefaultDialerPackageName(int userId) { 11783 synchronized (mPackages) { 11784 return mSettings.getDefaultDialerPackageNameLPw(userId); 11785 } 11786 } 11787 11788 @Override verifyPendingInstall(int id, int verificationCode)11789 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 11790 mContext.enforceCallingOrSelfPermission( 11791 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11792 "Only package verification agents can verify applications"); 11793 11794 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 11795 final PackageVerificationResponse response = new PackageVerificationResponse( 11796 verificationCode, Binder.getCallingUid()); 11797 msg.arg1 = id; 11798 msg.obj = response; 11799 mHandler.sendMessage(msg); 11800 } 11801 11802 @Override extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)11803 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 11804 long millisecondsToDelay) { 11805 mContext.enforceCallingOrSelfPermission( 11806 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11807 "Only package verification agents can extend verification timeouts"); 11808 11809 final PackageVerificationState state = mPendingVerification.get(id); 11810 final PackageVerificationResponse response = new PackageVerificationResponse( 11811 verificationCodeAtTimeout, Binder.getCallingUid()); 11812 11813 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 11814 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 11815 } 11816 if (millisecondsToDelay < 0) { 11817 millisecondsToDelay = 0; 11818 } 11819 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 11820 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 11821 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 11822 } 11823 11824 if ((state != null) && !state.timeoutExtended()) { 11825 state.extendTimeout(); 11826 11827 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 11828 msg.arg1 = id; 11829 msg.obj = response; 11830 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 11831 } 11832 } 11833 broadcastPackageVerified(int verificationId, Uri packageUri, int verificationCode, UserHandle user)11834 private void broadcastPackageVerified(int verificationId, Uri packageUri, 11835 int verificationCode, UserHandle user) { 11836 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 11837 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 11838 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11839 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11840 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 11841 11842 mContext.sendBroadcastAsUser(intent, user, 11843 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 11844 } 11845 matchComponentForVerifier(String packageName, List<ResolveInfo> receivers)11846 private ComponentName matchComponentForVerifier(String packageName, 11847 List<ResolveInfo> receivers) { 11848 ActivityInfo targetReceiver = null; 11849 11850 final int NR = receivers.size(); 11851 for (int i = 0; i < NR; i++) { 11852 final ResolveInfo info = receivers.get(i); 11853 if (info.activityInfo == null) { 11854 continue; 11855 } 11856 11857 if (packageName.equals(info.activityInfo.packageName)) { 11858 targetReceiver = info.activityInfo; 11859 break; 11860 } 11861 } 11862 11863 if (targetReceiver == null) { 11864 return null; 11865 } 11866 11867 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 11868 } 11869 matchVerifiers(PackageInfoLite pkgInfo, List<ResolveInfo> receivers, final PackageVerificationState verificationState)11870 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 11871 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 11872 if (pkgInfo.verifiers.length == 0) { 11873 return null; 11874 } 11875 11876 final int N = pkgInfo.verifiers.length; 11877 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 11878 for (int i = 0; i < N; i++) { 11879 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 11880 11881 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 11882 receivers); 11883 if (comp == null) { 11884 continue; 11885 } 11886 11887 final int verifierUid = getUidForVerifier(verifierInfo); 11888 if (verifierUid == -1) { 11889 continue; 11890 } 11891 11892 if (DEBUG_VERIFY) { 11893 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 11894 + " with the correct signature"); 11895 } 11896 sufficientVerifiers.add(comp); 11897 verificationState.addSufficientVerifier(verifierUid); 11898 } 11899 11900 return sufficientVerifiers; 11901 } 11902 getUidForVerifier(VerifierInfo verifierInfo)11903 private int getUidForVerifier(VerifierInfo verifierInfo) { 11904 synchronized (mPackages) { 11905 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 11906 if (pkg == null) { 11907 return -1; 11908 } else if (pkg.mSignatures.length != 1) { 11909 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11910 + " has more than one signature; ignoring"); 11911 return -1; 11912 } 11913 11914 /* 11915 * If the public key of the package's signature does not match 11916 * our expected public key, then this is a different package and 11917 * we should skip. 11918 */ 11919 11920 final byte[] expectedPublicKey; 11921 try { 11922 final Signature verifierSig = pkg.mSignatures[0]; 11923 final PublicKey publicKey = verifierSig.getPublicKey(); 11924 expectedPublicKey = publicKey.getEncoded(); 11925 } catch (CertificateException e) { 11926 return -1; 11927 } 11928 11929 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 11930 11931 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 11932 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11933 + " does not have the expected public key; ignoring"); 11934 return -1; 11935 } 11936 11937 return pkg.applicationInfo.uid; 11938 } 11939 } 11940 11941 @Override finishPackageInstall(int token, boolean didLaunch)11942 public void finishPackageInstall(int token, boolean didLaunch) { 11943 enforceSystemOrRoot("Only the system is allowed to finish installs"); 11944 11945 if (DEBUG_INSTALL) { 11946 Slog.v(TAG, "BM finishing package install for " + token); 11947 } 11948 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11949 11950 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 11951 mHandler.sendMessage(msg); 11952 } 11953 11954 /** 11955 * Get the verification agent timeout. 11956 * 11957 * @return verification timeout in milliseconds 11958 */ getVerificationTimeout()11959 private long getVerificationTimeout() { 11960 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 11961 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 11962 DEFAULT_VERIFICATION_TIMEOUT); 11963 } 11964 11965 /** 11966 * Get the default verification agent response code. 11967 * 11968 * @return default verification response code 11969 */ getDefaultVerificationResponse()11970 private int getDefaultVerificationResponse() { 11971 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11972 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 11973 DEFAULT_VERIFICATION_RESPONSE); 11974 } 11975 11976 /** 11977 * Check whether or not package verification has been enabled. 11978 * 11979 * @return true if verification should be performed 11980 */ isVerificationEnabled(int userId, int installFlags)11981 private boolean isVerificationEnabled(int userId, int installFlags) { 11982 if (!DEFAULT_VERIFY_ENABLE) { 11983 return false; 11984 } 11985 // Ephemeral apps don't get the full verification treatment 11986 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11987 if (DEBUG_EPHEMERAL) { 11988 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 11989 } 11990 return false; 11991 } 11992 11993 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 11994 11995 // Check if installing from ADB 11996 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 11997 // Do not run verification in a test harness environment 11998 if (ActivityManager.isRunningInTestHarness()) { 11999 return false; 12000 } 12001 if (ensureVerifyAppsEnabled) { 12002 return true; 12003 } 12004 // Check if the developer does not want package verification for ADB installs 12005 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12006 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 12007 return false; 12008 } 12009 } 12010 12011 if (ensureVerifyAppsEnabled) { 12012 return true; 12013 } 12014 12015 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12016 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 12017 } 12018 12019 @Override verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)12020 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 12021 throws RemoteException { 12022 mContext.enforceCallingOrSelfPermission( 12023 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 12024 "Only intentfilter verification agents can verify applications"); 12025 12026 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 12027 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 12028 Binder.getCallingUid(), verificationCode, failedDomains); 12029 msg.arg1 = id; 12030 msg.obj = response; 12031 mHandler.sendMessage(msg); 12032 } 12033 12034 @Override getIntentVerificationStatus(String packageName, int userId)12035 public int getIntentVerificationStatus(String packageName, int userId) { 12036 synchronized (mPackages) { 12037 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 12038 } 12039 } 12040 12041 @Override updateIntentVerificationStatus(String packageName, int status, int userId)12042 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 12043 mContext.enforceCallingOrSelfPermission( 12044 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12045 12046 boolean result = false; 12047 synchronized (mPackages) { 12048 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 12049 } 12050 if (result) { 12051 scheduleWritePackageRestrictionsLocked(userId); 12052 } 12053 return result; 12054 } 12055 12056 @Override getIntentFilterVerifications( String packageName)12057 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 12058 String packageName) { 12059 synchronized (mPackages) { 12060 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 12061 } 12062 } 12063 12064 @Override getAllIntentFilters(String packageName)12065 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 12066 if (TextUtils.isEmpty(packageName)) { 12067 return ParceledListSlice.emptyList(); 12068 } 12069 synchronized (mPackages) { 12070 PackageParser.Package pkg = mPackages.get(packageName); 12071 if (pkg == null || pkg.activities == null) { 12072 return ParceledListSlice.emptyList(); 12073 } 12074 final int count = pkg.activities.size(); 12075 ArrayList<IntentFilter> result = new ArrayList<>(); 12076 for (int n=0; n<count; n++) { 12077 PackageParser.Activity activity = pkg.activities.get(n); 12078 if (activity.intents != null && activity.intents.size() > 0) { 12079 result.addAll(activity.intents); 12080 } 12081 } 12082 return new ParceledListSlice<>(result); 12083 } 12084 } 12085 12086 @Override setDefaultBrowserPackageName(String packageName, int userId)12087 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 12088 mContext.enforceCallingOrSelfPermission( 12089 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12090 12091 synchronized (mPackages) { 12092 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 12093 if (packageName != null) { 12094 result |= updateIntentVerificationStatus(packageName, 12095 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 12096 userId); 12097 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 12098 packageName, userId); 12099 } 12100 return result; 12101 } 12102 } 12103 12104 @Override getDefaultBrowserPackageName(int userId)12105 public String getDefaultBrowserPackageName(int userId) { 12106 synchronized (mPackages) { 12107 return mSettings.getDefaultBrowserPackageNameLPw(userId); 12108 } 12109 } 12110 12111 /** 12112 * Get the "allow unknown sources" setting. 12113 * 12114 * @return the current "allow unknown sources" setting 12115 */ getUnknownSourcesSettings()12116 private int getUnknownSourcesSettings() { 12117 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 12118 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 12119 -1); 12120 } 12121 12122 @Override setInstallerPackageName(String targetPackage, String installerPackageName)12123 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 12124 final int uid = Binder.getCallingUid(); 12125 // writer 12126 synchronized (mPackages) { 12127 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 12128 if (targetPackageSetting == null) { 12129 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 12130 } 12131 12132 PackageSetting installerPackageSetting; 12133 if (installerPackageName != null) { 12134 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 12135 if (installerPackageSetting == null) { 12136 throw new IllegalArgumentException("Unknown installer package: " 12137 + installerPackageName); 12138 } 12139 } else { 12140 installerPackageSetting = null; 12141 } 12142 12143 Signature[] callerSignature; 12144 Object obj = mSettings.getUserIdLPr(uid); 12145 if (obj != null) { 12146 if (obj instanceof SharedUserSetting) { 12147 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 12148 } else if (obj instanceof PackageSetting) { 12149 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 12150 } else { 12151 throw new SecurityException("Bad object " + obj + " for uid " + uid); 12152 } 12153 } else { 12154 throw new SecurityException("Unknown calling UID: " + uid); 12155 } 12156 12157 // Verify: can't set installerPackageName to a package that is 12158 // not signed with the same cert as the caller. 12159 if (installerPackageSetting != null) { 12160 if (compareSignatures(callerSignature, 12161 installerPackageSetting.signatures.mSignatures) 12162 != PackageManager.SIGNATURE_MATCH) { 12163 throw new SecurityException( 12164 "Caller does not have same cert as new installer package " 12165 + installerPackageName); 12166 } 12167 } 12168 12169 // Verify: if target already has an installer package, it must 12170 // be signed with the same cert as the caller. 12171 if (targetPackageSetting.installerPackageName != null) { 12172 PackageSetting setting = mSettings.mPackages.get( 12173 targetPackageSetting.installerPackageName); 12174 // If the currently set package isn't valid, then it's always 12175 // okay to change it. 12176 if (setting != null) { 12177 if (compareSignatures(callerSignature, 12178 setting.signatures.mSignatures) 12179 != PackageManager.SIGNATURE_MATCH) { 12180 throw new SecurityException( 12181 "Caller does not have same cert as old installer package " 12182 + targetPackageSetting.installerPackageName); 12183 } 12184 } 12185 } 12186 12187 // Okay! 12188 targetPackageSetting.installerPackageName = installerPackageName; 12189 if (installerPackageName != null) { 12190 mSettings.mInstallerPackages.add(installerPackageName); 12191 } 12192 scheduleWriteSettingsLocked(); 12193 } 12194 } 12195 processPendingInstall(final InstallArgs args, final int currentStatus)12196 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 12197 // Queue up an async operation since the package installation may take a little while. 12198 mHandler.post(new Runnable() { 12199 public void run() { 12200 mHandler.removeCallbacks(this); 12201 // Result object to be returned 12202 PackageInstalledInfo res = new PackageInstalledInfo(); 12203 res.setReturnCode(currentStatus); 12204 res.uid = -1; 12205 res.pkg = null; 12206 res.removedInfo = null; 12207 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12208 args.doPreInstall(res.returnCode); 12209 synchronized (mInstallLock) { 12210 installPackageTracedLI(args, res); 12211 } 12212 args.doPostInstall(res.returnCode, res.uid); 12213 } 12214 12215 // A restore should be performed at this point if (a) the install 12216 // succeeded, (b) the operation is not an update, and (c) the new 12217 // package has not opted out of backup participation. 12218 final boolean update = res.removedInfo != null 12219 && res.removedInfo.removedPackage != null; 12220 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 12221 boolean doRestore = !update 12222 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 12223 12224 // Set up the post-install work request bookkeeping. This will be used 12225 // and cleaned up by the post-install event handling regardless of whether 12226 // there's a restore pass performed. Token values are >= 1. 12227 int token; 12228 if (mNextInstallToken < 0) mNextInstallToken = 1; 12229 token = mNextInstallToken++; 12230 12231 PostInstallData data = new PostInstallData(args, res); 12232 mRunningInstalls.put(token, data); 12233 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 12234 12235 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 12236 // Pass responsibility to the Backup Manager. It will perform a 12237 // restore if appropriate, then pass responsibility back to the 12238 // Package Manager to run the post-install observer callbacks 12239 // and broadcasts. 12240 IBackupManager bm = IBackupManager.Stub.asInterface( 12241 ServiceManager.getService(Context.BACKUP_SERVICE)); 12242 if (bm != null) { 12243 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 12244 + " to BM for possible restore"); 12245 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12246 try { 12247 // TODO: http://b/22388012 12248 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 12249 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 12250 } else { 12251 doRestore = false; 12252 } 12253 } catch (RemoteException e) { 12254 // can't happen; the backup manager is local 12255 } catch (Exception e) { 12256 Slog.e(TAG, "Exception trying to enqueue restore", e); 12257 doRestore = false; 12258 } 12259 } else { 12260 Slog.e(TAG, "Backup Manager not found!"); 12261 doRestore = false; 12262 } 12263 } 12264 12265 if (!doRestore) { 12266 // No restore possible, or the Backup Manager was mysteriously not 12267 // available -- just fire the post-install work request directly. 12268 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 12269 12270 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 12271 12272 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 12273 mHandler.sendMessage(msg); 12274 } 12275 } 12276 }); 12277 } 12278 12279 /** 12280 * Callback from PackageSettings whenever an app is first transitioned out of the 12281 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 12282 * the app was "launched" for a restoreAtInstall operation. Therefore we check 12283 * here whether the app is the target of an ongoing install, and only send the 12284 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 12285 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 12286 * handling. 12287 */ notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId)12288 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 12289 // Serialize this with the rest of the install-process message chain. In the 12290 // restore-at-install case, this Runnable will necessarily run before the 12291 // POST_INSTALL message is processed, so the contents of mRunningInstalls 12292 // are coherent. In the non-restore case, the app has already completed install 12293 // and been launched through some other means, so it is not in a problematic 12294 // state for observers to see the FIRST_LAUNCH signal. 12295 mHandler.post(new Runnable() { 12296 @Override 12297 public void run() { 12298 for (int i = 0; i < mRunningInstalls.size(); i++) { 12299 final PostInstallData data = mRunningInstalls.valueAt(i); 12300 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12301 continue; 12302 } 12303 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 12304 // right package; but is it for the right user? 12305 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 12306 if (userId == data.res.newUsers[uIndex]) { 12307 if (DEBUG_BACKUP) { 12308 Slog.i(TAG, "Package " + pkgName 12309 + " being restored so deferring FIRST_LAUNCH"); 12310 } 12311 return; 12312 } 12313 } 12314 } 12315 } 12316 // didn't find it, so not being restored 12317 if (DEBUG_BACKUP) { 12318 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 12319 } 12320 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 12321 } 12322 }); 12323 } 12324 sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds)12325 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 12326 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 12327 installerPkg, null, userIds); 12328 } 12329 12330 private abstract class HandlerParams { 12331 private static final int MAX_RETRIES = 4; 12332 12333 /** 12334 * Number of times startCopy() has been attempted and had a non-fatal 12335 * error. 12336 */ 12337 private int mRetries = 0; 12338 12339 /** User handle for the user requesting the information or installation. */ 12340 private final UserHandle mUser; 12341 String traceMethod; 12342 int traceCookie; 12343 HandlerParams(UserHandle user)12344 HandlerParams(UserHandle user) { 12345 mUser = user; 12346 } 12347 getUser()12348 UserHandle getUser() { 12349 return mUser; 12350 } 12351 setTraceMethod(String traceMethod)12352 HandlerParams setTraceMethod(String traceMethod) { 12353 this.traceMethod = traceMethod; 12354 return this; 12355 } 12356 setTraceCookie(int traceCookie)12357 HandlerParams setTraceCookie(int traceCookie) { 12358 this.traceCookie = traceCookie; 12359 return this; 12360 } 12361 startCopy()12362 final boolean startCopy() { 12363 boolean res; 12364 try { 12365 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 12366 12367 if (++mRetries > MAX_RETRIES) { 12368 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 12369 mHandler.sendEmptyMessage(MCS_GIVE_UP); 12370 handleServiceError(); 12371 return false; 12372 } else { 12373 handleStartCopy(); 12374 res = true; 12375 } 12376 } catch (RemoteException e) { 12377 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 12378 mHandler.sendEmptyMessage(MCS_RECONNECT); 12379 res = false; 12380 } 12381 handleReturnCode(); 12382 return res; 12383 } 12384 serviceError()12385 final void serviceError() { 12386 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 12387 handleServiceError(); 12388 handleReturnCode(); 12389 } 12390 12391 abstract void handleStartCopy() throws RemoteException; 12392 abstract void handleServiceError(); 12393 abstract void handleReturnCode(); 12394 } 12395 12396 class MeasureParams extends HandlerParams { 12397 private final PackageStats mStats; 12398 private boolean mSuccess; 12399 12400 private final IPackageStatsObserver mObserver; 12401 MeasureParams(PackageStats stats, IPackageStatsObserver observer)12402 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 12403 super(new UserHandle(stats.userHandle)); 12404 mObserver = observer; 12405 mStats = stats; 12406 } 12407 12408 @Override toString()12409 public String toString() { 12410 return "MeasureParams{" 12411 + Integer.toHexString(System.identityHashCode(this)) 12412 + " " + mStats.packageName + "}"; 12413 } 12414 12415 @Override handleStartCopy()12416 void handleStartCopy() throws RemoteException { 12417 synchronized (mInstallLock) { 12418 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 12419 } 12420 12421 if (mSuccess) { 12422 boolean mounted = false; 12423 try { 12424 final String status = Environment.getExternalStorageState(); 12425 mounted = (Environment.MEDIA_MOUNTED.equals(status) 12426 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 12427 } catch (Exception e) { 12428 } 12429 12430 if (mounted) { 12431 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 12432 12433 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 12434 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 12435 12436 mStats.externalDataSize = calculateDirectorySize(mContainerService, 12437 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 12438 12439 // Always subtract cache size, since it's a subdirectory 12440 mStats.externalDataSize -= mStats.externalCacheSize; 12441 12442 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 12443 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 12444 12445 mStats.externalObbSize = calculateDirectorySize(mContainerService, 12446 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 12447 } 12448 } 12449 } 12450 12451 @Override handleReturnCode()12452 void handleReturnCode() { 12453 if (mObserver != null) { 12454 try { 12455 mObserver.onGetStatsCompleted(mStats, mSuccess); 12456 } catch (RemoteException e) { 12457 Slog.i(TAG, "Observer no longer exists."); 12458 } 12459 } 12460 } 12461 12462 @Override handleServiceError()12463 void handleServiceError() { 12464 Slog.e(TAG, "Could not measure application " + mStats.packageName 12465 + " external storage"); 12466 } 12467 } 12468 calculateDirectorySize(IMediaContainerService mcs, File[] paths)12469 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 12470 throws RemoteException { 12471 long result = 0; 12472 for (File path : paths) { 12473 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 12474 } 12475 return result; 12476 } 12477 clearDirectory(IMediaContainerService mcs, File[] paths)12478 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 12479 for (File path : paths) { 12480 try { 12481 mcs.clearDirectory(path.getAbsolutePath()); 12482 } catch (RemoteException e) { 12483 } 12484 } 12485 } 12486 12487 static class OriginInfo { 12488 /** 12489 * Location where install is coming from, before it has been 12490 * copied/renamed into place. This could be a single monolithic APK 12491 * file, or a cluster directory. This location may be untrusted. 12492 */ 12493 final File file; 12494 final String cid; 12495 12496 /** 12497 * Flag indicating that {@link #file} or {@link #cid} has already been 12498 * staged, meaning downstream users don't need to defensively copy the 12499 * contents. 12500 */ 12501 final boolean staged; 12502 12503 /** 12504 * Flag indicating that {@link #file} or {@link #cid} is an already 12505 * installed app that is being moved. 12506 */ 12507 final boolean existing; 12508 12509 final String resolvedPath; 12510 final File resolvedFile; 12511 fromNothing()12512 static OriginInfo fromNothing() { 12513 return new OriginInfo(null, null, false, false); 12514 } 12515 fromUntrustedFile(File file)12516 static OriginInfo fromUntrustedFile(File file) { 12517 return new OriginInfo(file, null, false, false); 12518 } 12519 fromExistingFile(File file)12520 static OriginInfo fromExistingFile(File file) { 12521 return new OriginInfo(file, null, false, true); 12522 } 12523 fromStagedFile(File file)12524 static OriginInfo fromStagedFile(File file) { 12525 return new OriginInfo(file, null, true, false); 12526 } 12527 fromStagedContainer(String cid)12528 static OriginInfo fromStagedContainer(String cid) { 12529 return new OriginInfo(null, cid, true, false); 12530 } 12531 OriginInfo(File file, String cid, boolean staged, boolean existing)12532 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 12533 this.file = file; 12534 this.cid = cid; 12535 this.staged = staged; 12536 this.existing = existing; 12537 12538 if (cid != null) { 12539 resolvedPath = PackageHelper.getSdDir(cid); 12540 resolvedFile = new File(resolvedPath); 12541 } else if (file != null) { 12542 resolvedPath = file.getAbsolutePath(); 12543 resolvedFile = file; 12544 } else { 12545 resolvedPath = null; 12546 resolvedFile = null; 12547 } 12548 } 12549 } 12550 12551 static class MoveInfo { 12552 final int moveId; 12553 final String fromUuid; 12554 final String toUuid; 12555 final String packageName; 12556 final String dataAppName; 12557 final int appId; 12558 final String seinfo; 12559 final int targetSdkVersion; 12560 MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, String dataAppName, int appId, String seinfo, int targetSdkVersion)12561 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 12562 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 12563 this.moveId = moveId; 12564 this.fromUuid = fromUuid; 12565 this.toUuid = toUuid; 12566 this.packageName = packageName; 12567 this.dataAppName = dataAppName; 12568 this.appId = appId; 12569 this.seinfo = seinfo; 12570 this.targetSdkVersion = targetSdkVersion; 12571 } 12572 } 12573 12574 static class VerificationInfo { 12575 /** A constant used to indicate that a uid value is not present. */ 12576 public static final int NO_UID = -1; 12577 12578 /** URI referencing where the package was downloaded from. */ 12579 final Uri originatingUri; 12580 12581 /** HTTP referrer URI associated with the originatingURI. */ 12582 final Uri referrer; 12583 12584 /** UID of the application that the install request originated from. */ 12585 final int originatingUid; 12586 12587 /** UID of application requesting the install */ 12588 final int installerUid; 12589 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid)12590 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 12591 this.originatingUri = originatingUri; 12592 this.referrer = referrer; 12593 this.originatingUid = originatingUid; 12594 this.installerUid = installerUid; 12595 } 12596 } 12597 12598 class InstallParams extends HandlerParams { 12599 final OriginInfo origin; 12600 final MoveInfo move; 12601 final IPackageInstallObserver2 observer; 12602 int installFlags; 12603 final String installerPackageName; 12604 final String volumeUuid; 12605 private InstallArgs mArgs; 12606 private int mRet; 12607 final String packageAbiOverride; 12608 final String[] grantedRuntimePermissions; 12609 final VerificationInfo verificationInfo; 12610 final Certificate[][] certificates; 12611 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, String[] grantedPermissions, Certificate[][] certificates)12612 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12613 int installFlags, String installerPackageName, String volumeUuid, 12614 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 12615 String[] grantedPermissions, Certificate[][] certificates) { 12616 super(user); 12617 this.origin = origin; 12618 this.move = move; 12619 this.observer = observer; 12620 this.installFlags = installFlags; 12621 this.installerPackageName = installerPackageName; 12622 this.volumeUuid = volumeUuid; 12623 this.verificationInfo = verificationInfo; 12624 this.packageAbiOverride = packageAbiOverride; 12625 this.grantedRuntimePermissions = grantedPermissions; 12626 this.certificates = certificates; 12627 } 12628 12629 @Override toString()12630 public String toString() { 12631 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 12632 + " file=" + origin.file + " cid=" + origin.cid + "}"; 12633 } 12634 installLocationPolicy(PackageInfoLite pkgLite)12635 private int installLocationPolicy(PackageInfoLite pkgLite) { 12636 String packageName = pkgLite.packageName; 12637 int installLocation = pkgLite.installLocation; 12638 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12639 // reader 12640 synchronized (mPackages) { 12641 // Currently installed package which the new package is attempting to replace or 12642 // null if no such package is installed. 12643 PackageParser.Package installedPkg = mPackages.get(packageName); 12644 // Package which currently owns the data which the new package will own if installed. 12645 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 12646 // will be null whereas dataOwnerPkg will contain information about the package 12647 // which was uninstalled while keeping its data. 12648 PackageParser.Package dataOwnerPkg = installedPkg; 12649 if (dataOwnerPkg == null) { 12650 PackageSetting ps = mSettings.mPackages.get(packageName); 12651 if (ps != null) { 12652 dataOwnerPkg = ps.pkg; 12653 } 12654 } 12655 12656 if (dataOwnerPkg != null) { 12657 // If installed, the package will get access to data left on the device by its 12658 // predecessor. As a security measure, this is permited only if this is not a 12659 // version downgrade or if the predecessor package is marked as debuggable and 12660 // a downgrade is explicitly requested. 12661 // 12662 // On debuggable platform builds, downgrades are permitted even for 12663 // non-debuggable packages to make testing easier. Debuggable platform builds do 12664 // not offer security guarantees and thus it's OK to disable some security 12665 // mechanisms to make debugging/testing easier on those builds. However, even on 12666 // debuggable builds downgrades of packages are permitted only if requested via 12667 // installFlags. This is because we aim to keep the behavior of debuggable 12668 // platform builds as close as possible to the behavior of non-debuggable 12669 // platform builds. 12670 final boolean downgradeRequested = 12671 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 12672 final boolean packageDebuggable = 12673 (dataOwnerPkg.applicationInfo.flags 12674 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 12675 final boolean downgradePermitted = 12676 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 12677 if (!downgradePermitted) { 12678 try { 12679 checkDowngrade(dataOwnerPkg, pkgLite); 12680 } catch (PackageManagerException e) { 12681 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 12682 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 12683 } 12684 } 12685 } 12686 12687 if (installedPkg != null) { 12688 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 12689 // Check for updated system application. 12690 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 12691 if (onSd) { 12692 Slog.w(TAG, "Cannot install update to system app on sdcard"); 12693 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 12694 } 12695 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12696 } else { 12697 if (onSd) { 12698 // Install flag overrides everything. 12699 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12700 } 12701 // If current upgrade specifies particular preference 12702 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 12703 // Application explicitly specified internal. 12704 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12705 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 12706 // App explictly prefers external. Let policy decide 12707 } else { 12708 // Prefer previous location 12709 if (isExternal(installedPkg)) { 12710 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12711 } 12712 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12713 } 12714 } 12715 } else { 12716 // Invalid install. Return error code 12717 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 12718 } 12719 } 12720 } 12721 // All the special cases have been taken care of. 12722 // Return result based on recommended install location. 12723 if (onSd) { 12724 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12725 } 12726 return pkgLite.recommendedInstallLocation; 12727 } 12728 12729 /* 12730 * Invoke remote method to get package information and install 12731 * location values. Override install location based on default 12732 * policy if needed and then create install arguments based 12733 * on the install location. 12734 */ handleStartCopy()12735 public void handleStartCopy() throws RemoteException { 12736 int ret = PackageManager.INSTALL_SUCCEEDED; 12737 12738 // If we're already staged, we've firmly committed to an install location 12739 if (origin.staged) { 12740 if (origin.file != null) { 12741 installFlags |= PackageManager.INSTALL_INTERNAL; 12742 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 12743 } else if (origin.cid != null) { 12744 installFlags |= PackageManager.INSTALL_EXTERNAL; 12745 installFlags &= ~PackageManager.INSTALL_INTERNAL; 12746 } else { 12747 throw new IllegalStateException("Invalid stage location"); 12748 } 12749 } 12750 12751 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12752 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 12753 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12754 PackageInfoLite pkgLite = null; 12755 12756 if (onInt && onSd) { 12757 // Check if both bits are set. 12758 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 12759 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12760 } else if (onSd && ephemeral) { 12761 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 12762 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12763 } else { 12764 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 12765 packageAbiOverride); 12766 12767 if (DEBUG_EPHEMERAL && ephemeral) { 12768 Slog.v(TAG, "pkgLite for install: " + pkgLite); 12769 } 12770 12771 /* 12772 * If we have too little free space, try to free cache 12773 * before giving up. 12774 */ 12775 if (!origin.staged && pkgLite.recommendedInstallLocation 12776 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 12777 // TODO: focus freeing disk space on the target device 12778 final StorageManager storage = StorageManager.from(mContext); 12779 final long lowThreshold = storage.getStorageLowBytes( 12780 Environment.getDataDirectory()); 12781 12782 final long sizeBytes = mContainerService.calculateInstalledSize( 12783 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 12784 12785 try { 12786 mInstaller.freeCache(null, sizeBytes + lowThreshold); 12787 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 12788 installFlags, packageAbiOverride); 12789 } catch (InstallerException e) { 12790 Slog.w(TAG, "Failed to free cache", e); 12791 } 12792 12793 /* 12794 * The cache free must have deleted the file we 12795 * downloaded to install. 12796 * 12797 * TODO: fix the "freeCache" call to not delete 12798 * the file we care about. 12799 */ 12800 if (pkgLite.recommendedInstallLocation 12801 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 12802 pkgLite.recommendedInstallLocation 12803 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 12804 } 12805 } 12806 } 12807 12808 if (ret == PackageManager.INSTALL_SUCCEEDED) { 12809 int loc = pkgLite.recommendedInstallLocation; 12810 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 12811 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12812 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 12813 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 12814 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 12815 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12816 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 12817 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 12818 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 12819 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 12820 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 12821 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 12822 } else { 12823 // Override with defaults if needed. 12824 loc = installLocationPolicy(pkgLite); 12825 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 12826 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 12827 } else if (!onSd && !onInt) { 12828 // Override install location with flags 12829 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 12830 // Set the flag to install on external media. 12831 installFlags |= PackageManager.INSTALL_EXTERNAL; 12832 installFlags &= ~PackageManager.INSTALL_INTERNAL; 12833 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 12834 if (DEBUG_EPHEMERAL) { 12835 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 12836 } 12837 installFlags |= PackageManager.INSTALL_EPHEMERAL; 12838 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 12839 |PackageManager.INSTALL_INTERNAL); 12840 } else { 12841 // Make sure the flag for installing on external 12842 // media is unset 12843 installFlags |= PackageManager.INSTALL_INTERNAL; 12844 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 12845 } 12846 } 12847 } 12848 } 12849 12850 final InstallArgs args = createInstallArgs(this); 12851 mArgs = args; 12852 12853 if (ret == PackageManager.INSTALL_SUCCEEDED) { 12854 // TODO: http://b/22976637 12855 // Apps installed for "all" users use the device owner to verify the app 12856 UserHandle verifierUser = getUser(); 12857 if (verifierUser == UserHandle.ALL) { 12858 verifierUser = UserHandle.SYSTEM; 12859 } 12860 12861 /* 12862 * Determine if we have any installed package verifiers. If we 12863 * do, then we'll defer to them to verify the packages. 12864 */ 12865 final int requiredUid = mRequiredVerifierPackage == null ? -1 12866 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 12867 verifierUser.getIdentifier()); 12868 if (!origin.existing && requiredUid != -1 12869 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 12870 final Intent verification = new Intent( 12871 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 12872 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12873 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 12874 PACKAGE_MIME_TYPE); 12875 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 12876 12877 // Query all live verifiers based on current user state 12878 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 12879 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 12880 12881 if (DEBUG_VERIFY) { 12882 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 12883 + verification.toString() + " with " + pkgLite.verifiers.length 12884 + " optional verifiers"); 12885 } 12886 12887 final int verificationId = mPendingVerificationToken++; 12888 12889 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 12890 12891 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 12892 installerPackageName); 12893 12894 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 12895 installFlags); 12896 12897 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 12898 pkgLite.packageName); 12899 12900 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 12901 pkgLite.versionCode); 12902 12903 if (verificationInfo != null) { 12904 if (verificationInfo.originatingUri != null) { 12905 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 12906 verificationInfo.originatingUri); 12907 } 12908 if (verificationInfo.referrer != null) { 12909 verification.putExtra(Intent.EXTRA_REFERRER, 12910 verificationInfo.referrer); 12911 } 12912 if (verificationInfo.originatingUid >= 0) { 12913 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 12914 verificationInfo.originatingUid); 12915 } 12916 if (verificationInfo.installerUid >= 0) { 12917 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 12918 verificationInfo.installerUid); 12919 } 12920 } 12921 12922 final PackageVerificationState verificationState = new PackageVerificationState( 12923 requiredUid, args); 12924 12925 mPendingVerification.append(verificationId, verificationState); 12926 12927 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 12928 receivers, verificationState); 12929 12930 /* 12931 * If any sufficient verifiers were listed in the package 12932 * manifest, attempt to ask them. 12933 */ 12934 if (sufficientVerifiers != null) { 12935 final int N = sufficientVerifiers.size(); 12936 if (N == 0) { 12937 Slog.i(TAG, "Additional verifiers required, but none installed."); 12938 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 12939 } else { 12940 for (int i = 0; i < N; i++) { 12941 final ComponentName verifierComponent = sufficientVerifiers.get(i); 12942 12943 final Intent sufficientIntent = new Intent(verification); 12944 sufficientIntent.setComponent(verifierComponent); 12945 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 12946 } 12947 } 12948 } 12949 12950 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 12951 mRequiredVerifierPackage, receivers); 12952 if (ret == PackageManager.INSTALL_SUCCEEDED 12953 && mRequiredVerifierPackage != null) { 12954 Trace.asyncTraceBegin( 12955 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 12956 /* 12957 * Send the intent to the required verification agent, 12958 * but only start the verification timeout after the 12959 * target BroadcastReceivers have run. 12960 */ 12961 verification.setComponent(requiredVerifierComponent); 12962 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 12963 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12964 new BroadcastReceiver() { 12965 @Override 12966 public void onReceive(Context context, Intent intent) { 12967 final Message msg = mHandler 12968 .obtainMessage(CHECK_PENDING_VERIFICATION); 12969 msg.arg1 = verificationId; 12970 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 12971 } 12972 }, null, 0, null, null); 12973 12974 /* 12975 * We don't want the copy to proceed until verification 12976 * succeeds, so null out this field. 12977 */ 12978 mArgs = null; 12979 } 12980 } else { 12981 /* 12982 * No package verification is enabled, so immediately start 12983 * the remote call to initiate copy using temporary file. 12984 */ 12985 ret = args.copyApk(mContainerService, true); 12986 } 12987 } 12988 12989 mRet = ret; 12990 } 12991 12992 @Override handleReturnCode()12993 void handleReturnCode() { 12994 // If mArgs is null, then MCS couldn't be reached. When it 12995 // reconnects, it will try again to install. At that point, this 12996 // will succeed. 12997 if (mArgs != null) { 12998 processPendingInstall(mArgs, mRet); 12999 } 13000 } 13001 13002 @Override handleServiceError()13003 void handleServiceError() { 13004 mArgs = createInstallArgs(this); 13005 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13006 } 13007 isForwardLocked()13008 public boolean isForwardLocked() { 13009 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13010 } 13011 } 13012 13013 /** 13014 * Used during creation of InstallArgs 13015 * 13016 * @param installFlags package installation flags 13017 * @return true if should be installed on external storage 13018 */ installOnExternalAsec(int installFlags)13019 private static boolean installOnExternalAsec(int installFlags) { 13020 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 13021 return false; 13022 } 13023 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 13024 return true; 13025 } 13026 return false; 13027 } 13028 13029 /** 13030 * Used during creation of InstallArgs 13031 * 13032 * @param installFlags package installation flags 13033 * @return true if should be installed as forward locked 13034 */ installForwardLocked(int installFlags)13035 private static boolean installForwardLocked(int installFlags) { 13036 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13037 } 13038 createInstallArgs(InstallParams params)13039 private InstallArgs createInstallArgs(InstallParams params) { 13040 if (params.move != null) { 13041 return new MoveInstallArgs(params); 13042 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 13043 return new AsecInstallArgs(params); 13044 } else { 13045 return new FileInstallArgs(params); 13046 } 13047 } 13048 13049 /** 13050 * Create args that describe an existing installed package. Typically used 13051 * when cleaning up old installs, or used as a move source. 13052 */ createInstallArgsForExisting(int installFlags, String codePath, String resourcePath, String[] instructionSets)13053 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 13054 String resourcePath, String[] instructionSets) { 13055 final boolean isInAsec; 13056 if (installOnExternalAsec(installFlags)) { 13057 /* Apps on SD card are always in ASEC containers. */ 13058 isInAsec = true; 13059 } else if (installForwardLocked(installFlags) 13060 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 13061 /* 13062 * Forward-locked apps are only in ASEC containers if they're the 13063 * new style 13064 */ 13065 isInAsec = true; 13066 } else { 13067 isInAsec = false; 13068 } 13069 13070 if (isInAsec) { 13071 return new AsecInstallArgs(codePath, instructionSets, 13072 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 13073 } else { 13074 return new FileInstallArgs(codePath, resourcePath, instructionSets); 13075 } 13076 } 13077 13078 static abstract class InstallArgs { 13079 /** @see InstallParams#origin */ 13080 final OriginInfo origin; 13081 /** @see InstallParams#move */ 13082 final MoveInfo move; 13083 13084 final IPackageInstallObserver2 observer; 13085 // Always refers to PackageManager flags only 13086 final int installFlags; 13087 final String installerPackageName; 13088 final String volumeUuid; 13089 final UserHandle user; 13090 final String abiOverride; 13091 final String[] installGrantPermissions; 13092 /** If non-null, drop an async trace when the install completes */ 13093 final String traceMethod; 13094 final int traceCookie; 13095 final Certificate[][] certificates; 13096 13097 // The list of instruction sets supported by this app. This is currently 13098 // only used during the rmdex() phase to clean up resources. We can get rid of this 13099 // if we move dex files under the common app path. 13100 /* nullable */ String[] instructionSets; 13101 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, int installFlags, String installerPackageName, String volumeUuid, UserHandle user, String[] instructionSets, String abiOverride, String[] installGrantPermissions, String traceMethod, int traceCookie, Certificate[][] certificates)13102 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 13103 int installFlags, String installerPackageName, String volumeUuid, 13104 UserHandle user, String[] instructionSets, 13105 String abiOverride, String[] installGrantPermissions, 13106 String traceMethod, int traceCookie, Certificate[][] certificates) { 13107 this.origin = origin; 13108 this.move = move; 13109 this.installFlags = installFlags; 13110 this.observer = observer; 13111 this.installerPackageName = installerPackageName; 13112 this.volumeUuid = volumeUuid; 13113 this.user = user; 13114 this.instructionSets = instructionSets; 13115 this.abiOverride = abiOverride; 13116 this.installGrantPermissions = installGrantPermissions; 13117 this.traceMethod = traceMethod; 13118 this.traceCookie = traceCookie; 13119 this.certificates = certificates; 13120 } 13121 13122 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 13123 abstract int doPreInstall(int status); 13124 13125 /** 13126 * Rename package into final resting place. All paths on the given 13127 * scanned package should be updated to reflect the rename. 13128 */ 13129 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 13130 abstract int doPostInstall(int status, int uid); 13131 13132 /** @see PackageSettingBase#codePathString */ 13133 abstract String getCodePath(); 13134 /** @see PackageSettingBase#resourcePathString */ 13135 abstract String getResourcePath(); 13136 13137 // Need installer lock especially for dex file removal. 13138 abstract void cleanUpResourcesLI(); 13139 abstract boolean doPostDeleteLI(boolean delete); 13140 13141 /** 13142 * Called before the source arguments are copied. This is used mostly 13143 * for MoveParams when it needs to read the source file to put it in the 13144 * destination. 13145 */ doPreCopy()13146 int doPreCopy() { 13147 return PackageManager.INSTALL_SUCCEEDED; 13148 } 13149 13150 /** 13151 * Called after the source arguments are copied. This is used mostly for 13152 * MoveParams when it needs to read the source file to put it in the 13153 * destination. 13154 */ doPostCopy(int uid)13155 int doPostCopy(int uid) { 13156 return PackageManager.INSTALL_SUCCEEDED; 13157 } 13158 isFwdLocked()13159 protected boolean isFwdLocked() { 13160 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13161 } 13162 isExternalAsec()13163 protected boolean isExternalAsec() { 13164 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13165 } 13166 isEphemeral()13167 protected boolean isEphemeral() { 13168 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13169 } 13170 getUser()13171 UserHandle getUser() { 13172 return user; 13173 } 13174 } 13175 removeDexFiles(List<String> allCodePaths, String[] instructionSets)13176 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 13177 if (!allCodePaths.isEmpty()) { 13178 if (instructionSets == null) { 13179 throw new IllegalStateException("instructionSet == null"); 13180 } 13181 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 13182 for (String codePath : allCodePaths) { 13183 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 13184 try { 13185 mInstaller.rmdex(codePath, dexCodeInstructionSet); 13186 } catch (InstallerException ignored) { 13187 } 13188 } 13189 } 13190 } 13191 } 13192 13193 /** 13194 * Logic to handle installation of non-ASEC applications, including copying 13195 * and renaming logic. 13196 */ 13197 class FileInstallArgs extends InstallArgs { 13198 private File codeFile; 13199 private File resourceFile; 13200 13201 // Example topology: 13202 // /data/app/com.example/base.apk 13203 // /data/app/com.example/split_foo.apk 13204 // /data/app/com.example/lib/arm/libfoo.so 13205 // /data/app/com.example/lib/arm64/libfoo.so 13206 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 13207 13208 /** New install */ FileInstallArgs(InstallParams params)13209 FileInstallArgs(InstallParams params) { 13210 super(params.origin, params.move, params.observer, params.installFlags, 13211 params.installerPackageName, params.volumeUuid, 13212 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 13213 params.grantedRuntimePermissions, 13214 params.traceMethod, params.traceCookie, params.certificates); 13215 if (isFwdLocked()) { 13216 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 13217 } 13218 } 13219 13220 /** Existing install */ FileInstallArgs(String codePath, String resourcePath, String[] instructionSets)13221 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 13222 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 13223 null, null, null, 0, null /*certificates*/); 13224 this.codeFile = (codePath != null) ? new File(codePath) : null; 13225 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 13226 } 13227 copyApk(IMediaContainerService imcs, boolean temp)13228 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13229 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 13230 try { 13231 return doCopyApk(imcs, temp); 13232 } finally { 13233 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13234 } 13235 } 13236 doCopyApk(IMediaContainerService imcs, boolean temp)13237 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13238 if (origin.staged) { 13239 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 13240 codeFile = origin.file; 13241 resourceFile = origin.file; 13242 return PackageManager.INSTALL_SUCCEEDED; 13243 } 13244 13245 try { 13246 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13247 final File tempDir = 13248 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 13249 codeFile = tempDir; 13250 resourceFile = tempDir; 13251 } catch (IOException e) { 13252 Slog.w(TAG, "Failed to create copy file: " + e); 13253 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13254 } 13255 13256 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 13257 @Override 13258 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 13259 if (!FileUtils.isValidExtFilename(name)) { 13260 throw new IllegalArgumentException("Invalid filename: " + name); 13261 } 13262 try { 13263 final File file = new File(codeFile, name); 13264 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 13265 O_RDWR | O_CREAT, 0644); 13266 Os.chmod(file.getAbsolutePath(), 0644); 13267 return new ParcelFileDescriptor(fd); 13268 } catch (ErrnoException e) { 13269 throw new RemoteException("Failed to open: " + e.getMessage()); 13270 } 13271 } 13272 }; 13273 13274 int ret = PackageManager.INSTALL_SUCCEEDED; 13275 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 13276 if (ret != PackageManager.INSTALL_SUCCEEDED) { 13277 Slog.e(TAG, "Failed to copy package"); 13278 return ret; 13279 } 13280 13281 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 13282 NativeLibraryHelper.Handle handle = null; 13283 try { 13284 handle = NativeLibraryHelper.Handle.create(codeFile); 13285 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 13286 abiOverride); 13287 } catch (IOException e) { 13288 Slog.e(TAG, "Copying native libraries failed", e); 13289 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13290 } finally { 13291 IoUtils.closeQuietly(handle); 13292 } 13293 13294 return ret; 13295 } 13296 doPreInstall(int status)13297 int doPreInstall(int status) { 13298 if (status != PackageManager.INSTALL_SUCCEEDED) { 13299 cleanUp(); 13300 } 13301 return status; 13302 } 13303 doRename(int status, PackageParser.Package pkg, String oldCodePath)13304 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13305 if (status != PackageManager.INSTALL_SUCCEEDED) { 13306 cleanUp(); 13307 return false; 13308 } 13309 13310 final File targetDir = codeFile.getParentFile(); 13311 final File beforeCodeFile = codeFile; 13312 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 13313 13314 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 13315 try { 13316 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 13317 } catch (ErrnoException e) { 13318 Slog.w(TAG, "Failed to rename", e); 13319 return false; 13320 } 13321 13322 if (!SELinux.restoreconRecursive(afterCodeFile)) { 13323 Slog.w(TAG, "Failed to restorecon"); 13324 return false; 13325 } 13326 13327 // Reflect the rename internally 13328 codeFile = afterCodeFile; 13329 resourceFile = afterCodeFile; 13330 13331 // Reflect the rename in scanned details 13332 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13333 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13334 afterCodeFile, pkg.baseCodePath)); 13335 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13336 afterCodeFile, pkg.splitCodePaths)); 13337 13338 // Reflect the rename in app info 13339 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13340 pkg.setApplicationInfoCodePath(pkg.codePath); 13341 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13342 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13343 pkg.setApplicationInfoResourcePath(pkg.codePath); 13344 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13345 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13346 13347 return true; 13348 } 13349 doPostInstall(int status, int uid)13350 int doPostInstall(int status, int uid) { 13351 if (status != PackageManager.INSTALL_SUCCEEDED) { 13352 cleanUp(); 13353 } 13354 return status; 13355 } 13356 13357 @Override getCodePath()13358 String getCodePath() { 13359 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 13360 } 13361 13362 @Override getResourcePath()13363 String getResourcePath() { 13364 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 13365 } 13366 cleanUp()13367 private boolean cleanUp() { 13368 if (codeFile == null || !codeFile.exists()) { 13369 return false; 13370 } 13371 13372 removeCodePathLI(codeFile); 13373 13374 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 13375 resourceFile.delete(); 13376 } 13377 13378 return true; 13379 } 13380 cleanUpResourcesLI()13381 void cleanUpResourcesLI() { 13382 // Try enumerating all code paths before deleting 13383 List<String> allCodePaths = Collections.EMPTY_LIST; 13384 if (codeFile != null && codeFile.exists()) { 13385 try { 13386 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13387 allCodePaths = pkg.getAllCodePaths(); 13388 } catch (PackageParserException e) { 13389 // Ignored; we tried our best 13390 } 13391 } 13392 13393 cleanUp(); 13394 removeDexFiles(allCodePaths, instructionSets); 13395 } 13396 doPostDeleteLI(boolean delete)13397 boolean doPostDeleteLI(boolean delete) { 13398 // XXX err, shouldn't we respect the delete flag? 13399 cleanUpResourcesLI(); 13400 return true; 13401 } 13402 } 13403 isAsecExternal(String cid)13404 private boolean isAsecExternal(String cid) { 13405 final String asecPath = PackageHelper.getSdFilesystem(cid); 13406 return !asecPath.startsWith(mAsecInternalPath); 13407 } 13408 maybeThrowExceptionForMultiArchCopy(String message, int copyRet)13409 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 13410 PackageManagerException { 13411 if (copyRet < 0) { 13412 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 13413 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 13414 throw new PackageManagerException(copyRet, message); 13415 } 13416 } 13417 } 13418 13419 /** 13420 * Extract the MountService "container ID" from the full code path of an 13421 * .apk. 13422 */ cidFromCodePath(String fullCodePath)13423 static String cidFromCodePath(String fullCodePath) { 13424 int eidx = fullCodePath.lastIndexOf("/"); 13425 String subStr1 = fullCodePath.substring(0, eidx); 13426 int sidx = subStr1.lastIndexOf("/"); 13427 return subStr1.substring(sidx+1, eidx); 13428 } 13429 13430 /** 13431 * Logic to handle installation of ASEC applications, including copying and 13432 * renaming logic. 13433 */ 13434 class AsecInstallArgs extends InstallArgs { 13435 static final String RES_FILE_NAME = "pkg.apk"; 13436 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 13437 13438 String cid; 13439 String packagePath; 13440 String resourcePath; 13441 13442 /** New install */ AsecInstallArgs(InstallParams params)13443 AsecInstallArgs(InstallParams params) { 13444 super(params.origin, params.move, params.observer, params.installFlags, 13445 params.installerPackageName, params.volumeUuid, 13446 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13447 params.grantedRuntimePermissions, 13448 params.traceMethod, params.traceCookie, params.certificates); 13449 } 13450 13451 /** Existing install */ AsecInstallArgs(String fullCodePath, String[] instructionSets, boolean isExternal, boolean isForwardLocked)13452 AsecInstallArgs(String fullCodePath, String[] instructionSets, 13453 boolean isExternal, boolean isForwardLocked) { 13454 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 13455 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13456 instructionSets, null, null, null, 0, null /*certificates*/); 13457 // Hackily pretend we're still looking at a full code path 13458 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 13459 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 13460 } 13461 13462 // Extract cid from fullCodePath 13463 int eidx = fullCodePath.lastIndexOf("/"); 13464 String subStr1 = fullCodePath.substring(0, eidx); 13465 int sidx = subStr1.lastIndexOf("/"); 13466 cid = subStr1.substring(sidx+1, eidx); 13467 setMountPath(subStr1); 13468 } 13469 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked)13470 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 13471 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 13472 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13473 instructionSets, null, null, null, 0, null /*certificates*/); 13474 this.cid = cid; 13475 setMountPath(PackageHelper.getSdDir(cid)); 13476 } 13477 createCopyFile()13478 void createCopyFile() { 13479 cid = mInstallerService.allocateExternalStageCidLegacy(); 13480 } 13481 copyApk(IMediaContainerService imcs, boolean temp)13482 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13483 if (origin.staged && origin.cid != null) { 13484 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 13485 cid = origin.cid; 13486 setMountPath(PackageHelper.getSdDir(cid)); 13487 return PackageManager.INSTALL_SUCCEEDED; 13488 } 13489 13490 if (temp) { 13491 createCopyFile(); 13492 } else { 13493 /* 13494 * Pre-emptively destroy the container since it's destroyed if 13495 * copying fails due to it existing anyway. 13496 */ 13497 PackageHelper.destroySdDir(cid); 13498 } 13499 13500 final String newMountPath = imcs.copyPackageToContainer( 13501 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 13502 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 13503 13504 if (newMountPath != null) { 13505 setMountPath(newMountPath); 13506 return PackageManager.INSTALL_SUCCEEDED; 13507 } else { 13508 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13509 } 13510 } 13511 13512 @Override getCodePath()13513 String getCodePath() { 13514 return packagePath; 13515 } 13516 13517 @Override getResourcePath()13518 String getResourcePath() { 13519 return resourcePath; 13520 } 13521 doPreInstall(int status)13522 int doPreInstall(int status) { 13523 if (status != PackageManager.INSTALL_SUCCEEDED) { 13524 // Destroy container 13525 PackageHelper.destroySdDir(cid); 13526 } else { 13527 boolean mounted = PackageHelper.isContainerMounted(cid); 13528 if (!mounted) { 13529 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 13530 Process.SYSTEM_UID); 13531 if (newMountPath != null) { 13532 setMountPath(newMountPath); 13533 } else { 13534 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13535 } 13536 } 13537 } 13538 return status; 13539 } 13540 doRename(int status, PackageParser.Package pkg, String oldCodePath)13541 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13542 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 13543 String newMountPath = null; 13544 if (PackageHelper.isContainerMounted(cid)) { 13545 // Unmount the container 13546 if (!PackageHelper.unMountSdDir(cid)) { 13547 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 13548 return false; 13549 } 13550 } 13551 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13552 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 13553 " which might be stale. Will try to clean up."); 13554 // Clean up the stale container and proceed to recreate. 13555 if (!PackageHelper.destroySdDir(newCacheId)) { 13556 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 13557 return false; 13558 } 13559 // Successfully cleaned up stale container. Try to rename again. 13560 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13561 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 13562 + " inspite of cleaning it up."); 13563 return false; 13564 } 13565 } 13566 if (!PackageHelper.isContainerMounted(newCacheId)) { 13567 Slog.w(TAG, "Mounting container " + newCacheId); 13568 newMountPath = PackageHelper.mountSdDir(newCacheId, 13569 getEncryptKey(), Process.SYSTEM_UID); 13570 } else { 13571 newMountPath = PackageHelper.getSdDir(newCacheId); 13572 } 13573 if (newMountPath == null) { 13574 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 13575 return false; 13576 } 13577 Log.i(TAG, "Succesfully renamed " + cid + 13578 " to " + newCacheId + 13579 " at new path: " + newMountPath); 13580 cid = newCacheId; 13581 13582 final File beforeCodeFile = new File(packagePath); 13583 setMountPath(newMountPath); 13584 final File afterCodeFile = new File(packagePath); 13585 13586 // Reflect the rename in scanned details 13587 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13588 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13589 afterCodeFile, pkg.baseCodePath)); 13590 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13591 afterCodeFile, pkg.splitCodePaths)); 13592 13593 // Reflect the rename in app info 13594 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13595 pkg.setApplicationInfoCodePath(pkg.codePath); 13596 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13597 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13598 pkg.setApplicationInfoResourcePath(pkg.codePath); 13599 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13600 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13601 13602 return true; 13603 } 13604 setMountPath(String mountPath)13605 private void setMountPath(String mountPath) { 13606 final File mountFile = new File(mountPath); 13607 13608 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 13609 if (monolithicFile.exists()) { 13610 packagePath = monolithicFile.getAbsolutePath(); 13611 if (isFwdLocked()) { 13612 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 13613 } else { 13614 resourcePath = packagePath; 13615 } 13616 } else { 13617 packagePath = mountFile.getAbsolutePath(); 13618 resourcePath = packagePath; 13619 } 13620 } 13621 doPostInstall(int status, int uid)13622 int doPostInstall(int status, int uid) { 13623 if (status != PackageManager.INSTALL_SUCCEEDED) { 13624 cleanUp(); 13625 } else { 13626 final int groupOwner; 13627 final String protectedFile; 13628 if (isFwdLocked()) { 13629 groupOwner = UserHandle.getSharedAppGid(uid); 13630 protectedFile = RES_FILE_NAME; 13631 } else { 13632 groupOwner = -1; 13633 protectedFile = null; 13634 } 13635 13636 if (uid < Process.FIRST_APPLICATION_UID 13637 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 13638 Slog.e(TAG, "Failed to finalize " + cid); 13639 PackageHelper.destroySdDir(cid); 13640 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13641 } 13642 13643 boolean mounted = PackageHelper.isContainerMounted(cid); 13644 if (!mounted) { 13645 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 13646 } 13647 } 13648 return status; 13649 } 13650 cleanUp()13651 private void cleanUp() { 13652 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 13653 13654 // Destroy secure container 13655 PackageHelper.destroySdDir(cid); 13656 } 13657 getAllCodePaths()13658 private List<String> getAllCodePaths() { 13659 final File codeFile = new File(getCodePath()); 13660 if (codeFile != null && codeFile.exists()) { 13661 try { 13662 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13663 return pkg.getAllCodePaths(); 13664 } catch (PackageParserException e) { 13665 // Ignored; we tried our best 13666 } 13667 } 13668 return Collections.EMPTY_LIST; 13669 } 13670 cleanUpResourcesLI()13671 void cleanUpResourcesLI() { 13672 // Enumerate all code paths before deleting 13673 cleanUpResourcesLI(getAllCodePaths()); 13674 } 13675 cleanUpResourcesLI(List<String> allCodePaths)13676 private void cleanUpResourcesLI(List<String> allCodePaths) { 13677 cleanUp(); 13678 removeDexFiles(allCodePaths, instructionSets); 13679 } 13680 getPackageName()13681 String getPackageName() { 13682 return getAsecPackageName(cid); 13683 } 13684 doPostDeleteLI(boolean delete)13685 boolean doPostDeleteLI(boolean delete) { 13686 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 13687 final List<String> allCodePaths = getAllCodePaths(); 13688 boolean mounted = PackageHelper.isContainerMounted(cid); 13689 if (mounted) { 13690 // Unmount first 13691 if (PackageHelper.unMountSdDir(cid)) { 13692 mounted = false; 13693 } 13694 } 13695 if (!mounted && delete) { 13696 cleanUpResourcesLI(allCodePaths); 13697 } 13698 return !mounted; 13699 } 13700 13701 @Override doPreCopy()13702 int doPreCopy() { 13703 if (isFwdLocked()) { 13704 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 13705 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 13706 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13707 } 13708 } 13709 13710 return PackageManager.INSTALL_SUCCEEDED; 13711 } 13712 13713 @Override doPostCopy(int uid)13714 int doPostCopy(int uid) { 13715 if (isFwdLocked()) { 13716 if (uid < Process.FIRST_APPLICATION_UID 13717 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 13718 RES_FILE_NAME)) { 13719 Slog.e(TAG, "Failed to finalize " + cid); 13720 PackageHelper.destroySdDir(cid); 13721 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13722 } 13723 } 13724 13725 return PackageManager.INSTALL_SUCCEEDED; 13726 } 13727 } 13728 13729 /** 13730 * Logic to handle movement of existing installed applications. 13731 */ 13732 class MoveInstallArgs extends InstallArgs { 13733 private File codeFile; 13734 private File resourceFile; 13735 13736 /** New install */ MoveInstallArgs(InstallParams params)13737 MoveInstallArgs(InstallParams params) { 13738 super(params.origin, params.move, params.observer, params.installFlags, 13739 params.installerPackageName, params.volumeUuid, 13740 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13741 params.grantedRuntimePermissions, 13742 params.traceMethod, params.traceCookie, params.certificates); 13743 } 13744 copyApk(IMediaContainerService imcs, boolean temp)13745 int copyApk(IMediaContainerService imcs, boolean temp) { 13746 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 13747 + move.fromUuid + " to " + move.toUuid); 13748 synchronized (mInstaller) { 13749 try { 13750 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 13751 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 13752 } catch (InstallerException e) { 13753 Slog.w(TAG, "Failed to move app", e); 13754 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13755 } 13756 } 13757 13758 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 13759 resourceFile = codeFile; 13760 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 13761 13762 return PackageManager.INSTALL_SUCCEEDED; 13763 } 13764 doPreInstall(int status)13765 int doPreInstall(int status) { 13766 if (status != PackageManager.INSTALL_SUCCEEDED) { 13767 cleanUp(move.toUuid); 13768 } 13769 return status; 13770 } 13771 doRename(int status, PackageParser.Package pkg, String oldCodePath)13772 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13773 if (status != PackageManager.INSTALL_SUCCEEDED) { 13774 cleanUp(move.toUuid); 13775 return false; 13776 } 13777 13778 // Reflect the move in app info 13779 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13780 pkg.setApplicationInfoCodePath(pkg.codePath); 13781 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13782 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13783 pkg.setApplicationInfoResourcePath(pkg.codePath); 13784 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13785 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13786 13787 return true; 13788 } 13789 doPostInstall(int status, int uid)13790 int doPostInstall(int status, int uid) { 13791 if (status == PackageManager.INSTALL_SUCCEEDED) { 13792 cleanUp(move.fromUuid); 13793 } else { 13794 cleanUp(move.toUuid); 13795 } 13796 return status; 13797 } 13798 13799 @Override getCodePath()13800 String getCodePath() { 13801 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 13802 } 13803 13804 @Override getResourcePath()13805 String getResourcePath() { 13806 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 13807 } 13808 cleanUp(String volumeUuid)13809 private boolean cleanUp(String volumeUuid) { 13810 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 13811 move.dataAppName); 13812 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 13813 final int[] userIds = sUserManager.getUserIds(); 13814 synchronized (mInstallLock) { 13815 // Clean up both app data and code 13816 // All package moves are frozen until finished 13817 for (int userId : userIds) { 13818 try { 13819 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 13820 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 13821 } catch (InstallerException e) { 13822 Slog.w(TAG, String.valueOf(e)); 13823 } 13824 } 13825 removeCodePathLI(codeFile); 13826 } 13827 return true; 13828 } 13829 cleanUpResourcesLI()13830 void cleanUpResourcesLI() { 13831 throw new UnsupportedOperationException(); 13832 } 13833 doPostDeleteLI(boolean delete)13834 boolean doPostDeleteLI(boolean delete) { 13835 throw new UnsupportedOperationException(); 13836 } 13837 } 13838 getAsecPackageName(String packageCid)13839 static String getAsecPackageName(String packageCid) { 13840 int idx = packageCid.lastIndexOf("-"); 13841 if (idx == -1) { 13842 return packageCid; 13843 } 13844 return packageCid.substring(0, idx); 13845 } 13846 13847 // Utility method used to create code paths based on package name and available index. getNextCodePath(String oldCodePath, String prefix, String suffix)13848 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 13849 String idxStr = ""; 13850 int idx = 1; 13851 // Fall back to default value of idx=1 if prefix is not 13852 // part of oldCodePath 13853 if (oldCodePath != null) { 13854 String subStr = oldCodePath; 13855 // Drop the suffix right away 13856 if (suffix != null && subStr.endsWith(suffix)) { 13857 subStr = subStr.substring(0, subStr.length() - suffix.length()); 13858 } 13859 // If oldCodePath already contains prefix find out the 13860 // ending index to either increment or decrement. 13861 int sidx = subStr.lastIndexOf(prefix); 13862 if (sidx != -1) { 13863 subStr = subStr.substring(sidx + prefix.length()); 13864 if (subStr != null) { 13865 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 13866 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 13867 } 13868 try { 13869 idx = Integer.parseInt(subStr); 13870 if (idx <= 1) { 13871 idx++; 13872 } else { 13873 idx--; 13874 } 13875 } catch(NumberFormatException e) { 13876 } 13877 } 13878 } 13879 } 13880 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 13881 return prefix + idxStr; 13882 } 13883 getNextCodePath(File targetDir, String packageName)13884 private File getNextCodePath(File targetDir, String packageName) { 13885 int suffix = 1; 13886 File result; 13887 do { 13888 result = new File(targetDir, packageName + "-" + suffix); 13889 suffix++; 13890 } while (result.exists()); 13891 return result; 13892 } 13893 13894 // Utility method that returns the relative package path with respect 13895 // to the installation directory. Like say for /data/data/com.test-1.apk 13896 // string com.test-1 is returned. deriveCodePathName(String codePath)13897 static String deriveCodePathName(String codePath) { 13898 if (codePath == null) { 13899 return null; 13900 } 13901 final File codeFile = new File(codePath); 13902 final String name = codeFile.getName(); 13903 if (codeFile.isDirectory()) { 13904 return name; 13905 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 13906 final int lastDot = name.lastIndexOf('.'); 13907 return name.substring(0, lastDot); 13908 } else { 13909 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 13910 return null; 13911 } 13912 } 13913 13914 static class PackageInstalledInfo { 13915 String name; 13916 int uid; 13917 // The set of users that originally had this package installed. 13918 int[] origUsers; 13919 // The set of users that now have this package installed. 13920 int[] newUsers; 13921 PackageParser.Package pkg; 13922 int returnCode; 13923 String returnMsg; 13924 PackageRemovedInfo removedInfo; 13925 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 13926 setError(int code, String msg)13927 public void setError(int code, String msg) { 13928 setReturnCode(code); 13929 setReturnMessage(msg); 13930 Slog.w(TAG, msg); 13931 } 13932 setError(String msg, PackageParserException e)13933 public void setError(String msg, PackageParserException e) { 13934 setReturnCode(e.error); 13935 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 13936 Slog.w(TAG, msg, e); 13937 } 13938 setError(String msg, PackageManagerException e)13939 public void setError(String msg, PackageManagerException e) { 13940 returnCode = e.error; 13941 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 13942 Slog.w(TAG, msg, e); 13943 } 13944 setReturnCode(int returnCode)13945 public void setReturnCode(int returnCode) { 13946 this.returnCode = returnCode; 13947 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13948 for (int i = 0; i < childCount; i++) { 13949 addedChildPackages.valueAt(i).returnCode = returnCode; 13950 } 13951 } 13952 setReturnMessage(String returnMsg)13953 private void setReturnMessage(String returnMsg) { 13954 this.returnMsg = returnMsg; 13955 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13956 for (int i = 0; i < childCount; i++) { 13957 addedChildPackages.valueAt(i).returnMsg = returnMsg; 13958 } 13959 } 13960 13961 // In some error cases we want to convey more info back to the observer 13962 String origPackage; 13963 String origPermission; 13964 } 13965 13966 /* 13967 * Install a non-existing package. 13968 */ installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, PackageInstalledInfo res)13969 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 13970 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 13971 PackageInstalledInfo res) { 13972 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 13973 13974 // Remember this for later, in case we need to rollback this install 13975 String pkgName = pkg.packageName; 13976 13977 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 13978 13979 synchronized(mPackages) { 13980 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 13981 // A package with the same name is already installed, though 13982 // it has been renamed to an older name. The package we 13983 // are trying to install should be installed as an update to 13984 // the existing one, but that has not been requested, so bail. 13985 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13986 + " without first uninstalling package running as " 13987 + mSettings.mRenamedPackages.get(pkgName)); 13988 return; 13989 } 13990 if (mPackages.containsKey(pkgName)) { 13991 // Don't allow installation over an existing package with the same name. 13992 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13993 + " without first uninstalling."); 13994 return; 13995 } 13996 } 13997 13998 try { 13999 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 14000 System.currentTimeMillis(), user); 14001 14002 updateSettingsLI(newPackage, installerPackageName, null, res, user); 14003 14004 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14005 prepareAppDataAfterInstallLIF(newPackage); 14006 14007 } else { 14008 // Remove package from internal structures, but keep around any 14009 // data that might have already existed 14010 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 14011 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 14012 } 14013 } catch (PackageManagerException e) { 14014 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14015 } 14016 14017 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14018 } 14019 shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags)14020 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 14021 // Can't rotate keys during boot or if sharedUser. 14022 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 14023 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 14024 return false; 14025 } 14026 // app is using upgradeKeySets; make sure all are valid 14027 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14028 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 14029 for (int i = 0; i < upgradeKeySets.length; i++) { 14030 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 14031 Slog.wtf(TAG, "Package " 14032 + (oldPs.name != null ? oldPs.name : "<null>") 14033 + " contains upgrade-key-set reference to unknown key-set: " 14034 + upgradeKeySets[i] 14035 + " reverting to signatures check."); 14036 return false; 14037 } 14038 } 14039 return true; 14040 } 14041 checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg)14042 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 14043 // Upgrade keysets are being used. Determine if new package has a superset of the 14044 // required keys. 14045 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 14046 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14047 for (int i = 0; i < upgradeKeySets.length; i++) { 14048 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 14049 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 14050 return true; 14051 } 14052 } 14053 return false; 14054 } 14055 updateDigest(MessageDigest digest, File file)14056 private static void updateDigest(MessageDigest digest, File file) throws IOException { 14057 try (DigestInputStream digestStream = 14058 new DigestInputStream(new FileInputStream(file), digest)) { 14059 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 14060 } 14061 } 14062 replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, String installerPackageName, PackageInstalledInfo res)14063 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 14064 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 14065 final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 14066 14067 final PackageParser.Package oldPackage; 14068 final String pkgName = pkg.packageName; 14069 final int[] allUsers; 14070 final int[] installedUsers; 14071 14072 synchronized(mPackages) { 14073 oldPackage = mPackages.get(pkgName); 14074 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 14075 14076 // don't allow upgrade to target a release SDK from a pre-release SDK 14077 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 14078 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14079 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 14080 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14081 if (oldTargetsPreRelease 14082 && !newTargetsPreRelease 14083 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 14084 Slog.w(TAG, "Can't install package targeting released sdk"); 14085 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 14086 return; 14087 } 14088 14089 // don't allow an upgrade from full to ephemeral 14090 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 14091 if (isEphemeral && !oldIsEphemeral) { 14092 // can't downgrade from full to ephemeral 14093 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 14094 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14095 return; 14096 } 14097 14098 // verify signatures are valid 14099 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14100 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14101 if (!checkUpgradeKeySetLP(ps, pkg)) { 14102 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14103 "New package not signed by keys specified by upgrade-keysets: " 14104 + pkgName); 14105 return; 14106 } 14107 } else { 14108 // default to original signature matching 14109 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 14110 != PackageManager.SIGNATURE_MATCH) { 14111 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14112 "New package has a different signature: " + pkgName); 14113 return; 14114 } 14115 } 14116 14117 // don't allow a system upgrade unless the upgrade hash matches 14118 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 14119 byte[] digestBytes = null; 14120 try { 14121 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 14122 updateDigest(digest, new File(pkg.baseCodePath)); 14123 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 14124 for (String path : pkg.splitCodePaths) { 14125 updateDigest(digest, new File(path)); 14126 } 14127 } 14128 digestBytes = digest.digest(); 14129 } catch (NoSuchAlgorithmException | IOException e) { 14130 res.setError(INSTALL_FAILED_INVALID_APK, 14131 "Could not compute hash: " + pkgName); 14132 return; 14133 } 14134 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 14135 res.setError(INSTALL_FAILED_INVALID_APK, 14136 "New package fails restrict-update check: " + pkgName); 14137 return; 14138 } 14139 // retain upgrade restriction 14140 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 14141 } 14142 14143 // Check for shared user id changes 14144 String invalidPackageName = 14145 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 14146 if (invalidPackageName != null) { 14147 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 14148 "Package " + invalidPackageName + " tried to change user " 14149 + oldPackage.mSharedUserId); 14150 return; 14151 } 14152 14153 // In case of rollback, remember per-user/profile install state 14154 allUsers = sUserManager.getUserIds(); 14155 installedUsers = ps.queryInstalledUsers(allUsers, true); 14156 } 14157 14158 // Update what is removed 14159 res.removedInfo = new PackageRemovedInfo(); 14160 res.removedInfo.uid = oldPackage.applicationInfo.uid; 14161 res.removedInfo.removedPackage = oldPackage.packageName; 14162 res.removedInfo.isUpdate = true; 14163 res.removedInfo.origUsers = installedUsers; 14164 final int childCount = (oldPackage.childPackages != null) 14165 ? oldPackage.childPackages.size() : 0; 14166 for (int i = 0; i < childCount; i++) { 14167 boolean childPackageUpdated = false; 14168 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 14169 if (res.addedChildPackages != null) { 14170 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14171 if (childRes != null) { 14172 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 14173 childRes.removedInfo.removedPackage = childPkg.packageName; 14174 childRes.removedInfo.isUpdate = true; 14175 childPackageUpdated = true; 14176 } 14177 } 14178 if (!childPackageUpdated) { 14179 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 14180 childRemovedRes.removedPackage = childPkg.packageName; 14181 childRemovedRes.isUpdate = false; 14182 childRemovedRes.dataRemoved = true; 14183 synchronized (mPackages) { 14184 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14185 if (childPs != null) { 14186 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 14187 } 14188 } 14189 if (res.removedInfo.removedChildPackages == null) { 14190 res.removedInfo.removedChildPackages = new ArrayMap<>(); 14191 } 14192 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 14193 } 14194 } 14195 14196 boolean sysPkg = (isSystemApp(oldPackage)); 14197 if (sysPkg) { 14198 // Set the system/privileged flags as needed 14199 final boolean privileged = 14200 (oldPackage.applicationInfo.privateFlags 14201 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14202 final int systemPolicyFlags = policyFlags 14203 | PackageParser.PARSE_IS_SYSTEM 14204 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 14205 14206 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 14207 user, allUsers, installerPackageName, res); 14208 } else { 14209 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 14210 user, allUsers, installerPackageName, res); 14211 } 14212 } 14213 getPreviousCodePaths(String packageName)14214 public List<String> getPreviousCodePaths(String packageName) { 14215 final PackageSetting ps = mSettings.mPackages.get(packageName); 14216 final List<String> result = new ArrayList<String>(); 14217 if (ps != null && ps.oldCodePaths != null) { 14218 result.addAll(ps.oldCodePaths); 14219 } 14220 return result; 14221 } 14222 replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, int[] allUsers, String installerPackageName, PackageInstalledInfo res)14223 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 14224 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14225 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14226 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 14227 + deletedPackage); 14228 14229 String pkgName = deletedPackage.packageName; 14230 boolean deletedPkg = true; 14231 boolean addedPkg = false; 14232 boolean updatedSettings = false; 14233 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 14234 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 14235 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 14236 14237 final long origUpdateTime = (pkg.mExtras != null) 14238 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 14239 14240 // First delete the existing package while retaining the data directory 14241 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14242 res.removedInfo, true, pkg)) { 14243 // If the existing package wasn't successfully deleted 14244 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 14245 deletedPkg = false; 14246 } else { 14247 // Successfully deleted the old package; proceed with replace. 14248 14249 // If deleted package lived in a container, give users a chance to 14250 // relinquish resources before killing. 14251 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 14252 if (DEBUG_INSTALL) { 14253 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 14254 } 14255 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 14256 final ArrayList<String> pkgList = new ArrayList<String>(1); 14257 pkgList.add(deletedPackage.applicationInfo.packageName); 14258 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 14259 } 14260 14261 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14262 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14263 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14264 14265 try { 14266 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 14267 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 14268 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14269 14270 // Update the in-memory copy of the previous code paths. 14271 PackageSetting ps = mSettings.mPackages.get(pkgName); 14272 if (!killApp) { 14273 if (ps.oldCodePaths == null) { 14274 ps.oldCodePaths = new ArraySet<>(); 14275 } 14276 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 14277 if (deletedPackage.splitCodePaths != null) { 14278 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 14279 } 14280 } else { 14281 ps.oldCodePaths = null; 14282 } 14283 if (ps.childPackageNames != null) { 14284 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 14285 final String childPkgName = ps.childPackageNames.get(i); 14286 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 14287 childPs.oldCodePaths = ps.oldCodePaths; 14288 } 14289 } 14290 prepareAppDataAfterInstallLIF(newPackage); 14291 addedPkg = true; 14292 } catch (PackageManagerException e) { 14293 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14294 } 14295 } 14296 14297 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14298 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 14299 14300 // Revert all internal state mutations and added folders for the failed install 14301 if (addedPkg) { 14302 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14303 res.removedInfo, true, null); 14304 } 14305 14306 // Restore the old package 14307 if (deletedPkg) { 14308 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 14309 File restoreFile = new File(deletedPackage.codePath); 14310 // Parse old package 14311 boolean oldExternal = isExternal(deletedPackage); 14312 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 14313 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 14314 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 14315 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 14316 try { 14317 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 14318 null); 14319 } catch (PackageManagerException e) { 14320 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 14321 + e.getMessage()); 14322 return; 14323 } 14324 14325 synchronized (mPackages) { 14326 // Ensure the installer package name up to date 14327 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14328 14329 // Update permissions for restored package 14330 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14331 14332 mSettings.writeLPr(); 14333 } 14334 14335 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 14336 } 14337 } else { 14338 synchronized (mPackages) { 14339 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 14340 if (ps != null) { 14341 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 14342 if (res.removedInfo.removedChildPackages != null) { 14343 final int childCount = res.removedInfo.removedChildPackages.size(); 14344 // Iterate in reverse as we may modify the collection 14345 for (int i = childCount - 1; i >= 0; i--) { 14346 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 14347 if (res.addedChildPackages.containsKey(childPackageName)) { 14348 res.removedInfo.removedChildPackages.removeAt(i); 14349 } else { 14350 PackageRemovedInfo childInfo = res.removedInfo 14351 .removedChildPackages.valueAt(i); 14352 childInfo.removedForAllUsers = mPackages.get( 14353 childInfo.removedPackage) == null; 14354 } 14355 } 14356 } 14357 } 14358 } 14359 } 14360 } 14361 replaceSystemPackageLIF(PackageParser.Package deletedPackage, PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, int[] allUsers, String installerPackageName, PackageInstalledInfo res)14362 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 14363 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14364 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14365 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 14366 + ", old=" + deletedPackage); 14367 14368 final boolean disabledSystem; 14369 14370 // Remove existing system package 14371 removePackageLI(deletedPackage, true); 14372 14373 synchronized (mPackages) { 14374 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 14375 } 14376 if (!disabledSystem) { 14377 // We didn't need to disable the .apk as a current system package, 14378 // which means we are replacing another update that is already 14379 // installed. We need to make sure to delete the older one's .apk. 14380 res.removedInfo.args = createInstallArgsForExisting(0, 14381 deletedPackage.applicationInfo.getCodePath(), 14382 deletedPackage.applicationInfo.getResourcePath(), 14383 getAppDexInstructionSets(deletedPackage.applicationInfo)); 14384 } else { 14385 res.removedInfo.args = null; 14386 } 14387 14388 // Successfully disabled the old package. Now proceed with re-installation 14389 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14390 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14391 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14392 14393 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14394 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 14395 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 14396 14397 PackageParser.Package newPackage = null; 14398 try { 14399 // Add the package to the internal data structures 14400 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 14401 14402 // Set the update and install times 14403 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 14404 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 14405 System.currentTimeMillis()); 14406 14407 // Update the package dynamic state if succeeded 14408 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14409 // Now that the install succeeded make sure we remove data 14410 // directories for any child package the update removed. 14411 final int deletedChildCount = (deletedPackage.childPackages != null) 14412 ? deletedPackage.childPackages.size() : 0; 14413 final int newChildCount = (newPackage.childPackages != null) 14414 ? newPackage.childPackages.size() : 0; 14415 for (int i = 0; i < deletedChildCount; i++) { 14416 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 14417 boolean childPackageDeleted = true; 14418 for (int j = 0; j < newChildCount; j++) { 14419 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 14420 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 14421 childPackageDeleted = false; 14422 break; 14423 } 14424 } 14425 if (childPackageDeleted) { 14426 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 14427 deletedChildPkg.packageName); 14428 if (ps != null && res.removedInfo.removedChildPackages != null) { 14429 PackageRemovedInfo removedChildRes = res.removedInfo 14430 .removedChildPackages.get(deletedChildPkg.packageName); 14431 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 14432 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 14433 } 14434 } 14435 } 14436 14437 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14438 prepareAppDataAfterInstallLIF(newPackage); 14439 } 14440 } catch (PackageManagerException e) { 14441 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 14442 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14443 } 14444 14445 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14446 // Re installation failed. Restore old information 14447 // Remove new pkg information 14448 if (newPackage != null) { 14449 removeInstalledPackageLI(newPackage, true); 14450 } 14451 // Add back the old system package 14452 try { 14453 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 14454 } catch (PackageManagerException e) { 14455 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 14456 } 14457 14458 synchronized (mPackages) { 14459 if (disabledSystem) { 14460 enableSystemPackageLPw(deletedPackage); 14461 } 14462 14463 // Ensure the installer package name up to date 14464 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14465 14466 // Update permissions for restored package 14467 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14468 14469 mSettings.writeLPr(); 14470 } 14471 14472 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 14473 + " after failed upgrade"); 14474 } 14475 } 14476 14477 /** 14478 * Checks whether the parent or any of the child packages have a change shared 14479 * user. For a package to be a valid update the shred users of the parent and 14480 * the children should match. We may later support changing child shared users. 14481 * @param oldPkg The updated package. 14482 * @param newPkg The update package. 14483 * @return The shared user that change between the versions. 14484 */ getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, PackageParser.Package newPkg)14485 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 14486 PackageParser.Package newPkg) { 14487 // Check parent shared user 14488 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 14489 return newPkg.packageName; 14490 } 14491 // Check child shared users 14492 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14493 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 14494 for (int i = 0; i < newChildCount; i++) { 14495 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 14496 // If this child was present, did it have the same shared user? 14497 for (int j = 0; j < oldChildCount; j++) { 14498 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 14499 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 14500 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 14501 return newChildPkg.packageName; 14502 } 14503 } 14504 } 14505 return null; 14506 } 14507 removeNativeBinariesLI(PackageSetting ps)14508 private void removeNativeBinariesLI(PackageSetting ps) { 14509 // Remove the lib path for the parent package 14510 if (ps != null) { 14511 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 14512 // Remove the lib path for the child packages 14513 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14514 for (int i = 0; i < childCount; i++) { 14515 PackageSetting childPs = null; 14516 synchronized (mPackages) { 14517 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14518 } 14519 if (childPs != null) { 14520 NativeLibraryHelper.removeNativeBinariesLI(childPs 14521 .legacyNativeLibraryPathString); 14522 } 14523 } 14524 } 14525 } 14526 enableSystemPackageLPw(PackageParser.Package pkg)14527 private void enableSystemPackageLPw(PackageParser.Package pkg) { 14528 // Enable the parent package 14529 mSettings.enableSystemPackageLPw(pkg.packageName); 14530 // Enable the child packages 14531 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14532 for (int i = 0; i < childCount; i++) { 14533 PackageParser.Package childPkg = pkg.childPackages.get(i); 14534 mSettings.enableSystemPackageLPw(childPkg.packageName); 14535 } 14536 } 14537 disableSystemPackageLPw(PackageParser.Package oldPkg, PackageParser.Package newPkg)14538 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 14539 PackageParser.Package newPkg) { 14540 // Disable the parent package (parent always replaced) 14541 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 14542 // Disable the child packages 14543 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14544 for (int i = 0; i < childCount; i++) { 14545 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 14546 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 14547 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 14548 } 14549 return disabled; 14550 } 14551 setInstallerPackageNameLPw(PackageParser.Package pkg, String installerPackageName)14552 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 14553 String installerPackageName) { 14554 // Enable the parent package 14555 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 14556 // Enable the child packages 14557 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14558 for (int i = 0; i < childCount; i++) { 14559 PackageParser.Package childPkg = pkg.childPackages.get(i); 14560 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 14561 } 14562 } 14563 revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds)14564 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 14565 // Collect all used permissions in the UID 14566 ArraySet<String> usedPermissions = new ArraySet<>(); 14567 final int packageCount = su.packages.size(); 14568 for (int i = 0; i < packageCount; i++) { 14569 PackageSetting ps = su.packages.valueAt(i); 14570 if (ps.pkg == null) { 14571 continue; 14572 } 14573 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 14574 for (int j = 0; j < requestedPermCount; j++) { 14575 String permission = ps.pkg.requestedPermissions.get(j); 14576 BasePermission bp = mSettings.mPermissions.get(permission); 14577 if (bp != null) { 14578 usedPermissions.add(permission); 14579 } 14580 } 14581 } 14582 14583 PermissionsState permissionsState = su.getPermissionsState(); 14584 // Prune install permissions 14585 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 14586 final int installPermCount = installPermStates.size(); 14587 for (int i = installPermCount - 1; i >= 0; i--) { 14588 PermissionState permissionState = installPermStates.get(i); 14589 if (!usedPermissions.contains(permissionState.getName())) { 14590 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14591 if (bp != null) { 14592 permissionsState.revokeInstallPermission(bp); 14593 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 14594 PackageManager.MASK_PERMISSION_FLAGS, 0); 14595 } 14596 } 14597 } 14598 14599 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 14600 14601 // Prune runtime permissions 14602 for (int userId : allUserIds) { 14603 List<PermissionState> runtimePermStates = permissionsState 14604 .getRuntimePermissionStates(userId); 14605 final int runtimePermCount = runtimePermStates.size(); 14606 for (int i = runtimePermCount - 1; i >= 0; i--) { 14607 PermissionState permissionState = runtimePermStates.get(i); 14608 if (!usedPermissions.contains(permissionState.getName())) { 14609 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14610 if (bp != null) { 14611 permissionsState.revokeRuntimePermission(bp, userId); 14612 permissionsState.updatePermissionFlags(bp, userId, 14613 PackageManager.MASK_PERMISSION_FLAGS, 0); 14614 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 14615 runtimePermissionChangedUserIds, userId); 14616 } 14617 } 14618 } 14619 } 14620 14621 return runtimePermissionChangedUserIds; 14622 } 14623 updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, PackageInstalledInfo res, UserHandle user)14624 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 14625 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 14626 // Update the parent package setting 14627 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 14628 res, user); 14629 // Update the child packages setting 14630 final int childCount = (newPackage.childPackages != null) 14631 ? newPackage.childPackages.size() : 0; 14632 for (int i = 0; i < childCount; i++) { 14633 PackageParser.Package childPackage = newPackage.childPackages.get(i); 14634 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 14635 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 14636 childRes.origUsers, childRes, user); 14637 } 14638 } 14639 updateSettingsInternalLI(PackageParser.Package newPackage, String installerPackageName, int[] allUsers, int[] installedForUsers, PackageInstalledInfo res, UserHandle user)14640 private void updateSettingsInternalLI(PackageParser.Package newPackage, 14641 String installerPackageName, int[] allUsers, int[] installedForUsers, 14642 PackageInstalledInfo res, UserHandle user) { 14643 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 14644 14645 String pkgName = newPackage.packageName; 14646 synchronized (mPackages) { 14647 //write settings. the installStatus will be incomplete at this stage. 14648 //note that the new package setting would have already been 14649 //added to mPackages. It hasn't been persisted yet. 14650 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 14651 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14652 mSettings.writeLPr(); 14653 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14654 } 14655 14656 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 14657 synchronized (mPackages) { 14658 updatePermissionsLPw(newPackage.packageName, newPackage, 14659 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 14660 ? UPDATE_PERMISSIONS_ALL : 0)); 14661 // For system-bundled packages, we assume that installing an upgraded version 14662 // of the package implies that the user actually wants to run that new code, 14663 // so we enable the package. 14664 PackageSetting ps = mSettings.mPackages.get(pkgName); 14665 final int userId = user.getIdentifier(); 14666 if (ps != null) { 14667 if (isSystemApp(newPackage)) { 14668 if (DEBUG_INSTALL) { 14669 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 14670 } 14671 // Enable system package for requested users 14672 if (res.origUsers != null) { 14673 for (int origUserId : res.origUsers) { 14674 if (userId == UserHandle.USER_ALL || userId == origUserId) { 14675 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 14676 origUserId, installerPackageName); 14677 } 14678 } 14679 } 14680 // Also convey the prior install/uninstall state 14681 if (allUsers != null && installedForUsers != null) { 14682 for (int currentUserId : allUsers) { 14683 final boolean installed = ArrayUtils.contains( 14684 installedForUsers, currentUserId); 14685 if (DEBUG_INSTALL) { 14686 Slog.d(TAG, " user " + currentUserId + " => " + installed); 14687 } 14688 ps.setInstalled(installed, currentUserId); 14689 } 14690 // these install state changes will be persisted in the 14691 // upcoming call to mSettings.writeLPr(). 14692 } 14693 } 14694 // It's implied that when a user requests installation, they want the app to be 14695 // installed and enabled. 14696 if (userId != UserHandle.USER_ALL) { 14697 ps.setInstalled(true, userId); 14698 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 14699 } 14700 } 14701 res.name = pkgName; 14702 res.uid = newPackage.applicationInfo.uid; 14703 res.pkg = newPackage; 14704 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 14705 mSettings.setInstallerPackageName(pkgName, installerPackageName); 14706 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14707 //to update install status 14708 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14709 mSettings.writeLPr(); 14710 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14711 } 14712 14713 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14714 } 14715 installPackageTracedLI(InstallArgs args, PackageInstalledInfo res)14716 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 14717 try { 14718 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 14719 installPackageLI(args, res); 14720 } finally { 14721 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14722 } 14723 } 14724 installPackageLI(InstallArgs args, PackageInstalledInfo res)14725 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 14726 final int installFlags = args.installFlags; 14727 final String installerPackageName = args.installerPackageName; 14728 final String volumeUuid = args.volumeUuid; 14729 final File tmpPackageFile = new File(args.getCodePath()); 14730 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 14731 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 14732 || (args.volumeUuid != null)); 14733 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 14734 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 14735 boolean replace = false; 14736 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 14737 if (args.move != null) { 14738 // moving a complete application; perform an initial scan on the new install location 14739 scanFlags |= SCAN_INITIAL; 14740 } 14741 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 14742 scanFlags |= SCAN_DONT_KILL_APP; 14743 } 14744 14745 // Result object to be returned 14746 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14747 14748 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 14749 14750 // Sanity check 14751 if (ephemeral && (forwardLocked || onExternal)) { 14752 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 14753 + " external=" + onExternal); 14754 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14755 return; 14756 } 14757 14758 // Retrieve PackageSettings and parse package 14759 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 14760 | PackageParser.PARSE_ENFORCE_CODE 14761 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 14762 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 14763 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0) 14764 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 14765 PackageParser pp = new PackageParser(); 14766 pp.setSeparateProcesses(mSeparateProcesses); 14767 pp.setDisplayMetrics(mMetrics); 14768 14769 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 14770 final PackageParser.Package pkg; 14771 try { 14772 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 14773 } catch (PackageParserException e) { 14774 res.setError("Failed parse during installPackageLI", e); 14775 return; 14776 } finally { 14777 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14778 } 14779 14780 // If we are installing a clustered package add results for the children 14781 if (pkg.childPackages != null) { 14782 synchronized (mPackages) { 14783 final int childCount = pkg.childPackages.size(); 14784 for (int i = 0; i < childCount; i++) { 14785 PackageParser.Package childPkg = pkg.childPackages.get(i); 14786 PackageInstalledInfo childRes = new PackageInstalledInfo(); 14787 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14788 childRes.pkg = childPkg; 14789 childRes.name = childPkg.packageName; 14790 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14791 if (childPs != null) { 14792 childRes.origUsers = childPs.queryInstalledUsers( 14793 sUserManager.getUserIds(), true); 14794 } 14795 if ((mPackages.containsKey(childPkg.packageName))) { 14796 childRes.removedInfo = new PackageRemovedInfo(); 14797 childRes.removedInfo.removedPackage = childPkg.packageName; 14798 } 14799 if (res.addedChildPackages == null) { 14800 res.addedChildPackages = new ArrayMap<>(); 14801 } 14802 res.addedChildPackages.put(childPkg.packageName, childRes); 14803 } 14804 } 14805 } 14806 14807 // If package doesn't declare API override, mark that we have an install 14808 // time CPU ABI override. 14809 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 14810 pkg.cpuAbiOverride = args.abiOverride; 14811 } 14812 14813 String pkgName = res.name = pkg.packageName; 14814 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 14815 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 14816 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 14817 return; 14818 } 14819 } 14820 14821 try { 14822 // either use what we've been given or parse directly from the APK 14823 if (args.certificates != null) { 14824 try { 14825 PackageParser.populateCertificates(pkg, args.certificates); 14826 } catch (PackageParserException e) { 14827 // there was something wrong with the certificates we were given; 14828 // try to pull them from the APK 14829 PackageParser.collectCertificates(pkg, parseFlags); 14830 } 14831 } else { 14832 PackageParser.collectCertificates(pkg, parseFlags); 14833 } 14834 } catch (PackageParserException e) { 14835 res.setError("Failed collect during installPackageLI", e); 14836 return; 14837 } 14838 14839 // Get rid of all references to package scan path via parser. 14840 pp = null; 14841 String oldCodePath = null; 14842 boolean systemApp = false; 14843 synchronized (mPackages) { 14844 // Check if installing already existing package 14845 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 14846 String oldName = mSettings.mRenamedPackages.get(pkgName); 14847 if (pkg.mOriginalPackages != null 14848 && pkg.mOriginalPackages.contains(oldName) 14849 && mPackages.containsKey(oldName)) { 14850 // This package is derived from an original package, 14851 // and this device has been updating from that original 14852 // name. We must continue using the original name, so 14853 // rename the new package here. 14854 pkg.setPackageName(oldName); 14855 pkgName = pkg.packageName; 14856 replace = true; 14857 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 14858 + oldName + " pkgName=" + pkgName); 14859 } else if (mPackages.containsKey(pkgName)) { 14860 // This package, under its official name, already exists 14861 // on the device; we should replace it. 14862 replace = true; 14863 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 14864 } 14865 14866 // Child packages are installed through the parent package 14867 if (pkg.parentPackage != null) { 14868 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 14869 "Package " + pkg.packageName + " is child of package " 14870 + pkg.parentPackage.parentPackage + ". Child packages " 14871 + "can be updated only through the parent package."); 14872 return; 14873 } 14874 14875 if (replace) { 14876 // Prevent apps opting out from runtime permissions 14877 PackageParser.Package oldPackage = mPackages.get(pkgName); 14878 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 14879 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 14880 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 14881 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 14882 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 14883 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 14884 + " doesn't support runtime permissions but the old" 14885 + " target SDK " + oldTargetSdk + " does."); 14886 return; 14887 } 14888 14889 // Prevent installing of child packages 14890 if (oldPackage.parentPackage != null) { 14891 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 14892 "Package " + pkg.packageName + " is child of package " 14893 + oldPackage.parentPackage + ". Child packages " 14894 + "can be updated only through the parent package."); 14895 return; 14896 } 14897 } 14898 } 14899 14900 PackageSetting ps = mSettings.mPackages.get(pkgName); 14901 if (ps != null) { 14902 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 14903 14904 // Quick sanity check that we're signed correctly if updating; 14905 // we'll check this again later when scanning, but we want to 14906 // bail early here before tripping over redefined permissions. 14907 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14908 if (!checkUpgradeKeySetLP(ps, pkg)) { 14909 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 14910 + pkg.packageName + " upgrade keys do not match the " 14911 + "previously installed version"); 14912 return; 14913 } 14914 } else { 14915 try { 14916 verifySignaturesLP(ps, pkg); 14917 } catch (PackageManagerException e) { 14918 res.setError(e.error, e.getMessage()); 14919 return; 14920 } 14921 } 14922 14923 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 14924 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 14925 systemApp = (ps.pkg.applicationInfo.flags & 14926 ApplicationInfo.FLAG_SYSTEM) != 0; 14927 } 14928 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 14929 } 14930 14931 // Check whether the newly-scanned package wants to define an already-defined perm 14932 int N = pkg.permissions.size(); 14933 for (int i = N-1; i >= 0; i--) { 14934 PackageParser.Permission perm = pkg.permissions.get(i); 14935 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 14936 if (bp != null) { 14937 // If the defining package is signed with our cert, it's okay. This 14938 // also includes the "updating the same package" case, of course. 14939 // "updating same package" could also involve key-rotation. 14940 final boolean sigsOk; 14941 if (bp.sourcePackage.equals(pkg.packageName) 14942 && (bp.packageSetting instanceof PackageSetting) 14943 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 14944 scanFlags))) { 14945 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 14946 } else { 14947 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 14948 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 14949 } 14950 if (!sigsOk) { 14951 // If the owning package is the system itself, we log but allow 14952 // install to proceed; we fail the install on all other permission 14953 // redefinitions. 14954 if (!bp.sourcePackage.equals("android")) { 14955 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 14956 + pkg.packageName + " attempting to redeclare permission " 14957 + perm.info.name + " already owned by " + bp.sourcePackage); 14958 res.origPermission = perm.info.name; 14959 res.origPackage = bp.sourcePackage; 14960 return; 14961 } else { 14962 Slog.w(TAG, "Package " + pkg.packageName 14963 + " attempting to redeclare system permission " 14964 + perm.info.name + "; ignoring new declaration"); 14965 pkg.permissions.remove(i); 14966 } 14967 } 14968 } 14969 } 14970 } 14971 14972 if (systemApp) { 14973 if (onExternal) { 14974 // Abort update; system app can't be replaced with app on sdcard 14975 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 14976 "Cannot install updates to system apps on sdcard"); 14977 return; 14978 } else if (ephemeral) { 14979 // Abort update; system app can't be replaced with an ephemeral app 14980 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 14981 "Cannot update a system app with an ephemeral app"); 14982 return; 14983 } 14984 } 14985 14986 if (args.move != null) { 14987 // We did an in-place move, so dex is ready to roll 14988 scanFlags |= SCAN_NO_DEX; 14989 scanFlags |= SCAN_MOVE; 14990 14991 synchronized (mPackages) { 14992 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14993 if (ps == null) { 14994 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 14995 "Missing settings for moved package " + pkgName); 14996 } 14997 14998 // We moved the entire application as-is, so bring over the 14999 // previously derived ABI information. 15000 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 15001 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 15002 } 15003 15004 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 15005 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 15006 scanFlags |= SCAN_NO_DEX; 15007 15008 try { 15009 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 15010 args.abiOverride : pkg.cpuAbiOverride); 15011 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 15012 true /* extract libs */); 15013 } catch (PackageManagerException pme) { 15014 Slog.e(TAG, "Error deriving application ABI", pme); 15015 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 15016 return; 15017 } 15018 15019 // Shared libraries for the package need to be updated. 15020 synchronized (mPackages) { 15021 try { 15022 updateSharedLibrariesLPw(pkg, null); 15023 } catch (PackageManagerException e) { 15024 Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage()); 15025 } 15026 } 15027 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 15028 // Do not run PackageDexOptimizer through the local performDexOpt 15029 // method because `pkg` may not be in `mPackages` yet. 15030 // 15031 // Also, don't fail application installs if the dexopt step fails. 15032 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 15033 null /* instructionSets */, false /* checkProfiles */, 15034 getCompilerFilterForReason(REASON_INSTALL), 15035 getOrCreateCompilerPackageStats(pkg)); 15036 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15037 15038 // Notify BackgroundDexOptService that the package has been changed. 15039 // If this is an update of a package which used to fail to compile, 15040 // BDOS will remove it from its blacklist. 15041 BackgroundDexOptService.notifyPackageChanged(pkg.packageName); 15042 } 15043 15044 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 15045 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 15046 return; 15047 } 15048 15049 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 15050 15051 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 15052 "installPackageLI")) { 15053 if (replace) { 15054 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 15055 installerPackageName, res); 15056 } else { 15057 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 15058 args.user, installerPackageName, volumeUuid, res); 15059 } 15060 } 15061 synchronized (mPackages) { 15062 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15063 if (ps != null) { 15064 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15065 } 15066 15067 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15068 for (int i = 0; i < childCount; i++) { 15069 PackageParser.Package childPkg = pkg.childPackages.get(i); 15070 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15071 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 15072 if (childPs != null) { 15073 childRes.newUsers = childPs.queryInstalledUsers( 15074 sUserManager.getUserIds(), true); 15075 } 15076 } 15077 } 15078 } 15079 startIntentFilterVerifications(int userId, boolean replacing, PackageParser.Package pkg)15080 private void startIntentFilterVerifications(int userId, boolean replacing, 15081 PackageParser.Package pkg) { 15082 if (mIntentFilterVerifierComponent == null) { 15083 Slog.w(TAG, "No IntentFilter verification will not be done as " 15084 + "there is no IntentFilterVerifier available!"); 15085 return; 15086 } 15087 15088 final int verifierUid = getPackageUid( 15089 mIntentFilterVerifierComponent.getPackageName(), 15090 MATCH_DEBUG_TRIAGED_MISSING, 15091 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 15092 15093 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15094 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 15095 mHandler.sendMessage(msg); 15096 15097 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15098 for (int i = 0; i < childCount; i++) { 15099 PackageParser.Package childPkg = pkg.childPackages.get(i); 15100 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15101 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 15102 mHandler.sendMessage(msg); 15103 } 15104 } 15105 verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, PackageParser.Package pkg)15106 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 15107 PackageParser.Package pkg) { 15108 int size = pkg.activities.size(); 15109 if (size == 0) { 15110 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15111 "No activity, so no need to verify any IntentFilter!"); 15112 return; 15113 } 15114 15115 final boolean hasDomainURLs = hasDomainURLs(pkg); 15116 if (!hasDomainURLs) { 15117 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15118 "No domain URLs, so no need to verify any IntentFilter!"); 15119 return; 15120 } 15121 15122 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 15123 + " if any IntentFilter from the " + size 15124 + " Activities needs verification ..."); 15125 15126 int count = 0; 15127 final String packageName = pkg.packageName; 15128 15129 synchronized (mPackages) { 15130 // If this is a new install and we see that we've already run verification for this 15131 // package, we have nothing to do: it means the state was restored from backup. 15132 if (!replacing) { 15133 IntentFilterVerificationInfo ivi = 15134 mSettings.getIntentFilterVerificationLPr(packageName); 15135 if (ivi != null) { 15136 if (DEBUG_DOMAIN_VERIFICATION) { 15137 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 15138 + ivi.getStatusString()); 15139 } 15140 return; 15141 } 15142 } 15143 15144 // If any filters need to be verified, then all need to be. 15145 boolean needToVerify = false; 15146 for (PackageParser.Activity a : pkg.activities) { 15147 for (ActivityIntentInfo filter : a.intents) { 15148 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 15149 if (DEBUG_DOMAIN_VERIFICATION) { 15150 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 15151 } 15152 needToVerify = true; 15153 break; 15154 } 15155 } 15156 } 15157 15158 if (needToVerify) { 15159 final int verificationId = mIntentFilterVerificationToken++; 15160 for (PackageParser.Activity a : pkg.activities) { 15161 for (ActivityIntentInfo filter : a.intents) { 15162 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 15163 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15164 "Verification needed for IntentFilter:" + filter.toString()); 15165 mIntentFilterVerifier.addOneIntentFilterVerification( 15166 verifierUid, userId, verificationId, filter, packageName); 15167 count++; 15168 } 15169 } 15170 } 15171 } 15172 } 15173 15174 if (count > 0) { 15175 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 15176 + " IntentFilter verification" + (count > 1 ? "s" : "") 15177 + " for userId:" + userId); 15178 mIntentFilterVerifier.startVerifications(userId); 15179 } else { 15180 if (DEBUG_DOMAIN_VERIFICATION) { 15181 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 15182 } 15183 } 15184 } 15185 needsNetworkVerificationLPr(ActivityIntentInfo filter)15186 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 15187 final ComponentName cn = filter.activity.getComponentName(); 15188 final String packageName = cn.getPackageName(); 15189 15190 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 15191 packageName); 15192 if (ivi == null) { 15193 return true; 15194 } 15195 int status = ivi.getStatus(); 15196 switch (status) { 15197 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 15198 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 15199 return true; 15200 15201 default: 15202 // Nothing to do 15203 return false; 15204 } 15205 } 15206 isMultiArch(ApplicationInfo info)15207 private static boolean isMultiArch(ApplicationInfo info) { 15208 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 15209 } 15210 isExternal(PackageParser.Package pkg)15211 private static boolean isExternal(PackageParser.Package pkg) { 15212 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15213 } 15214 isExternal(PackageSetting ps)15215 private static boolean isExternal(PackageSetting ps) { 15216 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15217 } 15218 isEphemeral(PackageParser.Package pkg)15219 private static boolean isEphemeral(PackageParser.Package pkg) { 15220 return pkg.applicationInfo.isEphemeralApp(); 15221 } 15222 isEphemeral(PackageSetting ps)15223 private static boolean isEphemeral(PackageSetting ps) { 15224 return ps.pkg != null && isEphemeral(ps.pkg); 15225 } 15226 isSystemApp(PackageParser.Package pkg)15227 private static boolean isSystemApp(PackageParser.Package pkg) { 15228 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 15229 } 15230 isPrivilegedApp(PackageParser.Package pkg)15231 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 15232 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15233 } 15234 hasDomainURLs(PackageParser.Package pkg)15235 private static boolean hasDomainURLs(PackageParser.Package pkg) { 15236 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 15237 } 15238 isSystemApp(PackageSetting ps)15239 private static boolean isSystemApp(PackageSetting ps) { 15240 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 15241 } 15242 isUpdatedSystemApp(PackageSetting ps)15243 private static boolean isUpdatedSystemApp(PackageSetting ps) { 15244 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 15245 } 15246 packageFlagsToInstallFlags(PackageSetting ps)15247 private int packageFlagsToInstallFlags(PackageSetting ps) { 15248 int installFlags = 0; 15249 if (isEphemeral(ps)) { 15250 installFlags |= PackageManager.INSTALL_EPHEMERAL; 15251 } 15252 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 15253 // This existing package was an external ASEC install when we have 15254 // the external flag without a UUID 15255 installFlags |= PackageManager.INSTALL_EXTERNAL; 15256 } 15257 if (ps.isForwardLocked()) { 15258 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 15259 } 15260 return installFlags; 15261 } 15262 getVolumeUuidForPackage(PackageParser.Package pkg)15263 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 15264 if (isExternal(pkg)) { 15265 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15266 return StorageManager.UUID_PRIMARY_PHYSICAL; 15267 } else { 15268 return pkg.volumeUuid; 15269 } 15270 } else { 15271 return StorageManager.UUID_PRIVATE_INTERNAL; 15272 } 15273 } 15274 getSettingsVersionForPackage(PackageParser.Package pkg)15275 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 15276 if (isExternal(pkg)) { 15277 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15278 return mSettings.getExternalVersion(); 15279 } else { 15280 return mSettings.findOrCreateVersion(pkg.volumeUuid); 15281 } 15282 } else { 15283 return mSettings.getInternalVersion(); 15284 } 15285 } 15286 deleteTempPackageFiles()15287 private void deleteTempPackageFiles() { 15288 final FilenameFilter filter = new FilenameFilter() { 15289 public boolean accept(File dir, String name) { 15290 return name.startsWith("vmdl") && name.endsWith(".tmp"); 15291 } 15292 }; 15293 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 15294 file.delete(); 15295 } 15296 } 15297 15298 @Override deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, int flags)15299 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 15300 int flags) { 15301 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 15302 flags); 15303 } 15304 15305 @Override deletePackage(final String packageName, final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags)15306 public void deletePackage(final String packageName, 15307 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 15308 mContext.enforceCallingOrSelfPermission( 15309 android.Manifest.permission.DELETE_PACKAGES, null); 15310 Preconditions.checkNotNull(packageName); 15311 Preconditions.checkNotNull(observer); 15312 final int uid = Binder.getCallingUid(); 15313 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 15314 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 15315 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 15316 mContext.enforceCallingOrSelfPermission( 15317 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 15318 "deletePackage for user " + userId); 15319 } 15320 15321 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 15322 try { 15323 observer.onPackageDeleted(packageName, 15324 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 15325 } catch (RemoteException re) { 15326 } 15327 return; 15328 } 15329 15330 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 15331 try { 15332 observer.onPackageDeleted(packageName, 15333 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 15334 } catch (RemoteException re) { 15335 } 15336 return; 15337 } 15338 15339 if (DEBUG_REMOVE) { 15340 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 15341 + " deleteAllUsers: " + deleteAllUsers ); 15342 } 15343 // Queue up an async operation since the package deletion may take a little while. 15344 mHandler.post(new Runnable() { 15345 public void run() { 15346 mHandler.removeCallbacks(this); 15347 int returnCode; 15348 if (!deleteAllUsers) { 15349 returnCode = deletePackageX(packageName, userId, deleteFlags); 15350 } else { 15351 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 15352 // If nobody is blocking uninstall, proceed with delete for all users 15353 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 15354 returnCode = deletePackageX(packageName, userId, deleteFlags); 15355 } else { 15356 // Otherwise uninstall individually for users with blockUninstalls=false 15357 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 15358 for (int userId : users) { 15359 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 15360 returnCode = deletePackageX(packageName, userId, userFlags); 15361 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 15362 Slog.w(TAG, "Package delete failed for user " + userId 15363 + ", returnCode " + returnCode); 15364 } 15365 } 15366 } 15367 // The app has only been marked uninstalled for certain users. 15368 // We still need to report that delete was blocked 15369 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 15370 } 15371 } 15372 try { 15373 observer.onPackageDeleted(packageName, returnCode, null); 15374 } catch (RemoteException e) { 15375 Log.i(TAG, "Observer no longer exists."); 15376 } //end catch 15377 } //end run 15378 }); 15379 } 15380 getBlockUninstallForUsers(String packageName, int[] userIds)15381 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 15382 int[] result = EMPTY_INT_ARRAY; 15383 for (int userId : userIds) { 15384 if (getBlockUninstallForUser(packageName, userId)) { 15385 result = ArrayUtils.appendInt(result, userId); 15386 } 15387 } 15388 return result; 15389 } 15390 15391 @Override isPackageDeviceAdminOnAnyUser(String packageName)15392 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 15393 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 15394 } 15395 isPackageDeviceAdmin(String packageName, int userId)15396 private boolean isPackageDeviceAdmin(String packageName, int userId) { 15397 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 15398 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 15399 try { 15400 if (dpm != null) { 15401 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 15402 /* callingUserOnly =*/ false); 15403 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 15404 : deviceOwnerComponentName.getPackageName(); 15405 // Does the package contains the device owner? 15406 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 15407 // this check is probably not needed, since DO should be registered as a device 15408 // admin on some user too. (Original bug for this: b/17657954) 15409 if (packageName.equals(deviceOwnerPackageName)) { 15410 return true; 15411 } 15412 // Does it contain a device admin for any user? 15413 int[] users; 15414 if (userId == UserHandle.USER_ALL) { 15415 users = sUserManager.getUserIds(); 15416 } else { 15417 users = new int[]{userId}; 15418 } 15419 for (int i = 0; i < users.length; ++i) { 15420 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 15421 return true; 15422 } 15423 } 15424 } 15425 } catch (RemoteException e) { 15426 } 15427 return false; 15428 } 15429 shouldKeepUninstalledPackageLPr(String packageName)15430 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 15431 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 15432 } 15433 15434 /** 15435 * This method is an internal method that could be get invoked either 15436 * to delete an installed package or to clean up a failed installation. 15437 * After deleting an installed package, a broadcast is sent to notify any 15438 * listeners that the package has been removed. For cleaning up a failed 15439 * installation, the broadcast is not necessary since the package's 15440 * installation wouldn't have sent the initial broadcast either 15441 * The key steps in deleting a package are 15442 * deleting the package information in internal structures like mPackages, 15443 * deleting the packages base directories through installd 15444 * updating mSettings to reflect current status 15445 * persisting settings for later use 15446 * sending a broadcast if necessary 15447 */ deletePackageX(String packageName, int userId, int deleteFlags)15448 private int deletePackageX(String packageName, int userId, int deleteFlags) { 15449 final PackageRemovedInfo info = new PackageRemovedInfo(); 15450 final boolean res; 15451 15452 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 15453 ? UserHandle.USER_ALL : userId; 15454 15455 if (isPackageDeviceAdmin(packageName, removeUser)) { 15456 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 15457 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 15458 } 15459 15460 PackageSetting uninstalledPs = null; 15461 15462 // for the uninstall-updates case and restricted profiles, remember the per- 15463 // user handle installed state 15464 int[] allUsers; 15465 synchronized (mPackages) { 15466 uninstalledPs = mSettings.mPackages.get(packageName); 15467 if (uninstalledPs == null) { 15468 Slog.w(TAG, "Not removing non-existent package " + packageName); 15469 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15470 } 15471 allUsers = sUserManager.getUserIds(); 15472 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 15473 } 15474 15475 final int freezeUser; 15476 if (isUpdatedSystemApp(uninstalledPs) 15477 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 15478 // We're downgrading a system app, which will apply to all users, so 15479 // freeze them all during the downgrade 15480 freezeUser = UserHandle.USER_ALL; 15481 } else { 15482 freezeUser = removeUser; 15483 } 15484 15485 synchronized (mInstallLock) { 15486 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 15487 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 15488 deleteFlags, "deletePackageX")) { 15489 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 15490 deleteFlags | REMOVE_CHATTY, info, true, null); 15491 } 15492 synchronized (mPackages) { 15493 if (res) { 15494 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 15495 } 15496 } 15497 } 15498 15499 if (res) { 15500 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15501 info.sendPackageRemovedBroadcasts(killApp); 15502 info.sendSystemPackageUpdatedBroadcasts(); 15503 info.sendSystemPackageAppearedBroadcasts(); 15504 } 15505 // Force a gc here. 15506 Runtime.getRuntime().gc(); 15507 // Delete the resources here after sending the broadcast to let 15508 // other processes clean up before deleting resources. 15509 if (info.args != null) { 15510 synchronized (mInstallLock) { 15511 info.args.doPostDeleteLI(true); 15512 } 15513 } 15514 15515 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15516 } 15517 15518 class PackageRemovedInfo { 15519 String removedPackage; 15520 int uid = -1; 15521 int removedAppId = -1; 15522 int[] origUsers; 15523 int[] removedUsers = null; 15524 boolean isRemovedPackageSystemUpdate = false; 15525 boolean isUpdate; 15526 boolean dataRemoved; 15527 boolean removedForAllUsers; 15528 // Clean up resources deleted packages. 15529 InstallArgs args = null; 15530 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 15531 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 15532 sendPackageRemovedBroadcasts(boolean killApp)15533 void sendPackageRemovedBroadcasts(boolean killApp) { 15534 sendPackageRemovedBroadcastInternal(killApp); 15535 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 15536 for (int i = 0; i < childCount; i++) { 15537 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15538 childInfo.sendPackageRemovedBroadcastInternal(killApp); 15539 } 15540 } 15541 sendSystemPackageUpdatedBroadcasts()15542 void sendSystemPackageUpdatedBroadcasts() { 15543 if (isRemovedPackageSystemUpdate) { 15544 sendSystemPackageUpdatedBroadcastsInternal(); 15545 final int childCount = (removedChildPackages != null) 15546 ? removedChildPackages.size() : 0; 15547 for (int i = 0; i < childCount; i++) { 15548 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15549 if (childInfo.isRemovedPackageSystemUpdate) { 15550 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 15551 } 15552 } 15553 } 15554 } 15555 sendSystemPackageAppearedBroadcasts()15556 void sendSystemPackageAppearedBroadcasts() { 15557 final int packageCount = (appearedChildPackages != null) 15558 ? appearedChildPackages.size() : 0; 15559 for (int i = 0; i < packageCount; i++) { 15560 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 15561 for (int userId : installedInfo.newUsers) { 15562 sendPackageAddedForUser(installedInfo.name, true, 15563 UserHandle.getAppId(installedInfo.uid), userId); 15564 } 15565 } 15566 } 15567 sendSystemPackageUpdatedBroadcastsInternal()15568 private void sendSystemPackageUpdatedBroadcastsInternal() { 15569 Bundle extras = new Bundle(2); 15570 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15571 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15572 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 15573 extras, 0, null, null, null); 15574 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 15575 extras, 0, null, null, null); 15576 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 15577 null, 0, removedPackage, null, null); 15578 } 15579 sendPackageRemovedBroadcastInternal(boolean killApp)15580 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 15581 Bundle extras = new Bundle(2); 15582 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15583 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 15584 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 15585 if (isUpdate || isRemovedPackageSystemUpdate) { 15586 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15587 } 15588 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 15589 if (removedPackage != null) { 15590 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 15591 extras, 0, null, null, removedUsers); 15592 if (dataRemoved && !isRemovedPackageSystemUpdate) { 15593 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 15594 removedPackage, extras, 0, null, null, removedUsers); 15595 } 15596 } 15597 if (removedAppId >= 0) { 15598 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 15599 removedUsers); 15600 } 15601 } 15602 } 15603 15604 /* 15605 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 15606 * flag is not set, the data directory is removed as well. 15607 * make sure this flag is set for partially installed apps. If not its meaningless to 15608 * delete a partially installed application. 15609 */ removePackageDataLIF(PackageSetting ps, int[] allUserHandles, PackageRemovedInfo outInfo, int flags, boolean writeSettings)15610 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 15611 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 15612 String packageName = ps.name; 15613 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 15614 // Retrieve object to delete permissions for shared user later on 15615 final PackageParser.Package deletedPkg; 15616 final PackageSetting deletedPs; 15617 // reader 15618 synchronized (mPackages) { 15619 deletedPkg = mPackages.get(packageName); 15620 deletedPs = mSettings.mPackages.get(packageName); 15621 if (outInfo != null) { 15622 outInfo.removedPackage = packageName; 15623 outInfo.removedUsers = deletedPs != null 15624 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 15625 : null; 15626 } 15627 } 15628 15629 removePackageLI(ps, (flags & REMOVE_CHATTY) != 0); 15630 15631 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 15632 final PackageParser.Package resolvedPkg; 15633 if (deletedPkg != null) { 15634 resolvedPkg = deletedPkg; 15635 } else { 15636 // We don't have a parsed package when it lives on an ejected 15637 // adopted storage device, so fake something together 15638 resolvedPkg = new PackageParser.Package(ps.name); 15639 resolvedPkg.setVolumeUuid(ps.volumeUuid); 15640 } 15641 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 15642 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 15643 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 15644 if (outInfo != null) { 15645 outInfo.dataRemoved = true; 15646 } 15647 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 15648 } 15649 15650 // writer 15651 synchronized (mPackages) { 15652 if (deletedPs != null) { 15653 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 15654 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 15655 clearDefaultBrowserIfNeeded(packageName); 15656 if (outInfo != null) { 15657 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 15658 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 15659 } 15660 updatePermissionsLPw(deletedPs.name, null, 0); 15661 if (deletedPs.sharedUser != null) { 15662 // Remove permissions associated with package. Since runtime 15663 // permissions are per user we have to kill the removed package 15664 // or packages running under the shared user of the removed 15665 // package if revoking the permissions requested only by the removed 15666 // package is successful and this causes a change in gids. 15667 for (int userId : UserManagerService.getInstance().getUserIds()) { 15668 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 15669 userId); 15670 if (userIdToKill == UserHandle.USER_ALL 15671 || userIdToKill >= UserHandle.USER_SYSTEM) { 15672 // If gids changed for this user, kill all affected packages. 15673 mHandler.post(new Runnable() { 15674 @Override 15675 public void run() { 15676 // This has to happen with no lock held. 15677 killApplication(deletedPs.name, deletedPs.appId, 15678 KILL_APP_REASON_GIDS_CHANGED); 15679 } 15680 }); 15681 break; 15682 } 15683 } 15684 } 15685 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 15686 } 15687 // make sure to preserve per-user disabled state if this removal was just 15688 // a downgrade of a system app to the factory package 15689 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 15690 if (DEBUG_REMOVE) { 15691 Slog.d(TAG, "Propagating install state across downgrade"); 15692 } 15693 for (int userId : allUserHandles) { 15694 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 15695 if (DEBUG_REMOVE) { 15696 Slog.d(TAG, " user " + userId + " => " + installed); 15697 } 15698 ps.setInstalled(installed, userId); 15699 } 15700 } 15701 } 15702 // can downgrade to reader 15703 if (writeSettings) { 15704 // Save settings now 15705 mSettings.writeLPr(); 15706 } 15707 } 15708 if (outInfo != null) { 15709 // A user ID was deleted here. Go through all users and remove it 15710 // from KeyStore. 15711 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 15712 } 15713 } 15714 locationIsPrivileged(File path)15715 static boolean locationIsPrivileged(File path) { 15716 try { 15717 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 15718 .getCanonicalPath(); 15719 return path.getCanonicalPath().startsWith(privilegedAppDir); 15720 } catch (IOException e) { 15721 Slog.e(TAG, "Unable to access code path " + path); 15722 } 15723 return false; 15724 } 15725 15726 /* 15727 * Tries to delete system package. 15728 */ deleteSystemPackageLIF(PackageParser.Package deletedPkg, PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings)15729 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 15730 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 15731 boolean writeSettings) { 15732 if (deletedPs.parentPackageName != null) { 15733 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 15734 return false; 15735 } 15736 15737 final boolean applyUserRestrictions 15738 = (allUserHandles != null) && (outInfo.origUsers != null); 15739 final PackageSetting disabledPs; 15740 // Confirm if the system package has been updated 15741 // An updated system app can be deleted. This will also have to restore 15742 // the system pkg from system partition 15743 // reader 15744 synchronized (mPackages) { 15745 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 15746 } 15747 15748 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 15749 + " disabledPs=" + disabledPs); 15750 15751 if (disabledPs == null) { 15752 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 15753 return false; 15754 } else if (DEBUG_REMOVE) { 15755 Slog.d(TAG, "Deleting system pkg from data partition"); 15756 } 15757 15758 if (DEBUG_REMOVE) { 15759 if (applyUserRestrictions) { 15760 Slog.d(TAG, "Remembering install states:"); 15761 for (int userId : allUserHandles) { 15762 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 15763 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 15764 } 15765 } 15766 } 15767 15768 // Delete the updated package 15769 outInfo.isRemovedPackageSystemUpdate = true; 15770 if (outInfo.removedChildPackages != null) { 15771 final int childCount = (deletedPs.childPackageNames != null) 15772 ? deletedPs.childPackageNames.size() : 0; 15773 for (int i = 0; i < childCount; i++) { 15774 String childPackageName = deletedPs.childPackageNames.get(i); 15775 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 15776 .contains(childPackageName)) { 15777 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 15778 childPackageName); 15779 if (childInfo != null) { 15780 childInfo.isRemovedPackageSystemUpdate = true; 15781 } 15782 } 15783 } 15784 } 15785 15786 if (disabledPs.versionCode < deletedPs.versionCode) { 15787 // Delete data for downgrades 15788 flags &= ~PackageManager.DELETE_KEEP_DATA; 15789 } else { 15790 // Preserve data by setting flag 15791 flags |= PackageManager.DELETE_KEEP_DATA; 15792 } 15793 15794 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 15795 outInfo, writeSettings, disabledPs.pkg); 15796 if (!ret) { 15797 return false; 15798 } 15799 15800 // writer 15801 synchronized (mPackages) { 15802 // Reinstate the old system package 15803 enableSystemPackageLPw(disabledPs.pkg); 15804 // Remove any native libraries from the upgraded package. 15805 removeNativeBinariesLI(deletedPs); 15806 } 15807 15808 // Install the system package 15809 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 15810 int parseFlags = mDefParseFlags 15811 | PackageParser.PARSE_MUST_BE_APK 15812 | PackageParser.PARSE_IS_SYSTEM 15813 | PackageParser.PARSE_IS_SYSTEM_DIR; 15814 if (locationIsPrivileged(disabledPs.codePath)) { 15815 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 15816 } 15817 15818 final PackageParser.Package newPkg; 15819 try { 15820 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 15821 } catch (PackageManagerException e) { 15822 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 15823 + e.getMessage()); 15824 return false; 15825 } 15826 try { 15827 // update shared libraries for the newly re-installed system package 15828 updateSharedLibrariesLPw(newPkg, null); 15829 } catch (PackageManagerException e) { 15830 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 15831 } 15832 15833 prepareAppDataAfterInstallLIF(newPkg); 15834 15835 // writer 15836 synchronized (mPackages) { 15837 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 15838 15839 // Propagate the permissions state as we do not want to drop on the floor 15840 // runtime permissions. The update permissions method below will take 15841 // care of removing obsolete permissions and grant install permissions. 15842 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 15843 updatePermissionsLPw(newPkg.packageName, newPkg, 15844 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 15845 15846 if (applyUserRestrictions) { 15847 if (DEBUG_REMOVE) { 15848 Slog.d(TAG, "Propagating install state across reinstall"); 15849 } 15850 for (int userId : allUserHandles) { 15851 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 15852 if (DEBUG_REMOVE) { 15853 Slog.d(TAG, " user " + userId + " => " + installed); 15854 } 15855 ps.setInstalled(installed, userId); 15856 15857 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 15858 } 15859 // Regardless of writeSettings we need to ensure that this restriction 15860 // state propagation is persisted 15861 mSettings.writeAllUsersPackageRestrictionsLPr(); 15862 } 15863 // can downgrade to reader here 15864 if (writeSettings) { 15865 mSettings.writeLPr(); 15866 } 15867 } 15868 return true; 15869 } 15870 deleteInstalledPackageLIF(PackageSetting ps, boolean deleteCodeAndResources, int flags, int[] allUserHandles, PackageRemovedInfo outInfo, boolean writeSettings, PackageParser.Package replacingPackage)15871 private boolean deleteInstalledPackageLIF(PackageSetting ps, 15872 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 15873 PackageRemovedInfo outInfo, boolean writeSettings, 15874 PackageParser.Package replacingPackage) { 15875 synchronized (mPackages) { 15876 if (outInfo != null) { 15877 outInfo.uid = ps.appId; 15878 } 15879 15880 if (outInfo != null && outInfo.removedChildPackages != null) { 15881 final int childCount = (ps.childPackageNames != null) 15882 ? ps.childPackageNames.size() : 0; 15883 for (int i = 0; i < childCount; i++) { 15884 String childPackageName = ps.childPackageNames.get(i); 15885 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 15886 if (childPs == null) { 15887 return false; 15888 } 15889 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 15890 childPackageName); 15891 if (childInfo != null) { 15892 childInfo.uid = childPs.appId; 15893 } 15894 } 15895 } 15896 } 15897 15898 // Delete package data from internal structures and also remove data if flag is set 15899 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 15900 15901 // Delete the child packages data 15902 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 15903 for (int i = 0; i < childCount; i++) { 15904 PackageSetting childPs; 15905 synchronized (mPackages) { 15906 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 15907 } 15908 if (childPs != null) { 15909 PackageRemovedInfo childOutInfo = (outInfo != null 15910 && outInfo.removedChildPackages != null) 15911 ? outInfo.removedChildPackages.get(childPs.name) : null; 15912 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 15913 && (replacingPackage != null 15914 && !replacingPackage.hasChildPackage(childPs.name)) 15915 ? flags & ~DELETE_KEEP_DATA : flags; 15916 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 15917 deleteFlags, writeSettings); 15918 } 15919 } 15920 15921 // Delete application code and resources only for parent packages 15922 if (ps.parentPackageName == null) { 15923 if (deleteCodeAndResources && (outInfo != null)) { 15924 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 15925 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 15926 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 15927 } 15928 } 15929 15930 return true; 15931 } 15932 15933 @Override setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId)15934 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 15935 int userId) { 15936 mContext.enforceCallingOrSelfPermission( 15937 android.Manifest.permission.DELETE_PACKAGES, null); 15938 synchronized (mPackages) { 15939 PackageSetting ps = mSettings.mPackages.get(packageName); 15940 if (ps == null) { 15941 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 15942 return false; 15943 } 15944 if (!ps.getInstalled(userId)) { 15945 // Can't block uninstall for an app that is not installed or enabled. 15946 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 15947 return false; 15948 } 15949 ps.setBlockUninstall(blockUninstall, userId); 15950 mSettings.writePackageRestrictionsLPr(userId); 15951 } 15952 return true; 15953 } 15954 15955 @Override getBlockUninstallForUser(String packageName, int userId)15956 public boolean getBlockUninstallForUser(String packageName, int userId) { 15957 synchronized (mPackages) { 15958 PackageSetting ps = mSettings.mPackages.get(packageName); 15959 if (ps == null) { 15960 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 15961 return false; 15962 } 15963 return ps.getBlockUninstall(userId); 15964 } 15965 } 15966 15967 @Override setRequiredForSystemUser(String packageName, boolean systemUserApp)15968 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 15969 int callingUid = Binder.getCallingUid(); 15970 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 15971 throw new SecurityException( 15972 "setRequiredForSystemUser can only be run by the system or root"); 15973 } 15974 synchronized (mPackages) { 15975 PackageSetting ps = mSettings.mPackages.get(packageName); 15976 if (ps == null) { 15977 Log.w(TAG, "Package doesn't exist: " + packageName); 15978 return false; 15979 } 15980 if (systemUserApp) { 15981 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 15982 } else { 15983 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 15984 } 15985 mSettings.writeLPr(); 15986 } 15987 return true; 15988 } 15989 15990 /* 15991 * This method handles package deletion in general 15992 */ deletePackageLIF(String packageName, UserHandle user, boolean deleteCodeAndResources, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, boolean writeSettings, PackageParser.Package replacingPackage)15993 private boolean deletePackageLIF(String packageName, UserHandle user, 15994 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 15995 PackageRemovedInfo outInfo, boolean writeSettings, 15996 PackageParser.Package replacingPackage) { 15997 if (packageName == null) { 15998 Slog.w(TAG, "Attempt to delete null packageName."); 15999 return false; 16000 } 16001 16002 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 16003 16004 PackageSetting ps; 16005 16006 synchronized (mPackages) { 16007 ps = mSettings.mPackages.get(packageName); 16008 if (ps == null) { 16009 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16010 return false; 16011 } 16012 16013 if (ps.parentPackageName != null && (!isSystemApp(ps) 16014 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 16015 if (DEBUG_REMOVE) { 16016 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 16017 + ((user == null) ? UserHandle.USER_ALL : user)); 16018 } 16019 final int removedUserId = (user != null) ? user.getIdentifier() 16020 : UserHandle.USER_ALL; 16021 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 16022 return false; 16023 } 16024 markPackageUninstalledForUserLPw(ps, user); 16025 scheduleWritePackageRestrictionsLocked(user); 16026 return true; 16027 } 16028 } 16029 16030 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 16031 && user.getIdentifier() != UserHandle.USER_ALL)) { 16032 // The caller is asking that the package only be deleted for a single 16033 // user. To do this, we just mark its uninstalled state and delete 16034 // its data. If this is a system app, we only allow this to happen if 16035 // they have set the special DELETE_SYSTEM_APP which requests different 16036 // semantics than normal for uninstalling system apps. 16037 markPackageUninstalledForUserLPw(ps, user); 16038 16039 if (!isSystemApp(ps)) { 16040 // Do not uninstall the APK if an app should be cached 16041 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 16042 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 16043 // Other user still have this package installed, so all 16044 // we need to do is clear this user's data and save that 16045 // it is uninstalled. 16046 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 16047 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16048 return false; 16049 } 16050 scheduleWritePackageRestrictionsLocked(user); 16051 return true; 16052 } else { 16053 // We need to set it back to 'installed' so the uninstall 16054 // broadcasts will be sent correctly. 16055 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 16056 ps.setInstalled(true, user.getIdentifier()); 16057 } 16058 } else { 16059 // This is a system app, so we assume that the 16060 // other users still have this package installed, so all 16061 // we need to do is clear this user's data and save that 16062 // it is uninstalled. 16063 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 16064 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16065 return false; 16066 } 16067 scheduleWritePackageRestrictionsLocked(user); 16068 return true; 16069 } 16070 } 16071 16072 // If we are deleting a composite package for all users, keep track 16073 // of result for each child. 16074 if (ps.childPackageNames != null && outInfo != null) { 16075 synchronized (mPackages) { 16076 final int childCount = ps.childPackageNames.size(); 16077 outInfo.removedChildPackages = new ArrayMap<>(childCount); 16078 for (int i = 0; i < childCount; i++) { 16079 String childPackageName = ps.childPackageNames.get(i); 16080 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 16081 childInfo.removedPackage = childPackageName; 16082 outInfo.removedChildPackages.put(childPackageName, childInfo); 16083 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 16084 if (childPs != null) { 16085 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 16086 } 16087 } 16088 } 16089 } 16090 16091 boolean ret = false; 16092 if (isSystemApp(ps)) { 16093 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 16094 // When an updated system application is deleted we delete the existing resources 16095 // as well and fall back to existing code in system partition 16096 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 16097 } else { 16098 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 16099 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 16100 outInfo, writeSettings, replacingPackage); 16101 } 16102 16103 // Take a note whether we deleted the package for all users 16104 if (outInfo != null) { 16105 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 16106 if (outInfo.removedChildPackages != null) { 16107 synchronized (mPackages) { 16108 final int childCount = outInfo.removedChildPackages.size(); 16109 for (int i = 0; i < childCount; i++) { 16110 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 16111 if (childInfo != null) { 16112 childInfo.removedForAllUsers = mPackages.get( 16113 childInfo.removedPackage) == null; 16114 } 16115 } 16116 } 16117 } 16118 // If we uninstalled an update to a system app there may be some 16119 // child packages that appeared as they are declared in the system 16120 // app but were not declared in the update. 16121 if (isSystemApp(ps)) { 16122 synchronized (mPackages) { 16123 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 16124 final int childCount = (updatedPs.childPackageNames != null) 16125 ? updatedPs.childPackageNames.size() : 0; 16126 for (int i = 0; i < childCount; i++) { 16127 String childPackageName = updatedPs.childPackageNames.get(i); 16128 if (outInfo.removedChildPackages == null 16129 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 16130 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 16131 if (childPs == null) { 16132 continue; 16133 } 16134 PackageInstalledInfo installRes = new PackageInstalledInfo(); 16135 installRes.name = childPackageName; 16136 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 16137 installRes.pkg = mPackages.get(childPackageName); 16138 installRes.uid = childPs.pkg.applicationInfo.uid; 16139 if (outInfo.appearedChildPackages == null) { 16140 outInfo.appearedChildPackages = new ArrayMap<>(); 16141 } 16142 outInfo.appearedChildPackages.put(childPackageName, installRes); 16143 } 16144 } 16145 } 16146 } 16147 } 16148 16149 return ret; 16150 } 16151 markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user)16152 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 16153 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 16154 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 16155 for (int nextUserId : userIds) { 16156 if (DEBUG_REMOVE) { 16157 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 16158 } 16159 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 16160 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 16161 false /*hidden*/, false /*suspended*/, null, null, null, 16162 false /*blockUninstall*/, 16163 ps.readUserState(nextUserId).domainVerificationStatus, 0); 16164 } 16165 } 16166 clearPackageStateForUserLIF(PackageSetting ps, int userId, PackageRemovedInfo outInfo)16167 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 16168 PackageRemovedInfo outInfo) { 16169 final PackageParser.Package pkg; 16170 synchronized (mPackages) { 16171 pkg = mPackages.get(ps.name); 16172 } 16173 16174 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 16175 : new int[] {userId}; 16176 for (int nextUserId : userIds) { 16177 if (DEBUG_REMOVE) { 16178 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 16179 + nextUserId); 16180 } 16181 16182 destroyAppDataLIF(pkg, userId, 16183 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16184 destroyAppProfilesLIF(pkg, userId); 16185 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 16186 schedulePackageCleaning(ps.name, nextUserId, false); 16187 synchronized (mPackages) { 16188 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 16189 scheduleWritePackageRestrictionsLocked(nextUserId); 16190 } 16191 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 16192 } 16193 } 16194 16195 if (outInfo != null) { 16196 outInfo.removedPackage = ps.name; 16197 outInfo.removedAppId = ps.appId; 16198 outInfo.removedUsers = userIds; 16199 } 16200 16201 return true; 16202 } 16203 16204 private final class ClearStorageConnection implements ServiceConnection { 16205 IMediaContainerService mContainerService; 16206 16207 @Override onServiceConnected(ComponentName name, IBinder service)16208 public void onServiceConnected(ComponentName name, IBinder service) { 16209 synchronized (this) { 16210 mContainerService = IMediaContainerService.Stub.asInterface(service); 16211 notifyAll(); 16212 } 16213 } 16214 16215 @Override onServiceDisconnected(ComponentName name)16216 public void onServiceDisconnected(ComponentName name) { 16217 } 16218 } 16219 clearExternalStorageDataSync(String packageName, int userId, boolean allData)16220 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 16221 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 16222 16223 final boolean mounted; 16224 if (Environment.isExternalStorageEmulated()) { 16225 mounted = true; 16226 } else { 16227 final String status = Environment.getExternalStorageState(); 16228 16229 mounted = status.equals(Environment.MEDIA_MOUNTED) 16230 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 16231 } 16232 16233 if (!mounted) { 16234 return; 16235 } 16236 16237 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 16238 int[] users; 16239 if (userId == UserHandle.USER_ALL) { 16240 users = sUserManager.getUserIds(); 16241 } else { 16242 users = new int[] { userId }; 16243 } 16244 final ClearStorageConnection conn = new ClearStorageConnection(); 16245 if (mContext.bindServiceAsUser( 16246 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 16247 try { 16248 for (int curUser : users) { 16249 long timeout = SystemClock.uptimeMillis() + 5000; 16250 synchronized (conn) { 16251 long now; 16252 while (conn.mContainerService == null && 16253 (now = SystemClock.uptimeMillis()) < timeout) { 16254 try { 16255 conn.wait(timeout - now); 16256 } catch (InterruptedException e) { 16257 } 16258 } 16259 } 16260 if (conn.mContainerService == null) { 16261 return; 16262 } 16263 16264 final UserEnvironment userEnv = new UserEnvironment(curUser); 16265 clearDirectory(conn.mContainerService, 16266 userEnv.buildExternalStorageAppCacheDirs(packageName)); 16267 if (allData) { 16268 clearDirectory(conn.mContainerService, 16269 userEnv.buildExternalStorageAppDataDirs(packageName)); 16270 clearDirectory(conn.mContainerService, 16271 userEnv.buildExternalStorageAppMediaDirs(packageName)); 16272 } 16273 } 16274 } finally { 16275 mContext.unbindService(conn); 16276 } 16277 } 16278 } 16279 16280 @Override clearApplicationProfileData(String packageName)16281 public void clearApplicationProfileData(String packageName) { 16282 enforceSystemOrRoot("Only the system can clear all profile data"); 16283 16284 final PackageParser.Package pkg; 16285 synchronized (mPackages) { 16286 pkg = mPackages.get(packageName); 16287 } 16288 16289 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 16290 synchronized (mInstallLock) { 16291 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 16292 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL, 16293 true /* removeBaseMarker */); 16294 } 16295 } 16296 } 16297 16298 @Override clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId)16299 public void clearApplicationUserData(final String packageName, 16300 final IPackageDataObserver observer, final int userId) { 16301 mContext.enforceCallingOrSelfPermission( 16302 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 16303 16304 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16305 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 16306 16307 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 16308 throw new SecurityException("Cannot clear data for a protected package: " 16309 + packageName); 16310 } 16311 // Queue up an async operation since the package deletion may take a little while. 16312 mHandler.post(new Runnable() { 16313 public void run() { 16314 mHandler.removeCallbacks(this); 16315 final boolean succeeded; 16316 try (PackageFreezer freezer = freezePackage(packageName, 16317 "clearApplicationUserData")) { 16318 synchronized (mInstallLock) { 16319 succeeded = clearApplicationUserDataLIF(packageName, userId); 16320 } 16321 clearExternalStorageDataSync(packageName, userId, true); 16322 } 16323 if (succeeded) { 16324 // invoke DeviceStorageMonitor's update method to clear any notifications 16325 DeviceStorageMonitorInternal dsm = LocalServices 16326 .getService(DeviceStorageMonitorInternal.class); 16327 if (dsm != null) { 16328 dsm.checkMemory(); 16329 } 16330 } 16331 if(observer != null) { 16332 try { 16333 observer.onRemoveCompleted(packageName, succeeded); 16334 } catch (RemoteException e) { 16335 Log.i(TAG, "Observer no longer exists."); 16336 } 16337 } //end if observer 16338 } //end run 16339 }); 16340 } 16341 clearApplicationUserDataLIF(String packageName, int userId)16342 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 16343 if (packageName == null) { 16344 Slog.w(TAG, "Attempt to delete null packageName."); 16345 return false; 16346 } 16347 16348 // Try finding details about the requested package 16349 PackageParser.Package pkg; 16350 synchronized (mPackages) { 16351 pkg = mPackages.get(packageName); 16352 if (pkg == null) { 16353 final PackageSetting ps = mSettings.mPackages.get(packageName); 16354 if (ps != null) { 16355 pkg = ps.pkg; 16356 } 16357 } 16358 16359 if (pkg == null) { 16360 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16361 return false; 16362 } 16363 16364 PackageSetting ps = (PackageSetting) pkg.mExtras; 16365 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16366 } 16367 16368 clearAppDataLIF(pkg, userId, 16369 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16370 16371 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 16372 removeKeystoreDataIfNeeded(userId, appId); 16373 16374 UserManagerInternal umInternal = getUserManagerInternal(); 16375 final int flags; 16376 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 16377 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 16378 } else if (umInternal.isUserRunning(userId)) { 16379 flags = StorageManager.FLAG_STORAGE_DE; 16380 } else { 16381 flags = 0; 16382 } 16383 prepareAppDataContentsLIF(pkg, userId, flags); 16384 16385 return true; 16386 } 16387 16388 /** 16389 * Reverts user permission state changes (permissions and flags) in 16390 * all packages for a given user. 16391 * 16392 * @param userId The device user for which to do a reset. 16393 */ resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId)16394 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 16395 final int packageCount = mPackages.size(); 16396 for (int i = 0; i < packageCount; i++) { 16397 PackageParser.Package pkg = mPackages.valueAt(i); 16398 PackageSetting ps = (PackageSetting) pkg.mExtras; 16399 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16400 } 16401 } 16402 resetNetworkPolicies(int userId)16403 private void resetNetworkPolicies(int userId) { 16404 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 16405 } 16406 16407 /** 16408 * Reverts user permission state changes (permissions and flags). 16409 * 16410 * @param ps The package for which to reset. 16411 * @param userId The device user for which to do a reset. 16412 */ resetUserChangesToRuntimePermissionsAndFlagsLPw( final PackageSetting ps, final int userId)16413 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 16414 final PackageSetting ps, final int userId) { 16415 if (ps.pkg == null) { 16416 return; 16417 } 16418 16419 // These are flags that can change base on user actions. 16420 final int userSettableMask = FLAG_PERMISSION_USER_SET 16421 | FLAG_PERMISSION_USER_FIXED 16422 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 16423 | FLAG_PERMISSION_REVIEW_REQUIRED; 16424 16425 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 16426 | FLAG_PERMISSION_POLICY_FIXED; 16427 16428 boolean writeInstallPermissions = false; 16429 boolean writeRuntimePermissions = false; 16430 16431 final int permissionCount = ps.pkg.requestedPermissions.size(); 16432 for (int i = 0; i < permissionCount; i++) { 16433 String permission = ps.pkg.requestedPermissions.get(i); 16434 16435 BasePermission bp = mSettings.mPermissions.get(permission); 16436 if (bp == null) { 16437 continue; 16438 } 16439 16440 // If shared user we just reset the state to which only this app contributed. 16441 if (ps.sharedUser != null) { 16442 boolean used = false; 16443 final int packageCount = ps.sharedUser.packages.size(); 16444 for (int j = 0; j < packageCount; j++) { 16445 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 16446 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 16447 && pkg.pkg.requestedPermissions.contains(permission)) { 16448 used = true; 16449 break; 16450 } 16451 } 16452 if (used) { 16453 continue; 16454 } 16455 } 16456 16457 PermissionsState permissionsState = ps.getPermissionsState(); 16458 16459 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 16460 16461 // Always clear the user settable flags. 16462 final boolean hasInstallState = permissionsState.getInstallPermissionState( 16463 bp.name) != null; 16464 // If permission review is enabled and this is a legacy app, mark the 16465 // permission as requiring a review as this is the initial state. 16466 int flags = 0; 16467 if (Build.PERMISSIONS_REVIEW_REQUIRED 16468 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 16469 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 16470 } 16471 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 16472 if (hasInstallState) { 16473 writeInstallPermissions = true; 16474 } else { 16475 writeRuntimePermissions = true; 16476 } 16477 } 16478 16479 // Below is only runtime permission handling. 16480 if (!bp.isRuntime()) { 16481 continue; 16482 } 16483 16484 // Never clobber system or policy. 16485 if ((oldFlags & policyOrSystemFlags) != 0) { 16486 continue; 16487 } 16488 16489 // If this permission was granted by default, make sure it is. 16490 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 16491 if (permissionsState.grantRuntimePermission(bp, userId) 16492 != PERMISSION_OPERATION_FAILURE) { 16493 writeRuntimePermissions = true; 16494 } 16495 // If permission review is enabled the permissions for a legacy apps 16496 // are represented as constantly granted runtime ones, so don't revoke. 16497 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 16498 // Otherwise, reset the permission. 16499 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 16500 switch (revokeResult) { 16501 case PERMISSION_OPERATION_SUCCESS: 16502 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 16503 writeRuntimePermissions = true; 16504 final int appId = ps.appId; 16505 mHandler.post(new Runnable() { 16506 @Override 16507 public void run() { 16508 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 16509 } 16510 }); 16511 } break; 16512 } 16513 } 16514 } 16515 16516 // Synchronously write as we are taking permissions away. 16517 if (writeRuntimePermissions) { 16518 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 16519 } 16520 16521 // Synchronously write as we are taking permissions away. 16522 if (writeInstallPermissions) { 16523 mSettings.writeLPr(); 16524 } 16525 } 16526 16527 /** 16528 * Remove entries from the keystore daemon. Will only remove it if the 16529 * {@code appId} is valid. 16530 */ removeKeystoreDataIfNeeded(int userId, int appId)16531 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 16532 if (appId < 0) { 16533 return; 16534 } 16535 16536 final KeyStore keyStore = KeyStore.getInstance(); 16537 if (keyStore != null) { 16538 if (userId == UserHandle.USER_ALL) { 16539 for (final int individual : sUserManager.getUserIds()) { 16540 keyStore.clearUid(UserHandle.getUid(individual, appId)); 16541 } 16542 } else { 16543 keyStore.clearUid(UserHandle.getUid(userId, appId)); 16544 } 16545 } else { 16546 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 16547 } 16548 } 16549 16550 @Override deleteApplicationCacheFiles(final String packageName, final IPackageDataObserver observer)16551 public void deleteApplicationCacheFiles(final String packageName, 16552 final IPackageDataObserver observer) { 16553 final int userId = UserHandle.getCallingUserId(); 16554 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 16555 } 16556 16557 @Override deleteApplicationCacheFilesAsUser(final String packageName, final int userId, final IPackageDataObserver observer)16558 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 16559 final IPackageDataObserver observer) { 16560 mContext.enforceCallingOrSelfPermission( 16561 android.Manifest.permission.DELETE_CACHE_FILES, null); 16562 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16563 /* requireFullPermission= */ true, /* checkShell= */ false, 16564 "delete application cache files"); 16565 16566 final PackageParser.Package pkg; 16567 synchronized (mPackages) { 16568 pkg = mPackages.get(packageName); 16569 } 16570 16571 // Queue up an async operation since the package deletion may take a little while. 16572 mHandler.post(new Runnable() { 16573 public void run() { 16574 synchronized (mInstallLock) { 16575 final int flags = StorageManager.FLAG_STORAGE_DE 16576 | StorageManager.FLAG_STORAGE_CE; 16577 // We're only clearing cache files, so we don't care if the 16578 // app is unfrozen and still able to run 16579 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 16580 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16581 } 16582 clearExternalStorageDataSync(packageName, userId, false); 16583 if (observer != null) { 16584 try { 16585 observer.onRemoveCompleted(packageName, true); 16586 } catch (RemoteException e) { 16587 Log.i(TAG, "Observer no longer exists."); 16588 } 16589 } 16590 } 16591 }); 16592 } 16593 16594 @Override getPackageSizeInfo(final String packageName, int userHandle, final IPackageStatsObserver observer)16595 public void getPackageSizeInfo(final String packageName, int userHandle, 16596 final IPackageStatsObserver observer) { 16597 mContext.enforceCallingOrSelfPermission( 16598 android.Manifest.permission.GET_PACKAGE_SIZE, null); 16599 if (packageName == null) { 16600 throw new IllegalArgumentException("Attempt to get size of null packageName"); 16601 } 16602 16603 PackageStats stats = new PackageStats(packageName, userHandle); 16604 16605 /* 16606 * Queue up an async operation since the package measurement may take a 16607 * little while. 16608 */ 16609 Message msg = mHandler.obtainMessage(INIT_COPY); 16610 msg.obj = new MeasureParams(stats, observer); 16611 mHandler.sendMessage(msg); 16612 } 16613 getPackageSizeInfoLI(String packageName, int userId, PackageStats stats)16614 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 16615 final PackageSetting ps; 16616 synchronized (mPackages) { 16617 ps = mSettings.mPackages.get(packageName); 16618 if (ps == null) { 16619 Slog.w(TAG, "Failed to find settings for " + packageName); 16620 return false; 16621 } 16622 } 16623 try { 16624 mInstaller.getAppSize(ps.volumeUuid, packageName, userId, 16625 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 16626 ps.getCeDataInode(userId), ps.codePathString, stats); 16627 } catch (InstallerException e) { 16628 Slog.w(TAG, String.valueOf(e)); 16629 return false; 16630 } 16631 16632 // For now, ignore code size of packages on system partition 16633 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 16634 stats.codeSize = 0; 16635 } 16636 16637 return true; 16638 } 16639 getUidTargetSdkVersionLockedLPr(int uid)16640 private int getUidTargetSdkVersionLockedLPr(int uid) { 16641 Object obj = mSettings.getUserIdLPr(uid); 16642 if (obj instanceof SharedUserSetting) { 16643 final SharedUserSetting sus = (SharedUserSetting) obj; 16644 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 16645 final Iterator<PackageSetting> it = sus.packages.iterator(); 16646 while (it.hasNext()) { 16647 final PackageSetting ps = it.next(); 16648 if (ps.pkg != null) { 16649 int v = ps.pkg.applicationInfo.targetSdkVersion; 16650 if (v < vers) vers = v; 16651 } 16652 } 16653 return vers; 16654 } else if (obj instanceof PackageSetting) { 16655 final PackageSetting ps = (PackageSetting) obj; 16656 if (ps.pkg != null) { 16657 return ps.pkg.applicationInfo.targetSdkVersion; 16658 } 16659 } 16660 return Build.VERSION_CODES.CUR_DEVELOPMENT; 16661 } 16662 16663 @Override addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)16664 public void addPreferredActivity(IntentFilter filter, int match, 16665 ComponentName[] set, ComponentName activity, int userId) { 16666 addPreferredActivityInternal(filter, match, set, activity, true, userId, 16667 "Adding preferred"); 16668 } 16669 addPreferredActivityInternal(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, boolean always, int userId, String opname)16670 private void addPreferredActivityInternal(IntentFilter filter, int match, 16671 ComponentName[] set, ComponentName activity, boolean always, int userId, 16672 String opname) { 16673 // writer 16674 int callingUid = Binder.getCallingUid(); 16675 enforceCrossUserPermission(callingUid, userId, 16676 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 16677 if (filter.countActions() == 0) { 16678 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16679 return; 16680 } 16681 synchronized (mPackages) { 16682 if (mContext.checkCallingOrSelfPermission( 16683 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16684 != PackageManager.PERMISSION_GRANTED) { 16685 if (getUidTargetSdkVersionLockedLPr(callingUid) 16686 < Build.VERSION_CODES.FROYO) { 16687 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 16688 + callingUid); 16689 return; 16690 } 16691 mContext.enforceCallingOrSelfPermission( 16692 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16693 } 16694 16695 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 16696 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 16697 + userId + ":"); 16698 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16699 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 16700 scheduleWritePackageRestrictionsLocked(userId); 16701 postPreferredActivityChangedBroadcast(userId); 16702 } 16703 } 16704 postPreferredActivityChangedBroadcast(int userId)16705 private void postPreferredActivityChangedBroadcast(int userId) { 16706 mHandler.post(() -> { 16707 final IActivityManager am = ActivityManagerNative.getDefault(); 16708 if (am == null) { 16709 return; 16710 } 16711 16712 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 16713 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16714 try { 16715 am.broadcastIntent(null, intent, null, null, 16716 0, null, null, null, android.app.AppOpsManager.OP_NONE, 16717 null, false, false, userId); 16718 } catch (RemoteException e) { 16719 } 16720 }); 16721 } 16722 16723 @Override replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)16724 public void replacePreferredActivity(IntentFilter filter, int match, 16725 ComponentName[] set, ComponentName activity, int userId) { 16726 if (filter.countActions() != 1) { 16727 throw new IllegalArgumentException( 16728 "replacePreferredActivity expects filter to have only 1 action."); 16729 } 16730 if (filter.countDataAuthorities() != 0 16731 || filter.countDataPaths() != 0 16732 || filter.countDataSchemes() > 1 16733 || filter.countDataTypes() != 0) { 16734 throw new IllegalArgumentException( 16735 "replacePreferredActivity expects filter to have no data authorities, " + 16736 "paths, or types; and at most one scheme."); 16737 } 16738 16739 final int callingUid = Binder.getCallingUid(); 16740 enforceCrossUserPermission(callingUid, userId, 16741 true /* requireFullPermission */, false /* checkShell */, 16742 "replace preferred activity"); 16743 synchronized (mPackages) { 16744 if (mContext.checkCallingOrSelfPermission( 16745 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16746 != PackageManager.PERMISSION_GRANTED) { 16747 if (getUidTargetSdkVersionLockedLPr(callingUid) 16748 < Build.VERSION_CODES.FROYO) { 16749 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 16750 + Binder.getCallingUid()); 16751 return; 16752 } 16753 mContext.enforceCallingOrSelfPermission( 16754 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16755 } 16756 16757 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 16758 if (pir != null) { 16759 // Get all of the existing entries that exactly match this filter. 16760 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 16761 if (existing != null && existing.size() == 1) { 16762 PreferredActivity cur = existing.get(0); 16763 if (DEBUG_PREFERRED) { 16764 Slog.i(TAG, "Checking replace of preferred:"); 16765 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16766 if (!cur.mPref.mAlways) { 16767 Slog.i(TAG, " -- CUR; not mAlways!"); 16768 } else { 16769 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 16770 Slog.i(TAG, " -- CUR: mSet=" 16771 + Arrays.toString(cur.mPref.mSetComponents)); 16772 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 16773 Slog.i(TAG, " -- NEW: mMatch=" 16774 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 16775 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 16776 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 16777 } 16778 } 16779 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 16780 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 16781 && cur.mPref.sameSet(set)) { 16782 // Setting the preferred activity to what it happens to be already 16783 if (DEBUG_PREFERRED) { 16784 Slog.i(TAG, "Replacing with same preferred activity " 16785 + cur.mPref.mShortComponent + " for user " 16786 + userId + ":"); 16787 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16788 } 16789 return; 16790 } 16791 } 16792 16793 if (existing != null) { 16794 if (DEBUG_PREFERRED) { 16795 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 16796 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16797 } 16798 for (int i = 0; i < existing.size(); i++) { 16799 PreferredActivity pa = existing.get(i); 16800 if (DEBUG_PREFERRED) { 16801 Slog.i(TAG, "Removing existing preferred activity " 16802 + pa.mPref.mComponent + ":"); 16803 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 16804 } 16805 pir.removeFilter(pa); 16806 } 16807 } 16808 } 16809 addPreferredActivityInternal(filter, match, set, activity, true, userId, 16810 "Replacing preferred"); 16811 } 16812 } 16813 16814 @Override clearPackagePreferredActivities(String packageName)16815 public void clearPackagePreferredActivities(String packageName) { 16816 final int uid = Binder.getCallingUid(); 16817 // writer 16818 synchronized (mPackages) { 16819 PackageParser.Package pkg = mPackages.get(packageName); 16820 if (pkg == null || pkg.applicationInfo.uid != uid) { 16821 if (mContext.checkCallingOrSelfPermission( 16822 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16823 != PackageManager.PERMISSION_GRANTED) { 16824 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 16825 < Build.VERSION_CODES.FROYO) { 16826 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 16827 + Binder.getCallingUid()); 16828 return; 16829 } 16830 mContext.enforceCallingOrSelfPermission( 16831 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16832 } 16833 } 16834 16835 int user = UserHandle.getCallingUserId(); 16836 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 16837 scheduleWritePackageRestrictionsLocked(user); 16838 } 16839 } 16840 } 16841 16842 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ clearPackagePreferredActivitiesLPw(String packageName, int userId)16843 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 16844 ArrayList<PreferredActivity> removed = null; 16845 boolean changed = false; 16846 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 16847 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 16848 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 16849 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 16850 continue; 16851 } 16852 Iterator<PreferredActivity> it = pir.filterIterator(); 16853 while (it.hasNext()) { 16854 PreferredActivity pa = it.next(); 16855 // Mark entry for removal only if it matches the package name 16856 // and the entry is of type "always". 16857 if (packageName == null || 16858 (pa.mPref.mComponent.getPackageName().equals(packageName) 16859 && pa.mPref.mAlways)) { 16860 if (removed == null) { 16861 removed = new ArrayList<PreferredActivity>(); 16862 } 16863 removed.add(pa); 16864 } 16865 } 16866 if (removed != null) { 16867 for (int j=0; j<removed.size(); j++) { 16868 PreferredActivity pa = removed.get(j); 16869 pir.removeFilter(pa); 16870 } 16871 changed = true; 16872 } 16873 } 16874 if (changed) { 16875 postPreferredActivityChangedBroadcast(userId); 16876 } 16877 return changed; 16878 } 16879 16880 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ clearIntentFilterVerificationsLPw(int userId)16881 private void clearIntentFilterVerificationsLPw(int userId) { 16882 final int packageCount = mPackages.size(); 16883 for (int i = 0; i < packageCount; i++) { 16884 PackageParser.Package pkg = mPackages.valueAt(i); 16885 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 16886 } 16887 } 16888 16889 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ clearIntentFilterVerificationsLPw(String packageName, int userId)16890 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 16891 if (userId == UserHandle.USER_ALL) { 16892 if (mSettings.removeIntentFilterVerificationLPw(packageName, 16893 sUserManager.getUserIds())) { 16894 for (int oneUserId : sUserManager.getUserIds()) { 16895 scheduleWritePackageRestrictionsLocked(oneUserId); 16896 } 16897 } 16898 } else { 16899 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 16900 scheduleWritePackageRestrictionsLocked(userId); 16901 } 16902 } 16903 } 16904 clearDefaultBrowserIfNeeded(String packageName)16905 void clearDefaultBrowserIfNeeded(String packageName) { 16906 for (int oneUserId : sUserManager.getUserIds()) { 16907 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 16908 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 16909 if (packageName.equals(defaultBrowserPackageName)) { 16910 setDefaultBrowserPackageName(null, oneUserId); 16911 } 16912 } 16913 } 16914 16915 @Override resetApplicationPreferences(int userId)16916 public void resetApplicationPreferences(int userId) { 16917 mContext.enforceCallingOrSelfPermission( 16918 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16919 final long identity = Binder.clearCallingIdentity(); 16920 // writer 16921 try { 16922 synchronized (mPackages) { 16923 clearPackagePreferredActivitiesLPw(null, userId); 16924 mSettings.applyDefaultPreferredAppsLPw(this, userId); 16925 // TODO: We have to reset the default SMS and Phone. This requires 16926 // significant refactoring to keep all default apps in the package 16927 // manager (cleaner but more work) or have the services provide 16928 // callbacks to the package manager to request a default app reset. 16929 applyFactoryDefaultBrowserLPw(userId); 16930 clearIntentFilterVerificationsLPw(userId); 16931 primeDomainVerificationsLPw(userId); 16932 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 16933 scheduleWritePackageRestrictionsLocked(userId); 16934 } 16935 resetNetworkPolicies(userId); 16936 } finally { 16937 Binder.restoreCallingIdentity(identity); 16938 } 16939 } 16940 16941 @Override getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)16942 public int getPreferredActivities(List<IntentFilter> outFilters, 16943 List<ComponentName> outActivities, String packageName) { 16944 16945 int num = 0; 16946 final int userId = UserHandle.getCallingUserId(); 16947 // reader 16948 synchronized (mPackages) { 16949 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 16950 if (pir != null) { 16951 final Iterator<PreferredActivity> it = pir.filterIterator(); 16952 while (it.hasNext()) { 16953 final PreferredActivity pa = it.next(); 16954 if (packageName == null 16955 || (pa.mPref.mComponent.getPackageName().equals(packageName) 16956 && pa.mPref.mAlways)) { 16957 if (outFilters != null) { 16958 outFilters.add(new IntentFilter(pa)); 16959 } 16960 if (outActivities != null) { 16961 outActivities.add(pa.mPref.mComponent); 16962 } 16963 } 16964 } 16965 } 16966 } 16967 16968 return num; 16969 } 16970 16971 @Override addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, int userId)16972 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 16973 int userId) { 16974 int callingUid = Binder.getCallingUid(); 16975 if (callingUid != Process.SYSTEM_UID) { 16976 throw new SecurityException( 16977 "addPersistentPreferredActivity can only be run by the system"); 16978 } 16979 if (filter.countActions() == 0) { 16980 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16981 return; 16982 } 16983 synchronized (mPackages) { 16984 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 16985 ":"); 16986 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16987 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 16988 new PersistentPreferredActivity(filter, activity)); 16989 scheduleWritePackageRestrictionsLocked(userId); 16990 postPreferredActivityChangedBroadcast(userId); 16991 } 16992 } 16993 16994 @Override clearPackagePersistentPreferredActivities(String packageName, int userId)16995 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 16996 int callingUid = Binder.getCallingUid(); 16997 if (callingUid != Process.SYSTEM_UID) { 16998 throw new SecurityException( 16999 "clearPackagePersistentPreferredActivities can only be run by the system"); 17000 } 17001 ArrayList<PersistentPreferredActivity> removed = null; 17002 boolean changed = false; 17003 synchronized (mPackages) { 17004 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 17005 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 17006 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 17007 .valueAt(i); 17008 if (userId != thisUserId) { 17009 continue; 17010 } 17011 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 17012 while (it.hasNext()) { 17013 PersistentPreferredActivity ppa = it.next(); 17014 // Mark entry for removal only if it matches the package name. 17015 if (ppa.mComponent.getPackageName().equals(packageName)) { 17016 if (removed == null) { 17017 removed = new ArrayList<PersistentPreferredActivity>(); 17018 } 17019 removed.add(ppa); 17020 } 17021 } 17022 if (removed != null) { 17023 for (int j=0; j<removed.size(); j++) { 17024 PersistentPreferredActivity ppa = removed.get(j); 17025 ppir.removeFilter(ppa); 17026 } 17027 changed = true; 17028 } 17029 } 17030 17031 if (changed) { 17032 scheduleWritePackageRestrictionsLocked(userId); 17033 postPreferredActivityChangedBroadcast(userId); 17034 } 17035 } 17036 } 17037 17038 /** 17039 * Common machinery for picking apart a restored XML blob and passing 17040 * it to a caller-supplied functor to be applied to the running system. 17041 */ restoreFromXml(XmlPullParser parser, int userId, String expectedStartTag, BlobXmlRestorer functor)17042 private void restoreFromXml(XmlPullParser parser, int userId, 17043 String expectedStartTag, BlobXmlRestorer functor) 17044 throws IOException, XmlPullParserException { 17045 int type; 17046 while ((type = parser.next()) != XmlPullParser.START_TAG 17047 && type != XmlPullParser.END_DOCUMENT) { 17048 } 17049 if (type != XmlPullParser.START_TAG) { 17050 // oops didn't find a start tag?! 17051 if (DEBUG_BACKUP) { 17052 Slog.e(TAG, "Didn't find start tag during restore"); 17053 } 17054 return; 17055 } 17056 Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 17057 // this is supposed to be TAG_PREFERRED_BACKUP 17058 if (!expectedStartTag.equals(parser.getName())) { 17059 if (DEBUG_BACKUP) { 17060 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 17061 } 17062 return; 17063 } 17064 17065 // skip interfering stuff, then we're aligned with the backing implementation 17066 while ((type = parser.next()) == XmlPullParser.TEXT) { } 17067 Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 17068 functor.apply(parser, userId); 17069 } 17070 17071 private interface BlobXmlRestorer { 17072 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 17073 } 17074 17075 /** 17076 * Non-Binder method, support for the backup/restore mechanism: write the 17077 * full set of preferred activities in its canonical XML format. Returns the 17078 * XML output as a byte array, or null if there is none. 17079 */ 17080 @Override getPreferredActivityBackup(int userId)17081 public byte[] getPreferredActivityBackup(int userId) { 17082 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17083 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 17084 } 17085 17086 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17087 try { 17088 final XmlSerializer serializer = new FastXmlSerializer(); 17089 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17090 serializer.startDocument(null, true); 17091 serializer.startTag(null, TAG_PREFERRED_BACKUP); 17092 17093 synchronized (mPackages) { 17094 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 17095 } 17096 17097 serializer.endTag(null, TAG_PREFERRED_BACKUP); 17098 serializer.endDocument(); 17099 serializer.flush(); 17100 } catch (Exception e) { 17101 if (DEBUG_BACKUP) { 17102 Slog.e(TAG, "Unable to write preferred activities for backup", e); 17103 } 17104 return null; 17105 } 17106 17107 return dataStream.toByteArray(); 17108 } 17109 17110 @Override restorePreferredActivities(byte[] backup, int userId)17111 public void restorePreferredActivities(byte[] backup, int userId) { 17112 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17113 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17114 } 17115 17116 try { 17117 final XmlPullParser parser = Xml.newPullParser(); 17118 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17119 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 17120 new BlobXmlRestorer() { 17121 @Override 17122 public void apply(XmlPullParser parser, int userId) 17123 throws XmlPullParserException, IOException { 17124 synchronized (mPackages) { 17125 mSettings.readPreferredActivitiesLPw(parser, userId); 17126 } 17127 } 17128 } ); 17129 } catch (Exception e) { 17130 if (DEBUG_BACKUP) { 17131 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17132 } 17133 } 17134 } 17135 17136 /** 17137 * Non-Binder method, support for the backup/restore mechanism: write the 17138 * default browser (etc) settings in its canonical XML format. Returns the default 17139 * browser XML representation as a byte array, or null if there is none. 17140 */ 17141 @Override getDefaultAppsBackup(int userId)17142 public byte[] getDefaultAppsBackup(int userId) { 17143 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17144 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 17145 } 17146 17147 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17148 try { 17149 final XmlSerializer serializer = new FastXmlSerializer(); 17150 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17151 serializer.startDocument(null, true); 17152 serializer.startTag(null, TAG_DEFAULT_APPS); 17153 17154 synchronized (mPackages) { 17155 mSettings.writeDefaultAppsLPr(serializer, userId); 17156 } 17157 17158 serializer.endTag(null, TAG_DEFAULT_APPS); 17159 serializer.endDocument(); 17160 serializer.flush(); 17161 } catch (Exception e) { 17162 if (DEBUG_BACKUP) { 17163 Slog.e(TAG, "Unable to write default apps for backup", e); 17164 } 17165 return null; 17166 } 17167 17168 return dataStream.toByteArray(); 17169 } 17170 17171 @Override restoreDefaultApps(byte[] backup, int userId)17172 public void restoreDefaultApps(byte[] backup, int userId) { 17173 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17174 throw new SecurityException("Only the system may call restoreDefaultApps()"); 17175 } 17176 17177 try { 17178 final XmlPullParser parser = Xml.newPullParser(); 17179 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17180 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 17181 new BlobXmlRestorer() { 17182 @Override 17183 public void apply(XmlPullParser parser, int userId) 17184 throws XmlPullParserException, IOException { 17185 synchronized (mPackages) { 17186 mSettings.readDefaultAppsLPw(parser, userId); 17187 } 17188 } 17189 } ); 17190 } catch (Exception e) { 17191 if (DEBUG_BACKUP) { 17192 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 17193 } 17194 } 17195 } 17196 17197 @Override getIntentFilterVerificationBackup(int userId)17198 public byte[] getIntentFilterVerificationBackup(int userId) { 17199 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17200 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 17201 } 17202 17203 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17204 try { 17205 final XmlSerializer serializer = new FastXmlSerializer(); 17206 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17207 serializer.startDocument(null, true); 17208 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 17209 17210 synchronized (mPackages) { 17211 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 17212 } 17213 17214 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 17215 serializer.endDocument(); 17216 serializer.flush(); 17217 } catch (Exception e) { 17218 if (DEBUG_BACKUP) { 17219 Slog.e(TAG, "Unable to write default apps for backup", e); 17220 } 17221 return null; 17222 } 17223 17224 return dataStream.toByteArray(); 17225 } 17226 17227 @Override restoreIntentFilterVerification(byte[] backup, int userId)17228 public void restoreIntentFilterVerification(byte[] backup, int userId) { 17229 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17230 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17231 } 17232 17233 try { 17234 final XmlPullParser parser = Xml.newPullParser(); 17235 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17236 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 17237 new BlobXmlRestorer() { 17238 @Override 17239 public void apply(XmlPullParser parser, int userId) 17240 throws XmlPullParserException, IOException { 17241 synchronized (mPackages) { 17242 mSettings.readAllDomainVerificationsLPr(parser, userId); 17243 mSettings.writeLPr(); 17244 } 17245 } 17246 } ); 17247 } catch (Exception e) { 17248 if (DEBUG_BACKUP) { 17249 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17250 } 17251 } 17252 } 17253 17254 @Override getPermissionGrantBackup(int userId)17255 public byte[] getPermissionGrantBackup(int userId) { 17256 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17257 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 17258 } 17259 17260 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17261 try { 17262 final XmlSerializer serializer = new FastXmlSerializer(); 17263 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17264 serializer.startDocument(null, true); 17265 serializer.startTag(null, TAG_PERMISSION_BACKUP); 17266 17267 synchronized (mPackages) { 17268 serializeRuntimePermissionGrantsLPr(serializer, userId); 17269 } 17270 17271 serializer.endTag(null, TAG_PERMISSION_BACKUP); 17272 serializer.endDocument(); 17273 serializer.flush(); 17274 } catch (Exception e) { 17275 if (DEBUG_BACKUP) { 17276 Slog.e(TAG, "Unable to write default apps for backup", e); 17277 } 17278 return null; 17279 } 17280 17281 return dataStream.toByteArray(); 17282 } 17283 17284 @Override restorePermissionGrants(byte[] backup, int userId)17285 public void restorePermissionGrants(byte[] backup, int userId) { 17286 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17287 throw new SecurityException("Only the system may call restorePermissionGrants()"); 17288 } 17289 17290 try { 17291 final XmlPullParser parser = Xml.newPullParser(); 17292 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17293 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 17294 new BlobXmlRestorer() { 17295 @Override 17296 public void apply(XmlPullParser parser, int userId) 17297 throws XmlPullParserException, IOException { 17298 synchronized (mPackages) { 17299 processRestoredPermissionGrantsLPr(parser, userId); 17300 } 17301 } 17302 } ); 17303 } catch (Exception e) { 17304 if (DEBUG_BACKUP) { 17305 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17306 } 17307 } 17308 } 17309 serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)17310 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 17311 throws IOException { 17312 serializer.startTag(null, TAG_ALL_GRANTS); 17313 17314 final int N = mSettings.mPackages.size(); 17315 for (int i = 0; i < N; i++) { 17316 final PackageSetting ps = mSettings.mPackages.valueAt(i); 17317 boolean pkgGrantsKnown = false; 17318 17319 PermissionsState packagePerms = ps.getPermissionsState(); 17320 17321 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 17322 final int grantFlags = state.getFlags(); 17323 // only look at grants that are not system/policy fixed 17324 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 17325 final boolean isGranted = state.isGranted(); 17326 // And only back up the user-twiddled state bits 17327 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 17328 final String packageName = mSettings.mPackages.keyAt(i); 17329 if (!pkgGrantsKnown) { 17330 serializer.startTag(null, TAG_GRANT); 17331 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 17332 pkgGrantsKnown = true; 17333 } 17334 17335 final boolean userSet = 17336 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 17337 final boolean userFixed = 17338 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 17339 final boolean revoke = 17340 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 17341 17342 serializer.startTag(null, TAG_PERMISSION); 17343 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 17344 if (isGranted) { 17345 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 17346 } 17347 if (userSet) { 17348 serializer.attribute(null, ATTR_USER_SET, "true"); 17349 } 17350 if (userFixed) { 17351 serializer.attribute(null, ATTR_USER_FIXED, "true"); 17352 } 17353 if (revoke) { 17354 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 17355 } 17356 serializer.endTag(null, TAG_PERMISSION); 17357 } 17358 } 17359 } 17360 17361 if (pkgGrantsKnown) { 17362 serializer.endTag(null, TAG_GRANT); 17363 } 17364 } 17365 17366 serializer.endTag(null, TAG_ALL_GRANTS); 17367 } 17368 processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)17369 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 17370 throws XmlPullParserException, IOException { 17371 String pkgName = null; 17372 int outerDepth = parser.getDepth(); 17373 int type; 17374 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 17375 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 17376 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 17377 continue; 17378 } 17379 17380 final String tagName = parser.getName(); 17381 if (tagName.equals(TAG_GRANT)) { 17382 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 17383 if (DEBUG_BACKUP) { 17384 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 17385 } 17386 } else if (tagName.equals(TAG_PERMISSION)) { 17387 17388 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 17389 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 17390 17391 int newFlagSet = 0; 17392 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 17393 newFlagSet |= FLAG_PERMISSION_USER_SET; 17394 } 17395 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 17396 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 17397 } 17398 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 17399 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 17400 } 17401 if (DEBUG_BACKUP) { 17402 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 17403 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 17404 } 17405 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17406 if (ps != null) { 17407 // Already installed so we apply the grant immediately 17408 if (DEBUG_BACKUP) { 17409 Slog.v(TAG, " + already installed; applying"); 17410 } 17411 PermissionsState perms = ps.getPermissionsState(); 17412 BasePermission bp = mSettings.mPermissions.get(permName); 17413 if (bp != null) { 17414 if (isGranted) { 17415 perms.grantRuntimePermission(bp, userId); 17416 } 17417 if (newFlagSet != 0) { 17418 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 17419 } 17420 } 17421 } else { 17422 // Need to wait for post-restore install to apply the grant 17423 if (DEBUG_BACKUP) { 17424 Slog.v(TAG, " - not yet installed; saving for later"); 17425 } 17426 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 17427 isGranted, newFlagSet, userId); 17428 } 17429 } else { 17430 PackageManagerService.reportSettingsProblem(Log.WARN, 17431 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 17432 XmlUtils.skipCurrentTag(parser); 17433 } 17434 } 17435 17436 scheduleWriteSettingsLocked(); 17437 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 17438 } 17439 17440 @Override addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, int sourceUserId, int targetUserId, int flags)17441 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 17442 int sourceUserId, int targetUserId, int flags) { 17443 mContext.enforceCallingOrSelfPermission( 17444 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17445 int callingUid = Binder.getCallingUid(); 17446 enforceOwnerRights(ownerPackage, callingUid); 17447 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17448 if (intentFilter.countActions() == 0) { 17449 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 17450 return; 17451 } 17452 synchronized (mPackages) { 17453 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 17454 ownerPackage, targetUserId, flags); 17455 CrossProfileIntentResolver resolver = 17456 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17457 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 17458 // We have all those whose filter is equal. Now checking if the rest is equal as well. 17459 if (existing != null) { 17460 int size = existing.size(); 17461 for (int i = 0; i < size; i++) { 17462 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 17463 return; 17464 } 17465 } 17466 } 17467 resolver.addFilter(newFilter); 17468 scheduleWritePackageRestrictionsLocked(sourceUserId); 17469 } 17470 } 17471 17472 @Override clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage)17473 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 17474 mContext.enforceCallingOrSelfPermission( 17475 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17476 int callingUid = Binder.getCallingUid(); 17477 enforceOwnerRights(ownerPackage, callingUid); 17478 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17479 synchronized (mPackages) { 17480 CrossProfileIntentResolver resolver = 17481 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17482 ArraySet<CrossProfileIntentFilter> set = 17483 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 17484 for (CrossProfileIntentFilter filter : set) { 17485 if (filter.getOwnerPackage().equals(ownerPackage)) { 17486 resolver.removeFilter(filter); 17487 } 17488 } 17489 scheduleWritePackageRestrictionsLocked(sourceUserId); 17490 } 17491 } 17492 17493 // Enforcing that callingUid is owning pkg on userId enforceOwnerRights(String pkg, int callingUid)17494 private void enforceOwnerRights(String pkg, int callingUid) { 17495 // The system owns everything. 17496 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 17497 return; 17498 } 17499 int callingUserId = UserHandle.getUserId(callingUid); 17500 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 17501 if (pi == null) { 17502 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 17503 + callingUserId); 17504 } 17505 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 17506 throw new SecurityException("Calling uid " + callingUid 17507 + " does not own package " + pkg); 17508 } 17509 } 17510 17511 @Override getHomeActivities(List<ResolveInfo> allHomeCandidates)17512 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 17513 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 17514 } 17515 getHomeIntent()17516 private Intent getHomeIntent() { 17517 Intent intent = new Intent(Intent.ACTION_MAIN); 17518 intent.addCategory(Intent.CATEGORY_HOME); 17519 intent.addCategory(Intent.CATEGORY_DEFAULT); 17520 return intent; 17521 } 17522 getHomeFilter()17523 private IntentFilter getHomeFilter() { 17524 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 17525 filter.addCategory(Intent.CATEGORY_HOME); 17526 filter.addCategory(Intent.CATEGORY_DEFAULT); 17527 return filter; 17528 } 17529 getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)17530 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 17531 int userId) { 17532 Intent intent = getHomeIntent(); 17533 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 17534 PackageManager.GET_META_DATA, userId); 17535 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 17536 true, false, false, userId); 17537 17538 allHomeCandidates.clear(); 17539 if (list != null) { 17540 for (ResolveInfo ri : list) { 17541 allHomeCandidates.add(ri); 17542 } 17543 } 17544 return (preferred == null || preferred.activityInfo == null) 17545 ? null 17546 : new ComponentName(preferred.activityInfo.packageName, 17547 preferred.activityInfo.name); 17548 } 17549 17550 @Override setHomeActivity(ComponentName comp, int userId)17551 public void setHomeActivity(ComponentName comp, int userId) { 17552 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 17553 getHomeActivitiesAsUser(homeActivities, userId); 17554 17555 boolean found = false; 17556 17557 final int size = homeActivities.size(); 17558 final ComponentName[] set = new ComponentName[size]; 17559 for (int i = 0; i < size; i++) { 17560 final ResolveInfo candidate = homeActivities.get(i); 17561 final ActivityInfo info = candidate.activityInfo; 17562 final ComponentName activityName = new ComponentName(info.packageName, info.name); 17563 set[i] = activityName; 17564 if (!found && activityName.equals(comp)) { 17565 found = true; 17566 } 17567 } 17568 if (!found) { 17569 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 17570 + userId); 17571 } 17572 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 17573 set, comp, userId); 17574 } 17575 getSetupWizardPackageName()17576 private @Nullable String getSetupWizardPackageName() { 17577 final Intent intent = new Intent(Intent.ACTION_MAIN); 17578 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 17579 17580 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 17581 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 17582 | MATCH_DISABLED_COMPONENTS, 17583 UserHandle.myUserId()); 17584 if (matches.size() == 1) { 17585 return matches.get(0).getComponentInfo().packageName; 17586 } else { 17587 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 17588 + ": matches=" + matches); 17589 return null; 17590 } 17591 } 17592 17593 @Override setApplicationEnabledSetting(String appPackageName, int newState, int flags, int userId, String callingPackage)17594 public void setApplicationEnabledSetting(String appPackageName, 17595 int newState, int flags, int userId, String callingPackage) { 17596 if (!sUserManager.exists(userId)) return; 17597 if (callingPackage == null) { 17598 callingPackage = Integer.toString(Binder.getCallingUid()); 17599 } 17600 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 17601 } 17602 17603 @Override setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId)17604 public void setComponentEnabledSetting(ComponentName componentName, 17605 int newState, int flags, int userId) { 17606 if (!sUserManager.exists(userId)) return; 17607 setEnabledSetting(componentName.getPackageName(), 17608 componentName.getClassName(), newState, flags, userId, null); 17609 } 17610 setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage)17611 private void setEnabledSetting(final String packageName, String className, int newState, 17612 final int flags, int userId, String callingPackage) { 17613 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 17614 || newState == COMPONENT_ENABLED_STATE_ENABLED 17615 || newState == COMPONENT_ENABLED_STATE_DISABLED 17616 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17617 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 17618 throw new IllegalArgumentException("Invalid new component state: " 17619 + newState); 17620 } 17621 PackageSetting pkgSetting; 17622 final int uid = Binder.getCallingUid(); 17623 final int permission; 17624 if (uid == Process.SYSTEM_UID) { 17625 permission = PackageManager.PERMISSION_GRANTED; 17626 } else { 17627 permission = mContext.checkCallingOrSelfPermission( 17628 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 17629 } 17630 enforceCrossUserPermission(uid, userId, 17631 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 17632 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 17633 boolean sendNow = false; 17634 boolean isApp = (className == null); 17635 String componentName = isApp ? packageName : className; 17636 int packageUid = -1; 17637 ArrayList<String> components; 17638 17639 // writer 17640 synchronized (mPackages) { 17641 pkgSetting = mSettings.mPackages.get(packageName); 17642 if (pkgSetting == null) { 17643 if (className == null) { 17644 throw new IllegalArgumentException("Unknown package: " + packageName); 17645 } 17646 throw new IllegalArgumentException( 17647 "Unknown component: " + packageName + "/" + className); 17648 } 17649 } 17650 17651 // Limit who can change which apps 17652 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 17653 // Don't allow apps that don't have permission to modify other apps 17654 if (!allowedByPermission) { 17655 throw new SecurityException( 17656 "Permission Denial: attempt to change component state from pid=" 17657 + Binder.getCallingPid() 17658 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 17659 } 17660 // Don't allow changing protected packages. 17661 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 17662 throw new SecurityException("Cannot disable a protected package: " + packageName); 17663 } 17664 } 17665 17666 synchronized (mPackages) { 17667 if (uid == Process.SHELL_UID) { 17668 // Shell can only change whole packages between ENABLED and DISABLED_USER states 17669 int oldState = pkgSetting.getEnabled(userId); 17670 if (className == null 17671 && 17672 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 17673 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 17674 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 17675 && 17676 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17677 || newState == COMPONENT_ENABLED_STATE_DEFAULT 17678 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 17679 // ok 17680 } else { 17681 throw new SecurityException( 17682 "Shell cannot change component state for " + packageName + "/" 17683 + className + " to " + newState); 17684 } 17685 } 17686 if (className == null) { 17687 // We're dealing with an application/package level state change 17688 if (pkgSetting.getEnabled(userId) == newState) { 17689 // Nothing to do 17690 return; 17691 } 17692 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 17693 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 17694 // Don't care about who enables an app. 17695 callingPackage = null; 17696 } 17697 pkgSetting.setEnabled(newState, userId, callingPackage); 17698 // pkgSetting.pkg.mSetEnabled = newState; 17699 } else { 17700 // We're dealing with a component level state change 17701 // First, verify that this is a valid class name. 17702 PackageParser.Package pkg = pkgSetting.pkg; 17703 if (pkg == null || !pkg.hasComponentClassName(className)) { 17704 if (pkg != null && 17705 pkg.applicationInfo.targetSdkVersion >= 17706 Build.VERSION_CODES.JELLY_BEAN) { 17707 throw new IllegalArgumentException("Component class " + className 17708 + " does not exist in " + packageName); 17709 } else { 17710 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 17711 + className + " does not exist in " + packageName); 17712 } 17713 } 17714 switch (newState) { 17715 case COMPONENT_ENABLED_STATE_ENABLED: 17716 if (!pkgSetting.enableComponentLPw(className, userId)) { 17717 return; 17718 } 17719 break; 17720 case COMPONENT_ENABLED_STATE_DISABLED: 17721 if (!pkgSetting.disableComponentLPw(className, userId)) { 17722 return; 17723 } 17724 break; 17725 case COMPONENT_ENABLED_STATE_DEFAULT: 17726 if (!pkgSetting.restoreComponentLPw(className, userId)) { 17727 return; 17728 } 17729 break; 17730 default: 17731 Slog.e(TAG, "Invalid new component state: " + newState); 17732 return; 17733 } 17734 } 17735 scheduleWritePackageRestrictionsLocked(userId); 17736 components = mPendingBroadcasts.get(userId, packageName); 17737 final boolean newPackage = components == null; 17738 if (newPackage) { 17739 components = new ArrayList<String>(); 17740 } 17741 if (!components.contains(componentName)) { 17742 components.add(componentName); 17743 } 17744 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 17745 sendNow = true; 17746 // Purge entry from pending broadcast list if another one exists already 17747 // since we are sending one right away. 17748 mPendingBroadcasts.remove(userId, packageName); 17749 } else { 17750 if (newPackage) { 17751 mPendingBroadcasts.put(userId, packageName, components); 17752 } 17753 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 17754 // Schedule a message 17755 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 17756 } 17757 } 17758 } 17759 17760 long callingId = Binder.clearCallingIdentity(); 17761 try { 17762 if (sendNow) { 17763 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 17764 sendPackageChangedBroadcast(packageName, 17765 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 17766 } 17767 } finally { 17768 Binder.restoreCallingIdentity(callingId); 17769 } 17770 } 17771 17772 @Override flushPackageRestrictionsAsUser(int userId)17773 public void flushPackageRestrictionsAsUser(int userId) { 17774 if (!sUserManager.exists(userId)) { 17775 return; 17776 } 17777 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 17778 false /* checkShell */, "flushPackageRestrictions"); 17779 synchronized (mPackages) { 17780 mSettings.writePackageRestrictionsLPr(userId); 17781 mDirtyUsers.remove(userId); 17782 if (mDirtyUsers.isEmpty()) { 17783 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 17784 } 17785 } 17786 } 17787 sendPackageChangedBroadcast(String packageName, boolean killFlag, ArrayList<String> componentNames, int packageUid)17788 private void sendPackageChangedBroadcast(String packageName, 17789 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 17790 if (DEBUG_INSTALL) 17791 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 17792 + componentNames); 17793 Bundle extras = new Bundle(4); 17794 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 17795 String nameList[] = new String[componentNames.size()]; 17796 componentNames.toArray(nameList); 17797 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 17798 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 17799 extras.putInt(Intent.EXTRA_UID, packageUid); 17800 // If this is not reporting a change of the overall package, then only send it 17801 // to registered receivers. We don't want to launch a swath of apps for every 17802 // little component state change. 17803 final int flags = !componentNames.contains(packageName) 17804 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 17805 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 17806 new int[] {UserHandle.getUserId(packageUid)}); 17807 } 17808 17809 @Override setPackageStoppedState(String packageName, boolean stopped, int userId)17810 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 17811 if (!sUserManager.exists(userId)) return; 17812 final int uid = Binder.getCallingUid(); 17813 final int permission = mContext.checkCallingOrSelfPermission( 17814 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 17815 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 17816 enforceCrossUserPermission(uid, userId, 17817 true /* requireFullPermission */, true /* checkShell */, "stop package"); 17818 // writer 17819 synchronized (mPackages) { 17820 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 17821 allowedByPermission, uid, userId)) { 17822 scheduleWritePackageRestrictionsLocked(userId); 17823 } 17824 } 17825 } 17826 17827 @Override getInstallerPackageName(String packageName)17828 public String getInstallerPackageName(String packageName) { 17829 // reader 17830 synchronized (mPackages) { 17831 return mSettings.getInstallerPackageNameLPr(packageName); 17832 } 17833 } 17834 isOrphaned(String packageName)17835 public boolean isOrphaned(String packageName) { 17836 // reader 17837 synchronized (mPackages) { 17838 return mSettings.isOrphaned(packageName); 17839 } 17840 } 17841 17842 @Override getApplicationEnabledSetting(String packageName, int userId)17843 public int getApplicationEnabledSetting(String packageName, int userId) { 17844 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 17845 int uid = Binder.getCallingUid(); 17846 enforceCrossUserPermission(uid, userId, 17847 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 17848 // reader 17849 synchronized (mPackages) { 17850 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 17851 } 17852 } 17853 17854 @Override getComponentEnabledSetting(ComponentName componentName, int userId)17855 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 17856 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 17857 int uid = Binder.getCallingUid(); 17858 enforceCrossUserPermission(uid, userId, 17859 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 17860 // reader 17861 synchronized (mPackages) { 17862 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 17863 } 17864 } 17865 17866 @Override enterSafeMode()17867 public void enterSafeMode() { 17868 enforceSystemOrRoot("Only the system can request entering safe mode"); 17869 17870 if (!mSystemReady) { 17871 mSafeMode = true; 17872 } 17873 } 17874 17875 @Override systemReady()17876 public void systemReady() { 17877 mSystemReady = true; 17878 17879 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 17880 // disabled after already being started. 17881 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 17882 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 17883 17884 // Read the compatibilty setting when the system is ready. 17885 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 17886 mContext.getContentResolver(), 17887 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 17888 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 17889 if (DEBUG_SETTINGS) { 17890 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 17891 } 17892 17893 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 17894 17895 synchronized (mPackages) { 17896 // Verify that all of the preferred activity components actually 17897 // exist. It is possible for applications to be updated and at 17898 // that point remove a previously declared activity component that 17899 // had been set as a preferred activity. We try to clean this up 17900 // the next time we encounter that preferred activity, but it is 17901 // possible for the user flow to never be able to return to that 17902 // situation so here we do a sanity check to make sure we haven't 17903 // left any junk around. 17904 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 17905 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17906 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17907 removed.clear(); 17908 for (PreferredActivity pa : pir.filterSet()) { 17909 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 17910 removed.add(pa); 17911 } 17912 } 17913 if (removed.size() > 0) { 17914 for (int r=0; r<removed.size(); r++) { 17915 PreferredActivity pa = removed.get(r); 17916 Slog.w(TAG, "Removing dangling preferred activity: " 17917 + pa.mPref.mComponent); 17918 pir.removeFilter(pa); 17919 } 17920 mSettings.writePackageRestrictionsLPr( 17921 mSettings.mPreferredActivities.keyAt(i)); 17922 } 17923 } 17924 17925 for (int userId : UserManagerService.getInstance().getUserIds()) { 17926 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 17927 grantPermissionsUserIds = ArrayUtils.appendInt( 17928 grantPermissionsUserIds, userId); 17929 } 17930 } 17931 } 17932 sUserManager.systemReady(); 17933 17934 // If we upgraded grant all default permissions before kicking off. 17935 for (int userId : grantPermissionsUserIds) { 17936 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 17937 } 17938 17939 // If we did not grant default permissions, we preload from this the 17940 // default permission exceptions lazily to ensure we don't hit the 17941 // disk on a new user creation. 17942 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { 17943 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); 17944 } 17945 17946 // Kick off any messages waiting for system ready 17947 if (mPostSystemReadyMessages != null) { 17948 for (Message msg : mPostSystemReadyMessages) { 17949 msg.sendToTarget(); 17950 } 17951 mPostSystemReadyMessages = null; 17952 } 17953 17954 // Watch for external volumes that come and go over time 17955 final StorageManager storage = mContext.getSystemService(StorageManager.class); 17956 storage.registerListener(mStorageListener); 17957 17958 mInstallerService.systemReady(); 17959 mPackageDexOptimizer.systemReady(); 17960 17961 MountServiceInternal mountServiceInternal = LocalServices.getService( 17962 MountServiceInternal.class); 17963 mountServiceInternal.addExternalStoragePolicy( 17964 new MountServiceInternal.ExternalStorageMountPolicy() { 17965 @Override 17966 public int getMountMode(int uid, String packageName) { 17967 if (Process.isIsolated(uid)) { 17968 return Zygote.MOUNT_EXTERNAL_NONE; 17969 } 17970 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 17971 return Zygote.MOUNT_EXTERNAL_DEFAULT; 17972 } 17973 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 17974 return Zygote.MOUNT_EXTERNAL_DEFAULT; 17975 } 17976 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 17977 return Zygote.MOUNT_EXTERNAL_READ; 17978 } 17979 return Zygote.MOUNT_EXTERNAL_WRITE; 17980 } 17981 17982 @Override 17983 public boolean hasExternalStorage(int uid, String packageName) { 17984 return true; 17985 } 17986 }); 17987 17988 // Now that we're mostly running, clean up stale users and apps 17989 reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 17990 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 17991 } 17992 17993 @Override isSafeMode()17994 public boolean isSafeMode() { 17995 return mSafeMode; 17996 } 17997 17998 @Override hasSystemUidErrors()17999 public boolean hasSystemUidErrors() { 18000 return mHasSystemUidErrors; 18001 } 18002 arrayToString(int[] array)18003 static String arrayToString(int[] array) { 18004 StringBuffer buf = new StringBuffer(128); 18005 buf.append('['); 18006 if (array != null) { 18007 for (int i=0; i<array.length; i++) { 18008 if (i > 0) buf.append(", "); 18009 buf.append(array[i]); 18010 } 18011 } 18012 buf.append(']'); 18013 return buf.toString(); 18014 } 18015 18016 static class DumpState { 18017 public static final int DUMP_LIBS = 1 << 0; 18018 public static final int DUMP_FEATURES = 1 << 1; 18019 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 18020 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 18021 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 18022 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 18023 public static final int DUMP_PERMISSIONS = 1 << 6; 18024 public static final int DUMP_PACKAGES = 1 << 7; 18025 public static final int DUMP_SHARED_USERS = 1 << 8; 18026 public static final int DUMP_MESSAGES = 1 << 9; 18027 public static final int DUMP_PROVIDERS = 1 << 10; 18028 public static final int DUMP_VERIFIERS = 1 << 11; 18029 public static final int DUMP_PREFERRED = 1 << 12; 18030 public static final int DUMP_PREFERRED_XML = 1 << 13; 18031 public static final int DUMP_KEYSETS = 1 << 14; 18032 public static final int DUMP_VERSION = 1 << 15; 18033 public static final int DUMP_INSTALLS = 1 << 16; 18034 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 18035 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 18036 public static final int DUMP_FROZEN = 1 << 19; 18037 public static final int DUMP_DEXOPT = 1 << 20; 18038 public static final int DUMP_COMPILER_STATS = 1 << 21; 18039 18040 public static final int OPTION_SHOW_FILTERS = 1 << 0; 18041 18042 private int mTypes; 18043 18044 private int mOptions; 18045 18046 private boolean mTitlePrinted; 18047 18048 private SharedUserSetting mSharedUser; 18049 isDumping(int type)18050 public boolean isDumping(int type) { 18051 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 18052 return true; 18053 } 18054 18055 return (mTypes & type) != 0; 18056 } 18057 setDump(int type)18058 public void setDump(int type) { 18059 mTypes |= type; 18060 } 18061 isOptionEnabled(int option)18062 public boolean isOptionEnabled(int option) { 18063 return (mOptions & option) != 0; 18064 } 18065 setOptionEnabled(int option)18066 public void setOptionEnabled(int option) { 18067 mOptions |= option; 18068 } 18069 onTitlePrinted()18070 public boolean onTitlePrinted() { 18071 final boolean printed = mTitlePrinted; 18072 mTitlePrinted = true; 18073 return printed; 18074 } 18075 getTitlePrinted()18076 public boolean getTitlePrinted() { 18077 return mTitlePrinted; 18078 } 18079 setTitlePrinted(boolean enabled)18080 public void setTitlePrinted(boolean enabled) { 18081 mTitlePrinted = enabled; 18082 } 18083 getSharedUser()18084 public SharedUserSetting getSharedUser() { 18085 return mSharedUser; 18086 } 18087 setSharedUser(SharedUserSetting user)18088 public void setSharedUser(SharedUserSetting user) { 18089 mSharedUser = user; 18090 } 18091 } 18092 18093 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ResultReceiver resultReceiver)18094 public void onShellCommand(FileDescriptor in, FileDescriptor out, 18095 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 18096 (new PackageManagerShellCommand(this)).exec( 18097 this, in, out, err, args, resultReceiver); 18098 } 18099 18100 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)18101 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 18102 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 18103 != PackageManager.PERMISSION_GRANTED) { 18104 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 18105 + Binder.getCallingPid() 18106 + ", uid=" + Binder.getCallingUid() 18107 + " without permission " 18108 + android.Manifest.permission.DUMP); 18109 return; 18110 } 18111 18112 DumpState dumpState = new DumpState(); 18113 boolean fullPreferred = false; 18114 boolean checkin = false; 18115 18116 String packageName = null; 18117 ArraySet<String> permissionNames = null; 18118 18119 int opti = 0; 18120 while (opti < args.length) { 18121 String opt = args[opti]; 18122 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 18123 break; 18124 } 18125 opti++; 18126 18127 if ("-a".equals(opt)) { 18128 // Right now we only know how to print all. 18129 } else if ("-h".equals(opt)) { 18130 pw.println("Package manager dump options:"); 18131 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 18132 pw.println(" --checkin: dump for a checkin"); 18133 pw.println(" -f: print details of intent filters"); 18134 pw.println(" -h: print this help"); 18135 pw.println(" cmd may be one of:"); 18136 pw.println(" l[ibraries]: list known shared libraries"); 18137 pw.println(" f[eatures]: list device features"); 18138 pw.println(" k[eysets]: print known keysets"); 18139 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 18140 pw.println(" perm[issions]: dump permissions"); 18141 pw.println(" permission [name ...]: dump declaration and use of given permission"); 18142 pw.println(" pref[erred]: print preferred package settings"); 18143 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 18144 pw.println(" prov[iders]: dump content providers"); 18145 pw.println(" p[ackages]: dump installed packages"); 18146 pw.println(" s[hared-users]: dump shared user IDs"); 18147 pw.println(" m[essages]: print collected runtime messages"); 18148 pw.println(" v[erifiers]: print package verifier info"); 18149 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 18150 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 18151 pw.println(" version: print database version info"); 18152 pw.println(" write: write current settings now"); 18153 pw.println(" installs: details about install sessions"); 18154 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 18155 pw.println(" dexopt: dump dexopt state"); 18156 pw.println(" compiler-stats: dump compiler statistics"); 18157 pw.println(" <package.name>: info about given package"); 18158 return; 18159 } else if ("--checkin".equals(opt)) { 18160 checkin = true; 18161 } else if ("-f".equals(opt)) { 18162 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18163 } else { 18164 pw.println("Unknown argument: " + opt + "; use -h for help"); 18165 } 18166 } 18167 18168 // Is the caller requesting to dump a particular piece of data? 18169 if (opti < args.length) { 18170 String cmd = args[opti]; 18171 opti++; 18172 // Is this a package name? 18173 if ("android".equals(cmd) || cmd.contains(".")) { 18174 packageName = cmd; 18175 // When dumping a single package, we always dump all of its 18176 // filter information since the amount of data will be reasonable. 18177 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18178 } else if ("check-permission".equals(cmd)) { 18179 if (opti >= args.length) { 18180 pw.println("Error: check-permission missing permission argument"); 18181 return; 18182 } 18183 String perm = args[opti]; 18184 opti++; 18185 if (opti >= args.length) { 18186 pw.println("Error: check-permission missing package argument"); 18187 return; 18188 } 18189 String pkg = args[opti]; 18190 opti++; 18191 int user = UserHandle.getUserId(Binder.getCallingUid()); 18192 if (opti < args.length) { 18193 try { 18194 user = Integer.parseInt(args[opti]); 18195 } catch (NumberFormatException e) { 18196 pw.println("Error: check-permission user argument is not a number: " 18197 + args[opti]); 18198 return; 18199 } 18200 } 18201 pw.println(checkPermission(perm, pkg, user)); 18202 return; 18203 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 18204 dumpState.setDump(DumpState.DUMP_LIBS); 18205 } else if ("f".equals(cmd) || "features".equals(cmd)) { 18206 dumpState.setDump(DumpState.DUMP_FEATURES); 18207 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 18208 if (opti >= args.length) { 18209 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 18210 | DumpState.DUMP_SERVICE_RESOLVERS 18211 | DumpState.DUMP_RECEIVER_RESOLVERS 18212 | DumpState.DUMP_CONTENT_RESOLVERS); 18213 } else { 18214 while (opti < args.length) { 18215 String name = args[opti]; 18216 if ("a".equals(name) || "activity".equals(name)) { 18217 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 18218 } else if ("s".equals(name) || "service".equals(name)) { 18219 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 18220 } else if ("r".equals(name) || "receiver".equals(name)) { 18221 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 18222 } else if ("c".equals(name) || "content".equals(name)) { 18223 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 18224 } else { 18225 pw.println("Error: unknown resolver table type: " + name); 18226 return; 18227 } 18228 opti++; 18229 } 18230 } 18231 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 18232 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 18233 } else if ("permission".equals(cmd)) { 18234 if (opti >= args.length) { 18235 pw.println("Error: permission requires permission name"); 18236 return; 18237 } 18238 permissionNames = new ArraySet<>(); 18239 while (opti < args.length) { 18240 permissionNames.add(args[opti]); 18241 opti++; 18242 } 18243 dumpState.setDump(DumpState.DUMP_PERMISSIONS 18244 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 18245 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 18246 dumpState.setDump(DumpState.DUMP_PREFERRED); 18247 } else if ("preferred-xml".equals(cmd)) { 18248 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 18249 if (opti < args.length && "--full".equals(args[opti])) { 18250 fullPreferred = true; 18251 opti++; 18252 } 18253 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 18254 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 18255 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 18256 dumpState.setDump(DumpState.DUMP_PACKAGES); 18257 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 18258 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 18259 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 18260 dumpState.setDump(DumpState.DUMP_PROVIDERS); 18261 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 18262 dumpState.setDump(DumpState.DUMP_MESSAGES); 18263 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 18264 dumpState.setDump(DumpState.DUMP_VERIFIERS); 18265 } else if ("i".equals(cmd) || "ifv".equals(cmd) 18266 || "intent-filter-verifiers".equals(cmd)) { 18267 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 18268 } else if ("version".equals(cmd)) { 18269 dumpState.setDump(DumpState.DUMP_VERSION); 18270 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 18271 dumpState.setDump(DumpState.DUMP_KEYSETS); 18272 } else if ("installs".equals(cmd)) { 18273 dumpState.setDump(DumpState.DUMP_INSTALLS); 18274 } else if ("frozen".equals(cmd)) { 18275 dumpState.setDump(DumpState.DUMP_FROZEN); 18276 } else if ("dexopt".equals(cmd)) { 18277 dumpState.setDump(DumpState.DUMP_DEXOPT); 18278 } else if ("compiler-stats".equals(cmd)) { 18279 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 18280 } else if ("write".equals(cmd)) { 18281 synchronized (mPackages) { 18282 mSettings.writeLPr(); 18283 pw.println("Settings written."); 18284 return; 18285 } 18286 } 18287 } 18288 18289 if (checkin) { 18290 pw.println("vers,1"); 18291 } 18292 18293 // reader 18294 synchronized (mPackages) { 18295 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 18296 if (!checkin) { 18297 if (dumpState.onTitlePrinted()) 18298 pw.println(); 18299 pw.println("Database versions:"); 18300 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 18301 } 18302 } 18303 18304 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 18305 if (!checkin) { 18306 if (dumpState.onTitlePrinted()) 18307 pw.println(); 18308 pw.println("Verifiers:"); 18309 pw.print(" Required: "); 18310 pw.print(mRequiredVerifierPackage); 18311 pw.print(" (uid="); 18312 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18313 UserHandle.USER_SYSTEM)); 18314 pw.println(")"); 18315 } else if (mRequiredVerifierPackage != null) { 18316 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 18317 pw.print(","); 18318 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18319 UserHandle.USER_SYSTEM)); 18320 } 18321 } 18322 18323 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 18324 packageName == null) { 18325 if (mIntentFilterVerifierComponent != null) { 18326 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 18327 if (!checkin) { 18328 if (dumpState.onTitlePrinted()) 18329 pw.println(); 18330 pw.println("Intent Filter Verifier:"); 18331 pw.print(" Using: "); 18332 pw.print(verifierPackageName); 18333 pw.print(" (uid="); 18334 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18335 UserHandle.USER_SYSTEM)); 18336 pw.println(")"); 18337 } else if (verifierPackageName != null) { 18338 pw.print("ifv,"); pw.print(verifierPackageName); 18339 pw.print(","); 18340 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18341 UserHandle.USER_SYSTEM)); 18342 } 18343 } else { 18344 pw.println(); 18345 pw.println("No Intent Filter Verifier available!"); 18346 } 18347 } 18348 18349 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 18350 boolean printedHeader = false; 18351 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 18352 while (it.hasNext()) { 18353 String name = it.next(); 18354 SharedLibraryEntry ent = mSharedLibraries.get(name); 18355 if (!checkin) { 18356 if (!printedHeader) { 18357 if (dumpState.onTitlePrinted()) 18358 pw.println(); 18359 pw.println("Libraries:"); 18360 printedHeader = true; 18361 } 18362 pw.print(" "); 18363 } else { 18364 pw.print("lib,"); 18365 } 18366 pw.print(name); 18367 if (!checkin) { 18368 pw.print(" -> "); 18369 } 18370 if (ent.path != null) { 18371 if (!checkin) { 18372 pw.print("(jar) "); 18373 pw.print(ent.path); 18374 } else { 18375 pw.print(",jar,"); 18376 pw.print(ent.path); 18377 } 18378 } else { 18379 if (!checkin) { 18380 pw.print("(apk) "); 18381 pw.print(ent.apk); 18382 } else { 18383 pw.print(",apk,"); 18384 pw.print(ent.apk); 18385 } 18386 } 18387 pw.println(); 18388 } 18389 } 18390 18391 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 18392 if (dumpState.onTitlePrinted()) 18393 pw.println(); 18394 if (!checkin) { 18395 pw.println("Features:"); 18396 } 18397 18398 for (FeatureInfo feat : mAvailableFeatures.values()) { 18399 if (checkin) { 18400 pw.print("feat,"); 18401 pw.print(feat.name); 18402 pw.print(","); 18403 pw.println(feat.version); 18404 } else { 18405 pw.print(" "); 18406 pw.print(feat.name); 18407 if (feat.version > 0) { 18408 pw.print(" version="); 18409 pw.print(feat.version); 18410 } 18411 pw.println(); 18412 } 18413 } 18414 } 18415 18416 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 18417 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 18418 : "Activity Resolver Table:", " ", packageName, 18419 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18420 dumpState.setTitlePrinted(true); 18421 } 18422 } 18423 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 18424 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 18425 : "Receiver Resolver Table:", " ", packageName, 18426 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18427 dumpState.setTitlePrinted(true); 18428 } 18429 } 18430 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 18431 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 18432 : "Service Resolver Table:", " ", packageName, 18433 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18434 dumpState.setTitlePrinted(true); 18435 } 18436 } 18437 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 18438 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 18439 : "Provider Resolver Table:", " ", packageName, 18440 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18441 dumpState.setTitlePrinted(true); 18442 } 18443 } 18444 18445 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 18446 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18447 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18448 int user = mSettings.mPreferredActivities.keyAt(i); 18449 if (pir.dump(pw, 18450 dumpState.getTitlePrinted() 18451 ? "\nPreferred Activities User " + user + ":" 18452 : "Preferred Activities User " + user + ":", " ", 18453 packageName, true, false)) { 18454 dumpState.setTitlePrinted(true); 18455 } 18456 } 18457 } 18458 18459 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 18460 pw.flush(); 18461 FileOutputStream fout = new FileOutputStream(fd); 18462 BufferedOutputStream str = new BufferedOutputStream(fout); 18463 XmlSerializer serializer = new FastXmlSerializer(); 18464 try { 18465 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 18466 serializer.startDocument(null, true); 18467 serializer.setFeature( 18468 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 18469 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 18470 serializer.endDocument(); 18471 serializer.flush(); 18472 } catch (IllegalArgumentException e) { 18473 pw.println("Failed writing: " + e); 18474 } catch (IllegalStateException e) { 18475 pw.println("Failed writing: " + e); 18476 } catch (IOException e) { 18477 pw.println("Failed writing: " + e); 18478 } 18479 } 18480 18481 if (!checkin 18482 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 18483 && packageName == null) { 18484 pw.println(); 18485 int count = mSettings.mPackages.size(); 18486 if (count == 0) { 18487 pw.println("No applications!"); 18488 pw.println(); 18489 } else { 18490 final String prefix = " "; 18491 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 18492 if (allPackageSettings.size() == 0) { 18493 pw.println("No domain preferred apps!"); 18494 pw.println(); 18495 } else { 18496 pw.println("App verification status:"); 18497 pw.println(); 18498 count = 0; 18499 for (PackageSetting ps : allPackageSettings) { 18500 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 18501 if (ivi == null || ivi.getPackageName() == null) continue; 18502 pw.println(prefix + "Package: " + ivi.getPackageName()); 18503 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 18504 pw.println(prefix + "Status: " + ivi.getStatusString()); 18505 pw.println(); 18506 count++; 18507 } 18508 if (count == 0) { 18509 pw.println(prefix + "No app verification established."); 18510 pw.println(); 18511 } 18512 for (int userId : sUserManager.getUserIds()) { 18513 pw.println("App linkages for user " + userId + ":"); 18514 pw.println(); 18515 count = 0; 18516 for (PackageSetting ps : allPackageSettings) { 18517 final long status = ps.getDomainVerificationStatusForUser(userId); 18518 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 18519 continue; 18520 } 18521 pw.println(prefix + "Package: " + ps.name); 18522 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 18523 String statusStr = IntentFilterVerificationInfo. 18524 getStatusStringFromValue(status); 18525 pw.println(prefix + "Status: " + statusStr); 18526 pw.println(); 18527 count++; 18528 } 18529 if (count == 0) { 18530 pw.println(prefix + "No configured app linkages."); 18531 pw.println(); 18532 } 18533 } 18534 } 18535 } 18536 } 18537 18538 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 18539 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 18540 if (packageName == null && permissionNames == null) { 18541 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 18542 if (iperm == 0) { 18543 if (dumpState.onTitlePrinted()) 18544 pw.println(); 18545 pw.println("AppOp Permissions:"); 18546 } 18547 pw.print(" AppOp Permission "); 18548 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 18549 pw.println(":"); 18550 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 18551 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 18552 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 18553 } 18554 } 18555 } 18556 } 18557 18558 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 18559 boolean printedSomething = false; 18560 for (PackageParser.Provider p : mProviders.mProviders.values()) { 18561 if (packageName != null && !packageName.equals(p.info.packageName)) { 18562 continue; 18563 } 18564 if (!printedSomething) { 18565 if (dumpState.onTitlePrinted()) 18566 pw.println(); 18567 pw.println("Registered ContentProviders:"); 18568 printedSomething = true; 18569 } 18570 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 18571 pw.print(" "); pw.println(p.toString()); 18572 } 18573 printedSomething = false; 18574 for (Map.Entry<String, PackageParser.Provider> entry : 18575 mProvidersByAuthority.entrySet()) { 18576 PackageParser.Provider p = entry.getValue(); 18577 if (packageName != null && !packageName.equals(p.info.packageName)) { 18578 continue; 18579 } 18580 if (!printedSomething) { 18581 if (dumpState.onTitlePrinted()) 18582 pw.println(); 18583 pw.println("ContentProvider Authorities:"); 18584 printedSomething = true; 18585 } 18586 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 18587 pw.print(" "); pw.println(p.toString()); 18588 if (p.info != null && p.info.applicationInfo != null) { 18589 final String appInfo = p.info.applicationInfo.toString(); 18590 pw.print(" applicationInfo="); pw.println(appInfo); 18591 } 18592 } 18593 } 18594 18595 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 18596 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 18597 } 18598 18599 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 18600 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 18601 } 18602 18603 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 18604 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 18605 } 18606 18607 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 18608 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 18609 } 18610 18611 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 18612 // XXX should handle packageName != null by dumping only install data that 18613 // the given package is involved with. 18614 if (dumpState.onTitlePrinted()) pw.println(); 18615 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 18616 } 18617 18618 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 18619 // XXX should handle packageName != null by dumping only install data that 18620 // the given package is involved with. 18621 if (dumpState.onTitlePrinted()) pw.println(); 18622 18623 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18624 ipw.println(); 18625 ipw.println("Frozen packages:"); 18626 ipw.increaseIndent(); 18627 if (mFrozenPackages.size() == 0) { 18628 ipw.println("(none)"); 18629 } else { 18630 for (int i = 0; i < mFrozenPackages.size(); i++) { 18631 ipw.println(mFrozenPackages.valueAt(i)); 18632 } 18633 } 18634 ipw.decreaseIndent(); 18635 } 18636 18637 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 18638 if (dumpState.onTitlePrinted()) pw.println(); 18639 dumpDexoptStateLPr(pw, packageName); 18640 } 18641 18642 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 18643 if (dumpState.onTitlePrinted()) pw.println(); 18644 dumpCompilerStatsLPr(pw, packageName); 18645 } 18646 18647 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 18648 if (dumpState.onTitlePrinted()) pw.println(); 18649 mSettings.dumpReadMessagesLPr(pw, dumpState); 18650 18651 pw.println(); 18652 pw.println("Package warning messages:"); 18653 BufferedReader in = null; 18654 String line = null; 18655 try { 18656 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18657 while ((line = in.readLine()) != null) { 18658 if (line.contains("ignored: updated version")) continue; 18659 pw.println(line); 18660 } 18661 } catch (IOException ignored) { 18662 } finally { 18663 IoUtils.closeQuietly(in); 18664 } 18665 } 18666 18667 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 18668 BufferedReader in = null; 18669 String line = null; 18670 try { 18671 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18672 while ((line = in.readLine()) != null) { 18673 if (line.contains("ignored: updated version")) continue; 18674 pw.print("msg,"); 18675 pw.println(line); 18676 } 18677 } catch (IOException ignored) { 18678 } finally { 18679 IoUtils.closeQuietly(in); 18680 } 18681 } 18682 } 18683 } 18684 dumpDexoptStateLPr(PrintWriter pw, String packageName)18685 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 18686 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18687 ipw.println(); 18688 ipw.println("Dexopt state:"); 18689 ipw.increaseIndent(); 18690 Collection<PackageParser.Package> packages = null; 18691 if (packageName != null) { 18692 PackageParser.Package targetPackage = mPackages.get(packageName); 18693 if (targetPackage != null) { 18694 packages = Collections.singletonList(targetPackage); 18695 } else { 18696 ipw.println("Unable to find package: " + packageName); 18697 return; 18698 } 18699 } else { 18700 packages = mPackages.values(); 18701 } 18702 18703 for (PackageParser.Package pkg : packages) { 18704 ipw.println("[" + pkg.packageName + "]"); 18705 ipw.increaseIndent(); 18706 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 18707 ipw.decreaseIndent(); 18708 } 18709 } 18710 dumpCompilerStatsLPr(PrintWriter pw, String packageName)18711 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 18712 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18713 ipw.println(); 18714 ipw.println("Compiler stats:"); 18715 ipw.increaseIndent(); 18716 Collection<PackageParser.Package> packages = null; 18717 if (packageName != null) { 18718 PackageParser.Package targetPackage = mPackages.get(packageName); 18719 if (targetPackage != null) { 18720 packages = Collections.singletonList(targetPackage); 18721 } else { 18722 ipw.println("Unable to find package: " + packageName); 18723 return; 18724 } 18725 } else { 18726 packages = mPackages.values(); 18727 } 18728 18729 for (PackageParser.Package pkg : packages) { 18730 ipw.println("[" + pkg.packageName + "]"); 18731 ipw.increaseIndent(); 18732 18733 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 18734 if (stats == null) { 18735 ipw.println("(No recorded stats)"); 18736 } else { 18737 stats.dump(ipw); 18738 } 18739 ipw.decreaseIndent(); 18740 } 18741 } 18742 dumpDomainString(String packageName)18743 private String dumpDomainString(String packageName) { 18744 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 18745 .getList(); 18746 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 18747 18748 ArraySet<String> result = new ArraySet<>(); 18749 if (iviList.size() > 0) { 18750 for (IntentFilterVerificationInfo ivi : iviList) { 18751 for (String host : ivi.getDomains()) { 18752 result.add(host); 18753 } 18754 } 18755 } 18756 if (filters != null && filters.size() > 0) { 18757 for (IntentFilter filter : filters) { 18758 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 18759 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 18760 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 18761 result.addAll(filter.getHostsList()); 18762 } 18763 } 18764 } 18765 18766 StringBuilder sb = new StringBuilder(result.size() * 16); 18767 for (String domain : result) { 18768 if (sb.length() > 0) sb.append(" "); 18769 sb.append(domain); 18770 } 18771 return sb.toString(); 18772 } 18773 18774 // ------- apps on sdcard specific code ------- 18775 static final boolean DEBUG_SD_INSTALL = false; 18776 18777 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 18778 18779 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 18780 18781 private boolean mMediaMounted = false; 18782 getEncryptKey()18783 static String getEncryptKey() { 18784 try { 18785 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 18786 SD_ENCRYPTION_KEYSTORE_NAME); 18787 if (sdEncKey == null) { 18788 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 18789 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 18790 if (sdEncKey == null) { 18791 Slog.e(TAG, "Failed to create encryption keys"); 18792 return null; 18793 } 18794 } 18795 return sdEncKey; 18796 } catch (NoSuchAlgorithmException nsae) { 18797 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 18798 return null; 18799 } catch (IOException ioe) { 18800 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 18801 return null; 18802 } 18803 } 18804 18805 /* 18806 * Update media status on PackageManager. 18807 */ 18808 @Override updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus)18809 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 18810 int callingUid = Binder.getCallingUid(); 18811 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 18812 throw new SecurityException("Media status can only be updated by the system"); 18813 } 18814 // reader; this apparently protects mMediaMounted, but should probably 18815 // be a different lock in that case. 18816 synchronized (mPackages) { 18817 Log.i(TAG, "Updating external media status from " 18818 + (mMediaMounted ? "mounted" : "unmounted") + " to " 18819 + (mediaStatus ? "mounted" : "unmounted")); 18820 if (DEBUG_SD_INSTALL) 18821 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 18822 + ", mMediaMounted=" + mMediaMounted); 18823 if (mediaStatus == mMediaMounted) { 18824 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 18825 : 0, -1); 18826 mHandler.sendMessage(msg); 18827 return; 18828 } 18829 mMediaMounted = mediaStatus; 18830 } 18831 // Queue up an async operation since the package installation may take a 18832 // little while. 18833 mHandler.post(new Runnable() { 18834 public void run() { 18835 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 18836 } 18837 }); 18838 } 18839 18840 /** 18841 * Called by MountService when the initial ASECs to scan are available. 18842 * Should block until all the ASEC containers are finished being scanned. 18843 */ scanAvailableAsecs()18844 public void scanAvailableAsecs() { 18845 updateExternalMediaStatusInner(true, false, false); 18846 } 18847 18848 /* 18849 * Collect information of applications on external media, map them against 18850 * existing containers and update information based on current mount status. 18851 * Please note that we always have to report status if reportStatus has been 18852 * set to true especially when unloading packages. 18853 */ updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, boolean externalStorage)18854 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 18855 boolean externalStorage) { 18856 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 18857 int[] uidArr = EmptyArray.INT; 18858 18859 final String[] list = PackageHelper.getSecureContainerList(); 18860 if (ArrayUtils.isEmpty(list)) { 18861 Log.i(TAG, "No secure containers found"); 18862 } else { 18863 // Process list of secure containers and categorize them 18864 // as active or stale based on their package internal state. 18865 18866 // reader 18867 synchronized (mPackages) { 18868 for (String cid : list) { 18869 // Leave stages untouched for now; installer service owns them 18870 if (PackageInstallerService.isStageName(cid)) continue; 18871 18872 if (DEBUG_SD_INSTALL) 18873 Log.i(TAG, "Processing container " + cid); 18874 String pkgName = getAsecPackageName(cid); 18875 if (pkgName == null) { 18876 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 18877 continue; 18878 } 18879 if (DEBUG_SD_INSTALL) 18880 Log.i(TAG, "Looking for pkg : " + pkgName); 18881 18882 final PackageSetting ps = mSettings.mPackages.get(pkgName); 18883 if (ps == null) { 18884 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 18885 continue; 18886 } 18887 18888 /* 18889 * Skip packages that are not external if we're unmounting 18890 * external storage. 18891 */ 18892 if (externalStorage && !isMounted && !isExternal(ps)) { 18893 continue; 18894 } 18895 18896 final AsecInstallArgs args = new AsecInstallArgs(cid, 18897 getAppDexInstructionSets(ps), ps.isForwardLocked()); 18898 // The package status is changed only if the code path 18899 // matches between settings and the container id. 18900 if (ps.codePathString != null 18901 && ps.codePathString.startsWith(args.getCodePath())) { 18902 if (DEBUG_SD_INSTALL) { 18903 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 18904 + " at code path: " + ps.codePathString); 18905 } 18906 18907 // We do have a valid package installed on sdcard 18908 processCids.put(args, ps.codePathString); 18909 final int uid = ps.appId; 18910 if (uid != -1) { 18911 uidArr = ArrayUtils.appendInt(uidArr, uid); 18912 } 18913 } else { 18914 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 18915 + ps.codePathString); 18916 } 18917 } 18918 } 18919 18920 Arrays.sort(uidArr); 18921 } 18922 18923 // Process packages with valid entries. 18924 if (isMounted) { 18925 if (DEBUG_SD_INSTALL) 18926 Log.i(TAG, "Loading packages"); 18927 loadMediaPackages(processCids, uidArr, externalStorage); 18928 startCleaningPackages(); 18929 mInstallerService.onSecureContainersAvailable(); 18930 } else { 18931 if (DEBUG_SD_INSTALL) 18932 Log.i(TAG, "Unloading packages"); 18933 unloadMediaPackages(processCids, uidArr, reportStatus); 18934 } 18935 } 18936 sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver)18937 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 18938 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 18939 final int size = infos.size(); 18940 final String[] packageNames = new String[size]; 18941 final int[] packageUids = new int[size]; 18942 for (int i = 0; i < size; i++) { 18943 final ApplicationInfo info = infos.get(i); 18944 packageNames[i] = info.packageName; 18945 packageUids[i] = info.uid; 18946 } 18947 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 18948 finishedReceiver); 18949 } 18950 sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver)18951 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 18952 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 18953 sendResourcesChangedBroadcast(mediaStatus, replacing, 18954 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 18955 } 18956 sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver)18957 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 18958 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 18959 int size = pkgList.length; 18960 if (size > 0) { 18961 // Send broadcasts here 18962 Bundle extras = new Bundle(); 18963 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 18964 if (uidArr != null) { 18965 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 18966 } 18967 if (replacing) { 18968 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 18969 } 18970 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 18971 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 18972 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 18973 } 18974 } 18975 18976 /* 18977 * Look at potentially valid container ids from processCids If package 18978 * information doesn't match the one on record or package scanning fails, 18979 * the cid is added to list of removeCids. We currently don't delete stale 18980 * containers. 18981 */ loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, boolean externalStorage)18982 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 18983 boolean externalStorage) { 18984 ArrayList<String> pkgList = new ArrayList<String>(); 18985 Set<AsecInstallArgs> keys = processCids.keySet(); 18986 18987 for (AsecInstallArgs args : keys) { 18988 String codePath = processCids.get(args); 18989 if (DEBUG_SD_INSTALL) 18990 Log.i(TAG, "Loading container : " + args.cid); 18991 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 18992 try { 18993 // Make sure there are no container errors first. 18994 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 18995 Slog.e(TAG, "Failed to mount cid : " + args.cid 18996 + " when installing from sdcard"); 18997 continue; 18998 } 18999 // Check code path here. 19000 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 19001 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 19002 + " does not match one in settings " + codePath); 19003 continue; 19004 } 19005 // Parse package 19006 int parseFlags = mDefParseFlags; 19007 if (args.isExternalAsec()) { 19008 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 19009 } 19010 if (args.isFwdLocked()) { 19011 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 19012 } 19013 19014 synchronized (mInstallLock) { 19015 PackageParser.Package pkg = null; 19016 try { 19017 // Sadly we don't know the package name yet to freeze it 19018 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 19019 SCAN_IGNORE_FROZEN, 0, null); 19020 } catch (PackageManagerException e) { 19021 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 19022 } 19023 // Scan the package 19024 if (pkg != null) { 19025 /* 19026 * TODO why is the lock being held? doPostInstall is 19027 * called in other places without the lock. This needs 19028 * to be straightened out. 19029 */ 19030 // writer 19031 synchronized (mPackages) { 19032 retCode = PackageManager.INSTALL_SUCCEEDED; 19033 pkgList.add(pkg.packageName); 19034 // Post process args 19035 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 19036 pkg.applicationInfo.uid); 19037 } 19038 } else { 19039 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 19040 } 19041 } 19042 19043 } finally { 19044 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 19045 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 19046 } 19047 } 19048 } 19049 // writer 19050 synchronized (mPackages) { 19051 // If the platform SDK has changed since the last time we booted, 19052 // we need to re-grant app permission to catch any new ones that 19053 // appear. This is really a hack, and means that apps can in some 19054 // cases get permissions that the user didn't initially explicitly 19055 // allow... it would be nice to have some better way to handle 19056 // this situation. 19057 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 19058 : mSettings.getInternalVersion(); 19059 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 19060 : StorageManager.UUID_PRIVATE_INTERNAL; 19061 19062 int updateFlags = UPDATE_PERMISSIONS_ALL; 19063 if (ver.sdkVersion != mSdkVersion) { 19064 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19065 + mSdkVersion + "; regranting permissions for external"); 19066 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19067 } 19068 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19069 19070 // Yay, everything is now upgraded 19071 ver.forceCurrent(); 19072 19073 // can downgrade to reader 19074 // Persist settings 19075 mSettings.writeLPr(); 19076 } 19077 // Send a broadcast to let everyone know we are done processing 19078 if (pkgList.size() > 0) { 19079 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 19080 } 19081 } 19082 19083 /* 19084 * Utility method to unload a list of specified containers 19085 */ unloadAllContainers(Set<AsecInstallArgs> cidArgs)19086 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 19087 // Just unmount all valid containers. 19088 for (AsecInstallArgs arg : cidArgs) { 19089 synchronized (mInstallLock) { 19090 arg.doPostDeleteLI(false); 19091 } 19092 } 19093 } 19094 19095 /* 19096 * Unload packages mounted on external media. This involves deleting package 19097 * data from internal structures, sending broadcasts about disabled packages, 19098 * gc'ing to free up references, unmounting all secure containers 19099 * corresponding to packages on external media, and posting a 19100 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 19101 * that we always have to post this message if status has been requested no 19102 * matter what. 19103 */ unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus)19104 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 19105 final boolean reportStatus) { 19106 if (DEBUG_SD_INSTALL) 19107 Log.i(TAG, "unloading media packages"); 19108 ArrayList<String> pkgList = new ArrayList<String>(); 19109 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 19110 final Set<AsecInstallArgs> keys = processCids.keySet(); 19111 for (AsecInstallArgs args : keys) { 19112 String pkgName = args.getPackageName(); 19113 if (DEBUG_SD_INSTALL) 19114 Log.i(TAG, "Trying to unload pkg : " + pkgName); 19115 // Delete package internally 19116 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19117 synchronized (mInstallLock) { 19118 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19119 final boolean res; 19120 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 19121 "unloadMediaPackages")) { 19122 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 19123 null); 19124 } 19125 if (res) { 19126 pkgList.add(pkgName); 19127 } else { 19128 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 19129 failedList.add(args); 19130 } 19131 } 19132 } 19133 19134 // reader 19135 synchronized (mPackages) { 19136 // We didn't update the settings after removing each package; 19137 // write them now for all packages. 19138 mSettings.writeLPr(); 19139 } 19140 19141 // We have to absolutely send UPDATED_MEDIA_STATUS only 19142 // after confirming that all the receivers processed the ordered 19143 // broadcast when packages get disabled, force a gc to clean things up. 19144 // and unload all the containers. 19145 if (pkgList.size() > 0) { 19146 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 19147 new IIntentReceiver.Stub() { 19148 public void performReceive(Intent intent, int resultCode, String data, 19149 Bundle extras, boolean ordered, boolean sticky, 19150 int sendingUser) throws RemoteException { 19151 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 19152 reportStatus ? 1 : 0, 1, keys); 19153 mHandler.sendMessage(msg); 19154 } 19155 }); 19156 } else { 19157 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 19158 keys); 19159 mHandler.sendMessage(msg); 19160 } 19161 } 19162 loadPrivatePackages(final VolumeInfo vol)19163 private void loadPrivatePackages(final VolumeInfo vol) { 19164 mHandler.post(new Runnable() { 19165 @Override 19166 public void run() { 19167 loadPrivatePackagesInner(vol); 19168 } 19169 }); 19170 } 19171 loadPrivatePackagesInner(VolumeInfo vol)19172 private void loadPrivatePackagesInner(VolumeInfo vol) { 19173 final String volumeUuid = vol.fsUuid; 19174 if (TextUtils.isEmpty(volumeUuid)) { 19175 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 19176 return; 19177 } 19178 19179 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 19180 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 19181 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 19182 19183 final VersionInfo ver; 19184 final List<PackageSetting> packages; 19185 synchronized (mPackages) { 19186 ver = mSettings.findOrCreateVersion(volumeUuid); 19187 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19188 } 19189 19190 for (PackageSetting ps : packages) { 19191 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 19192 synchronized (mInstallLock) { 19193 final PackageParser.Package pkg; 19194 try { 19195 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 19196 loaded.add(pkg.applicationInfo); 19197 19198 } catch (PackageManagerException e) { 19199 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 19200 } 19201 19202 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 19203 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 19204 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 19205 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 19206 } 19207 } 19208 } 19209 19210 // Reconcile app data for all started/unlocked users 19211 final StorageManager sm = mContext.getSystemService(StorageManager.class); 19212 final UserManager um = mContext.getSystemService(UserManager.class); 19213 UserManagerInternal umInternal = getUserManagerInternal(); 19214 for (UserInfo user : um.getUsers()) { 19215 final int flags; 19216 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19217 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19218 } else if (umInternal.isUserRunning(user.id)) { 19219 flags = StorageManager.FLAG_STORAGE_DE; 19220 } else { 19221 continue; 19222 } 19223 19224 try { 19225 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 19226 synchronized (mInstallLock) { 19227 reconcileAppsDataLI(volumeUuid, user.id, flags); 19228 } 19229 } catch (IllegalStateException e) { 19230 // Device was probably ejected, and we'll process that event momentarily 19231 Slog.w(TAG, "Failed to prepare storage: " + e); 19232 } 19233 } 19234 19235 synchronized (mPackages) { 19236 int updateFlags = UPDATE_PERMISSIONS_ALL; 19237 if (ver.sdkVersion != mSdkVersion) { 19238 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19239 + mSdkVersion + "; regranting permissions for " + volumeUuid); 19240 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19241 } 19242 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19243 19244 // Yay, everything is now upgraded 19245 ver.forceCurrent(); 19246 19247 mSettings.writeLPr(); 19248 } 19249 19250 for (PackageFreezer freezer : freezers) { 19251 freezer.close(); 19252 } 19253 19254 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 19255 sendResourcesChangedBroadcast(true, false, loaded, null); 19256 } 19257 unloadPrivatePackages(final VolumeInfo vol)19258 private void unloadPrivatePackages(final VolumeInfo vol) { 19259 mHandler.post(new Runnable() { 19260 @Override 19261 public void run() { 19262 unloadPrivatePackagesInner(vol); 19263 } 19264 }); 19265 } 19266 unloadPrivatePackagesInner(VolumeInfo vol)19267 private void unloadPrivatePackagesInner(VolumeInfo vol) { 19268 final String volumeUuid = vol.fsUuid; 19269 if (TextUtils.isEmpty(volumeUuid)) { 19270 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 19271 return; 19272 } 19273 19274 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 19275 synchronized (mInstallLock) { 19276 synchronized (mPackages) { 19277 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 19278 for (PackageSetting ps : packages) { 19279 if (ps.pkg == null) continue; 19280 19281 final ApplicationInfo info = ps.pkg.applicationInfo; 19282 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19283 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19284 19285 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 19286 "unloadPrivatePackagesInner")) { 19287 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 19288 false, null)) { 19289 unloaded.add(info); 19290 } else { 19291 Slog.w(TAG, "Failed to unload " + ps.codePath); 19292 } 19293 } 19294 19295 // Try very hard to release any references to this package 19296 // so we don't risk the system server being killed due to 19297 // open FDs 19298 AttributeCache.instance().removePackage(ps.name); 19299 } 19300 19301 mSettings.writeLPr(); 19302 } 19303 } 19304 19305 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 19306 sendResourcesChangedBroadcast(false, false, unloaded, null); 19307 19308 // Try very hard to release any references to this path so we don't risk 19309 // the system server being killed due to open FDs 19310 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 19311 19312 for (int i = 0; i < 3; i++) { 19313 System.gc(); 19314 System.runFinalization(); 19315 } 19316 } 19317 19318 /** 19319 * Prepare storage areas for given user on all mounted devices. 19320 */ prepareUserData(int userId, int userSerial, int flags)19321 void prepareUserData(int userId, int userSerial, int flags) { 19322 synchronized (mInstallLock) { 19323 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19324 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19325 final String volumeUuid = vol.getFsUuid(); 19326 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); 19327 } 19328 } 19329 } 19330 prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, boolean allowRecover)19331 private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, 19332 boolean allowRecover) { 19333 // Prepare storage and verify that serial numbers are consistent; if 19334 // there's a mismatch we need to destroy to avoid leaking data 19335 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19336 try { 19337 storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); 19338 19339 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) { 19340 UserManagerService.enforceSerialNumber( 19341 Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial); 19342 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19343 UserManagerService.enforceSerialNumber( 19344 Environment.getDataSystemDeDirectory(userId), userSerial); 19345 } 19346 } 19347 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) { 19348 UserManagerService.enforceSerialNumber( 19349 Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial); 19350 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19351 UserManagerService.enforceSerialNumber( 19352 Environment.getDataSystemCeDirectory(userId), userSerial); 19353 } 19354 } 19355 19356 synchronized (mInstallLock) { 19357 mInstaller.createUserData(volumeUuid, userId, userSerial, flags); 19358 } 19359 } catch (Exception e) { 19360 logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid 19361 + " because we failed to prepare: " + e); 19362 destroyUserDataLI(volumeUuid, userId, 19363 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19364 19365 if (allowRecover) { 19366 // Try one last time; if we fail again we're really in trouble 19367 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false); 19368 } 19369 } 19370 } 19371 19372 /** 19373 * Destroy storage areas for given user on all mounted devices. 19374 */ destroyUserData(int userId, int flags)19375 void destroyUserData(int userId, int flags) { 19376 synchronized (mInstallLock) { 19377 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19378 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19379 final String volumeUuid = vol.getFsUuid(); 19380 destroyUserDataLI(volumeUuid, userId, flags); 19381 } 19382 } 19383 } 19384 destroyUserDataLI(String volumeUuid, int userId, int flags)19385 private void destroyUserDataLI(String volumeUuid, int userId, int flags) { 19386 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19387 try { 19388 // Clean up app data, profile data, and media data 19389 mInstaller.destroyUserData(volumeUuid, userId, flags); 19390 19391 // Clean up system data 19392 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19393 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19394 FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId)); 19395 FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId)); 19396 } 19397 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19398 FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId)); 19399 } 19400 } 19401 19402 // Data with special labels is now gone, so finish the job 19403 storage.destroyUserStorage(volumeUuid, userId, flags); 19404 19405 } catch (Exception e) { 19406 logCriticalInfo(Log.WARN, 19407 "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e); 19408 } 19409 } 19410 19411 /** 19412 * Examine all users present on given mounted volume, and destroy data 19413 * belonging to users that are no longer valid, or whose user ID has been 19414 * recycled. 19415 */ reconcileUsers(String volumeUuid)19416 private void reconcileUsers(String volumeUuid) { 19417 final List<File> files = new ArrayList<>(); 19418 Collections.addAll(files, FileUtils 19419 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid))); 19420 Collections.addAll(files, FileUtils 19421 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid))); 19422 Collections.addAll(files, FileUtils 19423 .listFilesOrEmpty(Environment.getDataSystemDeDirectory())); 19424 Collections.addAll(files, FileUtils 19425 .listFilesOrEmpty(Environment.getDataSystemCeDirectory())); 19426 for (File file : files) { 19427 if (!file.isDirectory()) continue; 19428 19429 final int userId; 19430 final UserInfo info; 19431 try { 19432 userId = Integer.parseInt(file.getName()); 19433 info = sUserManager.getUserInfo(userId); 19434 } catch (NumberFormatException e) { 19435 Slog.w(TAG, "Invalid user directory " + file); 19436 continue; 19437 } 19438 19439 boolean destroyUser = false; 19440 if (info == null) { 19441 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19442 + " because no matching user was found"); 19443 destroyUser = true; 19444 } else if (!mOnlyCore) { 19445 try { 19446 UserManagerService.enforceSerialNumber(file, info.serialNumber); 19447 } catch (IOException e) { 19448 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19449 + " because we failed to enforce serial number: " + e); 19450 destroyUser = true; 19451 } 19452 } 19453 19454 if (destroyUser) { 19455 synchronized (mInstallLock) { 19456 destroyUserDataLI(volumeUuid, userId, 19457 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19458 } 19459 } 19460 } 19461 } 19462 assertPackageKnown(String volumeUuid, String packageName)19463 private void assertPackageKnown(String volumeUuid, String packageName) 19464 throws PackageManagerException { 19465 synchronized (mPackages) { 19466 final PackageSetting ps = mSettings.mPackages.get(packageName); 19467 if (ps == null) { 19468 throw new PackageManagerException("Package " + packageName + " is unknown"); 19469 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19470 throw new PackageManagerException( 19471 "Package " + packageName + " found on unknown volume " + volumeUuid 19472 + "; expected volume " + ps.volumeUuid); 19473 } 19474 } 19475 } 19476 assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)19477 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 19478 throws PackageManagerException { 19479 synchronized (mPackages) { 19480 final PackageSetting ps = mSettings.mPackages.get(packageName); 19481 if (ps == null) { 19482 throw new PackageManagerException("Package " + packageName + " is unknown"); 19483 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19484 throw new PackageManagerException( 19485 "Package " + packageName + " found on unknown volume " + volumeUuid 19486 + "; expected volume " + ps.volumeUuid); 19487 } else if (!ps.getInstalled(userId)) { 19488 throw new PackageManagerException( 19489 "Package " + packageName + " not installed for user " + userId); 19490 } 19491 } 19492 } 19493 19494 /** 19495 * Examine all apps present on given mounted volume, and destroy apps that 19496 * aren't expected, either due to uninstallation or reinstallation on 19497 * another volume. 19498 */ reconcileApps(String volumeUuid)19499 private void reconcileApps(String volumeUuid) { 19500 final File[] files = FileUtils 19501 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 19502 for (File file : files) { 19503 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 19504 && !PackageInstallerService.isStageName(file.getName()); 19505 if (!isPackage) { 19506 // Ignore entries which are not packages 19507 continue; 19508 } 19509 19510 try { 19511 final PackageLite pkg = PackageParser.parsePackageLite(file, 19512 PackageParser.PARSE_MUST_BE_APK); 19513 assertPackageKnown(volumeUuid, pkg.packageName); 19514 19515 } catch (PackageParserException | PackageManagerException e) { 19516 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19517 synchronized (mInstallLock) { 19518 removeCodePathLI(file); 19519 } 19520 } 19521 } 19522 } 19523 19524 /** 19525 * Reconcile all app data for the given user. 19526 * <p> 19527 * Verifies that directories exist and that ownership and labeling is 19528 * correct for all installed apps on all mounted volumes. 19529 */ reconcileAppsData(int userId, int flags)19530 void reconcileAppsData(int userId, int flags) { 19531 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19532 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19533 final String volumeUuid = vol.getFsUuid(); 19534 synchronized (mInstallLock) { 19535 reconcileAppsDataLI(volumeUuid, userId, flags); 19536 } 19537 } 19538 } 19539 19540 /** 19541 * Reconcile all app data on given mounted volume. 19542 * <p> 19543 * Destroys app data that isn't expected, either due to uninstallation or 19544 * reinstallation on another volume. 19545 * <p> 19546 * Verifies that directories exist and that ownership and labeling is 19547 * correct for all installed apps. 19548 */ reconcileAppsDataLI(String volumeUuid, int userId, int flags)19549 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) { 19550 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 19551 + Integer.toHexString(flags)); 19552 19553 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 19554 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 19555 19556 boolean restoreconNeeded = false; 19557 19558 // First look for stale data that doesn't belong, and check if things 19559 // have changed since we did our last restorecon 19560 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19561 if (StorageManager.isFileEncryptedNativeOrEmulated() 19562 && !StorageManager.isUserKeyUnlocked(userId)) { 19563 throw new RuntimeException( 19564 "Yikes, someone asked us to reconcile CE storage while " + userId 19565 + " was still locked; this would have caused massive data loss!"); 19566 } 19567 19568 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); 19569 19570 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 19571 for (File file : files) { 19572 final String packageName = file.getName(); 19573 try { 19574 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19575 } catch (PackageManagerException e) { 19576 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19577 try { 19578 mInstaller.destroyAppData(volumeUuid, packageName, userId, 19579 StorageManager.FLAG_STORAGE_CE, 0); 19580 } catch (InstallerException e2) { 19581 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 19582 } 19583 } 19584 } 19585 } 19586 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19587 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); 19588 19589 final File[] files = FileUtils.listFilesOrEmpty(deDir); 19590 for (File file : files) { 19591 final String packageName = file.getName(); 19592 try { 19593 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19594 } catch (PackageManagerException e) { 19595 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19596 try { 19597 mInstaller.destroyAppData(volumeUuid, packageName, userId, 19598 StorageManager.FLAG_STORAGE_DE, 0); 19599 } catch (InstallerException e2) { 19600 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 19601 } 19602 } 19603 } 19604 } 19605 19606 // Ensure that data directories are ready to roll for all packages 19607 // installed for this volume and user 19608 final List<PackageSetting> packages; 19609 synchronized (mPackages) { 19610 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19611 } 19612 int preparedCount = 0; 19613 for (PackageSetting ps : packages) { 19614 final String packageName = ps.name; 19615 if (ps.pkg == null) { 19616 Slog.w(TAG, "Odd, missing scanned package " + packageName); 19617 // TODO: might be due to legacy ASEC apps; we should circle back 19618 // and reconcile again once they're scanned 19619 continue; 19620 } 19621 19622 if (ps.getInstalled(userId)) { 19623 prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded); 19624 19625 if (maybeMigrateAppDataLIF(ps.pkg, userId)) { 19626 // We may have just shuffled around app data directories, so 19627 // prepare them one more time 19628 prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded); 19629 } 19630 19631 preparedCount++; 19632 } 19633 } 19634 19635 if (restoreconNeeded) { 19636 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19637 SELinuxMMAC.setRestoreconDone(ceDir); 19638 } 19639 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19640 SELinuxMMAC.setRestoreconDone(deDir); 19641 } 19642 } 19643 19644 Slog.v(TAG, "reconcileAppsData finished " + preparedCount 19645 + " packages; restoreconNeeded was " + restoreconNeeded); 19646 } 19647 19648 /** 19649 * Prepare app data for the given app just after it was installed or 19650 * upgraded. This method carefully only touches users that it's installed 19651 * for, and it forces a restorecon to handle any seinfo changes. 19652 * <p> 19653 * Verifies that directories exist and that ownership and labeling is 19654 * correct for all installed apps. If there is an ownership mismatch, it 19655 * will try recovering system apps by wiping data; third-party app data is 19656 * left intact. 19657 * <p> 19658 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 19659 */ prepareAppDataAfterInstallLIF(PackageParser.Package pkg)19660 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 19661 final PackageSetting ps; 19662 synchronized (mPackages) { 19663 ps = mSettings.mPackages.get(pkg.packageName); 19664 mSettings.writeKernelMappingLPr(ps); 19665 } 19666 19667 final UserManager um = mContext.getSystemService(UserManager.class); 19668 UserManagerInternal umInternal = getUserManagerInternal(); 19669 for (UserInfo user : um.getUsers()) { 19670 final int flags; 19671 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19672 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19673 } else if (umInternal.isUserRunning(user.id)) { 19674 flags = StorageManager.FLAG_STORAGE_DE; 19675 } else { 19676 continue; 19677 } 19678 19679 if (ps.getInstalled(user.id)) { 19680 // Whenever an app changes, force a restorecon of its data 19681 // TODO: when user data is locked, mark that we're still dirty 19682 prepareAppDataLIF(pkg, user.id, flags, true); 19683 } 19684 } 19685 } 19686 19687 /** 19688 * Prepare app data for the given app. 19689 * <p> 19690 * Verifies that directories exist and that ownership and labeling is 19691 * correct for all installed apps. If there is an ownership mismatch, this 19692 * will try recovering system apps by wiping data; third-party app data is 19693 * left intact. 19694 */ prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags, boolean restoreconNeeded)19695 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags, 19696 boolean restoreconNeeded) { 19697 if (pkg == null) { 19698 Slog.wtf(TAG, "Package was null!", new Throwable()); 19699 return; 19700 } 19701 prepareAppDataLeafLIF(pkg, userId, flags, restoreconNeeded); 19702 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 19703 for (int i = 0; i < childCount; i++) { 19704 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags, restoreconNeeded); 19705 } 19706 } 19707 prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags, boolean restoreconNeeded)19708 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags, 19709 boolean restoreconNeeded) { 19710 if (DEBUG_APP_DATA) { 19711 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 19712 + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); 19713 } 19714 19715 final String volumeUuid = pkg.volumeUuid; 19716 final String packageName = pkg.packageName; 19717 final ApplicationInfo app = pkg.applicationInfo; 19718 final int appId = UserHandle.getAppId(app.uid); 19719 19720 Preconditions.checkNotNull(app.seinfo); 19721 19722 try { 19723 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 19724 appId, app.seinfo, app.targetSdkVersion); 19725 } catch (InstallerException e) { 19726 if (app.isSystemApp()) { 19727 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 19728 + ", but trying to recover: " + e); 19729 destroyAppDataLeafLIF(pkg, userId, flags); 19730 try { 19731 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 19732 appId, app.seinfo, app.targetSdkVersion); 19733 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 19734 } catch (InstallerException e2) { 19735 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 19736 } 19737 } else { 19738 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 19739 } 19740 } 19741 19742 if (restoreconNeeded) { 19743 try { 19744 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, 19745 app.seinfo); 19746 } catch (InstallerException e) { 19747 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); 19748 } 19749 } 19750 19751 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19752 try { 19753 // CE storage is unlocked right now, so read out the inode and 19754 // remember for use later when it's locked 19755 // TODO: mark this structure as dirty so we persist it! 19756 final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId, 19757 StorageManager.FLAG_STORAGE_CE); 19758 synchronized (mPackages) { 19759 final PackageSetting ps = mSettings.mPackages.get(packageName); 19760 if (ps != null) { 19761 ps.setCeDataInode(ceDataInode, userId); 19762 } 19763 } 19764 } catch (InstallerException e) { 19765 Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e); 19766 } 19767 } 19768 19769 prepareAppDataContentsLeafLIF(pkg, userId, flags); 19770 } 19771 prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags)19772 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 19773 if (pkg == null) { 19774 Slog.wtf(TAG, "Package was null!", new Throwable()); 19775 return; 19776 } 19777 prepareAppDataContentsLeafLIF(pkg, userId, flags); 19778 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 19779 for (int i = 0; i < childCount; i++) { 19780 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 19781 } 19782 } 19783 prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags)19784 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 19785 final String volumeUuid = pkg.volumeUuid; 19786 final String packageName = pkg.packageName; 19787 final ApplicationInfo app = pkg.applicationInfo; 19788 19789 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19790 // Create a native library symlink only if we have native libraries 19791 // and if the native libraries are 32 bit libraries. We do not provide 19792 // this symlink for 64 bit libraries. 19793 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 19794 final String nativeLibPath = app.nativeLibraryDir; 19795 try { 19796 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 19797 nativeLibPath, userId); 19798 } catch (InstallerException e) { 19799 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 19800 } 19801 } 19802 } 19803 } 19804 19805 /** 19806 * For system apps on non-FBE devices, this method migrates any existing 19807 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 19808 * requested by the app. 19809 */ maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId)19810 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 19811 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 19812 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 19813 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 19814 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 19815 try { 19816 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 19817 storageTarget); 19818 } catch (InstallerException e) { 19819 logCriticalInfo(Log.WARN, 19820 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 19821 } 19822 return true; 19823 } else { 19824 return false; 19825 } 19826 } 19827 freezePackage(String packageName, String killReason)19828 public PackageFreezer freezePackage(String packageName, String killReason) { 19829 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 19830 } 19831 freezePackage(String packageName, int userId, String killReason)19832 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 19833 return new PackageFreezer(packageName, userId, killReason); 19834 } 19835 freezePackageForInstall(String packageName, int installFlags, String killReason)19836 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 19837 String killReason) { 19838 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 19839 } 19840 freezePackageForInstall(String packageName, int userId, int installFlags, String killReason)19841 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 19842 String killReason) { 19843 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 19844 return new PackageFreezer(); 19845 } else { 19846 return freezePackage(packageName, userId, killReason); 19847 } 19848 } 19849 freezePackageForDelete(String packageName, int deleteFlags, String killReason)19850 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 19851 String killReason) { 19852 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 19853 } 19854 freezePackageForDelete(String packageName, int userId, int deleteFlags, String killReason)19855 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 19856 String killReason) { 19857 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 19858 return new PackageFreezer(); 19859 } else { 19860 return freezePackage(packageName, userId, killReason); 19861 } 19862 } 19863 19864 /** 19865 * Class that freezes and kills the given package upon creation, and 19866 * unfreezes it upon closing. This is typically used when doing surgery on 19867 * app code/data to prevent the app from running while you're working. 19868 */ 19869 private class PackageFreezer implements AutoCloseable { 19870 private final String mPackageName; 19871 private final PackageFreezer[] mChildren; 19872 19873 private final boolean mWeFroze; 19874 19875 private final AtomicBoolean mClosed = new AtomicBoolean(); 19876 private final CloseGuard mCloseGuard = CloseGuard.get(); 19877 19878 /** 19879 * Create and return a stub freezer that doesn't actually do anything, 19880 * typically used when someone requested 19881 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 19882 * {@link PackageManager#DELETE_DONT_KILL_APP}. 19883 */ PackageFreezer()19884 public PackageFreezer() { 19885 mPackageName = null; 19886 mChildren = null; 19887 mWeFroze = false; 19888 mCloseGuard.open("close"); 19889 } 19890 PackageFreezer(String packageName, int userId, String killReason)19891 public PackageFreezer(String packageName, int userId, String killReason) { 19892 synchronized (mPackages) { 19893 mPackageName = packageName; 19894 mWeFroze = mFrozenPackages.add(mPackageName); 19895 19896 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 19897 if (ps != null) { 19898 killApplication(ps.name, ps.appId, userId, killReason); 19899 } 19900 19901 final PackageParser.Package p = mPackages.get(packageName); 19902 if (p != null && p.childPackages != null) { 19903 final int N = p.childPackages.size(); 19904 mChildren = new PackageFreezer[N]; 19905 for (int i = 0; i < N; i++) { 19906 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 19907 userId, killReason); 19908 } 19909 } else { 19910 mChildren = null; 19911 } 19912 } 19913 mCloseGuard.open("close"); 19914 } 19915 19916 @Override finalize()19917 protected void finalize() throws Throwable { 19918 try { 19919 mCloseGuard.warnIfOpen(); 19920 close(); 19921 } finally { 19922 super.finalize(); 19923 } 19924 } 19925 19926 @Override close()19927 public void close() { 19928 mCloseGuard.close(); 19929 if (mClosed.compareAndSet(false, true)) { 19930 synchronized (mPackages) { 19931 if (mWeFroze) { 19932 mFrozenPackages.remove(mPackageName); 19933 } 19934 19935 if (mChildren != null) { 19936 for (PackageFreezer freezer : mChildren) { 19937 freezer.close(); 19938 } 19939 } 19940 } 19941 } 19942 } 19943 } 19944 19945 /** 19946 * Verify that given package is currently frozen. 19947 */ checkPackageFrozen(String packageName)19948 private void checkPackageFrozen(String packageName) { 19949 synchronized (mPackages) { 19950 if (!mFrozenPackages.contains(packageName)) { 19951 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 19952 } 19953 } 19954 } 19955 19956 @Override movePackage(final String packageName, final String volumeUuid)19957 public int movePackage(final String packageName, final String volumeUuid) { 19958 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 19959 19960 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 19961 final int moveId = mNextMoveId.getAndIncrement(); 19962 mHandler.post(new Runnable() { 19963 @Override 19964 public void run() { 19965 try { 19966 movePackageInternal(packageName, volumeUuid, moveId, user); 19967 } catch (PackageManagerException e) { 19968 Slog.w(TAG, "Failed to move " + packageName, e); 19969 mMoveCallbacks.notifyStatusChanged(moveId, 19970 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 19971 } 19972 } 19973 }); 19974 return moveId; 19975 } 19976 movePackageInternal(final String packageName, final String volumeUuid, final int moveId, UserHandle user)19977 private void movePackageInternal(final String packageName, final String volumeUuid, 19978 final int moveId, UserHandle user) throws PackageManagerException { 19979 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19980 final PackageManager pm = mContext.getPackageManager(); 19981 19982 final boolean currentAsec; 19983 final String currentVolumeUuid; 19984 final File codeFile; 19985 final String installerPackageName; 19986 final String packageAbiOverride; 19987 final int appId; 19988 final String seinfo; 19989 final String label; 19990 final int targetSdkVersion; 19991 final PackageFreezer freezer; 19992 final int[] installedUserIds; 19993 19994 // reader 19995 synchronized (mPackages) { 19996 final PackageParser.Package pkg = mPackages.get(packageName); 19997 final PackageSetting ps = mSettings.mPackages.get(packageName); 19998 if (pkg == null || ps == null) { 19999 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 20000 } 20001 20002 if (pkg.applicationInfo.isSystemApp()) { 20003 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 20004 "Cannot move system application"); 20005 } 20006 20007 if (pkg.applicationInfo.isExternalAsec()) { 20008 currentAsec = true; 20009 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 20010 } else if (pkg.applicationInfo.isForwardLocked()) { 20011 currentAsec = true; 20012 currentVolumeUuid = "forward_locked"; 20013 } else { 20014 currentAsec = false; 20015 currentVolumeUuid = ps.volumeUuid; 20016 20017 final File probe = new File(pkg.codePath); 20018 final File probeOat = new File(probe, "oat"); 20019 if (!probe.isDirectory() || !probeOat.isDirectory()) { 20020 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20021 "Move only supported for modern cluster style installs"); 20022 } 20023 } 20024 20025 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 20026 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20027 "Package already moved to " + volumeUuid); 20028 } 20029 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 20030 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 20031 "Device admin cannot be moved"); 20032 } 20033 20034 if (mFrozenPackages.contains(packageName)) { 20035 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 20036 "Failed to move already frozen package"); 20037 } 20038 20039 codeFile = new File(pkg.codePath); 20040 installerPackageName = ps.installerPackageName; 20041 packageAbiOverride = ps.cpuAbiOverrideString; 20042 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 20043 seinfo = pkg.applicationInfo.seinfo; 20044 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 20045 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 20046 freezer = freezePackage(packageName, "movePackageInternal"); 20047 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 20048 } 20049 20050 final Bundle extras = new Bundle(); 20051 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 20052 extras.putString(Intent.EXTRA_TITLE, label); 20053 mMoveCallbacks.notifyCreated(moveId, extras); 20054 20055 int installFlags; 20056 final boolean moveCompleteApp; 20057 final File measurePath; 20058 20059 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 20060 installFlags = INSTALL_INTERNAL; 20061 moveCompleteApp = !currentAsec; 20062 measurePath = Environment.getDataAppDirectory(volumeUuid); 20063 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 20064 installFlags = INSTALL_EXTERNAL; 20065 moveCompleteApp = false; 20066 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 20067 } else { 20068 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 20069 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 20070 || !volume.isMountedWritable()) { 20071 freezer.close(); 20072 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20073 "Move location not mounted private volume"); 20074 } 20075 20076 Preconditions.checkState(!currentAsec); 20077 20078 installFlags = INSTALL_INTERNAL; 20079 moveCompleteApp = true; 20080 measurePath = Environment.getDataAppDirectory(volumeUuid); 20081 } 20082 20083 final PackageStats stats = new PackageStats(null, -1); 20084 synchronized (mInstaller) { 20085 for (int userId : installedUserIds) { 20086 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 20087 freezer.close(); 20088 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20089 "Failed to measure package size"); 20090 } 20091 } 20092 } 20093 20094 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 20095 + stats.dataSize); 20096 20097 final long startFreeBytes = measurePath.getFreeSpace(); 20098 final long sizeBytes; 20099 if (moveCompleteApp) { 20100 sizeBytes = stats.codeSize + stats.dataSize; 20101 } else { 20102 sizeBytes = stats.codeSize; 20103 } 20104 20105 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 20106 freezer.close(); 20107 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20108 "Not enough free space to move"); 20109 } 20110 20111 mMoveCallbacks.notifyStatusChanged(moveId, 10); 20112 20113 final CountDownLatch installedLatch = new CountDownLatch(1); 20114 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 20115 @Override 20116 public void onUserActionRequired(Intent intent) throws RemoteException { 20117 throw new IllegalStateException(); 20118 } 20119 20120 @Override 20121 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 20122 Bundle extras) throws RemoteException { 20123 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 20124 + PackageManager.installStatusToString(returnCode, msg)); 20125 20126 installedLatch.countDown(); 20127 freezer.close(); 20128 20129 final int status = PackageManager.installStatusToPublicStatus(returnCode); 20130 switch (status) { 20131 case PackageInstaller.STATUS_SUCCESS: 20132 mMoveCallbacks.notifyStatusChanged(moveId, 20133 PackageManager.MOVE_SUCCEEDED); 20134 break; 20135 case PackageInstaller.STATUS_FAILURE_STORAGE: 20136 mMoveCallbacks.notifyStatusChanged(moveId, 20137 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 20138 break; 20139 default: 20140 mMoveCallbacks.notifyStatusChanged(moveId, 20141 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20142 break; 20143 } 20144 } 20145 }; 20146 20147 final MoveInfo move; 20148 if (moveCompleteApp) { 20149 // Kick off a thread to report progress estimates 20150 new Thread() { 20151 @Override 20152 public void run() { 20153 while (true) { 20154 try { 20155 if (installedLatch.await(1, TimeUnit.SECONDS)) { 20156 break; 20157 } 20158 } catch (InterruptedException ignored) { 20159 } 20160 20161 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 20162 final int progress = 10 + (int) MathUtils.constrain( 20163 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 20164 mMoveCallbacks.notifyStatusChanged(moveId, progress); 20165 } 20166 } 20167 }.start(); 20168 20169 final String dataAppName = codeFile.getName(); 20170 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 20171 dataAppName, appId, seinfo, targetSdkVersion); 20172 } else { 20173 move = null; 20174 } 20175 20176 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 20177 20178 final Message msg = mHandler.obtainMessage(INIT_COPY); 20179 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 20180 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 20181 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 20182 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/); 20183 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 20184 msg.obj = params; 20185 20186 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 20187 System.identityHashCode(msg.obj)); 20188 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 20189 System.identityHashCode(msg.obj)); 20190 20191 mHandler.sendMessage(msg); 20192 } 20193 20194 @Override movePrimaryStorage(String volumeUuid)20195 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 20196 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20197 20198 final int realMoveId = mNextMoveId.getAndIncrement(); 20199 final Bundle extras = new Bundle(); 20200 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 20201 mMoveCallbacks.notifyCreated(realMoveId, extras); 20202 20203 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 20204 @Override 20205 public void onCreated(int moveId, Bundle extras) { 20206 // Ignored 20207 } 20208 20209 @Override 20210 public void onStatusChanged(int moveId, int status, long estMillis) { 20211 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 20212 } 20213 }; 20214 20215 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20216 storage.setPrimaryStorageUuid(volumeUuid, callback); 20217 return realMoveId; 20218 } 20219 20220 @Override getMoveStatus(int moveId)20221 public int getMoveStatus(int moveId) { 20222 mContext.enforceCallingOrSelfPermission( 20223 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20224 return mMoveCallbacks.mLastStatus.get(moveId); 20225 } 20226 20227 @Override registerMoveCallback(IPackageMoveObserver callback)20228 public void registerMoveCallback(IPackageMoveObserver callback) { 20229 mContext.enforceCallingOrSelfPermission( 20230 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20231 mMoveCallbacks.register(callback); 20232 } 20233 20234 @Override unregisterMoveCallback(IPackageMoveObserver callback)20235 public void unregisterMoveCallback(IPackageMoveObserver callback) { 20236 mContext.enforceCallingOrSelfPermission( 20237 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20238 mMoveCallbacks.unregister(callback); 20239 } 20240 20241 @Override setInstallLocation(int loc)20242 public boolean setInstallLocation(int loc) { 20243 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 20244 null); 20245 if (getInstallLocation() == loc) { 20246 return true; 20247 } 20248 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 20249 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 20250 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 20251 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 20252 return true; 20253 } 20254 return false; 20255 } 20256 20257 @Override getInstallLocation()20258 public int getInstallLocation() { 20259 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 20260 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 20261 PackageHelper.APP_INSTALL_AUTO); 20262 } 20263 20264 /** Called by UserManagerService */ cleanUpUser(UserManagerService userManager, int userHandle)20265 void cleanUpUser(UserManagerService userManager, int userHandle) { 20266 synchronized (mPackages) { 20267 mDirtyUsers.remove(userHandle); 20268 mUserNeedsBadging.delete(userHandle); 20269 mSettings.removeUserLPw(userHandle); 20270 mPendingBroadcasts.remove(userHandle); 20271 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 20272 removeUnusedPackagesLPw(userManager, userHandle); 20273 } 20274 } 20275 20276 /** 20277 * We're removing userHandle and would like to remove any downloaded packages 20278 * that are no longer in use by any other user. 20279 * @param userHandle the user being removed 20280 */ removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle)20281 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 20282 final boolean DEBUG_CLEAN_APKS = false; 20283 int [] users = userManager.getUserIds(); 20284 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 20285 while (psit.hasNext()) { 20286 PackageSetting ps = psit.next(); 20287 if (ps.pkg == null) { 20288 continue; 20289 } 20290 final String packageName = ps.pkg.packageName; 20291 // Skip over if system app 20292 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 20293 continue; 20294 } 20295 if (DEBUG_CLEAN_APKS) { 20296 Slog.i(TAG, "Checking package " + packageName); 20297 } 20298 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 20299 if (keep) { 20300 if (DEBUG_CLEAN_APKS) { 20301 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 20302 } 20303 } else { 20304 for (int i = 0; i < users.length; i++) { 20305 if (users[i] != userHandle && ps.getInstalled(users[i])) { 20306 keep = true; 20307 if (DEBUG_CLEAN_APKS) { 20308 Slog.i(TAG, " Keeping package " + packageName + " for user " 20309 + users[i]); 20310 } 20311 break; 20312 } 20313 } 20314 } 20315 if (!keep) { 20316 if (DEBUG_CLEAN_APKS) { 20317 Slog.i(TAG, " Removing package " + packageName); 20318 } 20319 mHandler.post(new Runnable() { 20320 public void run() { 20321 deletePackageX(packageName, userHandle, 0); 20322 } //end run 20323 }); 20324 } 20325 } 20326 } 20327 20328 /** Called by UserManagerService */ createNewUser(int userId)20329 void createNewUser(int userId) { 20330 synchronized (mInstallLock) { 20331 mSettings.createNewUserLI(this, mInstaller, userId); 20332 } 20333 synchronized (mPackages) { 20334 scheduleWritePackageRestrictionsLocked(userId); 20335 scheduleWritePackageListLocked(userId); 20336 applyFactoryDefaultBrowserLPw(userId); 20337 primeDomainVerificationsLPw(userId); 20338 } 20339 } 20340 onNewUserCreated(final int userId)20341 void onNewUserCreated(final int userId) { 20342 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 20343 // If permission review for legacy apps is required, we represent 20344 // dagerous permissions for such apps as always granted runtime 20345 // permissions to keep per user flag state whether review is needed. 20346 // Hence, if a new user is added we have to propagate dangerous 20347 // permission grants for these legacy apps. 20348 if (Build.PERMISSIONS_REVIEW_REQUIRED) { 20349 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 20350 | UPDATE_PERMISSIONS_REPLACE_ALL); 20351 } 20352 } 20353 20354 @Override getVerifierDeviceIdentity()20355 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 20356 mContext.enforceCallingOrSelfPermission( 20357 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 20358 "Only package verification agents can read the verifier device identity"); 20359 20360 synchronized (mPackages) { 20361 return mSettings.getVerifierDeviceIdentityLPw(); 20362 } 20363 } 20364 20365 @Override setPermissionEnforced(String permission, boolean enforced)20366 public void setPermissionEnforced(String permission, boolean enforced) { 20367 // TODO: Now that we no longer change GID for storage, this should to away. 20368 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 20369 "setPermissionEnforced"); 20370 if (READ_EXTERNAL_STORAGE.equals(permission)) { 20371 synchronized (mPackages) { 20372 if (mSettings.mReadExternalStorageEnforced == null 20373 || mSettings.mReadExternalStorageEnforced != enforced) { 20374 mSettings.mReadExternalStorageEnforced = enforced; 20375 mSettings.writeLPr(); 20376 } 20377 } 20378 // kill any non-foreground processes so we restart them and 20379 // grant/revoke the GID. 20380 final IActivityManager am = ActivityManagerNative.getDefault(); 20381 if (am != null) { 20382 final long token = Binder.clearCallingIdentity(); 20383 try { 20384 am.killProcessesBelowForeground("setPermissionEnforcement"); 20385 } catch (RemoteException e) { 20386 } finally { 20387 Binder.restoreCallingIdentity(token); 20388 } 20389 } 20390 } else { 20391 throw new IllegalArgumentException("No selective enforcement for " + permission); 20392 } 20393 } 20394 20395 @Override 20396 @Deprecated isPermissionEnforced(String permission)20397 public boolean isPermissionEnforced(String permission) { 20398 return true; 20399 } 20400 20401 @Override isStorageLow()20402 public boolean isStorageLow() { 20403 final long token = Binder.clearCallingIdentity(); 20404 try { 20405 final DeviceStorageMonitorInternal 20406 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 20407 if (dsm != null) { 20408 return dsm.isMemoryLow(); 20409 } else { 20410 return false; 20411 } 20412 } finally { 20413 Binder.restoreCallingIdentity(token); 20414 } 20415 } 20416 20417 @Override getPackageInstaller()20418 public IPackageInstaller getPackageInstaller() { 20419 return mInstallerService; 20420 } 20421 userNeedsBadging(int userId)20422 private boolean userNeedsBadging(int userId) { 20423 int index = mUserNeedsBadging.indexOfKey(userId); 20424 if (index < 0) { 20425 final UserInfo userInfo; 20426 final long token = Binder.clearCallingIdentity(); 20427 try { 20428 userInfo = sUserManager.getUserInfo(userId); 20429 } finally { 20430 Binder.restoreCallingIdentity(token); 20431 } 20432 final boolean b; 20433 if (userInfo != null && userInfo.isManagedProfile()) { 20434 b = true; 20435 } else { 20436 b = false; 20437 } 20438 mUserNeedsBadging.put(userId, b); 20439 return b; 20440 } 20441 return mUserNeedsBadging.valueAt(index); 20442 } 20443 20444 @Override getKeySetByAlias(String packageName, String alias)20445 public KeySet getKeySetByAlias(String packageName, String alias) { 20446 if (packageName == null || alias == null) { 20447 return null; 20448 } 20449 synchronized(mPackages) { 20450 final PackageParser.Package pkg = mPackages.get(packageName); 20451 if (pkg == null) { 20452 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20453 throw new IllegalArgumentException("Unknown package: " + packageName); 20454 } 20455 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20456 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 20457 } 20458 } 20459 20460 @Override getSigningKeySet(String packageName)20461 public KeySet getSigningKeySet(String packageName) { 20462 if (packageName == null) { 20463 return null; 20464 } 20465 synchronized(mPackages) { 20466 final PackageParser.Package pkg = mPackages.get(packageName); 20467 if (pkg == null) { 20468 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20469 throw new IllegalArgumentException("Unknown package: " + packageName); 20470 } 20471 if (pkg.applicationInfo.uid != Binder.getCallingUid() 20472 && Process.SYSTEM_UID != Binder.getCallingUid()) { 20473 throw new SecurityException("May not access signing KeySet of other apps."); 20474 } 20475 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20476 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 20477 } 20478 } 20479 20480 @Override isPackageSignedByKeySet(String packageName, KeySet ks)20481 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 20482 if (packageName == null || ks == null) { 20483 return false; 20484 } 20485 synchronized(mPackages) { 20486 final PackageParser.Package pkg = mPackages.get(packageName); 20487 if (pkg == null) { 20488 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20489 throw new IllegalArgumentException("Unknown package: " + packageName); 20490 } 20491 IBinder ksh = ks.getToken(); 20492 if (ksh instanceof KeySetHandle) { 20493 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20494 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 20495 } 20496 return false; 20497 } 20498 } 20499 20500 @Override isPackageSignedByKeySetExactly(String packageName, KeySet ks)20501 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 20502 if (packageName == null || ks == null) { 20503 return false; 20504 } 20505 synchronized(mPackages) { 20506 final PackageParser.Package pkg = mPackages.get(packageName); 20507 if (pkg == null) { 20508 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20509 throw new IllegalArgumentException("Unknown package: " + packageName); 20510 } 20511 IBinder ksh = ks.getToken(); 20512 if (ksh instanceof KeySetHandle) { 20513 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20514 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 20515 } 20516 return false; 20517 } 20518 } 20519 deletePackageIfUnusedLPr(final String packageName)20520 private void deletePackageIfUnusedLPr(final String packageName) { 20521 PackageSetting ps = mSettings.mPackages.get(packageName); 20522 if (ps == null) { 20523 return; 20524 } 20525 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 20526 // TODO Implement atomic delete if package is unused 20527 // It is currently possible that the package will be deleted even if it is installed 20528 // after this method returns. 20529 mHandler.post(new Runnable() { 20530 public void run() { 20531 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 20532 } 20533 }); 20534 } 20535 } 20536 20537 /** 20538 * Check and throw if the given before/after packages would be considered a 20539 * downgrade. 20540 */ checkDowngrade(PackageParser.Package before, PackageInfoLite after)20541 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 20542 throws PackageManagerException { 20543 if (after.versionCode < before.mVersionCode) { 20544 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20545 "Update version code " + after.versionCode + " is older than current " 20546 + before.mVersionCode); 20547 } else if (after.versionCode == before.mVersionCode) { 20548 if (after.baseRevisionCode < before.baseRevisionCode) { 20549 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20550 "Update base revision code " + after.baseRevisionCode 20551 + " is older than current " + before.baseRevisionCode); 20552 } 20553 20554 if (!ArrayUtils.isEmpty(after.splitNames)) { 20555 for (int i = 0; i < after.splitNames.length; i++) { 20556 final String splitName = after.splitNames[i]; 20557 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 20558 if (j != -1) { 20559 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 20560 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20561 "Update split " + splitName + " revision code " 20562 + after.splitRevisionCodes[i] + " is older than current " 20563 + before.splitRevisionCodes[j]); 20564 } 20565 } 20566 } 20567 } 20568 } 20569 } 20570 20571 private static class MoveCallbacks extends Handler { 20572 private static final int MSG_CREATED = 1; 20573 private static final int MSG_STATUS_CHANGED = 2; 20574 20575 private final RemoteCallbackList<IPackageMoveObserver> 20576 mCallbacks = new RemoteCallbackList<>(); 20577 20578 private final SparseIntArray mLastStatus = new SparseIntArray(); 20579 MoveCallbacks(Looper looper)20580 public MoveCallbacks(Looper looper) { 20581 super(looper); 20582 } 20583 register(IPackageMoveObserver callback)20584 public void register(IPackageMoveObserver callback) { 20585 mCallbacks.register(callback); 20586 } 20587 unregister(IPackageMoveObserver callback)20588 public void unregister(IPackageMoveObserver callback) { 20589 mCallbacks.unregister(callback); 20590 } 20591 20592 @Override handleMessage(Message msg)20593 public void handleMessage(Message msg) { 20594 final SomeArgs args = (SomeArgs) msg.obj; 20595 final int n = mCallbacks.beginBroadcast(); 20596 for (int i = 0; i < n; i++) { 20597 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 20598 try { 20599 invokeCallback(callback, msg.what, args); 20600 } catch (RemoteException ignored) { 20601 } 20602 } 20603 mCallbacks.finishBroadcast(); 20604 args.recycle(); 20605 } 20606 invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)20607 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 20608 throws RemoteException { 20609 switch (what) { 20610 case MSG_CREATED: { 20611 callback.onCreated(args.argi1, (Bundle) args.arg2); 20612 break; 20613 } 20614 case MSG_STATUS_CHANGED: { 20615 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 20616 break; 20617 } 20618 } 20619 } 20620 notifyCreated(int moveId, Bundle extras)20621 private void notifyCreated(int moveId, Bundle extras) { 20622 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 20623 20624 final SomeArgs args = SomeArgs.obtain(); 20625 args.argi1 = moveId; 20626 args.arg2 = extras; 20627 obtainMessage(MSG_CREATED, args).sendToTarget(); 20628 } 20629 notifyStatusChanged(int moveId, int status)20630 private void notifyStatusChanged(int moveId, int status) { 20631 notifyStatusChanged(moveId, status, -1); 20632 } 20633 notifyStatusChanged(int moveId, int status, long estMillis)20634 private void notifyStatusChanged(int moveId, int status, long estMillis) { 20635 Slog.v(TAG, "Move " + moveId + " status " + status); 20636 20637 final SomeArgs args = SomeArgs.obtain(); 20638 args.argi1 = moveId; 20639 args.argi2 = status; 20640 args.arg3 = estMillis; 20641 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 20642 20643 synchronized (mLastStatus) { 20644 mLastStatus.put(moveId, status); 20645 } 20646 } 20647 } 20648 20649 private final static class OnPermissionChangeListeners extends Handler { 20650 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 20651 20652 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 20653 new RemoteCallbackList<>(); 20654 OnPermissionChangeListeners(Looper looper)20655 public OnPermissionChangeListeners(Looper looper) { 20656 super(looper); 20657 } 20658 20659 @Override handleMessage(Message msg)20660 public void handleMessage(Message msg) { 20661 switch (msg.what) { 20662 case MSG_ON_PERMISSIONS_CHANGED: { 20663 final int uid = msg.arg1; 20664 handleOnPermissionsChanged(uid); 20665 } break; 20666 } 20667 } 20668 addListenerLocked(IOnPermissionsChangeListener listener)20669 public void addListenerLocked(IOnPermissionsChangeListener listener) { 20670 mPermissionListeners.register(listener); 20671 20672 } 20673 removeListenerLocked(IOnPermissionsChangeListener listener)20674 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 20675 mPermissionListeners.unregister(listener); 20676 } 20677 onPermissionsChanged(int uid)20678 public void onPermissionsChanged(int uid) { 20679 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 20680 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 20681 } 20682 } 20683 handleOnPermissionsChanged(int uid)20684 private void handleOnPermissionsChanged(int uid) { 20685 final int count = mPermissionListeners.beginBroadcast(); 20686 try { 20687 for (int i = 0; i < count; i++) { 20688 IOnPermissionsChangeListener callback = mPermissionListeners 20689 .getBroadcastItem(i); 20690 try { 20691 callback.onPermissionsChanged(uid); 20692 } catch (RemoteException e) { 20693 Log.e(TAG, "Permission listener is dead", e); 20694 } 20695 } 20696 } finally { 20697 mPermissionListeners.finishBroadcast(); 20698 } 20699 } 20700 } 20701 20702 private class PackageManagerInternalImpl extends PackageManagerInternal { 20703 @Override setLocationPackagesProvider(PackagesProvider provider)20704 public void setLocationPackagesProvider(PackagesProvider provider) { 20705 synchronized (mPackages) { 20706 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 20707 } 20708 } 20709 20710 @Override setVoiceInteractionPackagesProvider(PackagesProvider provider)20711 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 20712 synchronized (mPackages) { 20713 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 20714 } 20715 } 20716 20717 @Override setSmsAppPackagesProvider(PackagesProvider provider)20718 public void setSmsAppPackagesProvider(PackagesProvider provider) { 20719 synchronized (mPackages) { 20720 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 20721 } 20722 } 20723 20724 @Override setDialerAppPackagesProvider(PackagesProvider provider)20725 public void setDialerAppPackagesProvider(PackagesProvider provider) { 20726 synchronized (mPackages) { 20727 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 20728 } 20729 } 20730 20731 @Override setSimCallManagerPackagesProvider(PackagesProvider provider)20732 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 20733 synchronized (mPackages) { 20734 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 20735 } 20736 } 20737 20738 @Override setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider)20739 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 20740 synchronized (mPackages) { 20741 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 20742 } 20743 } 20744 20745 @Override grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId)20746 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 20747 synchronized (mPackages) { 20748 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 20749 packageName, userId); 20750 } 20751 } 20752 20753 @Override grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId)20754 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 20755 synchronized (mPackages) { 20756 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 20757 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 20758 packageName, userId); 20759 } 20760 } 20761 20762 @Override grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId)20763 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 20764 synchronized (mPackages) { 20765 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 20766 packageName, userId); 20767 } 20768 } 20769 20770 @Override setKeepUninstalledPackages(final List<String> packageList)20771 public void setKeepUninstalledPackages(final List<String> packageList) { 20772 Preconditions.checkNotNull(packageList); 20773 List<String> removedFromList = null; 20774 synchronized (mPackages) { 20775 if (mKeepUninstalledPackages != null) { 20776 final int packagesCount = mKeepUninstalledPackages.size(); 20777 for (int i = 0; i < packagesCount; i++) { 20778 String oldPackage = mKeepUninstalledPackages.get(i); 20779 if (packageList != null && packageList.contains(oldPackage)) { 20780 continue; 20781 } 20782 if (removedFromList == null) { 20783 removedFromList = new ArrayList<>(); 20784 } 20785 removedFromList.add(oldPackage); 20786 } 20787 } 20788 mKeepUninstalledPackages = new ArrayList<>(packageList); 20789 if (removedFromList != null) { 20790 final int removedCount = removedFromList.size(); 20791 for (int i = 0; i < removedCount; i++) { 20792 deletePackageIfUnusedLPr(removedFromList.get(i)); 20793 } 20794 } 20795 } 20796 } 20797 20798 @Override isPermissionsReviewRequired(String packageName, int userId)20799 public boolean isPermissionsReviewRequired(String packageName, int userId) { 20800 synchronized (mPackages) { 20801 // If we do not support permission review, done. 20802 if (!Build.PERMISSIONS_REVIEW_REQUIRED) { 20803 return false; 20804 } 20805 20806 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 20807 if (packageSetting == null) { 20808 return false; 20809 } 20810 20811 // Permission review applies only to apps not supporting the new permission model. 20812 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 20813 return false; 20814 } 20815 20816 // Legacy apps have the permission and get user consent on launch. 20817 PermissionsState permissionsState = packageSetting.getPermissionsState(); 20818 return permissionsState.isPermissionReviewRequired(userId); 20819 } 20820 } 20821 20822 @Override getApplicationInfo(String packageName, int userId)20823 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 20824 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 20825 } 20826 20827 @Override getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, int userId)20828 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 20829 int userId) { 20830 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 20831 } 20832 20833 @Override setDeviceAndProfileOwnerPackages( int deviceOwnerUserId, String deviceOwnerPackage, SparseArray<String> profileOwnerPackages)20834 public void setDeviceAndProfileOwnerPackages( 20835 int deviceOwnerUserId, String deviceOwnerPackage, 20836 SparseArray<String> profileOwnerPackages) { 20837 mProtectedPackages.setDeviceAndProfileOwnerPackages( 20838 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 20839 } 20840 20841 @Override isPackageDataProtected(int userId, String packageName)20842 public boolean isPackageDataProtected(int userId, String packageName) { 20843 return mProtectedPackages.isPackageDataProtected(userId, packageName); 20844 } 20845 } 20846 20847 @Override grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId)20848 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 20849 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 20850 synchronized (mPackages) { 20851 final long identity = Binder.clearCallingIdentity(); 20852 try { 20853 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 20854 packageNames, userId); 20855 } finally { 20856 Binder.restoreCallingIdentity(identity); 20857 } 20858 } 20859 } 20860 enforceSystemOrPhoneCaller(String tag)20861 private static void enforceSystemOrPhoneCaller(String tag) { 20862 int callingUid = Binder.getCallingUid(); 20863 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 20864 throw new SecurityException( 20865 "Cannot call " + tag + " from UID " + callingUid); 20866 } 20867 } 20868 isHistoricalPackageUsageAvailable()20869 boolean isHistoricalPackageUsageAvailable() { 20870 return mPackageUsage.isHistoricalPackageUsageAvailable(); 20871 } 20872 20873 /** 20874 * Return a <b>copy</b> of the collection of packages known to the package manager. 20875 * @return A copy of the values of mPackages. 20876 */ getPackages()20877 Collection<PackageParser.Package> getPackages() { 20878 synchronized (mPackages) { 20879 return new ArrayList<>(mPackages.values()); 20880 } 20881 } 20882 20883 /** 20884 * Logs process start information (including base APK hash) to the security log. 20885 * @hide 20886 */ logAppProcessStartIfNeeded(String processName, int uid, String seinfo, String apkFile, int pid)20887 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 20888 String apkFile, int pid) { 20889 if (!SecurityLog.isLoggingEnabled()) { 20890 return; 20891 } 20892 Bundle data = new Bundle(); 20893 data.putLong("startTimestamp", System.currentTimeMillis()); 20894 data.putString("processName", processName); 20895 data.putInt("uid", uid); 20896 data.putString("seinfo", seinfo); 20897 data.putString("apkFile", apkFile); 20898 data.putInt("pid", pid); 20899 Message msg = mProcessLoggingHandler.obtainMessage( 20900 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 20901 msg.setData(data); 20902 mProcessLoggingHandler.sendMessage(msg); 20903 } 20904 getCompilerPackageStats(String pkgName)20905 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 20906 return mCompilerStats.getPackageStats(pkgName); 20907 } 20908 getOrCreateCompilerPackageStats(PackageParser.Package pkg)20909 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 20910 return getOrCreateCompilerPackageStats(pkg.packageName); 20911 } 20912 getOrCreateCompilerPackageStats(String pkgName)20913 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 20914 return mCompilerStats.getOrCreatePackageStats(pkgName); 20915 } 20916 deleteCompilerPackageStats(String pkgName)20917 public void deleteCompilerPackageStats(String pkgName) { 20918 mCompilerStats.deletePackageStats(pkgName); 20919 } 20920 } 20921