Index: src/wp-admin/includes/class-wp-upgrader.php
===================================================================
--- src/wp-admin/includes/class-wp-upgrader.php	(revision 29678)
+++ src/wp-admin/includes/class-wp-upgrader.php	(working copy)
@@ -1196,20 +1196,48 @@
 
 	public static function async_upgrade( $upgrader = false ) {
 		// Avoid recursion.
-		if ( $upgrader && $upgrader instanceof Language_Pack_Upgrader )
+		if ( $upgrader && $upgrader instanceof Language_Pack_Upgrader ) {
 			return;
+		}
 
 		// Nothing to do?
 		$language_updates = wp_get_translation_updates();
-		if ( ! $language_updates )
+		if ( ! $language_updates ) {
 			return;
+		}
 
+		foreach ( $language_updates as $key => $language_update ) {
+			$type = $language_update->type;
+			$update = ! empty( $language_update->autoupdate );
+
+			/**
+			 * Filter whether to asynchronously update translation of core, a plugin, or a theme.
+			 *
+			 * The dynamic portion of the hook name, $type, refers to the type of update
+			 * being checked. Can be 'core', 'theme', or 'plugin'.
+			 *
+			 * @since 4.0.0
+			 *
+			 * @param bool   $update          Whether to update.
+			 * @param object $language_update The update offer.
+			 */
+			$update = apply_filters( 'async_update_' . $type, $update, $language_update );
+
+			if ( ! $update ) {
+				unset( $language_updates[ $key ] );
+			}
+		}
+
+		if ( empty( $language_updates ) ) {
+			return;
+		}
+
 		$skin = new Language_Pack_Upgrader_Skin( array(
 			'skip_header_footer' => true,
 		) );
 
 		$lp_upgrader = new Language_Pack_Upgrader( $skin );
-		$lp_upgrader->upgrade();
+		$lp_upgrader->bulk_upgrade( $language_updates );
 	}
 
 	public function upgrade_strings() {
@@ -1264,6 +1292,9 @@
 		if ( 'upgrader_process_complete' == current_filter() )
 			$this->skin->feedback( 'starting_upgrade' );
 
+		// Remove any existing pre-install filters, like from plugin upgrader, #WP29425.
+		remove_all_filters( 'upgrader_pre_install' );
+
 		// Remove any existing package checks and then set the new one for translations, #WP29230.
 		remove_all_filters( 'upgrader_source_selection' );
 		add_filter( 'upgrader_source_selection', array( $this, 'check_package' ), 10, 2 );
