diff --git a/DEPS b/DEPS index 5c3929e..0d76b9c 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'e94871bf8308b72ed44353956f1ff6c4ba6e7597', + 'skia_revision': '5b071782585024bd75a203f3cde0429bfb7ec99d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'f914089eae2ea692c6ae29d1ee4d1fe8aea59629', + 'v8_revision': '2a4a00d524586b4dcbd4984c8de24ab57d40203d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -64,7 +64,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'b0860beccd6a4a8d9f8ea3dbba392a3a13218ad3', + 'pdfium_revision': '827f6ff220edea40252e52d128662d37a591fdb9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -166,7 +166,7 @@ Var('chromium_git') + '/external/leveldb.git' + '@' + '09a3c8e7417547829b94bcdaa62cdf9e896f29a9', 'src/third_party/snappy/src': - Var('chromium_git') + '/external/github.com/google/snappy.git' + '@' + '77c12adc192ac6620a0f0d340c99149ec56a97a3', + Var('chromium_git') + '/external/github.com/google/snappy.git' + '@' + 'b02bfa754ebf27921d8da3bd2517eab445b84ff9', 'src/tools/gyp': Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb', @@ -208,7 +208,7 @@ Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd', 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + '6b9c691dafc884424e05b5294b6e0e4996d533a5', + Var('chromium_git') + '/webm/libvpx.git' + '@' + '30c261b1ebe8f06d687cac5b3b442d51a7839d00', 'src/third_party/ffmpeg': Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'dbbdb1680bd8e77ea72f8e5a79a09101bd7a9bdd',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 11f96396c..0118129 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -349,6 +349,8 @@ "system/bluetooth/bluetooth_notification_controller.cc", "system/bluetooth/bluetooth_notification_controller.h", "system/bluetooth/bluetooth_observer.h", + "system/bluetooth/bluetooth_power_controller.cc", + "system/bluetooth/bluetooth_power_controller.h", "system/bluetooth/tray_bluetooth.cc", "system/bluetooth/tray_bluetooth.h", "system/bluetooth/tray_bluetooth_helper.cc", @@ -1199,6 +1201,7 @@ "sticky_keys/sticky_keys_overlay_unittest.cc", "sticky_keys/sticky_keys_unittest.cc", "system/audio/tray_audio_unittest.cc", + "system/bluetooth/bluetooth_power_controller_unittest.cc", "system/bluetooth/tray_bluetooth_helper_unittest.cc", "system/brightness/tray_brightness_unittest.cc", "system/date/date_view_unittest.cc",
diff --git a/ash/display/display_configuration_controller.cc b/ash/display/display_configuration_controller.cc index 0fdee48..ae55f50 100644 --- a/ash/display/display_configuration_controller.cc +++ b/ash/display/display_configuration_controller.cc
@@ -110,13 +110,14 @@ void DisplayConfigurationController::SetDisplayRotation( int64_t display_id, display::Display::Rotation rotation, - display::Display::RotationSource source) { + display::Display::RotationSource source, + DisplayConfigurationController::RotationAnimation mode) { if (display_manager_->IsDisplayIdValid(display_id)) { if (GetTargetRotation(display_id) == rotation) return; ScreenRotationAnimator* screen_rotation_animator = GetScreenRotationAnimatorForDisplay(display_id); - screen_rotation_animator->Rotate(rotation, source); + screen_rotation_animator->Rotate(rotation, source, mode); } else { display_manager_->SetDisplayRotation(display_id, rotation, source); }
diff --git a/ash/display/display_configuration_controller.h b/ash/display/display_configuration_controller.h index e17f140a4..f2e194b 100644 --- a/ash/display/display_configuration_controller.h +++ b/ash/display/display_configuration_controller.h
@@ -31,6 +31,15 @@ class ASH_EXPORT DisplayConfigurationController : public WindowTreeHostManager::Observer { public: + // Use SYNC if it is important to rotate immediately after the + // |SetDisplayRotation()|. As a side effect, the animation is less smooth. + // ASYNC is actually slower because it takes longer to rotate the screen after + // a screenshot is taken. http://crbug.com/757851. + enum RotationAnimation { + ANIMATION_SYNC = 0, + ANIMATION_ASYNC, + }; + DisplayConfigurationController( display::DisplayManager* display_manager, WindowTreeHostManager* window_tree_host_manager); @@ -48,7 +57,8 @@ // Sets the display's rotation with animation if available. void SetDisplayRotation(int64_t display_id, display::Display::Rotation rotation, - display::Display::RotationSource source); + display::Display::RotationSource source, + RotationAnimation mode = ANIMATION_ASYNC); // Returns the rotation of the display given by |display_id|. This returns // the target rotation when the display is being rotated.
diff --git a/ash/display/display_configuration_controller_unittest.cc b/ash/display/display_configuration_controller_unittest.cc index b491db751..a7d04d75 100644 --- a/ash/display/display_configuration_controller_unittest.cc +++ b/ash/display/display_configuration_controller_unittest.cc
@@ -59,17 +59,31 @@ display.id(), display::Display::ROTATE_0, display::Display::RotationSource::ROTATION_SOURCE_USER); old_screen_rotation_animator->Rotate( - display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATE_90, display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); ScreenRotationAnimator* new_screen_rotation_animator = testapi.GetScreenRotationAnimatorForDisplay(display.id()); new_screen_rotation_animator->Rotate( - display::Display::ROTATE_180, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATE_180, display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_EQ(old_screen_rotation_animator, new_screen_rotation_animator); } +TEST_F(DisplayConfigurationControllerTest, GetTargetRotationWithAnimation) { + display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); + DisplayConfigurationController* controller = + Shell::Get()->display_configuration_controller(); + DisplayConfigurationControllerTestApi testapi(controller); + controller->SetDisplayRotation( + display.id(), display::Display::ROTATE_180, + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); + EXPECT_EQ(display::Display::ROTATE_180, + controller->GetTargetRotation(display.id())); + EXPECT_EQ(display::Display::ROTATE_180, GetDisplayRotation(display.id())); +} + TEST_F(DisplayConfigurationControllerSmoothRotationTest, GetTargetRotationWithAnimation) { display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); @@ -78,7 +92,8 @@ DisplayConfigurationControllerTestApi testapi(controller); controller->SetDisplayRotation( display.id(), display::Display::ROTATE_180, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); EXPECT_EQ(display::Display::ROTATE_180, controller->GetTargetRotation(display.id())); EXPECT_EQ(display::Display::ROTATE_0, GetDisplayRotation(display.id()));
diff --git a/ash/display/screen_orientation_controller_chromeos.cc b/ash/display/screen_orientation_controller_chromeos.cc index 4c1e217..27e54f9 100644 --- a/ash/display/screen_orientation_controller_chromeos.cc +++ b/ash/display/screen_orientation_controller_chromeos.cc
@@ -5,7 +5,6 @@ #include "ash/display/screen_orientation_controller_chromeos.h" #include "ash/ash_switches.h" -#include "ash/display/display_configuration_controller.h" #include "ash/public/cpp/app_types.h" #include "ash/shell.h" #include "ash/wm/mru_window_tracker.h" @@ -212,7 +211,8 @@ SetRotationLockedInternal(false); if (user_rotation_ != current_rotation_) { SetDisplayRotation(user_rotation_, - display::Display::ROTATION_SOURCE_ACCELEROMETER); + display::Display::ROTATION_SOURCE_ACCELEROMETER, + DisplayConfigurationController::ANIMATION_SYNC); } } @@ -343,9 +343,11 @@ Shell::Get()->window_tree_host_manager()->RemoveObserver(this); if (!display::Display::HasInternalDisplay()) return; + if (current_rotation_ != user_rotation_) { SetDisplayRotation(user_rotation_, - display::Display::ROTATION_SOURCE_ACCELEROMETER); + display::Display::ROTATION_SOURCE_ACCELEROMETER, + DisplayConfigurationController::ANIMATION_SYNC); } for (auto& observer : observers_) observer.OnUserRotationLockChanged(); @@ -353,7 +355,8 @@ void ScreenOrientationController::SetDisplayRotation( display::Display::Rotation rotation, - display::Display::RotationSource source) { + display::Display::RotationSource source, + DisplayConfigurationController::RotationAnimation mode) { if (!display::Display::HasInternalDisplay()) return; current_rotation_ = rotation; @@ -361,7 +364,7 @@ &ignore_display_configuration_updates_, true); Shell::Get()->display_configuration_controller()->SetDisplayRotation( - display::Display::InternalDisplayId(), rotation, source); + display::Display::InternalDisplayId(), rotation, source, mode); } void ScreenOrientationController::SetRotationLockedInternal(
diff --git a/ash/display/screen_orientation_controller_chromeos.h b/ash/display/screen_orientation_controller_chromeos.h index df0387ce..98ef0ff 100644 --- a/ash/display/screen_orientation_controller_chromeos.h +++ b/ash/display/screen_orientation_controller_chromeos.h
@@ -8,6 +8,7 @@ #include <unordered_map> #include "ash/ash_export.h" +#include "ash/display/display_configuration_controller.h" #include "ash/display/window_tree_host_manager.h" #include "ash/wm/tablet_mode/tablet_mode_observer.h" #include "base/macros.h" @@ -141,8 +142,11 @@ // Sets the display rotation for the given |source|. The new |rotation| will // also become active. Display changed notifications are suppressed for this // change. - void SetDisplayRotation(display::Display::Rotation rotation, - display::Display::RotationSource source); + void SetDisplayRotation( + display::Display::Rotation rotation, + display::Display::RotationSource source, + DisplayConfigurationController::RotationAnimation mode = + DisplayConfigurationController::ANIMATION_ASYNC); void SetRotationLockedInternal(bool rotation_locked);
diff --git a/ash/public/cpp/ash_pref_names.cc b/ash/public/cpp/ash_pref_names.cc index 9f09a3a..5364a2c 100644 --- a/ash/public/cpp/ash_pref_names.cc +++ b/ash/public/cpp/ash_pref_names.cc
@@ -129,6 +129,14 @@ // A dictionary pref that maps wallpaper file paths to their prominent colors. const char kWallpaperColors[] = "ash.wallpaper.prominent_colors"; +// Boolean pref indicating whether a user has enabled the bluetooth adapter. +const char kUserBluetoothAdapterEnabled[] = + "ash.user.bluetooth.adapter_enabled"; + +// Boolean pref indicating system-wide setting for bluetooth adapter power. +const char kSystemBluetoothAdapterEnabled[] = + "ash.system.bluetooth.adapter_enabled"; + // NOTE: New prefs should start with the "ash." prefix. Existing prefs moved // into this file should not be renamed, since they may be synced.
diff --git a/ash/public/cpp/ash_pref_names.h b/ash/public/cpp/ash_pref_names.h index 8135d5ba..4137014 100644 --- a/ash/public/cpp/ash_pref_names.h +++ b/ash/public/cpp/ash_pref_names.h
@@ -50,6 +50,9 @@ ASH_PUBLIC_EXPORT extern const char kWallpaperColors[]; +ASH_PUBLIC_EXPORT extern const char kUserBluetoothAdapterEnabled[]; +ASH_PUBLIC_EXPORT extern const char kSystemBluetoothAdapterEnabled[]; + } // namespace prefs } // namespace ash
diff --git a/ash/public/interfaces/user_info.mojom b/ash/public/interfaces/user_info.mojom index 6fba255..5a86856 100644 --- a/ash/public/interfaces/user_info.mojom +++ b/ash/public/interfaces/user_info.mojom
@@ -44,4 +44,7 @@ string display_name; string display_email; gfx.mojom.ImageSkia avatar; -}; \ No newline at end of file + // True if this user has a newly created profile (first time login on the + // device) + bool is_new_profile; +};
diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc index 84caa96..326648c 100644 --- a/ash/rotator/screen_rotation_animator.cc +++ b/ash/rotator/screen_rotation_animator.cc
@@ -163,6 +163,7 @@ metrics_reporter_( base::MakeUnique<ScreenRotationAnimationMetricsReporter>()), disable_animation_timers_for_test_(false), + // TODO(wutao): remove the flag. http://crbug.com/707800. has_switch_ash_disable_smooth_screen_rotation_( base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kAshDisableSmoothScreenRotation) && @@ -194,7 +195,9 @@ } rotation_request->old_rotation = current_rotation; - if (has_switch_ash_disable_smooth_screen_rotation_) { + if (has_switch_ash_disable_smooth_screen_rotation_ || + DisplayConfigurationController::ANIMATION_SYNC == + rotation_request->mode) { StartSlowAnimation(std::move(rotation_request)); } else { std::unique_ptr<viz::CopyOutputRequest> copy_output_request = @@ -433,8 +436,10 @@ observer->SetActive(); } -void ScreenRotationAnimator::Rotate(display::Display::Rotation new_rotation, - display::Display::RotationSource source) { +void ScreenRotationAnimator::Rotate( + display::Display::Rotation new_rotation, + display::Display::RotationSource source, + DisplayConfigurationController::RotationAnimation mode) { // |rotation_request_id_| is used to skip stale requests. Before the layer // CopyOutputResult callback called, there could have new rotation request. // Increases |rotation_request_id_| for each new request and in the callback, @@ -445,7 +450,7 @@ display::Screen::GetScreen()->GetDisplayNearestWindow(root_window_).id(); std::unique_ptr<ScreenRotationRequest> rotation_request = base::MakeUnique<ScreenRotationRequest>(rotation_request_id_, display_id, - new_rotation, source); + new_rotation, source, mode); target_rotation_ = new_rotation; switch (screen_rotation_state_) { case IDLE:
diff --git a/ash/rotator/screen_rotation_animator.h b/ash/rotator/screen_rotation_animator.h index 06b0e53f..c7f4dcec 100644 --- a/ash/rotator/screen_rotation_animator.h +++ b/ash/rotator/screen_rotation_animator.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include "ash/ash_export.h" +#include "ash/display/display_configuration_controller.h" #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -46,7 +47,8 @@ // the target position, followed by a new |Rotate()| call with the pending // rotation request. void Rotate(display::Display::Rotation new_rotation, - display::Display::RotationSource source); + display::Display::RotationSource source, + DisplayConfigurationController::RotationAnimation mode); void AddScreenRotationAnimatorObserver( ScreenRotationAnimatorObserver* observer); @@ -69,19 +71,23 @@ using CopyCallback = base::OnceCallback<void(std::unique_ptr<viz::CopyOutputResult> result)>; struct ScreenRotationRequest { - ScreenRotationRequest(int64_t id, - int64_t display_id, - display::Display::Rotation to_rotation, - display::Display::RotationSource from_source) + ScreenRotationRequest( + int64_t id, + int64_t display_id, + display::Display::Rotation to_rotation, + display::Display::RotationSource from_source, + DisplayConfigurationController::RotationAnimation mode) : id(id), display_id(display_id), new_rotation(to_rotation), - source(from_source) {} + source(from_source), + mode(mode) {} int64_t id; int64_t display_id; display::Display::Rotation old_rotation; display::Display::Rotation new_rotation; display::Display::RotationSource source; + DisplayConfigurationController::RotationAnimation mode; }; // This function can be overridden in unit test to test removing external
diff --git a/ash/rotator/screen_rotation_animator_unittest.cc b/ash/rotator/screen_rotation_animator_unittest.cc index aadfbb88..49e4e69 100644 --- a/ash/rotator/screen_rotation_animator_unittest.cc +++ b/ash/rotator/screen_rotation_animator_unittest.cc
@@ -5,6 +5,7 @@ #include "ash/rotator/screen_rotation_animator.h" #include "ash/ash_switches.h" +#include "ash/display/screen_orientation_controller_chromeos.h" #include "ash/display/window_tree_host_manager.h" #include "ash/public/cpp/config.h" #include "ash/rotator/screen_rotation_animator_observer.h" @@ -263,7 +264,8 @@ EXPECT_FALSE(observer.notified()); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_FALSE(observer.notified()); test_api()->CompleteAnimations(); @@ -279,11 +281,13 @@ EXPECT_FALSE(observer.notified()); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_FALSE(observer.notified()); animator()->Rotate(display::Display::ROTATE_180, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_FALSE(observer.notified()); test_api()->CompleteAnimations(); @@ -295,7 +299,8 @@ TEST_F(ScreenRotationAnimatorSlowAnimationTest, RotatesToDifferentRotation) { SetDisplayRotation(display_id(), display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_TRUE(test_api()->HasActiveAnimations()); test_api()->CompleteAnimations(); @@ -306,7 +311,8 @@ ShouldNotRotateTheSameRotation) { SetDisplayRotation(display_id(), display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_0, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_FALSE(test_api()->HasActiveAnimations()); } @@ -316,12 +322,14 @@ TEST_F(ScreenRotationAnimatorSlowAnimationTest, RotatesDuringRotation) { SetDisplayRotation(display_id(), display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_TRUE(animator()->IsRotating()); EXPECT_EQ(display::Display::ROTATE_90, animator()->GetTargetRotation()); animator()->Rotate(display::Display::ROTATE_180, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_TRUE(test_api()->HasActiveAnimations()); EXPECT_TRUE(animator()->IsRotating()); EXPECT_EQ(display::Display::ROTATE_180, animator()->GetTargetRotation()); @@ -338,15 +346,18 @@ TEST_F(ScreenRotationAnimatorSlowAnimationTest, ShouldCompleteAnimations) { SetDisplayRotation(display_id(), display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_TRUE(test_api()->HasActiveAnimations()); animator()->Rotate(display::Display::ROTATE_180, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_TRUE(test_api()->HasActiveAnimations()); animator()->Rotate(display::Display::ROTATE_270, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_TRUE(test_api()->HasActiveAnimations()); test_api()->CompleteAnimations(); @@ -371,7 +382,8 @@ ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); SetDisplayRotation(display_id(), display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_SYNC); EXPECT_FALSE(GetTray()->visible()); } @@ -393,7 +405,8 @@ base::Unretained(this))); SetDisplayRotation(display_id, display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); EXPECT_TRUE(animator()->IsRotating()); EXPECT_EQ(display::Display::ROTATE_90, animator()->GetTargetRotation()); @@ -429,7 +442,8 @@ run_loop_->QuitWhenIdleClosure()); SetDisplayRotation(secondary_display_id, display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); WaitForCopyCallback(); EXPECT_EQ(1U, display_manager()->GetNumDisplays()); EXPECT_EQ(primary_display_id, display_manager()->GetDisplayAt(0).id()); @@ -454,7 +468,8 @@ run_loop_->QuitWhenIdleClosure()); SetDisplayRotation(primary_display_id, display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); WaitForCopyCallback(); EXPECT_EQ(1U, display_manager()->GetNumDisplays()); EXPECT_EQ(secondary_display_id, display_manager()->GetDisplayAt(0).id()); @@ -482,7 +497,8 @@ base::Unretained(this), "640x480")); SetDisplayRotation(secondary_display_id, display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); WaitForCopyCallback(); EXPECT_EQ(1U, display_manager()->GetNumDisplays()); EXPECT_EQ(primary_display_id, display_manager()->GetDisplayAt(0).id()); @@ -512,7 +528,8 @@ base::Unretained(this), "640x480")); SetDisplayRotation(primary_display_id, display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); WaitForCopyCallback(); EXPECT_EQ(1U, display_manager()->GetNumDisplays()); EXPECT_EQ(secondary_display_id, display_manager()->GetDisplayAt(0).id()); @@ -537,7 +554,8 @@ run_loop_->QuitWhenIdleClosure()); SetDisplayRotation(secondary_display_id, display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); WaitForCopyCallback(); EXPECT_EQ(1U, display_manager()->GetNumDisplays()); EXPECT_EQ(secondary_display_id, display_manager()->GetDisplayAt(0).id()); @@ -573,7 +591,8 @@ base::Unretained(this))); SetDisplayRotation(display_id, display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); WaitForCopyCallback(); GetTray()->layer()->GetAnimator()->StopAnimating(); @@ -598,7 +617,8 @@ base::Unretained(this))); SetDisplayRotation(display_id, display::Display::ROTATE_0); animator()->Rotate(display::Display::ROTATE_90, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); WaitForCopyCallback(); EXPECT_TRUE(test_api()->HasActiveAnimations()); @@ -613,7 +633,8 @@ // Should work for another rotation. animator()->Rotate(display::Display::ROTATE_180, - display::Display::RotationSource::ROTATION_SOURCE_USER); + display::Display::ROTATION_SOURCE_USER, + DisplayConfigurationController::ANIMATION_ASYNC); WaitForCopyCallback(); EXPECT_TRUE(test_api()->HasActiveAnimations()); @@ -621,5 +642,4 @@ EXPECT_FALSE(test_api()->HasActiveAnimations()); EXPECT_EQ(display::Display::ROTATE_180, GetDisplayRotation(display_id)); } - } // namespace ash
diff --git a/ash/session/session_controller.cc b/ash/session/session_controller.cc index 5c045a9d..b7a7c98 100644 --- a/ash/session/session_controller.cc +++ b/ash/session/session_controller.cc
@@ -178,6 +178,27 @@ return active_user_type == user_manager::USER_TYPE_CHILD; } +base::Optional<user_manager::UserType> SessionController::GetUserType() const { + if (!IsActiveUserSessionStarted()) + return base::nullopt; + + return base::make_optional(GetUserSession(0)->user_info->type); +} + +bool SessionController::IsUserPrimary() const { + if (!IsActiveUserSessionStarted()) + return false; + + return GetUserSession(0)->session_id == primary_session_id_; +} + +bool SessionController::IsUserFirstLogin() const { + if (!IsActiveUserSessionStarted()) + return false; + + return GetUserSession(0)->user_info->is_new_profile; +} + bool SessionController::IsKioskSession() const { if (!IsActiveUserSessionStarted()) return false;
diff --git a/ash/session/session_controller.h b/ash/session/session_controller.h index a639e90ef..045149d 100644 --- a/ash/session/session_controller.h +++ b/ash/session/session_controller.h
@@ -109,6 +109,18 @@ // Returns true if the current user is a child account. bool IsUserChild() const; + // Returns the type of the current user, or empty if there is no current user + // logged in. + base::Optional<user_manager::UserType> GetUserType() const; + + // Returns true if the current user is the primary user in a multi-profile + // scenario. This always return true if there is only one user logged in. + bool IsUserPrimary() const; + + // Returns true if the current user has the profile newly created on the + // device (i.e. first time login on the device). + bool IsUserFirstLogin() const; + // Returns true if the current user session is a kiosk session (either // chrome app kiosk or ARC kiosk). bool IsKioskSession() const;
diff --git a/ash/session/session_controller_unittest.cc b/ash/session/session_controller_unittest.cc index c1cba24..4721dd2e 100644 --- a/ash/session/session_controller_unittest.cc +++ b/ash/session/session_controller_unittest.cc
@@ -110,6 +110,7 @@ session->user_info->account_id = AccountId::FromUserEmail(email); session->user_info->display_name = email; session->user_info->display_email = email; + session->user_info->is_new_profile = false; controller_->UpdateUserSession(std::move(session)); } @@ -476,5 +477,63 @@ controller->RemoveObserver(&observer); } +TEST_F(SessionControllerTest, GetUserType) { + // Child accounts + mojom::UserSessionPtr session = mojom::UserSession::New(); + session->session_id = 1u; + session->user_info = mojom::UserInfo::New(); + session->user_info->type = user_manager::USER_TYPE_CHILD; + controller()->UpdateUserSession(std::move(session)); + EXPECT_EQ(user_manager::USER_TYPE_CHILD, controller()->GetUserType()); + + // Regular accounts + session = mojom::UserSession::New(); + session->session_id = 1u; + session->user_info = mojom::UserInfo::New(); + session->user_info->type = user_manager::USER_TYPE_REGULAR; + controller()->UpdateUserSession(std::move(session)); + EXPECT_EQ(user_manager::USER_TYPE_REGULAR, controller()->GetUserType()); +} + +TEST_F(SessionControllerTest, IsUserPrimary) { + controller()->ClearUserSessionsForTest(); + + // The first added user is a primary user + mojom::UserSessionPtr session = mojom::UserSession::New(); + session->session_id = 1u; + session->user_info = mojom::UserInfo::New(); + session->user_info->type = user_manager::USER_TYPE_REGULAR; + controller()->UpdateUserSession(std::move(session)); + EXPECT_TRUE(controller()->IsUserPrimary()); + + // The users added thereafter are not primary users + session = mojom::UserSession::New(); + session->session_id = 2u; + session->user_info = mojom::UserInfo::New(); + session->user_info->type = user_manager::USER_TYPE_REGULAR; + controller()->UpdateUserSession(std::move(session)); + // Simulates user switching by changing the order of session_ids. + controller()->SetUserSessionOrder({2u, 1u}); + EXPECT_FALSE(controller()->IsUserPrimary()); +} + +TEST_F(SessionControllerTest, IsUserFirstLogin) { + mojom::UserSessionPtr session = mojom::UserSession::New(); + session->session_id = 1u; + session->user_info = mojom::UserInfo::New(); + session->user_info->type = user_manager::USER_TYPE_REGULAR; + controller()->UpdateUserSession(std::move(session)); + EXPECT_FALSE(controller()->IsUserFirstLogin()); + + // user_info->is_new_profile being true means the user is first time login. + session = mojom::UserSession::New(); + session->session_id = 1u; + session->user_info = mojom::UserInfo::New(); + session->user_info->type = user_manager::USER_TYPE_REGULAR; + session->user_info->is_new_profile = true; + controller()->UpdateUserSession(std::move(session)); + EXPECT_TRUE(controller()->IsUserFirstLogin()); +} + } // namespace } // namespace ash
diff --git a/ash/session/test_session_controller_client.cc b/ash/session/test_session_controller_client.cc index 5710e46..a00739f2 100644 --- a/ash/session/test_session_controller_client.cc +++ b/ash/session/test_session_controller_client.cc
@@ -104,7 +104,8 @@ const std::string& display_email, user_manager::UserType user_type, bool enable_settings, - bool provide_pref_service) { + bool provide_pref_service, + bool is_new_profile) { auto account_id = AccountId::FromUserEmail(GetUserIdFromEmail(display_email)); mojom::UserSessionPtr session = mojom::UserSession::New(); session->session_id = ++fake_session_id_; @@ -113,6 +114,7 @@ session->user_info->account_id = account_id; session->user_info->display_name = "Über tray Über tray Über tray Über tray"; session->user_info->display_email = display_email; + session->user_info->is_new_profile = is_new_profile; session->should_enable_settings = enable_settings; session->should_show_notification_tray = true; controller_->UpdateUserSession(std::move(session));
diff --git a/ash/session/test_session_controller_client.h b/ash/session/test_session_controller_client.h index c2f7ebb..2951173 100644 --- a/ash/session/test_session_controller_client.h +++ b/ash/session/test_session_controller_client.h
@@ -52,12 +52,14 @@ // Adds a user session from a given display email. The display email will be // canonicalized and used to construct an AccountId. |enable_settings| sets // whether web UI settings are allowed. If |provide_pref_service| is true, - // eagerly inject a PrefService for this user. + // eagerly inject a PrefService for this user. |is_new_profile| indicates + // whether the user has a newly created profile on the device. void AddUserSession( const std::string& display_email, user_manager::UserType user_type = user_manager::USER_TYPE_REGULAR, bool enable_settings = true, - bool provide_pref_service = true); + bool provide_pref_service = true, + bool is_new_profile = false); // Simulates screen unlocking. It is virtual so that test cases can override // it. The default implementation sets the session state of SessionController
diff --git a/ash/shelf/shelf_constants.h b/ash/shelf/shelf_constants.h index 862d582d..f29671f 100644 --- a/ash/shelf/shelf_constants.h +++ b/ash/shelf/shelf_constants.h
@@ -59,7 +59,7 @@ // The alpha value used to darken a colorized shelf when the shelf is // translucent. -constexpr int kShelfTranslucentColorDarkenAlpha = 128; +constexpr int kShelfTranslucentColorDarkenAlpha = 178; // The alpha vlaue usesd to darken a colorized shelf when the shelf is opaque. constexpr int kShelfOpaqueColorDarkenAlpha = 178;
diff --git a/ash/shell.cc b/ash/shell.cc index 224057b..6bf5e68 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -67,6 +67,7 @@ #include "ash/shutdown_controller.h" #include "ash/sticky_keys/sticky_keys_controller.h" #include "ash/system/bluetooth/bluetooth_notification_controller.h" +#include "ash/system/bluetooth/bluetooth_power_controller.h" #include "ash/system/bluetooth/tray_bluetooth_helper.h" #include "ash/system/brightness/brightness_controller_chromeos.h" #include "ash/system/brightness_control_delegate.h" @@ -333,6 +334,7 @@ void Shell::RegisterLocalStatePrefs(PrefRegistrySimple* registry) { PaletteTray::RegisterLocalStatePrefs(registry); WallpaperController::RegisterLocalStatePrefs(registry); + BluetoothPowerController::RegisterLocalStatePrefs(registry); } // static @@ -340,10 +342,10 @@ LogoutButtonTray::RegisterProfilePrefs(registry); NightLightController::RegisterProfilePrefs(registry); ShelfController::RegisterProfilePrefs(registry); - // Request access to prefs used by ash but owned by chrome. // See //services/preferences/README.md TrayCapsLock::RegisterForeignPrefs(registry); + BluetoothPowerController::RegisterProfilePrefs(registry); } views::NonClientFrameView* Shell::CreateDefaultNonClientFrameView( @@ -864,6 +866,9 @@ shell_port_.reset(); session_controller_->RemoveObserver(this); wallpaper_delegate_.reset(); + // BluetoothPowerController depends on the PrefService and must be destructed + // before it. + bluetooth_power_controller_ = nullptr; // NightLightController depeneds on the PrefService and must be destructed // before it. crbug.com/724231. night_light_controller_ = nullptr; @@ -886,6 +891,8 @@ if (NightLightController::IsFeatureEnabled()) night_light_controller_ = base::MakeUnique<NightLightController>(); + bluetooth_power_controller_ = base::MakeUnique<BluetoothPowerController>(); + wallpaper_delegate_ = shell_delegate_->CreateWallpaperDelegate(); // Connector can be null in tests.
diff --git a/ash/shell.h b/ash/shell.h index e8673c81..e414fcb 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -91,6 +91,7 @@ class AshTouchTransformController; class AutoclickController; class BluetoothNotificationController; +class BluetoothPowerController; class BrightnessControlDelegate; class CastConfigController; class DisplayColorManager; @@ -479,6 +480,10 @@ return tray_bluetooth_helper_.get(); } + BluetoothPowerController* bluetooth_power_controller() { + return bluetooth_power_controller_.get(); + } + VirtualKeyboardController* virtual_keyboard_controller() { return virtual_keyboard_controller_.get(); } @@ -778,6 +783,7 @@ resolution_notification_controller_; std::unique_ptr<BluetoothNotificationController> bluetooth_notification_controller_; + std::unique_ptr<BluetoothPowerController> bluetooth_power_controller_; std::unique_ptr<TrayBluetoothHelper> tray_bluetooth_helper_; std::unique_ptr<VirtualKeyboardController> virtual_keyboard_controller_; std::unique_ptr<chromeos::AudioA11yController> audio_a11y_controller_;
diff --git a/ash/system/bluetooth/bluetooth_power_controller.cc b/ash/system/bluetooth/bluetooth_power_controller.cc new file mode 100644 index 0000000..cf351ffb --- /dev/null +++ b/ash/system/bluetooth/bluetooth_power_controller.cc
@@ -0,0 +1,260 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/system/bluetooth/bluetooth_power_controller.h" + +#include "ash/public/cpp/ash_pref_names.h" +#include "ash/session/session_controller.h" +#include "ash/shell.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" + +namespace ash { + +BluetoothPowerController::BluetoothPowerController() : weak_ptr_factory_(this) { + device::BluetoothAdapterFactory::GetAdapter( + base::Bind(&BluetoothPowerController::InitializeOnAdapterReady, + weak_ptr_factory_.GetWeakPtr())); + Shell::Get()->AddShellObserver(this); + Shell::Get()->session_controller()->AddObserver(this); +} + +BluetoothPowerController::~BluetoothPowerController() { + if (bluetooth_adapter_) + bluetooth_adapter_->RemoveObserver(this); + Shell::Get()->RemoveShellObserver(this); + Shell::Get()->session_controller()->RemoveObserver(this); +} + +void BluetoothPowerController::ToggleBluetoothEnabled() { + if (active_user_pref_service_) { + active_user_pref_service_->SetBoolean( + prefs::kUserBluetoothAdapterEnabled, + !active_user_pref_service_->GetBoolean( + prefs::kUserBluetoothAdapterEnabled)); + } else if (local_state_pref_service_) { + local_state_pref_service_->SetBoolean( + prefs::kSystemBluetoothAdapterEnabled, + !local_state_pref_service_->GetBoolean( + prefs::kSystemBluetoothAdapterEnabled)); + } else { + DLOG(ERROR) + << "active user and local state pref service cannot both be null"; + } +} + +// static +void BluetoothPowerController::RegisterLocalStatePrefs( + PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kSystemBluetoothAdapterEnabled, false); +} + +// static +void BluetoothPowerController::RegisterProfilePrefs( + PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kUserBluetoothAdapterEnabled, false, + PrefRegistry::PUBLIC); +} + +void BluetoothPowerController::StartWatchingActiveUserPrefsChanges() { + DCHECK(active_user_pref_service_); + DCHECK(Shell::Get()->session_controller()->IsUserPrimary()); + + active_user_pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); + active_user_pref_change_registrar_->Init(active_user_pref_service_); + active_user_pref_change_registrar_->Add( + prefs::kUserBluetoothAdapterEnabled, + base::Bind( + &BluetoothPowerController::OnBluetoothPowerActiveUserPrefChanged, + base::Unretained(this))); +} + +void BluetoothPowerController::StartWatchingLocalStatePrefsChanges() { + DCHECK(local_state_pref_service_); + + local_state_pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); + local_state_pref_change_registrar_->Init(local_state_pref_service_); + local_state_pref_change_registrar_->Add( + prefs::kSystemBluetoothAdapterEnabled, + base::Bind( + &BluetoothPowerController::OnBluetoothPowerLocalStatePrefChanged, + base::Unretained(this))); +} + +void BluetoothPowerController::StopWatchingActiveUserPrefsChanges() { + active_user_pref_change_registrar_.reset(); +} + +void BluetoothPowerController::OnBluetoothPowerActiveUserPrefChanged() { + DCHECK(active_user_pref_service_); + SetBluetoothPower(active_user_pref_service_->GetBoolean( + prefs::kUserBluetoothAdapterEnabled)); +} + +void BluetoothPowerController::OnBluetoothPowerLocalStatePrefChanged() { + DCHECK(local_state_pref_service_); + SetBluetoothPower(local_state_pref_service_->GetBoolean( + prefs::kSystemBluetoothAdapterEnabled)); +} + +void BluetoothPowerController::SetPrimaryUserBluetoothPowerSetting( + bool enabled) { + // This method should only be called when the primary user is the active user. + CHECK(Shell::Get()->session_controller()->IsUserPrimary()); + + active_user_pref_service_->SetBoolean(prefs::kUserBluetoothAdapterEnabled, + enabled); +} + +void BluetoothPowerController::InitializeOnAdapterReady( + scoped_refptr<device::BluetoothAdapter> adapter) { + bluetooth_adapter_ = std::move(adapter); + bluetooth_adapter_->AddObserver(this); + if (bluetooth_adapter_->IsPresent()) { + RunPendingBluetoothTasks(bluetooth_adapter_.get()); + } +} + +void BluetoothPowerController::OnActiveUserPrefServiceChanged( + PrefService* pref_service) { + active_user_pref_service_ = pref_service; + + // Only listen to primary user's pref changes since non-primary users + // are not able to change bluetooth pref. + if (!Shell::Get()->session_controller()->IsUserPrimary()) { + StopWatchingActiveUserPrefsChanges(); + return; + } + StartWatchingActiveUserPrefsChanges(); + + // Apply the bluetooth pref only for regular users (i.e. users representing + // a human individual). We don't want to apply bluetooth pref for other users + // e.g. kiosk, guest etc. For non-human users, bluetooth power should be left + // to the current power state. + if (!is_primary_user_bluetooth_applied_) { + ApplyBluetoothPrimaryUserPref(); + is_primary_user_bluetooth_applied_ = true; + } +} + +void BluetoothPowerController::OnLocalStatePrefServiceInitialized( + PrefService* pref_service) { + // AppLaunchTest.TestQuickLaunch fails under target=linux due to + // pref_service being nullptr. + if (!pref_service) + return; + + local_state_pref_service_ = pref_service; + + StartWatchingLocalStatePrefsChanges(); + + if (!Shell::Get()->session_controller()->IsActiveUserSessionStarted()) { + // Apply the local state pref only if no user has logged in (still in login + // screen). + ApplyBluetoothLocalStatePref(); + } +} + +void BluetoothPowerController::AdapterPresentChanged( + device::BluetoothAdapter* adapter, + bool present) { + if (present) + RunPendingBluetoothTasks(adapter); +} + +void BluetoothPowerController::ApplyBluetoothPrimaryUserPref() { + base::Optional<user_manager::UserType> user_type = + Shell::Get()->session_controller()->GetUserType(); + if (!user_type || !ShouldApplyUserBluetoothSetting(*user_type)) { + // Do not apply bluetooth setting if user is not of the allowed types. + return; + } + + DCHECK(Shell::Get()->session_controller()->IsUserPrimary()); + + PrefService* prefs = active_user_pref_service_; + + if (!prefs->FindPreference(prefs::kUserBluetoothAdapterEnabled) + ->IsDefaultValue()) { + SetBluetoothPower(prefs->GetBoolean(prefs::kUserBluetoothAdapterEnabled)); + return; + } + + // If the user has not had the bluetooth pref yet, set the user pref + // according to whatever the current bluetooth power is, except for + // new users (first login on the device) always set the new pref to true. + if (Shell::Get()->session_controller()->IsUserFirstLogin()) { + prefs->SetBoolean(prefs::kUserBluetoothAdapterEnabled, true); + } else { + SavePrefValue(prefs, prefs::kUserBluetoothAdapterEnabled); + } +} + +void BluetoothPowerController::ApplyBluetoothLocalStatePref() { + PrefService* prefs = local_state_pref_service_; + + if (prefs->FindPreference(prefs::kSystemBluetoothAdapterEnabled) + ->IsDefaultValue()) { + // If the device has not had the local state bluetooth pref, set the pref + // according to whatever the current bluetooth power is. + SavePrefValue(prefs, prefs::kSystemBluetoothAdapterEnabled); + } else { + SetBluetoothPower(prefs->GetBoolean(prefs::kSystemBluetoothAdapterEnabled)); + } +} + +void BluetoothPowerController::SetBluetoothPower(bool enabled) { + RunBluetoothTaskWhenAdapterReady( + base::BindOnce(&BluetoothPowerController::SetBluetoothPowerOnAdapterReady, + weak_ptr_factory_.GetWeakPtr(), enabled)); +} + +void BluetoothPowerController::SetBluetoothPowerOnAdapterReady( + bool enabled, + device::BluetoothAdapter* adapter) { + adapter->SetPowered(enabled, base::Bind(&base::DoNothing), + base::Bind(&base::DoNothing)); +} + +void BluetoothPowerController::RunBluetoothTaskWhenAdapterReady( + base::OnceCallback<void(device::BluetoothAdapter*)> task) { + if (bluetooth_adapter_ && bluetooth_adapter_->IsPresent()) { + std::move(task).Run(bluetooth_adapter_.get()); + } else { + pending_bluetooth_tasks_.push_back(std::move(task)); + } +} + +void BluetoothPowerController::RunPendingBluetoothTasks( + device::BluetoothAdapter* adapter) { + for (auto& task : pending_bluetooth_tasks_) { + std::move(task).Run(adapter); + } + pending_bluetooth_tasks_.clear(); +} + +void BluetoothPowerController::SavePrefValue(PrefService* prefs, + const char* pref_name) { + RunBluetoothTaskWhenAdapterReady( + base::BindOnce(&BluetoothPowerController::SavePrefValueOnAdapterReady, + weak_ptr_factory_.GetWeakPtr(), prefs, pref_name)); +} + +void BluetoothPowerController::SavePrefValueOnAdapterReady( + PrefService* prefs, + const char* pref_name, + device::BluetoothAdapter* adapter) { + prefs->SetBoolean(pref_name, adapter->IsPowered()); +} + +bool BluetoothPowerController::ShouldApplyUserBluetoothSetting( + user_manager::UserType user_type) const { + return user_type == user_manager::USER_TYPE_REGULAR || + user_type == user_manager::USER_TYPE_CHILD || + user_type == user_manager::USER_TYPE_SUPERVISED || + user_type == user_manager::USER_TYPE_ACTIVE_DIRECTORY; +} + +} // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_power_controller.h b/ash/system/bluetooth/bluetooth_power_controller.h new file mode 100644 index 0000000..f97d0613 --- /dev/null +++ b/ash/system/bluetooth/bluetooth_power_controller.h
@@ -0,0 +1,145 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SYSTEM_BLUETOOTH_BLUETOOTH_POWER_CONTROLLER_H_ +#define ASH_SYSTEM_BLUETOOTH_BLUETOOTH_POWER_CONTROLLER_H_ + +#include "ash/ash_export.h" +#include "ash/session/session_observer.h" +#include "ash/shell_observer.h" +#include "base/logging.h" +#include "base/macros.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/user_manager/user_manager.h" +#include "device/bluetooth/bluetooth_adapter.h" + +class PrefRegistrySimple; +class PrefService; + +namespace ash { + +// Listens to changes of bluetooth power preferences and apply them to the +// device. Also initializes the bluetooth power during system startup +// and user session startup. +// +// This should be the only entity controlling bluetooth power. All other code +// outside ash that wants to control bluetooth power should set user pref +// setting instead. +class ASH_EXPORT BluetoothPowerController + : public SessionObserver, + public ShellObserver, + public device::BluetoothAdapter::Observer { + public: + BluetoothPowerController(); + ~BluetoothPowerController() override; + + // Toggles the bluetooth power setting on or off. + void ToggleBluetoothEnabled(); + + static void RegisterLocalStatePrefs(PrefRegistrySimple* registry); + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + + // Sets the primary user's bluetooth power pref. Setting the pref will also + // trigger the change of the bluetooth power. This method can only be called + // when the primary user is the active user, otherwise the operation is + // ignored. + void SetPrimaryUserBluetoothPowerSetting(bool enabled); + + // Called when BluetoothAdapterFactory::GetAdapter is ready to pass the + // adapter pointer. + void InitializeOnAdapterReady( + scoped_refptr<device::BluetoothAdapter> adapter); + + // SessionObserver: + void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; + + // ShellObserver: + void OnLocalStatePrefServiceInitialized(PrefService* pref_service) override; + + // BluetoothAdapter::Observer: + void AdapterPresentChanged(device::BluetoothAdapter* adapter, + bool present) override; + + private: + friend class BluetoothPowerControllerTest; + + void StartWatchingActiveUserPrefsChanges(); + void StartWatchingLocalStatePrefsChanges(); + void StopWatchingActiveUserPrefsChanges(); + + void OnBluetoothPowerActiveUserPrefChanged(); + void OnBluetoothPowerLocalStatePrefChanged(); + + // At primary user session startup, apply the user's bluetooth power setting + // or set the default if the user doesn't have the setting yet. + void ApplyBluetoothPrimaryUserPref(); + + // At login screen startup, apply the local state bluetooth power setting + // or set the default if the device doesn't have the setting yet. + void ApplyBluetoothLocalStatePref(); + + // Sets the bluetooth power, may defer the operation if bluetooth adapter + // is not yet ready. + void SetBluetoothPower(bool enabled); + + // Sets the bluetooth power given the ready adapter. + void SetBluetoothPowerOnAdapterReady(bool enabled, + device::BluetoothAdapter* adapter); + + // If adapter is ready run the task right now, otherwise add the task + // to the queue which will be executed when bluetooth adapter is ready. + void RunBluetoothTaskWhenAdapterReady( + base::OnceCallback<void(device::BluetoothAdapter*)> task); + + // Runs all pending bluetooth adapter-dependent tasks. + void RunPendingBluetoothTasks(device::BluetoothAdapter* adapter); + + // Sets the pref value based on current bluetooth power state. May defer + // the operation if bluetooth adapter is not ready yet. + void SavePrefValue(PrefService* prefs, const char* pref_name); + + // Sets the pref value based on current bluetooth power state, given the ready + // bluetooth adapter. + void SavePrefValueOnAdapterReady(PrefService* prefs, + const char* pref_name, + device::BluetoothAdapter* adapter); + + // Decides whether to apply bluetooth setting based on user type. + // Returns true if the user type represents a human individual, currently this + // includes: regular, child, supervised, or active directory. The other types + // do not represent human account so those account should follow system-wide + // bluetooth setting instead. + bool ShouldApplyUserBluetoothSetting(user_manager::UserType user_type) const; + + // Remembers whether we have ever applied the primary user's bluetooth + // setting. If this variable is true, we will ignore any active user change + // event since we know that the primary user's bluetooth setting has been + // applied. + bool is_primary_user_bluetooth_applied_ = false; + + PrefService* active_user_pref_service_ = nullptr; + PrefService* local_state_pref_service_ = nullptr; + + // Contains pending tasks which depend on the availability of bluetooth + // adapter. + std::vector<base::OnceCallback<void(device::BluetoothAdapter*)>> + pending_bluetooth_tasks_; + + // The registrar used to watch prefs changes in the above + // |active_user_pref_service_| from outside ash. + // NOTE: Prefs are how Chrome communicates changes to the bluetooth power + // settings controlled by this class from the WebUI settings. + std::unique_ptr<PrefChangeRegistrar> active_user_pref_change_registrar_; + std::unique_ptr<PrefChangeRegistrar> local_state_pref_change_registrar_; + + scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; + + base::WeakPtrFactory<BluetoothPowerController> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothPowerController); +}; + +} // namespace ash + +#endif // ASH_SYSTEM_BLUETOOTH_BLUETOOTH_POWER_CONTROLLER_H_
diff --git a/ash/system/bluetooth/bluetooth_power_controller_unittest.cc b/ash/system/bluetooth/bluetooth_power_controller_unittest.cc new file mode 100644 index 0000000..9ea3f063 --- /dev/null +++ b/ash/system/bluetooth/bluetooth_power_controller_unittest.cc
@@ -0,0 +1,300 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/system/bluetooth/bluetooth_power_controller.h" + +#include "ash/public/cpp/ash_pref_names.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/test/ash_test_helper.h" +#include "ash/test_shell_delegate.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/testing_pref_service.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" + +namespace ash { +namespace { + +constexpr char kUser1Email[] = "user1@bluetooth"; +constexpr bool kUserFirstLogin = true; + +} // namespace + +class BluetoothPowerControllerTest : public NoSessionAshTestBase { + public: + BluetoothPowerControllerTest() {} + ~BluetoothPowerControllerTest() override {} + + void SetUp() override { + NoSessionAshTestBase::SetUp(); + + // Set Bluetooth discovery simulation delay to 0 so the test doesn't have to + // wait or use timers. + bluez::FakeBluetoothAdapterClient* adapter_client = + static_cast<bluez::FakeBluetoothAdapterClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()); + adapter_client->SetSimulationIntervalMs(0); + + BluetoothPowerController::RegisterProfilePrefs( + active_user_prefs_.registry()); + BluetoothPowerController::RegisterLocalStatePrefs( + local_state_prefs_.registry()); + + GetController()->local_state_pref_service_ = &local_state_prefs_; + + // Makes sure we get the callback from BluetoothAdapterFactory::GetAdapter + // first before running the remaining test. + RunAllPendingInMessageLoop(); + } + + void AddUserSessionAndStartWatchingPrefsChanges( + const std::string& display_email, + user_manager::UserType user_type = user_manager::USER_TYPE_REGULAR, + bool is_new_profile = false) { + GetSessionControllerClient()->AddUserSession( + display_email, user_type, false /* enable_settings */, + false /* provide_pref_service */, is_new_profile); + GetController()->active_user_pref_service_ = &active_user_prefs_; + GetController()->StartWatchingActiveUserPrefsChanges(); + } + + void StartWatchingLocalStatePrefsChanges() { + GetController()->StartWatchingLocalStatePrefsChanges(); + } + + protected: + BluetoothPowerController* GetController() { + return Shell::Get()->bluetooth_power_controller(); + } + + device::BluetoothAdapter* GetBluetoothAdapter() { + return Shell::Get()->bluetooth_power_controller()->bluetooth_adapter_.get(); + } + + void ApplyBluetoothLocalStatePref() { + Shell::Get()->bluetooth_power_controller()->ApplyBluetoothLocalStatePref(); + } + + void ApplyBluetoothPrimaryUserPref() { + Shell::Get()->bluetooth_power_controller()->ApplyBluetoothPrimaryUserPref(); + } + + TestingPrefServiceSimple active_user_prefs_; + TestingPrefServiceSimple local_state_prefs_; + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothPowerControllerTest); +}; + +// Tests toggling Bluetooth setting on and off. +TEST_F(BluetoothPowerControllerTest, ToggleBluetoothEnabled) { + // Toggling bluetooth on/off when there is no user session should affect + // local state prefs. + EXPECT_FALSE( + local_state_prefs_.GetBoolean(prefs::kSystemBluetoothAdapterEnabled)); + GetController()->ToggleBluetoothEnabled(); + EXPECT_TRUE( + local_state_prefs_.GetBoolean(prefs::kSystemBluetoothAdapterEnabled)); + GetController()->ToggleBluetoothEnabled(); + EXPECT_FALSE( + local_state_prefs_.GetBoolean(prefs::kSystemBluetoothAdapterEnabled)); + + // Toggling bluetooth on/off when there is user session should affect + // user prefs. + AddUserSessionAndStartWatchingPrefsChanges(kUser1Email); + EXPECT_FALSE( + active_user_prefs_.GetBoolean(prefs::kUserBluetoothAdapterEnabled)); + GetController()->ToggleBluetoothEnabled(); + EXPECT_TRUE( + active_user_prefs_.GetBoolean(prefs::kUserBluetoothAdapterEnabled)); + GetController()->ToggleBluetoothEnabled(); + EXPECT_FALSE( + active_user_prefs_.GetBoolean(prefs::kUserBluetoothAdapterEnabled)); +} + +// Tests that BluetoothPowerController listens to local state pref changes +// and applies the changes to bluetooth device. +TEST_F(BluetoothPowerControllerTest, ListensPrefChangesLocalState) { + StartWatchingLocalStatePrefsChanges(); + + // Makes sure we start with bluetooth power off. + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); + EXPECT_FALSE( + local_state_prefs_.GetBoolean(prefs::kSystemBluetoothAdapterEnabled)); + + // Power should be turned on when pref changes to enabled. + local_state_prefs_.SetBoolean(prefs::kSystemBluetoothAdapterEnabled, true); + EXPECT_TRUE(GetBluetoothAdapter()->IsPowered()); + + // Power should be turned off when pref changes to disabled. + local_state_prefs_.SetBoolean(prefs::kSystemBluetoothAdapterEnabled, false); + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); +} + +// Tests that BluetoothPowerController listens to active user pref changes +// and applies the changes to bluetooth device. +TEST_F(BluetoothPowerControllerTest, ListensPrefChangesActiveUser) { + AddUserSessionAndStartWatchingPrefsChanges(kUser1Email); + + // Makes sure we start with bluetooth power off. + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); + EXPECT_FALSE( + active_user_prefs_.GetBoolean(prefs::kUserBluetoothAdapterEnabled)); + + // Power should be turned on when pref changes to enabled. + active_user_prefs_.SetBoolean(prefs::kUserBluetoothAdapterEnabled, true); + EXPECT_TRUE(GetBluetoothAdapter()->IsPowered()); + + // Power should be turned off when pref changes to disabled. + active_user_prefs_.SetBoolean(prefs::kUserBluetoothAdapterEnabled, false); + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); +} + +// Tests how BluetoothPowerController applies the local state pref when +// the pref hasn't been set before. +TEST_F(BluetoothPowerControllerTest, ApplyBluetoothLocalStatePrefDefault) { + // Makes sure pref hasn't been set before. + EXPECT_TRUE( + local_state_prefs_.FindPreference(prefs::kSystemBluetoothAdapterEnabled) + ->IsDefaultValue()); + // Start with bluetooth power on. + GetBluetoothAdapter()->SetPowered(true, base::Bind(&base::DoNothing), + base::Bind(&base::DoNothing)); + EXPECT_TRUE(GetBluetoothAdapter()->IsPowered()); + + ApplyBluetoothLocalStatePref(); + + // Pref should now contain the current bluetooth adapter state (on). + EXPECT_FALSE( + local_state_prefs_.FindPreference(prefs::kSystemBluetoothAdapterEnabled) + ->IsDefaultValue()); + EXPECT_TRUE( + local_state_prefs_.GetBoolean(prefs::kSystemBluetoothAdapterEnabled)); +} + +// Tests how BluetoothPowerController applies the local state pref when +// the pref has been set before. +TEST_F(BluetoothPowerControllerTest, ApplyBluetoothLocalStatePrefOn) { + // Set the pref to true. + local_state_prefs_.SetBoolean(prefs::kSystemBluetoothAdapterEnabled, true); + EXPECT_FALSE( + local_state_prefs_.FindPreference(prefs::kSystemBluetoothAdapterEnabled) + ->IsDefaultValue()); + // Start with bluetooth power off. + GetBluetoothAdapter()->SetPowered(false, base::Bind(&base::DoNothing), + base::Bind(&base::DoNothing)); + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); + + ApplyBluetoothLocalStatePref(); + + // Bluetooth power setting should be applied (on), and pref value unchanged. + EXPECT_TRUE( + local_state_prefs_.GetBoolean(prefs::kSystemBluetoothAdapterEnabled)); + EXPECT_TRUE(GetBluetoothAdapter()->IsPowered()); +} + +// Tests how BluetoothPowerController applies the user pref when +// the pref hasn't been set before. +TEST_F(BluetoothPowerControllerTest, ApplyBluetoothPrimaryUserPrefDefault) { + AddUserSessionAndStartWatchingPrefsChanges(kUser1Email); + + // Makes sure pref hasn't been set before. + EXPECT_TRUE( + active_user_prefs_.FindPreference(prefs::kUserBluetoothAdapterEnabled) + ->IsDefaultValue()); + // Start with bluetooth power off. + GetBluetoothAdapter()->SetPowered(false, base::Bind(&base::DoNothing), + base::Bind(&base::DoNothing)); + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); + + ApplyBluetoothPrimaryUserPref(); + + // Pref should now contain the current bluetooth adapter state (off). + EXPECT_FALSE( + active_user_prefs_.FindPreference(prefs::kUserBluetoothAdapterEnabled) + ->IsDefaultValue()); + EXPECT_FALSE( + active_user_prefs_.GetBoolean(prefs::kUserBluetoothAdapterEnabled)); +} + +// Tests how BluetoothPowerController applies the user pref when +// the pref hasn't been set before, and it's a first-login user. +TEST_F(BluetoothPowerControllerTest, ApplyBluetoothPrimaryUserPrefDefaultNew) { + AddUserSessionAndStartWatchingPrefsChanges( + kUser1Email, user_manager::USER_TYPE_REGULAR, kUserFirstLogin); + + // Makes sure pref hasn't been set before. + EXPECT_TRUE( + active_user_prefs_.FindPreference(prefs::kUserBluetoothAdapterEnabled) + ->IsDefaultValue()); + // Start with bluetooth power off. + GetBluetoothAdapter()->SetPowered(false, base::Bind(&base::DoNothing), + base::Bind(&base::DoNothing)); + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); + + ApplyBluetoothPrimaryUserPref(); + + // Pref should be set to true for first-login users, and this will also + // trigger the bluetooth power on. + EXPECT_FALSE( + active_user_prefs_.FindPreference(prefs::kUserBluetoothAdapterEnabled) + ->IsDefaultValue()); + EXPECT_TRUE( + active_user_prefs_.GetBoolean(prefs::kUserBluetoothAdapterEnabled)); + EXPECT_TRUE(GetBluetoothAdapter()->IsPowered()); +} + +// Tests how BluetoothPowerController applies the user pref when +// the pref hasn't been set before, but not a regular user (e.g. kiosk). +TEST_F(BluetoothPowerControllerTest, ApplyBluetoothKioskUserPrefDefault) { + AddUserSessionAndStartWatchingPrefsChanges(kUser1Email, + user_manager::USER_TYPE_KIOSK_APP); + + // Makes sure pref hasn't been set before. + EXPECT_TRUE( + active_user_prefs_.FindPreference(prefs::kUserBluetoothAdapterEnabled) + ->IsDefaultValue()); + // Start with bluetooth power off. + GetBluetoothAdapter()->SetPowered(false, base::Bind(&base::DoNothing), + base::Bind(&base::DoNothing)); + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); + + ApplyBluetoothPrimaryUserPref(); + + // For non-regular user, do not apply the bluetooth setting and no need + // to set the pref. + EXPECT_TRUE( + active_user_prefs_.FindPreference(prefs::kUserBluetoothAdapterEnabled) + ->IsDefaultValue()); + EXPECT_FALSE( + active_user_prefs_.GetBoolean(prefs::kUserBluetoothAdapterEnabled)); + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); +} + +// Tests how BluetoothPowerController applies the user pref when +// the pref has been set before. +TEST_F(BluetoothPowerControllerTest, ApplyBluetoothPrimaryUserPrefOn) { + AddUserSessionAndStartWatchingPrefsChanges(kUser1Email); + + // Set the pref to true. + active_user_prefs_.SetBoolean(prefs::kUserBluetoothAdapterEnabled, true); + EXPECT_FALSE( + active_user_prefs_.FindPreference(prefs::kUserBluetoothAdapterEnabled) + ->IsDefaultValue()); + // Start with bluetooth power off. + GetBluetoothAdapter()->SetPowered(false, base::Bind(&base::DoNothing), + base::Bind(&base::DoNothing)); + EXPECT_FALSE(GetBluetoothAdapter()->IsPowered()); + + ApplyBluetoothPrimaryUserPref(); + + // Pref should be applied to trigger the bluetooth power on, and the pref + // value should be unchanged.. + EXPECT_TRUE( + active_user_prefs_.GetBoolean(prefs::kUserBluetoothAdapterEnabled)); + EXPECT_TRUE(GetBluetoothAdapter()->IsPowered()); +} + +} // namespace ash
diff --git a/ash/system/bluetooth/tray_bluetooth.cc b/ash/system/bluetooth/tray_bluetooth.cc index d6377f4..c5427b9 100644 --- a/ash/system/bluetooth/tray_bluetooth.cc +++ b/ash/system/bluetooth/tray_bluetooth.cc
@@ -12,8 +12,10 @@ #include "ash/ash_view_ids.h" #include "ash/metrics/user_metrics_recorder.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/system/bluetooth/bluetooth_power_controller.h" #include "ash/system/bluetooth/tray_bluetooth_helper.h" #include "ash/system/tray/hover_highlight_view.h" #include "ash/system/tray/system_tray.h" @@ -390,10 +392,12 @@ const ui::Event& event) override { if (sender == toggle_) { TrayBluetoothHelper* helper = Shell::Get()->tray_bluetooth_helper(); + BluetoothPowerController* power_controller = + Shell::Get()->bluetooth_power_controller(); Shell::Get()->metrics()->RecordUserMetricsAction( helper->GetBluetoothEnabled() ? UMA_STATUS_AREA_BLUETOOTH_DISABLED : UMA_STATUS_AREA_BLUETOOTH_ENABLED); - helper->ToggleBluetoothEnabled(); + power_controller->ToggleBluetoothEnabled(); } else if (sender == settings_) { ShowSettings(); } else { @@ -538,8 +542,20 @@ views::View* TrayBluetooth::CreateDefaultView(LoginStatus status) { CHECK(default_ == nullptr); + SessionController* session_controller = Shell::Get()->session_controller(); default_ = new tray::BluetoothDefaultView(this); - default_->SetEnabled(status != LoginStatus::LOCKED); + if (!session_controller->IsActiveUserSessionStarted()) { + // Bluetooth power setting is always mutable in login screen before any + // user logs in. The changes will affect local state preferences. + default_->SetEnabled(true); + } else { + // The bluetooth setting should be mutable only if: + // * the active user is the primary user, and + // * the session is not in lock screen + // The changes will affect the primary user's preferences. + default_->SetEnabled(session_controller->IsUserPrimary() && + status != LoginStatus::LOCKED); + } default_->Update(); return default_; }
diff --git a/ash/system/bluetooth/tray_bluetooth_helper.cc b/ash/system/bluetooth/tray_bluetooth_helper.cc index 2ea5c3f7..fa4b461 100644 --- a/ash/system/bluetooth/tray_bluetooth_helper.cc +++ b/ash/system/bluetooth/tray_bluetooth_helper.cc
@@ -119,11 +119,6 @@ device->IsConnected()); } -void TrayBluetoothHelper::ToggleBluetoothEnabled() { - adapter_->SetPowered(!adapter_->IsPowered(), base::Bind(&base::DoNothing), - base::Bind(&base::DoNothing)); -} - bool TrayBluetoothHelper::GetBluetoothAvailable() { return adapter_ && adapter_->IsPresent(); }
diff --git a/ash/system/bluetooth/tray_bluetooth_helper.h b/ash/system/bluetooth/tray_bluetooth_helper.h index 7aa22d59..4560614 100644 --- a/ash/system/bluetooth/tray_bluetooth_helper.h +++ b/ash/system/bluetooth/tray_bluetooth_helper.h
@@ -67,9 +67,6 @@ // Connect to a specific bluetooth device. void ConnectToBluetoothDevice(const std::string& address); - // Toggles whether bluetooth is enabled. - void ToggleBluetoothEnabled(); - // Returns whether bluetooth capability is available (e.g. the device has // hardware support). bool GetBluetoothAvailable();
diff --git a/ash/system/bluetooth/tray_bluetooth_helper_unittest.cc b/ash/system/bluetooth/tray_bluetooth_helper_unittest.cc index d88b11f..396b3cc 100644 --- a/ash/system/bluetooth/tray_bluetooth_helper_unittest.cc +++ b/ash/system/bluetooth/tray_bluetooth_helper_unittest.cc
@@ -18,7 +18,7 @@ using TrayBluetoothHelperTest = AshTestBase; -// Tests basic functionality like turning Bluetooth on and off. +// Tests basic functionality. TEST_F(TrayBluetoothHelperTest, Basics) { // Set Bluetooth discovery simulation delay to 0 so the test doesn't have to // wait or use timers. @@ -38,11 +38,6 @@ // The devices are fake in tests, so don't assume any particular number. EXPECT_FALSE(devices.empty()); - // Turn Bluetooth on. - helper.ToggleBluetoothEnabled(); - RunAllPendingInMessageLoop(); - EXPECT_TRUE(helper.GetBluetoothEnabled()); - helper.StartBluetoothDiscovering(); RunAllPendingInMessageLoop(); EXPECT_TRUE(helper.HasBluetoothDiscoverySession()); @@ -50,11 +45,6 @@ helper.StopBluetoothDiscovering(); RunAllPendingInMessageLoop(); EXPECT_FALSE(helper.HasBluetoothDiscoverySession()); - - // Turn Bluetooth off. - helper.ToggleBluetoothEnabled(); - RunAllPendingInMessageLoop(); - EXPECT_FALSE(helper.GetBluetoothEnabled()); } } // namespace
diff --git a/ash/wallpaper/wallpaper_controller_test_api.cc b/ash/wallpaper/wallpaper_controller_test_api.cc index 95fcd00..2b74f87e 100644 --- a/ash/wallpaper/wallpaper_controller_test_api.cc +++ b/ash/wallpaper/wallpaper_controller_test_api.cc
@@ -5,6 +5,7 @@ #include "ash/wallpaper/wallpaper_controller_test_api.h" #include "ash/wallpaper/wallpaper_controller.h" #include "ui/gfx/canvas.h" +#include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image_skia.h" @@ -18,7 +19,7 @@ SkColor WallpaperControllerTestApi::ApplyColorProducingWallpaper() { const SkColor color = SkColorSetRGB(60, 40, 40); - const SkColor expected_color = SkColorSetRGB(30, 20, 20); + const SkColor expected_color = SkColorSetRGB(18, 12, 12); gfx::Canvas canvas(gfx::Size(5, 5), 1.0f, true); canvas.DrawColor(color);
diff --git a/base/bind.h b/base/bind.h index b1c6ac698..32a1c851e 100644 --- a/base/bind.h +++ b/base/bind.h
@@ -66,18 +66,18 @@ }; // The implementation of TransformToUnwrappedType below. -template <RepeatMode, typename T> +template <bool is_once, typename T> struct TransformToUnwrappedTypeImpl; template <typename T> -struct TransformToUnwrappedTypeImpl<RepeatMode::Once, T> { +struct TransformToUnwrappedTypeImpl<true, T> { using StoredType = std::decay_t<T>; using ForwardType = StoredType&&; using Unwrapped = decltype(Unwrap(std::declval<ForwardType>())); }; template <typename T> -struct TransformToUnwrappedTypeImpl<RepeatMode::Repeating, T> { +struct TransformToUnwrappedTypeImpl<false, T> { using StoredType = std::decay_t<T>; using ForwardType = const StoredType&; using Unwrapped = decltype(Unwrap(std::declval<ForwardType>())); @@ -85,40 +85,40 @@ // Transform |T| into `Unwrapped` type, which is passed to the target function. // Example: -// In repeat_mode == RepeatMode::Once case, +// In is_once == true case, // `int&&` -> `int&&`, // `const int&` -> `int&&`, // `OwnedWrapper<int>&` -> `int*&&`. -// In repeat_mode == RepeatMode::Repeating case, +// In is_once == false case, // `int&&` -> `const int&`, // `const int&` -> `const int&`, // `OwnedWrapper<int>&` -> `int* const &`. -template <RepeatMode repeat_mode, typename T> +template <bool is_once, typename T> using TransformToUnwrappedType = - typename TransformToUnwrappedTypeImpl<repeat_mode, T>::Unwrapped; + typename TransformToUnwrappedTypeImpl<is_once, T>::Unwrapped; // Transforms |Args| into `Unwrapped` types, and packs them into a TypeList. // If |is_method| is true, tries to dereference the first argument to support // smart pointers. -template <RepeatMode repeat_mode, bool is_method, typename... Args> +template <bool is_once, bool is_method, typename... Args> struct MakeUnwrappedTypeListImpl { - using Type = TypeList<TransformToUnwrappedType<repeat_mode, Args>...>; + using Type = TypeList<TransformToUnwrappedType<is_once, Args>...>; }; // Performs special handling for this pointers. // Example: // int* -> int*, // std::unique_ptr<int> -> int*. -template <RepeatMode repeat_mode, typename Receiver, typename... Args> -struct MakeUnwrappedTypeListImpl<repeat_mode, true, Receiver, Args...> { - using UnwrappedReceiver = TransformToUnwrappedType<repeat_mode, Receiver>; +template <bool is_once, typename Receiver, typename... Args> +struct MakeUnwrappedTypeListImpl<is_once, true, Receiver, Args...> { + using UnwrappedReceiver = TransformToUnwrappedType<is_once, Receiver>; using Type = TypeList<decltype(&*std::declval<UnwrappedReceiver>()), - TransformToUnwrappedType<repeat_mode, Args>...>; + TransformToUnwrappedType<is_once, Args>...>; }; -template <RepeatMode repeat_mode, bool is_method, typename... Args> +template <bool is_once, bool is_method, typename... Args> using MakeUnwrappedTypeList = - typename MakeUnwrappedTypeListImpl<repeat_mode, is_method, Args...>::Type; + typename MakeUnwrappedTypeListImpl<is_once, is_method, Args...>::Type; } // namespace internal @@ -139,8 +139,8 @@ using FunctorTraits = typename Helper::FunctorTraits; using BoundArgsList = typename Helper::BoundArgsList; using UnwrappedArgsList = - internal::MakeUnwrappedTypeList<internal::RepeatMode::Once, - FunctorTraits::is_method, Args&&...>; + internal::MakeUnwrappedTypeList<true, FunctorTraits::is_method, + Args&&...>; using BoundParamsList = typename Helper::BoundParamsList; static_assert(internal::AssertBindArgsValidity< std::make_index_sequence<Helper::num_bounds>, BoundArgsList, @@ -180,8 +180,8 @@ using FunctorTraits = typename Helper::FunctorTraits; using BoundArgsList = typename Helper::BoundArgsList; using UnwrappedArgsList = - internal::MakeUnwrappedTypeList<internal::RepeatMode::Repeating, - FunctorTraits::is_method, Args&&...>; + internal::MakeUnwrappedTypeList<false, FunctorTraits::is_method, + Args&&...>; using BoundParamsList = typename Helper::BoundParamsList; static_assert(internal::AssertBindArgsValidity< std::make_index_sequence<Helper::num_bounds>, BoundArgsList,
diff --git a/base/bind_helpers.h b/base/bind_helpers.h index 8e1c725..638cedd 100644 --- a/base/bind_helpers.h +++ b/base/bind_helpers.h
@@ -551,11 +551,19 @@ }; // Specialization for a nested bind. -template <typename Signature, - typename... BoundArgs, - internal::CopyMode copy_mode, - internal::RepeatMode repeat_mode> -struct CallbackCancellationTraits<Callback<Signature, copy_mode, repeat_mode>, +template <typename Signature, typename... BoundArgs> +struct CallbackCancellationTraits<OnceCallback<Signature>, + std::tuple<BoundArgs...>> { + static constexpr bool is_cancellable = true; + + template <typename Functor> + static bool IsCancelled(const Functor& functor, const BoundArgs&...) { + return functor.IsCancelled(); + } +}; + +template <typename Signature, typename... BoundArgs> +struct CallbackCancellationTraits<RepeatingCallback<Signature>, std::tuple<BoundArgs...>> { static constexpr bool is_cancellable = true;
diff --git a/base/bind_internal.h b/base/bind_internal.h index 756f890..c19f759 100644 --- a/base/bind_internal.h +++ b/base/bind_internal.h
@@ -225,10 +225,24 @@ } }; -// For Callbacks. -template <typename R, typename... Args, - CopyMode copy_mode, RepeatMode repeat_mode> -struct FunctorTraits<Callback<R(Args...), copy_mode, repeat_mode>> { +// For OnceCallbacks. +template <typename R, typename... Args> +struct FunctorTraits<OnceCallback<R(Args...)>> { + using RunType = R(Args...); + static constexpr bool is_method = false; + static constexpr bool is_nullable = true; + + template <typename CallbackType, typename... RunArgs> + static R Invoke(CallbackType&& callback, RunArgs&&... args) { + DCHECK(!callback.is_null()); + return std::forward<CallbackType>(callback).Run( + std::forward<RunArgs>(args)...); + } +}; + +// For RepeatingCallbacks. +template <typename R, typename... Args> +struct FunctorTraits<RepeatingCallback<R(Args...)>> { using RunType = R(Args...); static constexpr bool is_method = false; static constexpr bool is_nullable = true;
diff --git a/base/bind_unittest.nc b/base/bind_unittest.nc index cfdfe98..92b461f 100644 --- a/base/bind_unittest.nc +++ b/base/bind_unittest.nc
@@ -70,7 +70,7 @@ void VoidPolymorphic1(T t) { } -#if defined(NCTEST_METHOD_ON_CONST_OBJECT) // [r"fatal error: static_assert failed \"|Param| needs to be constructible from |Unwrapped| type\.\""] +#if defined(NCTEST_METHOD_ON_CONST_OBJECT) // [r"fatal error: static_assert failed \"\|Param\| needs to be constructible from \|Unwrapped\| type\."] // Method bound to const-object. // @@ -107,7 +107,7 @@ no_ref_const_cb.Run(); } -#elif defined(NCTEST_CONST_POINTER) // [r"fatal error: static_assert failed \"|Param| needs to be constructible from |Unwrapped| type\.\""] +#elif defined(NCTEST_CONST_POINTER) // [r"fatal error: static_assert failed \"\|Param\| needs to be constructible from \|Unwrapped\| type\."] // Const argument used with non-const pointer parameter of same type. // @@ -119,7 +119,7 @@ pointer_same_cb.Run(); } -#elif defined(NCTEST_CONST_POINTER_SUBTYPE) // [r"fatal error: static_assert failed \"|Param| needs to be constructible from |Unwrapped| type\.\""] +#elif defined(NCTEST_CONST_POINTER_SUBTYPE) // [r"fatal error: static_assert failed \"\|Param\| needs to be constructible from \|Unwrapped\| type\."] // Const argument used with non-const pointer parameter of super type. // @@ -148,7 +148,7 @@ ref_arg_cb.Run(p); } -#elif defined(NCTEST_DISALLOW_BIND_TO_NON_CONST_REF_PARAM) // [r"fatal error: static_assert failed \"|Param| needs to be constructible from |Unwrapped| type\.\""] +#elif defined(NCTEST_DISALLOW_BIND_TO_NON_CONST_REF_PARAM) // [r"fatal error: static_assert failed \"\|Param\| needs to be constructible from \|Unwrapped\| type\."] // Binding functions with reference parameters, unsupported. // @@ -159,7 +159,7 @@ ref_cb.Run(); } -#elif defined(NCTEST_NO_IMPLICIT_ARRAY_PTR_CONVERSION) // [r"fatal error: static_assert failed \"First bound argument to a method cannot be an array.\""] +#elif defined(NCTEST_NO_IMPLICIT_ARRAY_PTR_CONVERSION) // [r"fatal error: static_assert failed \"First bound argument to a method cannot be an array\.\""] // A method should not be bindable with an array of objects. // @@ -173,7 +173,7 @@ method_bound_to_array_cb.Run(); } -#elif defined(NCTEST_NO_RVALUE_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static_assert failed \"A parameter is a refcounted type and needs scoped_refptr.\""] +#elif defined(NCTEST_NO_RVALUE_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static_assert failed \"A parameter is a refcounted type and needs scoped_refptr\.\""] // Refcounted types should not be bound as a raw pointer. void WontCompile() { @@ -185,7 +185,7 @@ Bind(&VoidPolymorphic1<HasRef*>, &for_raw_ptr); } -#elif defined(NCTEST_NO_LVALUE_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static_assert failed \"A parameter is a refcounted type and needs scoped_refptr.\""] +#elif defined(NCTEST_NO_LVALUE_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static_assert failed \"A parameter is a refcounted type and needs scoped_refptr\.\""] // Refcounted types should not be bound as a raw pointer. void WontCompile() { @@ -194,7 +194,7 @@ Bind(&VoidPolymorphic1<HasRef*>, for_raw_ptr); } -#elif defined(NCTEST_NO_RVALUE_CONST_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static_assert failed \"A parameter is a refcounted type and needs scoped_refptr.\""] +#elif defined(NCTEST_NO_RVALUE_CONST_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static_assert failed \"A parameter is a refcounted type and needs scoped_refptr\.\""] // Refcounted types should not be bound as a raw pointer. void WontCompile() { @@ -203,7 +203,7 @@ Bind(&VoidPolymorphic1<const HasRef*>, &for_raw_ptr); } -#elif defined(NCTEST_NO_LVALUE_CONST_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static_assert failed \"A parameter is a refcounted type and needs scoped_refptr.\""] +#elif defined(NCTEST_NO_LVALUE_CONST_RAW_PTR_FOR_REFCOUNTED_TYPES) // [r"fatal error: static_assert failed \"A parameter is a refcounted type and needs scoped_refptr\.\""] // Refcounted types should not be bound as a raw pointer. void WontCompile() {
diff --git a/base/callback.h b/base/callback.h index d2a6228..043f72d 100644 --- a/base/callback.h +++ b/base/callback.h
@@ -19,62 +19,74 @@ namespace base { -namespace internal { - -template <typename From, typename To> -struct IsCallbackConvertible : std::false_type {}; - -template <typename Signature> -struct IsCallbackConvertible<RepeatingCallback<Signature>, - OnceCallback<Signature>> : std::true_type {}; - -} // namespace internal - -template <typename R, - typename... Args, - internal::CopyMode copy_mode, - internal::RepeatMode repeat_mode> -class Callback<R(Args...), copy_mode, repeat_mode> - : public internal::CallbackBase<copy_mode> { +template <typename R, typename... Args> +class OnceCallback<R(Args...)> : public internal::CallbackBase { public: - static_assert(repeat_mode != internal::RepeatMode::Once || - copy_mode == internal::CopyMode::MoveOnly, - "OnceCallback must be MoveOnly."); - using RunType = R(Args...); using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...); - Callback() : internal::CallbackBase<copy_mode>(nullptr) {} + OnceCallback() : internal::CallbackBase(nullptr) {} - explicit Callback(internal::BindStateBase* bind_state) - : internal::CallbackBase<copy_mode>(bind_state) { - } + explicit OnceCallback(internal::BindStateBase* bind_state) + : internal::CallbackBase(bind_state) {} - template < - typename OtherCallback, - typename = std::enable_if_t< - internal::IsCallbackConvertible<OtherCallback, Callback>::value>> - Callback(OtherCallback other) - : internal::CallbackBase<copy_mode>(std::move(other)) {} + OnceCallback(const OnceCallback&) = delete; + OnceCallback& operator=(const OnceCallback&) = delete; - template < - typename OtherCallback, - typename = std::enable_if_t< - internal::IsCallbackConvertible<OtherCallback, Callback>::value>> - Callback& operator=(OtherCallback other) { - static_cast<internal::CallbackBase<copy_mode>&>(*this) = std::move(other); + OnceCallback(OnceCallback&&) = default; + OnceCallback& operator=(OnceCallback&&) = default; + + OnceCallback(RepeatingCallback<RunType> other) + : internal::CallbackBase(std::move(other)) {} + + OnceCallback& operator=(RepeatingCallback<RunType> other) { + static_cast<internal::CallbackBase&>(*this) = std::move(other); return *this; } - bool Equals(const Callback& other) const { - return this->EqualsInternal(other); + bool Equals(const OnceCallback& other) const { return EqualsInternal(other); } + + R Run(Args... args) const & { + static_assert(!sizeof(*this), + "OnceCallback::Run() may only be invoked on a non-const " + "rvalue, i.e. std::move(callback).Run()."); + NOTREACHED(); + } + + R Run(Args... args) && { + // Move the callback instance into a local variable before the invocation, + // that ensures the internal state is cleared after the invocation. + // It's not safe to touch |this| after the invocation, since running the + // bound function may destroy |this|. + OnceCallback cb = std::move(*this); + PolymorphicInvoke f = + reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); + return f(cb.bind_state_.get(), std::forward<Args>(args)...); + } +}; + +template <typename R, typename... Args> +class RepeatingCallback<R(Args...)> : public internal::CallbackBaseCopyable { + public: + using RunType = R(Args...); + using PolymorphicInvoke = R (*)(internal::BindStateBase*, Args&&...); + + RepeatingCallback() : internal::CallbackBaseCopyable(nullptr) {} + + explicit RepeatingCallback(internal::BindStateBase* bind_state) + : internal::CallbackBaseCopyable(bind_state) {} + + // Copyable and movabl. + RepeatingCallback(const RepeatingCallback&) = default; + RepeatingCallback& operator=(const RepeatingCallback&) = default; + RepeatingCallback(RepeatingCallback&&) = default; + RepeatingCallback& operator=(RepeatingCallback&&) = default; + + bool Equals(const RepeatingCallback& other) const { + return EqualsInternal(other); } R Run(Args... args) const & { - static_assert(repeat_mode == internal::RepeatMode::Repeating, - "OnceCallback::Run() may only be invoked on a non-const " - "rvalue, i.e. std::move(callback).Run()."); - PolymorphicInvoke f = reinterpret_cast<PolymorphicInvoke>(this->polymorphic_invoke()); return f(this->bind_state_.get(), std::forward<Args>(args)...); @@ -85,7 +97,7 @@ // that ensures the internal state is cleared after the invocation. // It's not safe to touch |this| after the invocation, since running the // bound function may destroy |this|. - Callback cb = std::move(*this); + RepeatingCallback cb = std::move(*this); PolymorphicInvoke f = reinterpret_cast<PolymorphicInvoke>(cb.polymorphic_invoke()); return f(cb.bind_state_.get(), std::forward<Args>(args)...);
diff --git a/base/callback_forward.h b/base/callback_forward.h index 13eed0e..f1851c4 100644 --- a/base/callback_forward.h +++ b/base/callback_forward.h
@@ -6,42 +6,21 @@ #define BASE_CALLBACK_FORWARD_H_ namespace base { -namespace internal { -// CopyMode is used to control the copyablity of a Callback. -// MoveOnly indicates the Callback is not copyable but movable, and Copyable -// indicates it is copyable and movable. -enum class CopyMode { - MoveOnly, - Copyable, -}; +template <typename Signature> +class OnceCallback; -enum class RepeatMode { - Once, - Repeating, -}; +template <typename Signature> +class RepeatingCallback; -} // namespace internal - -template <typename Signature, - internal::CopyMode copy_mode = internal::CopyMode::Copyable, - internal::RepeatMode repeat_mode = internal::RepeatMode::Repeating> -class Callback; +template <typename Signature> +using Callback = RepeatingCallback<Signature>; // Syntactic sugar to make Callback<void()> easier to declare since it // will be used in a lot of APIs with delayed execution. -using Closure = Callback<void()>; - -template <typename Signature> -using OnceCallback = Callback<Signature, - internal::CopyMode::MoveOnly, - internal::RepeatMode::Once>; -template <typename Signature> -using RepeatingCallback = Callback<Signature, - internal::CopyMode::Copyable, - internal::RepeatMode::Repeating>; using OnceClosure = OnceCallback<void()>; using RepeatingClosure = RepeatingCallback<void()>; +using Closure = Callback<void()>; } // namespace base
diff --git a/base/callback_helpers.h b/base/callback_helpers.h index 0cba0fd..2a9f7f4 100644 --- a/base/callback_helpers.h +++ b/base/callback_helpers.h
@@ -25,12 +25,9 @@ namespace base { -template <typename Signature, - internal::CopyMode copy_mode, - internal::RepeatMode repeat_mode> -Callback<Signature, copy_mode, repeat_mode> ResetAndReturn( - Callback<Signature, copy_mode, repeat_mode>* cb) { - Callback<Signature, copy_mode, repeat_mode> ret(std::move(*cb)); +template <typename CallbackType> +CallbackType ResetAndReturn(CallbackType* cb) { + CallbackType ret(std::move(*cb)); DCHECK(!*cb); return ret; }
diff --git a/base/callback_internal.cc b/base/callback_internal.cc index a760f06..864c1a0 100644 --- a/base/callback_internal.cc +++ b/base/callback_internal.cc
@@ -33,73 +33,61 @@ destructor_(destructor), is_cancelled_(is_cancelled) {} -CallbackBase<CopyMode::MoveOnly>::CallbackBase(CallbackBase&& c) = default; - -CallbackBase<CopyMode::MoveOnly>& -CallbackBase<CopyMode::MoveOnly>::operator=(CallbackBase&& c) = default; - -CallbackBase<CopyMode::MoveOnly>::CallbackBase( - const CallbackBase<CopyMode::Copyable>& c) +CallbackBase::CallbackBase(CallbackBase&& c) = default; +CallbackBase& CallbackBase::operator=(CallbackBase&& c) = default; +CallbackBase::CallbackBase(const CallbackBaseCopyable& c) : bind_state_(c.bind_state_) {} -CallbackBase<CopyMode::MoveOnly>& CallbackBase<CopyMode::MoveOnly>::operator=( - const CallbackBase<CopyMode::Copyable>& c) { +CallbackBase& CallbackBase::operator=(const CallbackBaseCopyable& c) { bind_state_ = c.bind_state_; return *this; } -CallbackBase<CopyMode::MoveOnly>::CallbackBase( - CallbackBase<CopyMode::Copyable>&& c) +CallbackBase::CallbackBase(CallbackBaseCopyable&& c) : bind_state_(std::move(c.bind_state_)) {} -CallbackBase<CopyMode::MoveOnly>& CallbackBase<CopyMode::MoveOnly>::operator=( - CallbackBase<CopyMode::Copyable>&& c) { +CallbackBase& CallbackBase::operator=(CallbackBaseCopyable&& c) { bind_state_ = std::move(c.bind_state_); return *this; } -void CallbackBase<CopyMode::MoveOnly>::Reset() { +void CallbackBase::Reset() { // NULL the bind_state_ last, since it may be holding the last ref to whatever // object owns us, and we may be deleted after that. bind_state_ = nullptr; } -bool CallbackBase<CopyMode::MoveOnly>::IsCancelled() const { +bool CallbackBase::IsCancelled() const { DCHECK(bind_state_); return bind_state_->IsCancelled(); } -bool CallbackBase<CopyMode::MoveOnly>::EqualsInternal( - const CallbackBase& other) const { +bool CallbackBase::EqualsInternal(const CallbackBase& other) const { return bind_state_ == other.bind_state_; } -CallbackBase<CopyMode::MoveOnly>::CallbackBase(BindStateBase* bind_state) +CallbackBase::CallbackBase(BindStateBase* bind_state) : bind_state_(bind_state ? AdoptRef(bind_state) : nullptr) { DCHECK(!bind_state_.get() || bind_state_->HasOneRef()); } -CallbackBase<CopyMode::MoveOnly>::~CallbackBase() {} +CallbackBase::~CallbackBase() {} -CallbackBase<CopyMode::Copyable>::CallbackBase( - const CallbackBase& c) - : CallbackBase<CopyMode::MoveOnly>(nullptr) { +CallbackBaseCopyable::CallbackBaseCopyable(const CallbackBaseCopyable& c) + : CallbackBase(nullptr) { bind_state_ = c.bind_state_; } -CallbackBase<CopyMode::Copyable>::CallbackBase(CallbackBase&& c) = default; +CallbackBaseCopyable::CallbackBaseCopyable(CallbackBaseCopyable&& c) = default; -CallbackBase<CopyMode::Copyable>& -CallbackBase<CopyMode::Copyable>::operator=(const CallbackBase& c) { +CallbackBaseCopyable& CallbackBaseCopyable::operator=( + const CallbackBaseCopyable& c) { bind_state_ = c.bind_state_; return *this; } -CallbackBase<CopyMode::Copyable>& -CallbackBase<CopyMode::Copyable>::operator=(CallbackBase&& c) = default; - -template class CallbackBase<CopyMode::MoveOnly>; -template class CallbackBase<CopyMode::Copyable>; +CallbackBaseCopyable& CallbackBaseCopyable::operator=( + CallbackBaseCopyable&& c) = default; } // namespace internal } // namespace base
diff --git a/base/callback_internal.h b/base/callback_internal.h index 29b07c2..8ad8449 100644 --- a/base/callback_internal.h +++ b/base/callback_internal.h
@@ -19,8 +19,8 @@ namespace internal { -template <CopyMode copy_mode> class CallbackBase; +class CallbackBaseCopyable; class BindStateBase; @@ -61,8 +61,8 @@ friend struct BindStateBaseRefCountTraits; friend class RefCountedThreadSafe<BindStateBase, BindStateBaseRefCountTraits>; - template <CopyMode copy_mode> friend class CallbackBase; + friend class CallbackBaseCopyable; // Whitelist subclasses that access the destructor of BindStateBase. template <typename Functor, typename... BoundArgs> @@ -90,17 +90,16 @@ // template bloat. // CallbackBase<MoveOnly> is a direct base class of MoveOnly callbacks, and // CallbackBase<Copyable> uses CallbackBase<MoveOnly> for its implementation. -template <> -class BASE_EXPORT CallbackBase<CopyMode::MoveOnly> { +class BASE_EXPORT CallbackBase { public: CallbackBase(CallbackBase&& c); CallbackBase& operator=(CallbackBase&& c); - explicit CallbackBase(const CallbackBase<CopyMode::Copyable>& c); - CallbackBase& operator=(const CallbackBase<CopyMode::Copyable>& c); + explicit CallbackBase(const CallbackBaseCopyable& c); + CallbackBase& operator=(const CallbackBaseCopyable& c); - explicit CallbackBase(CallbackBase<CopyMode::Copyable>&& c); - CallbackBase& operator=(CallbackBase<CopyMode::Copyable>&& c); + explicit CallbackBase(CallbackBaseCopyable&& c); + CallbackBase& operator=(CallbackBaseCopyable&& c); // Returns true if Callback is null (doesn't refer to anything). bool is_null() const { return !bind_state_; } @@ -136,22 +135,18 @@ }; // CallbackBase<Copyable> is a direct base class of Copyable Callbacks. -template <> -class BASE_EXPORT CallbackBase<CopyMode::Copyable> - : public CallbackBase<CopyMode::MoveOnly> { +class BASE_EXPORT CallbackBaseCopyable : public CallbackBase { public: - CallbackBase(const CallbackBase& c); - CallbackBase(CallbackBase&& c); - CallbackBase& operator=(const CallbackBase& c); - CallbackBase& operator=(CallbackBase&& c); - protected: - explicit CallbackBase(BindStateBase* bind_state) - : CallbackBase<CopyMode::MoveOnly>(bind_state) {} - ~CallbackBase() {} -}; + CallbackBaseCopyable(const CallbackBaseCopyable& c); + CallbackBaseCopyable(CallbackBaseCopyable&& c); + CallbackBaseCopyable& operator=(const CallbackBaseCopyable& c); + CallbackBaseCopyable& operator=(CallbackBaseCopyable&& c); -extern template class CallbackBase<CopyMode::MoveOnly>; -extern template class CallbackBase<CopyMode::Copyable>; + protected: + explicit CallbackBaseCopyable(BindStateBase* bind_state) + : CallbackBase(bind_state) {} + ~CallbackBaseCopyable() {} +}; } // namespace internal } // namespace base
diff --git a/base/callback_unittest.nc b/base/callback_unittest.nc index 710362a2..3261529 100644 --- a/base/callback_unittest.nc +++ b/base/callback_unittest.nc
@@ -15,7 +15,7 @@ class Child : Parent { }; -#if defined(NCTEST_EQUALS_REQUIRES_SAMETYPE) // [r"fatal error: no viable conversion from 'Callback<int \(\), \[2 \* \.\.\.\]>' to 'const Callback<void \(\), \[2 \* \.\.\.\]>'"] +#if defined(NCTEST_EQUALS_REQUIRES_SAMETYPE) // [r"fatal error: no viable conversion from 'RepeatingCallback<int \(\)>' to 'const RepeatingCallback<void \(\)>'"] // Attempting to call comparison function on two callbacks of different type. //
diff --git a/base/message_loop/message_pump_android.cc b/base/message_loop/message_pump_android.cc index 4be8899..5326658 100644 --- a/base/message_loop/message_pump_android.cc +++ b/base/message_loop/message_pump_android.cc
@@ -117,11 +117,8 @@ namespace base { -MessagePumpForUI::MessagePumpForUI() - : run_loop_(nullptr), should_abort_(false) {} - -MessagePumpForUI::~MessagePumpForUI() { -} +MessagePumpForUI::MessagePumpForUI() = default; +MessagePumpForUI::~MessagePumpForUI() = default; void MessagePumpForUI::Run(Delegate* delegate) { NOTREACHED() << "UnitTests should rely on MessagePumpForUIStub in" @@ -129,6 +126,7 @@ } JNIEnv* MessagePumpForUI::StartInternal() { + DCHECK(!quit_); run_loop_ = new RunLoop(); // Since the RunLoop was just created above, BeforeRun should be guaranteed to // return true (it only returns false if the RunLoop has been Quit already). @@ -159,6 +157,7 @@ } void MessagePumpForUI::Quit() { + quit_ = true; if (!system_message_handler_obj_.is_null()) { JNIEnv* env = base::android::AttachCurrentThread(); DCHECK(env); @@ -176,6 +175,8 @@ } void MessagePumpForUI::ScheduleWork() { + if (quit_) + return; DCHECK(!system_message_handler_obj_.is_null()); JNIEnv* env = base::android::AttachCurrentThread(); @@ -185,6 +186,8 @@ } void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) { + if (quit_) + return; DCHECK(!system_message_handler_obj_.is_null()); JNIEnv* env = base::android::AttachCurrentThread();
diff --git a/base/message_loop/message_pump_android.h b/base/message_loop/message_pump_android.h index 895d213..3c8ac654 100644 --- a/base/message_loop/message_pump_android.h +++ b/base/message_loop/message_pump_android.h
@@ -50,9 +50,10 @@ private: JNIEnv* StartInternal(); - RunLoop* run_loop_; + RunLoop* run_loop_ = nullptr; base::android::ScopedJavaGlobalRef<jobject> system_message_handler_obj_; - bool should_abort_; + bool should_abort_ = false; + bool quit_ = false; DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI); };
diff --git a/base/synchronization/waitable_event_mac.cc b/base/synchronization/waitable_event_mac.cc index 3054a179..382c1d1b 100644 --- a/base/synchronization/waitable_event_mac.cc +++ b/base/synchronization/waitable_event_mac.cc
@@ -4,13 +4,16 @@ #include "base/synchronization/waitable_event.h" +#include <dispatch/dispatch.h> #include <mach/mach.h> #include <sys/event.h> #include "base/debug/activity_tracker.h" #include "base/files/scoped_file.h" +#include "base/mac/dispatch_source_mach.h" #include "base/mac/mac_util.h" #include "base/mac/mach_logging.h" +#include "base/mac/scoped_dispatch_object.h" #include "base/posix/eintr_wrapper.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" @@ -169,16 +172,24 @@ // On macOS 10.11+, using Mach port sets may cause system instability, per // https://crbug.com/756102. On macOS 10.12+, a kqueue can be used - // instead to work around that. But on macOS 10.9-10.11, kqueue only works - // for port sets. On those platforms, port sets are just used directly. This - // does leave 10.11 susceptible to instability, though. - // TODO(rsesek): See if a libdispatch solution works on 10.11. + // instead to work around that. On macOS 10.9 and 10.10, kqueue only works + // for port sets, so port sets are just used directly. On macOS 10.11, + // libdispatch sources are used. Therefore, there are three different + // primitives that can be used to implement WaitMany. Which one to use is + // selected at run-time by OS version checks. + enum WaitManyPrimitive { + KQUEUE, + DISPATCH, + PORT_SET, + }; #if defined(OS_IOS) - const bool use_kqueue = false; + const WaitManyPrimitive kPrimitive = PORT_SET; #else - const bool use_kqueue = mac::IsAtLeastOS10_12(); + const WaitManyPrimitive kPrimitive = + mac::IsAtLeastOS10_12() ? KQUEUE + : (mac::IsOS10_11() ? DISPATCH : PORT_SET); #endif - if (use_kqueue) { + if (kPrimitive == KQUEUE) { std::vector<kevent64_s> events(count); for (size_t i = 0; i < count; ++i) { EV_SET64(&events[i], raw_waitables[i]->receive_right_->Name(), @@ -208,7 +219,54 @@ } return triggered; + } else if (kPrimitive == DISPATCH) { + // Each item in |raw_waitables| will be watched using a dispatch souce + // scheduled on the serial |queue|. The first one to be invoked will + // signal the |semaphore| that this method will wait on. + ScopedDispatchObject<dispatch_queue_t> queue(dispatch_queue_create( + "org.chromium.base.WaitableEvent.WaitMany", DISPATCH_QUEUE_SERIAL)); + ScopedDispatchObject<dispatch_semaphore_t> semaphore( + dispatch_semaphore_create(0)); + + // Block capture references. |signaled| will identify the index in + // |raw_waitables| whose source was invoked. + dispatch_semaphore_t semaphore_ref = semaphore.get(); + const size_t kUnsignaled = -1; + __block size_t signaled = kUnsignaled; + + // Create a MACH_RECV dispatch source for each event. These must be + // destroyed before the |queue| and |semaphore|. + std::vector<std::unique_ptr<DispatchSourceMach>> sources; + for (size_t i = 0; i < count; ++i) { + const bool auto_reset = + raw_waitables[i]->policy_ == WaitableEvent::ResetPolicy::AUTOMATIC; + // The block will copy a reference to |right|. + scoped_refptr<WaitableEvent::ReceiveRight> right = + raw_waitables[i]->receive_right_; + auto source = + std::make_unique<DispatchSourceMach>(queue, right->Name(), ^{ + // After the semaphore is signaled, another event be signaled and + // the source may have its block put on the |queue|. WaitMany + // should only report (and auto-reset) one event, so the first + // event to signal is reported. + if (signaled == kUnsignaled) { + signaled = i; + if (auto_reset) { + PeekPort(right->Name(), true); + } + dispatch_semaphore_signal(semaphore_ref); + } + }); + source->Resume(); + sources.push_back(std::move(source)); + } + + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + DCHECK_NE(signaled, kUnsignaled); + return signaled; } else { + DCHECK_EQ(kPrimitive, PORT_SET); + kern_return_t kr; mac::ScopedMachPortSet port_set;
diff --git a/build/android/apk_operations.py b/build/android/apk_operations.py index d861b5e..e543fd3b 100755 --- a/build/android/apk_operations.py +++ b/build/android/apk_operations.py
@@ -836,12 +836,12 @@ constants.SetOutputDirectory(output_directory) devil_chromium.Initialize(output_directory=output_directory) parser = argparse.ArgumentParser() + exists_or_None = lambda p: p if p and os.path.exists(p) else None parser.set_defaults( command_line_flags_file=command_line_flags_file, target_cpu=target_cpu, - apk_path=apk_path if os.path.exists(apk_path) else None, - incremental_json=( - incremental_json if os.path.exists(incremental_json) else None)) + apk_path=exists_or_None(apk_path), + incremental_json=exists_or_None(incremental_json)) _RunInternal(parser, output_directory=output_directory)
diff --git a/build/android/gyp/aar.py b/build/android/gyp/aar.py index 6c0bc89..e8196e5a 100755 --- a/build/android/gyp/aar.py +++ b/build/android/gyp/aar.py
@@ -38,76 +38,97 @@ return True +def _CreateInfo(aar_file): + data = {} + data['aidl'] = [] + data['assets'] = [] + data['resources'] = [] + data['subjars'] = [] + data['subjar_tuples'] = [] + data['has_classes_jar'] = False + data['has_proguard_flags'] = False + data['has_native_libraries'] = False + data['has_r_text_file'] = False + with zipfile.ZipFile(aar_file) as z: + data['is_manifest_empty'] = ( + _IsManifestEmpty(z.read('AndroidManifest.xml'))) + + for name in z.namelist(): + if name.endswith('/'): + continue + if name.startswith('aidl/'): + data['aidl'].append(name) + elif name.startswith('res/'): + data['resources'].append(name) + elif name.startswith('libs/') and name.endswith('.jar'): + label = posixpath.basename(name)[:-4] + label = re.sub(r'[^a-zA-Z0-9._]', '_', label) + data['subjars'].append(name) + data['subjar_tuples'].append([label, name]) + elif name.startswith('assets/'): + data['assets'].append(name) + elif name.startswith('jni/'): + data['has_native_libraries'] = True + elif name == 'classes.jar': + data['has_classes_jar'] = True + elif name == 'proguard.txt': + data['has_proguard_flags'] = True + elif name == 'R.txt': + # Some AARs, e.g. gvr_controller_java, have empty R.txt. Such AARs + # have no resources as well. We treat empty R.txt as having no R.txt. + data['has_r_text_file'] = (z.read('R.txt').strip() != '') + + return """\ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +""" + gn_helpers.ToGNString(data) + + +def _AddCommonArgs(parser): + parser.add_argument('aar_file', + help='Path to the AAR file.', + type=os.path.normpath) + + def main(): parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('--input-file', - help='Path to the AAR file.', - required=True, - metavar='FILE') - parser.add_argument('--extract', - help='Extract the files to output directory.', - action='store_true') - parser.add_argument('--list', - help='List all the resource and jar files.', - action='store_true') - parser.add_argument('--output-dir', - help='Output directory for the extracted files. Must ' - 'be set if --extract is set.', - metavar='DIR') + command_parsers = parser.add_subparsers(dest='command') + subp = command_parsers.add_parser( + 'list', help='Output a GN scope describing the contents of the .aar.') + _AddCommonArgs(subp) + subp.add_argument('--output', + help='Output file.', + type=argparse.FileType('w'), + default='-') + + subp = command_parsers.add_parser('extract', help='Extracts the .aar') + _AddCommonArgs(subp) + subp.add_argument('--output-dir', + help='Output directory for the extracted files.', + required=True, + type=os.path.normpath) + subp.add_argument('--assert-info-file', + help='Path to .info file. Asserts that it matches what ' + '"list" would output.', + type=argparse.FileType('r')) args = parser.parse_args() - if not args.extract and not args.list: - parser.error('Either --extract or --list has to be specified.') - aar_file = args.input_file - output_dir = args.output_dir - - if args.extract: + if args.command == 'extract': + if args.assert_info_file: + expected = _CreateInfo(args.aar_file) + actual = args.assert_info_file.read() + if actual != expected: + raise Exception('android_aar_prebuilt() cached .info file is ' + 'out-of-date. Run gn gen with ' + 'update_android_aar_prebuilts=true to update it.') # Clear previously extracted versions of the AAR. - shutil.rmtree(output_dir, True) - build_utils.ExtractAll(aar_file, path=output_dir) + shutil.rmtree(args.output_dir, True) + build_utils.ExtractAll(args.aar_file, path=args.output_dir) - if args.list: - data = {} - data['aidl'] = [] - data['assets'] = [] - data['resources'] = [] - data['subjars'] = [] - data['subjar_tuples'] = [] - data['has_classes_jar'] = False - data['has_proguard_flags'] = False - data['has_native_libraries'] = False - data['has_r_text_file'] = False - with zipfile.ZipFile(aar_file) as z: - data['is_manifest_empty'] = ( - _IsManifestEmpty(z.read('AndroidManifest.xml'))) - - for name in z.namelist(): - if name.endswith('/'): - continue - if name.startswith('aidl/'): - data['aidl'].append(name) - elif name.startswith('res/'): - data['resources'].append(name) - elif name.startswith('libs/') and name.endswith('.jar'): - label = posixpath.basename(name)[:-4] - label = re.sub(r'[^a-zA-Z0-9._]', '_', label) - data['subjars'].append(name) - data['subjar_tuples'].append([label, name]) - elif name.startswith('assets/'): - data['assets'].append(name) - elif name.startswith('jni/'): - data['has_native_libraries'] = True - elif name == 'classes.jar': - data['has_classes_jar'] = True - elif name == 'proguard.txt': - data['has_proguard_flags'] = True - elif name == 'R.txt': - # Some AARs, e.g. gvr_controller_java, have empty R.txt. Such AARs - # have no resources as well. We treat empty R.txt as having no R.txt. - data['has_r_text_file'] = (z.read('R.txt').strip() != '') - - print gn_helpers.ToGNString(data) + elif args.command == 'list': + args.output.write(_CreateInfo(args.aar_file)) if __name__ == '__main__':
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py index 42ae442..367aa2f 100644 --- a/build/android/pylib/instrumentation/instrumentation_test_instance.py +++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -159,8 +159,10 @@ if 'stack' in bundle: if symbolizer and device_abi: current_result.SetLog( - '\n'.join(symbolizer.ExtractAndResolveNativeStackTraces( - bundle['stack'], device_abi))) + '%s\n%s' % ( + bundle['stack'], + '\n'.join(symbolizer.ExtractAndResolveNativeStackTraces( + bundle['stack'], device_abi)))) else: current_result.SetLog(bundle['stack'])
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index 6723744..35fab78 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -164,6 +164,10 @@ # Ex. with this arg set to true, the chrome_public_apk target result in # chrome_public_apk_incremental being built. incremental_apk_by_default = false + + # When true, updates all android_aar_prebuilt() .info files during gn gen. + # Refer to android_aar_prebuilt() for more details. + update_android_aar_prebuilts = false } # We need a second declare_args block to make sure we are using the overridden
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 429bc32..27ba696e 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2934,22 +2934,33 @@ # resources. For libraries without resources, it will not generate # corresponding android_resources targets. # + # To avoid slowing down "gn gen", an associated .info file must be committed + # along with the .aar file. In order to create this file, define the target + # and then run once with the gn arg "update_android_aar_prebuilts = true". + # # Variables # aar_path: Path to the AAR. + # info_path: Path to the .aar.info file (generated via + # update_android_aar_prebuilts GN arg). # proguard_configs: List of proguard configs to use in final apk step for - # any apk that depends on this library. + # any apk that depends on this library. # ignore_aidl: Whether to ignore .aidl files found with the .aar. # ignore_assets: Whether to ignore assets found in the .aar. # ignore_native_libraries: Whether to ignore .so files found in the .aar. # create_srcjar: If false, does not create an R.java file. # TODO(jbudorick@): remove this arguments after crbug.com/522043 is fixed. - # requires_android: Whether this target can only be used for compiling Android related targets. + # requires_android: Whether this target can only be used for compiling + # Android related targets. # # Example # android_aar_prebuilt("foo_java") { # aar_path = "foo.aar" # } template("android_aar_prebuilt") { + _info_path = "$target_name.info" + if (defined(invoker.info_path)) { + _info_path = invoker.info_path + } _output_path = "${target_gen_dir}/${target_name}" _unpack_target_name = "${target_name}__unpack_aar" _ignore_aidl = defined(invoker.ignore_aidl) && invoker.ignore_aidl @@ -2959,14 +2970,17 @@ # Scan the AAR file and determine the resources and jar files. # Some libraries might not have resources; others might have two jars. - _scanned_files = - exec_script("//build/android/gyp/aar.py", - [ - "--input-file", - rebase_path(invoker.aar_path, root_build_dir), - "--list", - ], - "scope") + if (update_android_aar_prebuilts) { + print("Writing " + rebase_path(_info_path, "//")) + exec_script("//build/android/gyp/aar.py", + [ + "list", + rebase_path(invoker.aar_path, root_build_dir), + "--output", + rebase_path(_info_path, root_build_dir), + ]) + } + _scanned_files = read_file(_info_path, "scope") assert(_ignore_aidl || _scanned_files.aidl == [], "android_aar_prebuilt() aidl not yet supported." + @@ -2984,11 +2998,12 @@ action(_unpack_target_name) { script = "//build/android/gyp/aar.py" # Unzips the AAR args = [ - "--input-file", + "extract", rebase_path(invoker.aar_path, root_build_dir), "--output-dir", rebase_path(_output_path, root_build_dir), - "--extract", + "--assert-info-file", + rebase_path(_info_path, root_build_dir), ] inputs = [ invoker.aar_path,
diff --git a/build/secondary/third_party/android_tools/BUILD.gn b/build/secondary/third_party/android_tools/BUILD.gn index e9e7058..58a851c 100644 --- a/build/secondary/third_party/android_tools/BUILD.gn +++ b/build/secondary/third_party/android_tools/BUILD.gn
@@ -59,6 +59,7 @@ ] _lib_name = "design" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_transition_java") { @@ -67,10 +68,12 @@ ] _lib_name = "transition" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_multidex_java") { aar_path = "$lib_path/multidex/1.0.1/multidex-1.0.1.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_java_prebuilt("android_support_annotations_java") { @@ -94,6 +97,7 @@ ] _lib_name = "support-compat" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" ignore_aidl = true # We don't appear to need these currently. } @@ -103,6 +107,7 @@ ] _lib_name = "support-core-ui" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_core_utils_java") { @@ -111,6 +116,7 @@ ] _lib_name = "support-core-utils" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_fragment_java") { @@ -122,6 +128,7 @@ ] _lib_name = "support-fragment" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_media_compat_java") { @@ -130,6 +137,7 @@ ] _lib_name = "support-media-compat" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" ignore_aidl = true # We don't appear to need these currently. } @@ -139,6 +147,7 @@ ] _lib_name = "support-v13" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_vector_drawable_java") { @@ -147,6 +156,7 @@ ] _lib_name = "support-vector-drawable" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_v7_appcompat_java_internal") { @@ -155,6 +165,7 @@ ] _lib_name = "appcompat-v7" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } java_group("android_support_v7_appcompat_java") { @@ -172,6 +183,7 @@ ] _lib_name = "gridlayout-v7" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_v7_mediarouter_java") { @@ -181,6 +193,7 @@ ] _lib_name = "mediarouter-v7" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_v7_recyclerview_java") { @@ -191,6 +204,7 @@ ] _lib_name = "recyclerview-v7" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_v7_palette_java") { @@ -200,6 +214,7 @@ ] _lib_name = "palette-v7" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_v7_preference_java") { @@ -210,6 +225,7 @@ ] _lib_name = "preference-v7" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_v14_preference_java") { @@ -221,6 +237,7 @@ ] _lib_name = "preference-v14" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_v17_leanback_java") { @@ -230,6 +247,7 @@ ] _lib_name = "leanback-v17" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("android_support_v17_preference_java") { @@ -243,6 +261,7 @@ ] _lib_name = "preference-leanback-v17" aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_library("android_support_chromium_java") { @@ -282,6 +301,7 @@ ] _lib_name = "play-services-basement" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" input_jars_paths = [ "$android_sdk/optional/org.apache.http.legacy.jar" ] } @@ -291,6 +311,7 @@ ] _lib_name = "play-services-tasks" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_base_java") { @@ -301,6 +322,7 @@ ] _lib_name = "play-services-base" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_auth_base_java") { @@ -310,6 +332,7 @@ ] _lib_name = "play-services-auth-base" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_auth_java") { @@ -320,6 +343,7 @@ ] _lib_name = "play-services-auth" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_cast_java") { @@ -330,6 +354,7 @@ ] _lib_name = "play-services-cast" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_iid_java") { @@ -339,6 +364,7 @@ ] _lib_name = "play-services-iid" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_gcm_java") { @@ -349,6 +375,7 @@ ] _lib_name = "play-services-gcm" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_location_java") { @@ -358,6 +385,7 @@ ] _lib_name = "play-services-location" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_nearby_java") { @@ -367,6 +395,7 @@ ] _lib_name = "play-services-nearby" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } android_aar_prebuilt("google_play_services_vision_java") { @@ -376,6 +405,7 @@ ] _lib_name = "play-services-vision" aar_path = "$gms_path/$_lib_name/$gms_version/$_lib_name-$gms_version.aar" + info_path = "//build/secondary/third_party/android_tools/$target_name.info" } # TODO(paulmiller): Replace this with a proper target after rolling to a GMS
diff --git a/build/secondary/third_party/android_tools/android_support_compat_java.info b/build/secondary/third_party/android_tools/android_support_compat_java.info new file mode 100644 index 0000000..b68ec40 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_compat_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ "aidl/android/support/v4/os/ResultReceiver.aidl" ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ [ "internal_impl_25.0.1", "libs/internal_impl-25.0.1.jar" ] ] +subjars = [ "libs/internal_impl-25.0.1.jar" ]
diff --git a/build/secondary/third_party/android_tools/android_support_core_ui_java.info b/build/secondary/third_party/android_tools/android_support_core_ui_java.info new file mode 100644 index 0000000..5f0071dd --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_core_ui_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ [ "internal_impl_25.0.1", "libs/internal_impl-25.0.1.jar" ] ] +subjars = [ "libs/internal_impl-25.0.1.jar" ]
diff --git a/build/secondary/third_party/android_tools/android_support_core_utils_java.info b/build/secondary/third_party/android_tools/android_support_core_utils_java.info new file mode 100644 index 0000000..d82eb75 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_core_utils_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ [ "internal_impl_25.0.1", "libs/internal_impl-25.0.1.jar" ] ] +subjars = [ "libs/internal_impl-25.0.1.jar" ]
diff --git a/build/secondary/third_party/android_tools/android_support_design_java.info b/build/secondary/third_party/android_tools/android_support_design_java.info new file mode 100644 index 0000000..37e2270 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_design_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/drawable-v21/design_bottom_navigation_item_background.xml", "res/values-v21/values-v21.xml", "res/anim-v21/design_bottom_sheet_slide_out.xml", "res/anim-v21/design_appbar_state_list_animator.xml", "res/anim-v21/design_bottom_sheet_slide_in.xml", "res/anim/design_fab_out.xml", "res/anim/design_bottom_sheet_slide_out.xml", "res/anim/design_snackbar_in.xml", "res/anim/design_fab_in.xml", "res/anim/design_snackbar_out.xml", "res/anim/design_bottom_sheet_slide_in.xml", "res/layout/design_layout_tab_text.xml", "res/layout/design_navigation_item_separator.xml", "res/layout/design_bottom_sheet_dialog.xml", "res/layout/design_layout_snackbar_include.xml", "res/layout/design_text_input_password_icon.xml", "res/layout/design_navigation_menu_item.xml", "res/layout/design_menu_item_action_area.xml", "res/layout/design_navigation_item.xml", "res/layout/design_navigation_item_header.xml", "res/layout/design_layout_snackbar.xml", "res/layout/design_navigation_item_subheader.xml", "res/layout/design_navigation_menu.xml", "res/layout/design_layout_tab_icon.xml", "res/layout/design_bottom_navigation_item.xml", "res/values-sw600dp-v13/values-sw600dp-v13.xml", "res/values-land/values-land.xml", "res/color-v23/design_tint_password_toggle.xml", "res/values/values.xml", "res/layout-sw600dp-v13/design_layout_snackbar.xml", "res/color/design_error.xml", "res/color/design_tint_password_toggle.xml", "res/drawable/design_snackbar_background.xml", "res/drawable/design_fab_background.xml", "res/drawable/design_bottom_navigation_item_background.xml", "res/drawable/design_ic_visibility.xml", "res/drawable/navigation_empty_icon.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_fragment_java.info b/build/secondary/third_party/android_tools/android_support_fragment_java.info new file mode 100644 index 0000000..d82eb75 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_fragment_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ [ "internal_impl_25.0.1", "libs/internal_impl-25.0.1.jar" ] ] +subjars = [ "libs/internal_impl-25.0.1.jar" ]
diff --git a/build/secondary/third_party/android_tools/android_support_media_compat_java.info b/build/secondary/third_party/android_tools/android_support_media_compat_java.info new file mode 100644 index 0000000..347df34 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_media_compat_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ "aidl/android/support/v4/media/session/MediaSessionCompat.aidl", "aidl/android/support/v4/media/session/PlaybackStateCompat.aidl", "aidl/android/support/v4/media/session/ParcelableVolumeInfo.aidl", "aidl/android/support/v4/media/RatingCompat.aidl", "aidl/android/support/v4/media/MediaMetadataCompat.aidl" ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ [ "internal_impl_25.0.1", "libs/internal_impl-25.0.1.jar" ] ] +subjars = [ "libs/internal_impl-25.0.1.jar" ]
diff --git a/build/secondary/third_party/android_tools/android_support_multidex_java.info b/build/secondary/third_party/android_tools/android_support_multidex_java.info new file mode 100644 index 0000000..a2ebd4a --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_multidex_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_transition_java.info b/build/secondary/third_party/android_tools/android_support_transition_java.info new file mode 100644 index 0000000..28c8330 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_transition_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/values/values.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_v13_java.info b/build/secondary/third_party/android_tools/android_support_v13_java.info new file mode 100644 index 0000000..d82eb75 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v13_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ [ "internal_impl_25.0.1", "libs/internal_impl-25.0.1.jar" ] ] +subjars = [ "libs/internal_impl-25.0.1.jar" ]
diff --git a/build/secondary/third_party/android_tools/android_support_v14_preference_java.info b/build/secondary/third_party/android_tools/android_support_v14_preference_java.info new file mode 100644 index 0000000..e7f9be67 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v14_preference_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/layout-v17/preference_material.xml", "res/layout-v17/preference_information_material.xml", "res/layout-v17/preference_category_material.xml", "res/layout-v17/preference_dropdown_material.xml", "res/values-v17/values-v17.xml", "res/layout/preference_material.xml", "res/layout/preference_information_material.xml", "res/layout/preference_category_material.xml", "res/layout/preference_dropdown_material.xml", "res/layout/preference_widget_switch.xml", "res/values/values.xml", "res/layout-v21/preference_material.xml", "res/layout-v21/preference_information_material.xml", "res/layout-v21/preference_category_material.xml", "res/layout-v21/preference_dropdown_material.xml", "res/drawable/preference_list_divider_material.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_v17_leanback_java.info b/build/secondary/third_party/android_tools/android_support_v17_leanback_java.info new file mode 100644 index 0000000..93dae49 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v17_leanback_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/values-km-rKH/values-km-rKH.xml", "res/values-nl/values-nl.xml", "res/values-az-rAZ/values-az-rAZ.xml", "res/values-gl-rES/values-gl-rES.xml", "res/values-bg/values-bg.xml", "res/values-ldrtl-v17/values-ldrtl-v17.xml", "res/values-pt-rBR/values-pt-rBR.xml", "res/values-eu-rES/values-eu-rES.xml", "res/values-el/values-el.xml", "res/animator/lb_onboarding_page_indicator_enter.xml", "res/animator/lb_guidedactions_item_unpressed.xml", "res/animator/lb_onboarding_logo_enter.xml", "res/animator/lb_guidedactions_item_pressed.xml", "res/animator/lb_onboarding_start_button_fade_out.xml", "res/animator/lb_playback_rows_fade_out.xml", "res/animator/lb_onboarding_start_button_fade_in.xml", "res/animator/lb_decelerator_4.xml", "res/animator/lb_onboarding_logo_exit.xml", "res/animator/lb_guidedstep_slide_up.xml", "res/animator/lb_onboarding_title_enter.xml", "res/animator/lb_onboarding_page_indicator_fade_out.xml", "res/animator/lb_playback_controls_fade_in.xml", "res/animator/lb_playback_rows_fade_in.xml", "res/animator/lb_playback_description_fade_in.xml", "res/animator/lb_playback_controls_fade_out.xml", "res/animator/lb_onboarding_page_indicator_fade_in.xml", "res/animator/lb_playback_description_fade_out.xml", "res/animator/lb_playback_bg_fade_out.xml", "res/animator/lb_decelerator_2.xml", "res/animator/lb_guidedstep_slide_down.xml", "res/animator/lb_playback_bg_fade_in.xml", "res/animator/lb_onboarding_description_enter.xml", "res/values-mk-rMK/values-mk-rMK.xml", "res/values-af/values-af.xml", "res/raw/lb_voice_open.ogg", "res/raw/lb_voice_no_input.ogg", "res/raw/lb_voice_failure.ogg", "res/raw/lb_voice_success.ogg", "res/drawable-v21/lb_card_foreground.xml", "res/drawable-v21/lb_selectable_item_rounded_rect.xml", "res/drawable-v21/lb_action_bg.xml", "res/drawable-v21/lb_control_button_secondary.xml", "res/drawable-v21/lb_control_button_primary.xml", "res/values-uk/values-uk.xml", "res/transition-v21/lb_vertical_grid_entrance_transition.xml", "res/transition-v21/lb_vertical_grid_enter_transition.xml", "res/transition-v21/lb_browse_headers_in.xml", "res/transition-v21/lb_browse_return_transition.xml", "res/transition-v21/lb_title_in.xml", "res/transition-v21/lb_return_transition.xml", "res/transition-v21/lb_browse_enter_transition.xml", "res/transition-v21/lb_guidedstep_activity_enter.xml", "res/transition-v21/lb_browse_headers_out.xml", "res/transition-v21/lb_shared_element_enter_transition.xml", "res/transition-v21/lb_details_return_transition.xml", "res/transition-v21/lb_shared_element_return_transition.xml", "res/transition-v21/lb_title_out.xml", "res/transition-v21/lb_guidedstep_activity_enter_bottom.xml", "res/transition-v21/lb_enter_transition.xml", "res/transition-v21/lb_vertical_grid_return_transition.xml", "res/transition-v21/lb_browse_entrance_transition.xml", "res/transition-v21/lb_details_enter_transition.xml", "res/values-zu/values-zu.xml", "res/values-et-rEE/values-et-rEE.xml", "res/values-v21/values-v21.xml", "res/values-lo-rLA/values-lo-rLA.xml", "res/drawable-hdpi-v4/lb_ic_search_mic_out.png", "res/drawable-hdpi-v4/lb_ic_sad_cloud.png", "res/drawable-hdpi-v4/lb_in_app_search_shadow_normal.9.png", "res/drawable-hdpi-v4/lb_in_app_search_shadow_focused.9.png", "res/drawable-hdpi-v4/lb_ic_actions_right_arrow.png", "res/drawable-hdpi-v4/lb_action_bg_focused.9.png", "res/drawable-hdpi-v4/lb_in_app_search_bg.9.png", "res/drawable-hdpi-v4/lb_ic_search_mic.png", "res/drawable-hdpi-v4/lb_ic_in_app_search.png", "res/values-v22/values-v22.xml", "res/values-bn-rBD/values-bn-rBD.xml", "res/values-is-rIS/values-is-rIS.xml", "res/values-gu-rIN/values-gu-rIN.xml", "res/drawable-mdpi-v4/lb_ic_search_mic_out.png", "res/drawable-mdpi-v4/lb_ic_sad_cloud.png", "res/drawable-mdpi-v4/lb_in_app_search_shadow_normal.9.png", "res/drawable-mdpi-v4/lb_in_app_search_shadow_focused.9.png", "res/drawable-mdpi-v4/lb_ic_actions_right_arrow.png", "res/drawable-mdpi-v4/lb_action_bg_focused.9.png", "res/drawable-mdpi-v4/lb_in_app_search_bg.9.png", "res/drawable-mdpi-v4/lb_ic_search_mic.png", "res/drawable-mdpi-v4/lb_ic_in_app_search.png", "res/values-pa-rIN/values-pa-rIN.xml", "res/values-mr-rIN/values-mr-rIN.xml", "res/values-ru/values-ru.xml", "res/values-pl/values-pl.xml", "res/values-fa/values-fa.xml", "res/values-be-rBY/values-be-rBY.xml", "res/values-si-rLK/values-si-rLK.xml", "res/values-sv/values-sv.xml", "res/values-my-rMM/values-my-rMM.xml", "res/values-b+sr+Latn/values-b+sr+Latn.xml", "res/values-fr/values-fr.xml", "res/values-uz-rUZ/values-uz-rUZ.xml", "res/values-ms-rMY/values-ms-rMY.xml", "res/values-ka-rGE/values-ka-rGE.xml", "res/values-fi/values-fi.xml", "res/values-fr-rCA/values-fr-rCA.xml", "res/values-ca/values-ca.xml", "res/values-in/values-in.xml", "res/values-vi/values-vi.xml", "res/layout/lb_row_media_item_action.xml", "res/layout/lb_error_fragment.xml", "res/layout/lb_picker.xml", "res/layout/lb_speech_orb.xml", "res/layout/lb_details_fragment.xml", "res/layout/lb_divider.xml", "res/layout/lb_guidedstep_fragment.xml", "res/layout/lb_background_window.xml", "res/layout/lb_rows_fragment.xml", "res/layout/lb_guidedstep_background.xml", "res/layout/lb_details_description.xml", "res/layout/lb_media_item_number_view_flipper.xml", "res/layout/lb_action_1_line.xml", "res/layout/lb_guidedbuttonactions.xml", "res/layout/lb_control_bar.xml", "res/layout/lb_vertical_grid_fragment.xml", "res/layout/lb_headers_fragment.xml", "res/layout/lb_guidance.xml", "res/layout/lb_fullwidth_details_overview_logo.xml", "res/layout/lb_header.xml", "res/layout/lb_browse_fragment.xml", "res/layout/lb_row_header.xml", "res/layout/lb_vertical_grid.xml", "res/layout/lb_control_button_secondary.xml", "res/layout/lb_details_overview.xml", "res/layout/lb_image_card_view_themed_badge_left.xml", "res/layout/lb_search_bar.xml", "res/layout/lb_list_row_hovercard.xml", "res/layout/lb_picker_column.xml", "res/layout/lb_image_card_view_themed_content.xml", "res/layout/lb_playback_now_playing_bars.xml", "res/layout/lb_row_media_item.xml", "res/layout/lb_shadow.xml", "res/layout/lb_picker_item.xml", "res/layout/lb_playback_controls_row.xml", "res/layout/lb_fullwidth_details_overview.xml", "res/layout/lb_guidedactions_item.xml", "res/layout/lb_control_button_primary.xml", "res/layout/lb_section_header.xml", "res/layout/lb_playback_controls.xml", "res/layout/lb_image_card_view_themed_badge_right.xml", "res/layout/lb_picker_separator.xml", "res/layout/lb_title_view.xml", "res/layout/lb_image_card_view.xml", "res/layout/lb_guidedactions_datepicker_item.xml", "res/layout/lb_action_2_lines.xml", "res/layout/lb_guidedactions.xml", "res/layout/lb_search_orb.xml", "res/layout/lb_search_fragment.xml", "res/layout/lb_row_container.xml", "res/layout/lb_list_row.xml", "res/layout/lb_browse_title.xml", "res/layout/lb_media_list_header.xml", "res/layout/lb_onboarding_fragment.xml", "res/layout/lb_image_card_view_themed_title.xml", "res/values-en-rGB/values-en-rGB.xml", "res/values-ja/values-ja.xml", "res/values-zh-rCN/values-zh-rCN.xml", "res/values-am/values-am.xml", "res/values-sq-rAL/values-sq-rAL.xml", "res/values-sl/values-sl.xml", "res/values-de/values-de.xml", "res/values-kk-rKZ/values-kk-rKZ.xml", "res/values-en-rAU/values-en-rAU.xml", "res/values-en-rIN/values-en-rIN.xml", "res/values-zh-rTW/values-zh-rTW.xml", "res/values-sw/values-sw.xml", "res/values-nb/values-nb.xml", "res/values-bs-rBA/values-bs-rBA.xml", "res/values-tr/values-tr.xml", "res/values-kn-rIN/values-kn-rIN.xml", "res/transition-v19/lb_browse_headers_in.xml", "res/transition-v19/lb_browse_headers_out.xml", "res/values-hy-rAM/values-hy-rAM.xml", "res/values-es-rUS/values-es-rUS.xml", "res/values-zh-rHK/values-zh-rHK.xml", "res/values-ko/values-ko.xml", "res/values-pt-rPT/values-pt-rPT.xml", "res/values-iw/values-iw.xml", "res/values-lt/values-lt.xml", "res/values-ro/values-ro.xml", "res/animator-v21/lb_playback_description_fade_out.xml", "res/animator-v21/lb_playback_bg_fade_out.xml", "res/animator-v21/lb_playback_bg_fade_in.xml", "res/values-pt/values-pt.xml", "res/values-ar/values-ar.xml", "res/values-ur-rPK/values-ur-rPK.xml", "res/values-ml-rIN/values-ml-rIN.xml", "res/drawable-xhdpi-v4/lb_ic_replay.png", "res/drawable-xhdpi-v4/lb_ic_nav_arrow.png", "res/drawable-xhdpi-v4/lb_text_dot_two_small.png", "res/drawable-xhdpi-v4/lb_text_dot_one_small.png", "res/drawable-xhdpi-v4/lb_ic_skip_previous.png", "res/drawable-xhdpi-v4/lb_ic_thumb_down.png", "res/drawable-xhdpi-v4/lb_ic_thumb_up_outline.png", "res/drawable-xhdpi-v4/lb_ic_search_mic_out.png", "res/drawable-xhdpi-v4/lb_ic_loop.png", "res/drawable-xhdpi-v4/lb_ic_play_fit.png", "res/drawable-xhdpi-v4/lb_ic_thumb_up.png", "res/drawable-xhdpi-v4/lb_ic_guidedactions_item_chevron.png", "res/drawable-xhdpi-v4/lb_ic_fast_rewind.png", "res/drawable-xhdpi-v4/lb_ic_shuffle.png", "res/drawable-xhdpi-v4/lb_ic_sad_cloud.png", "res/drawable-xhdpi-v4/lb_in_app_search_shadow_normal.9.png", "res/drawable-xhdpi-v4/lb_ic_fast_forward.png", "res/drawable-xhdpi-v4/lb_card_shadow_focused.9.png", "res/drawable-xhdpi-v4/lb_in_app_search_shadow_focused.9.png", "res/drawable-xhdpi-v4/lb_ic_actions_right_arrow.png", "res/drawable-xhdpi-v4/lb_action_bg_focused.9.png", "res/drawable-xhdpi-v4/lb_ic_hq.png", "res/drawable-xhdpi-v4/lb_in_app_search_bg.9.png", "res/drawable-xhdpi-v4/lb_ic_stop.png", "res/drawable-xhdpi-v4/lb_ic_search_mic.png", "res/drawable-xhdpi-v4/lb_card_shadow_normal.9.png", "res/drawable-xhdpi-v4/lb_ic_loop_one.png", "res/drawable-xhdpi-v4/lb_ic_in_app_search.png", "res/drawable-xhdpi-v4/lb_text_dot_one.png", "res/drawable-xhdpi-v4/lb_ic_pip.png", "res/drawable-xhdpi-v4/lb_text_dot_two.png", "res/drawable-xhdpi-v4/lb_ic_more.png", "res/drawable-xhdpi-v4/lb_ic_pause.png", "res/drawable-xhdpi-v4/lb_ic_cc.png", "res/drawable-xhdpi-v4/lb_ic_skip_next.png", "res/drawable-xhdpi-v4/lb_ic_thumb_down_outline.png", "res/drawable-xhdpi-v4/lb_ic_playback_loop.png", "res/drawable-xhdpi-v4/lb_ic_play.png", "res/values/values.xml", "res/values-hr/values-hr.xml", "res/values-mn-rMN/values-mn-rMN.xml", "res/values-da/values-da.xml", "res/values-hi/values-hi.xml", "res/values-it/values-it.xml", "res/values-es/values-es.xml", "res/values-sk/values-sk.xml", "res/values-lv/values-lv.xml", "res/values-ky-rKG/values-ky-rKG.xml", "res/values-hu/values-hu.xml", "res/drawable-xxhdpi-v4/lb_ic_search_mic_out.png", "res/drawable-xxhdpi-v4/lb_ic_sad_cloud.png", "res/drawable-xxhdpi-v4/lb_in_app_search_shadow_normal.9.png", "res/drawable-xxhdpi-v4/lb_in_app_search_shadow_focused.9.png", "res/drawable-xxhdpi-v4/lb_ic_actions_right_arrow.png", "res/drawable-xxhdpi-v4/lb_action_bg_focused.9.png", "res/drawable-xxhdpi-v4/lb_in_app_search_bg.9.png", "res/drawable-xxhdpi-v4/lb_ic_search_mic.png", "res/drawable-xxhdpi-v4/lb_ic_in_app_search.png", "res/values-v19/values-v19.xml", "res/values-th/values-th.xml", "res/values-cs/values-cs.xml", "res/values-sr/values-sr.xml", "res/values-tl/values-tl.xml", "res/values-te-rIN/values-te-rIN.xml", "res/values-ne-rNP/values-ne-rNP.xml", "res/values-ta-rIN/values-ta-rIN.xml", "res/drawable/lb_speech_orb.xml", "res/drawable/lb_playback_progress_bar.xml", "res/drawable/lb_card_foreground.xml", "res/drawable/lb_onboarding_start_button_background.xml", "res/drawable/lb_control_button_secondary.xml", "res/drawable/lb_playback_now_playing_bar.xml", "res/drawable/lb_control_button_primary.xml", "res/drawable/lb_background.xml", "res/drawable/lb_headers_right_fading.xml", "res/drawable/lb_search_orb.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_v17_preference_java.info b/build/secondary/third_party/android_tools/android_support_v17_preference_java.info new file mode 100644 index 0000000..e97682c1 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v17_preference_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/layout/leanback_preference_category.xml", "res/layout/leanback_list_preference_item_single.xml", "res/layout/leanback_list_preference_fragment.xml", "res/layout/leanback_list_preference_item_multi.xml", "res/layout/leanback_settings_fragment.xml", "res/layout/leanback_preference_fragment.xml", "res/layout/leanback_preferences_list.xml", "res/layout/leanback_preference_information.xml", "res/layout/leanback_preference.xml", "res/values/values.xml", "res/layout-v21/leanback_settings_fragment.xml", "res/color/lb_preference_item_secondary_text_color.xml", "res/color/lb_preference_item_primary_text_color.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_v7_appcompat_java_internal.info b/build/secondary/third_party/android_tools/android_support_v7_appcompat_java_internal.info new file mode 100644 index 0000000..780717bb --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v7_appcompat_java_internal.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/values-v23/values-v23.xml", "res/values-km-rKH/values-km-rKH.xml", "res/values-nl/values-nl.xml", "res/values-az-rAZ/values-az-rAZ.xml", "res/values-port/values-port.xml", "res/values-gl-rES/values-gl-rES.xml", "res/values-bg/values-bg.xml", "res/values-v18/values-v18.xml", "res/values-xlarge-v4/values-xlarge-v4.xml", "res/values-pt-rBR/values-pt-rBR.xml", "res/values-eu-rES/values-eu-rES.xml", "res/values-el/values-el.xml", "res/values-mk-rMK/values-mk-rMK.xml", "res/values-af/values-af.xml", "res/drawable-ldrtl-xhdpi-v17/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-ldrtl-xhdpi-v17/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-ldrtl-xhdpi-v17/abc_ic_menu_cut_mtrl_alpha.png", "res/drawable-ldrtl-xxxhdpi-v17/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-ldrtl-xxxhdpi-v17/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-ldrtl-xxxhdpi-v17/abc_ic_menu_cut_mtrl_alpha.png", "res/drawable-v21/abc_btn_colored_material.xml", "res/drawable-v21/abc_edit_text_material.xml", "res/drawable-v21/notification_action_background.xml", "res/drawable-v21/abc_action_bar_item_background_material.xml", "res/values-uk/values-uk.xml", "res/values-zu/values-zu.xml", "res/values-et-rEE/values-et-rEE.xml", "res/values-v21/values-v21.xml", "res/values-lo-rLA/values-lo-rLA.xml", "res/drawable-hdpi-v4/abc_ic_menu_share_mtrl_alpha.png", "res/drawable-hdpi-v4/abc_list_pressed_holo_light.9.png", "res/drawable-hdpi-v4/abc_btn_switch_to_on_mtrl_00012.9.png", "res/drawable-hdpi-v4/abc_scrubber_control_off_mtrl_alpha.png", "res/drawable-hdpi-v4/abc_list_focused_holo.9.png", "res/drawable-hdpi-v4/abc_menu_hardkey_panel_mtrl_mult.9.png", "res/drawable-hdpi-v4/abc_textfield_activated_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_popup_background_mtrl_mult.9.png", "res/drawable-hdpi-v4/abc_ic_star_black_36dp.png", "res/drawable-hdpi-v4/abc_list_selector_disabled_holo_dark.9.png", "res/drawable-hdpi-v4/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-hdpi-v4/abc_text_select_handle_left_mtrl_light.png", "res/drawable-hdpi-v4/abc_list_longpressed_holo.9.png", "res/drawable-hdpi-v4/abc_btn_check_to_on_mtrl_000.png", "res/drawable-hdpi-v4/abc_list_pressed_holo_dark.9.png", "res/drawable-hdpi-v4/abc_cab_background_top_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_btn_check_to_on_mtrl_015.png", "res/drawable-hdpi-v4/abc_text_select_handle_left_mtrl_dark.png", "res/drawable-hdpi-v4/abc_text_select_handle_middle_mtrl_light.png", "res/drawable-hdpi-v4/abc_switch_track_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_ic_menu_selectall_mtrl_alpha.png", "res/drawable-hdpi-v4/notification_bg_low_normal.9.png", "res/drawable-hdpi-v4/abc_btn_radio_to_on_mtrl_015.png", "res/drawable-hdpi-v4/abc_text_select_handle_middle_mtrl_dark.png", "res/drawable-hdpi-v4/abc_tab_indicator_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_ic_star_black_48dp.png", "res/drawable-hdpi-v4/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-hdpi-v4/abc_list_divider_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_textfield_search_activated_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_text_select_handle_right_mtrl_dark.png", "res/drawable-hdpi-v4/abc_scrubber_track_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_scrubber_primary_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_scrubber_control_to_pressed_mtrl_000.png", "res/drawable-hdpi-v4/abc_ic_star_half_black_16dp.png", "res/drawable-hdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png", "res/drawable-hdpi-v4/notification_bg_normal.9.png", "res/drawable-hdpi-v4/abc_ic_star_half_black_36dp.png", "res/drawable-hdpi-v4/notify_panel_notification_icon_bg.png", "res/drawable-hdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_text_select_handle_right_mtrl_light.png", "res/drawable-hdpi-v4/notification_bg_low_pressed.9.png", "res/drawable-hdpi-v4/abc_textfield_default_mtrl_alpha.9.png", "res/drawable-hdpi-v4/notification_bg_normal_pressed.9.png", "res/drawable-hdpi-v4/abc_ic_menu_paste_mtrl_am_alpha.png", "res/drawable-hdpi-v4/abc_btn_switch_to_on_mtrl_00001.9.png", "res/drawable-hdpi-v4/abc_ic_star_black_16dp.png", "res/drawable-hdpi-v4/abc_list_selector_disabled_holo_light.9.png", "res/drawable-hdpi-v4/abc_ic_commit_search_api_mtrl_alpha.png", "res/drawable-hdpi-v4/abc_ab_share_pack_mtrl_alpha.9.png", "res/drawable-hdpi-v4/abc_btn_radio_to_on_mtrl_000.png", "res/drawable-hdpi-v4/abc_ic_star_half_black_48dp.png", "res/drawable-hdpi-v4/abc_ic_menu_cut_mtrl_alpha.png", "res/values-v22/values-v22.xml", "res/values-bn-rBD/values-bn-rBD.xml", "res/values-v24/values-v24.xml", "res/values-is-rIS/values-is-rIS.xml", "res/values-gu-rIN/values-gu-rIN.xml", "res/drawable-mdpi-v4/abc_ic_menu_share_mtrl_alpha.png", "res/drawable-mdpi-v4/abc_list_pressed_holo_light.9.png", "res/drawable-mdpi-v4/abc_btn_switch_to_on_mtrl_00012.9.png", "res/drawable-mdpi-v4/abc_scrubber_control_off_mtrl_alpha.png", "res/drawable-mdpi-v4/abc_list_focused_holo.9.png", "res/drawable-mdpi-v4/abc_menu_hardkey_panel_mtrl_mult.9.png", "res/drawable-mdpi-v4/abc_textfield_activated_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_popup_background_mtrl_mult.9.png", "res/drawable-mdpi-v4/abc_ic_star_black_36dp.png", "res/drawable-mdpi-v4/abc_list_selector_disabled_holo_dark.9.png", "res/drawable-mdpi-v4/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-mdpi-v4/abc_text_select_handle_left_mtrl_light.png", "res/drawable-mdpi-v4/abc_list_longpressed_holo.9.png", "res/drawable-mdpi-v4/abc_btn_check_to_on_mtrl_000.png", "res/drawable-mdpi-v4/abc_list_pressed_holo_dark.9.png", "res/drawable-mdpi-v4/abc_cab_background_top_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_btn_check_to_on_mtrl_015.png", "res/drawable-mdpi-v4/abc_text_select_handle_left_mtrl_dark.png", "res/drawable-mdpi-v4/abc_text_select_handle_middle_mtrl_light.png", "res/drawable-mdpi-v4/abc_switch_track_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_ic_menu_selectall_mtrl_alpha.png", "res/drawable-mdpi-v4/notification_bg_low_normal.9.png", "res/drawable-mdpi-v4/abc_btn_radio_to_on_mtrl_015.png", "res/drawable-mdpi-v4/abc_text_select_handle_middle_mtrl_dark.png", "res/drawable-mdpi-v4/abc_tab_indicator_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_ic_star_black_48dp.png", "res/drawable-mdpi-v4/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-mdpi-v4/abc_list_divider_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_textfield_search_activated_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_text_select_handle_right_mtrl_dark.png", "res/drawable-mdpi-v4/abc_scrubber_track_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_scrubber_primary_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_scrubber_control_to_pressed_mtrl_000.png", "res/drawable-mdpi-v4/abc_ic_star_half_black_16dp.png", "res/drawable-mdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png", "res/drawable-mdpi-v4/notification_bg_normal.9.png", "res/drawable-mdpi-v4/abc_ic_star_half_black_36dp.png", "res/drawable-mdpi-v4/notify_panel_notification_icon_bg.png", "res/drawable-mdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_text_select_handle_right_mtrl_light.png", "res/drawable-mdpi-v4/notification_bg_low_pressed.9.png", "res/drawable-mdpi-v4/abc_textfield_default_mtrl_alpha.9.png", "res/drawable-mdpi-v4/notification_bg_normal_pressed.9.png", "res/drawable-mdpi-v4/abc_ic_menu_paste_mtrl_am_alpha.png", "res/drawable-mdpi-v4/abc_btn_switch_to_on_mtrl_00001.9.png", "res/drawable-mdpi-v4/abc_ic_star_black_16dp.png", "res/drawable-mdpi-v4/abc_list_selector_disabled_holo_light.9.png", "res/drawable-mdpi-v4/abc_ic_commit_search_api_mtrl_alpha.png", "res/drawable-mdpi-v4/abc_ab_share_pack_mtrl_alpha.9.png", "res/drawable-mdpi-v4/abc_btn_radio_to_on_mtrl_000.png", "res/drawable-mdpi-v4/abc_ic_star_half_black_48dp.png", "res/drawable-mdpi-v4/abc_ic_menu_cut_mtrl_alpha.png", "res/values-pa-rIN/values-pa-rIN.xml", "res/values-mr-rIN/values-mr-rIN.xml", "res/values-ru/values-ru.xml", "res/values-pl/values-pl.xml", "res/values-fa/values-fa.xml", "res/values-v11/values-v11.xml", "res/values-be-rBY/values-be-rBY.xml", "res/values-si-rLK/values-si-rLK.xml", "res/values-sv/values-sv.xml", "res/anim/abc_popup_exit.xml", "res/anim/abc_slide_out_top.xml", "res/anim/abc_grow_fade_in_from_bottom.xml", "res/anim/abc_popup_enter.xml", "res/anim/abc_slide_in_bottom.xml", "res/anim/abc_shrink_fade_out_from_bottom.xml", "res/anim/abc_slide_in_top.xml", "res/anim/abc_fade_out.xml", "res/anim/abc_slide_out_bottom.xml", "res/anim/abc_fade_in.xml", "res/values-my-rMM/values-my-rMM.xml", "res/values-b+sr+Latn/values-b+sr+Latn.xml", "res/values-fr/values-fr.xml", "res/values-uz-rUZ/values-uz-rUZ.xml", "res/values-ms-rMY/values-ms-rMY.xml", "res/values-ka-rGE/values-ka-rGE.xml", "res/values-fi/values-fi.xml", "res/values-fr-rCA/values-fr-rCA.xml", "res/values-v17/values-v17.xml", "res/values-ca/values-ca.xml", "res/values-in/values-in.xml", "res/values-vi/values-vi.xml", "res/drawable-ldrtl-hdpi-v17/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-ldrtl-hdpi-v17/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-ldrtl-hdpi-v17/abc_ic_menu_cut_mtrl_alpha.png", "res/layout/notification_media_cancel_action.xml", "res/layout/select_dialog_item_material.xml", "res/layout/notification_template_custom_big.xml", "res/layout/abc_action_bar_up_container.xml", "res/layout/abc_dialog_title_material.xml", "res/layout/notification_template_big_media_narrow.xml", "res/layout/abc_select_dialog_material.xml", "res/layout/abc_list_menu_item_layout.xml", "res/layout/notification_template_part_chronometer.xml", "res/layout/abc_popup_menu_header_item_layout.xml", "res/layout/notification_template_lines_media.xml", "res/layout/notification_template_part_time.xml", "res/layout/abc_list_menu_item_icon.xml", "res/layout/notification_action_tombstone.xml", "res/layout/abc_action_mode_bar.xml", "res/layout/notification_template_media_custom.xml", "res/layout/abc_popup_menu_item_layout.xml", "res/layout/abc_action_menu_item_layout.xml", "res/layout/abc_activity_chooser_view_list_item.xml", "res/layout/abc_list_menu_item_radio.xml", "res/layout/abc_screen_content_include.xml", "res/layout/abc_activity_chooser_view.xml", "res/layout/abc_alert_dialog_button_bar_material.xml", "res/layout/abc_action_menu_layout.xml", "res/layout/notification_template_big_media_narrow_custom.xml", "res/layout/notification_template_big_media_custom.xml", "res/layout/abc_list_menu_item_checkbox.xml", "res/layout/notification_media_action.xml", "res/layout/notification_template_icon_group.xml", "res/layout/abc_screen_simple.xml", "res/layout/abc_screen_simple_overlay_action_mode.xml", "res/layout/abc_screen_toolbar.xml", "res/layout/abc_alert_dialog_material.xml", "res/layout/abc_expanded_menu_layout.xml", "res/layout/abc_search_view.xml", "res/layout/notification_template_big_media.xml", "res/layout/abc_search_dropdown_item_icons_2line.xml", "res/layout/abc_action_bar_view_list_nav_layout.xml", "res/layout/select_dialog_multichoice_material.xml", "res/layout/abc_action_mode_close_item_material.xml", "res/layout/notification_template_media.xml", "res/layout/support_simple_spinner_dropdown_item.xml", "res/layout/notification_action.xml", "res/layout/abc_action_bar_title_item.xml", "res/layout/select_dialog_singlechoice_material.xml", "res/values-en-rGB/values-en-rGB.xml", "res/values-ja/values-ja.xml", "res/values-zh-rCN/values-zh-rCN.xml", "res/values-am/values-am.xml", "res/values-sq-rAL/values-sq-rAL.xml", "res/values-v16/values-v16.xml", "res/values-sl/values-sl.xml", "res/values-de/values-de.xml", "res/values-kk-rKZ/values-kk-rKZ.xml", "res/drawable-xxxhdpi-v4/abc_ic_menu_share_mtrl_alpha.png", "res/drawable-xxxhdpi-v4/abc_btn_switch_to_on_mtrl_00012.9.png", "res/drawable-xxxhdpi-v4/abc_ic_star_black_36dp.png", "res/drawable-xxxhdpi-v4/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-xxxhdpi-v4/abc_text_select_handle_left_mtrl_light.png", "res/drawable-xxxhdpi-v4/abc_btn_check_to_on_mtrl_000.png", "res/drawable-xxxhdpi-v4/abc_btn_check_to_on_mtrl_015.png", "res/drawable-xxxhdpi-v4/abc_text_select_handle_left_mtrl_dark.png", "res/drawable-xxxhdpi-v4/abc_switch_track_mtrl_alpha.9.png", "res/drawable-xxxhdpi-v4/abc_ic_menu_selectall_mtrl_alpha.png", "res/drawable-xxxhdpi-v4/abc_btn_radio_to_on_mtrl_015.png", "res/drawable-xxxhdpi-v4/abc_tab_indicator_mtrl_alpha.9.png", "res/drawable-xxxhdpi-v4/abc_ic_star_black_48dp.png", "res/drawable-xxxhdpi-v4/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-xxxhdpi-v4/abc_text_select_handle_right_mtrl_dark.png", "res/drawable-xxxhdpi-v4/abc_scrubber_control_to_pressed_mtrl_000.png", "res/drawable-xxxhdpi-v4/abc_ic_star_half_black_16dp.png", "res/drawable-xxxhdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png", "res/drawable-xxxhdpi-v4/abc_ic_star_half_black_36dp.png", "res/drawable-xxxhdpi-v4/abc_text_select_handle_right_mtrl_light.png", "res/drawable-xxxhdpi-v4/abc_ic_menu_paste_mtrl_am_alpha.png", "res/drawable-xxxhdpi-v4/abc_btn_switch_to_on_mtrl_00001.9.png", "res/drawable-xxxhdpi-v4/abc_ic_star_black_16dp.png", "res/drawable-xxxhdpi-v4/abc_btn_radio_to_on_mtrl_000.png", "res/drawable-xxxhdpi-v4/abc_ic_star_half_black_48dp.png", "res/drawable-xxxhdpi-v4/abc_ic_menu_cut_mtrl_alpha.png", "res/values-en-rAU/values-en-rAU.xml", "res/values-en-rIN/values-en-rIN.xml", "res/values-zh-rTW/values-zh-rTW.xml", "res/values-sw/values-sw.xml", "res/values-nb/values-nb.xml", "res/values-h720dp-v13/values-h720dp-v13.xml", "res/values-bs-rBA/values-bs-rBA.xml", "res/values-tr/values-tr.xml", "res/drawable-ldrtl-mdpi-v17/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-ldrtl-mdpi-v17/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-ldrtl-mdpi-v17/abc_ic_menu_cut_mtrl_alpha.png", "res/drawable-v23/abc_control_background_material.xml", "res/values-kn-rIN/values-kn-rIN.xml", "res/values-hy-rAM/values-hy-rAM.xml", "res/values-sw600dp-v13/values-sw600dp-v13.xml", "res/values-es-rUS/values-es-rUS.xml", "res/values-land/values-land.xml", "res/values-zh-rHK/values-zh-rHK.xml", "res/drawable-ldrtl-xxhdpi-v17/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-ldrtl-xxhdpi-v17/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-ldrtl-xxhdpi-v17/abc_ic_menu_cut_mtrl_alpha.png", "res/values-large-v4/values-large-v4.xml", "res/values-ko/values-ko.xml", "res/values-pt-rPT/values-pt-rPT.xml", "res/values-iw/values-iw.xml", "res/values-lt/values-lt.xml", "res/values-ro/values-ro.xml", "res/values-v14/values-v14.xml", "res/values-pt/values-pt.xml", "res/layout-v16/notification_template_custom_big.xml", "res/values-ar/values-ar.xml", "res/color-v23/abc_tint_seek_thumb.xml", "res/color-v23/abc_tint_btn_checkable.xml", "res/color-v23/abc_tint_edittext.xml", "res/color-v23/abc_tint_switch_thumb.xml", "res/color-v23/abc_btn_colored_borderless_text_material.xml", "res/color-v23/abc_tint_default.xml", "res/color-v23/abc_color_highlight_material.xml", "res/color-v23/abc_tint_spinner.xml", "res/color-v23/abc_tint_switch_track.xml", "res/values-hdpi-v4/values-hdpi-v4.xml", "res/values-ur-rPK/values-ur-rPK.xml", "res/values-ml-rIN/values-ml-rIN.xml", "res/drawable-xhdpi-v4/abc_ic_menu_share_mtrl_alpha.png", "res/drawable-xhdpi-v4/abc_list_pressed_holo_light.9.png", "res/drawable-xhdpi-v4/abc_btn_switch_to_on_mtrl_00012.9.png", "res/drawable-xhdpi-v4/abc_scrubber_control_off_mtrl_alpha.png", "res/drawable-xhdpi-v4/abc_list_focused_holo.9.png", "res/drawable-xhdpi-v4/abc_menu_hardkey_panel_mtrl_mult.9.png", "res/drawable-xhdpi-v4/abc_textfield_activated_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_popup_background_mtrl_mult.9.png", "res/drawable-xhdpi-v4/abc_ic_star_black_36dp.png", "res/drawable-xhdpi-v4/abc_list_selector_disabled_holo_dark.9.png", "res/drawable-xhdpi-v4/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-xhdpi-v4/abc_text_select_handle_left_mtrl_light.png", "res/drawable-xhdpi-v4/abc_list_longpressed_holo.9.png", "res/drawable-xhdpi-v4/abc_btn_check_to_on_mtrl_000.png", "res/drawable-xhdpi-v4/abc_list_pressed_holo_dark.9.png", "res/drawable-xhdpi-v4/abc_cab_background_top_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_btn_check_to_on_mtrl_015.png", "res/drawable-xhdpi-v4/abc_text_select_handle_left_mtrl_dark.png", "res/drawable-xhdpi-v4/abc_text_select_handle_middle_mtrl_light.png", "res/drawable-xhdpi-v4/abc_switch_track_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_ic_menu_selectall_mtrl_alpha.png", "res/drawable-xhdpi-v4/notification_bg_low_normal.9.png", "res/drawable-xhdpi-v4/abc_btn_radio_to_on_mtrl_015.png", "res/drawable-xhdpi-v4/abc_text_select_handle_middle_mtrl_dark.png", "res/drawable-xhdpi-v4/abc_tab_indicator_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_ic_star_black_48dp.png", "res/drawable-xhdpi-v4/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-xhdpi-v4/abc_list_divider_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_textfield_search_activated_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_text_select_handle_right_mtrl_dark.png", "res/drawable-xhdpi-v4/abc_scrubber_track_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_scrubber_primary_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_scrubber_control_to_pressed_mtrl_000.png", "res/drawable-xhdpi-v4/abc_ic_star_half_black_16dp.png", "res/drawable-xhdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png", "res/drawable-xhdpi-v4/notification_bg_normal.9.png", "res/drawable-xhdpi-v4/abc_ic_star_half_black_36dp.png", "res/drawable-xhdpi-v4/notify_panel_notification_icon_bg.png", "res/drawable-xhdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_text_select_handle_right_mtrl_light.png", "res/drawable-xhdpi-v4/notification_bg_low_pressed.9.png", "res/drawable-xhdpi-v4/abc_textfield_default_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/notification_bg_normal_pressed.9.png", "res/drawable-xhdpi-v4/abc_ic_menu_paste_mtrl_am_alpha.png", "res/drawable-xhdpi-v4/abc_btn_switch_to_on_mtrl_00001.9.png", "res/drawable-xhdpi-v4/abc_ic_star_black_16dp.png", "res/drawable-xhdpi-v4/abc_list_selector_disabled_holo_light.9.png", "res/drawable-xhdpi-v4/abc_ic_commit_search_api_mtrl_alpha.png", "res/drawable-xhdpi-v4/abc_ab_share_pack_mtrl_alpha.9.png", "res/drawable-xhdpi-v4/abc_btn_radio_to_on_mtrl_000.png", "res/drawable-xhdpi-v4/abc_ic_star_half_black_48dp.png", "res/drawable-xhdpi-v4/abc_ic_menu_cut_mtrl_alpha.png", "res/values/values.xml", "res/values-hr/values-hr.xml", "res/values-mn-rMN/values-mn-rMN.xml", "res/values-da/values-da.xml", "res/values-hi/values-hi.xml", "res/values-it/values-it.xml", "res/color-v11/abc_background_cache_hint_selector_material_light.xml", "res/color-v11/abc_background_cache_hint_selector_material_dark.xml", "res/values-night-v8/values-night-v8.xml", "res/values-es/values-es.xml", "res/values-sk/values-sk.xml", "res/layout-v21/notification_template_custom_big.xml", "res/layout-v21/notification_action_tombstone.xml", "res/layout-v21/notification_template_icon_group.xml", "res/layout-v21/notification_action.xml", "res/values-lv/values-lv.xml", "res/values-ky-rKG/values-ky-rKG.xml", "res/values-v25/values-v25.xml", "res/values-hu/values-hu.xml", "res/drawable-xxhdpi-v4/abc_ic_menu_share_mtrl_alpha.png", "res/drawable-xxhdpi-v4/abc_list_pressed_holo_light.9.png", "res/drawable-xxhdpi-v4/abc_btn_switch_to_on_mtrl_00012.9.png", "res/drawable-xxhdpi-v4/abc_scrubber_control_off_mtrl_alpha.png", "res/drawable-xxhdpi-v4/abc_list_focused_holo.9.png", "res/drawable-xxhdpi-v4/abc_menu_hardkey_panel_mtrl_mult.9.png", "res/drawable-xxhdpi-v4/abc_textfield_activated_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_popup_background_mtrl_mult.9.png", "res/drawable-xxhdpi-v4/abc_ic_star_black_36dp.png", "res/drawable-xxhdpi-v4/abc_list_selector_disabled_holo_dark.9.png", "res/drawable-xxhdpi-v4/abc_spinner_mtrl_am_alpha.9.png", "res/drawable-xxhdpi-v4/abc_text_select_handle_left_mtrl_light.png", "res/drawable-xxhdpi-v4/abc_list_longpressed_holo.9.png", "res/drawable-xxhdpi-v4/abc_btn_check_to_on_mtrl_000.png", "res/drawable-xxhdpi-v4/abc_list_pressed_holo_dark.9.png", "res/drawable-xxhdpi-v4/abc_cab_background_top_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_btn_check_to_on_mtrl_015.png", "res/drawable-xxhdpi-v4/abc_text_select_handle_left_mtrl_dark.png", "res/drawable-xxhdpi-v4/abc_text_select_handle_middle_mtrl_light.png", "res/drawable-xxhdpi-v4/abc_switch_track_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_ic_menu_selectall_mtrl_alpha.png", "res/drawable-xxhdpi-v4/abc_btn_radio_to_on_mtrl_015.png", "res/drawable-xxhdpi-v4/abc_text_select_handle_middle_mtrl_dark.png", "res/drawable-xxhdpi-v4/abc_tab_indicator_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_ic_star_black_48dp.png", "res/drawable-xxhdpi-v4/abc_ic_menu_copy_mtrl_am_alpha.png", "res/drawable-xxhdpi-v4/abc_list_divider_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_textfield_search_activated_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_text_select_handle_right_mtrl_dark.png", "res/drawable-xxhdpi-v4/abc_scrubber_track_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_scrubber_primary_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_scrubber_control_to_pressed_mtrl_000.png", "res/drawable-xxhdpi-v4/abc_ic_star_half_black_16dp.png", "res/drawable-xxhdpi-v4/abc_scrubber_control_to_pressed_mtrl_005.png", "res/drawable-xxhdpi-v4/abc_ic_star_half_black_36dp.png", "res/drawable-xxhdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_text_select_handle_right_mtrl_light.png", "res/drawable-xxhdpi-v4/abc_textfield_default_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_ic_menu_paste_mtrl_am_alpha.png", "res/drawable-xxhdpi-v4/abc_btn_switch_to_on_mtrl_00001.9.png", "res/drawable-xxhdpi-v4/abc_ic_star_black_16dp.png", "res/drawable-xxhdpi-v4/abc_list_selector_disabled_holo_light.9.png", "res/drawable-xxhdpi-v4/abc_ic_commit_search_api_mtrl_alpha.png", "res/drawable-xxhdpi-v4/abc_ab_share_pack_mtrl_alpha.9.png", "res/drawable-xxhdpi-v4/abc_btn_radio_to_on_mtrl_000.png", "res/drawable-xxhdpi-v4/abc_ic_star_half_black_48dp.png", "res/drawable-xxhdpi-v4/abc_ic_menu_cut_mtrl_alpha.png", "res/color/abc_search_url_text.xml", "res/color/switch_thumb_material_dark.xml", "res/color/abc_hint_foreground_material_light.xml", "res/color/abc_secondary_text_material_dark.xml", "res/color/abc_tint_seek_thumb.xml", "res/color/abc_tint_btn_checkable.xml", "res/color/abc_tint_edittext.xml", "res/color/abc_hint_foreground_material_dark.xml", "res/color/switch_thumb_material_light.xml", "res/color/abc_tint_switch_thumb.xml", "res/color/abc_btn_colored_borderless_text_material.xml", "res/color/abc_primary_text_material_light.xml", "res/color/abc_background_cache_hint_selector_material_light.xml", "res/color/abc_secondary_text_material_light.xml", "res/color/abc_primary_text_disable_only_material_light.xml", "res/color/abc_primary_text_disable_only_material_dark.xml", "res/color/abc_tint_default.xml", "res/color/abc_tint_spinner.xml", "res/color/abc_tint_switch_track.xml", "res/color/abc_background_cache_hint_selector_material_dark.xml", "res/color/abc_primary_text_material_dark.xml", "res/values-v12/values-v12.xml", "res/values-th/values-th.xml", "res/values-cs/values-cs.xml", "res/values-sr/values-sr.xml", "res/values-v13/values-v13.xml", "res/values-tl/values-tl.xml", "res/values-te-rIN/values-te-rIN.xml", "res/values-ne-rNP/values-ne-rNP.xml", "res/values-ta-rIN/values-ta-rIN.xml", "res/values-ldltr-v21/values-ldltr-v21.xml", "res/drawable/abc_switch_thumb_material.xml", "res/drawable/abc_btn_borderless_material.xml", "res/drawable/abc_textfield_search_material.xml", "res/drawable/abc_seekbar_track_material.xml", "res/drawable/abc_btn_colored_material.xml", "res/drawable/abc_ratingbar_indicator_material.xml", "res/drawable/notification_tile_bg.xml", "res/drawable/abc_ic_ab_back_material.xml", "res/drawable/notification_icon_background.xml", "res/drawable/notification_bg_low.xml", "res/drawable/abc_btn_default_mtrl_shape.xml", "res/drawable/abc_seekbar_thumb_material.xml", "res/drawable/abc_cab_background_internal_bg.xml", "res/drawable/abc_dialog_material_background.xml", "res/drawable/abc_text_cursor_material.xml", "res/drawable/notification_bg.xml", "res/drawable/abc_btn_radio_material.xml", "res/drawable/abc_item_background_holo_dark.xml", "res/drawable/abc_list_selector_holo_light.xml", "res/drawable/abc_ic_voice_search_api_material.xml", "res/drawable/abc_ic_search_api_material.xml", "res/drawable/abc_cab_background_top_material.xml", "res/drawable/abc_list_selector_background_transition_holo_dark.xml", "res/drawable/abc_edit_text_material.xml", "res/drawable/abc_tab_indicator_material.xml", "res/drawable/abc_ratingbar_material.xml", "res/drawable/abc_seekbar_tick_mark_material.xml", "res/drawable/abc_ic_go_search_api_material.xml", "res/drawable/abc_list_selector_holo_dark.xml", "res/drawable/abc_ic_arrow_drop_right_black_24dp.xml", "res/drawable/abc_btn_check_material.xml", "res/drawable/abc_spinner_textfield_background_material.xml", "res/drawable/abc_ic_clear_material.xml", "res/drawable/abc_item_background_holo_light.xml", "res/drawable/abc_list_selector_background_transition_holo_light.xml", "res/drawable/abc_ic_menu_overflow_material.xml", "res/drawable/abc_vector_test.xml", "res/drawable/abc_ratingbar_small_material.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_v7_gridlayout_java.info b/build/secondary/third_party/android_tools/android_support_v7_gridlayout_java.info new file mode 100644 index 0000000..28c8330 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v7_gridlayout_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/values/values.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_v7_mediarouter_java.info b/build/secondary/third_party/android_tools/android_support_v7_mediarouter_java.info new file mode 100644 index 0000000..55b51f5 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v7_mediarouter_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/values-km-rKH/values-km-rKH.xml", "res/values-nl/values-nl.xml", "res/values-az-rAZ/values-az-rAZ.xml", "res/values-gl-rES/values-gl-rES.xml", "res/values-bg/values-bg.xml", "res/values-pt-rBR/values-pt-rBR.xml", "res/values-eu-rES/values-eu-rES.xml", "res/values-el/values-el.xml", "res/values-sw720dp-v13/values-sw720dp-v13.xml", "res/values-mk-rMK/values-mk-rMK.xml", "res/values-af/values-af.xml", "res/values-uk/values-uk.xml", "res/values-zu/values-zu.xml", "res/values-et-rEE/values-et-rEE.xml", "res/values-lo-rLA/values-lo-rLA.xml", "res/drawable-hdpi-v4/ic_mr_button_disconnected_light.png", "res/drawable-hdpi-v4/ic_vol_type_speaker_group_light.png", "res/drawable-hdpi-v4/ic_audiotrack_light.png", "res/drawable-hdpi-v4/ic_vol_type_speaker_light.png", "res/drawable-hdpi-v4/ic_vol_type_tv_dark.png", "res/drawable-hdpi-v4/ic_dialog_close_dark.png", "res/drawable-hdpi-v4/ic_vol_type_tv_light.png", "res/drawable-hdpi-v4/ic_mr_button_disabled_dark.png", "res/drawable-hdpi-v4/ic_mr_button_disabled_light.png", "res/drawable-hdpi-v4/ic_dialog_close_light.png", "res/drawable-hdpi-v4/ic_mr_button_disconnected_dark.png", "res/drawable-hdpi-v4/ic_vol_type_speaker_group_dark.png", "res/drawable-hdpi-v4/ic_vol_type_speaker_dark.png", "res/drawable-hdpi-v4/ic_media_pause_light.png", "res/drawable-hdpi-v4/ic_mr_button_grey.png", "res/drawable-hdpi-v4/ic_audiotrack_dark.png", "res/drawable-hdpi-v4/ic_media_play_light.png", "res/drawable-hdpi-v4/ic_media_pause_dark.png", "res/drawable-hdpi-v4/ic_media_play_dark.png", "res/values-bn-rBD/values-bn-rBD.xml", "res/values-is-rIS/values-is-rIS.xml", "res/values-gu-rIN/values-gu-rIN.xml", "res/drawable-mdpi-v4/ic_mr_button_disconnected_light.png", "res/drawable-mdpi-v4/ic_vol_type_speaker_group_light.png", "res/drawable-mdpi-v4/ic_audiotrack_light.png", "res/drawable-mdpi-v4/ic_vol_type_speaker_light.png", "res/drawable-mdpi-v4/ic_vol_type_tv_dark.png", "res/drawable-mdpi-v4/ic_dialog_close_dark.png", "res/drawable-mdpi-v4/ic_vol_type_tv_light.png", "res/drawable-mdpi-v4/ic_mr_button_disabled_dark.png", "res/drawable-mdpi-v4/ic_mr_button_disabled_light.png", "res/drawable-mdpi-v4/ic_dialog_close_light.png", "res/drawable-mdpi-v4/ic_mr_button_disconnected_dark.png", "res/drawable-mdpi-v4/ic_vol_type_speaker_group_dark.png", "res/drawable-mdpi-v4/ic_vol_type_speaker_dark.png", "res/drawable-mdpi-v4/ic_media_pause_light.png", "res/drawable-mdpi-v4/ic_mr_button_grey.png", "res/drawable-mdpi-v4/ic_audiotrack_dark.png", "res/drawable-mdpi-v4/ic_media_play_light.png", "res/drawable-mdpi-v4/ic_media_pause_dark.png", "res/drawable-mdpi-v4/ic_media_play_dark.png", "res/values-pa-rIN/values-pa-rIN.xml", "res/values-mr-rIN/values-mr-rIN.xml", "res/values-ru/values-ru.xml", "res/values-pl/values-pl.xml", "res/values-fa/values-fa.xml", "res/values-be-rBY/values-be-rBY.xml", "res/values-si-rLK/values-si-rLK.xml", "res/values-sv/values-sv.xml", "res/values-my-rMM/values-my-rMM.xml", "res/values-b+sr+Latn/values-b+sr+Latn.xml", "res/interpolator/mr_linear_out_slow_in.xml", "res/interpolator/mr_fast_out_slow_in.xml", "res/values-fr/values-fr.xml", "res/values-uz-rUZ/values-uz-rUZ.xml", "res/values-ms-rMY/values-ms-rMY.xml", "res/values-ka-rGE/values-ka-rGE.xml", "res/values-fi/values-fi.xml", "res/values-fr-rCA/values-fr-rCA.xml", "res/values-ca/values-ca.xml", "res/values-in/values-in.xml", "res/values-vi/values-vi.xml", "res/layout/mr_controller_material_dialog_b.xml", "res/layout/mr_chooser_dialog.xml", "res/layout/mr_chooser_list_item.xml", "res/layout/mr_volume_control.xml", "res/layout/mr_playback_control.xml", "res/layout/mr_controller_volume_item.xml", "res/values-en-rGB/values-en-rGB.xml", "res/values-ja/values-ja.xml", "res/values-zh-rCN/values-zh-rCN.xml", "res/values-am/values-am.xml", "res/values-sq-rAL/values-sq-rAL.xml", "res/values-sl/values-sl.xml", "res/values-de/values-de.xml", "res/values-kk-rKZ/values-kk-rKZ.xml", "res/drawable-xxxhdpi-v4/ic_group_collapse_03.png", "res/drawable-xxxhdpi-v4/ic_group_expand_15.png", "res/drawable-xxxhdpi-v4/ic_group_expand_13.png", "res/drawable-xxxhdpi-v4/ic_group_expand_10.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_14.png", "res/drawable-xxxhdpi-v4/ic_group_expand_06.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_11.png", "res/drawable-xxxhdpi-v4/ic_group_expand_11.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_01.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_10.png", "res/drawable-xxxhdpi-v4/ic_group_expand_07.png", "res/drawable-xxxhdpi-v4/ic_group_expand_09.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_13.png", "res/drawable-xxxhdpi-v4/ic_group_expand_01.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_00.png", "res/drawable-xxxhdpi-v4/ic_group_expand_00.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_04.png", "res/drawable-xxxhdpi-v4/ic_group_expand_12.png", "res/drawable-xxxhdpi-v4/ic_group_expand_08.png", "res/drawable-xxxhdpi-v4/ic_group_expand_04.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_08.png", "res/drawable-xxxhdpi-v4/ic_group_expand_03.png", "res/drawable-xxxhdpi-v4/ic_group_expand_02.png", "res/drawable-xxxhdpi-v4/ic_group_expand_05.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_02.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_07.png", "res/drawable-xxxhdpi-v4/ic_mr_button_grey.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_05.png", "res/drawable-xxxhdpi-v4/ic_group_expand_14.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_12.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_06.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_09.png", "res/drawable-xxxhdpi-v4/ic_group_collapse_15.png", "res/values-en-rAU/values-en-rAU.xml", "res/values-en-rIN/values-en-rIN.xml", "res/values-zh-rTW/values-zh-rTW.xml", "res/values-sw/values-sw.xml", "res/values-nb/values-nb.xml", "res/values-bs-rBA/values-bs-rBA.xml", "res/values-tr/values-tr.xml", "res/values-kn-rIN/values-kn-rIN.xml", "res/values-hy-rAM/values-hy-rAM.xml", "res/values-sw600dp-v13/values-sw600dp-v13.xml", "res/values-es-rUS/values-es-rUS.xml", "res/values-land/values-land.xml", "res/values-zh-rHK/values-zh-rHK.xml", "res/values-ko/values-ko.xml", "res/values-pt-rPT/values-pt-rPT.xml", "res/values-iw/values-iw.xml", "res/values-lt/values-lt.xml", "res/values-ro/values-ro.xml", "res/values-pt/values-pt.xml", "res/values-ar/values-ar.xml", "res/values-ur-rPK/values-ur-rPK.xml", "res/values-ml-rIN/values-ml-rIN.xml", "res/drawable-xhdpi-v4/ic_mr_button_connected_20_light.png", "res/drawable-xhdpi-v4/ic_mr_button_disconnected_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_06_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_14_dark.png", "res/drawable-xhdpi-v4/ic_vol_type_speaker_group_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_18_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_12_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_15_dark.png", "res/drawable-xhdpi-v4/ic_audiotrack_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_01_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_18_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_04_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_04_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_09_dark.png", "res/drawable-xhdpi-v4/ic_vol_type_speaker_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_03_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_19_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_15_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_17_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_20_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_07_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_12_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_19_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_11_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_22_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_10_light.png", "res/drawable-xhdpi-v4/ic_vol_type_tv_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_13_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_16_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_08_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_07_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_05_light.png", "res/drawable-xhdpi-v4/ic_dialog_close_dark.png", "res/drawable-xhdpi-v4/ic_vol_type_tv_light.png", "res/drawable-xhdpi-v4/ic_mr_button_disabled_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_disabled_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_13_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_00_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_09_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_02_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_02_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_21_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_21_light.png", "res/drawable-xhdpi-v4/ic_dialog_close_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_15_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_13_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_07_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_17_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_21_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_01_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_19_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_02_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_02_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_09_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_18_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_05_light.png", "res/drawable-xhdpi-v4/ic_mr_button_disconnected_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_10_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_14_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_00_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_03_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_15_light.png", "res/drawable-xhdpi-v4/ic_vol_type_speaker_group_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_06_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_11_light.png", "res/drawable-xhdpi-v4/ic_vol_type_speaker_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_10_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_16_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_08_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_09_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_11_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_05_dark.png", "res/drawable-xhdpi-v4/ic_media_pause_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_10_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_22_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_17_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_grey.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_08_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_04_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_16_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_20_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_03_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_14_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_17_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_06_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_06_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_20_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_01_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_16_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_21_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_12_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_12_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_22_light.png", "res/drawable-xhdpi-v4/ic_audiotrack_dark.png", "res/drawable-xhdpi-v4/ic_media_play_light.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_19_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_05_dark.png", "res/drawable-xhdpi-v4/ic_media_pause_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_22_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_14_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_11_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_00_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_08_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_13_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_18_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connecting_04_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_07_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_00_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_01_light.png", "res/drawable-xhdpi-v4/ic_media_play_dark.png", "res/drawable-xhdpi-v4/ic_mr_button_connected_03_light.png", "res/values/values.xml", "res/values-hr/values-hr.xml", "res/values-mn-rMN/values-mn-rMN.xml", "res/values-da/values-da.xml", "res/values-hi/values-hi.xml", "res/values-it/values-it.xml", "res/values-es/values-es.xml", "res/values-sk/values-sk.xml", "res/values-lv/values-lv.xml", "res/values-ky-rKG/values-ky-rKG.xml", "res/values-hu/values-hu.xml", "res/drawable-xxhdpi-v4/ic_mr_button_connected_20_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_disconnected_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_06_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_14_dark.png", "res/drawable-xxhdpi-v4/ic_vol_type_speaker_group_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_18_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_12_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_15_dark.png", "res/drawable-xxhdpi-v4/ic_audiotrack_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_01_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_18_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_04_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_04_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_09_dark.png", "res/drawable-xxhdpi-v4/ic_vol_type_speaker_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_03_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_19_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_15_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_17_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_20_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_07_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_12_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_19_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_11_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_22_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_10_light.png", "res/drawable-xxhdpi-v4/ic_vol_type_tv_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_13_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_16_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_08_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_07_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_05_light.png", "res/drawable-xxhdpi-v4/ic_dialog_close_dark.png", "res/drawable-xxhdpi-v4/ic_vol_type_tv_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_disabled_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_disabled_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_13_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_00_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_09_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_02_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_02_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_21_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_21_light.png", "res/drawable-xxhdpi-v4/ic_dialog_close_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_15_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_13_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_07_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_17_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_21_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_01_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_19_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_02_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_02_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_09_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_18_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_05_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_disconnected_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_10_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_14_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_00_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_03_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_15_light.png", "res/drawable-xxhdpi-v4/ic_vol_type_speaker_group_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_06_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_11_light.png", "res/drawable-xxhdpi-v4/ic_vol_type_speaker_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_10_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_16_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_08_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_09_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_11_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_05_dark.png", "res/drawable-xxhdpi-v4/ic_media_pause_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_10_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_22_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_17_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_grey.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_08_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_04_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_16_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_20_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_03_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_14_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_17_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_06_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_06_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_20_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_01_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_16_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_21_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_12_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_12_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_22_light.png", "res/drawable-xxhdpi-v4/ic_audiotrack_dark.png", "res/drawable-xxhdpi-v4/ic_media_play_light.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_19_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_05_dark.png", "res/drawable-xxhdpi-v4/ic_media_pause_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_22_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_14_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_11_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_00_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_08_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_13_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_18_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connecting_04_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_07_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_00_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_01_light.png", "res/drawable-xxhdpi-v4/ic_media_play_dark.png", "res/drawable-xxhdpi-v4/ic_mr_button_connected_03_light.png", "res/values-th/values-th.xml", "res/values-cs/values-cs.xml", "res/values-sr/values-sr.xml", "res/values-tl/values-tl.xml", "res/values-te-rIN/values-te-rIN.xml", "res/values-ne-rNP/values-ne-rNP.xml", "res/values-ta-rIN/values-ta-rIN.xml", "res/drawable/mr_button_connecting_light.xml", "res/drawable/mr_group_collapse.xml", "res/drawable/mr_button_connecting_dark.xml", "res/drawable/mr_dialog_close_dark.xml", "res/drawable/mr_vol_type_audiotrack_dark.xml", "res/drawable/mr_media_pause_light.xml", "res/drawable/mr_group_expand.xml", "res/drawable/mr_vol_type_audiotrack_light.xml", "res/drawable/mr_dialog_material_background_light.xml", "res/drawable/mr_media_play_dark.xml", "res/drawable/mr_button_dark.xml", "res/drawable/mr_media_pause_dark.xml", "res/drawable/mr_dialog_material_background_dark.xml", "res/drawable/mr_button_connected_light.xml", "res/drawable/mr_dialog_close_light.xml", "res/drawable/mr_media_play_light.xml", "res/drawable/mr_button_connected_dark.xml", "res/drawable/mr_button_light.xml" ] +subjar_tuples = [ [ "internal_impl_25.0.1", "libs/internal_impl-25.0.1.jar" ] ] +subjars = [ "libs/internal_impl-25.0.1.jar" ]
diff --git a/build/secondary/third_party/android_tools/android_support_v7_palette_java.info b/build/secondary/third_party/android_tools/android_support_v7_palette_java.info new file mode 100644 index 0000000..a2ebd4a --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v7_palette_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_v7_preference_java.info b/build/secondary/third_party/android_tools/android_support_v7_preference_java.info new file mode 100644 index 0000000..fc60261 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v7_preference_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/values-v17/values-v17.xml", "res/layout/preference_dropdown.xml", "res/layout/preference_list_fragment.xml", "res/layout/preference.xml", "res/layout/preference_category.xml", "res/layout/preference_widget_checkbox.xml", "res/layout/preference_widget_switch_compat.xml", "res/layout/preference_information.xml", "res/layout/preference_recyclerview.xml", "res/layout/preference_dialog_edittext.xml", "res/values/values.xml", "res/layout-v11/preference_dropdown.xml", "res/layout-v11/preference.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_v7_recyclerview_java.info b/build/secondary/third_party/android_tools/android_support_v7_recyclerview_java.info new file mode 100644 index 0000000..a25d255 --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_v7_recyclerview_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/values/values.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/android_support_vector_drawable_java.info b/build/secondary/third_party/android_tools/android_support_vector_drawable_java.info new file mode 100644 index 0000000..a2ebd4a --- /dev/null +++ b/build/secondary/third_party/android_tools/android_support_vector_drawable_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_auth_base_java.info b/build/secondary/third_party/android_tools/google_play_services_auth_base_java.info new file mode 100644 index 0000000..0dfcb237 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_auth_base_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_auth_java.info b/build/secondary/third_party/android_tools/google_play_services_auth_java.info new file mode 100644 index 0000000..acf40e8 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_auth_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = false +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_base_java.info b/build/secondary/third_party/android_tools/google_play_services_base_java.info new file mode 100644 index 0000000..0a0aeb4 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_base_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = false +resources = [ "res/color/common_google_signin_btn_text_dark.xml", "res/color/common_google_signin_btn_text_light.xml", "res/color/common_google_signin_btn_tint.xml", "res/drawable-hdpi-v4/common_full_open_on_phone.png", "res/drawable-hdpi-v4/common_google_signin_btn_icon_dark_normal_background.9.png", "res/drawable-hdpi-v4/common_google_signin_btn_icon_light_normal_background.9.png", "res/drawable-hdpi-v4/common_google_signin_btn_text_dark_normal_background.9.png", "res/drawable-hdpi-v4/common_google_signin_btn_text_light_normal_background.9.png", "res/drawable-hdpi-v4/googleg_disabled_color_18.png", "res/drawable-hdpi-v4/googleg_standard_color_18.png", "res/drawable-mdpi-v4/common_google_signin_btn_icon_dark_normal_background.9.png", "res/drawable-mdpi-v4/common_google_signin_btn_icon_light_normal_background.9.png", "res/drawable-mdpi-v4/common_google_signin_btn_text_dark_normal_background.9.png", "res/drawable-mdpi-v4/common_google_signin_btn_text_light_normal_background.9.png", "res/drawable-mdpi-v4/googleg_disabled_color_18.png", "res/drawable-mdpi-v4/googleg_standard_color_18.png", "res/drawable-xhdpi-v4/common_full_open_on_phone.png", "res/drawable-xhdpi-v4/common_google_signin_btn_icon_dark_normal_background.9.png", "res/drawable-xhdpi-v4/common_google_signin_btn_icon_light_normal_background.9.png", "res/drawable-xhdpi-v4/common_google_signin_btn_text_dark_normal_background.9.png", "res/drawable-xhdpi-v4/common_google_signin_btn_text_light_normal_background.9.png", "res/drawable-xhdpi-v4/googleg_disabled_color_18.png", "res/drawable-xhdpi-v4/googleg_standard_color_18.png", "res/drawable-xxhdpi-v4/common_google_signin_btn_icon_dark_normal_background.9.png", "res/drawable-xxhdpi-v4/common_google_signin_btn_icon_light_normal_background.9.png", "res/drawable-xxhdpi-v4/common_google_signin_btn_text_dark_normal_background.9.png", "res/drawable-xxhdpi-v4/common_google_signin_btn_text_light_normal_background.9.png", "res/drawable-xxhdpi-v4/googleg_disabled_color_18.png", "res/drawable-xxhdpi-v4/googleg_standard_color_18.png", "res/drawable/common_google_signin_btn_icon_dark.xml", "res/drawable/common_google_signin_btn_icon_dark_focused.xml", "res/drawable/common_google_signin_btn_icon_dark_normal.xml", "res/drawable/common_google_signin_btn_icon_disabled.xml", "res/drawable/common_google_signin_btn_icon_light.xml", "res/drawable/common_google_signin_btn_icon_light_focused.xml", "res/drawable/common_google_signin_btn_icon_light_normal.xml", "res/drawable/common_google_signin_btn_text_dark.xml", "res/drawable/common_google_signin_btn_text_dark_focused.xml", "res/drawable/common_google_signin_btn_text_dark_normal.xml", "res/drawable/common_google_signin_btn_text_disabled.xml", "res/drawable/common_google_signin_btn_text_light.xml", "res/drawable/common_google_signin_btn_text_light_focused.xml", "res/drawable/common_google_signin_btn_text_light_normal.xml", "res/values-af/values.xml", "res/values-am/values.xml", "res/values-ar/values.xml", "res/values-az/values.xml", "res/values-be/values.xml", "res/values-bg/values.xml", "res/values-bn/values.xml", "res/values-bs/values.xml", "res/values-ca/values.xml", "res/values-cs/values.xml", "res/values-da/values.xml", "res/values-de/values.xml", "res/values-el/values.xml", "res/values-en-rGB/values.xml", "res/values-es-rUS/values.xml", "res/values-es/values.xml", "res/values-et/values.xml", "res/values-eu/values.xml", "res/values-fa/values.xml", "res/values-fi/values.xml", "res/values-fr-rCA/values.xml", "res/values-fr/values.xml", "res/values-gl/values.xml", "res/values-gu/values.xml", "res/values-hi/values.xml", "res/values-hr/values.xml", "res/values-hu/values.xml", "res/values-hy/values.xml", "res/values-in/values.xml", "res/values-is/values.xml", "res/values-it/values.xml", "res/values-iw/values.xml", "res/values-ja/values.xml", "res/values-ka/values.xml", "res/values-kk/values.xml", "res/values-km/values.xml", "res/values-kn/values.xml", "res/values-ko/values.xml", "res/values-ky/values.xml", "res/values-lo/values.xml", "res/values-lt/values.xml", "res/values-lv/values.xml", "res/values-mk/values.xml", "res/values-ml/values.xml", "res/values-mn/values.xml", "res/values-mr/values.xml", "res/values-ms/values.xml", "res/values-my/values.xml", "res/values-nb/values.xml", "res/values-ne/values.xml", "res/values-nl/values.xml", "res/values-pa/values.xml", "res/values-pl/values.xml", "res/values-pt-rBR/values.xml", "res/values-pt-rPT/values.xml", "res/values-ro/values.xml", "res/values-ru/values.xml", "res/values-si/values.xml", "res/values-sk/values.xml", "res/values-sl/values.xml", "res/values-sq/values.xml", "res/values-sr/values.xml", "res/values-sv/values.xml", "res/values-sw/values.xml", "res/values-ta/values.xml", "res/values-te/values.xml", "res/values-th/values.xml", "res/values-tl/values.xml", "res/values-tr/values.xml", "res/values-uk/values.xml", "res/values-ur/values.xml", "res/values-uz/values.xml", "res/values-vi/values.xml", "res/values-zh-rCN/values.xml", "res/values-zh-rHK/values.xml", "res/values-zh-rTW/values.xml", "res/values-zu/values.xml", "res/values/values.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_basement_java.info b/build/secondary/third_party/android_tools/google_play_services_basement_java.info new file mode 100644 index 0000000..19c75ad --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_basement_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = true +is_manifest_empty = false +resources = [ "res/values-af/values.xml", "res/values-am/values.xml", "res/values-ar/values.xml", "res/values-az/values.xml", "res/values-be/values.xml", "res/values-bg/values.xml", "res/values-bn/values.xml", "res/values-bs/values.xml", "res/values-ca/values.xml", "res/values-cs/values.xml", "res/values-da/values.xml", "res/values-de/values.xml", "res/values-el/values.xml", "res/values-en-rGB/values.xml", "res/values-es-rUS/values.xml", "res/values-es/values.xml", "res/values-et/values.xml", "res/values-eu/values.xml", "res/values-fa/values.xml", "res/values-fi/values.xml", "res/values-fr-rCA/values.xml", "res/values-fr/values.xml", "res/values-gl/values.xml", "res/values-gu/values.xml", "res/values-hi/values.xml", "res/values-hr/values.xml", "res/values-hu/values.xml", "res/values-hy/values.xml", "res/values-in/values.xml", "res/values-is/values.xml", "res/values-it/values.xml", "res/values-iw/values.xml", "res/values-ja/values.xml", "res/values-ka/values.xml", "res/values-kk/values.xml", "res/values-km/values.xml", "res/values-kn/values.xml", "res/values-ko/values.xml", "res/values-ky/values.xml", "res/values-lo/values.xml", "res/values-lt/values.xml", "res/values-lv/values.xml", "res/values-mk/values.xml", "res/values-ml/values.xml", "res/values-mn/values.xml", "res/values-mr/values.xml", "res/values-ms/values.xml", "res/values-my/values.xml", "res/values-nb/values.xml", "res/values-ne/values.xml", "res/values-nl/values.xml", "res/values-pa/values.xml", "res/values-pl/values.xml", "res/values-pt-rBR/values.xml", "res/values-pt-rPT/values.xml", "res/values-ro/values.xml", "res/values-ru/values.xml", "res/values-si/values.xml", "res/values-sk/values.xml", "res/values-sl/values.xml", "res/values-sq/values.xml", "res/values-sr/values.xml", "res/values-sv/values.xml", "res/values-sw/values.xml", "res/values-ta/values.xml", "res/values-te/values.xml", "res/values-th/values.xml", "res/values-tl/values.xml", "res/values-tr/values.xml", "res/values-uk/values.xml", "res/values-ur/values.xml", "res/values-uz/values.xml", "res/values-vi/values.xml", "res/values-zh-rCN/values.xml", "res/values-zh-rHK/values.xml", "res/values-zh-rTW/values.xml", "res/values-zu/values.xml", "res/values/values.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_cast_java.info b/build/secondary/third_party/android_tools/google_play_services_cast_java.info new file mode 100644 index 0000000..913e27b --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_cast_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = true +resources = [ "res/drawable-hdpi-v4/cast_ic_notification_0.png", "res/drawable-hdpi-v4/cast_ic_notification_1.png", "res/drawable-hdpi-v4/cast_ic_notification_2.png", "res/drawable-hdpi-v4/cast_ic_notification_on.png", "res/drawable-mdpi-v4/cast_ic_notification_0.png", "res/drawable-mdpi-v4/cast_ic_notification_1.png", "res/drawable-mdpi-v4/cast_ic_notification_2.png", "res/drawable-mdpi-v4/cast_ic_notification_on.png", "res/drawable-xhdpi-v4/cast_ic_notification_0.png", "res/drawable-xhdpi-v4/cast_ic_notification_1.png", "res/drawable-xhdpi-v4/cast_ic_notification_2.png", "res/drawable-xhdpi-v4/cast_ic_notification_on.png", "res/drawable-xxhdpi-v4/cast_ic_notification_0.png", "res/drawable-xxhdpi-v4/cast_ic_notification_1.png", "res/drawable-xxhdpi-v4/cast_ic_notification_2.png", "res/drawable-xxhdpi-v4/cast_ic_notification_on.png", "res/drawable/cast_ic_notification_connecting.xml", "res/values-af/values.xml", "res/values-am/values.xml", "res/values-ar/values.xml", "res/values-az/values.xml", "res/values-be/values.xml", "res/values-bg/values.xml", "res/values-bn/values.xml", "res/values-bs/values.xml", "res/values-ca/values.xml", "res/values-cs/values.xml", "res/values-da/values.xml", "res/values-de/values.xml", "res/values-el/values.xml", "res/values-en-rGB/values.xml", "res/values-es-rUS/values.xml", "res/values-es/values.xml", "res/values-et/values.xml", "res/values-eu/values.xml", "res/values-fa/values.xml", "res/values-fi/values.xml", "res/values-fr-rCA/values.xml", "res/values-fr/values.xml", "res/values-gl/values.xml", "res/values-gu/values.xml", "res/values-hi/values.xml", "res/values-hr/values.xml", "res/values-hu/values.xml", "res/values-hy/values.xml", "res/values-in/values.xml", "res/values-is/values.xml", "res/values-it/values.xml", "res/values-iw/values.xml", "res/values-ja/values.xml", "res/values-ka/values.xml", "res/values-kk/values.xml", "res/values-km/values.xml", "res/values-kn/values.xml", "res/values-ko/values.xml", "res/values-ky/values.xml", "res/values-lo/values.xml", "res/values-lt/values.xml", "res/values-lv/values.xml", "res/values-mk/values.xml", "res/values-ml/values.xml", "res/values-mn/values.xml", "res/values-mr/values.xml", "res/values-ms/values.xml", "res/values-my/values.xml", "res/values-nb/values.xml", "res/values-ne/values.xml", "res/values-nl/values.xml", "res/values-pa/values.xml", "res/values-pl/values.xml", "res/values-pt-rBR/values.xml", "res/values-pt-rPT/values.xml", "res/values-ro/values.xml", "res/values-ru/values.xml", "res/values-si/values.xml", "res/values-sk/values.xml", "res/values-sl/values.xml", "res/values-sq/values.xml", "res/values-sr/values.xml", "res/values-sv/values.xml", "res/values-sw/values.xml", "res/values-ta/values.xml", "res/values-te/values.xml", "res/values-th/values.xml", "res/values-tl/values.xml", "res/values-tr/values.xml", "res/values-uk/values.xml", "res/values-ur/values.xml", "res/values-uz/values.xml", "res/values-vi/values.xml", "res/values-zh-rCN/values.xml", "res/values-zh-rHK/values.xml", "res/values-zh-rTW/values.xml", "res/values-zu/values.xml", "res/values/values.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_gcm_java.info b/build/secondary/third_party/android_tools/google_play_services_gcm_java.info new file mode 100644 index 0000000..acf40e8 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_gcm_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = false +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_iid_java.info b/build/secondary/third_party/android_tools/google_play_services_iid_java.info new file mode 100644 index 0000000..acf40e8 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_iid_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = false +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_location_java.info b/build/secondary/third_party/android_tools/google_play_services_location_java.info new file mode 100644 index 0000000..0dfcb237 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_location_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_nearby_java.info b/build/secondary/third_party/android_tools/google_play_services_nearby_java.info new file mode 100644 index 0000000..acf40e8 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_nearby_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = false +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_tasks_java.info b/build/secondary/third_party/android_tools/google_play_services_tasks_java.info new file mode 100644 index 0000000..0dfcb237 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_tasks_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/build/secondary/third_party/android_tools/google_play_services_vision_java.info b/build/secondary/third_party/android_tools/google_play_services_vision_java.info new file mode 100644 index 0000000..0dfcb237 --- /dev/null +++ b/build/secondary/third_party/android_tools/google_play_services_vision_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = true +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index 9837932..3ef88ede 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1188,12 +1188,13 @@ } void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override { - if (host_impl->sync_tree()->source_frame_number() != 0) + // After activating the sync tree PrepareTiles will be called + // again (which races with the test exiting). + LayerTreeImpl* sync_tree = host_impl->sync_tree(); + if (!sync_tree || TestEnded()) return; - // After checking this on the sync tree, we will activate, which will cause - // PrepareTiles to happen again (which races with the test exiting). - if (TestEnded()) + if (sync_tree->source_frame_number() != 0) return; scoped_refptr<AnimationTimeline> timeline_impl = @@ -1201,7 +1202,7 @@ scoped_refptr<AnimationPlayer> player_impl = timeline_impl->GetPlayerById(player_id_); - LayerImpl* child = host_impl->sync_tree()->LayerById(layer_->id()); + LayerImpl* child = sync_tree->LayerById(layer_->id()); Animation* animation = player_impl->GetAnimation(TargetProperty::TRANSFORM); // The animation should be starting for the first frame. @@ -1225,13 +1226,8 @@ scoped_refptr<Layer> layer_; }; -SINGLE_THREAD_TEST_F(LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit); - -// The multi-thread test is flaky. See http://crbug.com/755965. -using DISABLED_LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit = - LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit; -MULTI_THREAD_TEST_F( - DISABLED_LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit); +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit); // When a layer with an animation is removed from the tree and later re-added, // the animation should resume.
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 4a08e51..802a7fa 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -189,6 +189,7 @@ "$google_play_services_package:google_play_services_nearby_java", "$google_play_services_package:google_play_services_tasks_java", "//base:base_java", + "//chrome/android/third_party/widget_bottomsheet_base:widget_bottomsheet_base_java", "//chrome/android/webapk/libs/client:client_java", "//chrome/android/webapk/libs/common:common_java", "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 96eb57bc0..755d158 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -1581,7 +1581,7 @@ * that the compositor's surface should support alpha and not be marked as opaque. */ public void setOverlayMode(boolean useOverlayMode) { - mCompositorViewHolder.setOverlayMode(useOverlayMode); + if (mCompositorViewHolder != null) mCompositorViewHolder.setOverlayMode(useOverlayMode); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java index bb6cd67a..51106db 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
@@ -43,6 +43,7 @@ public static final String ACCOUNT_PICKER_DIALOG_TAG = "account_picker_dialog_tag"; public static final String EXTRA_SHOW_SEARCH_ENGINE_PICKER = "show_search_engine_picker"; + private SignInPreference mSignInPreference; private ManagedPreferenceDelegate mManagedPreferenceDelegate; public MainPreferences() { @@ -64,6 +65,7 @@ if (SigninManager.get(getActivity()).isSigninSupported()) { SigninManager.get(getActivity()).addSignInStateObserver(this); + setupSignInPref(); } } @@ -72,6 +74,7 @@ super.onPause(); if (SigninManager.get(getActivity()).isSigninSupported()) { SigninManager.get(getActivity()).removeSignInStateObserver(this); + clearSignInPref(); } } @@ -185,6 +188,18 @@ pref.setSummary(getResources().getString(isOn ? R.string.text_on : R.string.text_off)); } + private void setupSignInPref() { + mSignInPreference = (SignInPreference) findPreference(PREF_SIGN_IN); + mSignInPreference.registerForUpdates(); + } + + private void clearSignInPref() { + if (mSignInPreference != null) { + mSignInPreference.unregisterForUpdates(); + mSignInPreference = null; + } + } + // SignInStateObserver @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SignInPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SignInPreference.java index f396b75..9096a914 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SignInPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SignInPreference.java
@@ -7,7 +7,6 @@ import android.accounts.Account; import android.content.Context; import android.preference.Preference; -import android.preference.PreferenceManager; import android.support.v7.content.res.AppCompatResources; import android.util.AttributeSet; import android.view.View; @@ -58,10 +57,10 @@ mProfileDataCache = new ProfileDataCache(context, Profile.getLastUsedProfile(), imageSize); } - @Override - protected void onAttachedToHierarchy(PreferenceManager preferenceManager) { - super.onAttachedToHierarchy(preferenceManager); - + /** + * Starts listening for updates to the sign-in and sync state. + */ + public void registerForUpdates() { AccountManagerFacade.get().addObserver(this); SigninManager.get(getContext()).addSignInAllowedObserver(this); mProfileDataCache.addObserver(this); @@ -75,8 +74,11 @@ update(); } - @Override - protected void onPrepareForRemoval() { + /** + * Stops listening for updates to the sign-in and sync state. Every call to registerForUpdates() + * must be matched with a call to this method. + */ + public void unregisterForUpdates() { AccountManagerFacade.get().removeObserver(this); SigninManager.get(getContext()).removeSignInAllowedObserver(this); mProfileDataCache.removeObserver(this); @@ -85,8 +87,6 @@ if (syncService != null) { syncService.removeSyncStateChangedListener(this); } - - super.onPrepareForRemoval(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java index dedc40e6..ee80947 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
@@ -61,6 +61,11 @@ Boolean isBackButtonEnabled(); /** + * Returns whether the forward button is enabled. + */ + Boolean isForwardButtonEnabled(); + + /** * Requests to exit VR. */ void requestToExitVr(@UiUnsupportedMode int reason); @@ -70,4 +75,14 @@ * VrShell from the view hierarchy. */ void onBeforeWindowDetached(); + + /** + * Triggers VrShell to navigate forward. + */ + void navigateForward(); + + /** + * Triggers VrShell to navigate backward. + */ + void navigateBack(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 3e6f790..536c0ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -650,6 +650,8 @@ UrlConstants.NTP_URL, TabLaunchType.FROM_CHROME_UI); } + @VisibleForTesting + @Override @CalledByNative public void navigateForward() { if (!mCanGoForward) return; @@ -657,6 +659,8 @@ updateHistoryButtonsVisibility(); } + @VisibleForTesting + @Override @CalledByNative public void navigateBack() { if (!mCanGoBack) return; @@ -720,6 +724,12 @@ } @VisibleForTesting + @Override + public Boolean isForwardButtonEnabled() { + return mCanGoForward; + } + + @VisibleForTesting public float getContentWidthForTesting() { return mLastContentWidth; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/PasswordViewingTypeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/PasswordViewingTypeTest.java index 0b33c64..7602064 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/PasswordViewingTypeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/PasswordViewingTypeTest.java
@@ -12,7 +12,6 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; -import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -76,11 +75,6 @@ mAccountManager.addAccountHolderExplicitly(accountHolder.build()); } - @After - public void tearDown() { - AccountManagerFacade.resetAccountManagerFacadeForTests(); - } - /** * Launches the main preferences. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java index ddb81326..5b50ee92 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellNavigationTest.java
@@ -290,7 +290,7 @@ @MediumTest @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM) public void testBackDoesntBackgroundChrome() - throws IllegalArgumentException, InterruptedException, TimeoutException { + throws IllegalArgumentException, InterruptedException { Assert.assertFalse("Back button isn't disabled.", VrTransitionUtils.isBackButtonEnabled()); mVrTestRule.loadUrlInNewTab(getUrl(Page.PAGE_2D), false, TabLaunchType.FROM_CHROME_UI); Assert.assertFalse("Back button isn't disabled.", VrTransitionUtils.isBackButtonEnabled()); @@ -305,4 +305,32 @@ }); Assert.assertFalse("Back button isn't disabled.", VrTransitionUtils.isBackButtonEnabled()); } + + /** + * Tests navigation from a fullscreened WebVR to a WebVR page. + */ + @Test + @MediumTest + @Restriction(RESTRICTION_TYPE_VIEWER_DAYDREAM) + public void testNavigationButtons() throws IllegalArgumentException, InterruptedException { + Assert.assertFalse("Back button isn't disabled.", VrTransitionUtils.isBackButtonEnabled()); + Assert.assertFalse( + "Forward button isn't disabled.", VrTransitionUtils.isForwardButtonEnabled()); + mVrTestRule.loadUrlInNewTab(getUrl(Page.PAGE_2D), false, TabLaunchType.FROM_CHROME_UI); + Assert.assertFalse("Back button isn't disabled.", VrTransitionUtils.isBackButtonEnabled()); + Assert.assertFalse( + "Forward button isn't disabled.", VrTransitionUtils.isForwardButtonEnabled()); + mVrTestRule.loadUrl(getUrl(Page.PAGE_WEBVR)); + Assert.assertTrue("Back button isn't enabled.", VrTransitionUtils.isBackButtonEnabled()); + Assert.assertFalse( + "Forward button isn't disabled.", VrTransitionUtils.isForwardButtonEnabled()); + VrTransitionUtils.navigateBack(); + Assert.assertFalse("Back button isn't disabled.", VrTransitionUtils.isBackButtonEnabled()); + Assert.assertTrue( + "Forward button isn't enabled.", VrTransitionUtils.isForwardButtonEnabled()); + VrTransitionUtils.navigateForward(); + Assert.assertTrue("Back button isn't enabled.", VrTransitionUtils.isBackButtonEnabled()); + Assert.assertFalse( + "Forward button isn't disabled.", VrTransitionUtils.isForwardButtonEnabled()); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java index bbe8292..ec99c13f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/VrTransitionUtils.java
@@ -141,6 +141,45 @@ } /** + * @return Whether the VR forward button is enabled. + */ + public static Boolean isForwardButtonEnabled() { + final AtomicBoolean isForwardButtonEnabled = new AtomicBoolean(); + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + isForwardButtonEnabled.set( + VrShellDelegate.getVrShellForTesting().isForwardButtonEnabled()); + } + }); + return isForwardButtonEnabled.get(); + } + + /** + * Navigates VrShell back. + */ + public static void navigateBack() { + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + VrShellDelegate.getVrShellForTesting().navigateBack(); + } + }); + } + + /** + * Navigates VrShell forward. + */ + public static void navigateForward() { + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + VrShellDelegate.getVrShellForTesting().navigateForward(); + } + }); + } + + /** * Sends an intent to Chrome telling it to autopresent the given URL. This * is expected to fail unless the trusted intent check is disabled in VrShellDelegate. *
diff --git a/chrome/android/third_party/widget_bottomsheet_base/BUILD.gn b/chrome/android/third_party/widget_bottomsheet_base/BUILD.gn new file mode 100644 index 0000000..78bcb51 --- /dev/null +++ b/chrome/android/third_party/widget_bottomsheet_base/BUILD.gn
@@ -0,0 +1,26 @@ +# Copyright 2017 Google Inc. +# +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/android/rules.gni") + +android_library("widget_bottomsheet_base_java") { + java_files = [ + "java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperBase.java", + "java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperIcs.java", + "java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationItemView.java", + "java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenu.java", + "java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenuView.java", + "java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationPresenter.java", + "java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationView.java", + "java/src/org/chromium/chrome/browser/widget/bottomsheet/base/ThemeUtils.java", + ] + + deps = [ + "//third_party/android_tools:android_support_annotations_java", + "//third_party/android_tools:android_support_design_java", + "//third_party/android_tools:android_support_transition_java", + "//third_party/android_tools:android_support_v7_appcompat_java", + ] +}
diff --git a/chrome/android/third_party/widget_bottomsheet_base/README.chromium b/chrome/android/third_party/widget_bottomsheet_base/README.chromium index dc2aa0a..1f06148 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/README.chromium +++ b/chrome/android/third_party/widget_bottomsheet_base/README.chromium
@@ -6,4 +6,5 @@ Bottom navigation menu widget from Android SDK Sources 25. Local Modifications: -* None. \ No newline at end of file +* Change package. +* Removed unnecessary version check when creating animation helper in BottomNavigationMenuView. \ No newline at end of file
diff --git a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperBase.java b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperBase.java index 3d0e91b..5d1ea008 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperBase.java +++ b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperBase.java
@@ -14,10 +14,13 @@ * limitations under the License. */ -package android.support.design.internal; +package org.chromium.chrome.browser.widget.bottomsheet.base; import android.view.ViewGroup; +/** + * Forked from android.support.design.internal.BottomNavigationAnimationHelperBase. + */ class BottomNavigationAnimationHelperBase { void beginDelayedTransition(ViewGroup view) { // Do nothing.
diff --git a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperIcs.java b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperIcs.java index e8766f472..bde2b91 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperIcs.java +++ b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationAnimationHelperIcs.java
@@ -14,15 +14,17 @@ * limitations under the License. */ -package android.support.design.internal; +package org.chromium.chrome.browser.widget.bottomsheet.base; +import android.support.design.internal.TextScale; import android.support.transition.AutoTransition; import android.support.transition.TransitionManager; import android.support.transition.TransitionSet; import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.view.ViewGroup; -class BottomNavigationAnimationHelperIcs extends BottomNavigationAnimationHelperBase { +/** Forked from android.support.design.internal.BottomNavigationAnimationHelperIcs */ +public class BottomNavigationAnimationHelperIcs extends BottomNavigationAnimationHelperBase { private static final long ACTIVE_ANIMATION_DURATION_MS = 115L; private final TransitionSet mSet;
diff --git a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationItemView.java b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationItemView.java index c5ed684..c1af27a 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationItemView.java +++ b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationItemView.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package android.support.design.internal; +package org.chromium.chrome.browser.widget.bottomsheet.base; import static android.support.annotation.RestrictTo.Scope.GROUP_ID; @@ -38,6 +38,8 @@ import android.widget.TextView; /** + * Forked from android.support.design.internal.BottomNavigationItemView. + * * @hide */ @RestrictTo(GROUP_ID) @@ -130,9 +132,9 @@ @Override public void setChecked(boolean checked) { - ViewCompat.setPivotX(mLargeLabel, mLargeLabel.getWidth() / 2); + ViewCompat.setPivotX(mLargeLabel, mLargeLabel.getWidth() / 2f); ViewCompat.setPivotY(mLargeLabel, mLargeLabel.getBaseline()); - ViewCompat.setPivotX(mSmallLabel, mSmallLabel.getWidth() / 2); + ViewCompat.setPivotX(mSmallLabel, mSmallLabel.getWidth() / 2f); ViewCompat.setPivotY(mSmallLabel, mSmallLabel.getBaseline()); if (mShiftingMode) { if (checked) { @@ -242,4 +244,4 @@ background == 0 ? null : ContextCompat.getDrawable(getContext(), background); ViewCompat.setBackground(this, backgroundDrawable); } -} \ No newline at end of file +}
diff --git a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenu.java b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenu.java index eaf5ad4..8110478 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenu.java +++ b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenu.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package android.support.design.internal; +package org.chromium.chrome.browser.widget.bottomsheet.base; import static android.support.annotation.RestrictTo.Scope.GROUP_ID; @@ -26,6 +26,8 @@ import android.view.SubMenu; /** + * Forked from android.support.design.internal.BottomNavigationMenu. + * * @hide */ @RestrictTo(GROUP_ID) @@ -56,4 +58,4 @@ startDispatchingItemsChanged(); return item; } -} \ No newline at end of file +}
diff --git a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenuView.java b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenuView.java index d05c414b..27a630b 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenuView.java +++ b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationMenuView.java
@@ -21,10 +21,11 @@ import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; -import android.os.Build; import android.support.annotation.Nullable; import android.support.annotation.RestrictTo; import android.support.design.R; +import android.support.design.internal.BottomNavigationItemView; +import android.support.design.internal.BottomNavigationPresenter; import android.support.v4.util.Pools; import android.support.v4.view.ViewCompat; import android.support.v7.view.menu.MenuBuilder; @@ -82,7 +83,12 @@ mOnClickListener = new OnClickListener() { @Override public void onClick(View v) { - final BottomNavigationItemView itemView = (BottomNavigationItemView) v; + BottomNavigationItemView itemView; + try { + itemView = (BottomNavigationItemView) v; + } catch (ClassCastException e) { + return; + } final int itemPosition = itemView.getItemPosition(); if (!mMenu.performItemAction(itemView.getItemData(), mPresenter, 0)) { activateNewButton(itemPosition);
diff --git a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationPresenter.java b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationPresenter.java index 6d020bf..37a52bc 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationPresenter.java +++ b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationPresenter.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package android.support.design.internal; +package org.chromium.chrome.browser.widget.bottomsheet.base; import android.content.Context; import android.os.Parcelable; @@ -29,6 +29,8 @@ import static android.support.annotation.RestrictTo.Scope.GROUP_ID; /** + * Forked from android.support.design.internal.BottomNavigationPresenter. + * * @hide */ @RestrictTo(GROUP_ID) @@ -104,4 +106,4 @@ public void setUpdateSuspended(boolean updateSuspended) { mUpdateSuspended = updateSuspended; } -} \ No newline at end of file +}
diff --git a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationView.java b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationView.java index a6909e3..5539db2 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationView.java +++ b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/BottomNavigationView.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package android.support.design.widget; +package org.chromium.chrome.browser.widget.bottomsheet.base; import android.content.Context; import android.content.res.ColorStateList; @@ -43,6 +43,8 @@ import android.widget.FrameLayout; /** + * Forked from android.support.design.internal.BottomNavigationView. + * * <p> * Represents a standard bottom navigation bar for application. It is an implementation of * <a href="https://material.google.com/components/bottom-navigation.html">material design bottom @@ -335,4 +337,4 @@ new int[] {baseColor.getColorForState(DISABLED_STATE_SET, defaultColor), colorPrimary, defaultColor}); } -} \ No newline at end of file +}
diff --git a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/ThemeUtils.java b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/ThemeUtils.java index 2f1cf405..98a2719 100644 --- a/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/ThemeUtils.java +++ b/chrome/android/third_party/widget_bottomsheet_base/java/src/org/chromium/chrome/browser/widget/bottomsheet/base/ThemeUtils.java
@@ -14,22 +14,23 @@ * limitations under the License. */ -package android.support.design.widget; +package org.chromium.chrome.browser.widget.bottomsheet.base; import android.content.Context; import android.content.res.TypedArray; import android.support.design.R; -class ThemeUtils { +/** + * Forked from android.support.design.widget.ThemeUtils. + */ +public class ThemeUtils { private static final int[] APPCOMPAT_CHECK_ATTRS = { android.support.v7.appcompat.R.attr.colorPrimary}; static void checkAppCompatTheme(Context context) { TypedArray a = context.obtainStyledAttributes(APPCOMPAT_CHECK_ATTRS); final boolean failed = !a.hasValue(0); - if (a != null) { - a.recycle(); - } + a.recycle(); if (failed) { throw new IllegalArgumentException("You need to use a Theme.AppCompat theme " + "(or descendant) with the design library.");
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 382535a..8bb443e 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -36,6 +36,9 @@ <message name="IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_BETA" desc="The beta label in the message about current channel."> beta </message> + <message name="IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_CANARY" desc="The canary label in the message about current channel."> + canary + </message> <message name="IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_DEV" desc="The dev label in the message about current channel."> dev </message>
diff --git a/chrome/browser/android/history/browsing_history_bridge.cc b/chrome/browser/android/history/browsing_history_bridge.cc index 03c27aa..11c81d8f5 100644 --- a/chrome/browser/android/history/browsing_history_bridge.cc +++ b/chrome/browser/android/history/browsing_history_bridge.cc
@@ -108,7 +108,7 @@ Java_BrowsingHistoryBridge_onQueryHistoryComplete( env, j_history_service_obj_, j_query_result_obj_, - !(query_results_info.reached_beginning)); + !(query_results_info.reached_beginning_of_local)); } void BrowsingHistoryBridge::MarkItemForRemoval(
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index e011d41..328da5d 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -1539,12 +1539,6 @@ NEEDS_TEST_SERVER); } -// Very flaky on Mac: http://crbug.com/614377 -#ifdef OS_MAC -#define MAYBE_Shim_TestDeclarativeWebRequestAPISendMessage DISABLED_Shim_TestDeclarativeWebRequestAPISendMessage -#else -#define MAYBE_Shim_TestDeclarativeWebRequestAPISendMessage Shim_TestDeclarativeWebRequestAPISendMessage -#endif IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestDeclarativeWebRequestAPISendMessage) { TestHelper("testDeclarativeWebRequestAPISendMessage", @@ -1552,6 +1546,13 @@ NEEDS_TEST_SERVER); } +IN_PROC_BROWSER_TEST_P( + WebViewTest, + Shim_TestDeclarativeWebRequestAPISendMessageSecondWebView) { + TestHelper("testDeclarativeWebRequestAPISendMessageSecondWebView", + "web_view/shim", NEEDS_TEST_SERVER); +} + IN_PROC_BROWSER_TEST_P(WebViewTest, Shim_TestWebRequestAPI) { TestHelper("testWebRequestAPI", "web_view/shim", NEEDS_TEST_SERVER); }
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 3a6d7e7..be834deb 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -385,6 +385,8 @@ "arc/notification/arc_boot_error_notification.h", "arc/notification/arc_provision_notification_service.cc", "arc/notification/arc_provision_notification_service.h", + "arc/oemcrypto/arc_oemcrypto_bridge.cc", + "arc/oemcrypto/arc_oemcrypto_bridge.h", "arc/optin/arc_optin_preference_handler.cc", "arc/optin/arc_optin_preference_handler.h", "arc/optin/arc_optin_preference_handler_observer.h",
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc index 106e1a8..927945de 100644 --- a/chrome/browser/chromeos/arc/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/chromeos/arc/kiosk/arc_kiosk_bridge.h" #include "chrome/browser/chromeos/arc/notification/arc_boot_error_notification.h" #include "chrome/browser/chromeos/arc/notification/arc_provision_notification_service.h" +#include "chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h" #include "chrome/browser/chromeos/arc/policy/arc_policy_bridge.h" #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" #include "chrome/browser/chromeos/arc/print/arc_print_service.h" @@ -49,7 +50,6 @@ #include "components/arc/metrics/arc_metrics_service.h" #include "components/arc/net/arc_net_host_impl.h" #include "components/arc/obb_mounter/arc_obb_mounter_bridge.h" -#include "components/arc/oemcrypto/arc_oemcrypto_bridge.h" #include "components/arc/power/arc_power_bridge.h" #include "components/arc/storage_manager/arc_storage_manager.h" #include "components/arc/volume_mounter/arc_volume_mounter_bridge.h"
diff --git a/components/arc/oemcrypto/arc_oemcrypto_bridge.cc b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc similarity index 85% rename from components/arc/oemcrypto/arc_oemcrypto_bridge.cc rename to chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc index e0d1498..941af6c5 100644 --- a/components/arc/oemcrypto/arc_oemcrypto_bridge.cc +++ b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc
@@ -2,10 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/oemcrypto/arc_oemcrypto_bridge.h" +#include "chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h" #include "base/bind.h" #include "base/memory/singleton.h" +#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chromeos/dbus/arc_oemcrypto_client.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "components/arc/arc_bridge_service.h" @@ -84,6 +85,24 @@ void ArcOemCryptoBridge::Connect(mojom::OemCryptoServiceRequest request) { DVLOG(1) << "ArcOemCryptoBridge::Connect called"; + + // Check that the user has Attestation for Content Protection enabled in + // their Chrome settings and if they do not then block this connection since + // OEMCrypto utilizes Attestation as the root of trust for its DRM + // implementation. + bool attestation_enabled = false; + if (!chromeos::CrosSettings::Get()->GetBoolean( + chromeos::kAttestationForContentProtectionEnabled, + &attestation_enabled)) { + LOG(ERROR) << "Failed to get attestation device setting"; + return; + } + if (!attestation_enabled) { + DVLOG(1) << "OEMCrypto L1 DRM denied because Verified Access is disabled " + "for this device."; + return; + } + if (oemcrypto_host_ptr_.is_bound()) { DVLOG(1) << "Re-using bootstrap connection for OemCryptoService Connect"; oemcrypto_host_ptr_->Connect(std::move(request));
diff --git a/components/arc/oemcrypto/arc_oemcrypto_bridge.h b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h similarity index 89% rename from components/arc/oemcrypto/arc_oemcrypto_bridge.h rename to chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h index c15b6b1..ede2407c 100644 --- a/components/arc/oemcrypto/arc_oemcrypto_bridge.h +++ b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_OEMCRYPTO_ARC_OEMCRYPTO_BRIDGE_H_ -#define COMPONENTS_ARC_OEMCRYPTO_ARC_OEMCRYPTO_BRIDGE_H_ +#ifndef CHROME_BROWSER_CHROMEOS_ARC_OEMCRYPTO_ARC_OEMCRYPTO_BRIDGE_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_OEMCRYPTO_ARC_OEMCRYPTO_BRIDGE_H_ #include <stdint.h> @@ -59,4 +59,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_OEMCRYPTO_ARC_OEMCRYPTO_BRIDGE_H_ +#endif // CHROME_BROWSER_CHROMEOS_ARC_OEMCRYPTO_ARC_OEMCRYPTO_BRIDGE_H_
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc b/chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc index 533dd3d..c20d346 100644 --- a/chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc +++ b/chrome/browser/data_use_measurement/chrome_data_use_ascriber.cc
@@ -90,16 +90,25 @@ } ChromeDataUseAscriber::DataUseRecorderEntry -ChromeDataUseAscriber::GetOrCreateDataUseRecorderEntry( - net::URLRequest* request) { +ChromeDataUseAscriber::GetDataUseRecorderEntry(net::URLRequest* request) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); // If a DataUseRecorder has already been set as user data, then return that. auto* user_data = static_cast<DataUseRecorderEntryAsUserData*>(request->GetUserData( DataUseRecorderEntryAsUserData::kDataUseAscriberUserDataKey)); - if (user_data) - return user_data->recorder_entry(); + return user_data ? user_data->recorder_entry() : data_use_recorders_.end(); +} + +ChromeDataUseAscriber::DataUseRecorderEntry +ChromeDataUseAscriber::GetOrCreateDataUseRecorderEntry( + net::URLRequest* request) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + // If a DataUseRecorder has already been created, then return that. + auto recorder = GetDataUseRecorderEntry(request); + if (recorder != data_use_recorders_.end()) + return recorder; // If request is associated with a ChromeService, create a new // DataUseRecorder for it. There is no reason to aggregate URLRequests @@ -217,10 +226,7 @@ if (IsDisabledPlatform()) return; - // TODO(rajendrant): GetDataUseRecorder is sufficient and - // GetOrCreateDataUseRecorderEntry is not needed. The entry gets created in - // DataUseAscriber::OnBeforeUrlRequest(). - const DataUseRecorderEntry entry = GetOrCreateDataUseRecorderEntry(request); + const DataUseRecorderEntry entry = GetDataUseRecorderEntry(request); if (entry == data_use_recorders_.end()) return;
diff --git a/chrome/browser/data_use_measurement/chrome_data_use_ascriber.h b/chrome/browser/data_use_measurement/chrome_data_use_ascriber.h index 7e629f4..dc649e0 100644 --- a/chrome/browser/data_use_measurement/chrome_data_use_ascriber.h +++ b/chrome/browser/data_use_measurement/chrome_data_use_ascriber.h
@@ -161,6 +161,8 @@ DISALLOW_COPY_AND_ASSIGN(MainRenderFrameEntry); }; + DataUseRecorderEntry GetDataUseRecorderEntry(net::URLRequest* request); + DataUseRecorderEntry GetOrCreateDataUseRecorderEntry( net::URLRequest* request);
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index dbd981a..109ef6a 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -310,6 +310,8 @@ settings_private::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[::chromeos::kSignedDataRoamingEnabled] = settings_private::PrefType::PREF_TYPE_BOOLEAN; + (*s_whitelist)[::ash::prefs::kUserBluetoothAdapterEnabled] = + settings_private::PrefType::PREF_TYPE_BOOLEAN; // Timezone settings. (*s_whitelist)[chromeos::kSystemTimezone] =
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc index 1e12aacd..4933e36 100644 --- a/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc
@@ -66,18 +66,12 @@ protected: bool IsTooIntensiveForThisPlatform() const { - // The tests are too slow to succeed with software GL on the bots. - if (UsingSoftwareGL()) - return true; - #if defined(NDEBUG) - return false; + // The tests are too slow to succeed with software GL on the bots. + return UsingSoftwareGL(); #else - // TODO(miu): Look into enabling these tests for the Debug build bots once - // they prove to be stable again on the Release bots. - // http://crbug.com/396413 - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - "run-tab-capture-api-pixel-tests"); + // The tests only run on release builds. + return true; #endif } };
diff --git a/chrome/browser/metrics/android_metrics_provider.cc b/chrome/browser/metrics/android_metrics_provider.cc index c9f5160..ce3c2a32 100644 --- a/chrome/browser/metrics/android_metrics_provider.cc +++ b/chrome/browser/metrics/android_metrics_provider.cc
@@ -27,6 +27,11 @@ return (1 << type); } +void EmitLowRamDeviceHistogram() { + UMA_HISTOGRAM_BOOLEAN("MemoryAndroid.LowRamDevice", + base::SysInfo::IsLowEndDevice()); +} + } // namespace AndroidMetricsProvider::AndroidMetricsProvider(PrefService* local_state) @@ -40,19 +45,21 @@ void AndroidMetricsProvider::ProvidePreviousSessionData( metrics::ChromeUserMetricsExtension* uma_proto) { ConvertStabilityPrefsToHistograms(); + // The low-ram device status is unlikely to change between browser restarts. + // Hence, it's safe and useful to attach this status to a previous session + // log. + EmitLowRamDeviceHistogram(); } void AndroidMetricsProvider::ProvideCurrentSessionData( metrics::ChromeUserMetricsExtension* uma_proto) { ConvertStabilityPrefsToHistograms(); + EmitLowRamDeviceHistogram(); UMA_HISTOGRAM_ENUMERATION( "CustomTabs.Visible", chrome::android::GetCustomTabsVisibleValue(), chrome::android::CUSTOM_TABS_VISIBILITY_MAX); UMA_HISTOGRAM_BOOLEAN( - "MemoryAndroid.LowRamDevice", - base::SysInfo::IsLowEndDevice()); - UMA_HISTOGRAM_BOOLEAN( "Android.MultiWindowMode.Active", chrome::android::GetIsInMultiWindowModeValue()); }
diff --git a/chrome/browser/resources/md_extensions/compiled_resources2.gyp b/chrome/browser/resources/md_extensions/compiled_resources2.gyp index ab7b556..555897e 100644 --- a/chrome/browser/resources/md_extensions/compiled_resources2.gyp +++ b/chrome/browser/resources/md_extensions/compiled_resources2.gyp
@@ -185,6 +185,7 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', + 'navigation_helper', ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], },
diff --git a/chrome/browser/resources/md_extensions/manager.html b/chrome/browser/resources/md_extensions/manager.html index 355a84ea..8b5d8917 100644 --- a/chrome/browser/resources/md_extensions/manager.html +++ b/chrome/browser/resources/md_extensions/manager.html
@@ -67,7 +67,8 @@ </div> </dialog> <extensions-view-manager id="viewManager"> - <extensions-item-list id="items-list" items="[[extensions]]" + <extensions-item-list id="items-list" + items="[[itemsList_]]" delegate="[[delegate]]" in-dev-mode="[[inDevMode]]" filter="[[filter]]" hidden$="[[!didInitPage_]]" slot="view"> </extensions-item-list> @@ -82,7 +83,8 @@ data="[[errorPageItem_]]" delegate="[[delegate]]" slot="view"> </extensions-error-page> </extensions-view-manager> - <extensions-options-dialog id="options-dialog"> + <extensions-options-dialog id="options-dialog" + on-close="onOptionsDialogClose_"> </extensions-options-dialog> <extensions-pack-dialog id="pack-dialog" delegate="[[delegate]]"> </extensions-pack-dialog>
diff --git a/chrome/browser/resources/md_extensions/manager.js b/chrome/browser/resources/md_extensions/manager.js index 6f64abe..c6d969e5 100644 --- a/chrome/browser/resources/md_extensions/manager.js +++ b/chrome/browser/resources/md_extensions/manager.js
@@ -94,6 +94,14 @@ }, }, + /** @private {extensions.ShowingType} */ + listType_: Number, + + itemsList_: { + type: Array, + computed: 'computeList_(listType_)', + }, + /** * Prevents page content from showing before data is first loaded. * @private @@ -132,19 +140,6 @@ this.navigationHelper_ = new extensions.NavigationHelper(newPage => { this.changePage(newPage, true); }); - this.optionsDialog.addEventListener('close', () => { - // We update the page when the options dialog closes, but only if we're - // still on the details page. We could be on a different page if the - // user hit back while the options dialog was visible; in that case, the - // new page is already correct. - if (this.currentPage_ && this.currentPage_.page == Page.DETAILS) { - // This will update the currentPage_ and the NavigationHelper; since - // the active page is already the details page, no main page - // transition occurs. - this.changePage( - {page: Page.DETAILS, extensionId: this.currentPage_.extensionId}); - } - }); }, get keyboardShortcuts() { @@ -168,14 +163,6 @@ }, /** - * Shows the details view for a given item. - * @param {!chrome.developerPrivate.ExtensionInfo} data - */ - showItemDetails: function(data) { - this.changePage({page: Page.DETAILS, extensionId: data.id}); - }, - - /** * Initializes the page to reflect what's specified in the url so that if * the user visits chrome://extensions/?id=..., we land on the proper page. */ @@ -330,6 +317,7 @@ */ changePage: function(newPage, isSilent) { if (this.currentPage_ && this.currentPage_.page == newPage.page && + this.currentPage_.type == newPage.type && this.currentPage_.subpage == newPage.subpage && this.currentPage_.extensionId == newPage.extensionId) { return; @@ -345,6 +333,9 @@ if (newPage.extensionId) data = assert(this.getData_(newPage.extensionId)); + if (newPage.hasOwnProperty('type')) + this.listType_ = newPage.type; + if (toPage == Page.DETAILS) this.detailViewItem_ = assert(data); else if (toPage == Page.ERRORS) @@ -353,6 +344,9 @@ if (fromPage != toPage) { /** @type {extensions.ViewManager} */ (this.$.viewManager) .switchView(toPage); + } else { + /** @type {extensions.ViewManager} */ (this.$.viewManager) + .animateCurrentView('fade-in'); } if (newPage.subpage) { @@ -373,7 +367,7 @@ * @private */ onShouldShowItemDetails_: function(e) { - this.showItemDetails(e.detail.data); + this.changePage({page: Page.DETAILS, extensionId: e.detail.data.id}); }, /** @@ -389,19 +383,52 @@ onDetailsViewClose_: function() { // Note: we don't reset detailViewItem_ here because doing so just causes // extra work for the data-bound details view. - this.changePage({page: Page.LIST}); + this.changePage({page: Page.LIST, type: this.listType_}); }, /** @private */ onErrorPageClose_: function() { // Note: we don't reset errorPageItem_ here because doing so just causes // extra work for the data-bound error page. - this.changePage({page: Page.LIST}); + this.changePage({page: Page.LIST, type: this.listType_}); }, /** @private */ onPackTap_: function() { this.$['pack-dialog'].show(); + }, + + /** @private */ + onOptionsDialogClose_: function() { + // We update the page when the options dialog closes, but only if we're + // still on the details page. We could be on a different page if the + // user hit back while the options dialog was visible; in that case, the + // new page is already correct. + if (this.currentPage_ && this.currentPage_.page == Page.DETAILS) { + // This will update the currentPage_ and the NavigationHelper; since + // the active page is already the details page, no main page + // transition occurs. + this.changePage( + {page: Page.DETAILS, extensionId: this.currentPage_.extensionId}); + } + }, + + /** + * @param {!extensions.ShowingType} listType + * @private + */ + computeList_: function(listType) { + // TODO(scottchen): the .slice is required to trigger the binding + // correctly, otherwise the list won't rerender. Should investigate + // the performance implication, or find better ways to trigger change. + switch (listType) { + case extensions.ShowingType.EXTENSIONS: + this.linkPaths('itemsList_', 'extensions'); + return this.extensions; + case extensions.ShowingType.APPS: + this.linkPaths('itemsList_', 'apps'); + return this.apps; + } } }); @@ -413,19 +440,9 @@ } /** @override */ - showType(type) { + showType(listType) { let items; - switch (type) { - case extensions.ShowingType.EXTENSIONS: - items = this.manager_.extensions; - break; - case extensions.ShowingType.APPS: - items = this.manager_.apps; - break; - } - - this.manager_.$ /* hack */['items-list'].set('items', assert(items)); - this.manager_.changePage({page: Page.LIST}); + this.manager_.changePage({page: Page.LIST, type: listType}); } /** @override */
diff --git a/chrome/browser/resources/md_extensions/navigation_helper.js b/chrome/browser/resources/md_extensions/navigation_helper.js index c5272a6..4f058b4 100644 --- a/chrome/browser/resources/md_extensions/navigation_helper.js +++ b/chrome/browser/resources/md_extensions/navigation_helper.js
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +cr.exportPath('extensions'); + /** * The different pages that can be shown at a time. * Note: This must remain in sync with the page ids in manager.html! @@ -19,6 +21,12 @@ OPTIONS: 'options', }; +/** @enum {number} */ +extensions.ShowingType = { + EXTENSIONS: 0, + APPS: 1, +}; + /** @typedef {{page: Page, extensionId: (string|undefined), subpage: (!Dialog|undefined)}} */ @@ -39,13 +47,9 @@ * forward in history; called with the new active page. */ constructor(onHistoryChange) { - this.onHistoryChange_ = onHistoryChange; - window.addEventListener('popstate', this.onPopState_.bind(this)); - } - - /** @private */ - onPopState_() { - this.onHistoryChange_(this.getCurrentPage()); + window.addEventListener('popstate', () => { + onHistoryChange(this.getCurrentPage()); + }); } /** @@ -67,7 +71,10 @@ if (location.pathname == '/shortcuts') return {page: Page.SHORTCUTS}; - return {page: Page.LIST}; + if (location.pathname == '/apps') + return {page: Page.LIST, type: extensions.ShowingType.APPS}; + + return {page: Page.LIST, type: extensions.ShowingType.EXTENSIONS}; } /** @@ -78,7 +85,10 @@ let path; switch (entry.page) { case Page.LIST: - path = '/'; + if (entry.type && entry.type == extensions.ShowingType.APPS) + path = '/apps'; + else + path = '/'; break; case Page.DETAILS: if (entry.subpage) {
diff --git a/chrome/browser/resources/md_extensions/sidebar.html b/chrome/browser/resources/md_extensions/sidebar.html index 635f68e..030c5c1 100644 --- a/chrome/browser/resources/md_extensions/sidebar.html +++ b/chrome/browser/resources/md_extensions/sidebar.html
@@ -5,6 +5,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> +<link rel="import" href="navigation_helper.html"> <dom-module id="extensions-sidebar"> <template>
diff --git a/chrome/browser/resources/md_extensions/sidebar.js b/chrome/browser/resources/md_extensions/sidebar.js index ee7978e7..cd1cd9c 100644 --- a/chrome/browser/resources/md_extensions/sidebar.js +++ b/chrome/browser/resources/md_extensions/sidebar.js
@@ -1,16 +1,6 @@ // Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - -cr.exportPath('extensions'); - -// Declare this here to make closure compiler happy, and us sad. -/** @enum {number} */ -extensions.ShowingType = { - EXTENSIONS: 0, - APPS: 1, -}; - cr.define('extensions', function() { /** @interface */ const SidebarListDelegate = function() {};
diff --git a/chrome/browser/resources/md_extensions/view_manager.js b/chrome/browser/resources/md_extensions/view_manager.js index 28ee965d..36e5383 100644 --- a/chrome/browser/resources/md_extensions/view_manager.js +++ b/chrome/browser/resources/md_extensions/view_manager.js
@@ -107,6 +107,19 @@ return Promise.all(promises); }, + + /** + * Helper function to only animate the current view. + * @param {string} animation + * @return {!Promise} + */ + animateCurrentView: function(animation) { + const currentView = assert(this.querySelector('.active')); + const animationFunction = extensions.viewAnimations.get(animation); + assert(animationFunction); + + return animationFunction(currentView); + }, }); return {viewAnimations: viewAnimations, ViewManager: ViewManager};
diff --git a/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js b/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js index 790bfe7..df85fd8 100644 --- a/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js +++ b/chrome/browser/resources/settings/about_page/about_page_browser_proxy.js
@@ -48,6 +48,7 @@ */ var BrowserChannel = { BETA: 'beta-channel', + CANARY: 'canary-channel', DEV: 'dev-channel', STABLE: 'stable-channel', }; @@ -102,6 +103,8 @@ switch (channel) { case BrowserChannel.BETA: return 'aboutChannelBeta'; + case BrowserChannel.CANARY: + return 'aboutChannelCanary'; case BrowserChannel.DEV: return 'aboutChannelDev'; case BrowserChannel.STABLE: @@ -120,6 +123,7 @@ function isTargetChannelMoreStable(currentChannel, targetChannel) { // List of channels in increasing stability order. var channelList = [ + BrowserChannel.CANARY, BrowserChannel.DEV, BrowserChannel.BETA, BrowserChannel.STABLE,
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html index 3a8bee6..45b028b 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
@@ -1,12 +1,15 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html"> +<link rel="import" href="../controls/settings_toggle_button.html"> <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../icons.html"> <link rel="import" href="../prefs/prefs.html"> +<link rel="import" href="../prefs/prefs_behavior.html"> <link rel="import" href="../settings_page/settings_animated_pages.html"> <link rel="import" href="../settings_page/settings_subpage.html"> <link rel="import" href="../settings_shared_css.html"> @@ -19,34 +22,45 @@ <settings-animated-pages id="pages" section="bluetooth" focus-config="[[focusConfig_]]"> <neon-animatable route-path="default"> - <div id="bluetoothDevices" - class="settings-box two-line" actionable on-tap="onTap_"> - <iron-icon icon="[[getIcon_(bluetoothToggleState_)]]"></iron-icon> - <div class="middle"> - $i18n{bluetoothPageTitle} - <div class="secondary" id="bluetoothSecondary"> - [[getOnOffString_(bluetoothToggleState_, - '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]] + <template is="dom-if" if="[[!isSecondaryUser_]]"> + <div id="bluetoothDevices" + class="settings-box two-line" actionable on-tap="onTap_"> + <iron-icon icon="[[getIcon_(adapterState_.powered)]]"></iron-icon> + <div class="middle"> + $i18n{bluetoothPageTitle} + <div class="secondary" id="bluetoothSecondary"> + [[getOnOffString_(adapterState_.powered, + '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]] + </div> + </div> + <cr-policy-pref-indicator + icon-aria-label="$i18n{bluetoothPageTitle}" + pref="[[prefs.cros.device.allow_bluetooth]]" + hidden="[[prefs.cros.device.allow_bluetooth.value]]"> + </cr-policy-pref-indicator> + <template is="dom-if" if="[[adapterState_.powered]]"> + <button class="subpage-arrow" is="paper-icon-button-light" + on-tap="onSubpageArrowTap_" + aria-label="$i18n{bluetoothPageTitle}" + aria-describedby="bluetoothSecondary"> + </button> + </template> + <div class="separator"></div> + <settings-toggle-button id="enableBluetooth" + pref="{{prefs.ash.user.bluetooth.adapter_enabled}}" + disabled$="[[!adapterState_.available]]" on-tap="stopTap_" + label="$i18n{bluetoothToggleA11yLabel}"> + </settings-toggle-button> + </div> + </template> + <template is="dom-if" if="[[isSecondaryUser_]]"> + <div id="bluetoothDevices" class="settings-box two-line"> + <iron-icon class="policy" icon="cr:group"></iron-icon> + <div class="middle"> + [[i18n('networkPrimaryUserControlled', primaryUserEmail_)]] </div> </div> - <cr-policy-pref-indicator icon-aria-label="$i18n{bluetoothPageTitle}" - pref="[[prefs.cros.device.allow_bluetooth]]" - hidden="[[prefs.cros.device.allow_bluetooth.value]]"> - </cr-policy-pref-indicator> - <template is="dom-if" if="[[bluetoothToggleState_]]"> - <button class="subpage-arrow" is="paper-icon-button-light" - on-tap="onSubpageArrowTap_" - aria-label="$i18n{bluetoothPageTitle}" - aria-describedby="bluetoothSecondary"> - </button> - </template> - <div class="separator"></div> - <paper-toggle-button id="enableBluetooth" - checked="{{bluetoothToggleState_}}" - disabled$="[[bluetoothToggleDisabled_]]" on-tap="stopTap_" - aria-label="$i18n{bluetoothToggleA11yLabel}"> - </paper-toggle-button> - </div> + </template> </neon-animatable> <template is="dom-if" route-path="/bluetoothDevices"> @@ -54,10 +68,9 @@ page-title="$i18n{bluetoothPageTitle}"> <settings-bluetooth-subpage adapter-state="[[adapterState_]]" - bluetooth-toggle-state="{{bluetoothToggleState_}}" - bluetooth-toggle-disabled="[[bluetoothToggleDisabled_]]" bluetooth="[[bluetooth]]" - bluetooth-private="[[bluetoothPrivate]]"> + bluetooth-private="[[bluetoothPrivate]]" + prefs="{{prefs}}"> </settings-bluetooth-subpage> </settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js index 35b5c439..13d380f 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.js
@@ -25,6 +25,8 @@ Polymer({ is: 'settings-bluetooth-page', + behaviors: [I18nBehavior, PrefsBehavior], + properties: { /** Preferences state. */ prefs: { @@ -33,29 +35,6 @@ }, /** - * Reflects the current state of the toggle buttons (in this page and the - * subpage). This will be set when the adapter state change or when the user - * changes the toggle. - * @private - */ - bluetoothToggleState_: { - type: Boolean, - observer: 'bluetoothToggleStateChanged_', - }, - - /** - * Set to true before the adapter state is received, when the adapter is - * unavailable, and while an adapter state change is requested. This - * prevents user changes while a change is in progress or when the adapter - * is not available. - * @private - */ - bluetoothToggleDisabled_: { - type: Boolean, - value: true, - }, - - /** * The cached bluetooth adapter state. * @type {!chrome.bluetooth.AdapterState|undefined} * @private @@ -98,6 +77,30 @@ type: Object, value: chrome.bluetoothPrivate, }, + + /** + * Whether the user is a secondary user. + * @private + */ + isSecondaryUser_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('isSecondaryUser'); + }, + readOnly: true, + }, + + /** + * Email address for the primary user. + * @private + */ + primaryUserEmail_: { + type: String, + value: function() { + return loadTimeData.getString('primaryUserEmail'); + }, + readOnly: true, + }, }, observers: ['deviceListChanged_(deviceList_.*)'], @@ -140,8 +143,8 @@ * @return {string} * @private */ - getIcon_: function() { - if (!this.bluetoothToggleState_) + getIcon_: function(enabled) { + if (!enabled) return 'settings:bluetooth-disabled'; return 'settings:bluetooth'; }, @@ -164,16 +167,14 @@ */ onBluetoothAdapterStateChanged_: function(state) { this.adapterState_ = state; - this.bluetoothToggleState_ = state.powered; - this.bluetoothToggleDisabled_ = !state.available; }, /** @private */ onTap_: function() { if (this.adapterState_.available === false) return; - if (!this.bluetoothToggleState_) - this.bluetoothToggleState_ = true; + if (!this.adapterState_.powered) + this.setPrefValue('ash.user.bluetooth.adapter_enabled', true); else this.openSubpage_(); }, @@ -196,23 +197,6 @@ }, /** @private */ - bluetoothToggleStateChanged_: function() { - if (!this.adapterState_ || this.bluetoothToggleDisabled_ || - this.bluetoothToggleState_ == this.adapterState_.powered) { - return; - } - this.bluetoothToggleDisabled_ = true; - this.bluetoothPrivate.setAdapterState( - {powered: this.bluetoothToggleState_}, function() { - if (chrome.runtime.lastError) { - console.error( - 'Error enabling bluetooth: ' + - chrome.runtime.lastError.message); - } - }); - }, - - /** @private */ openSubpage_: function() { settings.navigateTo(settings.routes.BLUETOOTH_DEVICES); }
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.html b/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.html index 7a782ee..c2ab103 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.html +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.html
@@ -6,6 +6,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html"> +<link rel="import" href="../controls/settings_toggle_button.html"> <link rel="import" href="../i18n_setup.html"> <link rel="import" href="../icons.html"> <link rel="import" href="../settings_shared_css.html"> @@ -40,28 +41,27 @@ </style> <div class="settings-box first"> - <div id="onOff" class="start" on$="[[bluetoothToggleState]]"> - [[getOnOffString_(bluetoothToggleState, + <div id="onOff" class="start" on$="[[adapterState.powered]]"> + [[getOnOffString_(adapterState.powered, '$i18nPolymer{deviceOn}', '$i18nPolymer{deviceOff}')]] </div> - <paper-toggle-button id="enableBluetooth" - checked="{{bluetoothToggleState}}" - disabled$="[[bluetoothToggleDisabled]]" - aria-label="$i18n{bluetoothToggleA11yLabel}"> - </paper-toggle-button> + <settings-toggle-button id="enableBluetooth" + pref="{{prefs.ash.user.bluetooth.adapter_enabled}}" + label="$i18n{bluetoothToggleA11yLabel}"> + </settings-toggle-button> </div> <!-- Paired device list --> - <div class="settings-box first header" hidden="[[!bluetoothToggleState]]"> + <div class="settings-box first header" hidden="[[!adapterState.powered]]"> <div class="start">$i18n{bluetoothDeviceListPaired}</div> </div> <div id="noPairedDevices" class="list-frame" - hidden="[[!showNoDevices_(bluetoothToggleState, pairedDeviceList_)]]"> + hidden="[[!showNoDevices_(adapterState.powered, pairedDeviceList_)]]"> $i18n{bluetoothNoDevices} </div> <div id="pairedContainer" class="container" scrollable on-device-event="onDeviceEvent_" - hidden="[[!showDevices_(bluetoothToggleState, pairedDeviceList_)]]"> + hidden="[[!showDevices_(adapterState.powered, pairedDeviceList_)]]"> <iron-list id="pairedDevices" class="vertical-list" preserve-focus items="[[pairedDeviceList_]]" selection-enabled selected-item="{{selectedPairedItem_}}" @@ -75,18 +75,18 @@ </div> <!-- Unpaired device list --> - <div class="settings-box first header" hidden="[[!bluetoothToggleState]]"> + <div class="settings-box first header" hidden="[[!adapterState.powered]]"> <div class="start">$i18n{bluetoothDeviceListUnpaired}</div> <paper-spinner active="[[showSpinner_]]"> </paper-spinner> </div> <div id="noUnpairedDevices" class="list-frame" - hidden="[[!showNoDevices_(bluetoothToggleState, unpairedDeviceList_)]]"> + hidden="[[!showNoDevices_(adapterState.powered, unpairedDeviceList_)]]"> $i18n{bluetoothNoDevicesFound} </div> <div id="unpairedContainer" class="container" scrollable on-device-event="onDeviceEvent_" - hidden="[[!showDevices_(bluetoothToggleState, unpairedDeviceList_)]]"> + hidden="[[!showDevices_(adapterState.powered, unpairedDeviceList_)]]"> <iron-list id="unpairedDevices" class="vertical-list" preserve-focus items="[[unpairedDeviceList_]]" selection-enabled selected-item="{{selectedUnpairedItem_}}"
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.js b/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.js index 5487662..3bae2526 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.js +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_subpage.js
@@ -18,9 +18,9 @@ ], properties: { - /** Reflects the bluetooth-page property. */ - bluetoothToggleState: { - type: Boolean, + /** Preferences state. */ + prefs: { + type: Object, notify: true, }, @@ -239,7 +239,7 @@ * @private */ updateDeviceList_: function() { - if (!this.bluetoothToggleState) { + if (!this.adapterState.powered) { this.deviceList_ = []; return; } @@ -342,23 +342,23 @@ }, /** - * @param {boolean} bluetoothToggleState + * @param {boolean} adapterPoweredState * @param {!Array<!chrome.bluetooth.Device>} deviceList * @return {boolean} * @private */ - showDevices_: function(bluetoothToggleState, deviceList) { - return bluetoothToggleState && deviceList.length > 0; + showDevices_: function(adapterPoweredState, deviceList) { + return adapterPoweredState && deviceList.length > 0; }, /** - * @param {boolean} bluetoothToggleState + * @param {boolean} adapterPoweredState * @param {!Array<!chrome.bluetooth.Device>} deviceList * @return {boolean} * @private */ - showNoDevices_: function(bluetoothToggleState, deviceList) { - return bluetoothToggleState && deviceList.length == 0; + showNoDevices_: function(adapterPoweredState, deviceList) { + return adapterPoweredState && deviceList.length == 0; }, /**
diff --git a/chrome/browser/resources/settings/bluetooth_page/compiled_resources2.gyp b/chrome/browser/resources/settings/bluetooth_page/compiled_resources2.gyp index 3d4051b..d7d70897 100644 --- a/chrome/browser/resources/settings/bluetooth_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/bluetooth_page/compiled_resources2.gyp
@@ -7,6 +7,7 @@ 'target_name': 'bluetooth_page', 'dependencies': [ '../compiled_resources2.gyp:route', + '../prefs/compiled_resources2.gyp:prefs_behavior', '../settings_page/compiled_resources2.gyp:settings_animated_pages', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', @@ -21,6 +22,7 @@ 'target_name': 'bluetooth_subpage', 'dependencies': [ '../compiled_resources2.gyp:route', + '../prefs/compiled_resources2.gyp:prefs_behavior', '<(DEPTH)/ui/webui/resources/cr_elements/compiled_resources2.gyp:cr_scrollable_behavior', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
diff --git a/chrome/browser/resources/settings/internet_page/network_siminfo.js b/chrome/browser/resources/settings/internet_page/network_siminfo.js index e9e19cfe..cb0eb9c 100644 --- a/chrome/browser/resources/settings/internet_page/network_siminfo.js +++ b/chrome/browser/resources/settings/internet_page/network_siminfo.js
@@ -78,7 +78,7 @@ var simLockStatus = this.networkProperties.Cellular.SIMLockStatus; this.pukRequired_ = !!simLockStatus && simLockStatus.LockType == CrOnc.LockType.PUK; - this.lockEnabled_ = simLockStatus.LockEnabled; + this.lockEnabled_ = !!simLockStatus && simLockStatus.LockEnabled; }, /** @private */ @@ -164,7 +164,7 @@ onChangePinTap_: function(event) { if (!this.networkProperties || !this.networkProperties.Cellular) return; - event.preventDefault(); + event.stopPropagation(); this.error_ = ErrorType.NONE; this.$.changePinOld.value = ''; this.$.changePinNew1.value = ''; @@ -205,7 +205,7 @@ * @private */ onUnlockPinTap_: function(event) { - event.preventDefault(); + event.stopPropagation(); if (this.pukRequired_) { this.showUnlockPukDialog_(); } else {
diff --git a/chrome/browser/resources/settings/internet_page/network_summary_item.js b/chrome/browser/resources/settings/internet_page/network_summary_item.js index 0ed7469f..656d666 100644 --- a/chrome/browser/resources/settings/internet_page/network_summary_item.js +++ b/chrome/browser/resources/settings/internet_page/network_summary_item.js
@@ -138,9 +138,12 @@ this.deviceIsEnabled_(deviceState)) { return false; } - return deviceState.SimPresent === false || - deviceState.SimLockType == CrOnc.LockType.PIN || - deviceState.SimLockType == CrOnc.LockType.PUK; + if (deviceState.SIMPresent === false) + return true; + var simLockType = + deviceState.SIMLockStatus ? deviceState.SIMLockStatus.LockType : ''; + return simLockType == CrOnc.LockType.PIN || + simLockType == CrOnc.LockType.PUK; }, /** @@ -157,11 +160,8 @@ GUID: '', Type: CrOnc.Type.CELLULAR, Cellular: { - SIMLockStatus: { - LockType: deviceState.SimLockType || '', - LockEnabled: deviceState.SimLockType != CrOnc.LockType.NONE, - }, - SIMPresent: deviceState.SimPresent, + SIMLockStatus: deviceState.SIMLockStatus, + SIMPresent: deviceState.SIMPresent, }, }; },
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc index 200bcfd..6ca6601 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request.cc
@@ -7,6 +7,7 @@ #include "base/metrics/histogram_macros.h" #include "base/rand_util.h" #include "base/task_scheduler/post_task.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/download_protection/download_feedback_service.h" @@ -798,6 +799,7 @@ request.set_length(item_->GetReceivedBytes()); request.set_skipped_url_whitelist(skipped_url_whitelist_); request.set_skipped_certificate_whitelist(skipped_certificate_whitelist_); + request.set_locale(g_browser_process->GetApplicationLocale()); for (size_t i = 0; i < item_->GetUrlChain().size(); ++i) { ClientDownloadRequest::Resource* resource = request.add_resources(); resource->set_url(SanitizeUrl(item_->GetUrlChain()[i]));
diff --git a/chrome/browser/ui/ash/session_controller_client.cc b/chrome/browser/ui/ash/session_controller_client.cc index 0520778d..5bef7eb 100644 --- a/chrome/browser/ui/ash/session_controller_client.cc +++ b/chrome/browser/ui/ash/session_controller_client.cc
@@ -82,12 +82,15 @@ return nullptr; ash::mojom::UserSessionPtr session = ash::mojom::UserSession::New(); + Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(&user); session->session_id = user_session_id; session->user_info = ash::mojom::UserInfo::New(); session->user_info->type = user.GetType(); session->user_info->account_id = user.GetAccountId(); session->user_info->display_name = base::UTF16ToUTF8(user.display_name()); session->user_info->display_email = user.display_email(); + if (profile) + session->user_info->is_new_profile = profile->IsNewProfile(); session->user_info->avatar = user.GetImage(); if (session->user_info->avatar.isNull()) { @@ -97,7 +100,6 @@ } if (user.IsSupervised()) { - Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(&user); if (profile) { SupervisedUserService* service = SupervisedUserServiceFactory::GetForProfile(profile);
diff --git a/chrome/browser/ui/webui/browsing_history_handler.cc b/chrome/browser/ui/webui/browsing_history_handler.cc index 891a1c0..5f5d01c 100644 --- a/chrome/browser/ui/webui/browsing_history_handler.cc +++ b/chrome/browser/ui/webui/browsing_history_handler.cc
@@ -391,7 +391,8 @@ // HistoryQuery. Please update it whenever you add or remove any keys in // results_info_value_. results_info.SetString("term", query_results_info.search_text); - results_info.SetBoolean("finished", query_results_info.reached_beginning); + results_info.SetBoolean("finished", + query_results_info.reached_beginning_of_local); results_info.SetBoolean("hasSyncedResults", query_results_info.has_synced_results);
diff --git a/chrome/browser/ui/webui/help/help_handler.cc b/chrome/browser/ui/webui/help/help_handler.cc deleted file mode 100644 index 6aad55c9..0000000 --- a/chrome/browser/ui/webui/help/help_handler.cc +++ /dev/null
@@ -1,766 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/help/help_handler.h" - -#include <stddef.h> - -#include <string> - -#include "base/base_switches.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/command_line.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/i18n/message_formatter.h" -#include "base/location.h" -#include "base/macros.h" -#include "base/strings/string16.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/task_scheduler/post_task.h" -#include "base/time/time.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/lifetime/application_lifetime.h" -#include "chrome/browser/obsolete_system/obsolete_system.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/chrome_pages.h" -#include "chrome/browser/upgrade_detector.h" -#include "chrome/common/channel_info.h" -#include "chrome/common/chrome_content_client.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/chromium_strings.h" -#include "chrome/grit/generated_resources.h" -#include "components/google/core/browser/google_util.h" -#include "components/policy/core/common/policy_namespace.h" -#include "components/policy/policy_constants.h" -#include "components/strings/grit/components_chromium_strings.h" -#include "components/strings/grit/components_strings.h" -#include "components/version_info/version_info.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" -#include "v8/include/v8-version-string.h" - -#if defined(OS_CHROMEOS) -#include "base/files/file_util_proxy.h" -#include "base/i18n/time_formatting.h" -#include "base/sys_info.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/chromeos/image_source.h" -#include "chrome/browser/ui/webui/help/help_utils_chromeos.h" -#include "chrome/browser/ui/webui/help/version_updater_chromeos.h" -#include "chromeos/chromeos_switches.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/power_manager_client.h" -#include "chromeos/system/statistics_provider.h" -#include "components/prefs/pref_service.h" -#include "components/user_manager/user_manager.h" -#include "ui/chromeos/devicetype_utils.h" -#endif - -using base::ListValue; -using content::BrowserThread; - -namespace { - -#if defined(OS_CHROMEOS) - -// Directory containing the regulatory labels for supported regions. -const char kRegulatoryLabelsDirectory[] = "regulatory_labels"; - -// File names of the image file and the file containing alt text for the label. -const char kRegulatoryLabelImageFilename[] = "label.png"; -const char kRegulatoryLabelTextFilename[] = "label.txt"; - -// Default region code to use if there's no label for the VPD region code. -const char kDefaultRegionCode[] = "us"; - -struct RegulatoryLabel { - const std::string label_text; - const std::string image_url; -}; - -// Returns message that informs user that for update it's better to -// connect to a network of one of the allowed types. -base::string16 GetAllowedConnectionTypesMessage() { - // Old help page does not support interactive-updates over cellular, so just - // sets |interactive| to false to make its behavior the same as before. - if (help_utils_chromeos::IsUpdateOverCellularAllowed( - false /* interactive */)) { - return l10n_util::GetStringUTF16(IDS_UPGRADE_NETWORK_LIST_CELLULAR_ALLOWED); - } else { - return l10n_util::GetStringUTF16( - IDS_UPGRADE_NETWORK_LIST_CELLULAR_DISALLOWED); - } -} - -// Returns true if the device is enterprise managed, false otherwise. -bool IsEnterpriseManaged() { - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return connector->IsEnterpriseManaged(); -} - -// Returns true if current user can change channel, false otherwise. -bool CanChangeChannel(Profile* profile) { - bool value = false; - chromeos::CrosSettings::Get()->GetBoolean(chromeos::kReleaseChannelDelegated, - &value); - - // On a managed machine we delegate this setting to the users of the same - // domain only if the policy value is "domain". - if (IsEnterpriseManaged()) { - if (!value) - return false; - // Get the currently logged in user and strip the domain part only. - std::string domain = ""; - const user_manager::User* user = - profile ? chromeos::ProfileHelper::Get()->GetUserByProfile(profile) - : nullptr; - std::string email = - user ? user->GetAccountId().GetUserEmail() : std::string(); - size_t at_pos = email.find('@'); - if (at_pos != std::string::npos && at_pos + 1 < email.length()) - domain = email.substr(email.find('@') + 1); - policy::BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return domain == connector->GetEnterpriseEnrollmentDomain(); - } else { - chromeos::OwnerSettingsServiceChromeOS* service = - chromeos::OwnerSettingsServiceChromeOSFactory::GetInstance() - ->GetForBrowserContext(profile); - // On non managed machines we have local owner who is the only one to change - // anything. Ensure that ReleaseChannelDelegated is false. - if (service && service->IsOwner()) - return !value; - } - return false; -} - -// Returns the path of the regulatory labels directory for a given region, if -// found. Must be called from the blocking pool. -base::FilePath GetRegulatoryLabelDirForRegion(const std::string& region) { - // Generate the path under the asset dir or URL host to the regulatory files - // for the region, e.g., "regulatory_labels/us/". - const base::FilePath region_path = - base::FilePath(kRegulatoryLabelsDirectory).AppendASCII(region); - - // Check for file existence starting in /usr/share/chromeos-assets/, e.g., - // "/usr/share/chromeos-assets/regulatory_labels/us/label.png". - const base::FilePath asset_dir(chrome::kChromeOSAssetPath); - if (base::PathExists(asset_dir.Append(region_path) - .AppendASCII(kRegulatoryLabelImageFilename))) { - return region_path; - } - - return base::FilePath(); -} - -// Finds the directory for the regulatory label, using the VPD region code. -// Also tries "us" as a fallback region. Must be called from the blocking pool. -base::FilePath FindRegulatoryLabelDir() { - std::string region; - base::FilePath region_path; - // Use the VPD region code to find the label dir. - if (chromeos::system::StatisticsProvider::GetInstance()->GetMachineStatistic( - "region", ®ion) && !region.empty()) { - region_path = GetRegulatoryLabelDirForRegion(region); - } - - // Try the fallback region code if no directory was found. - if (region_path.empty() && region != kDefaultRegionCode) - region_path = GetRegulatoryLabelDirForRegion(kDefaultRegionCode); - - return region_path; -} - -// Reads the file containing the regulatory label text, if found, relative to -// the asset directory. Must be called from the blocking pool. -std::string ReadRegulatoryLabelText(const base::FilePath& path) { - base::FilePath text_path(chrome::kChromeOSAssetPath); - text_path = text_path.Append(path); - text_path = text_path.AppendASCII(kRegulatoryLabelTextFilename); - - std::string contents; - if (base::ReadFileToString(text_path, &contents)) - return contents; - return std::string(); -} -#endif // defined(OS_CHROMEOS) - -} // namespace - -HelpHandler::HelpHandler() - : policy_registrar_( - g_browser_process->policy_service(), - policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string())), - apply_changes_from_upgrade_observer_(false), - weak_factory_(this) { - UpgradeDetector::GetInstance()->AddObserver(this); -} - -HelpHandler::~HelpHandler() { - UpgradeDetector::GetInstance()->RemoveObserver(this); -} - -void HelpHandler::GetLocalizedValues(base::DictionaryValue* localized_strings) { - struct L10nResources { - const char* name; - int ids; - }; - - static L10nResources resources[] = { - {"aboutTitle", IDS_ABOUT_TITLE}, -#if defined(OS_CHROMEOS) - {"aboutProductTitle", IDS_PRODUCT_OS_NAME}, -#else - {"aboutProductTitle", IDS_PRODUCT_NAME}, -#endif - {"aboutProductDescription", IDS_ABOUT_PRODUCT_DESCRIPTION}, - {"relaunch", IDS_RELAUNCH_BUTTON}, -#if defined(OS_CHROMEOS) - {"relaunchAndPowerwash", IDS_RELAUNCH_AND_POWERWASH_BUTTON}, -#endif - {"productName", IDS_PRODUCT_NAME}, - {"updateCheckStarted", IDS_UPGRADE_CHECK_STARTED}, - {"updating", IDS_UPGRADE_UPDATING}, -#if defined(OS_CHROMEOS) || defined(OS_WIN) - {"updateDisabledByPolicy", IDS_UPGRADE_DISABLED_BY_POLICY}, -#endif // defined(OS_CHROMEOS) || defined(OS_WIN) -#if defined(OS_CHROMEOS) - {"updateButton", IDS_UPGRADE_BUTTON}, - {"updatingChannelSwitch", IDS_UPGRADE_UPDATING_CHANNEL_SWITCH}, -#endif - {"updateAlmostDone", IDS_UPGRADE_SUCCESSFUL_RELAUNCH}, -#if defined(OS_CHROMEOS) - {"successfulChannelSwitch", IDS_UPGRADE_SUCCESSFUL_CHANNEL_SWITCH}, -#endif - {"getHelpWithChrome", IDS_GET_HELP_USING_CHROME}, - {"reportAnIssue", IDS_REPORT_AN_ISSUE}, -#if defined(OS_CHROMEOS) - {"platform", IDS_PLATFORM_LABEL}, - {"arcVersion", IDS_ARC_VERSION_LABEL}, - {"firmware", IDS_ABOUT_PAGE_FIRMWARE}, - {"showMoreInfo", IDS_SHOW_MORE_INFO}, - {"hideMoreInfo", IDS_HIDE_MORE_INFO}, - {"channel", IDS_ABOUT_PAGE_CHANNEL}, - {"stable", IDS_ABOUT_PAGE_CHANNEL_STABLE}, - {"beta", IDS_ABOUT_PAGE_CHANNEL_BETA}, - {"dev", IDS_ABOUT_PAGE_CHANNEL_DEVELOPMENT}, - {"devChannelDisclaimer", IDS_ABOUT_PAGE_CHANNEL_DEVELOPMENT_DISCLAIMER}, - {"channel-changed", IDS_ABOUT_PAGE_CHANNEL_CHANGED}, - {"currentChannelStable", IDS_ABOUT_PAGE_CURRENT_CHANNEL_STABLE}, - {"currentChannelBeta", IDS_ABOUT_PAGE_CURRENT_CHANNEL_BETA}, - {"currentChannelDev", IDS_ABOUT_PAGE_CURRENT_CHANNEL_DEV}, - {"currentChannel", IDS_ABOUT_PAGE_CURRENT_CHANNEL}, - {"channelChangeButton", IDS_ABOUT_PAGE_CHANNEL_CHANGE_BUTTON}, - {"channelChangeDisallowedMessage", - IDS_ABOUT_PAGE_CHANNEL_CHANGE_DISALLOWED_MESSAGE}, - {"channelChangePageTitle", IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_TITLE}, - {"channelChangePagePowerwashTitle", - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_POWERWASH_TITLE}, - {"channelChangePagePowerwashMessage", - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_POWERWASH_MESSAGE}, - {"channelChangePageDelayedChangeTitle", - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_DELAYED_CHANGE_TITLE}, - {"channelChangePageUnstableTitle", - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_UNSTABLE_TITLE}, - {"channelChangePagePowerwashButton", - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_POWERWASH_BUTTON}, - {"channelChangePageChangeButton", - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_CHANGE_BUTTON}, - {"channelChangePageCancelButton", - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_CANCEL_BUTTON}, - {"userAgent", IDS_VERSION_UI_USER_AGENT}, - {"commandLine", IDS_VERSION_UI_COMMAND_LINE}, - {"buildDate", IDS_VERSION_UI_BUILD_DATE}, -#endif -#if defined(OS_MACOSX) || defined(OS_WIN) - {"learnMore", IDS_LEARN_MORE}, -#endif -#if defined(OS_MACOSX) - {"promote", IDS_ABOUT_CHROME_PROMOTE_UPDATER}, -#endif - }; - - for (size_t i = 0; i < arraysize(resources); ++i) { - localized_strings->SetString(resources[i].name, - l10n_util::GetStringUTF16(resources[i].ids)); - } - -#if defined(OS_CHROMEOS) - localized_strings->SetString( - "upToDate", ui::SubstituteChromeOSDeviceType(IDS_UPGRADE_UP_TO_DATE)); -#else - localized_strings->SetString("upToDate", l10n_util::GetStringUTF16( - IDS_UPGRADE_UP_TO_DATE)); -#endif - - localized_strings->SetString("updateObsoleteSystem", - ObsoleteSystem::LocalizedObsoleteString()); - localized_strings->SetString("updateObsoleteSystemURL", - ObsoleteSystem::GetLinkURL()); - - localized_strings->SetString( - "browserVersion", - l10n_util::GetStringFUTF16(IDS_ABOUT_PRODUCT_VERSION, - BuildBrowserVersionString())); - - localized_strings->SetString( - "productCopyright", - base::i18n::MessageFormatter::FormatWithNumberedArgs( - l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_COPYRIGHT), - base::Time::Now())); - - base::string16 license = l10n_util::GetStringFUTF16( - IDS_VERSION_UI_LICENSE, base::ASCIIToUTF16(chrome::kChromiumProjectURL), - base::ASCIIToUTF16(chrome::kChromeUICreditsURL)); - localized_strings->SetString("productLicense", license); - -#if defined(OS_CHROMEOS) - base::string16 os_license = l10n_util::GetStringFUTF16( - IDS_ABOUT_CROS_VERSION_LICENSE, - base::ASCIIToUTF16(chrome::kChromeUIOSCreditsURL)); - localized_strings->SetString("productOsLicense", os_license); - - base::string16 product_name = l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME); - localized_strings->SetString( - "channelChangePageDelayedChangeMessage", - l10n_util::GetStringFUTF16( - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_DELAYED_CHANGE_MESSAGE, - product_name)); - localized_strings->SetString( - "channelChangePageUnstableMessage", - l10n_util::GetStringFUTF16( - IDS_ABOUT_PAGE_CHANNEL_CHANGE_PAGE_UNSTABLE_MESSAGE, - product_name)); - - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kDisableNewChannelSwitcherUI)) { - localized_strings->SetBoolean("disableNewChannelSwitcherUI", true); - } - - localized_strings->SetString( - "eolLearnMore", l10n_util::GetStringFUTF16( - IDS_ABOUT_PAGE_EOL_LEARN_MORE, - base::ASCIIToUTF16(chrome::kEolNotificationURL))); -#endif - - base::string16 tos = l10n_util::GetStringFUTF16( - IDS_ABOUT_TERMS_OF_SERVICE, base::UTF8ToUTF16(chrome::kChromeUITermsURL)); - localized_strings->SetString("productTOS", tos); - - localized_strings->SetString("jsEngine", "V8"); - localized_strings->SetString("jsEngineVersion", V8_VERSION_STRING); - - localized_strings->SetString("userAgentInfo", GetUserAgent()); - - base::CommandLine::StringType command_line = - base::CommandLine::ForCurrentProcess()->GetCommandLineString(); - localized_strings->SetString("commandLineInfo", command_line); -} - -void HelpHandler::RegisterMessages() { - version_updater_.reset(VersionUpdater::Create(web_ui()->GetWebContents())); - apply_changes_from_upgrade_observer_ = true; - policy_registrar_.Observe( - policy::key::kDeviceAutoUpdateDisabled, - base::Bind(&HelpHandler::OnDeviceAutoUpdatePolicyChanged, - base::Unretained(this))); - - web_ui()->RegisterMessageCallback("onPageLoaded", - base::Bind(&HelpHandler::OnPageLoaded, base::Unretained(this))); - web_ui()->RegisterMessageCallback("relaunchNow", - base::Bind(&HelpHandler::RelaunchNow, base::Unretained(this))); - web_ui()->RegisterMessageCallback("openFeedbackDialog", - base::Bind(&HelpHandler::OpenFeedbackDialog, base::Unretained(this))); - web_ui()->RegisterMessageCallback("openHelpPage", - base::Bind(&HelpHandler::OpenHelpPage, base::Unretained(this))); -#if defined(OS_CHROMEOS) - web_ui()->RegisterMessageCallback("setChannel", - base::Bind(&HelpHandler::SetChannel, base::Unretained(this))); - web_ui()->RegisterMessageCallback("relaunchAndPowerwash", - base::Bind(&HelpHandler::RelaunchAndPowerwash, base::Unretained(this))); - web_ui()->RegisterMessageCallback("requestUpdate", - base::Bind(&HelpHandler::RequestUpdate, base::Unretained(this))); -#endif -#if defined(OS_MACOSX) - web_ui()->RegisterMessageCallback("promoteUpdater", - base::Bind(&HelpHandler::PromoteUpdater, base::Unretained(this))); -#endif - -#if defined(OS_CHROMEOS) - // Handler for the product label image, which will be shown if available. - content::URLDataSource::Add(Profile::FromWebUI(web_ui()), - new chromeos::ImageSource()); -#endif -} - -void HelpHandler::OnUpgradeRecommended() { - if (apply_changes_from_upgrade_observer_) { - // A version update is installed and ready to go. Refresh the UI so the - // correct state will be shown. - RequestUpdate(nullptr); - } -} - -// static -base::string16 HelpHandler::BuildBrowserVersionString() { - std::string version = version_info::GetVersionNumber(); - - std::string modifier = chrome::GetChannelString(); - if (!modifier.empty()) - version += " " + modifier; - -#if defined(ARCH_CPU_64_BITS) - version += " (64-bit)"; -#endif - - return base::UTF8ToUTF16(version); -} - -void HelpHandler::OnDeviceAutoUpdatePolicyChanged( - const base::Value* previous_policy, - const base::Value* current_policy) { - bool previous_auto_update_disabled = false; - if (previous_policy) - CHECK(previous_policy->GetAsBoolean(&previous_auto_update_disabled)); - - bool current_auto_update_disabled = false; - if (current_policy) - CHECK(current_policy->GetAsBoolean(¤t_auto_update_disabled)); - - if (current_auto_update_disabled != previous_auto_update_disabled) { - // Refresh the update status to refresh the status of the UI. - RefreshUpdateStatus(); - } -} - -void HelpHandler::RefreshUpdateStatus() { - // On Chrome OS, do not check for an update automatically. -#if defined(OS_CHROMEOS) - static_cast<VersionUpdaterCros*>(version_updater_.get())->GetUpdateStatus( - base::Bind(&HelpHandler::SetUpdateStatus, base::Unretained(this))); -#else - RequestUpdate(NULL); -#endif -} - -void HelpHandler::OnPageLoaded(const base::ListValue* args) { -#if defined(OS_CHROMEOS) - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&chromeos::version_loader::GetVersion, - chromeos::version_loader::VERSION_FULL), - base::Bind(&HelpHandler::OnOSVersion, weak_factory_.GetWeakPtr())); - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&chromeos::version_loader::GetARCVersion), - base::Bind(&HelpHandler::OnARCVersion, weak_factory_.GetWeakPtr())); - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&chromeos::version_loader::GetFirmware), - base::Bind(&HelpHandler::OnOSFirmware, weak_factory_.GetWeakPtr())); - - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.updateEnableReleaseChannel", - base::Value(CanChangeChannel(Profile::FromWebUI(web_ui())))); - - base::Time build_time = base::SysInfo::GetLsbReleaseTime(); - base::string16 build_date = base::TimeFormatFriendlyDate(build_time); - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setBuildDate", - base::Value(build_date)); -#endif // defined(OS_CHROMEOS) - - RefreshUpdateStatus(); - - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.setObsoleteSystem", - base::Value(ObsoleteSystem::IsObsoleteNowOrSoon())); - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.setObsoleteSystemEndOfTheLine", - base::Value(ObsoleteSystem::IsObsoleteNowOrSoon() && - ObsoleteSystem::IsEndOfTheLine())); - -#if defined(OS_CHROMEOS) - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.updateIsEnterpriseManaged", - base::Value(IsEnterpriseManaged())); - // First argument to GetChannel() is a flag that indicates whether - // current channel should be returned (if true) or target channel - // (otherwise). - version_updater_->GetChannel(true, - base::Bind(&HelpHandler::OnCurrentChannel, weak_factory_.GetWeakPtr())); - version_updater_->GetChannel(false, - base::Bind(&HelpHandler::OnTargetChannel, weak_factory_.GetWeakPtr())); - - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kDisableEolNotification)) { - version_updater_->GetEolStatus( - base::Bind(&HelpHandler::OnEolStatus, weak_factory_.GetWeakPtr())); - } - - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&FindRegulatoryLabelDir), - base::Bind(&HelpHandler::OnRegulatoryLabelDirFound, - weak_factory_.GetWeakPtr())); -#endif -} - -#if defined(OS_MACOSX) -void HelpHandler::PromoteUpdater(const base::ListValue* args) { - version_updater_->PromoteUpdater(); -} -#endif - -void HelpHandler::RelaunchNow(const base::ListValue* args) { - DCHECK(args->empty()); - chrome::AttemptRelaunch(); -} - -void HelpHandler::OpenFeedbackDialog(const base::ListValue* args) { - DCHECK(args->empty()); - Browser* browser = chrome::FindBrowserWithWebContents( - web_ui()->GetWebContents()); - chrome::OpenFeedbackDialog(browser, - chrome::kFeedbackSourceOldSettingsAboutPage); -} - -void HelpHandler::OpenHelpPage(const base::ListValue* args) { - DCHECK(args->empty()); - Browser* browser = chrome::FindBrowserWithWebContents( - web_ui()->GetWebContents()); - chrome::ShowHelp(browser, chrome::HELP_SOURCE_WEBUI); -} - -#if defined(OS_CHROMEOS) - -void HelpHandler::SetChannel(const base::ListValue* args) { - DCHECK(args->GetSize() == 2); - - if (!CanChangeChannel(Profile::FromWebUI(web_ui()))) { - LOG(WARNING) << "Non-owner tried to change release track."; - return; - } - - base::string16 channel; - bool is_powerwash_allowed; - if (!args->GetString(0, &channel) || - !args->GetBoolean(1, &is_powerwash_allowed)) { - LOG(ERROR) << "Can't parse SetChannel() args"; - return; - } - - version_updater_->SetChannel(base::UTF16ToUTF8(channel), - is_powerwash_allowed); - if (user_manager::UserManager::Get()->IsCurrentUserOwner()) { - // Check for update after switching release channel. - version_updater_->CheckForUpdate(base::Bind(&HelpHandler::SetUpdateStatus, - base::Unretained(this)), - VersionUpdater::PromoteCallback()); - } -} - -void HelpHandler::RelaunchAndPowerwash(const base::ListValue* args) { - DCHECK(args->empty()); - - if (IsEnterpriseManaged()) - return; - - PrefService* prefs = g_browser_process->local_state(); - prefs->SetBoolean(prefs::kFactoryResetRequested, true); - prefs->CommitPendingWrite(); - - // Perform sign out. Current chrome process will then terminate, new one will - // be launched (as if it was a restart). - chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); -} - -#endif // defined(OS_CHROMEOS) - -void HelpHandler::RequestUpdate(const base::ListValue* args) { - VersionUpdater::PromoteCallback promote_callback; - version_updater_->CheckForUpdate( - base::Bind(&HelpHandler::SetUpdateStatus, base::Unretained(this)), -#if defined(OS_MACOSX) - base::Bind(&HelpHandler::SetPromotionState, base::Unretained(this))); -#else - VersionUpdater::PromoteCallback()); -#endif // OS_MACOSX -} - -void HelpHandler::SetUpdateStatus(VersionUpdater::Status status, - int progress, - const std::string& /* version */, - int64_t /* size */, - const base::string16& message) { - // Only UPDATING state should have progress set. - DCHECK(status == VersionUpdater::UPDATING || progress == 0); - - std::string status_str; - switch (status) { - case VersionUpdater::CHECKING: - status_str = "checking"; - break; - case VersionUpdater::UPDATING: - status_str = "updating"; - break; - case VersionUpdater::NEARLY_UPDATED: - status_str = "nearly_updated"; - break; - case VersionUpdater::UPDATED: - status_str = "updated"; - break; - case VersionUpdater::FAILED: - case VersionUpdater::FAILED_OFFLINE: - case VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED: - // Old help page does not support update over cellular connection. Treat this - // signal as FAILED. - case VersionUpdater::NEED_PERMISSION_TO_UPDATE: - status_str = "failed"; - break; - case VersionUpdater::DISABLED: - status_str = "disabled"; - break; - case VersionUpdater::DISABLED_BY_ADMIN: - status_str = "disabled_by_admin"; - break; - } - - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setUpdateStatus", - base::Value(status_str), - base::Value(message)); - - if (status == VersionUpdater::UPDATING) { - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setProgress", - base::Value(progress)); - } - -#if defined(OS_CHROMEOS) - if (status == VersionUpdater::FAILED_OFFLINE || - status == VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED) { - base::string16 types_msg = GetAllowedConnectionTypesMessage(); - if (!types_msg.empty()) { - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.setAndShowAllowedConnectionTypesMsg", - base::Value(types_msg)); - } else { - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.showAllowedConnectionTypesMsg", base::Value(false)); - } - } else { - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.showAllowedConnectionTypesMsg", base::Value(false)); - } -#endif // defined(OS_CHROMEOS) -} - -#if defined(OS_MACOSX) -void HelpHandler::SetPromotionState(VersionUpdater::PromotionState state) { - std::string state_str; - switch (state) { - case VersionUpdater::PROMOTE_HIDDEN: - case VersionUpdater::PROMOTED: - state_str = "hidden"; - break; - case VersionUpdater::PROMOTE_ENABLED: - state_str = "enabled"; - break; - case VersionUpdater::PROMOTE_DISABLED: - state_str = "disabled"; - break; - } - - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setPromotionState", - base::Value(state_str)); -} -#endif // defined(OS_MACOSX) - -#if defined(OS_CHROMEOS) -void HelpHandler::OnOSVersion(const std::string& version) { - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setOSVersion", - base::Value(version)); -} - -void HelpHandler::OnARCVersion(const std::string& firmware) { - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setARCVersion", - base::Value(firmware)); -} - -void HelpHandler::OnOSFirmware(const std::string& firmware) { - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setOSFirmware", - base::Value(firmware)); -} - -void HelpHandler::OnCurrentChannel(const std::string& channel) { - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.updateCurrentChannel", - base::Value(channel)); -} - -void HelpHandler::OnTargetChannel(const std::string& channel) { - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.updateTargetChannel", - base::Value(channel)); -} - -void HelpHandler::OnRegulatoryLabelDirFound(const base::FilePath& path) { - if (path.empty()) - return; - - base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, - base::Bind(&ReadRegulatoryLabelText, path), - base::Bind(&HelpHandler::OnRegulatoryLabelTextRead, - weak_factory_.GetWeakPtr())); - - // Send the image path to the WebUI. - OnRegulatoryLabelImageFound(path.AppendASCII(kRegulatoryLabelImageFilename)); -} - -void HelpHandler::OnRegulatoryLabelImageFound(const base::FilePath& path) { - std::string url = std::string("chrome://") + chrome::kChromeOSAssetHost + - "/" + path.MaybeAsASCII(); - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.setRegulatoryLabelPath", - base::Value(url)); -} - -void HelpHandler::OnRegulatoryLabelTextRead(const std::string& text) { - // Remove unnecessary whitespace. - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.setRegulatoryLabelText", - base::Value(base::CollapseWhitespaceASCII(text, true))); -} - -void HelpHandler::OnEolStatus(update_engine::EndOfLifeStatus status) { - // Security only state is no longer supported. - if (status == update_engine::EndOfLifeStatus::kSecurityOnly || - IsEnterpriseManaged()) { - return; - } - - if (status == update_engine::EndOfLifeStatus::kSupported) { - web_ui()->CallJavascriptFunctionUnsafe("help.HelpPage.updateEolMessage", - base::Value("device_supported"), - base::Value("")); - } else { - web_ui()->CallJavascriptFunctionUnsafe( - "help.HelpPage.updateEolMessage", base::Value("device_endoflife"), - base::Value(l10n_util::GetStringUTF16(IDS_ABOUT_PAGE_EOL_EOL))); - } -} - -#endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/help/help_handler.h b/chrome/browser/ui/webui/help/help_handler.h deleted file mode 100644 index 5aea40c..0000000 --- a/chrome/browser/ui/webui/help/help_handler.h +++ /dev/null
@@ -1,136 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_HELP_HELP_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_HELP_HELP_HANDLER_H_ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/strings/string16.h" -#include "build/build_config.h" -#include "chrome/browser/ui/webui/help/version_updater.h" -#include "chrome/browser/upgrade_observer.h" -#include "components/policy/core/common/policy_service.h" -#include "content/public/browser/web_ui_message_handler.h" - -#if defined(OS_CHROMEOS) -#include "base/task/cancelable_task_tracker.h" -#include "chromeos/system/version_loader.h" -#include "third_party/cros_system_api/dbus/update_engine/dbus-constants.h" -#endif // defined(OS_CHROMEOS) - -namespace base { -class DictionaryValue; -class FilePath; -class ListValue; -} - -// WebUI message handler for the help page. -class HelpHandler : public content::WebUIMessageHandler, - public UpgradeObserver { - public: - HelpHandler(); - ~HelpHandler() override; - - // WebUIMessageHandler implementation. - void RegisterMessages() override; - - // Adds string values for the UI to |localized_strings|. - static void GetLocalizedValues(base::DictionaryValue* localized_strings); - - // UpgradeObserver implementation. - void OnUpgradeRecommended() override; - - // Returns the browser version as a string. - static base::string16 BuildBrowserVersionString(); - - private: - void OnDeviceAutoUpdatePolicyChanged(const base::Value* previous_policy, - const base::Value* current_policy); - - // On ChromeOS, this gets the current update status. On other platforms, it - // will request and perform an update (if one is available). - void RefreshUpdateStatus(); - - // Initializes querying values for the page. - void OnPageLoaded(const base::ListValue* args); - -#if defined(OS_MACOSX) - // Promotes the updater for all users. - void PromoteUpdater(const base::ListValue* args); -#endif - - // Relaunches the browser. |args| must be empty. - void RelaunchNow(const base::ListValue* args); - - // Opens the feedback dialog. |args| must be empty. - void OpenFeedbackDialog(const base::ListValue* args); - - // Opens the help page. |args| must be empty. - void OpenHelpPage(const base::ListValue* args); - -#if defined(OS_CHROMEOS) - // Sets the release track version. - void SetChannel(const base::ListValue* args); - - // Performs relaunch and powerwash. - void RelaunchAndPowerwash(const base::ListValue* args); -#endif - - // Checks for and applies update. - void RequestUpdate(const base::ListValue* args); - - // Callback method which forwards status updates to the page. - void SetUpdateStatus(VersionUpdater::Status status, - int progress, - const std::string& version, - int64_t size, - const base::string16& fail_message); - -#if defined(OS_MACOSX) - // Callback method which forwards promotion state to the page. - void SetPromotionState(VersionUpdater::PromotionState state); -#endif - -#if defined(OS_CHROMEOS) - // Callbacks from VersionLoader. - void OnOSVersion(const std::string& version); - void OnARCVersion(const std::string& firmware); - void OnOSFirmware(const std::string& firmware); - void OnCurrentChannel(const std::string& channel); - void OnTargetChannel(const std::string& channel); - - // Callback for when the directory with the regulatory label image and alt - // text has been found. - void OnRegulatoryLabelDirFound(const base::FilePath& path); - - // Callback for setting the regulatory label source. - void OnRegulatoryLabelImageFound(const base::FilePath& path); - - // Callback for setting the regulatory label alt text. - void OnRegulatoryLabelTextRead(const std::string& text); - - // Callback for setting the eol string text. - void OnEolStatus(update_engine::EndOfLifeStatus status); -#endif - - // Specialized instance of the VersionUpdater used to update the browser. - std::unique_ptr<VersionUpdater> version_updater_; - - // Used to observe changes in the |kDeviceAutoUpdateDisabled| policy. - policy::PolicyChangeRegistrar policy_registrar_; - - // If true changes to UpgradeObserver are applied, if false they are ignored. - bool apply_changes_from_upgrade_observer_; - - // Used for callbacks. - base::WeakPtrFactory<HelpHandler> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(HelpHandler); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_HELP_HELP_HANDLER_H_
diff --git a/chrome/browser/ui/webui/help/help_utils_chromeos.cc b/chrome/browser/ui/webui/help/help_utils_chromeos.cc index 068f358..46b3ad2 100644 --- a/chrome/browser/ui/webui/help/help_utils_chromeos.cc +++ b/chrome/browser/ui/webui/help/help_utils_chromeos.cc
@@ -11,13 +11,8 @@ #include "base/logging.h" #include "base/values.h" #include "chrome/browser/chromeos/settings/cros_settings.h" -#include "chrome/grit/generated_resources.h" #include "chromeos/chromeos_switches.h" -#include "chromeos/network/network_state.h" -#include "chromeos/network/network_type_pattern.h" #include "chromeos/settings/cros_settings_names.h" -#include "third_party/cros_system_api/dbus/service_constants.h" -#include "ui/base/l10n/l10n_util.h" namespace help_utils_chromeos { @@ -52,25 +47,4 @@ return false; } -base::string16 GetConnectionTypeAsUTF16(const chromeos::NetworkState* network) { - const std::string type = - network->IsUsingMobileData() ? shill::kTypeCellular : network->type(); - if (chromeos::NetworkTypePattern::Ethernet().MatchesType(type)) - return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_ETHERNET); - if (type == shill::kTypeWifi) - return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_WIFI); - if (type == shill::kTypeWimax) - return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_WIMAX); - if (type == shill::kTypeBluetooth) - return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_BLUETOOTH); - if (type == shill::kTypeCellular || - chromeos::NetworkTypePattern::Tether().MatchesType(type)) { - return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_MOBILE_DATA); - } - if (type == shill::kTypeVPN) - return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_VPN); - NOTREACHED(); - return base::string16(); -} - } // namespace help_utils_chromeos
diff --git a/chrome/browser/ui/webui/help/help_utils_chromeos.h b/chrome/browser/ui/webui/help/help_utils_chromeos.h index ec388ef..c022989 100644 --- a/chrome/browser/ui/webui/help/help_utils_chromeos.h +++ b/chrome/browser/ui/webui/help/help_utils_chromeos.h
@@ -5,12 +5,6 @@ #ifndef CHROME_BROWSER_UI_WEBUI_HELP_HELP_UTILS_CHROMEOS_H_ #define CHROME_BROWSER_UI_WEBUI_HELP_HELP_UTILS_CHROMEOS_H_ -#include "base/strings/string16.h" - -namespace chromeos { -class NetworkState; -} - namespace help_utils_chromeos { // Returns true if updates over cellular networks are allowed. If |interactive| @@ -20,9 +14,6 @@ // policy. bool IsUpdateOverCellularAllowed(bool interactive); -// Returns localized name for the connection |type|. -base::string16 GetConnectionTypeAsUTF16(const chromeos::NetworkState* network); - } // namespace help_utils_chromeos #endif // CHROME_BROWSER_UI_WEBUI_HELP_HELP_UTILS_CHROMEOS_H_
diff --git a/chrome/browser/ui/webui/help/version_updater_chromeos.cc b/chrome/browser/ui/webui/help/version_updater_chromeos.cc index e40bf19..6f1d85c 100644 --- a/chrome/browser/ui/webui/help/version_updater_chromeos.cc +++ b/chrome/browser/ui/webui/help/version_updater_chromeos.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/strings/string16.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/startup_utils.h" @@ -22,8 +23,10 @@ #include "chromeos/network/network_handler.h" #include "chromeos/network/network_state.h" #include "chromeos/network/network_state_handler.h" +#include "chromeos/network/network_type_pattern.h" #include "chromeos/settings/cros_settings_names.h" #include "content/public/browser/web_contents.h" +#include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/base/l10n/l10n_util.h" using chromeos::CrosSettings; @@ -76,6 +79,27 @@ return update_disabled; } +base::string16 GetConnectionTypeAsUTF16(const chromeos::NetworkState* network) { + const std::string type = + network->IsUsingMobileData() ? shill::kTypeCellular : network->type(); + if (chromeos::NetworkTypePattern::Ethernet().MatchesType(type)) + return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_ETHERNET); + if (type == shill::kTypeWifi) + return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_WIFI); + if (type == shill::kTypeWimax) + return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_WIMAX); + if (type == shill::kTypeBluetooth) + return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_BLUETOOTH); + if (type == shill::kTypeCellular || + chromeos::NetworkTypePattern::Tether().MatchesType(type)) { + return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_MOBILE_DATA); + } + if (type == shill::kTypeVPN) + return l10n_util::GetStringUTF16(IDS_NETWORK_TYPE_VPN); + NOTREACHED(); + return base::string16(); +} + // Returns whether an update is allowed. If not, it calls the callback with // the appropriate status. |interactive| indicates whether the user is actively // checking for updates. @@ -101,8 +125,7 @@ return false; } else if (status == NETWORK_STATUS_DISALLOWED) { base::string16 message = l10n_util::GetStringFUTF16( - IDS_UPGRADE_DISALLOWED, - help_utils_chromeos::GetConnectionTypeAsUTF16(network)); + IDS_UPGRADE_DISALLOWED, GetConnectionTypeAsUTF16(network)); callback.Run(VersionUpdater::FAILED_CONNECTION_TYPE_DISALLOWED, 0, std::string(), 0, message); return false;
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 1ea65bf..be1d3c6 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -241,6 +241,7 @@ {"aboutArcVersionLabel", IDS_SETTINGS_ABOUT_PAGE_ARC_VERSION}, {"aboutBuildDateLabel", IDS_VERSION_UI_BUILD_DATE}, {"aboutChannelBeta", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_BETA}, + {"aboutChannelCanary", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_CANARY}, {"aboutChannelDev", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_DEV}, {"aboutChannelLabel", IDS_SETTINGS_ABOUT_PAGE_CHANNEL}, {"aboutChannelStable", IDS_SETTINGS_ABOUT_PAGE_CURRENT_CHANNEL_STABLE},
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index f99019f..11480b8 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -29,6 +29,7 @@ "elements/close_button_texture.h", "elements/content_element.cc", "elements/content_element.h", + "elements/draw_phase.h", "elements/exclusive_screen_toast.cc", "elements/exclusive_screen_toast.h", "elements/exclusive_screen_toast_texture.cc", @@ -72,7 +73,7 @@ "elements/transience_manager.h", "elements/ui_element.cc", "elements/ui_element.h", - "elements/ui_element_debug_id.h", + "elements/ui_element_name.h", "elements/ui_element_transform_operations.cc", "elements/ui_element_transform_operations.h", "elements/ui_texture.cc",
diff --git a/chrome/browser/vr/elements/draw_phase.h b/chrome/browser/vr/elements/draw_phase.h new file mode 100644 index 0000000..742e728 --- /dev/null +++ b/chrome/browser/vr/elements/draw_phase.h
@@ -0,0 +1,25 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VR_ELEMENTS_DRAW_PHASE_H_ +#define CHROME_BROWSER_VR_ELEMENTS_DRAW_PHASE_H_ + +namespace vr { + +// Each draw phase is rendered independently in the order specified below. +// +// TODO(vollick): once we've established the element hierarchy, only elements in +// the 2D browsing foreground need to be depth sorted. We should rewrite our +// sorting logic at that point to leverage the hierarchy and delete this enum. +enum DrawPhase : int { + // kPhaseNone is to be used for elements that do not draw. Eg, layouts. + kPhaseBackground = 0, + kPhaseFloorCeiling, + kPhaseForeground, + kPhaseNone, +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_ELEMENTS_DRAW_PHASE_H_
diff --git a/chrome/browser/vr/elements/linear_layout.cc b/chrome/browser/vr/elements/linear_layout.cc index d5ec7e2f..524cf02 100644 --- a/chrome/browser/vr/elements/linear_layout.cc +++ b/chrome/browser/vr/elements/linear_layout.cc
@@ -20,13 +20,13 @@ void LinearLayout::LayOutChildren() { float total_extent = -margin_; - for (auto* child : children()) { + for (auto& child : children()) { if (child->visible()) total_extent += GetExtent(*child, direction_) + margin_; } float offset = -0.5 * total_extent; - for (auto* child : children()) { + for (auto& child : children()) { if (!child->visible()) continue; float extent = GetExtent(*child, direction_);
diff --git a/chrome/browser/vr/elements/linear_layout_unittest.cc b/chrome/browser/vr/elements/linear_layout_unittest.cc index 833ce0d..d6c0cb07 100644 --- a/chrome/browser/vr/elements/linear_layout_unittest.cc +++ b/chrome/browser/vr/elements/linear_layout_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/vr/elements/linear_layout.h" +#include "base/memory/ptr_util.h" #include "testing/gtest/include/gtest/gtest.h" namespace vr { @@ -11,27 +12,29 @@ TEST(LinearLayout, HorizontalLayout) { LinearLayout layout(LinearLayout::kHorizontal); layout.set_margin(10); - UiElement rect_a; - rect_a.SetSize(10, 10); - rect_a.SetVisible(true); - layout.AddChild(&rect_a); + auto element = base::MakeUnique<UiElement>(); + UiElement* rect_a = element.get(); + rect_a->SetSize(10, 10); + rect_a->SetVisible(true); + layout.AddChild(std::move(element)); // One element should require no position adjustment at all. layout.LayOutChildren(); - EXPECT_TRUE(rect_a.LocalTransform().IsIdentity()); + EXPECT_TRUE(rect_a->LocalTransform().IsIdentity()); // Two elements should be centered and separated by the margin. - UiElement rect_b; - rect_b.SetSize(20, 20); - rect_b.SetVisible(true); - layout.AddChild(&rect_b); + element = base::MakeUnique<UiElement>(); + UiElement* rect_b = element.get(); + rect_b->SetSize(20, 20); + rect_b->SetVisible(true); + layout.AddChild(std::move(element)); layout.LayOutChildren(); gfx::Point3F position_a; - rect_a.LocalTransform().TransformPoint(&position_a); + rect_a->LocalTransform().TransformPoint(&position_a); gfx::Point3F position_b; - rect_b.LocalTransform().TransformPoint(&position_b); + rect_b->LocalTransform().TransformPoint(&position_b); EXPECT_FLOAT_EQ(-15.0f, position_a.x()); EXPECT_FLOAT_EQ(0.0f, position_a.y()); @@ -41,36 +44,38 @@ EXPECT_FLOAT_EQ(0.0f, position_b.y()); EXPECT_FLOAT_EQ(0.0f, position_b.z()); - rect_a.SetVisible(false); + rect_a->SetVisible(false); layout.LayOutChildren(); // The invisible child should not be accounted for in the layout. - EXPECT_TRUE(rect_b.LocalTransform().IsIdentity()); + EXPECT_TRUE(rect_b->LocalTransform().IsIdentity()); } TEST(LinearLayout, VerticalLayout) { LinearLayout layout(LinearLayout::kVertical); layout.set_margin(10); - UiElement rect_a; - rect_a.SetSize(10, 10); - rect_a.SetVisible(true); - layout.AddChild(&rect_a); + auto element = base::MakeUnique<UiElement>(); + UiElement* rect_a = element.get(); + rect_a->SetSize(10, 10); + rect_a->SetVisible(true); + layout.AddChild(std::move(element)); // One element should require no position adjustment at all. layout.LayOutChildren(); - EXPECT_TRUE(rect_a.LocalTransform().IsIdentity()); + EXPECT_TRUE(rect_a->LocalTransform().IsIdentity()); // Two elements should be centered and separated by the margin. - UiElement rect_b; - rect_b.SetSize(20, 20); - rect_b.SetVisible(true); - layout.AddChild(&rect_b); + element = base::MakeUnique<UiElement>(); + UiElement* rect_b = element.get(); + rect_b->SetSize(20, 20); + rect_b->SetVisible(true); + layout.AddChild(std::move(element)); layout.LayOutChildren(); gfx::Point3F position_a; - rect_a.LocalTransform().TransformPoint(&position_a); + rect_a->LocalTransform().TransformPoint(&position_a); gfx::Point3F position_b; - rect_b.LocalTransform().TransformPoint(&position_b); + rect_b->LocalTransform().TransformPoint(&position_b); EXPECT_FLOAT_EQ(0.0f, position_a.x()); EXPECT_FLOAT_EQ(-15.0f, position_a.y()); @@ -80,10 +85,10 @@ EXPECT_FLOAT_EQ(10.0f, position_b.y()); EXPECT_FLOAT_EQ(0.0f, position_b.z()); - rect_a.SetVisible(false); + rect_a->SetVisible(false); layout.LayOutChildren(); // The invisible child should not be accounted for in the layout. - EXPECT_TRUE(rect_b.LocalTransform().IsIdentity()); + EXPECT_TRUE(rect_b->LocalTransform().IsIdentity()); } } // namespace vr
diff --git a/chrome/browser/vr/elements/ui_element.cc b/chrome/browser/vr/elements/ui_element.cc index 442c209..c3eddc8 100644 --- a/chrome/browser/vr/elements/ui_element.cc +++ b/chrome/browser/vr/elements/ui_element.cc
@@ -7,6 +7,7 @@ #include <limits> #include "base/logging.h" +#include "base/stl_util.h" #include "base/time/time.h" #include "cc/base/math_util.h" #include "chrome/browser/vr/elements/ui_element_transform_operations.h" @@ -16,6 +17,11 @@ namespace { +int AllocateId() { + static int g_next_id = 1; + return g_next_id++; +} + bool GetRayPlaneDistance(const gfx::Point3F& ray_origin, const gfx::Vector3dF& ray_vector, const gfx::Point3F& plane_origin, @@ -32,7 +38,7 @@ } // namespace -UiElement::UiElement() { +UiElement::UiElement() : id_(AllocateId()) { animation_player_.set_target(this); layout_offset_.AppendTranslate(0, 0, 0); transform_operations_.AppendTranslate(0, 0, 0); @@ -158,6 +164,9 @@ } void UiElement::SetMode(ColorScheme::Mode mode) { + for (auto& child : children_) { + child->SetMode(mode); + } if (mode_ == mode) return; mode_ = mode; @@ -166,9 +175,20 @@ void UiElement::OnSetMode() {} -void UiElement::AddChild(UiElement* child) { +void UiElement::AddChild(std::unique_ptr<UiElement> child) { child->parent_ = this; - children_.push_back(child); + children_.push_back(std::move(child)); +} + +void UiElement::RemoveChild(UiElement* to_remove) { + DCHECK_EQ(this, to_remove->parent_); + to_remove->parent_ = nullptr; + size_t old_size = children_.size(); + base::EraseIf(children_, + [to_remove](const std::unique_ptr<UiElement>& child) { + return child.get() == to_remove; + }); + DCHECK_NE(old_size, children_.size()); } gfx::Point3F UiElement::GetCenter() const { @@ -243,7 +263,7 @@ } void UiElement::LayOutChildren() { - for (auto* child : children_) { + for (auto& child : children_) { // To anchor a child, use the parent's size to find its edge. float x_offset; switch (child->x_anchoring()) {
diff --git a/chrome/browser/vr/elements/ui_element.h b/chrome/browser/vr/elements/ui_element.h index 0a32557..1cecdef 100644 --- a/chrome/browser/vr/elements/ui_element.h +++ b/chrome/browser/vr/elements/ui_element.h
@@ -14,7 +14,8 @@ #include "cc/animation/transform_operations.h" #include "chrome/browser/vr/animation_player.h" #include "chrome/browser/vr/color_scheme.h" -#include "chrome/browser/vr/elements/ui_element_debug_id.h" +#include "chrome/browser/vr/elements/draw_phase.h" +#include "chrome/browser/vr/elements/ui_element_name.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/quaternion.h" @@ -101,7 +102,6 @@ virtual bool HitTest(const gfx::PointF& point) const; int id() const { return id_; } - void set_id(int id) { id_ = id; } // If true, this object will be visible. bool visible() const { return visible_; } @@ -187,8 +187,8 @@ void set_dirty(bool dirty) { dirty_ = dirty; } // A flag usable during transformation calculates to avoid duplicate work. - UiElementDebugId debug_id() const { return debug_id_; } - void set_debug_id(UiElementDebugId debug_id) { debug_id_ = debug_id; } + UiElementName name() const { return name_; } + void set_name(UiElementName name) { name_ = name; } // By default, sets an element to be visible or not. This may be overridden to // allow finer control of element visibility. @@ -205,10 +205,9 @@ } // Transformations are applied relative to the parent element, rather than - // absolutely. You cannot currently unparent elements. - // TODO(vollick): elements should own their children. UiScene can turn into - // recursive operations on the UiElement tree. - void AddChild(UiElement* child); + // absolutely. + void AddChild(std::unique_ptr<UiElement> child); + void RemoveChild(UiElement* child); UiElement* parent() { return parent_; } gfx::Point3F GetCenter() const; @@ -258,11 +257,14 @@ // or right where the head is pointing. virtual void AdjustRotationForHeadPose(const gfx::Vector3dF& look_at); + std::vector<std::unique_ptr<UiElement>>& children() { return children_; } + const std::vector<std::unique_ptr<UiElement>>& children() const { + return children_; + } + protected: virtual void OnSetMode(); - std::vector<UiElement*>& children() { return children_; } - base::TimeTicks last_frame_time() const { return last_frame_time_; } private: @@ -306,7 +308,7 @@ AnimationPlayer animation_player_; - int draw_phase_ = -1; + int draw_phase_ = kPhaseNone; // This is the time as of the last call to |Animate|. It is needed when // reversing transitions. @@ -319,7 +321,7 @@ bool dirty_ = false; // An identifier used for testing and debugging, in lieu of a string. - UiElementDebugId debug_id_ = UiElementDebugId::kNone; + UiElementName name_ = UiElementName::kNone; // This local transform operations. They are inherited by descendants and are // stored as a list of operations rather than a baked transform to make @@ -337,7 +339,7 @@ ColorScheme::Mode mode_ = ColorScheme::kModeNormal; UiElement* parent_ = nullptr; - std::vector<UiElement*> children_; + std::vector<std::unique_ptr<UiElement>> children_; DISALLOW_COPY_AND_ASSIGN(UiElement); };
diff --git a/chrome/browser/vr/elements/ui_element_debug_id.h b/chrome/browser/vr/elements/ui_element_name.h similarity index 67% rename from chrome/browser/vr/elements/ui_element_debug_id.h rename to chrome/browser/vr/elements/ui_element_name.h index ee334a5..eca211a 100644 --- a/chrome/browser/vr/elements/ui_element_debug_id.h +++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -2,40 +2,44 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_DEBUG_ID_H_ -#define CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_DEBUG_ID_H_ +#ifndef CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_NAME_H_ +#define CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_NAME_H_ namespace vr { // These identifiers serve as stable, semantic identifiers for UI elements. -// -// TODO(vollick): This should become UiElementName. These identifiers will be -// useful outside of testing and debugging code. Named as it is today, it sounds -// as if this can be done away with in release builds, which is not true. -enum UiElementDebugId { +enum UiElementName { kNone = 0, + kRoot, + k2dBrowsingRoot, + k2dBrowsingBackground, + k2dBrowsingForeground, + k2dBrowsingViewportAwareRoot, + kWebVrRoot, kWebVrPermanentHttpSecurityWarning, kWebVrTransientHttpSecurityWarning, + kWebVrViewportAwareRoot, kContentQuad, kBackplane, kCeiling, kFloor, kUrlBar, - kLoadingIndicator, + kIndicatorLayout, kAudioCaptureIndicator, kVideoCaptureIndicator, kScreenCaptureIndicator, + kLocationAccessIndicator, + kBluetoothConnectedIndicator, + kLoadingIndicator, kCloseButton, kScreenDimmer, kExitWarning, kExitPrompt, kExitPromptBackplane, kWebVrUrlToast, - kLocationAccessIndicator, kExclusiveScreenToast, kExclusiveScreenToastViewportAware, kSplashScreenText, - kBluetoothConnectedIndicator, kBackgroundFront, kBackgroundLeft, kBackgroundBack, @@ -47,4 +51,4 @@ } // namespace vr -#endif // CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_DEBUG_ID_H_ +#endif // CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_NAME_H_
diff --git a/chrome/browser/vr/elements/viewport_aware_root.cc b/chrome/browser/vr/elements/viewport_aware_root.cc index 687d9f7..c6b5f1c 100644 --- a/chrome/browser/vr/elements/viewport_aware_root.cc +++ b/chrome/browser/vr/elements/viewport_aware_root.cc
@@ -19,8 +19,16 @@ void ViewportAwareRoot::AdjustRotationForHeadPose( const gfx::Vector3dF& look_at) { - // This must be a top level element. - DCHECK(!parent()); + // We must not inherit a transform. + // + // TODO(vollick): ensure that this check happens at the right time in the + // frame lifecycle. More precisely, once we've made ApplyRecursiveTransforms a + // recursive function on the UiElement tree, we can do this check there. + // Presently, we're checking our parent's transform from last frame. The + // transform from last frame should also be the identity, of course, so the + // check is valid, but we'd prefer to check the transform for the current + // frame. + DCHECK(parent()->world_space_transform().IsIdentity()); DCHECK(viewport_aware()); gfx::Vector3dF rotated_center_vector{0.f, 0.f, -1.0f};
diff --git a/chrome/browser/vr/elements/viewport_aware_root_unittest.cc b/chrome/browser/vr/elements/viewport_aware_root_unittest.cc index 5bb1b9f..17f96dc 100644 --- a/chrome/browser/vr/elements/viewport_aware_root_unittest.cc +++ b/chrome/browser/vr/elements/viewport_aware_root_unittest.cc
@@ -7,6 +7,7 @@ #include <cmath> #include "base/memory/ptr_util.h" +#include "chrome/browser/vr/elements/draw_phase.h" #include "chrome/browser/vr/test/animation_utils.h" #include "chrome/browser/vr/test/constants.h" #include "chrome/browser/vr/ui_scene.h" @@ -50,7 +51,11 @@ } void CheckRotateClockwiseAndReverse(const gfx::Vector3dF& initial_look_at) { - ViewportAwareRoot root; + UiScene scene; + + auto element = base::MakeUnique<ViewportAwareRoot>(); + ViewportAwareRoot& root = *element; + scene.AddUiElement(kRoot, std::move(element)); gfx::Vector3dF look_at(initial_look_at); gfx::Transform expected; @@ -108,29 +113,28 @@ TEST(ViewportAwareRoot, ChildElementsRepositioned) { UiScene scene; - auto root = base::MakeUnique<ViewportAwareRoot>(); - root->set_id(0); - root->set_draw_phase(0); - scene.AddUiElement(std::move(root)); + auto viewport_aware_root = base::MakeUnique<ViewportAwareRoot>(); + ViewportAwareRoot& root = *viewport_aware_root; + root.set_draw_phase(kPhaseForeground); + scene.AddUiElement(kRoot, std::move(viewport_aware_root)); auto element = base::MakeUnique<UiElement>(); - element->set_id(1); + UiElement& child = *element; element->set_viewport_aware(true); - element->set_draw_phase(0); + element->set_draw_phase(kPhaseForeground); element->SetTranslate(0.f, 0.f, -1.f); - scene.GetUiElementById(0)->AddChild(element.get()); - scene.AddUiElement(std::move(element)); + root.AddChild(std::move(element)); gfx::Vector3dF look_at{0.f, 0.f, -1.f}; scene.OnBeginFrame(MicrosecondsToTicks(0), look_at); - EXPECT_TRUE(Point3FAreNearlyEqual(gfx::Point3F(0.f, 0.f, -1.f), - scene.GetUiElementById(1)->GetCenter())); + EXPECT_TRUE( + Point3FAreNearlyEqual(gfx::Point3F(0.f, 0.f, -1.f), child.GetCenter())); // This should trigger reposition of viewport aware elements. RotateAboutYAxis(90.f, &look_at); scene.OnBeginFrame(MicrosecondsToTicks(10), look_at); - EXPECT_TRUE(Point3FAreNearlyEqual(gfx::Point3F(-1.f, 0.f, 0.f), - scene.GetUiElementById(1)->GetCenter())); + EXPECT_TRUE( + Point3FAreNearlyEqual(gfx::Point3F(-1.f, 0.f, 0.f), child.GetCenter())); } } // namespace vr
diff --git a/chrome/browser/vr/test/ui_scene_manager_test.cc b/chrome/browser/vr/test/ui_scene_manager_test.cc index b46a666..5aacfd3 100644 --- a/chrome/browser/vr/test/ui_scene_manager_test.cc +++ b/chrome/browser/vr/test/ui_scene_manager_test.cc
@@ -33,29 +33,32 @@ kNotInWebVr, kAutopresented); } -bool UiSceneManagerTest::IsVisible(UiElementDebugId debug_id) const { - UiElement* element = scene_->GetUiElementByDebugId(debug_id); +bool UiSceneManagerTest::IsVisible(UiElementName name) const { + UiElement* element = scene_->GetUiElementByName(name); return element ? element->visible() : false; } void UiSceneManagerTest::VerifyElementsVisible( const std::string& debug_name, - const std::set<UiElementDebugId>& debug_ids) const { + const std::set<UiElementName>& names) const { SCOPED_TRACE(debug_name); - for (const auto& element : scene_->GetUiElements()) { - SCOPED_TRACE(element->debug_id()); - bool should_be_visible = - debug_ids.find(element->debug_id()) != debug_ids.end(); - EXPECT_EQ(should_be_visible, element->visible()); + for (auto name : names) { + SCOPED_TRACE(name); + auto* element = scene_->GetUiElementByName(name); + EXPECT_NE(nullptr, element); + EXPECT_TRUE(element->visible()); } } -bool UiSceneManagerTest::VerifyVisibility( - const std::set<UiElementDebugId>& debug_ids, - bool visible) const { - for (const auto& element : scene_->GetUiElements()) { - if (debug_ids.find(element->debug_id()) != debug_ids.end() && - element->visible() != visible) { +bool UiSceneManagerTest::VerifyVisibility(const std::set<UiElementName>& names, + bool visible) const { + for (auto name : names) { + SCOPED_TRACE(name); + auto* element = scene_->GetUiElementByName(name); + if (!element && visible) { + return false; + } + if (element && element->visible() != visible) { return false; } } @@ -83,7 +86,7 @@ SkColor UiSceneManagerTest::GetBackgroundColor() const { Rect* front = - static_cast<Rect*>(scene_->GetUiElementByDebugId(kBackgroundFront)); + static_cast<Rect*>(scene_->GetUiElementByName(kBackgroundFront)); EXPECT_NE(nullptr, front); if (!front) return SK_ColorBLACK; @@ -92,10 +95,9 @@ // While returning background color, ensure that all background panel elements // share the same color. - for (auto debug_id : {kBackgroundFront, kBackgroundLeft, kBackgroundBack, - kBackgroundRight, kBackgroundTop, kBackgroundBottom}) { - const Rect* panel = - static_cast<Rect*>(scene_->GetUiElementByDebugId(debug_id)); + for (auto name : {kBackgroundFront, kBackgroundLeft, kBackgroundBack, + kBackgroundRight, kBackgroundTop, kBackgroundBottom}) { + const Rect* panel = static_cast<Rect*>(scene_->GetUiElementByName(name)); EXPECT_NE(nullptr, panel); if (!panel) return SK_ColorBLACK;
diff --git a/chrome/browser/vr/test/ui_scene_manager_test.h b/chrome/browser/vr/test/ui_scene_manager_test.h index 2eb756c..b7f19bc 100644 --- a/chrome/browser/vr/test/ui_scene_manager_test.h +++ b/chrome/browser/vr/test/ui_scene_manager_test.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" -#include "chrome/browser/vr/elements/ui_element_debug_id.h" +#include "chrome/browser/vr/elements/ui_element_name.h" #include "chrome/browser/vr/test/mock_browser_interface.h" #include "chrome/browser/vr/test/mock_content_input_delegate.h" #include "testing/gtest/include/gtest/gtest.h" @@ -47,15 +47,15 @@ void MakeManager(InCct in_cct, InWebVr in_web_vr); void MakeAutoPresentedManager(); - bool IsVisible(UiElementDebugId debug_id) const; + bool IsVisible(UiElementName name) const; // Verify that only the elements in the set are visible. void VerifyElementsVisible(const std::string& debug_name, - const std::set<UiElementDebugId>& debug_ids) const; + const std::set<UiElementName>& names) const; // Return false if not all elements in the set match the specified visibility // state. Other elements are ignored. - bool VerifyVisibility(const std::set<UiElementDebugId>& debug_ids, + bool VerifyVisibility(const std::set<UiElementName>& names, bool visible) const; // Advances current_time_ by delta. This is done in frame increments and
diff --git a/chrome/browser/vr/ui_input_manager.cc b/chrome/browser/vr/ui_input_manager.cc index ac1f0438..8d3b0f9 100644 --- a/chrome/browser/vr/ui_input_manager.cc +++ b/chrome/browser/vr/ui_input_manager.cc
@@ -44,6 +44,65 @@ return false; } +bool GetTargetLocalPoint(const gfx::Vector3dF& eye_to_target, + const UiElement& element, + float max_distance_to_plane, + gfx::PointF* out_target_local_point, + gfx::Point3F* out_target_point, + float* out_distance_to_plane) { + if (!element.GetRayDistance(kOrigin, eye_to_target, out_distance_to_plane)) { + return false; + } + + if (*out_distance_to_plane < 0 || + *out_distance_to_plane >= max_distance_to_plane) { + return false; + } + + *out_target_point = + GetRayPoint(kOrigin, eye_to_target, *out_distance_to_plane); + gfx::PointF unit_xy_point = + element.GetUnitRectangleCoordinates(*out_target_point); + + out_target_local_point->set_x(0.5f + unit_xy_point.x()); + out_target_local_point->set_y(0.5f - unit_xy_point.y()); + return true; +} + +void HitTestElements(UiElement* element, + gfx::Vector3dF* out_eye_to_target, + float* out_closest_element_distance, + gfx::Point3F* out_target_point, + UiElement** out_target_element, + gfx::PointF* out_target_local_point) { + for (auto& child : element->children()) { + HitTestElements(child.get(), out_eye_to_target, + out_closest_element_distance, out_target_point, + out_target_element, out_target_local_point); + } + + if (!element->IsHitTestable()) { + return; + } + + gfx::PointF local_point; + gfx::Point3F plane_intersection_point; + float distance_to_plane; + if (!GetTargetLocalPoint(*out_eye_to_target, *element, + *out_closest_element_distance, &local_point, + &plane_intersection_point, &distance_to_plane)) { + return; + } + if (!element->HitTest(local_point)) { + return; + } + + *out_closest_element_distance = distance_to_plane; + *out_target_point = plane_intersection_point; + *out_target_element = element; + *out_target_local_point = local_point; +} + } // namespace UiInputManager::UiInputManager(UiScene* scene) : scene_(scene) {} @@ -236,7 +295,7 @@ // moves for how noisy the controller is. It's almost impossible to click a // link without unintentionally starting a drag event. For this reason we // disable mouse moves, only delivering a down and up event. - if (hover_target_->debug_id() == kContentQuad && in_click_) { + if (hover_target_->name() == kContentQuad && in_click_) { return; } @@ -311,52 +370,9 @@ // and the controller target position. float closest_element_distance = (*out_target_point - kOrigin).Length(); - for (auto& element : scene_->GetUiElements()) { - if (!element->IsHitTestable()) { - continue; - } - gfx::PointF local_point; - gfx::Point3F plane_intersection_point; - float distance_to_plane; - if (!GetTargetLocalPoint(*out_eye_to_target, *element.get(), - closest_element_distance, &local_point, - &plane_intersection_point, &distance_to_plane)) { - continue; - } - if (!element->HitTest(local_point)) { - continue; - } - - closest_element_distance = distance_to_plane; - *out_target_point = plane_intersection_point; - *out_target_element = element.get(); - *out_target_local_point = local_point; - } -} - -bool UiInputManager::GetTargetLocalPoint(const gfx::Vector3dF& eye_to_target, - const UiElement& element, - float max_distance_to_plane, - gfx::PointF* out_target_local_point, - gfx::Point3F* out_target_point, - float* out_distance_to_plane) const { - if (!element.GetRayDistance(kOrigin, eye_to_target, out_distance_to_plane)) { - return false; - } - - if (*out_distance_to_plane < 0 || - *out_distance_to_plane >= max_distance_to_plane) { - return false; - } - - *out_target_point = - GetRayPoint(kOrigin, eye_to_target, *out_distance_to_plane); - gfx::PointF unit_xy_point = - element.GetUnitRectangleCoordinates(*out_target_point); - - out_target_local_point->set_x(0.5f + unit_xy_point.x()); - out_target_local_point->set_y(0.5f - unit_xy_point.y()); - return true; + HitTestElements(&scene_->root_element(), out_eye_to_target, + &closest_element_distance, out_target_point, + out_target_element, out_target_local_point); } } // namespace vr
diff --git a/chrome/browser/vr/ui_input_manager.h b/chrome/browser/vr/ui_input_manager.h index ce8bdb4..e00578b 100644 --- a/chrome/browser/vr/ui_input_manager.h +++ b/chrome/browser/vr/ui_input_manager.h
@@ -69,12 +69,6 @@ gfx::Point3F* out_target_point, UiElement** out_target_element, gfx::PointF* out_target_local_point) const; - bool GetTargetLocalPoint(const gfx::Vector3dF& eye_to_target, - const UiElement& element, - float max_distance_to_plane, - gfx::PointF* out_target_local_point, - gfx::Point3F* out_target_point, - float* out_distance_to_plane) const; UiScene* scene_; // TODO(mthiesse): We need to handle elements being removed, and update this
diff --git a/chrome/browser/vr/ui_input_manager_unittest.cc b/chrome/browser/vr/ui_input_manager_unittest.cc index d9a22d8..c2a0f6e9 100644 --- a/chrome/browser/vr/ui_input_manager_unittest.cc +++ b/chrome/browser/vr/ui_input_manager_unittest.cc
@@ -38,7 +38,7 @@ // mock out the underlying sensor data. For now, we will hallucinate // parameters to HandleInput. UiElement* content_quad = - scene_->GetUiElementByDebugId(UiElementDebugId::kContentQuad); + scene_->GetUiElementByName(UiElementName::kContentQuad); gfx::Point3F content_quad_center; content_quad->world_space_transform().TransformPoint(&content_quad_center); gfx::Point3F origin; @@ -51,8 +51,7 @@ // We should have hit the content quad if our math was correct. ASSERT_NE(nullptr, out_reticle_render_target); - EXPECT_EQ(UiElementDebugId::kContentQuad, - out_reticle_render_target->debug_id()); + EXPECT_EQ(UiElementName::kContentQuad, out_reticle_render_target->name()); // Unless we suppress content move events during clicks, this will cause us to // call OnContentMove on the delegate. We should do this suppression, so we
diff --git a/chrome/browser/vr/ui_scene.cc b/chrome/browser/vr/ui_scene.cc index 5df9ee2..a6af243 100644 --- a/chrome/browser/vr/ui_scene.cc +++ b/chrome/browser/vr/ui_scene.cc
@@ -10,31 +10,48 @@ #include "base/memory/ptr_util.h" #include "base/time/time.h" #include "base/values.h" +#include "chrome/browser/vr/elements/draw_phase.h" #include "chrome/browser/vr/elements/ui_element.h" #include "ui/gfx/transform.h" namespace vr { -void UiScene::AddUiElement(std::unique_ptr<UiElement> element) { +template <typename F> +void ForAllElements(UiElement* e, F f) { + f(e); + for (auto& child : e->children()) { + ForAllElements(child.get(), f); + } +} + +template <typename P> +UiElement* FindElement(UiElement* e, P predicate) { + if (predicate(e)) { + return e; + } + for (const auto& child : e->children()) { + if (UiElement* match = FindElement(child.get(), predicate)) { + return match; + } + } + return nullptr; +} + +void UiScene::AddUiElement(UiElementName parent, + std::unique_ptr<UiElement> element) { CHECK_GE(element->id(), 0); CHECK_EQ(GetUiElementById(element->id()), nullptr); CHECK_GE(element->draw_phase(), 0); - if (!element->parent()) { - CHECK_EQ(element->x_anchoring(), XAnchoring::XNONE); - CHECK_EQ(element->y_anchoring(), YAnchoring::YNONE); - } if (gl_initialized_) element->Initialize(); - ui_elements_.push_back(std::move(element)); + GetUiElementByName(parent)->AddChild(std::move(element)); } void UiScene::RemoveUiElement(int element_id) { - for (auto it = ui_elements_.begin(); it != ui_elements_.end(); ++it) { - if ((*it)->id() == element_id) { - ui_elements_.erase(it); - return; - } - } + UiElement* to_remove = GetUiElementById(element_id); + CHECK_NE(nullptr, to_remove); + CHECK_NE(nullptr, to_remove->parent()); + to_remove->parent()->RemoveChild(to_remove); } void UiScene::AddAnimation(int element_id, @@ -50,83 +67,84 @@ void UiScene::OnBeginFrame(const base::TimeTicks& current_time, const gfx::Vector3dF& look_at) { - for (const auto& element : ui_elements_) { + ForAllElements(root_element_.get(), [current_time](UiElement* element) { // Process all animations before calculating object transforms. element->Animate(current_time); element->set_dirty(true); - } - for (auto& element : ui_elements_) { + }); + + ForAllElements(root_element_.get(), [look_at](UiElement* element) { element->LayOutChildren(); element->AdjustRotationForHeadPose(look_at); - } - for (auto& element : ui_elements_) { - ApplyRecursiveTransforms(element.get()); - } + }); + + ForAllElements(root_element_.get(), [this](UiElement* element) { + this->ApplyRecursiveTransforms(element); + }); } void UiScene::PrepareToDraw() { - for (const auto& element : ui_elements_) { - element->PrepareToDraw(); - } + ForAllElements(root_element_.get(), + [](UiElement* element) { element->PrepareToDraw(); }); +} + +UiElement& UiScene::root_element() { + return *root_element_; } UiElement* UiScene::GetUiElementById(int element_id) const { - for (const auto& element : ui_elements_) { - if (element->id() == element_id) { - return element.get(); - } - } - return nullptr; + return FindElement(root_element_.get(), [element_id](UiElement* element) { + return element->id() == element_id; + }); } -UiElement* UiScene::GetUiElementByDebugId(UiElementDebugId debug_id) const { - DCHECK(debug_id != UiElementDebugId::kNone); - for (const auto& element : ui_elements_) { - if (element->debug_id() == debug_id) { - return element.get(); - } - } - return nullptr; +UiElement* UiScene::GetUiElementByName(UiElementName name) const { + DCHECK(name != UiElementName::kNone); + return FindElement(root_element_.get(), [name](UiElement* element) { + return element->name() == name; + }); } std::vector<const UiElement*> UiScene::GetWorldElements() const { std::vector<const UiElement*> elements; - for (const auto& element : ui_elements_) { + ForAllElements(root_element_.get(), [&elements](UiElement* element) { if (element->IsVisible() && !element->viewport_aware() && !element->is_overlay()) { - elements.push_back(element.get()); + elements.push_back(element); } - } + }); return elements; } std::vector<const UiElement*> UiScene::GetOverlayElements() const { std::vector<const UiElement*> elements; - for (const auto& element : ui_elements_) { + ForAllElements(root_element_.get(), [&elements](UiElement* element) { if (element->IsVisible() && element->is_overlay()) { - elements.push_back(element.get()); + elements.push_back(element); } - } + }); return elements; } std::vector<const UiElement*> UiScene::GetViewportAwareElements() const { std::vector<const UiElement*> elements; - for (const auto& element : ui_elements_) { + ForAllElements(root_element_.get(), [&elements](UiElement* element) { if (element->IsVisible() && element->viewport_aware() && element->parent()) { - elements.push_back(element.get()); + elements.push_back(element); } - } + }); return elements; } -const std::vector<std::unique_ptr<UiElement>>& UiScene::GetUiElements() const { - return ui_elements_; +UiScene::UiScene() { + root_element_ = base::MakeUnique<UiElement>(); + root_element_->set_name(kRoot); + root_element_->set_draw_phase(kPhaseNone); + root_element_->SetVisible(false); + root_element_->set_hit_testable(false); } -UiScene::UiScene() = default; - UiScene::~UiScene() = default; void UiScene::ApplyRecursiveTransforms(UiElement* element) { @@ -159,12 +177,12 @@ element->set_dirty(false); } -// TODO(mthiesse): Move this to UiSceneManager. +// TODO(vollick): we should bind to gl-initialized state. Elements will +// initialize when the binding fires, automatically. void UiScene::OnGlInitialized() { gl_initialized_ = true; - for (auto& element : ui_elements_) { - element->Initialize(); - } + ForAllElements(root_element_.get(), + [](UiElement* element) { element->Initialize(); }); } } // namespace vr
diff --git a/chrome/browser/vr/ui_scene.h b/chrome/browser/vr/ui_scene.h index f0a8947..70967f4b 100644 --- a/chrome/browser/vr/ui_scene.h +++ b/chrome/browser/vr/ui_scene.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "chrome/browser/vr/color_scheme.h" -#include "chrome/browser/vr/elements/ui_element_debug_id.h" +#include "chrome/browser/vr/elements/ui_element_name.h" #include "third_party/skia/include/core/SkColor.h" namespace base { @@ -44,7 +44,7 @@ UiScene(); virtual ~UiScene(); - void AddUiElement(std::unique_ptr<UiElement> element); + void AddUiElement(UiElementName parent, std::unique_ptr<UiElement> element); void RemoveUiElement(int element_id); @@ -64,10 +64,10 @@ // frame lifecycle. After this function, no element should be dirtied. void PrepareToDraw(); - const std::vector<std::unique_ptr<UiElement>>& GetUiElements() const; + UiElement& root_element(); UiElement* GetUiElementById(int element_id) const; - UiElement* GetUiElementByDebugId(UiElementDebugId debug_id) const; + UiElement* GetUiElementByName(UiElementName name) const; std::vector<const UiElement*> GetWorldElements() const; std::vector<const UiElement*> GetOverlayElements() const; @@ -99,7 +99,7 @@ void Animate(const base::TimeTicks& current_time); void ApplyRecursiveTransforms(UiElement* element); - std::vector<std::unique_ptr<UiElement>> ui_elements_; + std::unique_ptr<UiElement> root_element_; ColorScheme::Mode mode_ = ColorScheme::kModeNormal; float background_distance_ = 10.0f;
diff --git a/chrome/browser/vr/ui_scene_manager.cc b/chrome/browser/vr/ui_scene_manager.cc index ad33866..4abfefd 100644 --- a/chrome/browser/vr/ui_scene_manager.cc +++ b/chrome/browser/vr/ui_scene_manager.cc
@@ -10,6 +10,7 @@ #include "chrome/browser/vr/elements/button.h" #include "chrome/browser/vr/elements/close_button_texture.h" #include "chrome/browser/vr/elements/content_element.h" +#include "chrome/browser/vr/elements/draw_phase.h" #include "chrome/browser/vr/elements/exclusive_screen_toast.h" #include "chrome/browser/vr/elements/exit_prompt.h" #include "chrome/browser/vr/elements/exit_prompt_backplane.h" @@ -21,7 +22,7 @@ #include "chrome/browser/vr/elements/system_indicator.h" #include "chrome/browser/vr/elements/text.h" #include "chrome/browser/vr/elements/ui_element.h" -#include "chrome/browser/vr/elements/ui_element_debug_id.h" +#include "chrome/browser/vr/elements/ui_element_name.h" #include "chrome/browser/vr/elements/ui_element_transform_operations.h" #include "chrome/browser/vr/elements/ui_texture.h" #include "chrome/browser/vr/elements/url_bar.h" @@ -156,14 +157,53 @@ // adjusted. static constexpr float kContentBoundsPropagationThreshold = 0.2f; -enum DrawPhase : int { - kPhaseBackground = 0, - kPhaseFloorCeiling, - kPhaseForeground, -}; - } // namespace +// The scene manager creates and maintains UiElements that form the following +// hierarchy. +// +// kRoot +// k2dBrowsingRoot +// k2dBrowsingBackground +// kBackgroundLeft +// kBackgroundRight +// kBackgroundTop +// kBackgroundBottom +// kBackgroundFront +// kBackgroundBack +// kFloor +// kCeiling +// k2dBrowsingForeground +// kContentQuad +// kBackplane +// kIndicatorLayout +// kAudioCaptureIndicator +// kVideoCaptureIndicator +// kScreenCaptureIndicator +// kLocationAccessIndicator +// kBluetoothConnectedIndicator +// kLoadingIndicator +// kExitPrompt +// kExitPromptBackplane +// kCloseButton +// kUrlBar +// kLoadingIndicator +// kExitButton +// kFullscreenToast +// kScreenDimmer +// k2dBrowsingViewportAwareRoot +// kExitWarning +// kWebVrRoot +// kWebVrContent +// kWebVrViewportAwareRoot +// kWebVrPresentationToast +// kWebVrPermanentHttpSecurityWarning, +// kWebVrTransientHttpSecurityWarning, +// kTransientUrlBar +// +// TODO(vollick): The above hierarchy is complex, brittle, and would be easier +// to manage if it were specified in a declarative format. + UiSceneManager::UiSceneManager(UiBrowserInterface* browser, UiScene* scene, ContentInputDelegate* content_input_delegate, @@ -177,6 +217,8 @@ started_for_autopresentation_(web_vr_autopresentation_expected), showing_web_vr_splash_screen_(web_vr_autopresentation_expected), weak_ptr_factory_(this) { + Create2dBrowsingSubtreeRoots(); + CreateWebVrRoot(); CreateBackground(); CreateViewportAwareRoot(); CreateContentQuad(content_input_delegate); @@ -196,17 +238,48 @@ UiSceneManager::~UiSceneManager() {} +void UiSceneManager::Create2dBrowsingSubtreeRoots() { + auto element = base::MakeUnique<UiElement>(); + element->set_name(k2dBrowsingRoot); + element->set_draw_phase(kPhaseNone); + element->SetVisible(false); + element->set_hit_testable(false); + scene_->AddUiElement(kRoot, std::move(element)); + + element = base::MakeUnique<UiElement>(); + element->set_name(k2dBrowsingBackground); + element->set_draw_phase(kPhaseNone); + element->SetVisible(false); + element->set_hit_testable(false); + scene_->AddUiElement(k2dBrowsingRoot, std::move(element)); + + element = base::MakeUnique<UiElement>(); + element->set_name(k2dBrowsingForeground); + element->set_draw_phase(kPhaseNone); + element->SetVisible(false); + element->set_hit_testable(false); + scene_->AddUiElement(k2dBrowsingRoot, std::move(element)); +} + +void UiSceneManager::CreateWebVrRoot() { + auto element = base::MakeUnique<UiElement>(); + element->set_name(kWebVrRoot); + element->set_draw_phase(kPhaseNone); + element->SetVisible(false); + element->set_hit_testable(false); + scene_->AddUiElement(kRoot, std::move(element)); +} + void UiSceneManager::CreateScreenDimmer() { std::unique_ptr<UiElement> element; element = base::MakeUnique<ScreenDimmer>(); - element->set_debug_id(kScreenDimmer); - element->set_id(AllocateId()); + element->set_name(kScreenDimmer); element->set_draw_phase(kPhaseForeground); element->SetVisible(false); element->set_hit_testable(false); element->set_is_overlay(true); screen_dimmer_ = element.get(); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(k2dBrowsingRoot, std::move(element)); } void UiSceneManager::CreateSecurityWarnings() { @@ -215,8 +288,7 @@ // TODO(mthiesse): Programatically compute the proper texture size for these // textured UI elements. element = base::MakeUnique<PermanentSecurityWarning>(512); - element->set_debug_id(kWebVrPermanentHttpSecurityWarning); - element->set_id(AllocateId()); + element->set_name(kWebVrPermanentHttpSecurityWarning); element->set_draw_phase(kPhaseForeground); element->SetSize(kPermanentWarningWidthDMM, kPermanentWarningHeightDMM); element->SetTranslate(0, kWarningDistance * sin(kWarningAngleRadians), @@ -226,16 +298,14 @@ element->SetVisible(false); element->set_hit_testable(false); element->set_viewport_aware(true); - viewport_aware_root_->AddChild(element.get()); permanent_security_warning_ = element.get(); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(element)); auto transient_warning = base::MakeUnique<TransientSecurityWarning>( 1024, base::TimeDelta::FromSeconds(kWarningTimeoutSeconds)); transient_security_warning_ = transient_warning.get(); element = std::move(transient_warning); - element->set_debug_id(kWebVrTransientHttpSecurityWarning); - element->set_id(AllocateId()); + element->set_name(kWebVrTransientHttpSecurityWarning); element->set_draw_phase(kPhaseForeground); element->SetSize(kTransientWarningWidthDMM, kTransientWarningHeightDMM); element->SetTranslate(0, 0, -kWarningDistance); @@ -243,12 +313,10 @@ element->SetVisible(false); element->set_hit_testable(false); element->set_viewport_aware(true); - viewport_aware_root_->AddChild(element.get()); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(element)); element = base::MakeUnique<ExitWarning>(1024); - element->set_debug_id(kExitWarning); - element->set_id(AllocateId()); + element->set_name(kExitWarning); element->set_draw_phase(kPhaseForeground); element->SetSize(kExitWarningWidth, kExitWarningHeight); element->SetTranslate(0, 0, -kExitWarningDistance); @@ -256,9 +324,8 @@ element->SetVisible(false); element->set_hit_testable(false); element->set_viewport_aware(true); - viewport_aware_root_->AddChild(element.get()); exit_warning_ = element.get(); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(k2dBrowsingViewportAwareRoot, std::move(element)); } void UiSceneManager::CreateSystemIndicators() { @@ -266,7 +333,7 @@ struct Indicator { UiElement** element; - UiElementDebugId debug_id; + UiElementName name; const gfx::VectorIcon& icon; int resource_string; }; @@ -285,37 +352,32 @@ std::unique_ptr<LinearLayout> indicator_layout = base::MakeUnique<LinearLayout>(LinearLayout::kHorizontal); + indicator_layout->set_name(kIndicatorLayout); indicator_layout->set_draw_phase(kPhaseForeground); - indicator_layout->set_id(AllocateId()); indicator_layout->set_y_anchoring(YAnchoring::YTOP); indicator_layout->SetTranslate(0, kIndicatorVerticalOffset, kIndicatorDistanceOffset); indicator_layout->set_margin(kIndicatorGap); - main_content_->AddChild(indicator_layout.get()); + scene_->AddUiElement(kContentQuad, std::move(indicator_layout)); for (const auto& indicator : indicators) { element = base::MakeUnique<SystemIndicator>( 512, kIndicatorHeight, indicator.icon, indicator.resource_string); - element->set_debug_id(indicator.debug_id); - element->set_id(AllocateId()); + element->set_name(indicator.name); element->set_draw_phase(kPhaseForeground); element->SetVisible(false); - indicator_layout->AddChild(element.get()); *(indicator.element) = element.get(); system_indicators_.push_back(element.get()); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(kIndicatorLayout, std::move(element)); } - scene_->AddUiElement(std::move(indicator_layout)); - ConfigureIndicators(); } void UiSceneManager::CreateContentQuad(ContentInputDelegate* delegate) { std::unique_ptr<ContentElement> main_content = base::MakeUnique<ContentElement>(delegate); - main_content->set_debug_id(kContentQuad); - main_content->set_id(AllocateId()); + main_content->set_name(kContentQuad); main_content->set_draw_phase(kPhaseForeground); main_content->SetSize(kContentWidth, kContentHeight); main_content->SetTranslate(0, kContentVerticalOffset, -kContentDistance); @@ -325,19 +387,17 @@ {TRANSFORM, BOUNDS}); main_content_ = main_content.get(); content_elements_.push_back(main_content.get()); - scene_->AddUiElement(std::move(main_content)); + scene_->AddUiElement(k2dBrowsingForeground, std::move(main_content)); // Place an invisible but hittable plane behind the content quad, to keep the // reticle roughly planar with the content if near content. std::unique_ptr<UiElement> hit_plane = base::MakeUnique<UiElement>(); - hit_plane->set_debug_id(kBackplane); - hit_plane->set_id(AllocateId()); + hit_plane->set_name(kBackplane); hit_plane->set_draw_phase(kPhaseForeground); hit_plane->SetSize(kBackplaneSize, kBackplaneSize); hit_plane->SetTranslate(0, 0, -kTextureOffset); - main_content_->AddChild(hit_plane.get()); content_elements_.push_back(hit_plane.get()); - scene_->AddUiElement(std::move(hit_plane)); + scene_->AddUiElement(kContentQuad, std::move(hit_plane)); // Limit reticle distance to a sphere based on content distance. scene_->set_background_distance( @@ -353,15 +413,14 @@ return color_scheme.splash_screen_text_color; }), IDS_VR_POWERED_BY_CHROME_MESSAGE); - text->set_debug_id(kSplashScreenText); - text->set_id(AllocateId()); + text->set_name(kSplashScreenText); text->set_draw_phase(kPhaseForeground); text->set_hit_testable(false); text->SetSize(kSplashScreenTextWidthM, kSplashScreenTextHeightM); text->SetTranslate(0, kSplashScreenTextVerticalOffset, -kSplashScreenTextDistance); splash_screen_text_ = text.get(); - scene_->AddUiElement(std::move(text)); + scene_->AddUiElement(kWebVrRoot, std::move(text)); } void UiSceneManager::CreateUnderDevelopmentNotice() { @@ -371,8 +430,7 @@ return color_scheme.world_background_text; }), IDS_VR_UNDER_DEVELOPMENT_NOTICE); - text->set_debug_id(kUnderDevelopmentNotice); - text->set_id(AllocateId()); + text->set_name(kUnderDevelopmentNotice); text->set_draw_phase(kPhaseForeground); text->set_hit_testable(false); text->SetSize(kUnderDevelopmentNoticeWidthM, kUnderDevelopmentNoticeHeightM); @@ -380,16 +438,15 @@ text->SetRotate(1, 0, 0, kUnderDevelopmentNoticeRotationRad); text->SetEnabled(true); text->set_y_anchoring(YAnchoring::YBOTTOM); - url_bar_->AddChild(text.get()); control_elements_.push_back(text.get()); - scene_->AddUiElement(std::move(text)); + scene_->AddUiElement(kUrlBar, std::move(text)); } void UiSceneManager::CreateBackground() { // Background solid-color panels. struct Panel { - UiElementDebugId debug_id; + UiElementName name; int x_offset; int y_offset; int z_offset; @@ -407,8 +464,7 @@ }; for (auto& panel : panels) { auto panel_element = base::MakeUnique<Rect>(); - panel_element->set_debug_id(panel.debug_id); - panel_element->set_id(AllocateId()); + panel_element->set_name(panel.name); panel_element->set_draw_phase(kPhaseBackground); panel_element->SetSize(kSceneSize, kSceneSize); panel_element->SetTranslate(panel.x_offset * kSceneSize / 2, @@ -418,41 +474,43 @@ M_PI_2 * panel.angle); panel_element->set_hit_testable(false); background_panels_.push_back(panel_element.get()); - scene_->AddUiElement(std::move(panel_element)); + scene_->AddUiElement(k2dBrowsingBackground, std::move(panel_element)); } // Floor. auto floor = base::MakeUnique<Grid>(); - floor->set_debug_id(kFloor); - floor->set_id(AllocateId()); + floor->set_name(kFloor); floor->set_draw_phase(kPhaseFloorCeiling); floor->SetSize(kSceneSize, kSceneSize); floor->SetTranslate(0.0, -kSceneHeight / 2, 0.0); floor->SetRotate(1, 0, 0, -M_PI_2); floor->set_gridline_count(kFloorGridlineCount); floor_ = floor.get(); - scene_->AddUiElement(std::move(floor)); + scene_->AddUiElement(k2dBrowsingBackground, std::move(floor)); // Ceiling. auto ceiling = base::MakeUnique<Rect>(); - ceiling->set_debug_id(kCeiling); - ceiling->set_id(AllocateId()); + ceiling->set_name(kCeiling); ceiling->set_draw_phase(kPhaseFloorCeiling); ceiling->SetSize(kSceneSize, kSceneSize); ceiling->SetTranslate(0.0, kSceneHeight / 2, 0.0); ceiling->SetRotate(1, 0, 0, M_PI_2); ceiling_ = ceiling.get(); - scene_->AddUiElement(std::move(ceiling)); + scene_->AddUiElement(k2dBrowsingBackground, std::move(ceiling)); scene_->set_first_foreground_draw_phase(kPhaseForeground); } void UiSceneManager::CreateViewportAwareRoot() { auto element = base::MakeUnique<ViewportAwareRoot>(); - element->set_id(AllocateId()); + element->set_name(kWebVrViewportAwareRoot); element->set_draw_phase(kPhaseForeground); - viewport_aware_root_ = element.get(); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(kWebVrRoot, std::move(element)); + + element = base::MakeUnique<ViewportAwareRoot>(); + element->set_name(k2dBrowsingViewportAwareRoot); + element->set_draw_phase(kPhaseForeground); + scene_->AddUiElement(k2dBrowsingRoot, std::move(element)); } void UiSceneManager::CreateUrlBar() { @@ -463,39 +521,34 @@ base::Bind(&UiSceneManager::OnSecurityIconClicked, base::Unretained(this)), base::Bind(&UiSceneManager::OnUnsupportedMode, base::Unretained(this))); - url_bar->set_debug_id(kUrlBar); - url_bar->set_id(AllocateId()); + url_bar->set_name(kUrlBar); url_bar->set_draw_phase(kPhaseForeground); url_bar->SetTranslate(0, kUrlBarVerticalOffset, -kUrlBarDistance); url_bar->SetRotate(1, 0, 0, kUrlBarRotationRad); url_bar->SetSize(kUrlBarWidth, kUrlBarHeight); url_bar_ = url_bar.get(); control_elements_.push_back(url_bar.get()); - scene_->AddUiElement(std::move(url_bar)); + scene_->AddUiElement(k2dBrowsingForeground, std::move(url_bar)); auto indicator = base::MakeUnique<LoadingIndicator>(256); - indicator->set_debug_id(kLoadingIndicator); - indicator->set_id(AllocateId()); + indicator->set_name(kLoadingIndicator); indicator->set_draw_phase(kPhaseForeground); indicator->SetTranslate(0, kLoadingIndicatorVerticalOffset, kLoadingIndicatorDepthOffset); indicator->SetSize(kLoadingIndicatorWidth, kLoadingIndicatorHeight); - url_bar_->AddChild(indicator.get()); indicator->set_y_anchoring(YAnchoring::YTOP); loading_indicator_ = indicator.get(); control_elements_.push_back(indicator.get()); - scene_->AddUiElement(std::move(indicator)); + scene_->AddUiElement(kUrlBar, std::move(indicator)); } void UiSceneManager::CreateWebVrUrlToast() { auto url_bar = base::MakeUnique<WebVrUrlToast>( 512, base::TimeDelta::FromSeconds(kWebVrUrlToastTimeoutSeconds), base::Bind(&UiSceneManager::OnUnsupportedMode, base::Unretained(this))); - url_bar->set_debug_id(kWebVrUrlToast); - url_bar->set_id(AllocateId()); + url_bar->set_name(kWebVrUrlToast); url_bar->set_draw_phase(kPhaseForeground); url_bar->set_viewport_aware(true); - viewport_aware_root_->AddChild(url_bar.get()); url_bar->SetVisible(false); url_bar->set_hit_testable(false); url_bar->SetTranslate(0, kWebVrUrlToastVerticalOffset, @@ -503,21 +556,20 @@ url_bar->SetRotate(1, 0, 0, kUrlBarRotationRad); url_bar->SetSize(kWebVrUrlToastWidth, kWebVrUrlToastHeight); webvr_url_toast_ = url_bar.get(); - scene_->AddUiElement(std::move(url_bar)); + scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(url_bar)); } void UiSceneManager::CreateCloseButton() { std::unique_ptr<Button> element = base::MakeUnique<Button>( base::Bind(&UiSceneManager::OnCloseButtonClicked, base::Unretained(this)), base::MakeUnique<CloseButtonTexture>()); - element->set_debug_id(kCloseButton); - element->set_id(AllocateId()); + element->set_name(kCloseButton); element->set_draw_phase(kPhaseForeground); element->SetTranslate(0, kContentVerticalOffset - (kContentHeight / 2) - 0.3, -kCloseButtonDistance); element->SetSize(kCloseButtonWidth, kCloseButtonHeight); close_button_ = element.get(); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(k2dBrowsingForeground, std::move(element)); } void UiSceneManager::CreateExitPrompt() { @@ -531,14 +583,12 @@ true)); exit_prompt_ = exit_prompt.get(); element = std::move(exit_prompt); - element->set_debug_id(kExitPrompt); - element->set_id(AllocateId()); + element->set_name(kExitPrompt); element->set_draw_phase(kPhaseForeground); element->SetSize(kExitPromptWidth, kExitPromptHeight); element->SetTranslate(0.0, kExitPromptVerticalOffset, kTextureOffset); element->SetVisible(false); - main_content_->AddChild(element.get()); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(kContentQuad, std::move(element)); // Place an invisible but hittable plane behind the exit prompt, to keep the // reticle roughly planar with the content if near content. @@ -546,22 +596,19 @@ &UiSceneManager::OnExitPromptBackplaneClicked, base::Unretained(this))); exit_prompt_backplane_ = backplane.get(); element = std::move(backplane); - element->set_debug_id(kExitPromptBackplane); - element->set_id(AllocateId()); + element->set_name(kExitPromptBackplane); element->set_draw_phase(kPhaseForeground); element->SetSize(kExitPromptBackplaneSize, kExitPromptBackplaneSize); element->SetTranslate(0.0, 0.0, -kTextureOffset); - exit_prompt_->AddChild(element.get()); exit_prompt_backplane_ = element.get(); content_elements_.push_back(element.get()); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(kExitPrompt, std::move(element)); } void UiSceneManager::CreateToasts() { auto element = base::MakeUnique<ExclusiveScreenToast>( 512, base::TimeDelta::FromSeconds(kToastTimeoutSeconds)); - element->set_debug_id(kExclusiveScreenToast); - element->set_id(AllocateId()); + element->set_name(kExclusiveScreenToast); element->set_draw_phase(kPhaseForeground); element->SetSize(kToastWidthDMM, kToastHeightDMM); element->SetTranslate( @@ -573,12 +620,11 @@ element->SetVisible(false); element->set_hit_testable(false); exclusive_screen_toast_ = element.get(); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(k2dBrowsingForeground, std::move(element)); element = base::MakeUnique<ExclusiveScreenToast>( 512, base::TimeDelta::FromSeconds(kToastTimeoutSeconds)); - element->set_debug_id(kExclusiveScreenToastViewportAware); - element->set_id(AllocateId()); + element->set_name(kExclusiveScreenToastViewportAware); element->set_draw_phase(kPhaseForeground); element->SetSize(kToastWidthDMM, kToastHeightDMM); element->SetTranslate(0, kWebVrToastDistance * sin(kWebVrAngleRadians), @@ -588,9 +634,8 @@ element->SetVisible(false); element->set_hit_testable(false); element->set_viewport_aware(true); - viewport_aware_root_->AddChild(element.get()); exclusive_screen_toast_viewport_aware_ = element.get(); - scene_->AddUiElement(std::move(element)); + scene_->AddUiElement(kWebVrViewportAwareRoot, std::move(element)); } base::WeakPtr<UiSceneManager> UiSceneManager::GetWeakPtr() { @@ -739,8 +784,7 @@ main_content_->LocalTransform().matrix().get(2, 3) * -kBackgroundDistanceMultiplier); - for (auto& element : scene_->GetUiElements()) - element->SetMode(mode()); + scene_->root_element().SetMode(mode()); webvr_url_toast_->SetEnabled(started_for_autopresentation_ && !showing_web_vr_splash_screen_); @@ -942,10 +986,6 @@ browser_->OnUnsupportedMode(mode); } -int UiSceneManager::AllocateId() { - return next_available_id_++; -} - ColorScheme::Mode UiSceneManager::mode() const { if (incognito_) return ColorScheme::kModeIncognito;
diff --git a/chrome/browser/vr/ui_scene_manager.h b/chrome/browser/vr/ui_scene_manager.h index 28781f8..766ff5a 100644 --- a/chrome/browser/vr/ui_scene_manager.h +++ b/chrome/browser/vr/ui_scene_manager.h
@@ -72,6 +72,8 @@ void OnExitPromptChoiceForTesting(bool chose_exit); private: + void Create2dBrowsingSubtreeRoots(); + void CreateWebVrRoot(); void CreateScreenDimmer(); void CreateSecurityWarnings(); void CreateSystemIndicators(); @@ -97,7 +99,6 @@ void OnExitPromptBackplaneClicked(); void OnCloseButtonClicked(); void OnUnsupportedMode(UiUnsupportedMode mode); - int AllocateId(); ColorScheme::Mode mode() const; const ColorScheme& color_scheme() const; @@ -119,7 +120,6 @@ UiElement* screen_capture_indicator_ = nullptr; UiElement* location_access_indicator_ = nullptr; UiElement* screen_dimmer_ = nullptr; - UiElement* viewport_aware_root_ = nullptr; Rect* ceiling_ = nullptr; Grid* floor_ = nullptr; UiElement* close_button_ = nullptr; @@ -151,8 +151,6 @@ bool bluetooth_connected_ = false; UiUnsupportedMode exit_vr_prompt_reason_ = UiUnsupportedMode::kCount; - int next_available_id_ = 1; - std::vector<Rect*> background_panels_; std::vector<UiElement*> content_elements_; std::vector<UiElement*> control_elements_;
diff --git a/chrome/browser/vr/ui_scene_manager_unittest.cc b/chrome/browser/vr/ui_scene_manager_unittest.cc index 05c9bd9f..9f9677d 100644 --- a/chrome/browser/vr/ui_scene_manager_unittest.cc +++ b/chrome/browser/vr/ui_scene_manager_unittest.cc
@@ -10,7 +10,7 @@ #include "cc/base/math_util.h" #include "chrome/browser/vr/color_scheme.h" #include "chrome/browser/vr/elements/ui_element.h" -#include "chrome/browser/vr/elements/ui_element_debug_id.h" +#include "chrome/browser/vr/elements/ui_element_name.h" #include "chrome/browser/vr/target_property.h" #include "chrome/browser/vr/test/animation_utils.h" #include "chrome/browser/vr/test/constants.h" @@ -28,18 +28,18 @@ using TargetProperty::OPACITY; namespace { -std::set<UiElementDebugId> kBackgroundElements = { +std::set<UiElementName> kBackgroundElements = { kBackgroundFront, kBackgroundLeft, kBackgroundBack, kBackgroundRight, kBackgroundTop, kBackgroundBottom}; -std::set<UiElementDebugId> kFloorCeilingBackgroundElements = { +std::set<UiElementName> kFloorCeilingBackgroundElements = { kBackgroundFront, kBackgroundLeft, kBackgroundBack, kBackgroundRight, kBackgroundTop, kBackgroundBottom, kCeiling, kFloor}; -std::set<UiElementDebugId> kElementsVisibleInBrowsing = { +std::set<UiElementName> kElementsVisibleInBrowsing = { kBackgroundFront, kBackgroundLeft, kBackgroundBack, kBackgroundRight, kBackgroundTop, kBackgroundBottom, kCeiling, kFloor, kContentQuad, kBackplane, kUrlBar, kUnderDevelopmentNotice}; -std::set<UiElementDebugId> kElementsVisibleWithExitPrompt = { +std::set<UiElementName> kElementsVisibleWithExitPrompt = { kBackgroundFront, kBackgroundLeft, kBackgroundBack, kBackgroundRight, kBackgroundTop, kBackgroundBottom, kCeiling, kFloor, kExitPrompt, kExitPromptBackplane}; @@ -243,19 +243,19 @@ manager_->OnWebVrFrameAvailable(); VerifyElementsVisible( - "Autopresented", std::set<UiElementDebugId>{ + "Autopresented", std::set<UiElementName>{ kWebVrPermanentHttpSecurityWarning, kWebVrTransientHttpSecurityWarning, kWebVrUrlToast}); // Make sure the transient elements go away. task_runner_->FastForwardUntilNoTasksRemain(); - UiElement* transient_url_bar = scene_->GetUiElementByDebugId(kWebVrUrlToast); + UiElement* transient_url_bar = scene_->GetUiElementByName(kWebVrUrlToast); EXPECT_TRUE(IsAnimating(transient_url_bar, {OPACITY, VISIBILITY})); // Finish the transition. AnimateBy(MsToDelta(1000)); EXPECT_FALSE(IsAnimating(transient_url_bar, {OPACITY, VISIBILITY})); - VerifyElementsVisible("End state", std::set<UiElementDebugId>{ - kWebVrPermanentHttpSecurityWarning}); + VerifyElementsVisible( + "End state", std::set<UiElementName>{kWebVrPermanentHttpSecurityWarning}); } TEST_F(UiSceneManagerTest, WebVrAutopresented) { @@ -276,11 +276,11 @@ manager_->SetWebVrMode(true, false); manager_->OnWebVrFrameAvailable(); VerifyElementsVisible("Autopresented", - std::set<UiElementDebugId>{kWebVrUrlToast}); + std::set<UiElementName>{kWebVrUrlToast}); // Make sure the transient URL bar times out. task_runner_->FastForwardUntilNoTasksRemain(); - UiElement* transient_url_bar = scene_->GetUiElementByDebugId(kWebVrUrlToast); + UiElement* transient_url_bar = scene_->GetUiElementByName(kWebVrUrlToast); EXPECT_TRUE(IsAnimating(transient_url_bar, {OPACITY, VISIBILITY})); // Finish the transition. AnimateBy(MsToDelta(1000)); @@ -309,7 +309,7 @@ // Hold onto the background color to make sure it changes. SkColor initial_background = GetBackgroundColor(); VerifyElementsVisible("Initial", kElementsVisibleInBrowsing); - UiElement* content_quad = scene_->GetUiElementByDebugId(kContentQuad); + UiElement* content_quad = scene_->GetUiElementByName(kContentQuad); gfx::SizeF initial_content_size = content_quad->size(); gfx::Transform initial_position = content_quad->LocalTransform(); @@ -396,8 +396,7 @@ EXPECT_CALL(*browser_, OnExitVrPromptResult(UiUnsupportedMode::kUnhandledPageInfo, ExitVrPromptChoice::CHOICE_NONE)); - scene_->GetUiElementByDebugId(kExitPromptBackplane) - ->OnButtonUp(gfx::PointF()); + scene_->GetUiElementByName(kExitPromptBackplane)->OnButtonUp(gfx::PointF()); VerifyElementsVisible("Prompt still visible", kElementsVisibleWithExitPrompt); } @@ -466,7 +465,7 @@ manager_->SetBluetoothConnectedIndicator(true); // All elements should be hidden. - VerifyElementsVisible("Elements hidden", std::set<UiElementDebugId>{}); + VerifyElementsVisible("Elements hidden", std::set<UiElementName>{}); } TEST_F(UiSceneManagerTest, UiUpdateTransitionToWebVR) { @@ -482,11 +481,11 @@ manager_->SetWebVrSecureOrigin(true); // All elements should be hidden. - VerifyElementsVisible("Elements hidden", std::set<UiElementDebugId>{}); + VerifyElementsVisible("Elements hidden", std::set<UiElementName>{}); } TEST_F(UiSceneManagerTest, CaptureIndicatorsVisibility) { - const std::set<UiElementDebugId> indicators = { + const std::set<UiElementName> indicators = { kAudioCaptureIndicator, kVideoCaptureIndicator, kScreenCaptureIndicator, kLocationAccessIndicator, kBluetoothConnectedIndicator, @@ -558,7 +557,7 @@ AnimateBy(MsToDelta(0)); manager_->OnProjMatrixChanged(kProjMatrix); - UiElement* content_quad = scene_->GetUiElementByDebugId(kContentQuad); + UiElement* content_quad = scene_->GetUiElementByName(kContentQuad); gfx::SizeF content_quad_size = content_quad->size(); content_quad_size.Scale(1.2f); content_quad->SetSize(content_quad_size.width(), content_quad_size.height());
diff --git a/chrome/browser/vr/ui_scene_unittest.cc b/chrome/browser/vr/ui_scene_unittest.cc index 32df386..2987ee0 100644 --- a/chrome/browser/vr/ui_scene_unittest.cc +++ b/chrome/browser/vr/ui_scene_unittest.cc
@@ -10,7 +10,9 @@ #include <vector> #include "base/memory/ptr_util.h" +#include "base/test/gtest_util.h" #include "base/values.h" +#include "chrome/browser/vr/elements/draw_phase.h" #include "chrome/browser/vr/elements/ui_element.h" #include "chrome/browser/vr/elements/ui_element_transform_operations.h" #include "chrome/browser/vr/elements/viewport_aware_root.h" @@ -30,11 +32,12 @@ namespace { -void addElement(UiScene* scene, int id) { - auto element = base::MakeUnique<UiElement>(); - element->set_id(id); - element->set_draw_phase(0); - scene->AddUiElement(std::move(element)); +size_t NumElementsInSubtree(UiElement* element) { + size_t count = 1; + for (auto& child : element->children()) { + count += NumElementsInSubtree(child.get()); + } + return count; } } // namespace @@ -42,26 +45,40 @@ TEST(UiScene, AddRemoveElements) { UiScene scene; - EXPECT_EQ(scene.GetUiElements().size(), 0u); - addElement(&scene, 0); - EXPECT_EQ(scene.GetUiElements().size(), 1u); - addElement(&scene, 99); - EXPECT_EQ(scene.GetUiElements().size(), 2u); + // Always start with the root element. + EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 1u); - EXPECT_NE(scene.GetUiElementById(0), nullptr); - EXPECT_NE(scene.GetUiElementById(99), nullptr); - EXPECT_EQ(scene.GetUiElementById(1), nullptr); + auto element = base::MakeUnique<UiElement>(); + element->set_draw_phase(kPhaseForeground); + UiElement* parent = element.get(); + int parent_id = parent->id(); + scene.AddUiElement(kRoot, std::move(element)); - scene.RemoveUiElement(0); - EXPECT_EQ(scene.GetUiElements().size(), 1u); - EXPECT_EQ(scene.GetUiElementById(0), nullptr); - scene.RemoveUiElement(99); - EXPECT_EQ(scene.GetUiElements().size(), 0u); - EXPECT_EQ(scene.GetUiElementById(99), nullptr); + EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 2u); - scene.RemoveUiElement(0); - scene.RemoveUiElement(99); - EXPECT_EQ(scene.GetUiElements().size(), 0u); + element = base::MakeUnique<UiElement>(); + element->set_draw_phase(kPhaseForeground); + UiElement* child = element.get(); + int child_id = child->id(); + + parent->AddChild(std::move(element)); + + EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 3u); + + EXPECT_NE(scene.GetUiElementById(parent_id), nullptr); + EXPECT_NE(scene.GetUiElementById(child_id), nullptr); + EXPECT_EQ(scene.GetUiElementById(-1), nullptr); + + scene.RemoveUiElement(child_id); + EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 2u); + EXPECT_EQ(scene.GetUiElementById(child_id), nullptr); + + scene.RemoveUiElement(parent_id); + EXPECT_EQ(NumElementsInSubtree(&scene.root_element()), 1u); + EXPECT_EQ(scene.GetUiElementById(parent_id), nullptr); + + // It is an error to remove an already-deleted element. + EXPECT_DCHECK_DEATH(scene.RemoveUiElement(child_id)); } // This test creates a parent and child UI element, each with their own @@ -73,7 +90,7 @@ // Add a parent element, with distinct transformations. // Size of the parent should be ignored by the child. auto element = base::MakeUnique<UiElement>(); - element->set_id(0); + UiElement* parent = element.get(); element->SetSize(1000, 1000); UiElementTransformOperations operations; @@ -82,20 +99,18 @@ operations.SetScale(3, 3, 1); element->SetTransformOperations(operations); element->set_draw_phase(0); - scene.AddUiElement(std::move(element)); + scene.AddUiElement(kRoot, std::move(element)); // Add a child to the parent, with different transformations. element = base::MakeUnique<UiElement>(); - element->set_id(1); - scene.GetUiElementById(0)->AddChild(element.get()); UiElementTransformOperations child_operations; child_operations.SetTranslate(3, 0, 0); child_operations.SetRotate(0, 0, 1, 90); child_operations.SetScale(2, 2, 1); element->SetTransformOperations(child_operations); element->set_draw_phase(0); - scene.AddUiElement(std::move(element)); - const UiElement* child = scene.GetUiElementById(1); + UiElement* child = element.get(); + parent->AddChild(std::move(element)); gfx::Point3F origin(0, 0, 0); gfx::Point3F point(1, 0, 0); @@ -111,48 +126,45 @@ UiScene scene; auto element = base::MakeUnique<UiElement>(); - element->set_id(0); + UiElement* parent = element.get(); element->SetOpacity(0.5); element->set_draw_phase(0); - scene.AddUiElement(std::move(element)); + scene.AddUiElement(kRoot, std::move(element)); element = base::MakeUnique<UiElement>(); - element->set_id(1); - scene.GetUiElementById(0)->AddChild(element.get()); + UiElement* child = element.get(); element->SetOpacity(0.5); element->set_draw_phase(0); - scene.AddUiElement(std::move(element)); + parent->AddChild(std::move(element)); scene.OnBeginFrame(MicrosecondsToTicks(0), gfx::Vector3dF()); - EXPECT_EQ(0.5f, scene.GetUiElementById(0)->computed_opacity()); - EXPECT_EQ(0.25f, scene.GetUiElementById(1)->computed_opacity()); + EXPECT_EQ(0.5f, parent->computed_opacity()); + EXPECT_EQ(0.25f, child->computed_opacity()); } TEST(UiScene, ViewportAware) { UiScene scene; auto root = base::MakeUnique<ViewportAwareRoot>(); - root->set_id(0); + UiElement* viewport_aware_root = root.get(); root->set_draw_phase(0); - scene.AddUiElement(std::move(root)); + scene.AddUiElement(kRoot, std::move(root)); auto element = base::MakeUnique<UiElement>(); - element->set_id(1); + UiElement* parent = element.get(); element->set_viewport_aware(true); element->set_draw_phase(0); - scene.GetUiElementById(0)->AddChild(element.get()); - scene.AddUiElement(std::move(element)); + viewport_aware_root->AddChild(std::move(element)); element = base::MakeUnique<UiElement>(); - element->set_id(2); - scene.GetUiElementById(1)->AddChild(element.get()); + UiElement* child = element.get(); element->set_viewport_aware(false); element->set_draw_phase(0); - scene.AddUiElement(std::move(element)); + parent->AddChild(std::move(element)); scene.OnBeginFrame(MicrosecondsToTicks(0), gfx::Vector3dF()); - EXPECT_TRUE(scene.GetUiElementById(1)->computed_viewport_aware()); - EXPECT_TRUE(scene.GetUiElementById(2)->computed_viewport_aware()); + EXPECT_TRUE(parent->computed_viewport_aware()); + EXPECT_TRUE(child->computed_viewport_aware()); } typedef struct { @@ -169,26 +181,23 @@ // Create a parent element with non-unity size and scale. auto element = base::MakeUnique<UiElement>(); - element->set_id(0); + UiElement* parent = element.get(); element->SetSize(2, 2); element->SetScale(2, 2, 1); element->set_draw_phase(0); - scene.AddUiElement(std::move(element)); + scene.AddUiElement(kRoot, std::move(element)); // Add a child to the parent, with anchoring. element = base::MakeUnique<UiElement>(); - element->set_id(1); - scene.GetUiElementById(0)->AddChild(element.get()); + UiElement* child = element.get(); element->set_x_anchoring(GetParam().x_anchoring); element->set_y_anchoring(GetParam().y_anchoring); element->set_draw_phase(0); - scene.AddUiElement(std::move(element)); + parent->AddChild(std::move(element)); scene.OnBeginFrame(MicrosecondsToTicks(0), gfx::Vector3dF()); - const UiElement* child = scene.GetUiElementById(1); EXPECT_NEAR(GetParam().expected_x, child->GetCenter().x(), TOLERANCE); EXPECT_NEAR(GetParam().expected_y, child->GetCenter().y(), TOLERANCE); - scene.RemoveUiElement(1); } const std::vector<AnchoringTestCase> anchoring_test_cases = {
diff --git a/chrome/common/stack_sampling_configuration.cc b/chrome/common/stack_sampling_configuration.cc index b88ac1a9..e28d59d9 100644 --- a/chrome/common/stack_sampling_configuration.cc +++ b/chrome/common/stack_sampling_configuration.cc
@@ -36,11 +36,9 @@ #elif defined(OS_MACOSX) // Only run on canary for now. #if defined(GOOGLE_CHROME_BUILD) - // TODO(lgrey): Reenable for 10.13 when crbug.com/748254 is fixed. - return base::mac::IsAtMostOS10_12() && - chrome::GetChannel() == version_info::Channel::CANARY; + return chrome::GetChannel() == version_info::Channel::CANARY; #else - return base::mac::IsAtMostOS10_12(); + return true; #endif #else return false;
diff --git a/chrome/profiling/json_exporter.cc b/chrome/profiling/json_exporter.cc index ee76a2bc..0c4bb9e 100644 --- a/chrome/profiling/json_exporter.cc +++ b/chrome/profiling/json_exporter.cc
@@ -255,12 +255,15 @@ const AllocationEventSet& event_set, const std::vector<memory_instrumentation::mojom::VmRegionPtr>& maps, std::ostream& out, - std::unique_ptr<base::DictionaryValue> metadata_dict) { + std::unique_ptr<base::DictionaryValue> metadata_dict, + size_t min_size_threshold, + size_t min_count_threshold) { out << "{ \"traceEvents\": ["; WriteProcessName(pid, out); out << ",\n"; WriteDumpsHeader(pid, out); - ExportMemoryMapsAndV2StackTraceToJSON(event_set, maps, out); + ExportMemoryMapsAndV2StackTraceToJSON( + event_set, maps, out, min_size_threshold, min_count_threshold); WriteDumpsFooter(out); out << "]"; @@ -277,7 +280,9 @@ void ExportMemoryMapsAndV2StackTraceToJSON( const AllocationEventSet& event_set, const std::vector<memory_instrumentation::mojom::VmRegionPtr>& maps, - std::ostream& out) { + std::ostream& out, + size_t min_size_threshold, + size_t min_count_threshold) { // Start dictionary. out << "{\n"; @@ -321,14 +326,35 @@ // We hardcode one type, "[unknown]". size_t type_string_id = AddOrGetString("[unknown]", &string_table); - // Find all backtraces referenced by the set. The backtrace storage will - // contain more stacks than we want to write out (it will refer to all - // processes, while we're only writing one). So do those only on demand. + // Aggregate allocations. Allocations of the same size and stack get grouped. + UniqueAllocCount alloc_counts; + for (const auto& alloc : event_set) { + UniqueAlloc unique_alloc(alloc.backtrace(), alloc.size()); + alloc_counts[unique_alloc]++; + } + + // Filter irrelevant allocations. + for (auto alloc = alloc_counts.begin(); alloc != alloc_counts.end();) { + size_t alloc_count = alloc->second; + size_t alloc_size = alloc->first.size; + size_t alloc_total_size = alloc_size * alloc_count; + if (alloc_total_size < min_size_threshold && + alloc_count < min_count_threshold) { + alloc = alloc_counts.erase(alloc); + } else { + ++alloc; + } + } + + // Find all backtraces referenced by the set and not filtered. The backtrace + // storage will contain more stacks than we want to write out (it will refer + // to all processes, while we're only writing one). So do those only on + // demand. // // The map maps backtrace keys to node IDs (computed below). std::map<const Backtrace*, size_t> backtraces; - for (const auto& event : event_set) - backtraces.emplace(event.backtrace(), 0); + for (const auto& alloc : alloc_counts) + backtraces.emplace(alloc.first.backtrace, 0); // Write each backtrace, converting the string for the stack entry to string // IDs. The backtrace -> node ID will be filled in at this time. @@ -347,13 +373,6 @@ << "}]"; out << "},\n"; // End of maps section. - // Aggregate allocations. Allocations of the same size and stack get grouped. - UniqueAllocCount alloc_counts; - for (const auto& alloc : event_set) { - UniqueAlloc unique_alloc(alloc.backtrace(), alloc.size()); - alloc_counts[unique_alloc]++; - } - // Allocators section. out << "\"allocators\":{\"malloc\":{\n"; WriteCounts(alloc_counts, out);
diff --git a/chrome/profiling/json_exporter.h b/chrome/profiling/json_exporter.h index f518d91..328ed7bc 100644 --- a/chrome/profiling/json_exporter.h +++ b/chrome/profiling/json_exporter.h
@@ -21,14 +21,18 @@ const AllocationEventSet& set, const std::vector<memory_instrumentation::mojom::VmRegionPtr>& maps, std::ostream& out, - std::unique_ptr<base::DictionaryValue> metadata); + std::unique_ptr<base::DictionaryValue> metadata, + size_t min_size_threshold, + size_t min_count_threshold); // Creates a JSON string representing a JSON dictionary that contains memory // maps and v2 format stack traces. void ExportMemoryMapsAndV2StackTraceToJSON( const AllocationEventSet& set, const std::vector<memory_instrumentation::mojom::VmRegionPtr>& maps, - std::ostream& out); + std::ostream& out, + size_t min_size_threshold, + size_t min_count_threshold); } // namespace profiling
diff --git a/chrome/profiling/json_exporter_unittest.cc b/chrome/profiling/json_exporter_unittest.cc index 14d2e86..0b66ee0 100644 --- a/chrome/profiling/json_exporter_unittest.cc +++ b/chrome/profiling/json_exporter_unittest.cc
@@ -20,6 +20,11 @@ namespace { +const size_t kNoSizeThreshold = 0; +const size_t kNoCountThreshold = 0; +const size_t kSizeThreshold = 1500; +const size_t kCountThreshold = 1000; + using MemoryMap = std::vector<memory_instrumentation::mojom::VmRegionPtr>; static constexpr int kNoParent = -1; @@ -152,7 +157,8 @@ events.insert(AllocationEvent(Address(0x3), 20, bt1)); std::ostringstream stream; - ExportAllocationEventSetToJSON(0x1234, events, MemoryMap(), stream, nullptr); + ExportAllocationEventSetToJSON(1234, events, MemoryMap(), stream, nullptr, + kNoSizeThreshold, kNoCountThreshold); std::string json = stream.str(); // JSON should parse. @@ -249,6 +255,92 @@ EXPECT_EQ(id3, backtraces->GetList()[node3].GetInt()); } +TEST(ProfilingJsonExporterTest, SimpleWithFilteredAllocations) { + BacktraceStorage backtrace_storage; + + std::vector<Address> stack1; + stack1.push_back(Address(0x1234)); + const Backtrace* bt1 = backtrace_storage.Insert(std::move(stack1)); + + std::vector<Address> stack2; + stack2.push_back(Address(0x5678)); + const Backtrace* bt2 = backtrace_storage.Insert(std::move(stack2)); + + std::vector<Address> stack3; + stack3.push_back(Address(0x9999)); + const Backtrace* bt3 = backtrace_storage.Insert(std::move(stack3)); + + AllocationEventSet events; + events.insert(AllocationEvent(Address(0x1), 16, bt1)); + events.insert(AllocationEvent(Address(0x2), 32, bt1)); + events.insert(AllocationEvent(Address(0x3), 1000, bt2)); + events.insert(AllocationEvent(Address(0x4), 1000, bt2)); + for (size_t i = 0; i < kCountThreshold + 1; ++i) + events.insert(AllocationEvent(Address(0x5 + i), 1, bt3)); + + // Validate filtering by size and count. + std::ostringstream stream; + ExportAllocationEventSetToJSON(1234, events, MemoryMap(), stream, nullptr, + kSizeThreshold, kCountThreshold); + std::string json = stream.str(); + + // JSON should parse. + base::JSONReader reader(base::JSON_PARSE_RFC); + std::unique_ptr<base::Value> root = reader.ReadToValue(stream.str()); + ASSERT_EQ(base::JSONReader::JSON_NO_ERROR, reader.error_code()) + << reader.GetErrorMessage(); + ASSERT_TRUE(root); + + // The trace array contains two items, a process_name one and a + // periodic_interval one. Find the latter. + const base::Value* periodic_interval = FindFirstPeriodicInterval(*root); + ASSERT_TRUE(periodic_interval) << "Array contains no periodic_interval"; + const base::Value* heaps_v2 = + periodic_interval->FindPath({"args", "dumps", "heaps_v2"}); + ASSERT_TRUE(heaps_v2); + const base::Value* nodes = heaps_v2->FindPath({"maps", "nodes"}); + const base::Value* strings = heaps_v2->FindPath({"maps", "strings"}); + ASSERT_TRUE(nodes); + ASSERT_TRUE(strings); + + // Validate the strings table. + EXPECT_EQ(3u, strings->GetList().size()); + int sid_unknown = GetStringFromStringTable(strings, "[unknown]"); + int sid_1234 = GetStringFromStringTable(strings, "pc:1234"); + int sid_5678 = GetStringFromStringTable(strings, "pc:5678"); + int sid_9999 = GetStringFromStringTable(strings, "pc:9999"); + EXPECT_NE(-1, sid_unknown); + EXPECT_EQ(-1, sid_1234); // Must be filtered. + EXPECT_NE(-1, sid_5678); + EXPECT_NE(-1, sid_9999); + + // Validate the nodes table. + // Nodes should be a list with 4 items. + // [0] => address: 5678 parent: none + // [1] => address: 9999 parent: none + EXPECT_EQ(2u, nodes->GetList().size()); + int id0 = GetNodeWithNameID(nodes, sid_5678); + int id1 = GetNodeWithNameID(nodes, sid_9999); + EXPECT_NE(-1, id0); + EXPECT_NE(-1, id1); + EXPECT_TRUE(IsBacktraceInList(nodes, id0, kNoParent)); + EXPECT_TRUE(IsBacktraceInList(nodes, id1, kNoParent)); + + // Counts should be a list with one item. Items with |bt1| are filtered. + // For |stack2|, there are two allocations of 1000 bytes. which is above the + // 1500 bytes threshold. For |stack3|, there are 1001 allocations of 1 bytes, + // which is above the 1000 allocations threshold. + const base::Value* backtraces = + heaps_v2->FindPath({"allocators", "malloc", "nodes"}); + ASSERT_TRUE(backtraces); + EXPECT_EQ(2u, backtraces->GetList().size()); + + int node_bt2 = GetOffsetForBacktraceID(backtraces, id0); + int node_bt3 = GetOffsetForBacktraceID(backtraces, id1); + EXPECT_NE(-1, node_bt2); + EXPECT_NE(-1, node_bt3); +} + TEST(ProfilingJsonExporterTest, MemoryMaps) { AllocationEventSet events; std::vector<memory_instrumentation::mojom::VmRegionPtr> memory_maps = @@ -257,7 +349,8 @@ ASSERT_GT(memory_maps.size(), 2u); std::ostringstream stream; - ExportAllocationEventSetToJSON(1234, events, memory_maps, stream, nullptr); + ExportAllocationEventSetToJSON(1234, events, memory_maps, stream, nullptr, + kNoSizeThreshold, kNoCountThreshold); std::string json = stream.str(); // JSON should parse. @@ -304,7 +397,8 @@ std::ostringstream stream; ExportAllocationEventSetToJSON(1234, events, MemoryMap(), stream, - std::move(metadata_dict)); + std::move(metadata_dict), kNoSizeThreshold, + kNoCountThreshold); std::string json = stream.str(); // JSON should parse.
diff --git a/chrome/profiling/memlog_connection_manager.cc b/chrome/profiling/memlog_connection_manager.cc index 360f1c81..adf80a6 100644 --- a/chrome/profiling/memlog_connection_manager.cc +++ b/chrome/profiling/memlog_connection_manager.cc
@@ -22,6 +22,13 @@ namespace profiling { +namespace { +const size_t kMinSizeThreshold = 16 * 1024; +const size_t kMinCountThreshold = 1024; +const size_t kMinSizeThresholdForTracing = 0; +const size_t kMinCountThresholdForTracing = 0; +} // namespace + struct MemlogConnectionManager::Connection { Connection(AllocationTracker::CompleteCallback complete_cb, BacktraceStorage* backtrace_storage, @@ -119,7 +126,8 @@ std::ostringstream oss; ExportAllocationEventSetToJSON(pid, connection->tracker.live_allocs(), maps, - oss, std::move(metadata)); + oss, std::move(metadata), kMinSizeThreshold, + kMinCountThreshold); std::string reply = oss.str(); // Pass ownership of the underlying fd/HANDLE to zlib. @@ -168,7 +176,8 @@ Connection* connection = it->second.get(); std::ostringstream oss; ExportMemoryMapsAndV2StackTraceToJSON(connection->tracker.live_allocs(), maps, - oss); + oss, kMinSizeThresholdForTracing, + kMinCountThresholdForTracing); std::string reply = oss.str(); mojo::ScopedSharedBufferHandle buffer =
diff --git a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js index f78c92f..b24f3f0 100644 --- a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js +++ b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
@@ -492,7 +492,9 @@ assertEq([ {Scanning: false, State: 'Enabled', Type: 'Ethernet'}, {Scanning: false, State: 'Enabled', Type: 'WiFi'}, - {State: 'Uninitialized', Type: 'Cellular', SimPresent: true}, + {State: 'Uninitialized', SIMPresent: true, + SIMLockStatus: {LockEnabled: true, LockType: '', RetriesLeft: 3}, + Type: 'Cellular' }, {State: 'Disabled', Type: 'WiMAX'}, ], result);
diff --git a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js index 874253c..285764b 100644 --- a/chrome/test/data/extensions/platform_apps/web_view/shim/main.js +++ b/chrome/test/data/extensions/platform_apps/web_view/shim/main.js
@@ -1897,6 +1897,11 @@ document.body.appendChild(webview); } +function testDeclarativeWebRequestAPISendMessageSecondWebView() { + var tempWebview = new WebView(); + testDeclarativeWebRequestAPISendMessage(); +} + // This test verifies that setting a <webview>'s style.display = 'block' does // not throw and attach error. function testDisplayBlock() { @@ -3174,6 +3179,8 @@ 'testDeclarativeWebRequestAPI': testDeclarativeWebRequestAPI, 'testDeclarativeWebRequestAPISendMessage': testDeclarativeWebRequestAPISendMessage, + 'testDeclarativeWebRequestAPISendMessageSecondWebView': + testDeclarativeWebRequestAPISendMessageSecondWebView, 'testDisplayBlock': testDisplayBlock, 'testWebRequestAPI': testWebRequestAPI, 'testWebRequestAPIErrorOccurred': testWebRequestAPIErrorOccurred,
diff --git a/chrome/test/data/webui/extensions/extension_manager_test.js b/chrome/test/data/webui/extensions/extension_manager_test.js index f3479c2..d9f2a30 100644 --- a/chrome/test/data/webui/extensions/extension_manager_test.js +++ b/chrome/test/data/webui/extensions/extension_manager_test.js
@@ -173,7 +173,10 @@ manager.addItem(extension); manager.addItem(secondExtension); var data = manager.extensions[0]; - manager.showItemDetails(extension); + // TODO(scottchen): maybe testing too many things in a single unit test. + manager.$['items-list'].fire( + 'extension-item-show-details', {data: extension}); + Polymer.dom.flush(); var detailsView = manager.$['details-view']; expectEquals(extension.id, detailsView.data.id); expectEquals(oldDescription, detailsView.data.description);
diff --git a/chrome/test/data/webui/extensions/extension_navigation_helper_test.js b/chrome/test/data/webui/extensions/extension_navigation_helper_test.js index 0e665f8..0390aca5 100644 --- a/chrome/test/data/webui/extensions/extension_navigation_helper_test.js +++ b/chrome/test/data/webui/extensions/extension_navigation_helper_test.js
@@ -39,7 +39,9 @@ var navigationHelper = new extensions.NavigationHelper(changePage); expectEquals('chrome://extensions/navigation_helper.html', location.href); - expectDeepEquals({page: Page.LIST}, navigationHelper.getCurrentPage()); + expectDeepEquals( + {page: Page.LIST, type: extensions.ShowingType.EXTENSIONS}, + navigationHelper.getCurrentPage()); var currentLength = history.length; navigationHelper.updateHistory({page: Page.DETAILS, extensionId: id}); @@ -55,7 +57,8 @@ .then(() => { mock.verifyMock(); - mock.addExpectation({page: Page.LIST}); + mock.addExpectation( + {page: Page.LIST, type: extensions.ShowingType.EXTENSIONS}); var waitForNextPop = getOnPopState(); history.back(); return waitForNextPop; @@ -68,9 +71,13 @@ test(assert(TestNames.Conversions), function() { var id = 'a'.repeat(32); var stateUrlPairs = { - list: { + extensions: { url: 'chrome://extensions/', - state: {page: Page.LIST}, + state: {page: Page.LIST, type: extensions.ShowingType.EXTENSIONS}, + }, + apps: { + url: 'chrome://extensions/apps', + state: {page: Page.LIST, type: extensions.ShowingType.APPS}, }, details: { url: 'chrome://extensions/?id=' + id, @@ -117,7 +124,9 @@ var navigationHelper = new extensions.NavigationHelper(function() {}); history.pushState({}, '', 'chrome://extensions/'); - expectDeepEquals({page: Page.LIST}, navigationHelper.getCurrentPage()); + expectDeepEquals( + {page: Page.LIST, type: extensions.ShowingType.EXTENSIONS}, + navigationHelper.getCurrentPage()); var expectedLength = history.length;
diff --git a/chrome/test/data/webui/settings/bluetooth_page_tests.js b/chrome/test/data/webui/settings/bluetooth_page_tests.js index 5644558..afda0af 100644 --- a/chrome/test/data/webui/settings/bluetooth_page_tests.js +++ b/chrome/test/data/webui/settings/bluetooth_page_tests.js
@@ -2,6 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +function getFakePrefs() { + return { + ash: { + user: { + bluetooth: { + adapter_enabled: { + key: 'ash.user.bluetooth.adapter_enabled', + type: chrome.settingsPrivate.PrefType.BOOLEAN, + value: false, + } + } + } + } + }; +} + suite('Bluetooth', function() { var bluetoothPage = null; @@ -60,6 +76,7 @@ setup(function() { PolymerTest.clearBody(); bluetoothPage = document.createElement('settings-bluetooth-page'); + bluetoothPage.prefs = getFakePrefs(); assertTrue(!!bluetoothPage); bluetoothApi_.setDevicesForTest([]); @@ -73,43 +90,51 @@ test('MainPage', function() { assertFalse(bluetoothApi_.getAdapterStateForTest().powered); - assertFalse(bluetoothPage.bluetoothToggleState_); + assertFalse(bluetoothPage.prefs.ash.user.bluetooth.adapter_enabled.value); // Test that tapping the single settings-box div enables bluetooth. var div = bluetoothPage.$$('div.settings-box'); assertTrue(!!div); MockInteractions.tap(div); - assertTrue(bluetoothPage.bluetoothToggleState_); - assertTrue(bluetoothApi_.getAdapterStateForTest().powered); + assertTrue(bluetoothPage.prefs.ash.user.bluetooth.adapter_enabled.value); }); suite('SubPage', function() { var subpage; setup(function() { - bluetoothApi_.setEnabled(true); - Polymer.dom.flush(); + assertFalse(bluetoothApi_.getAdapterStateForTest().powered); + assertFalse(bluetoothPage.prefs.ash.user.bluetooth.adapter_enabled.value); var div = bluetoothPage.$$('div.settings-box'); + + // First tap will turn on bluetooth. MockInteractions.tap(div); + assertTrue(bluetoothPage.prefs.ash.user.bluetooth.adapter_enabled.value); + bluetoothPage.adapterState_.powered = true; + // Second tap will open bluetooth subpage. + MockInteractions.tap(div); + + Polymer.dom.flush(); subpage = bluetoothPage.$$('settings-bluetooth-subpage'); assertTrue(!!subpage); - assertTrue(subpage.bluetoothToggleState); - assertFalse(subpage.bluetoothToggleDisabled); }); test('toggle', function() { - assertTrue(subpage.bluetoothToggleState); + assertTrue(bluetoothPage.prefs.ash.user.bluetooth.adapter_enabled.value); var enableButton = subpage.$.enableBluetooth; assertTrue(!!enableButton); assertTrue(enableButton.checked); - subpage.bluetoothToggleState = false; + bluetoothPage.setPrefValue('ash.user.bluetooth.adapter_enabled', false); + assertFalse(enableButton.checked); assertFalse(bluetoothApi_.getAdapterStateForTest().powered); - assertFalse(bluetoothPage.bluetoothToggleState_); + assertFalse(bluetoothPage.prefs.ash.user.bluetooth.adapter_enabled.value); }); test('paired device list', function() { + assertTrue(subpage.adapterState.powered); + var pairedContainer = subpage.$.pairedContainer; assertTrue(!!pairedContainer); assertTrue(pairedContainer.hidden); @@ -132,6 +157,8 @@ }); test('unpaired device list', function() { + assertTrue(subpage.adapterState.powered); + var unpairedContainer = subpage.$.unpairedContainer; assertTrue(!!unpairedContainer); assertTrue(unpairedContainer.hidden); @@ -154,6 +181,8 @@ }); test('pair device', function(done) { + assertTrue(subpage.adapterState.powered); + bluetoothApi_.setDevicesForTest(fakeDevices_); Polymer.dom.flush(); assertEquals(4, subpage.deviceList_.length); @@ -170,6 +199,8 @@ }); test('pair dialog', function() { + assertTrue(subpage.adapterState.powered); + bluetoothApi_.setDevicesForTest(fakeDevices_); Polymer.dom.flush(); var dialog = subpage.$.deviceDialog;
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn index 732f9f7..8ced54c7 100644 --- a/chromecast/android/BUILD.gn +++ b/chromecast/android/BUILD.gn
@@ -20,8 +20,6 @@ cast_shared_library("libcast_shell_android") { sources = [ "//chromecast/app/android/cast_jni_loader.cc", - "cast_jni_registrar.cc", - "cast_jni_registrar.h", ] deps = [
diff --git a/chromecast/android/cast_jni_registrar.cc b/chromecast/android/cast_jni_registrar.cc deleted file mode 100644 index 873048c..0000000 --- a/chromecast/android/cast_jni_registrar.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromecast/android/cast_jni_registrar.h" - -#include "base/android/jni_android.h" -#include "base/android/jni_registrar.h" -#include "base/macros.h" -#include "chromecast/base/android/system_time_change_notifier_android.h" -#include "chromecast/base/chromecast_config_android.h" -#include "chromecast/chromecast_features.h" - -#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) -#include "chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h" -#include "chromecast/media/cma/backend/android/volume_control_android.h" -#endif - -namespace chromecast { -namespace android { - -namespace { - -static base::android::RegistrationMethod kMethods[] = { - {"ChromecastConfigAndroid", ChromecastConfigAndroid::RegisterJni}, - {"SystemTimeChangeNotifierAndroid", - SystemTimeChangeNotifierAndroid::RegisterJni}, -#if BUILDFLAG(IS_CAST_USING_CMA_BACKEND) - {"AudioSinkAudioTrackImpl", - media::AudioSinkAndroidAudioTrackImpl::RegisterJni}, - {"VolumeControlAndroid", media::VolumeControlAndroid::RegisterJni}, -#endif -}; - -} // namespace - -bool RegisterJni(JNIEnv* env) { - return RegisterNativeMethods(env, kMethods, arraysize(kMethods)); -} - -} // namespace android -} // namespace chromecast
diff --git a/chromecast/android/cast_jni_registrar.h b/chromecast/android/cast_jni_registrar.h deleted file mode 100644 index b07316b..0000000 --- a/chromecast/android/cast_jni_registrar.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROMECAST_ANDROID_CAST_JNI_REGISTRAR_H_ -#define CHROMECAST_ANDROID_CAST_JNI_REGISTRAR_H_ - -#include <jni.h> - -namespace chromecast { -namespace android { - -// Register all JNI bindings necessary for the Android cast shell. -bool RegisterJni(JNIEnv* env); - -} // namespace android -} // namespace chromecast - -#endif // CHROMECAST_ANDROID_CAST_JNI_REGISTRAR_H_
diff --git a/chromecast/base/android/system_time_change_notifier_android.cc b/chromecast/base/android/system_time_change_notifier_android.cc index 2aa8bdf5..05d8e95 100644 --- a/chromecast/base/android/system_time_change_notifier_android.cc +++ b/chromecast/base/android/system_time_change_notifier_android.cc
@@ -10,11 +10,6 @@ namespace chromecast { -// static -bool SystemTimeChangeNotifierAndroid::RegisterJni(JNIEnv* env) { - return RegisterNativesImpl(env); -} - SystemTimeChangeNotifierAndroid::SystemTimeChangeNotifierAndroid() { }
diff --git a/chromecast/base/android/system_time_change_notifier_android.h b/chromecast/base/android/system_time_change_notifier_android.h index 2f1aceb..e4e44b4 100644 --- a/chromecast/base/android/system_time_change_notifier_android.h +++ b/chromecast/base/android/system_time_change_notifier_android.h
@@ -13,8 +13,6 @@ class SystemTimeChangeNotifierAndroid : public SystemTimeChangeNotifier { public: - static bool RegisterJni(JNIEnv* env); - SystemTimeChangeNotifierAndroid(); ~SystemTimeChangeNotifierAndroid() override;
diff --git a/chromecast/base/chromecast_config_android.cc b/chromecast/base/chromecast_config_android.cc index 1b36b79..9d87796 100644 --- a/chromecast/base/chromecast_config_android.cc +++ b/chromecast/base/chromecast_config_android.cc
@@ -25,11 +25,6 @@ return g_instance.Pointer(); } -// static -bool ChromecastConfigAndroid::RegisterJni(JNIEnv* env) { - return RegisterNativesImpl(env); -} - ChromecastConfigAndroid::ChromecastConfigAndroid() { }
diff --git a/chromecast/base/chromecast_config_android.h b/chromecast/base/chromecast_config_android.h index 4f2864f..03f8495 100644 --- a/chromecast/base/chromecast_config_android.h +++ b/chromecast/base/chromecast_config_android.h
@@ -17,7 +17,6 @@ class ChromecastConfigAndroid { public: static ChromecastConfigAndroid* GetInstance(); - static bool RegisterJni(JNIEnv* env); // Returns whether or not the user has allowed sending usage stats and // crash reports.
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index ee414f9..578caab 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -151,11 +151,8 @@ "android/cast_content_window_android.cc", "android/cast_content_window_android.h", "android/cast_metrics_helper_android.cc", - "android/cast_metrics_helper_android.h", "android/cast_web_contents_activity.cc", "android/cast_web_contents_activity.h", - "android/jni_registrar.cc", - "android/jni_registrar.h", ] deps += [
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn index 348b104..708752ed 100644 --- a/chromecast/browser/android/BUILD.gn +++ b/chromecast/browser/android/BUILD.gn
@@ -34,11 +34,22 @@ resource_dirs = [ "//chromecast/browser/android/apk/res" ] } +android_library("cast_audio_manager_java") { + java_src_dir = "//chromecast/browser/android/apk/src" + java_files = + [ "$java_src_dir/org/chromium/chromecast/shell/CastAudioManager.java" ] +} + +android_library("cast_intents_java") { + java_src_dir = "//chromecast/browser/android/apk/src" + java_files = + [ "$java_src_dir/org/chromium/chromecast/shell/CastIntents.java" ] +} + android_library("cast_shell_java") { java_src_dir = "//chromecast/browser/android/apk/src" java_files = [ "$java_src_dir/org/chromium/chromecast/shell/CastApplication.java", - "$java_src_dir/org/chromium/chromecast/shell/CastAudioManager.java", "$java_src_dir/org/chromium/chromecast/shell/CastBrowserHelper.java", "$java_src_dir/org/chromium/chromecast/shell/CastContentWindowAndroid.java", "$java_src_dir/org/chromium/chromecast/shell/CastCrashHandler.java", @@ -56,6 +67,8 @@ srcjar_deps = [ ":cast_shell_build_config_gen" ] deps = [ + ":cast_audio_manager_java", + ":cast_intents_java", ":cast_shell_android_resources", ":cast_shell_manifest", "//base:base_java",
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastIntents.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastIntents.java new file mode 100644 index 0000000..869064c --- /dev/null +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastIntents.java
@@ -0,0 +1,16 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chromecast.shell; + +/** + * A namespace for constants to uniquely describe certain public Intents that can be used to control + * the life cycle of CastWebContentsActivity. + */ +public class CastIntents { + public static final String ACTION_STOP_ACTIVITY = + "com.google.android.apps.castshell.intent.action.STOP_ACTIVITY"; + public static final String ACTION_SCREEN_OFF = + "com.google.android.apps.castshell.intent.action.ACTION_SCREEN_OFF"; +}
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java index d911508..974395b 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsActivity.java
@@ -60,11 +60,6 @@ private static final int TEARDOWN_GRACE_PERIOD_TIMEOUT_MILLIS = 300; - public static final String ACTION_STOP_ACTIVITY = - "com.google.android.apps.castshell.intent.action.STOP_ACTIVITY"; - public static final String ACTION_SCREEN_OFF = - "com.google.android.apps.castshell.intent.action.ACTION_SCREEN_OFF"; - /* * Intended to be called from "onStop" to determine if this is a "legitimate" stop or not. * When starting CastShellActivity from the TV in sleep mode, an extra onPause/onStop will be @@ -146,7 +141,7 @@ windowDestroyedIntentFilter.addDataScheme(intent.getData().getScheme()); windowDestroyedIntentFilter.addDataAuthority(intent.getData().getAuthority(), null); windowDestroyedIntentFilter.addDataPath(mInstanceId, PatternMatcher.PATTERN_LITERAL); - windowDestroyedIntentFilter.addAction(ACTION_STOP_ACTIVITY); + windowDestroyedIntentFilter.addAction(CastIntents.ACTION_STOP_ACTIVITY); LocalBroadcastManager.getInstance(this).registerReceiver( mWindowDestroyedBroadcastReceiver, windowDestroyedIntentFilter); @@ -163,7 +158,7 @@ }; IntentFilter screenOffIntentFilter = new IntentFilter(); - screenOffIntentFilter.addAction(ACTION_SCREEN_OFF); + screenOffIntentFilter.addAction(CastIntents.ACTION_SCREEN_OFF); LocalBroadcastManager.getInstance(this).registerReceiver( mScreenOffBroadcastReceiver, screenOffIntentFilter);
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java index 70f8272b..48100d36 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsComponent.java
@@ -62,8 +62,8 @@ public void stop(Context context) { if (DEBUG) Log.d(TAG, "stop"); - Intent intent = new Intent( - CastWebContentsActivity.ACTION_STOP_ACTIVITY, getInstanceUri(mInstanceId)); + Intent intent = + new Intent(CastIntents.ACTION_STOP_ACTIVITY, getInstanceUri(mInstanceId)); LocalBroadcastManager.getInstance(context).sendBroadcastSync(intent); } } @@ -201,4 +201,4 @@ .build(); return instanceUri; } -} \ No newline at end of file +}
diff --git a/chromecast/browser/android/cast_metrics_helper_android.cc b/chromecast/browser/android/cast_metrics_helper_android.cc index e7cc764..77680e09 100644 --- a/chromecast/browser/android/cast_metrics_helper_android.cc +++ b/chromecast/browser/android/cast_metrics_helper_android.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromecast/browser/android/cast_metrics_helper_android.h" - #include "chromecast/base/metrics/cast_metrics_helper.h" #include "jni/CastMetricsHelper_jni.h" @@ -12,11 +10,6 @@ namespace chromecast { namespace shell { -// static -bool CastMetricsHelperAndroid::RegisterJni(JNIEnv* env) { - return RegisterNativesImpl(env); -} - void LogMediaPlay(JNIEnv* env, const JavaParamRef<jclass>& clazz) { metrics::CastMetricsHelper::GetInstance()->LogMediaPlay(); }
diff --git a/chromecast/browser/android/cast_metrics_helper_android.h b/chromecast/browser/android/cast_metrics_helper_android.h deleted file mode 100644 index 6665436..0000000 --- a/chromecast/browser/android/cast_metrics_helper_android.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROMECAST_BROWSER_ANDROID_CAST_METRICS_HELPER_ANDROID_H_ -#define CHROMECAST_BROWSER_ANDROID_CAST_METRICS_HELPER_ANDROID_H_ - -#include <jni.h> -#include <vector> - -#include "base/macros.h" - -namespace chromecast { -namespace shell { -class CastMetricsHelperAndroid { - public: - // Registers the JNI methods for CastMetricsHelperAndroid. - static bool RegisterJni(JNIEnv* env); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(CastMetricsHelperAndroid); -}; - -} // namespace shell -} // namespace chromecast - -#endif // CHROMECAST_BROWSER_ANDROID_CAST_METRICS_HELPER_ANDROID_H_
diff --git a/chromecast/browser/android/cast_web_contents_activity.cc b/chromecast/browser/android/cast_web_contents_activity.cc index 8f314e5..209cf5e 100644 --- a/chromecast/browser/android/cast_web_contents_activity.cc +++ b/chromecast/browser/android/cast_web_contents_activity.cc
@@ -35,11 +35,6 @@ } // static -bool CastWebContentsActivity::RegisterJni(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static CastWebContentsActivity* CastWebContentsActivity::Get( content::WebContents* web_contents) { DCHECK(web_contents);
diff --git a/chromecast/browser/android/cast_web_contents_activity.h b/chromecast/browser/android/cast_web_contents_activity.h index 90404d8..93270f3 100644 --- a/chromecast/browser/android/cast_web_contents_activity.h +++ b/chromecast/browser/android/cast_web_contents_activity.h
@@ -25,7 +25,6 @@ public: ~CastWebContentsActivity() override; - static bool RegisterJni(JNIEnv* env); static CastWebContentsActivity* Get(content::WebContents* web_contents); base::android::ScopedJavaLocalRef<jobject> GetContentVideoViewEmbedder();
diff --git a/chromecast/browser/android/jni_registrar.cc b/chromecast/browser/android/jni_registrar.cc deleted file mode 100644 index 1fc51d8..0000000 --- a/chromecast/browser/android/jni_registrar.cc +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chromecast/browser/android/jni_registrar.h" - -#include "chromecast/browser/android/cast_content_window_android.h" -#include "chromecast/browser/android/cast_metrics_helper_android.h" -#include "chromecast/browser/android/cast_web_contents_activity.h" - -namespace chromecast { -namespace shell { - -bool RegisterJni(JNIEnv* env) { - if (!CastContentWindowAndroid::RegisterJni(env)) - return false; - if (!CastMetricsHelperAndroid::RegisterJni(env)) - return false; - if (!CastWebContentsActivity::RegisterJni(env)) - return false; - - return true; -} - -} // namespace shell -} // namespace chromecast
diff --git a/chromecast/browser/android/jni_registrar.h b/chromecast/browser/android/jni_registrar.h deleted file mode 100644 index 9d6a80d..0000000 --- a/chromecast/browser/android/jni_registrar.h +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROMECAST_BROWSER_ANDROID_JNI_REGISTRAR_H_ -#define CHROMECAST_BROWSER_ANDROID_JNI_REGISTRAR_H_ - -#include <jni.h> - -namespace chromecast { -namespace shell { - -// Register all JNI bindings necessary for the Android cast shell. -bool RegisterJni(JNIEnv* env); - -} // namespace shell -} // namespace chromecast - -#endif // CHROMECAST_BROWSER_ANDROID_JNI_REGISTRAR_H_
diff --git a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc index f7c51708..b8107c3 100644 --- a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc +++ b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.cc
@@ -157,11 +157,6 @@ weak_factory_.InvalidateWeakPtrs(); } -// static -bool AudioSinkAndroidAudioTrackImpl::RegisterJni(JNIEnv* env) { - return RegisterNativesImpl(env); -} - void AudioSinkAndroidAudioTrackImpl::CacheDirectBufferAddress( JNIEnv* env, const JavaParamRef<jobject>& obj,
diff --git a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h index 56bdbe1..e2535a6c 100644 --- a/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h +++ b/chromecast/media/cma/backend/android/audio_sink_android_audiotrack_impl.h
@@ -41,8 +41,6 @@ // buffer larger than this size and feed it in in smaller chunks. static const int kDirectBufferSize = 512 * 1024; - static bool RegisterJni(JNIEnv* env); - // Gets the Android audio session ids used for media and communication (TTS) // tracks. // Set a return value pointer to null if that id is not needed.
diff --git a/chromecast/media/cma/backend/android/volume_control_android.cc b/chromecast/media/cma/backend/android/volume_control_android.cc index c34797d8..15ba370 100644 --- a/chromecast/media/cma/backend/android/volume_control_android.cc +++ b/chromecast/media/cma/backend/android/volume_control_android.cc
@@ -47,71 +47,6 @@ VolumeMap::VolumeMap() { // TODO(ckuiper): Load active volume table from Android. volume_map_.insert(volume_map_.end(), kDefaultVolumeMap, - kDefaultVolumeMap + arraysize(kDefaultVolumeMap)); -} - -VolumeMap::~VolumeMap() {} - -float VolumeMap::VolumeToDbFS(float volume) { - if (volume <= volume_map_[0].level) { - return volume_map_[0].db; - } - for (size_t i = 1; i < volume_map_.size(); ++i) { - if (volume < volume_map_[i].level) { - const float x_range = volume_map_[i].level - volume_map_[i - 1].level; - const float y_range = volume_map_[i].db - volume_map_[i - 1].db; - const float x_pos = volume - volume_map_[i - 1].level; - - return volume_map_[i - 1].db + x_pos * y_range / x_range; - } - } - return volume_map_[volume_map_.size() - 1].db; -} - -float VolumeMap::DbFSToVolume(float db) { - if (db <= volume_map_[0].db) { - return volume_map_[0].level; - } - for (size_t i = 1; i < volume_map_.size(); ++i) { - if (db < volume_map_[i].db) { - const float x_range = volume_map_[i].db - volume_map_[i - 1].db; - const float y_range = volume_map_[i].level - volume_map_[i - 1].level; - const float x_pos = db - volume_map_[i - 1].db; - - return volume_map_[i - 1].level + x_pos * y_range / x_range; - } - } - return volume_map_[volume_map_.size() - 1].level; -} - -VolumeControlAndroid::VolumeControlAndroid() - : thread_("VolumeControl"), - initialize_complete_event_( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED) { - DCHECK(j_volume_control_.is_null()); - j_volume_control_.Reset(Java_VolumeControl_createVolumeControl( - base::android::AttachCurrentThread(), reinterpret_cast<intptr_t>(this))); - - // Load volume map to check that the config file is correct. - g_volume_map.Get(); - - base::Thread::Options options; - options.message_loop_type = base::MessageLoop::TYPE_IO; - thread_.StartWithOptions(options); - - thread_.task_runner()->PostTask( - FROM_HERE, base::BindOnce(&VolumeControlAndroid::InitializeOnThread, - base::Unretained(this))); - initialize_complete_event_.Wait(); -} - -VolumeControlAndroid::~VolumeControlAndroid() {} - -// static -bool VolumeControlAndroid::RegisterJni(JNIEnv* env) { - return RegisterNativesImpl(env); -} void VolumeControlAndroid::AddVolumeObserver(VolumeObserver* observer) { base::AutoLock lock(observer_lock_);
diff --git a/chromecast/media/cma/backend/android/volume_control_android.h b/chromecast/media/cma/backend/android/volume_control_android.h index 88ba5d44..7acf754 100644 --- a/chromecast/media/cma/backend/android/volume_control_android.h +++ b/chromecast/media/cma/backend/android/volume_control_android.h
@@ -48,8 +48,6 @@ VolumeControlAndroid(); ~VolumeControlAndroid(); - static bool RegisterJni(JNIEnv* env); - void AddVolumeObserver(VolumeObserver* observer); void RemoveVolumeObserver(VolumeObserver* observer); float GetVolume(AudioContentType type);
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 0a18b78..7a5f53c 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -202,9 +202,6 @@ const char kDisableNetworkPortalNotification[] = "disable-network-portal-notification"; -// Disables new channel switcher UI. -const char kDisableNewChannelSwitcherUI[] = "disable-new-channel-switcher-ui"; - // Disables the new Korean IME in chrome://settings/languages. const char kDisableNewKoreanIme[] = "disable-new-korean-ime";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index 2ea91073..b2e05ac2 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -65,7 +65,6 @@ CHROMEOS_EXPORT extern const char kDisableMtpWriteSupport[]; CHROMEOS_EXPORT extern const char kDisableMultiDisplayLayout[]; CHROMEOS_EXPORT extern const char kDisableNetworkPortalNotification[]; -CHROMEOS_EXPORT extern const char kDisableNewChannelSwitcherUI[]; CHROMEOS_EXPORT extern const char kDisableNewKoreanIme[]; CHROMEOS_EXPORT extern const char kDisableNewZIPUnpacker[]; CHROMEOS_EXPORT extern const char kDisableOfficeEditingComponentApp[];
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc index d48c4b9..a1000d4 100644 --- a/chromeos/dbus/fake_shill_manager_client.cc +++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -1105,6 +1105,9 @@ FakeShillDeviceClient::kSimPinRetryCount); } shill_device_property_map_[shill::kTypeCellular] + [shill::kSIMPresentProperty] = + new base::Value(true); + shill_device_property_map_[shill::kTypeCellular] [shill::kSIMLockStatusProperty] = simlock_dict; shill_device_property_map_[shill::kTypeCellular] [shill::kTechnologyFamilyProperty] = @@ -1115,6 +1118,8 @@ base::Value* sim_present = new base::Value(present); shill_device_property_map_[shill::kTypeCellular] [shill::kSIMPresentProperty] = sim_present; + if (!present) + shill_initial_state_map_[shill::kTypeCellular] = kNetworkDisabled; return true; } else if (arg0 == "tdls_busy") { if (!arg1.empty())
diff --git a/chromeos/network/device_state.cc b/chromeos/network/device_state.cc index d42d7c6e..3f9cf50 100644 --- a/chromeos/network/device_state.cc +++ b/chromeos/network/device_state.cc
@@ -70,6 +70,7 @@ // Set default values for SIM properties. sim_lock_type_.erase(); sim_retries_left_ = 0; + sim_lock_enabled_ = false; const base::Value* out_value = nullptr; if (dict->GetWithoutPathExpansion(shill::kSIMLockTypeProperty, @@ -81,6 +82,11 @@ GetIntegerValue(shill::kSIMLockRetriesLeftProperty, *out_value, &sim_retries_left_); } + if (dict->GetWithoutPathExpansion(shill::kSIMLockEnabledProperty, + &out_value)) { + GetBooleanValue(shill::kSIMLockEnabledProperty, *out_value, + &sim_lock_enabled_); + } return true; } else if (key == shill::kMeidProperty) { return GetStringValue(key, value, &meid_);
diff --git a/chromeos/network/device_state.h b/chromeos/network/device_state.h index 13ae1eb..6d7f31f 100644 --- a/chromeos/network/device_state.h +++ b/chromeos/network/device_state.h
@@ -46,6 +46,7 @@ const std::string& carrier() const { return carrier_; } const std::string& sim_lock_type() const { return sim_lock_type_; } int sim_retries_left() const { return sim_retries_left_; } + bool sim_lock_enabled() const { return sim_lock_enabled_; } const std::string& meid() const { return meid_; } const std::string& imei() const { return imei_; } const std::string& iccid() const { return iccid_; } @@ -84,6 +85,7 @@ std::string carrier_; std::string sim_lock_type_; int sim_retries_left_; + bool sim_lock_enabled_; bool sim_present_; std::string meid_; std::string imei_;
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index 5708943..7d21140 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -47,8 +47,6 @@ "net/arc_net_host_impl.h", "obb_mounter/arc_obb_mounter_bridge.cc", "obb_mounter/arc_obb_mounter_bridge.h", - "oemcrypto/arc_oemcrypto_bridge.cc", - "oemcrypto/arc_oemcrypto_bridge.h", "power/arc_power_bridge.cc", "power/arc_power_bridge.h", "storage_manager/arc_storage_manager.cc",
diff --git a/components/history/core/browser/browsing_history_service.cc b/components/history/core/browser/browsing_history_service.cc index bd735ad..0596d86 100644 --- a/components/history/core/browser/browsing_history_service.cc +++ b/components/history/core/browser/browsing_history_service.cc
@@ -88,9 +88,6 @@ return entry1.time > entry2.time; } -BrowsingHistoryService::QueryResultsInfo::QueryResultsInfo() - : reached_beginning(false), has_synced_results(false) {} - BrowsingHistoryService::QueryResultsInfo::~QueryResultsInfo() {} BrowsingHistoryService::BrowsingHistoryService( @@ -148,6 +145,8 @@ void BrowsingHistoryService::WebHistoryTimeout() { has_synced_results_ = false; + query_results_info_.sync_timed_out = true; + // TODO(dubroy): Communicate the failure to the front end. if (!query_task_tracker_.HasTrackedTasks()) ReturnResultsToDriver(); @@ -162,9 +161,13 @@ // Anything in-flight is invalid. query_task_tracker_.TryCancelAll(); web_history_request_.reset(); - query_results_.clear(); + // TODO(skym): Should |query_results_info_| be reset to default values + // instead? + // Set this to false until the results actually arrive. + query_results_info_.has_synced_results = false; + if (local_history_) { local_history_->QueryHistory( search_text, options, @@ -173,11 +176,10 @@ &query_task_tracker_); } - WebHistoryService* web_history = driver_->GetWebHistoryService(); - // Set this to false until the results actually arrive. query_results_info_.has_synced_results = false; + WebHistoryService* web_history = driver_->GetWebHistoryService(); if (web_history) { web_history_query_results_.clear(); @@ -395,7 +397,7 @@ } query_results_info_.search_text = search_text; - query_results_info_.reached_beginning = results->reached_beginning(); + query_results_info_.reached_beginning_of_local = results->reached_beginning(); query_results_info_.start_time = options.begin_time; // TODO(skym): |end_time| doesn't seem to be used anymore, and this logic's // intention is very confusing. Consider removing. @@ -517,8 +519,17 @@ } } } + + query_results_info_.sync_timed_out = false; has_synced_results_ = results_value != nullptr; query_results_info_.has_synced_results = has_synced_results_; + + if (results_value) { + std::string continuation_token; + results_value->GetString("continuation_token", &continuation_token); + query_results_info_.reached_beginning_of_sync = continuation_token.empty(); + } + if (!query_task_tracker_.HasTrackedTasks()) ReturnResultsToDriver(); }
diff --git a/components/history/core/browser/browsing_history_service.h b/components/history/core/browser/browsing_history_service.h index 961acaa..a4c778bf 100644 --- a/components/history/core/browser/browsing_history_service.h +++ b/components/history/core/browser/browsing_history_service.h
@@ -107,17 +107,23 @@ // Contains information about a completed history query. struct QueryResultsInfo { - QueryResultsInfo(); ~QueryResultsInfo(); // The query search text. base::string16 search_text; - // Whether the query reached the beginning of the database. - bool reached_beginning; + // Whether the query reached the beginning of the local database. + bool reached_beginning_of_local = false; - // Whether the last call to Web History returned synced results. - bool has_synced_results; + // Whether the last call to Web History timed out. + bool sync_timed_out = false; + + // Whether the last call to Web History returned successfully with a message + // body. + bool has_synced_results = false; + + // Whether the query reached the beginning of the synced history results. + bool reached_beginning_of_sync = false; // The localized query start time. base::Time start_time; @@ -235,6 +241,8 @@ ScopedObserver<syncer::SyncService, syncer::SyncServiceObserver> sync_service_observer_; + // TODO(skym): Why is this duplicated between this field and + // |query_results_info_.has_synced_results|? Can we simplify? // Whether the last call to Web History returned synced results. bool has_synced_results_;
diff --git a/components/history/core/browser/browsing_history_service_unittest.cc b/components/history/core/browser/browsing_history_service_unittest.cc index f834080..f1873637 100644 --- a/components/history/core/browser/browsing_history_service_unittest.cc +++ b/components/history/core/browser/browsing_history_service_unittest.cc
@@ -241,12 +241,17 @@ return *all_results.rbegin(); } - void VerifyQueryResult(bool reached_beginning, + void VerifyQueryResult(bool reached_beginning_of_local, bool has_synced_results, + bool reached_beginning_of_sync, const std::vector<TestResult>& expected_entries, TestBrowsingHistoryDriver::QueryResult result) { - EXPECT_EQ(reached_beginning, result.second.reached_beginning); + EXPECT_EQ(reached_beginning_of_local, + result.second.reached_beginning_of_local); EXPECT_EQ(has_synced_results, result.second.has_synced_results); + EXPECT_FALSE(result.second.sync_timed_out); + EXPECT_EQ(reached_beginning_of_sync, + result.second.reached_beginning_of_sync); EXPECT_EQ(expected_entries.size(), result.first.size()); for (size_t i = 0; i < expected_entries.size(); ++i) { VerifyEntry(expected_entries[i], result.first[i]); @@ -254,14 +259,15 @@ } void QueryAndVerifySingleQueryResult( - bool reached_beginning, + bool reached_beginning_of_local, bool has_synced_results, + bool reached_beginning_of_sync, const std::vector<TestResult>& expected_entries) { EXPECT_EQ(0U, driver()->GetQueryResults().size()); TestBrowsingHistoryDriver::QueryResult result = QueryHistory(QueryOptions()); - VerifyQueryResult(reached_beginning, has_synced_results, expected_entries, - result); + VerifyQueryResult(reached_beginning_of_local, has_synced_results, + reached_beginning_of_sync, expected_entries, result); } HistoryService* local_history() { return local_history_.get(); } @@ -382,45 +388,52 @@ TEST_F(BrowsingHistoryServiceTest, EmptyQueryHistoryJustLocal) { driver()->SetWebHistory(nullptr); ResetService(driver(), local_history(), nullptr); - QueryAndVerifySingleQueryResult(/*reached_beginning*/ true, - /*has_synced_results*/ false, {}); + QueryAndVerifySingleQueryResult(/*reached_beginning_of_local*/ true, + /*has_synced_results*/ false, + /*reached_beginning_of_sync*/ false, {}); } TEST_F(BrowsingHistoryServiceTest, QueryHistoryJustLocal) { driver()->SetWebHistory(nullptr); ResetService(driver(), local_history(), nullptr); + AddHistory({{kUrl1, 1, kLocal}}); - QueryAndVerifySingleQueryResult(/*reached_beginning*/ true, + QueryAndVerifySingleQueryResult(/*reached_beginning_of_local*/ true, /*has_synced_results*/ false, + /*reached_beginning_of_sync*/ false, {{kUrl1, 1, kLocal}}); } TEST_F(BrowsingHistoryServiceTest, EmptyQueryHistoryJustWeb) { ResetService(driver(), nullptr, nullptr); - QueryAndVerifySingleQueryResult(/*reached_beginning*/ false, - /*has_synced_results*/ true, {}); + QueryAndVerifySingleQueryResult(/*reached_beginning_of_local*/ false, + /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {}); } TEST_F(BrowsingHistoryServiceTest, EmptyQueryHistoryDelayedWeb) { driver()->SetWebHistory(nullptr); ResetService(driver(), nullptr, sync()); driver()->SetWebHistory(web_history()); - QueryAndVerifySingleQueryResult(/*reached_beginning*/ false, - /*has_synced_results*/ true, {}); + QueryAndVerifySingleQueryResult(/*reached_beginning_of_local*/ false, + /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {}); } TEST_F(BrowsingHistoryServiceTest, QueryHistoryJustWeb) { ResetService(driver(), nullptr, sync()); AddHistory({{kUrl1, 1, kRemote}}); - QueryAndVerifySingleQueryResult(/*reached_beginning*/ false, + QueryAndVerifySingleQueryResult(/*reached_beginning_of_local*/ false, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {{kUrl1, 1, kRemote}}); } TEST_F(BrowsingHistoryServiceTest, EmptyQueryHistoryBothSources) { ResetService(driver(), local_history(), sync()); - QueryAndVerifySingleQueryResult(/*reached_beginning*/ true, - /*has_synced_results*/ true, {}); + QueryAndVerifySingleQueryResult(/*reached_beginning_of_local*/ true, + /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {}); } TEST_F(BrowsingHistoryServiceTest, QueryHistoryAllSources) { @@ -430,7 +443,8 @@ {kUrl3, 3, kRemote}, {kUrl1, 4, kRemote}}); QueryAndVerifySingleQueryResult( - /*reached_beginning*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_local*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {{kUrl1, 4, kBoth}, {kUrl3, 3, kRemote}, {kUrl2, 2, kLocal}}); } @@ -442,12 +456,14 @@ QueryOptions options; options.begin_time = OffsetToTime(2); options.end_time = OffsetToTime(4); - // Having a |reached_beginning| value of false here seems counterintuitive. - // Seems to be for paging by |begin_time| instead of |count|. If the local - // history implementation changes, feel free to update this value, all this - // test cares about is that BrowsingHistoryService passes the values through - // correctly. - VerifyQueryResult(/*reached_beginning*/ false, /*has_synced_results*/ true, + // Having a |reached_beginning_of_local| value of false here seems + // counterintuitive. Seems to be for paging by |begin_time| instead of + // |count|. If the local history implementation changes, feel free to update + // this value, all this test cares about is that BrowsingHistoryService passes + // the values through correctly. + VerifyQueryResult(/*reached_beginning_of_local*/ false, + /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {{kUrl3, 3, kLocal}, {kUrl2, 2, kLocal}}, QueryHistory(options)); } @@ -460,9 +476,10 @@ QueryOptions options; options.begin_time = OffsetToTime(2); options.end_time = OffsetToTime(4); - VerifyQueryResult(/*reached_beginning*/ true, /*has_synced_results*/ true, - {{kUrl3, 3, kRemote}, {kUrl2, 2, kRemote}}, - QueryHistory(options)); + VerifyQueryResult( + /*reached_beginning_of_local*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, + {{kUrl3, 3, kRemote}, {kUrl2, 2, kRemote}}, QueryHistory(options)); } TEST_F(BrowsingHistoryServiceTest, QueryHistoryLocalPaging) { @@ -470,28 +487,62 @@ QueryOptions options; options.max_count = 2; - VerifyQueryResult(/*reached_beginning*/ false, /*has_synced_results*/ true, + VerifyQueryResult(/*reached_beginning_of_local*/ false, + /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {{kUrl3, 3, kLocal}, {kUrl2, 2, kLocal}}, QueryHistory(options)); options.end_time = OffsetToTime(2); - VerifyQueryResult(/*reached_beginning*/ true, /*has_synced_results*/ true, - {{kUrl1, 1, kLocal}}, QueryHistory(options)); + VerifyQueryResult( + /*reached_beginning_of_local*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {{kUrl1, 1, kLocal}}, + QueryHistory(options)); options.end_time = Time(); options.max_count = 3; VerifyQueryResult( - /*reached_beginning*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_local*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {{kUrl3, 3, kLocal}, {kUrl2, 2, kLocal}, {kUrl1, 1, kLocal}}, QueryHistory(options)); options.end_time = OffsetToTime(1); - VerifyQueryResult(/*reached_beginning*/ true, /*has_synced_results*/ true, {}, - QueryHistory(options)); + VerifyQueryResult( + /*reached_beginning_of_local*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {}, QueryHistory(options)); } -// TODO(skym, crbug.com/756097): When the concept of reaching end of sync -// results is added, add tests that verify this works correctly. +TEST_F(BrowsingHistoryServiceTest, QueryHistoryRemotePaging) { + AddHistory({{kUrl1, 1, kRemote}, {kUrl2, 2, kRemote}, {kUrl3, 3, kRemote}}); + + QueryOptions options; + options.max_count = 2; + VerifyQueryResult(/*reached_beginning_of_local*/ true, + /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ false, + {{kUrl3, 3, kRemote}, {kUrl2, 2, kRemote}}, + QueryHistory(options)); + + options.end_time = OffsetToTime(2); + VerifyQueryResult( + /*reached_beginning_of_local*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {{kUrl1, 1, kRemote}}, + QueryHistory(options)); + + options.end_time = Time(); + options.max_count = 3; + VerifyQueryResult( + /*reached_beginning_of_local*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, + {{kUrl3, 3, kRemote}, {kUrl2, 2, kRemote}, {kUrl1, 1, kRemote}}, + QueryHistory(options)); + + options.end_time = OffsetToTime(1); + VerifyQueryResult( + /*reached_beginning_of_local*/ true, /*has_synced_results*/ true, + /*reached_beginning_of_sync*/ true, {}, QueryHistory(options)); +} // TODO(skym, crbug.com/728727): Add more test cases, particularly when // QueryHistory returns partial results and sequential calls are made.
diff --git a/components/safe_browsing/features.cc b/components/safe_browsing/features.cc index f2e708ea..f929d01 100644 --- a/components/safe_browsing/features.cc +++ b/components/safe_browsing/features.cc
@@ -54,6 +54,10 @@ const base::Feature kThreatDomDetailsTagAndAttributeFeature{ "ThreatDomDetailsTagAttributes", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kTriggerThrottlerDailyQuotaFeature{ + "SafeBrowsingTriggerThrottlerDailyQuota", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kV4OnlyEnabled{"SafeBrowsingV4OnlyEnabled", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -75,6 +79,7 @@ {&kPasswordProtectionInterstitial, false}, {&kProtectedPasswordEntryPinging, true}, {&kThreatDomDetailsTagAndAttributeFeature, false}, + {&kTriggerThrottlerDailyQuotaFeature, false}, {&kV4OnlyEnabled, true}, };
diff --git a/components/safe_browsing/features.h b/components/safe_browsing/features.h index 7d3cea8c..f4c0bbc 100644 --- a/components/safe_browsing/features.h +++ b/components/safe_browsing/features.h
@@ -28,6 +28,7 @@ extern const base::Feature kPasswordFieldOnFocusPinging; extern const base::Feature kPasswordProtectionInterstitial; extern const base::Feature kProtectedPasswordEntryPinging; + // Specifies which non-resource HTML Elements to collect based on their tag and // attributes. It's a single param containing a comma-separated list of pairs. // For example: "tag1,id,tag1,height,tag2,foo" - this will collect elements with @@ -35,6 +36,13 @@ // "tag2" if they have attribute "foo" set. All tag names and attributes should // be lower case. extern const base::Feature kThreatDomDetailsTagAndAttributeFeature; + +// Controls the daily quota for data collection triggers. It's a single param +// containing a comma-separated list of pairs. The format of the param is +// "T1,Q1,T2,Q2,...Tn,Qn", where Tx is a TriggerType and Qx is how many reports +// that trigger is allowed to send per day. +extern const base::Feature kTriggerThrottlerDailyQuotaFeature; + extern const base::Feature kV4OnlyEnabled; base::ListValue GetFeatureStatusList();
diff --git a/components/safe_browsing/triggers/BUILD.gn b/components/safe_browsing/triggers/BUILD.gn index be02b24c9..c591384e 100644 --- a/components/safe_browsing/triggers/BUILD.gn +++ b/components/safe_browsing/triggers/BUILD.gn
@@ -31,6 +31,7 @@ ] deps = [ "//base:base", + "//components/safe_browsing:features", ] }
diff --git a/components/safe_browsing/triggers/trigger_throttler.cc b/components/safe_browsing/triggers/trigger_throttler.cc index ba2a6ca6..bc55854 100644 --- a/components/safe_browsing/triggers/trigger_throttler.cc +++ b/components/safe_browsing/triggers/trigger_throttler.cc
@@ -4,36 +4,114 @@ #include "components/safe_browsing/triggers/trigger_throttler.h" +#include "base/metrics/field_trial_params.h" #include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/time/default_clock.h" #include "base/time/time.h" +#include "components/safe_browsing/features.h" namespace safe_browsing { +const char kTriggerTypeAndQuotaParam[] = "trigger_type_and_quota_csv"; namespace { const size_t kUnlimitedTriggerQuota = std::numeric_limits<size_t>::max(); constexpr base::TimeDelta kOneDayTimeDelta = base::TimeDelta::FromDays(1); -size_t GetDailyQuotaForTrigger(const TriggerType trigger_type) { +// Predicate used to search |trigger_type_and_quota_list_| by trigger type. +class TriggerTypeIs { + public: + explicit TriggerTypeIs(const TriggerType type) : type_(type) {} + bool operator()(const TriggerTypeAndQuotaItem& trigger_type_and_quota) { + return type_ == trigger_type_and_quota.first; + } + + private: + TriggerType type_; +}; + +void ParseTriggerTypeAndQuotaParam( + std::vector<TriggerTypeAndQuotaItem>* trigger_type_and_quota_list) { + DCHECK(trigger_type_and_quota_list); + // If the feature is disabled we just use the default list. Otherwise the list + // from the Finch param will be the one used. + if (!base::FeatureList::IsEnabled(kTriggerThrottlerDailyQuotaFeature)) { + return; + } + + trigger_type_and_quota_list->clear(); + const std::string& trigger_and_quota_csv_param = + base::GetFieldTrialParamValueByFeature(kTriggerThrottlerDailyQuotaFeature, + kTriggerTypeAndQuotaParam); + if (trigger_and_quota_csv_param.empty()) { + return; + } + + std::vector<std::string> split = + base::SplitString(trigger_and_quota_csv_param, ",", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + // If we don't have the right number of pairs in the csv then don't bother + // parsing further. + if (split.size() % 2 != 0) { + return; + } + for (size_t i = 0; i < split.size(); i += 2) { + // Make sure both the trigger type and quota are integers. Skip them if not. + int trigger_type_int = -1; + int quota_int = -1; + if (!base::StringToInt(split[i], &trigger_type_int) || + !base::StringToInt(split[i + 1], "a_int)) { + continue; + } + trigger_type_and_quota_list->push_back( + std::make_pair(static_cast<TriggerType>(trigger_type_int), quota_int)); + } + + std::sort(trigger_type_and_quota_list->begin(), + trigger_type_and_quota_list->end(), + [](const TriggerTypeAndQuotaItem& a, + const TriggerTypeAndQuotaItem& b) { return a.first < b.first; }); +} + +size_t GetDailyQuotaForTrigger( + const TriggerType trigger_type, + const std::vector<TriggerTypeAndQuotaItem>& trigger_quota_list) { switch (trigger_type) { case TriggerType::SECURITY_INTERSTITIAL: return kUnlimitedTriggerQuota; case TriggerType::AD_SAMPLE: - // TODO(lpz): Introduce a finch param to configure quota per-trigger-type. - return 0; + // These triggers have quota configured via Finch, lookup the value in + // |trigger_quota_list|. + const auto& trigger_quota_iter = + std::find_if(trigger_quota_list.begin(), trigger_quota_list.end(), + TriggerTypeIs(trigger_type)); + if (trigger_quota_iter != trigger_quota_list.end()) + return trigger_quota_iter->second; + + break; } - // By default, unhandled trigger types have no quota. + // By default, unhandled or unconfigured trigger types have no quota. return 0; } } // namespace -TriggerThrottler::TriggerThrottler() {} +TriggerThrottler::TriggerThrottler() : clock_(new base::DefaultClock()) { + ParseTriggerTypeAndQuotaParam(&trigger_type_and_quota_list_); +} TriggerThrottler::~TriggerThrottler() {} +void TriggerThrottler::SetClockForTesting( + std::unique_ptr<base::Clock> test_clock) { + clock_ = std::move(test_clock); +} + bool TriggerThrottler::TriggerCanFire(const TriggerType trigger_type) const { // Lookup how many times this trigger is allowed to fire each day. - const size_t trigger_quota = GetDailyQuotaForTrigger(trigger_type); + const size_t trigger_quota = + GetDailyQuotaForTrigger(trigger_type, trigger_type_and_quota_list_); // Some basic corner cases for triggers that always fire, or disabled // triggers that never fire. @@ -52,18 +130,19 @@ if (trigger_quota > timestamps.size()) return true; - // Otherwise, we have more events than quota, check which day they occured on. - // Newest events are at the end of vector so we can simply look at the + // Otherwise, we have more events than quota, check which day they occurred + // on. Newest events are at the end of vector so we can simply look at the // Nth-from-last entry (where N is the quota) to see if it happened within // the current day or earlier. - base::Time min_timestamp = base::Time::Now() - kOneDayTimeDelta; + base::Time min_timestamp = clock_->Now() - kOneDayTimeDelta; const size_t pos = timestamps.size() - trigger_quota + 1; return timestamps[pos] < min_timestamp.ToTimeT(); } void TriggerThrottler::TriggerFired(const TriggerType trigger_type) { // Lookup how many times this trigger is allowed to fire each day. - const size_t trigger_quota = GetDailyQuotaForTrigger(trigger_type); + const size_t trigger_quota = + GetDailyQuotaForTrigger(trigger_type, trigger_type_and_quota_list_); // For triggers that always fire, don't bother tracking quota. if (trigger_quota == kUnlimitedTriggerQuota) @@ -71,7 +150,7 @@ // Otherwise, record that the trigger fired. std::vector<time_t>* timestamps = &trigger_events_[trigger_type]; - timestamps->push_back(base::Time::Now().ToTimeT()); + timestamps->push_back(clock_->Now().ToTimeT()); // Clean up the trigger events map. CleanupOldEvents(); @@ -80,7 +159,8 @@ void TriggerThrottler::CleanupOldEvents() { for (const auto& map_iter : trigger_events_) { const TriggerType trigger_type = map_iter.first; - const size_t trigger_quota = GetDailyQuotaForTrigger(trigger_type); + const size_t trigger_quota = + GetDailyQuotaForTrigger(trigger_type, trigger_type_and_quota_list_); const std::vector<time_t>& trigger_times = map_iter.second; // Skip the cleanup if we have quota room, quotas should generally be small. @@ -88,7 +168,7 @@ return; std::vector<time_t> tmp_trigger_times; - base::Time min_timestamp = base::Time::Now() - kOneDayTimeDelta; + base::Time min_timestamp = clock_->Now() - kOneDayTimeDelta; // Go over the event times for this trigger and keep timestamps which are // newer than |min_timestamp|. We put timestamps in a temp vector that will // get swapped into the map in place of the existing vector.
diff --git a/components/safe_browsing/triggers/trigger_throttler.h b/components/safe_browsing/triggers/trigger_throttler.h index 405a66b4..f4746d7 100644 --- a/components/safe_browsing/triggers/trigger_throttler.h +++ b/components/safe_browsing/triggers/trigger_throttler.h
@@ -5,14 +5,19 @@ #ifndef COMPONENTS_SAFE_BROWSING_TRIGGERS_TRIGGER_THROTTLER_H_ #define COMPONENTS_SAFE_BROWSING_TRIGGERS_TRIGGER_THROTTLER_H_ +#include <memory> #include <unordered_map> #include <vector> #include "base/macros.h" -#include "base/time/time.h" +#include "base/time/clock.h" namespace safe_browsing { +// Param name of the finch param containing the comma-separated list of trigger +// types and daily quotas. +extern const char kTriggerTypeAndQuotaParam[]; + enum class TriggerType { SECURITY_INTERSTITIAL = 1, AD_SAMPLE = 2, @@ -28,6 +33,9 @@ using TriggerTimestampMap = std::unordered_map<TriggerType, std::vector<time_t>, TriggerTypeHash>; +// A pair containing a TriggerType and its associated daily report quota. +using TriggerTypeAndQuotaItem = std::pair<TriggerType, int>; + // TriggerThrottler keeps track of how often each type of trigger gets fired // and throttles them if they fire too often. class TriggerThrottler { @@ -43,14 +51,26 @@ // should be updated. void TriggerFired(TriggerType trigger_type); + protected: + void SetClockForTesting(std::unique_ptr<base::Clock> test_clock); + private: + friend class TriggerThrottlerTest; + // Called to periodically clean-up the list of event timestamps. void CleanupOldEvents(); + // Can be set for testing. + std::unique_ptr<base::Clock> clock_; + // Stores each trigger type that fired along with the timestamps of when it // fired. TriggerTimestampMap trigger_events_; + // List of trigger types and their quotas, controlled by Finch feature + // |kTriggerThrottlerDailyQuotaFeature|. + std::vector<TriggerTypeAndQuotaItem> trigger_type_and_quota_list_; + DISALLOW_COPY_AND_ASSIGN(TriggerThrottler); };
diff --git a/components/safe_browsing/triggers/trigger_throttler_unittest.cc b/components/safe_browsing/triggers/trigger_throttler_unittest.cc index 1b01e72..b489bb1 100644 --- a/components/safe_browsing/triggers/trigger_throttler_unittest.cc +++ b/components/safe_browsing/triggers/trigger_throttler_unittest.cc
@@ -4,19 +4,154 @@ #include "components/safe_browsing/triggers/trigger_throttler.h" +#include "base/metrics/field_trial_params.h" +#include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/simple_test_clock.h" +#include "components/safe_browsing/features.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace safe_browsing { -namespace { +using testing::ElementsAre; -TEST(TriggerThrottler, SecurityInterstitialsHaveUnlimitedQuota) { +namespace safe_browsing { + +class TriggerThrottlerTest : public ::testing::Test { + public: + void SetQuotaForTriggerType(TriggerType trigger_type, size_t max_quota) { + trigger_throttler_.trigger_type_and_quota_list_.push_back( + std::make_pair(trigger_type, max_quota)); + } + + TriggerThrottler* throttler() { return &trigger_throttler_; } + + void SetTestClock(base::Clock* clock) { + trigger_throttler_.SetClockForTesting(base::WrapUnique(clock)); + } + + std::vector<time_t> GetEventTimestampsForTriggerType( + TriggerType trigger_type) { + return trigger_throttler_.trigger_events_[trigger_type]; + } + + private: + TriggerThrottler trigger_throttler_; +}; + +TEST_F(TriggerThrottlerTest, SecurityInterstitialsHaveUnlimitedQuota) { // Make sure that security interstitials never run out of quota. - TriggerThrottler throttler; for (int i = 0; i < 1000; ++i) { - throttler.TriggerFired(TriggerType::SECURITY_INTERSTITIAL); - EXPECT_TRUE(throttler.TriggerCanFire(TriggerType::SECURITY_INTERSTITIAL)); + throttler()->TriggerFired(TriggerType::SECURITY_INTERSTITIAL); + EXPECT_TRUE( + throttler()->TriggerCanFire(TriggerType::SECURITY_INTERSTITIAL)); } } -} // namespace +TEST_F(TriggerThrottlerTest, SecurityInterstitialQuotaCanNotBeOverwritten) { + // Make sure that security interstitials never run out of quota, even if we + // try to configure quota for this trigger type. + SetQuotaForTriggerType(TriggerType::SECURITY_INTERSTITIAL, 3); + for (int i = 0; i < 1000; ++i) { + throttler()->TriggerFired(TriggerType::SECURITY_INTERSTITIAL); + EXPECT_TRUE( + throttler()->TriggerCanFire(TriggerType::SECURITY_INTERSTITIAL)); + } +} + +TEST_F(TriggerThrottlerTest, TriggerExceedsQuota) { + // Ensure that a trigger can't fire more than its quota allows. + SetQuotaForTriggerType(TriggerType::AD_SAMPLE, 2); + + // First two triggers should work + EXPECT_TRUE(throttler()->TriggerCanFire(TriggerType::AD_SAMPLE)); + throttler()->TriggerFired(TriggerType::AD_SAMPLE); + EXPECT_TRUE(throttler()->TriggerCanFire(TriggerType::AD_SAMPLE)); + throttler()->TriggerFired(TriggerType::AD_SAMPLE); + + // Third attempt will fail since we're out of quota. + EXPECT_FALSE(throttler()->TriggerCanFire(TriggerType::AD_SAMPLE)); +} + +TEST_F(TriggerThrottlerTest, TriggerQuotaResetsAfterOneDay) { + // Ensure that trigger events older than a day are cleaned up and triggers can + // resume firing. + + // We initialize the test clock to several days ago and fire some events to + // use up quota. We then advance the clock by a day and ensure quota is + // available again. + base::SimpleTestClock* test_clock(new base::SimpleTestClock); + test_clock->SetNow(base::Time::Now() - base::TimeDelta::FromDays(10)); + time_t base_ts = test_clock->Now().ToTimeT(); + + SetTestClock(test_clock); + SetQuotaForTriggerType(TriggerType::AD_SAMPLE, 2); + + // First two triggers should work + EXPECT_TRUE(throttler()->TriggerCanFire(TriggerType::AD_SAMPLE)); + throttler()->TriggerFired(TriggerType::AD_SAMPLE); + EXPECT_TRUE(throttler()->TriggerCanFire(TriggerType::AD_SAMPLE)); + throttler()->TriggerFired(TriggerType::AD_SAMPLE); + + // Third attempt will fail since we're out of quota. + EXPECT_FALSE(throttler()->TriggerCanFire(TriggerType::AD_SAMPLE)); + + // Also confirm that the throttler contains two event timestamps for the above + // two events - since we use a test clock, it doesn't move unless we tell it + // to. + EXPECT_THAT(GetEventTimestampsForTriggerType(TriggerType::AD_SAMPLE), + ElementsAre(base_ts, base_ts)); + + // Move the clock forward by 1 day (and a bit) and try the trigger again, + // quota should be available now. + test_clock->Advance(base::TimeDelta::FromDays(1) + + base::TimeDelta::FromSeconds(1)); + time_t advanced_ts = test_clock->Now().ToTimeT(); + EXPECT_TRUE(throttler()->TriggerCanFire(TriggerType::AD_SAMPLE)); + + // The previous time stamps should remain in the throttler. + EXPECT_THAT(GetEventTimestampsForTriggerType(TriggerType::AD_SAMPLE), + ElementsAre(base_ts, base_ts)); + + // Firing the trigger will clean up the expired timestamps and insert the new + // timestamp. + throttler()->TriggerFired(TriggerType::AD_SAMPLE); + EXPECT_THAT(GetEventTimestampsForTriggerType(TriggerType::AD_SAMPLE), + ElementsAre(advanced_ts)); +} + +TEST(TriggerThrottlerTestFinch, ConfigureQuotaViaFinch) { + // Make sure that setting the quota param via Finch params works as expected. + base::FieldTrialList field_trial_list(nullptr); + base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial( + safe_browsing::kTriggerThrottlerDailyQuotaFeature.name, "Group"); + std::map<std::string, std::string> feature_params; + feature_params[std::string(safe_browsing::kTriggerTypeAndQuotaParam)] = + base::StringPrintf("%d,%d", TriggerType::AD_SAMPLE, 3); + base::AssociateFieldTrialParams( + safe_browsing::kTriggerThrottlerDailyQuotaFeature.name, "Group", + feature_params); + std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); + feature_list->InitializeFromCommandLine( + safe_browsing::kTriggerThrottlerDailyQuotaFeature.name, std::string()); + feature_list->AssociateReportingFieldTrial( + safe_browsing::kTriggerThrottlerDailyQuotaFeature.name, + base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial); + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatureList(std::move(feature_list)); + + // The throttler has been configured (above) to allow ad samples to fire three + // times per day. + TriggerThrottler throttler; + + // First three triggers should work + EXPECT_TRUE(throttler.TriggerCanFire(TriggerType::AD_SAMPLE)); + throttler.TriggerFired(TriggerType::AD_SAMPLE); + EXPECT_TRUE(throttler.TriggerCanFire(TriggerType::AD_SAMPLE)); + throttler.TriggerFired(TriggerType::AD_SAMPLE); + EXPECT_TRUE(throttler.TriggerCanFire(TriggerType::AD_SAMPLE)); + throttler.TriggerFired(TriggerType::AD_SAMPLE); + + // Fourth attempt will fail since we're out of quota. + EXPECT_FALSE(throttler.TriggerCanFire(TriggerType::AD_SAMPLE)); +} } // namespace safe_browsing
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 4d5042db..b5a2806c 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -745,6 +745,8 @@ "frame_host/frame_tree_node.h", "frame_host/frame_tree_node_blame_context.cc", "frame_host/frame_tree_node_blame_context.h", + "frame_host/input/input_injector_impl.cc", + "frame_host/input/input_injector_impl.h", "frame_host/input/legacy_ipc_frame_input_handler.cc", "frame_host/input/legacy_ipc_frame_input_handler.h", "frame_host/interstitial_page_impl.cc",
diff --git a/content/browser/android/dialog_overlay_impl.cc b/content/browser/android/dialog_overlay_impl.cc index 29271e2..b6a6368b 100644 --- a/content/browser/android/dialog_overlay_impl.cc +++ b/content/browser/android/dialog_overlay_impl.cc
@@ -73,10 +73,17 @@ const JavaParamRef<jobject>& obj) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + WebContentsDelegate* delegate = web_contents()->GetDelegate(); + + if (!delegate) { + Stop(); + return; + } + // Note: It's ok to call SetOverlayMode() directly here, because there can be // at most one overlay alive at the time. This logic needs to be updated if // ever AndroidOverlayProviderImpl.MAX_OVERLAYS > 1. - web_contents()->GetDelegate()->SetOverlayMode(true); + delegate->SetOverlayMode(true); // Send the initial token, if there is one. The observer will notify us about // changes only. @@ -134,7 +141,9 @@ // We clear overlay mode here rather than in Destroy(), because we may have // been called via a WebContentsDestroyed() event, and this might be the last // opportunity we have to access web_contents(). - web_contents()->GetDelegate()->SetOverlayMode(false); + WebContentsDelegate* delegate = web_contents()->GetDelegate(); + if (delegate) + delegate->SetOverlayMode(false); cvc_->RemoveObserver(this); cvc_ = nullptr;
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc index 26d257aa..7576665 100644 --- a/content/browser/frame_host/cross_process_frame_connector.cc +++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -78,6 +78,7 @@ view_->SetFrameConnectorDelegate(nullptr); } + ResetFrameRect(); view_ = view; // Attach ourselves to the new view and size it appropriately. Also update @@ -88,6 +89,8 @@ SetRect(child_frame_rect_); if (is_hidden_) OnVisibilityChanged(false); + frame_proxy_in_parent_renderer_->Send(new FrameMsg_ViewChanged( + frame_proxy_in_parent_renderer_->GetRoutingID())); } } @@ -267,7 +270,9 @@ } void CrossProcessFrameConnector::OnFrameRectChanged( - const gfx::Rect& frame_rect) { + const gfx::Rect& frame_rect, + const viz::LocalSurfaceId& local_surface_id) { + local_surface_id_ = local_surface_id; if (!frame_rect.size().IsEmpty()) SetRect(frame_rect); } @@ -392,4 +397,9 @@ ->SetVisibilityForChildViews(visible); } +void CrossProcessFrameConnector::ResetFrameRect() { + local_surface_id_ = viz::LocalSurfaceId(); + child_frame_rect_ = gfx::Rect(); +} + } // namespace content
diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h index c14b061..43468081 100644 --- a/content/browser/frame_host/cross_process_frame_connector.h +++ b/content/browser/frame_host/cross_process_frame_connector.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include "cc/output/compositor_frame.h" +#include "components/viz/common/surfaces/local_surface_id.h" #include "content/browser/renderer_host/frame_connector_delegate.h" #include "content/common/content_export.h" @@ -111,8 +112,13 @@ private: friend class MockCrossProcessFrameConnector; + // Resets the rect and the viz::LocalSurfaceId of the connector to ensure the + // unguessable surface ID is not reused after a cross-process navigation. + void ResetFrameRect(); + // Handlers for messages received from the parent frame. - void OnFrameRectChanged(const gfx::Rect& frame_rect); + void OnFrameRectChanged(const gfx::Rect& frame_rect, + const viz::LocalSurfaceId& local_surface_id); void OnUpdateViewportIntersection(const gfx::Rect& viewport_intersection); void OnVisibilityChanged(bool visible); void OnSetIsInert(bool);
diff --git a/content/browser/frame_host/input/input_injector_impl.cc b/content/browser/frame_host/input/input_injector_impl.cc new file mode 100644 index 0000000..cf14431c --- /dev/null +++ b/content/browser/frame_host/input/input_injector_impl.cc
@@ -0,0 +1,82 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/frame_host/input/input_injector_impl.h" + +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "mojo/public/cpp/bindings/strong_binding.h" + +namespace content { + +namespace { + +void SyntheticGestureCallback(base::OnceClosure callback, + SyntheticGesture::Result result) { + std::move(callback).Run(); +} + +} // namespace + +InputInjectorImpl::InputInjectorImpl( + base::WeakPtr<RenderFrameHostImpl> frame_host) + : frame_host_(std::move(frame_host)) {} + +InputInjectorImpl::~InputInjectorImpl() {} + +void InputInjectorImpl::Create(base::WeakPtr<RenderFrameHostImpl> frame_host, + mojom::InputInjectorRequest request) { + mojo::MakeStrongBinding(base::MakeUnique<InputInjectorImpl>(frame_host), + std::move(request)); +} + +void InputInjectorImpl::QueueSyntheticSmoothDrag( + const SyntheticSmoothDragGestureParams& drag, + QueueSyntheticSmoothDragCallback callback) { + if (!frame_host_) + return; + frame_host_->GetRenderWidgetHost()->QueueSyntheticGesture( + SyntheticGesture::Create(drag), + base::BindOnce(SyntheticGestureCallback, std::move(callback))); +} + +void InputInjectorImpl::QueueSyntheticSmoothScroll( + const SyntheticSmoothScrollGestureParams& scroll, + QueueSyntheticSmoothScrollCallback callback) { + if (!frame_host_) + return; + frame_host_->GetRenderWidgetHost()->QueueSyntheticGesture( + SyntheticGesture::Create(scroll), + base::BindOnce(SyntheticGestureCallback, std::move(callback))); +} + +void InputInjectorImpl::QueueSyntheticPinch( + const SyntheticPinchGestureParams& pinch, + QueueSyntheticPinchCallback callback) { + if (!frame_host_) + return; + frame_host_->GetRenderWidgetHost()->QueueSyntheticGesture( + SyntheticGesture::Create(pinch), + base::BindOnce(SyntheticGestureCallback, std::move(callback))); +} + +void InputInjectorImpl::QueueSyntheticTap(const SyntheticTapGestureParams& tap, + QueueSyntheticTapCallback callback) { + if (!frame_host_) + return; + frame_host_->GetRenderWidgetHost()->QueueSyntheticGesture( + SyntheticGesture::Create(tap), + base::BindOnce(SyntheticGestureCallback, std::move(callback))); +} + +void InputInjectorImpl::QueueSyntheticPointerAction( + const SyntheticPointerActionListParams& pointer_action, + QueueSyntheticPointerActionCallback callback) { + if (!frame_host_) + return; + frame_host_->GetRenderWidgetHost()->QueueSyntheticGesture( + SyntheticGesture::Create(pointer_action), + base::BindOnce(SyntheticGestureCallback, std::move(callback))); +} + +} // namespace content
diff --git a/content/browser/frame_host/input/input_injector_impl.h b/content/browser/frame_host/input/input_injector_impl.h new file mode 100644 index 0000000..4928854 --- /dev/null +++ b/content/browser/frame_host/input/input_injector_impl.h
@@ -0,0 +1,45 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_FRAME_HOST_INPUT_INPUT_INJECTOR_IMPL_H_ +#define CONTENT_BROWSER_FRAME_HOST_INPUT_INPUT_INJECTOR_IMPL_H_ + +#include "content/browser/frame_host/render_frame_host_impl.h" +#include "content/common/input/input_injector.mojom.h" + +namespace content { + +// An implementation of InputInjector. +class CONTENT_EXPORT InputInjectorImpl : public mojom::InputInjector { + public: + explicit InputInjectorImpl(base::WeakPtr<RenderFrameHostImpl> frame_host); + ~InputInjectorImpl() override; + + static void Create(base::WeakPtr<RenderFrameHostImpl> frame_host, + mojom::InputInjectorRequest request); + + // mojom::InputInjector overrides. + void QueueSyntheticSmoothDrag( + const SyntheticSmoothDragGestureParams& drag, + QueueSyntheticSmoothDragCallback callback) override; + void QueueSyntheticSmoothScroll( + const SyntheticSmoothScrollGestureParams& scroll, + QueueSyntheticSmoothScrollCallback callback) override; + void QueueSyntheticPinch(const SyntheticPinchGestureParams& pinch, + QueueSyntheticPinchCallback callback) override; + void QueueSyntheticTap(const SyntheticTapGestureParams& tap, + QueueSyntheticTapCallback callback) override; + void QueueSyntheticPointerAction( + const SyntheticPointerActionListParams& pointer_action, + QueueSyntheticPointerActionCallback callback) override; + + private: + base::WeakPtr<RenderFrameHostImpl> frame_host_; + + DISALLOW_COPY_AND_ASSIGN(InputInjectorImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_FRAME_HOST_INPUT_INPUT_INJECTOR_IMPL_H_
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index d691aa7..930fd055 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -19,6 +19,7 @@ #include "base/process/kill.h" #include "base/time/time.h" #include "build/build_config.h" +#include "cc/base/switches.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/bluetooth/web_bluetooth_service_impl.h" @@ -31,6 +32,7 @@ #include "content/browser/frame_host/debug_urls.h" #include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree_node.h" +#include "content/browser/frame_host/input/input_injector_impl.h" #include "content/browser/frame_host/input/legacy_ipc_frame_input_handler.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigation_handle_impl.h" @@ -3025,6 +3027,12 @@ registry_->AddInterface( base::Bind(&media::WatchTimeRecorder::CreateWatchTimeRecorderProvider)); + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + cc::switches::kEnableGpuBenchmarking)) { + registry_->AddInterface( + base::Bind(&InputInjectorImpl::Create, weak_ptr_factory_.GetWeakPtr())); + } } void RenderFrameHostImpl::ResetWaitingState() {
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc index 63b39d28..e17b42ae1 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -124,7 +124,7 @@ // Since we were last shown, our renderer may have had a different surface // set (e.g. showing an interstitial), so we resend our current surface to // the renderer. - if (local_surface_id_.is_valid()) + if (last_received_local_surface_id_.is_valid()) SendSurfaceInfoToEmbedder(); } host_->WasShown(ui::LatencyInfo());
diff --git a/content/browser/frame_host/render_widget_host_view_guest_unittest.cc b/content/browser/frame_host/render_widget_host_view_guest_unittest.cc index 10c77e06..921518cc 100644 --- a/content/browser/frame_host/render_widget_host_view_guest_unittest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
@@ -196,9 +196,10 @@ DCHECK(view_); RenderWidgetHostViewChildFrame* rwhvcf = static_cast<RenderWidgetHostViewChildFrame*>(view_); - if (!rwhvcf->local_surface_id_.is_valid()) + if (!rwhvcf->last_received_local_surface_id_.is_valid()) return viz::SurfaceId(); - return viz::SurfaceId(rwhvcf->frame_sink_id_, rwhvcf->local_surface_id_); + return viz::SurfaceId(rwhvcf->frame_sink_id_, + rwhvcf->last_received_local_surface_id_); } protected:
diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc index 2d89495..a081f56 100644 --- a/content/browser/loader/resource_scheduler.cc +++ b/content/browser/loader/resource_scheduler.cc
@@ -38,10 +38,13 @@ // When kPrioritySupportedRequestsDelayable is enabled, requests for // H2/QUIC/SPDY resources can be delayed by the ResourceScheduler just as -// HTTP/1.1 resources are. Disabling this appears to have negative performance -// impact, see https://crbug.com/655585. +// HTTP/1.1 resources are. It has good impact on performance, but breaks +// expected behavior of H2. See intent-to-unship: +// https://groups.google.com/a/chromium.org/forum/#!topic/blink- +// dev/ChqGX8UyHz8. We're keeping it around for finch trials to compare +// alternatives to. const base::Feature kPrioritySupportedRequestsDelayable{ - "PrioritySupportedRequestsDelayable", base::FEATURE_ENABLED_BY_DEFAULT}; + "PrioritySupportedRequestsDelayable", base::FEATURE_DISABLED_BY_DEFAULT}; // When enabled, low-priority H2 and QUIC requests are throttled, but only // when the parser is in head.
diff --git a/content/browser/renderer_host/frame_connector_delegate.h b/content/browser/renderer_host/frame_connector_delegate.h index d35cd38..8cbaa03 100644 --- a/content/browser/renderer_host/frame_connector_delegate.h +++ b/content/browser/renderer_host/frame_connector_delegate.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_FRAME_CONNECTOR_DELEGATE_H_ #define CONTENT_BROWSER_RENDERER_HOST_FRAME_CONNECTOR_DELEGATE_H_ +#include "components/viz/common/surfaces/local_surface_id.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/common/content_export.h" #include "content/common/input/input_event_ack_state.h" @@ -128,6 +129,12 @@ return viewport_intersection_rect_; } + // Returns the viz::LocalSurfaceId propagated from the parent to be used by + // this child frame. + const viz::LocalSurfaceId& local_surface_id() const { + return local_surface_id_; + } + // Determines whether the current view's content is inert, either because // an HTMLDialogElement is being modally displayed in a higher-level frame, // or because the inert attribute has been specified. @@ -149,6 +156,8 @@ // This is here rather than in the implementation class so that // ViewportIntersection() can return a reference. gfx::Rect viewport_intersection_rect_; + + viz::LocalSurfaceId local_surface_id_; }; } // namespace content
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller.cc b/content/browser/renderer_host/input/synthetic_gesture_controller.cc index 3c5dcdc..44308e0 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_controller.cc +++ b/content/browser/renderer_host/input/synthetic_gesture_controller.cc
@@ -28,13 +28,13 @@ void SyntheticGestureController::QueueSyntheticGesture( std::unique_ptr<SyntheticGesture> synthetic_gesture, - const OnGestureCompleteCallback& completion_callback) { + OnGestureCompleteCallback completion_callback) { DCHECK(synthetic_gesture); bool was_empty = pending_gesture_queue_.IsEmpty(); pending_gesture_queue_.Push(std::move(synthetic_gesture), - completion_callback); + std::move(completion_callback)); if (was_empty) StartGesture(*pending_gesture_queue_.FrontGesture()); @@ -95,14 +95,14 @@ void SyntheticGestureController::StopGesture( const SyntheticGesture& gesture, - const OnGestureCompleteCallback& completion_callback, + OnGestureCompleteCallback completion_callback, SyntheticGesture::Result result) { DCHECK_NE(result, SyntheticGesture::GESTURE_RUNNING); TRACE_EVENT_ASYNC_END0("input,benchmark", "SyntheticGestureController::running", &gesture); - completion_callback.Run(result); + std::move(completion_callback).Run(result); } SyntheticGestureController::GestureAndCallbackQueue::GestureAndCallbackQueue() {
diff --git a/content/browser/renderer_host/input/synthetic_gesture_controller.h b/content/browser/renderer_host/input/synthetic_gesture_controller.h index 5ed093a..cbb4403 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_controller.h +++ b/content/browser/renderer_host/input/synthetic_gesture_controller.h
@@ -41,11 +41,11 @@ std::unique_ptr<SyntheticGestureTarget> gesture_target); virtual ~SyntheticGestureController(); - typedef base::Callback<void(SyntheticGesture::Result)> + typedef base::OnceCallback<void(SyntheticGesture::Result)> OnGestureCompleteCallback; void QueueSyntheticGesture( std::unique_ptr<SyntheticGesture> synthetic_gesture, - const OnGestureCompleteCallback& completion_callback); + OnGestureCompleteCallback completion_callback); bool DispatchNextEvent(base::TimeTicks = base::TimeTicks::Now()); @@ -55,7 +55,7 @@ void StartTimer(); void StartGesture(const SyntheticGesture& gesture); void StopGesture(const SyntheticGesture& gesture, - const OnGestureCompleteCallback& completion_callback, + OnGestureCompleteCallback completion_callback, SyntheticGesture::Result result); Delegate* const delegate_; @@ -68,9 +68,9 @@ GestureAndCallbackQueue(); ~GestureAndCallbackQueue(); void Push(std::unique_ptr<SyntheticGesture> gesture, - const OnGestureCompleteCallback& callback) { + OnGestureCompleteCallback callback) { gestures_.push_back(std::move(gesture)); - callbacks_.push(callback); + callbacks_.push(std::move(callback)); } void Pop() { gestures_.erase(gestures_.begin()); @@ -78,8 +78,11 @@ result_of_current_gesture_ = SyntheticGesture::GESTURE_RUNNING; } SyntheticGesture* FrontGesture() { return gestures_.front().get(); } - OnGestureCompleteCallback& FrontCallback() { - return callbacks_.front(); + OnGestureCompleteCallback FrontCallback() { + // TODO(dtapuska): This is odd moving the top callback. Pop really + // should be rewritten to take two output parameters then we can + // remove FrontGesture/FrontCallback. + return std::move(callbacks_.front()); } bool IsEmpty() const { CHECK(gestures_.empty() == callbacks_.empty());
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 25b4786..b72bce8 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -600,8 +600,6 @@ IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostImpl, msg) IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone) IPC_MESSAGE_HANDLER(FrameHostMsg_HittestData, OnHittestData) - IPC_MESSAGE_HANDLER(InputHostMsg_QueueSyntheticGesture, - OnQueueSyntheticGesture) IPC_MESSAGE_HANDLER(InputHostMsg_ImeCancelComposition, OnImeCancelComposition) IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose) @@ -1369,7 +1367,7 @@ void RenderWidgetHostImpl::QueueSyntheticGesture( std::unique_ptr<SyntheticGesture> synthetic_gesture, - const base::Callback<void(SyntheticGesture::Result)>& on_complete) { + base::OnceCallback<void(SyntheticGesture::Result)> on_complete) { if (!synthetic_gesture_controller_ && view_) { synthetic_gesture_controller_ = base::MakeUnique<SyntheticGestureController>( @@ -1377,7 +1375,7 @@ } if (synthetic_gesture_controller_) { synthetic_gesture_controller_->QueueSyntheticGesture( - std::move(synthetic_gesture), on_complete); + std::move(synthetic_gesture), std::move(on_complete)); } } @@ -2074,22 +2072,6 @@ WasResized(); } -void RenderWidgetHostImpl::OnQueueSyntheticGesture( - const SyntheticGesturePacket& gesture_packet) { - // Only allow untrustworthy gestures if explicitly enabled. - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - cc::switches::kEnableGpuBenchmarking)) { - bad_message::ReceivedBadMessage(GetProcess(), - bad_message::RWH_SYNTHETIC_GESTURE); - return; - } - - QueueSyntheticGesture( - SyntheticGesture::Create(*gesture_packet.gesture_params()), - base::Bind(&RenderWidgetHostImpl::OnSyntheticGestureCompleted, - weak_factory_.GetWeakPtr())); -} - void RenderWidgetHostImpl::OnSetCursor(const WebCursor& cursor) { SetCursor(cursor); } @@ -2407,13 +2389,6 @@ } } -void RenderWidgetHostImpl::OnSyntheticGestureCompleted( - SyntheticGesture::Result result) { - // TODO(dtapuska): Define mojo interface for InputHostMsg's and this will be a - // callback for completing InputHostMsg_QueueSyntheticGesture. - process_->Send(new InputMsg_SyntheticGestureCompleted(GetRoutingID())); -} - bool RenderWidgetHostImpl::ShouldDropInputEvents() const { return ignore_input_events_ || process_->IgnoreInputEvents() || !delegate_; }
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index d737008..b75d5e7 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -41,7 +41,6 @@ #include "content/common/drag_event_source_info.h" #include "content/common/input/input_event_ack_state.h" #include "content/common/input/input_handler.mojom.h" -#include "content/common/input/synthetic_gesture_packet.h" #include "content/common/render_widget_surface_properties.h" #include "content/common/view_message_enums.h" #include "content/common/widget.mojom.h" @@ -404,7 +403,7 @@ // callback when the gesture is finished running. void QueueSyntheticGesture( std::unique_ptr<SyntheticGesture> synthetic_gesture, - const base::Callback<void(SyntheticGesture::Result)>& on_complete); + base::OnceCallback<void(SyntheticGesture::Result)> on_complete); void CancelUpdateTextDirection(); @@ -671,7 +670,6 @@ void OnSetTooltipText(const base::string16& tooltip_text, blink::WebTextDirection text_direction_hint); void OnUpdateRect(const ViewHostMsg_UpdateRect_Params& params); - void OnQueueSyntheticGesture(const SyntheticGesturePacket& gesture_packet); void OnSetCursor(const WebCursor& cursor); void OnAutoscrollStart(const gfx::PointF& position); void OnAutoscrollFling(const gfx::Vector2dF& velocity); @@ -742,8 +740,6 @@ InputEventAckState ack_result) override; void OnUnexpectedEventAck(UnexpectedEventAckType type) override; - void OnSyntheticGestureCompleted(SyntheticGesture::Result result); - // Called when there is a new auto resize (using a post to avoid a stack // which may get in recursive loops). void DelayedAutoResized();
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index b555878d..faec1e5 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -255,8 +255,11 @@ virtual void DidStopFlinging() {} // Returns the ID associated with the CompositorFrameSink of this view. + // TODO(fsamuel): Return by const ref. virtual viz::FrameSinkId GetFrameSinkId(); + // Returns the LocalSurfaceId allocated by the parent client for this view. + // TODO(fsamuel): Return by const ref. virtual viz::LocalSurfaceId GetLocalSurfaceId() const; // When there are multiple RenderWidgetHostViews for a single page, input
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc index dd2ad3e..48fd5c32 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -126,7 +126,7 @@ parent_frame_sink_id_, frame_sink_id_); } parent_frame_sink_id_ = viz::FrameSinkId(); - local_surface_id_ = viz::LocalSurfaceId(); + last_received_local_surface_id_ = viz::LocalSurfaceId(); // Unlocks the mouse if this RenderWidgetHostView holds the lock. UnlockMouse(); @@ -485,8 +485,9 @@ DCHECK(result); has_frame_ = true; - if (local_surface_id_ != local_surface_id || HasEmbedderChanged()) { - local_surface_id_ = local_surface_id; + if (last_received_local_surface_id_ != local_surface_id || + HasEmbedderChanged()) { + last_received_local_surface_id_ = local_surface_id; SendSurfaceInfoToEmbedder(); } @@ -506,7 +507,7 @@ viz::SurfaceSequence sequence = viz::SurfaceSequence(frame_sink_id_, next_surface_sequence_++); viz::SurfaceManager* manager = GetFrameSinkManager()->surface_manager(); - viz::SurfaceId surface_id(frame_sink_id_, local_surface_id_); + viz::SurfaceId surface_id(frame_sink_id_, last_received_local_surface_id_); // The renderer process will satisfy this dependency when it creates a // SurfaceLayer. if (!manager->using_surface_references()) @@ -592,6 +593,12 @@ return frame_sink_id_; } +viz::LocalSurfaceId RenderWidgetHostViewChildFrame::GetLocalSurfaceId() const { + if (frame_connector_) + return frame_connector_->local_surface_id(); + return viz::LocalSurfaceId(); +} + void RenderWidgetHostViewChildFrame::ProcessKeyboardEvent( const NativeWebKeyboardEvent& event, const ui::LatencyInfo& latency) { @@ -634,11 +641,11 @@ gfx::Point RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpace( const gfx::Point& point) { - if (!frame_connector_ || !local_surface_id_.is_valid()) + if (!frame_connector_ || !last_received_local_surface_id_.is_valid()) return point; return frame_connector_->TransformPointToRootCoordSpace( - point, viz::SurfaceId(frame_sink_id_, local_surface_id_)); + point, viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_)); } bool RenderWidgetHostViewChildFrame::TransformPointToLocalCoordSpace( @@ -646,19 +653,20 @@ const viz::SurfaceId& original_surface, gfx::Point* transformed_point) { *transformed_point = point; - if (!frame_connector_ || !local_surface_id_.is_valid()) + if (!frame_connector_ || !last_received_local_surface_id_.is_valid()) return false; return frame_connector_->TransformPointToLocalCoordSpace( point, original_surface, - viz::SurfaceId(frame_sink_id_, local_surface_id_), transformed_point); + viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_), + transformed_point); } bool RenderWidgetHostViewChildFrame::TransformPointToCoordSpaceForView( const gfx::Point& point, RenderWidgetHostViewBase* target_view, gfx::Point* transformed_point) { - if (!frame_connector_ || !local_surface_id_.is_valid()) + if (!frame_connector_ || !last_received_local_surface_id_.is_valid()) return false; if (target_view == this) { @@ -667,7 +675,8 @@ } return frame_connector_->TransformPointToCoordSpaceForView( - point, target_view, viz::SurfaceId(frame_sink_id_, local_surface_id_), + point, target_view, + viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_), transformed_point); } @@ -864,7 +873,7 @@ } viz::SurfaceId RenderWidgetHostViewChildFrame::SurfaceIdForTesting() const { - return viz::SurfaceId(frame_sink_id_, local_surface_id_); + return viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_); } void RenderWidgetHostViewChildFrame::CreateCompositorFrameSinkSupport() {
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h index 96e11aa..802ce0c 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame.h +++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -130,6 +130,7 @@ bool LockMouse() override; void UnlockMouse() override; viz::FrameSinkId GetFrameSinkId() override; + viz::LocalSurfaceId GetLocalSurfaceId() const override; void ProcessKeyboardEvent(const NativeWebKeyboardEvent& event, const ui::LatencyInfo& latency) override; void ProcessMouseEvent(const blink::WebMouseEvent& event, @@ -247,7 +248,7 @@ // Surface-related state. std::unique_ptr<viz::CompositorFrameSinkSupport> support_; - viz::LocalSurfaceId local_surface_id_; + viz::LocalSurfaceId last_received_local_surface_id_; uint32_t next_surface_sequence_; gfx::Size current_surface_size_; float current_surface_scale_factor_;
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc index 1f9161a3..23bdcf77 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
@@ -123,11 +123,12 @@ } viz::SurfaceId GetSurfaceId() const { - return viz::SurfaceId(view_->frame_sink_id_, view_->local_surface_id_); + return viz::SurfaceId(view_->frame_sink_id_, + view_->last_received_local_surface_id_); } viz::LocalSurfaceId GetLocalSurfaceId() const { - return view_->local_surface_id_; + return view_->last_received_local_surface_id_; } void ClearCompositorSurfaceIfNecessary() {
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 362290d..aed8fcf 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -1030,14 +1030,16 @@ private: ~FrameRectChangedMessageFilter() override {} - void OnFrameRectChanged(const gfx::Rect& rect) { + void OnFrameRectChanged(const gfx::Rect& rect, + const viz::LocalSurfaceId& local_surface_id) { content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, base::Bind(&FrameRectChangedMessageFilter::OnFrameRectChangedOnUI, this, - rect)); + rect, local_surface_id)); } - void OnFrameRectChangedOnUI(const gfx::Rect& rect) { + void OnFrameRectChangedOnUI(const gfx::Rect& rect, + const viz::LocalSurfaceId& local_surface_id) { last_rect_ = rect; if (!frame_rect_received_) { frame_rect_received_ = true;
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 29be3ff..119a5b751 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -177,8 +177,6 @@ "input/input_event_struct_traits.h", "input/input_param_traits.cc", "input/input_param_traits.h", - "input/synthetic_gesture_packet.cc", - "input/synthetic_gesture_packet.h", "input/synthetic_gesture_params.cc", "input/synthetic_gesture_params.h", "input/synthetic_pinch_gesture_params.cc", @@ -613,6 +611,7 @@ "image_downloader/image_downloader.mojom", "indexed_db/indexed_db.mojom", "input/input_handler.mojom", + "input/input_injector.mojom", "leveldb_wrapper.mojom", "manifest_observer.mojom", "media/media_devices.mojom",
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 72a527a..b54c9d2 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -870,6 +870,10 @@ url::Origin /* origin */, bool /* is potentially trustworthy unique origin */) +// Notifies RenderFrameProxy that its associated RenderWidgetHostView has +// changed. +IPC_MESSAGE_ROUTED0(FrameMsg_ViewChanged) + // Notifies this frame or proxy that it is now focused. This is used to // support cross-process focused frame changes. IPC_MESSAGE_ROUTED0(FrameMsg_SetFocusedFrame) @@ -1440,7 +1444,9 @@ // Tells the parent that a child's frame rect has changed (or the rect/scroll // position of a child's ancestor has changed). -IPC_MESSAGE_ROUTED1(FrameHostMsg_FrameRectChanged, gfx::Rect /* frame_rect */) +IPC_MESSAGE_ROUTED2(FrameHostMsg_FrameRectChanged, + gfx::Rect /* frame_rect */, + viz::LocalSurfaceId /* local_surface_id */) // Sent by a parent frame to update its child's viewport intersection rect for // use by the IntersectionObserver API.
diff --git a/content/common/input/input_injector.mojom b/content/common/input/input_injector.mojom new file mode 100644 index 0000000..d43891c --- /dev/null +++ b/content/common/input/input_injector.mojom
@@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module content.mojom; + +import "content/common/native_types.mojom"; + +// Host interface representing the ability to inject input +// from a less priviledged application. Available when +// --enable-gpu-benchmarking command line flag is provided. +interface InputInjector { + QueueSyntheticSmoothDrag(SyntheticSmoothDrag drag) => (); + QueueSyntheticSmoothScroll(SyntheticSmoothScroll scroll) => (); + QueueSyntheticPinch(SyntheticPinch pinch) => (); + QueueSyntheticTap(SyntheticTap tap) => (); + QueueSyntheticPointerAction(SyntheticPointerAction pointer_action) => (); +};
diff --git a/content/common/input/input_param_traits.cc b/content/common/input/input_param_traits.cc index 1ff8fb2..0fe6100 100644 --- a/content/common/input/input_param_traits.cc +++ b/content/common/input/input_param_traits.cc
@@ -15,18 +15,6 @@ #include "ui/events/blink/web_input_event_traits.h" namespace IPC { -namespace { -template <typename GestureType> -std::unique_ptr<content::SyntheticGestureParams> ReadGestureParams( - const base::Pickle* m, - base::PickleIterator* iter) { - std::unique_ptr<GestureType> gesture_params(new GestureType); - if (!ReadParam(m, iter, gesture_params.get())) - return std::unique_ptr<content::SyntheticGestureParams>(); - - return std::move(gesture_params); -} -} // namespace void ParamTraits<ui::WebScopedInputEvent>::GetSize(base::PickleSizer* s, const param_type& p) { @@ -64,103 +52,4 @@ LogParam(static_cast<WebInputEventPointer>(p.get()), l); } -void ParamTraits<content::SyntheticGesturePacket>::Write(base::Pickle* m, - const param_type& p) { - DCHECK(p.gesture_params()); - WriteParam(m, p.gesture_params()->GetGestureType()); - switch (p.gesture_params()->GetGestureType()) { - case content::SyntheticGestureParams::SMOOTH_SCROLL_GESTURE: - WriteParam(m, *content::SyntheticSmoothScrollGestureParams::Cast( - p.gesture_params())); - break; - case content::SyntheticGestureParams::SMOOTH_DRAG_GESTURE: - WriteParam(m, *content::SyntheticSmoothDragGestureParams::Cast( - p.gesture_params())); - break; - case content::SyntheticGestureParams::PINCH_GESTURE: - WriteParam(m, *content::SyntheticPinchGestureParams::Cast( - p.gesture_params())); - break; - case content::SyntheticGestureParams::TAP_GESTURE: - WriteParam(m, *content::SyntheticTapGestureParams::Cast( - p.gesture_params())); - break; - case content::SyntheticGestureParams::POINTER_ACTION_LIST: - WriteParam(m, *content::SyntheticPointerActionListParams::Cast( - p.gesture_params())); - break; - } -} - -bool ParamTraits<content::SyntheticGesturePacket>::Read( - const base::Pickle* m, - base::PickleIterator* iter, - param_type* p) { - content::SyntheticGestureParams::GestureType gesture_type; - if (!ReadParam(m, iter, &gesture_type)) - return false; - std::unique_ptr<content::SyntheticGestureParams> gesture_params; - switch (gesture_type) { - case content::SyntheticGestureParams::SMOOTH_SCROLL_GESTURE: - gesture_params = - ReadGestureParams<content::SyntheticSmoothScrollGestureParams>(m, - iter); - break; - case content::SyntheticGestureParams::SMOOTH_DRAG_GESTURE: - gesture_params = - ReadGestureParams<content::SyntheticSmoothDragGestureParams>(m, iter); - break; - case content::SyntheticGestureParams::PINCH_GESTURE: - gesture_params = - ReadGestureParams<content::SyntheticPinchGestureParams>(m, iter); - break; - case content::SyntheticGestureParams::TAP_GESTURE: - gesture_params = - ReadGestureParams<content::SyntheticTapGestureParams>(m, iter); - break; - case content::SyntheticGestureParams::POINTER_ACTION_LIST: - gesture_params = - ReadGestureParams<content::SyntheticPointerActionListParams>(m, iter); - break; - default: - return false; - } - - p->set_gesture_params(std::move(gesture_params)); - return p->gesture_params() != NULL; -} - -void ParamTraits<content::SyntheticGesturePacket>::Log(const param_type& p, - std::string* l) { - DCHECK(p.gesture_params()); - switch (p.gesture_params()->GetGestureType()) { - case content::SyntheticGestureParams::SMOOTH_SCROLL_GESTURE: - LogParam( - *content::SyntheticSmoothScrollGestureParams::Cast( - p.gesture_params()), - l); - break; - case content::SyntheticGestureParams::SMOOTH_DRAG_GESTURE: - LogParam( - *content::SyntheticSmoothDragGestureParams::Cast(p.gesture_params()), - l); - break; - case content::SyntheticGestureParams::PINCH_GESTURE: - LogParam( - *content::SyntheticPinchGestureParams::Cast(p.gesture_params()), - l); - break; - case content::SyntheticGestureParams::TAP_GESTURE: - LogParam( - *content::SyntheticTapGestureParams::Cast(p.gesture_params()), - l); - break; - case content::SyntheticGestureParams::POINTER_ACTION_LIST: - LogParam( - *content::SyntheticPointerActionListParams::Cast(p.gesture_params()), - l); - break; - } -} - } // namespace IPC
diff --git a/content/common/input/input_param_traits.h b/content/common/input/input_param_traits.h index db6e82d..5c36652 100644 --- a/content/common/input/input_param_traits.h +++ b/content/common/input/input_param_traits.h
@@ -10,7 +10,6 @@ #include "content/common/content_export.h" #include "content/common/content_param_traits_macros.h" -#include "content/common/input/synthetic_gesture_packet.h" #include "ui/events/blink/web_input_event_traits.h" namespace IPC { @@ -26,16 +25,6 @@ static void Log(const param_type& p, std::string* l); }; -template<> -struct CONTENT_EXPORT ParamTraits<content::SyntheticGesturePacket> { - typedef content::SyntheticGesturePacket param_type; - static void Write(base::Pickle* m, const param_type& p); - static bool Read(const base::Pickle* m, - base::PickleIterator* iter, - param_type* r); - static void Log(const param_type& p, std::string* l); -}; - } // namespace IPC #endif // CONTENT_COMMON_INPUT_INPUT_PARAM_TRAITS_H_
diff --git a/content/common/input/input_param_traits_unittest.cc b/content/common/input/input_param_traits_unittest.cc index f8dc5e03..4bc88c5f 100644 --- a/content/common/input/input_param_traits_unittest.cc +++ b/content/common/input/input_param_traits_unittest.cc
@@ -12,12 +12,6 @@ #include "base/memory/ptr_util.h" #include "content/common/input/input_event.h" -#include "content/common/input/synthetic_gesture_params.h" -#include "content/common/input/synthetic_pinch_gesture_params.h" -#include "content/common/input/synthetic_pointer_action_list_params.h" -#include "content/common/input/synthetic_pointer_action_params.h" -#include "content/common/input/synthetic_smooth_drag_gesture_params.h" -#include "content/common/input/synthetic_smooth_scroll_gesture_params.h" #include "content/common/input_messages.h" #include "ipc/ipc_message.h" #include "testing/gtest/include/gtest/gtest.h" @@ -50,99 +44,6 @@ Compare((*a)[i].get(), (*b)[i].get()); } - static void Compare(const SyntheticSmoothScrollGestureParams* a, - const SyntheticSmoothScrollGestureParams* b) { - EXPECT_EQ(a->gesture_source_type, b->gesture_source_type); - EXPECT_EQ(a->anchor, b->anchor); - EXPECT_EQ(a->distances.size(), b->distances.size()); - for (size_t i = 0; i < a->distances.size(); i++) - EXPECT_EQ(a->distances[i], b->distances[i]); - EXPECT_EQ(a->prevent_fling, b->prevent_fling); - EXPECT_EQ(a->speed_in_pixels_s, b->speed_in_pixels_s); - } - - static void Compare(const SyntheticSmoothDragGestureParams* a, - const SyntheticSmoothDragGestureParams* b) { - EXPECT_EQ(a->gesture_source_type, b->gesture_source_type); - EXPECT_EQ(a->start_point, b->start_point); - EXPECT_EQ(a->distances.size(), b->distances.size()); - for (size_t i = 0; i < a->distances.size(); i++) - EXPECT_EQ(a->distances[i], b->distances[i]); - EXPECT_EQ(a->speed_in_pixels_s, b->speed_in_pixels_s); - } - - static void Compare(const SyntheticPinchGestureParams* a, - const SyntheticPinchGestureParams* b) { - EXPECT_EQ(a->gesture_source_type, b->gesture_source_type); - EXPECT_EQ(a->scale_factor, b->scale_factor); - EXPECT_EQ(a->anchor, b->anchor); - EXPECT_EQ(a->relative_pointer_speed_in_pixels_s, - b->relative_pointer_speed_in_pixels_s); - } - - static void Compare(const SyntheticTapGestureParams* a, - const SyntheticTapGestureParams* b) { - EXPECT_EQ(a->gesture_source_type, b->gesture_source_type); - EXPECT_EQ(a->position, b->position); - EXPECT_EQ(a->duration_ms, b->duration_ms); - } - - static void Compare(const SyntheticPointerActionParams* a, - const SyntheticPointerActionParams* b) { - EXPECT_EQ(a->pointer_action_type(), b->pointer_action_type()); - if (a->pointer_action_type() == - SyntheticPointerActionParams::PointerActionType::PRESS || - a->pointer_action_type() == - SyntheticPointerActionParams::PointerActionType::MOVE) { - EXPECT_EQ(a->position(), b->position()); - } - EXPECT_EQ(a->index(), b->index()); - } - - static void Compare(const SyntheticPointerActionListParams* a, - const SyntheticPointerActionListParams* b) { - EXPECT_EQ(a->gesture_source_type, b->gesture_source_type); - EXPECT_EQ(a->params.size(), b->params.size()); - for (size_t i = 0; i < a->params.size(); ++i) { - EXPECT_EQ(a->params[i].size(), b->params[i].size()); - for (size_t j = 0; j < a->params[i].size(); ++j) { - Compare(&a->params[i][j], &b->params[i][j]); - } - } - } - - static void Compare(const SyntheticGesturePacket* a, - const SyntheticGesturePacket* b) { - ASSERT_EQ(!!a, !!b); - if (!a) return; - ASSERT_EQ(!!a->gesture_params(), !!b->gesture_params()); - if (!a->gesture_params()) return; - ASSERT_EQ(a->gesture_params()->GetGestureType(), - b->gesture_params()->GetGestureType()); - switch (a->gesture_params()->GetGestureType()) { - case SyntheticGestureParams::SMOOTH_SCROLL_GESTURE: - Compare(SyntheticSmoothScrollGestureParams::Cast(a->gesture_params()), - SyntheticSmoothScrollGestureParams::Cast(b->gesture_params())); - break; - case SyntheticGestureParams::SMOOTH_DRAG_GESTURE: - Compare(SyntheticSmoothDragGestureParams::Cast(a->gesture_params()), - SyntheticSmoothDragGestureParams::Cast(b->gesture_params())); - break; - case SyntheticGestureParams::PINCH_GESTURE: - Compare(SyntheticPinchGestureParams::Cast(a->gesture_params()), - SyntheticPinchGestureParams::Cast(b->gesture_params())); - break; - case SyntheticGestureParams::TAP_GESTURE: - Compare(SyntheticTapGestureParams::Cast(a->gesture_params()), - SyntheticTapGestureParams::Cast(b->gesture_params())); - break; - case SyntheticGestureParams::POINTER_ACTION_LIST: - Compare(SyntheticPointerActionListParams::Cast(a->gesture_params()), - SyntheticPointerActionListParams::Cast(b->gesture_params())); - break; - } - } - static void Verify(const InputEvents& events_in) { IPC::Message msg; IPC::ParamTraits<InputEvents>::Write(&msg, events_in); @@ -161,27 +62,6 @@ ASSERT_FALSE(events_in_string.empty()); EXPECT_EQ(events_in_string, events_out_string); } - - static void Verify(const SyntheticGesturePacket& packet_in) { - IPC::Message msg; - IPC::ParamTraits<SyntheticGesturePacket>::Write(&msg, packet_in); - - SyntheticGesturePacket packet_out; - base::PickleIterator iter(msg); - EXPECT_TRUE(IPC::ParamTraits<SyntheticGesturePacket>::Read(&msg, &iter, - &packet_out)); - - Compare(&packet_in, &packet_out); - - // Perform a sanity check that logging doesn't explode. - std::string packet_in_string; - IPC::ParamTraits<SyntheticGesturePacket>::Log(packet_in, &packet_in_string); - std::string packet_out_string; - IPC::ParamTraits<SyntheticGesturePacket>::Log(packet_out, - &packet_out_string); - ASSERT_FALSE(packet_in_string.empty()); - EXPECT_EQ(packet_in_string, packet_out_string); - } }; TEST_F(InputParamTraitsTest, UninitializedEvents) { @@ -238,133 +118,5 @@ Verify(events); } -TEST_F(InputParamTraitsTest, InvalidSyntheticGestureParams) { - IPC::Message msg; - // Write invalid value for SyntheticGestureParams::GestureType. - WriteParam(&msg, -3); - - SyntheticGesturePacket packet_out; - base::PickleIterator iter(msg); - ASSERT_FALSE( - IPC::ParamTraits<SyntheticGesturePacket>::Read(&msg, &iter, &packet_out)); -} - -TEST_F(InputParamTraitsTest, SyntheticSmoothScrollGestureParams) { - std::unique_ptr<SyntheticSmoothScrollGestureParams> gesture_params( - new SyntheticSmoothScrollGestureParams); - gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; - gesture_params->anchor.SetPoint(234, 345); - gesture_params->distances.push_back(gfx::Vector2d(123, -789)); - gesture_params->distances.push_back(gfx::Vector2d(-78, 43)); - gesture_params->prevent_fling = false; - gesture_params->speed_in_pixels_s = 456; - ASSERT_EQ(SyntheticGestureParams::SMOOTH_SCROLL_GESTURE, - gesture_params->GetGestureType()); - SyntheticGesturePacket packet_in; - packet_in.set_gesture_params(std::move(gesture_params)); - - Verify(packet_in); -} - -TEST_F(InputParamTraitsTest, SyntheticPinchGestureParams) { - std::unique_ptr<SyntheticPinchGestureParams> gesture_params( - new SyntheticPinchGestureParams); - gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; - gesture_params->scale_factor = 2.3f; - gesture_params->anchor.SetPoint(234, 345); - gesture_params->relative_pointer_speed_in_pixels_s = 456; - ASSERT_EQ(SyntheticGestureParams::PINCH_GESTURE, - gesture_params->GetGestureType()); - SyntheticGesturePacket packet_in; - packet_in.set_gesture_params(std::move(gesture_params)); - - Verify(packet_in); -} - -TEST_F(InputParamTraitsTest, SyntheticTapGestureParams) { - std::unique_ptr<SyntheticTapGestureParams> gesture_params( - new SyntheticTapGestureParams); - gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; - gesture_params->position.SetPoint(798, 233); - gesture_params->duration_ms = 13; - ASSERT_EQ(SyntheticGestureParams::TAP_GESTURE, - gesture_params->GetGestureType()); - SyntheticGesturePacket packet_in; - packet_in.set_gesture_params(std::move(gesture_params)); - - Verify(packet_in); -} - -TEST_F(InputParamTraitsTest, SyntheticPointerActionListParamsMove) { - SyntheticPointerActionParams action_params( - SyntheticPointerActionParams::PointerActionType::MOVE); - action_params.set_position(gfx::PointF(356, 287)); - action_params.set_index(0); - std::unique_ptr<SyntheticPointerActionListParams> gesture_params = - base::MakeUnique<SyntheticPointerActionListParams>(); - gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; - gesture_params->PushPointerActionParams(action_params); - - ASSERT_EQ(SyntheticGestureParams::POINTER_ACTION_LIST, - gesture_params->GetGestureType()); - SyntheticGesturePacket packet_in; - packet_in.set_gesture_params(std::move(gesture_params)); - Verify(packet_in); -} - -TEST_F(InputParamTraitsTest, SyntheticPointerActionListParamsPressRelease) { - std::unique_ptr<SyntheticPointerActionListParams> gesture_params = - base::MakeUnique<SyntheticPointerActionListParams>(); - gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; - SyntheticPointerActionParams action_params( - SyntheticPointerActionParams::PointerActionType::PRESS); - action_params.set_index(0); - gesture_params->PushPointerActionParams(action_params); - action_params.set_pointer_action_type( - SyntheticPointerActionParams::PointerActionType::RELEASE); - gesture_params->PushPointerActionParams(action_params); - - ASSERT_EQ(SyntheticGestureParams::POINTER_ACTION_LIST, - gesture_params->GetGestureType()); - SyntheticGesturePacket packet_in; - packet_in.set_gesture_params(std::move(gesture_params)); - Verify(packet_in); -} - -TEST_F(InputParamTraitsTest, SyntheticPointerActionParamsIdle) { - std::unique_ptr<SyntheticPointerActionListParams> gesture_params = - base::MakeUnique<SyntheticPointerActionListParams>(); - gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; - SyntheticPointerActionParams action_params( - SyntheticPointerActionParams::PointerActionType::IDLE); - action_params.set_index(0); - gesture_params->PushPointerActionParams(action_params); - - ASSERT_EQ(SyntheticGestureParams::POINTER_ACTION_LIST, - gesture_params->GetGestureType()); - SyntheticGesturePacket packet_in; - packet_in.set_gesture_params(std::move(gesture_params)); - Verify(packet_in); -} - -TEST_F(InputParamTraitsTest, SyntheticPointerActionListParamsTwoPresses) { - SyntheticPointerActionListParams::ParamList param_list; - SyntheticPointerActionParams action_params( - SyntheticPointerActionParams::PointerActionType::PRESS); - action_params.set_index(0); - param_list.push_back(action_params); - action_params.set_index(1); - param_list.push_back(action_params); - std::unique_ptr<SyntheticPointerActionListParams> gesture_params = - base::MakeUnique<SyntheticPointerActionListParams>(param_list); - gesture_params->gesture_source_type = SyntheticGestureParams::TOUCH_INPUT; - - ASSERT_EQ(SyntheticGestureParams::POINTER_ACTION_LIST, - gesture_params->GetGestureType()); - SyntheticGesturePacket packet_in; - packet_in.set_gesture_params(std::move(gesture_params)); - Verify(packet_in); -} - } // namespace } // namespace content
diff --git a/content/common/input/synthetic_gesture_packet.cc b/content/common/input/synthetic_gesture_packet.cc deleted file mode 100644 index 1a999b0..0000000 --- a/content/common/input/synthetic_gesture_packet.cc +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/input/synthetic_gesture_packet.h" - -namespace content { - -SyntheticGesturePacket::SyntheticGesturePacket() {} - -SyntheticGesturePacket::~SyntheticGesturePacket() {} - -} // namespace content
diff --git a/content/common/input/synthetic_gesture_packet.h b/content/common/input/synthetic_gesture_packet.h deleted file mode 100644 index 4f9b281d..0000000 --- a/content/common/input/synthetic_gesture_packet.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_INPUT_SYNTHETIC_GESTURE_PACKET_H_ -#define CONTENT_COMMON_INPUT_SYNTHETIC_GESTURE_PACKET_H_ - -#include <memory> -#include <utility> - -#include "base/macros.h" -#include "content/common/content_export.h" -#include "content/common/input/synthetic_gesture_params.h" - -namespace content { - -// Wraps an object of type SyntheticGestureParams (or one of its subclasses) for -// sending it over IPC. -class CONTENT_EXPORT SyntheticGesturePacket { - public: - SyntheticGesturePacket(); - ~SyntheticGesturePacket(); - - void set_gesture_params( - std::unique_ptr<SyntheticGestureParams> gesture_params) { - gesture_params_ = std::move(gesture_params); - } - const SyntheticGestureParams* gesture_params() const { - return gesture_params_.get(); - } - std::unique_ptr<SyntheticGestureParams> pass_gesture_params() { - return std::move(gesture_params_); - } - - private: - std::unique_ptr<SyntheticGestureParams> gesture_params_; - - DISALLOW_COPY_AND_ASSIGN(SyntheticGesturePacket); -}; - -} // namespace content - -#endif // CONTENT_COMMON_INPUT_SYNTHETIC_GESTURE_PACKET_H_
diff --git a/content/common/input/synthetic_gesture_params.h b/content/common/input/synthetic_gesture_params.h index 7dc59fa..9f5dfc47 100644 --- a/content/common/input/synthetic_gesture_params.h +++ b/content/common/input/synthetic_gesture_params.h
@@ -11,23 +11,12 @@ namespace content { -// Base class for storing parameters of synthetic gestures. Sending an object -// over IPC is handled by encapsulating it in a SyntheticGesturePacket object. +// Base class for storing parameters of synthetic gestures. // // The subclasses of this class only store data on synthetic gestures. // The logic for dispatching input events that implement the gesture lives // in separate classes in content/browser/renderer_host/input/. // -// Adding new gesture types involves the following steps: -// 1) Create a new sub-type of SyntheticGestureParams with the parameters -// needed for the new gesture. -// 2) Use IPC macros to create serialization methods for the new type in -// content/common/input_messages.h. -// 3) Extend ParamTraits<content::SyntheticGesturePacket>::Write/Read/Log in -// content/common/input/input_param_traits.cc. -// 4) Add a new unit test to make sure that sending the type over IPC works -// correctly. -// The details of each step should become clear when looking at other types. struct CONTENT_EXPORT SyntheticGestureParams { SyntheticGestureParams(); SyntheticGestureParams(const SyntheticGestureParams& other);
diff --git a/content/common/input_messages.h b/content/common/input_messages.h index 73dedb03..58a46ad 100644 --- a/content/common/input_messages.h +++ b/content/common/input_messages.h
@@ -18,7 +18,6 @@ #include "content/common/input/input_event_ack_state.h" #include "content/common/input/input_event_dispatch_type.h" #include "content/common/input/input_param_traits.h" -#include "content/common/input/synthetic_gesture_packet.h" #include "content/common/input/synthetic_gesture_params.h" #include "content/common/input/synthetic_pinch_gesture_params.h" #include "content/common/input/synthetic_pointer_action_list_params.h" @@ -309,8 +308,6 @@ bool /* immediate_request */, bool /* monitor_updates */) -IPC_MESSAGE_ROUTED0(InputMsg_SyntheticGestureCompleted) - // ----------------------------------------------------------------------------- // Messages sent from the renderer to the browser. @@ -318,9 +315,6 @@ IPC_MESSAGE_ROUTED1(InputHostMsg_HandleInputEvent_ACK, content::InputEventAck /* ack */) -IPC_MESSAGE_ROUTED1(InputHostMsg_QueueSyntheticGesture, - content::SyntheticGesturePacket) - // Notifies the allowed touch actions for a new touch point. IPC_MESSAGE_ROUTED1(InputHostMsg_SetTouchAction, cc::TouchAction /* touch_action */)
diff --git a/content/common/native_types.mojom b/content/common/native_types.mojom index cd0e90f..61d28a2e 100644 --- a/content/common/native_types.mojom +++ b/content/common/native_types.mojom
@@ -79,3 +79,18 @@ [Native] struct DidOverscrollParams; + +[Native] +struct SyntheticSmoothDrag; + +[Native] +struct SyntheticSmoothScroll; + +[Native] +struct SyntheticPinch; + +[Native] +struct SyntheticTap; + +[Native] +struct SyntheticPointerAction;
diff --git a/content/common/native_types.typemap b/content/common/native_types.typemap index 94240ef..2d463f1b 100644 --- a/content/common/native_types.typemap +++ b/content/common/native_types.typemap
@@ -11,6 +11,11 @@ "//content/common/input/input_event.h", "//content/common/input/input_event_ack_source.h", "//content/common/input/input_event_ack_state.h", + "//content/common/input/synthetic_pinch_gesture_params.h", + "//content/common/input/synthetic_pointer_action_list_params.h", + "//content/common/input/synthetic_smooth_drag_gesture_params.h", + "//content/common/input/synthetic_smooth_scroll_gesture_params.h", + "//content/common/input/synthetic_tap_gesture_params.h", "//content/public/common/renderer_preferences.h", "//content/public/common/web_preferences.h", "//net/base/network_change_notifier.h", @@ -73,6 +78,11 @@ "content.mojom.RendererPreferences=content::RendererPreferences", "content.mojom.ResizeParams=content::ResizeParams", "content.mojom.ScrollUnits=blink::WebGestureEvent::ScrollUnits", + "content.mojom.SyntheticSmoothDrag=content::SyntheticSmoothDragGestureParams", + "content.mojom.SyntheticSmoothScroll=content::SyntheticSmoothScrollGestureParams", + "content.mojom.SyntheticPinch=content::SyntheticPinchGestureParams", + "content.mojom.SyntheticTap=content::SyntheticTapGestureParams", + "content.mojom.SyntheticPointerAction=content::SyntheticPointerActionListParams", "content.mojom.TouchState=blink::WebTouchPoint::State", "content.mojom.WebPopupType=blink::WebPopupType", "content.mojom.WebPreferences=content::WebPreferences",
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index b84e3468..6b45cdac 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -127,6 +127,9 @@ // TODO(beng): figure out how to overlay test interfaces like this. "content::mojom::BrowserTarget", + // InputInjector is only exposed when gpu benchmarking is enabled. + "content::mojom::InputInjector", + "content::mojom::RendererAudioOutputStreamFactory", "device::mojom::Geolocation", "device::mojom::GeolocationService",
diff --git a/content/public/common/resource_request.h b/content/public/common/resource_request.h index 2f767350a..f776dfc 100644 --- a/content/public/common/resource_request.h +++ b/content/public/common/resource_request.h
@@ -33,7 +33,7 @@ ~ResourceRequest(); // The request method: GET, POST, etc. - std::string method; + std::string method = "GET"; // The absolute requested URL encoded in ASCII per the rules of RFC-2396. GURL url;
diff --git a/content/public/common/simple_url_loader_unittest.cc b/content/public/common/simple_url_loader_unittest.cc index 061586c0..6e43aad4 100644 --- a/content/public/common/simple_url_loader_unittest.cc +++ b/content/public/common/simple_url_loader_unittest.cc
@@ -79,7 +79,6 @@ void RunRequestForURL(mojom::URLLoaderFactory* url_loader_factory, const GURL& url) { ResourceRequest resource_request; - resource_request.method = "GET"; resource_request.url = url; RunRequest(url_loader_factory, resource_request); } @@ -101,7 +100,6 @@ const GURL& url, size_t max_size) { ResourceRequest resource_request; - resource_request.method = "GET"; resource_request.url = url; RunRequestWithBoundedSize(url_loader_factory, resource_request, max_size); } @@ -238,7 +236,6 @@ TEST_F(SimpleURLLoaderTest, BasicRequest) { ResourceRequest resource_request; - resource_request.method = "GET"; // Use a more interesting request than "/echo", just to verify more than the // request URL is hooked up. resource_request.url = test_server_.GetURL("/echoheader?foo"); @@ -255,7 +252,6 @@ // Test that SimpleURLLoader handles data URLs, which don't have headers. TEST_F(SimpleURLLoaderTest, DataURL) { ResourceRequest resource_request; - resource_request.method = "GET"; // Use a more interesting request than "/echo", just to verify more than the // request URL is hooked up. resource_request.url = GURL("data:text/plain,foo"); @@ -273,7 +269,6 @@ // different. TEST_F(SimpleURLLoaderTest, GzipBody) { ResourceRequest resource_request; - resource_request.method = "GET"; resource_request.url = test_server_.GetURL("/gzip-body?foo"); WaitForStringHelper string_helper; string_helper.RunRequest(url_loader_factory_.get(), resource_request); @@ -562,7 +557,6 @@ // before the request is even made, for that matter). TEST_F(SimpleURLLoaderTest, DestroyServiceBeforeResponseStarts) { ResourceRequest resource_request; - resource_request.method = "GET"; resource_request.url = test_server_.GetURL("/hung"); WaitForStringHelper string_helper; string_helper.simple_url_loader()
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 9e281e4..b779cc0 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -132,7 +132,8 @@ EnableCompositing(true); DCHECK(compositing_helper_.get()); - compositing_helper_->OnSetSurface(surface_info, sequence); + compositing_helper_->SetPrimarySurfaceInfo(surface_info); + compositing_helper_->SetFallbackSurfaceInfo(surface_info, sequence); } void BrowserPlugin::SendSatisfySequence(const viz::SurfaceSequence& sequence) {
diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index f72c341..8fad0fb1 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc
@@ -208,18 +208,18 @@ } void ChildFrameCompositingHelper::CheckSizeAndAdjustLayerProperties( - const gfx::Size& new_size, - float device_scale_factor, + const viz::SurfaceInfo& surface_info, cc::Layer* layer) { - if (buffer_size_ != new_size) { - buffer_size_ = new_size; - // The container size is in DIP, so is the layer size. - // Buffer size is in physical pixels, so we need to adjust - // it by the device scale factor. - gfx::Size device_scale_adjusted_size = - gfx::ScaleToFlooredSize(buffer_size_, 1.0f / device_scale_factor); - layer->SetBounds(device_scale_adjusted_size); - } + if (last_surface_size_in_pixels_ == surface_info.size_in_pixels()) + return; + + last_surface_size_in_pixels_ = surface_info.size_in_pixels(); + // The container size is in DIP, so is the layer size. + // Buffer size is in physical pixels, so we need to adjust + // it by the device scale factor. + gfx::Size device_scale_adjusted_size = gfx::ScaleToFlooredSize( + surface_info.size_in_pixels(), 1.0f / surface_info.device_scale_factor()); + layer->SetBounds(device_scale_adjusted_size); } void ChildFrameCompositingHelper::OnContainerDestroy() { @@ -259,13 +259,42 @@ UpdateWebLayer(std::move(layer)); } -void ChildFrameCompositingHelper::OnSetSurface( +void ChildFrameCompositingHelper::SetPrimarySurfaceInfo( + const viz::SurfaceInfo& surface_info) { + last_primary_surface_id_ = surface_info.id(); + float scale_factor = surface_info.device_scale_factor(); + // TODO(oshima): This is a stopgap fix so that the compositor does not + // scaledown the content when 2x frame data is added to 1x parent frame data. + // Fix this in cc/. + if (IsUseZoomForDSFEnabled()) + scale_factor = 1.0f; + + surface_layer_ = cc::SurfaceLayer::Create(surface_reference_factory_); + surface_layer_->SetMasksToBounds(true); + + viz::SurfaceInfo modified_surface_info(surface_info.id(), scale_factor, + surface_info.size_in_pixels()); + surface_layer_->SetPrimarySurfaceInfo(modified_surface_info); + + std::unique_ptr<cc_blink::WebLayerImpl> layer( + new cc_blink::WebLayerImpl(surface_layer_)); + // TODO(lfg): Investigate if it's possible to propagate the information about + // the child surface's opacity. https://crbug.com/629851. + layer->SetOpaque(false); + layer->SetContentsOpaqueIsFixed(true); + UpdateWebLayer(std::move(layer)); + + UpdateVisibility(true); + + CheckSizeAndAdjustLayerProperties( + surface_info, + static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer()); +} + +void ChildFrameCompositingHelper::SetFallbackSurfaceInfo( const viz::SurfaceInfo& surface_info, const viz::SurfaceSequence& sequence) { float scale_factor = surface_info.device_scale_factor(); - surface_id_ = surface_info.id(); - scoped_refptr<cc::SurfaceLayer> surface_layer = - cc::SurfaceLayer::Create(surface_reference_factory_); // TODO(oshima): This is a stopgap fix so that the compositor does not // scaledown the content when 2x frame data is added to 1x parent frame data. // Fix this in cc/. @@ -289,22 +318,7 @@ viz::SurfaceInfo modified_surface_info(surface_info.id(), scale_factor, surface_info.size_in_pixels()); - surface_layer->SetPrimarySurfaceInfo(modified_surface_info); - surface_layer->SetFallbackSurfaceInfo(modified_surface_info); - surface_layer->SetMasksToBounds(true); - std::unique_ptr<cc_blink::WebLayerImpl> layer( - new cc_blink::WebLayerImpl(surface_layer)); - // TODO(lfg): Investigate if it's possible to propagate the information about - // the child surface's opacity. https://crbug.com/629851. - layer->SetOpaque(false); - layer->SetContentsOpaqueIsFixed(true); - UpdateWebLayer(std::move(layer)); - - UpdateVisibility(true); - - CheckSizeAndAdjustLayerProperties( - surface_info.size_in_pixels(), surface_info.device_scale_factor(), - static_cast<cc_blink::WebLayerImpl*>(web_layer_.get())->layer()); + surface_layer_->SetFallbackSurfaceInfo(modified_surface_info); } void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
diff --git a/content/renderer/child_frame_compositing_helper.h b/content/renderer/child_frame_compositing_helper.h index a9b99d3..4346ec9 100644 --- a/content/renderer/child_frame_compositing_helper.h +++ b/content/renderer/child_frame_compositing_helper.h
@@ -15,6 +15,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/shared_memory.h" #include "base/memory/weak_ptr.h" +#include "cc/layers/surface_layer.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/common/surfaces/surface_reference_factory.h" #include "content/common/content_export.h" @@ -54,12 +55,13 @@ RenderFrameProxy* render_frame_proxy); void OnContainerDestroy(); - void OnSetSurface(const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence); + void SetPrimarySurfaceInfo(const viz::SurfaceInfo& surface_info); + void SetFallbackSurfaceInfo(const viz::SurfaceInfo& surface_info, + const viz::SurfaceSequence& sequence); void UpdateVisibility(bool); void ChildFrameGone(); - viz::SurfaceId surface_id() const { return surface_id_; } + const viz::SurfaceId& surface_id() const { return last_primary_surface_id_; } protected: // Friend RefCounted so that the dtor can be non-public. @@ -76,14 +78,14 @@ blink::WebPluginContainer* GetContainer(); - void CheckSizeAndAdjustLayerProperties(const gfx::Size& new_size, - float device_scale_factor, + void CheckSizeAndAdjustLayerProperties(const viz::SurfaceInfo& surface_info, cc::Layer* layer); void UpdateWebLayer(std::unique_ptr<blink::WebLayer> layer); const int host_routing_id_; - gfx::Size buffer_size_; + viz::SurfaceId last_primary_surface_id_; + gfx::Size last_surface_size_in_pixels_; // The lifetime of this weak pointer should be greater than the lifetime of // other member objects, as they may access this pointer during their @@ -91,8 +93,8 @@ const base::WeakPtr<BrowserPlugin> browser_plugin_; RenderFrameProxy* const render_frame_proxy_; + scoped_refptr<cc::SurfaceLayer> surface_layer_; std::unique_ptr<blink::WebLayer> web_layer_; - viz::SurfaceId surface_id_; blink::WebRemoteFrame* frame_; // If surface references are enabled use a stub reference factory.
diff --git a/content/renderer/gpu/actions_parser.cc b/content/renderer/gpu/actions_parser.cc index 0d3c654..615baba 100644 --- a/content/renderer/gpu/actions_parser.cc +++ b/content/renderer/gpu/actions_parser.cc
@@ -81,10 +81,7 @@ action_index_++; } - if (!gesture_params_) - gesture_params_ = base::MakeUnique<SyntheticPointerActionListParams>(); - - gesture_params_->gesture_source_type = + gesture_params_.gesture_source_type = ToSyntheticGestureSourceType(source_type_); // Group a list of actions from all pointers into a // SyntheticPointerActionListParams object, which is a list of actions, which @@ -96,7 +93,7 @@ if (action_index < pointer_list.size()) param_list.push_back(pointer_list[action_index]); } - gesture_params_->PushPointerActionParamsList(param_list); + gesture_params_.PushPointerActionParamsList(param_list); } return true;
diff --git a/content/renderer/gpu/actions_parser.h b/content/renderer/gpu/actions_parser.h index 7aa0bf8..5939685f 100644 --- a/content/renderer/gpu/actions_parser.h +++ b/content/renderer/gpu/actions_parser.h
@@ -27,8 +27,8 @@ ~ActionsParser(); bool ParsePointerActionSequence(); std::string error_message() { return error_message_; } - std::unique_ptr<SyntheticPointerActionListParams> gesture_params() { - return std::move(gesture_params_); + const SyntheticPointerActionListParams& gesture_params() const { + return gesture_params_; } private: @@ -37,7 +37,7 @@ bool ParseAction(const base::DictionaryValue& action, SyntheticPointerActionListParams::ParamList& param_list); - std::unique_ptr<SyntheticPointerActionListParams> gesture_params_; + SyntheticPointerActionListParams gesture_params_; std::vector<SyntheticPointerActionListParams::ParamList> pointer_actions_list_; size_t longest_action_sequence_; @@ -52,4 +52,4 @@ } // namespace content -#endif // CONTENT_RENDERER_GPU_ACTION_PARSER_H_ \ No newline at end of file +#endif // CONTENT_RENDERER_GPU_ACTION_PARSER_H_
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.cc b/content/renderer/gpu/gpu_benchmarking_extension.cc index f15bd60..820ffab 100644 --- a/content/renderer/gpu/gpu_benchmarking_extension.cc +++ b/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -42,6 +42,7 @@ #include "gin/handle.h" #include "gin/object_template_builder.h" #include "gpu/ipc/common/gpu_messages.h" +#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/WebKit/public/platform/WebMouseEvent.h" #include "third_party/WebKit/public/web/WebImageCache.h" #include "third_party/WebKit/public/web/WebKit.h" @@ -334,6 +335,7 @@ } bool BeginSmoothScroll(v8::Isolate* isolate, + mojom::InputInjectorPtr& injector, float pixels_to_scroll, v8::Local<v8::Function> callback, int gesture_source_type, @@ -370,22 +372,21 @@ new CallbackAndContext(isolate, callback, context.web_frame()->MainWorldScriptContext()); - std::unique_ptr<SyntheticSmoothScrollGestureParams> gesture_params( - new SyntheticSmoothScrollGestureParams); + SyntheticSmoothScrollGestureParams gesture_params; if (gesture_source_type < 0 || gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) { return false; } - gesture_params->gesture_source_type = + gesture_params.gesture_source_type = static_cast<SyntheticGestureParams::GestureSourceType>( gesture_source_type); - gesture_params->speed_in_pixels_s = speed_in_pixels_s; - gesture_params->prevent_fling = prevent_fling; + gesture_params.speed_in_pixels_s = speed_in_pixels_s; + gesture_params.prevent_fling = prevent_fling; - gesture_params->anchor.SetPoint(start_x * page_scale_factor, - start_y * page_scale_factor); + gesture_params.anchor.SetPoint(start_x * page_scale_factor, + start_y * page_scale_factor); float distance_length = pixels_to_scroll * page_scale_factor; gfx::Vector2dF distance; @@ -412,20 +413,17 @@ } else { return false; } - gesture_params->distances.push_back(distance); + gesture_params.distances.push_back(distance); - // TODO(678879): If the render_view_impl is destroyed while the gesture is in - // progress, we will leak the callback and context. This needs to be fixed, - // somehow, see https://crbug.com/678879. - context.render_view_impl()->GetWidget()->QueueSyntheticGesture( - std::move(gesture_params), - base::Bind(&OnSyntheticGestureCompleted, - base::RetainedRef(callback_and_context))); + injector->QueueSyntheticSmoothScroll( + gesture_params, base::BindOnce(&OnSyntheticGestureCompleted, + base::RetainedRef(callback_and_context))); return true; } bool BeginSmoothDrag(v8::Isolate* isolate, + mojom::InputInjectorPtr& injector, float start_x, float start_y, float end_x, @@ -440,30 +438,25 @@ new CallbackAndContext(isolate, callback, context.web_frame()->MainWorldScriptContext()); - std::unique_ptr<SyntheticSmoothDragGestureParams> gesture_params( - new SyntheticSmoothDragGestureParams); + SyntheticSmoothDragGestureParams gesture_params; // Convert coordinates from CSS pixels to density independent pixels (DIPs). float page_scale_factor = context.web_view()->PageScaleFactor(); - gesture_params->start_point.SetPoint(start_x * page_scale_factor, - start_y * page_scale_factor); + gesture_params.start_point.SetPoint(start_x * page_scale_factor, + start_y * page_scale_factor); gfx::PointF end_point(end_x * page_scale_factor, end_y * page_scale_factor); - gfx::Vector2dF distance = end_point - gesture_params->start_point; - gesture_params->distances.push_back(distance); - gesture_params->speed_in_pixels_s = speed_in_pixels_s * page_scale_factor; - gesture_params->gesture_source_type = + gfx::Vector2dF distance = end_point - gesture_params.start_point; + gesture_params.distances.push_back(distance); + gesture_params.speed_in_pixels_s = speed_in_pixels_s * page_scale_factor; + gesture_params.gesture_source_type = static_cast<SyntheticGestureParams::GestureSourceType>( gesture_source_type); - // TODO(678879): If the render_view_impl is destroyed while the gesture is in - // progress, we will leak the callback and context. This needs to be fixed, - // somehow, see https://crbug.com/678879. - context.render_view_impl()->GetWidget()->QueueSyntheticGesture( - std::move(gesture_params), - base::Bind(&OnSyntheticGestureCompleted, - base::RetainedRef(callback_and_context))); + injector->QueueSyntheticSmoothDrag( + gesture_params, base::BindOnce(&OnSyntheticGestureCompleted, + base::RetainedRef(callback_and_context))); return true; } @@ -545,17 +538,18 @@ gin::WrapperInfo GpuBenchmarking::kWrapperInfo = {gin::kEmbedderNativeGin}; // static -void GpuBenchmarking::Install(blink::WebLocalFrame* frame) { +void GpuBenchmarking::Install(RenderFrameImpl* frame) { v8::Isolate* isolate = blink::MainThreadIsolate(); v8::HandleScope handle_scope(isolate); - v8::Local<v8::Context> context = frame->MainWorldScriptContext(); + v8::Local<v8::Context> context = + frame->GetWebFrame()->MainWorldScriptContext(); if (context.IsEmpty()) return; v8::Context::Scope context_scope(context); gin::Handle<GpuBenchmarking> controller = - gin::CreateHandle(isolate, new GpuBenchmarking()); + gin::CreateHandle(isolate, new GpuBenchmarking(frame)); if (controller.IsEmpty()) return; @@ -564,7 +558,9 @@ chrome->Set(gin::StringToV8(isolate, "gpuBenchmarking"), controller.ToV8()); } -GpuBenchmarking::GpuBenchmarking() { +GpuBenchmarking::GpuBenchmarking(RenderFrameImpl* frame) { + frame->GetRemoteInterfaces()->GetInterface( + mojo::MakeRequest(&input_injector_)); } GpuBenchmarking::~GpuBenchmarking() { @@ -702,15 +698,9 @@ return false; } - return BeginSmoothScroll(args->isolate(), - pixels_to_scroll, - callback, - gesture_source_type, - direction, - speed_in_pixels_s, - true, - start_x, - start_y); + return BeginSmoothScroll(args->isolate(), input_injector_, pixels_to_scroll, + callback, gesture_source_type, direction, + speed_in_pixels_s, true, start_x, start_y); } bool GpuBenchmarking::SmoothDrag(gin::Arguments* args) { @@ -736,13 +726,8 @@ return false; } - return BeginSmoothDrag(args->isolate(), - start_x, - start_y, - end_x, - end_y, - callback, - gesture_source_type, + return BeginSmoothDrag(args->isolate(), input_injector_, start_x, start_y, + end_x, end_y, callback, gesture_source_type, speed_in_pixels_s); } @@ -770,15 +755,10 @@ return false; } - return BeginSmoothScroll(args->isolate(), - -pixels_to_scroll, - callback, - 1, // TOUCH_INPUT - direction, - speed_in_pixels_s, - false, - start_x, - start_y); + return BeginSmoothScroll( + args->isolate(), input_injector_, -pixels_to_scroll, callback, + 1, // TOUCH_INPUT + direction, speed_in_pixels_s, false, start_x, start_y); } bool GpuBenchmarking::ScrollBounce(gin::Arguments* args) { @@ -813,13 +793,12 @@ new CallbackAndContext(args->isolate(), callback, context.web_frame()->MainWorldScriptContext()); - std::unique_ptr<SyntheticSmoothScrollGestureParams> gesture_params( - new SyntheticSmoothScrollGestureParams); + SyntheticSmoothScrollGestureParams gesture_params; - gesture_params->speed_in_pixels_s = speed_in_pixels_s; + gesture_params.speed_in_pixels_s = speed_in_pixels_s; - gesture_params->anchor.SetPoint(start_x * page_scale_factor, - start_y * page_scale_factor); + gesture_params.anchor.SetPoint(start_x * page_scale_factor, + start_y * page_scale_factor); distance_length *= page_scale_factor; overscroll_length *= page_scale_factor; @@ -842,17 +821,12 @@ } for (int i = 0; i < repeat_count; i++) { - gesture_params->distances.push_back(distance); - gesture_params->distances.push_back(-distance + overscroll); + gesture_params.distances.push_back(distance); + gesture_params.distances.push_back(-distance + overscroll); } - - // TODO(678879): If the render_view_impl is destroyed while the gesture is in - // progress, we will leak the callback and context. This needs to be fixed, - // somehow, see https://crbug.com/678879. - context.render_view_impl()->GetWidget()->QueueSyntheticGesture( - std::move(gesture_params), - base::Bind(&OnSyntheticGestureCompleted, - base::RetainedRef(callback_and_context))); + input_injector_->QueueSyntheticSmoothScroll( + gesture_params, base::BindOnce(&OnSyntheticGestureCompleted, + base::RetainedRef(callback_and_context))); return true; } @@ -877,30 +851,24 @@ return false; } - std::unique_ptr<SyntheticPinchGestureParams> gesture_params( - new SyntheticPinchGestureParams); + SyntheticPinchGestureParams gesture_params; // TODO(bokan): Remove page scale here when change land in Catapult. // Convert coordinates from CSS pixels to density independent pixels (DIPs). float page_scale_factor = context.web_view()->PageScaleFactor(); - gesture_params->scale_factor = scale_factor; - gesture_params->anchor.SetPoint(anchor_x * page_scale_factor, - anchor_y * page_scale_factor); - gesture_params->relative_pointer_speed_in_pixels_s = + gesture_params.scale_factor = scale_factor; + gesture_params.anchor.SetPoint(anchor_x * page_scale_factor, + anchor_y * page_scale_factor); + gesture_params.relative_pointer_speed_in_pixels_s = relative_pointer_speed_in_pixels_s; scoped_refptr<CallbackAndContext> callback_and_context = new CallbackAndContext(args->isolate(), callback, context.web_frame()->MainWorldScriptContext()); - - // TODO(678879): If the render_view_impl is destroyed while the gesture is in - // progress, we will leak the callback and context. This needs to be fixed, - // somehow, see https://crbug.com/678879. - context.render_view_impl()->GetWidget()->QueueSyntheticGesture( - std::move(gesture_params), - base::Bind(&OnSyntheticGestureCompleted, - base::RetainedRef(callback_and_context))); + input_injector_->QueueSyntheticPinch( + gesture_params, base::BindOnce(&OnSyntheticGestureCompleted, + base::RetainedRef(callback_and_context))); return true; } @@ -981,32 +949,26 @@ return false; } - std::unique_ptr<SyntheticTapGestureParams> gesture_params( - new SyntheticTapGestureParams); + SyntheticTapGestureParams gesture_params; - gesture_params->position.SetPoint(position_x * page_scale_factor, - position_y * page_scale_factor); - gesture_params->duration_ms = duration_ms; + gesture_params.position.SetPoint(position_x * page_scale_factor, + position_y * page_scale_factor); + gesture_params.duration_ms = duration_ms; if (gesture_source_type < 0 || gesture_source_type > SyntheticGestureParams::GESTURE_SOURCE_TYPE_MAX) { return false; } - gesture_params->gesture_source_type = + gesture_params.gesture_source_type = static_cast<SyntheticGestureParams::GestureSourceType>( gesture_source_type); scoped_refptr<CallbackAndContext> callback_and_context = new CallbackAndContext(args->isolate(), callback, context.web_frame()->MainWorldScriptContext()); - - // TODO(678879): If the render_view_impl is destroyed while the gesture is in - // progress, we will leak the callback and context. This needs to be fixed, - // somehow, see https://crbug.com/678879. - context.render_view_impl()->GetWidget()->QueueSyntheticGesture( - std::move(gesture_params), - base::Bind(&OnSyntheticGestureCompleted, - base::RetainedRef(callback_and_context))); + input_injector_->QueueSyntheticTap( + gesture_params, base::BindOnce(&OnSyntheticGestureCompleted, + base::RetainedRef(callback_and_context))); return true; } @@ -1035,9 +997,6 @@ if (!actions_parser.ParsePointerActionSequence()) return false; - std::unique_ptr<SyntheticPointerActionListParams> gesture_params = - actions_parser.gesture_params(); - if (!GetOptionalArg(args, &callback)) { args->ThrowError(); return false; @@ -1047,13 +1006,10 @@ scoped_refptr<CallbackAndContext> callback_and_context = new CallbackAndContext(args->isolate(), callback, context.web_frame()->MainWorldScriptContext()); - // TODO(678879): If the render_view_impl is destroyed while the gesture is in - // progress, we will leak the callback and context. This needs to be fixed, - // somehow, see https://crbug.com/678879. - context.render_view_impl()->GetWidget()->QueueSyntheticGesture( - std::move(gesture_params), - base::Bind(&OnSyntheticGestureCompleted, - base::RetainedRef(callback_and_context))); + input_injector_->QueueSyntheticPointerAction( + actions_parser.gesture_params(), + base::BindOnce(&OnSyntheticGestureCompleted, + base::RetainedRef(callback_and_context))); return true; }
diff --git a/content/renderer/gpu/gpu_benchmarking_extension.h b/content/renderer/gpu/gpu_benchmarking_extension.h index fbb0022c..8d03051f 100644 --- a/content/renderer/gpu/gpu_benchmarking_extension.h +++ b/content/renderer/gpu/gpu_benchmarking_extension.h
@@ -6,12 +6,9 @@ #define CONTENT_RENDERER_GPU_GPU_BENCHMARKING_EXTENSION_H_ #include "base/macros.h" +#include "content/common/input/input_injector.mojom.h" #include "gin/wrappable.h" -namespace blink { -class WebLocalFrame; -} - namespace gin { class Arguments; } @@ -23,14 +20,16 @@ namespace content { +class RenderFrameImpl; + // gin class for gpu benchmarking class GpuBenchmarking : public gin::Wrappable<GpuBenchmarking> { public: static gin::WrapperInfo kWrapperInfo; - static void Install(blink::WebLocalFrame* frame); + static void Install(RenderFrameImpl* frame); private: - GpuBenchmarking(); + explicit GpuBenchmarking(RenderFrameImpl* frame); ~GpuBenchmarking() override; // gin::Wrappable. @@ -65,6 +64,7 @@ bool HasGpuProcess(); void GetGpuDriverBugWorkarounds(gin::Arguments* args); + mojom::InputInjectorPtr input_injector_; DISALLOW_COPY_AND_ASSIGN(GpuBenchmarking); };
diff --git a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc index c30b4d3..5672d52 100644 --- a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc +++ b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
@@ -740,7 +740,7 @@ EXPECT_EQ(output_sample_rate, mixer->GetOutputParamsForTesting().sample_rate()); -#if defined(OS_LINUX) || defined(OS_MACOSX) +#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_FUCHSIA) // Use 10 ms buffer (441 frames per buffer). EXPECT_EQ(output_sample_rate / 100, mixer->GetOutputParamsForTesting().frames_per_buffer());
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index ff9f5a7d..2540e89 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3817,7 +3817,7 @@ *base::CommandLine::ForCurrentProcess(); if (command_line.HasSwitch(cc::switches::kEnableGpuBenchmarking)) - GpuBenchmarking::Install(frame_); + GpuBenchmarking::Install(this); if (command_line.HasSwitch(switches::kEnableSkiaBenchmarking)) SkiaBenchmarking::Install(frame_);
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 7395813..35707b7 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -213,6 +213,13 @@ CHECK(result.second) << "Inserted a duplicate item."; } +void RenderFrameProxy::ResendFrameRects() { + // Reset |frame_rect_| in order to allocate a new viz::LocalSurfaceId. + gfx::Rect rect = frame_rect_; + frame_rect_ = gfx::Rect(); + FrameRectsChanged(rect); +} + void RenderFrameProxy::WillBeginCompositorFrame() { if (compositing_helper_) { FrameHostMsg_HittestData_Params params; @@ -283,6 +290,7 @@ IPC_MESSAGE_HANDLER(FrameMsg_ChildFrameProcessGone, OnChildFrameProcessGone) IPC_MESSAGE_HANDLER(FrameMsg_SetChildFrameSurface, OnSetChildFrameSurface) IPC_MESSAGE_HANDLER(FrameMsg_UpdateOpener, OnUpdateOpener) + IPC_MESSAGE_HANDLER(FrameMsg_ViewChanged, OnViewChanged) IPC_MESSAGE_HANDLER(FrameMsg_DidStartLoading, OnDidStartLoading) IPC_MESSAGE_HANDLER(FrameMsg_DidStopLoading, OnDidStopLoading) IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateFramePolicy, OnDidUpdateFramePolicy) @@ -338,7 +346,11 @@ compositing_helper_ = ChildFrameCompositingHelper::CreateForRenderFrameProxy(this); } - compositing_helper_->OnSetSurface(surface_info, sequence); + // TODO(fsamuel): When surface synchronization is enabled, only set the + // fallback here. The primary should be updated on resize/device scale factor + // change. + compositing_helper_->SetPrimarySurfaceInfo(surface_info); + compositing_helper_->SetFallbackSurfaceInfo(surface_info, sequence); } void RenderFrameProxy::OnUpdateOpener(int opener_routing_id) { @@ -350,6 +362,12 @@ web_frame_->DidStartLoading(); } +void RenderFrameProxy::OnViewChanged() { + // Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view + // changes. + ResendFrameRects(); +} + void RenderFrameProxy::OnDidStopLoading() { web_frame_->DidStopLoading(); } @@ -503,11 +521,17 @@ void RenderFrameProxy::FrameRectsChanged(const blink::WebRect& frame_rect) { gfx::Rect rect = frame_rect; + if (frame_rect_.size() != rect.size() || !local_surface_id_.is_valid()) + local_surface_id_ = local_surface_id_allocator_.GenerateId(); + + frame_rect_ = rect; + if (IsUseZoomForDSFEnabled()) { rect = gfx::ScaleToEnclosingRect( rect, 1.f / render_widget_->GetOriginalDeviceScaleFactor()); } - Send(new FrameHostMsg_FrameRectChanged(routing_id_, rect)); + + Send(new FrameHostMsg_FrameRectChanged(routing_id_, rect, local_surface_id_)); } void RenderFrameProxy::UpdateRemoteViewportIntersection(
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index cbde0285..a471d36c 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "components/viz/common/surfaces/local_surface_id_allocator.h" #include "content/common/content_export.h" #include "content/common/feature_policy/feature_policy.h" #include "ipc/ipc_listener.h" @@ -156,6 +157,8 @@ RenderViewImpl* render_view, RenderWidget* render_widget); + void ResendFrameRects(); + // IPC::Listener bool OnMessageReceived(const IPC::Message& msg) override; @@ -166,6 +169,7 @@ void OnSetChildFrameSurface(const viz::SurfaceInfo& surface_info, const viz::SurfaceSequence& sequence); void OnUpdateOpener(int opener_routing_id); + void OnViewChanged(); void OnDidStopLoading(); void OnDidUpdateFramePolicy( blink::WebSandboxFlags flags, @@ -200,6 +204,10 @@ RenderViewImpl* render_view_; RenderWidget* render_widget_; + gfx::Rect frame_rect_; + viz::LocalSurfaceId local_surface_id_; + viz::LocalSurfaceIdAllocator local_surface_id_allocator_; + DISALLOW_COPY_AND_ASSIGN(RenderFrameProxy); };
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index f9ac0e9..fe31bc9 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1018,6 +1018,9 @@ WebRuntimeFeatures::EnableNewRemotePlaybackPipeline( base::FeatureList::IsEnabled(media::kNewRemotePlaybackPipeline)); + WebRuntimeFeatures::EnablePreloadDefaultIsMetadata( + base::FeatureList::IsEnabled(media::kPreloadDefaultIsMetadata)); + settings->SetPresentationReceiver(prefs.presentation_receiver); settings->SetMediaControlsEnabled(prefs.media_controls_enabled);
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 7b18efc..2ac4221 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -32,7 +32,6 @@ #include "content/common/content_switches_internal.h" #include "content/common/drag_event_source_info.h" #include "content/common/drag_messages.h" -#include "content/common/input/synthetic_gesture_packet.h" #include "content/common/input_messages.h" #include "content/common/render_message_filter.mojom.h" #include "content/common/swapped_out_messages.h" @@ -628,8 +627,6 @@ IPC_MESSAGE_HANDLER(InputMsg_SetEditCommandsForNextKeyEvent, OnSetEditCommandsForNextKeyEvent) IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetFocus) - IPC_MESSAGE_HANDLER(InputMsg_SyntheticGestureCompleted, - OnSyntheticGestureCompleted) IPC_MESSAGE_HANDLER(ViewMsg_ShowContextMenu, OnShowContextMenu) IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose) IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize) @@ -1551,19 +1548,6 @@ FROM_HERE, base::Bind(&RenderWidget::DoDeferredClose, this)); } -void RenderWidget::QueueSyntheticGesture( - std::unique_ptr<SyntheticGestureParams> gesture_params, - const SyntheticGestureCompletionCallback& callback) { - DCHECK(!callback.is_null()); - - pending_synthetic_gesture_callbacks_.push(callback); - - SyntheticGesturePacket gesture_packet; - gesture_packet.set_gesture_params(std::move(gesture_params)); - - Send(new InputHostMsg_QueueSyntheticGesture(routing_id_, gesture_packet)); -} - void RenderWidget::Close() { screen_metrics_emulator_.reset(); WillCloseLayerTreeView(); @@ -1778,13 +1762,6 @@ compositor_->SetNeedsRedrawRect(gfx::Rect(size_to_paint)); } -void RenderWidget::OnSyntheticGestureCompleted() { - DCHECK(!pending_synthetic_gesture_callbacks_.empty()); - - pending_synthetic_gesture_callbacks_.front().Run(); - pending_synthetic_gesture_callbacks_.pop(); -} - void RenderWidget::OnSetTextDirection(WebTextDirection direction) { if (!GetWebWidget()) return;
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 5e26b77..31b94150 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -30,7 +30,6 @@ #include "content/common/drag_event_source_info.h" #include "content/common/edit_command.h" #include "content/common/features.h" -#include "content/common/input/synthetic_gesture_params.h" #include "content/common/widget.mojom.h" #include "content/public/common/drop_data.h" #include "content/public/common/screen_info.h" @@ -350,15 +349,6 @@ void SetHandlingInputEventForTesting(bool handling_input_event); - // Callback for use with synthetic gestures (e.g. BeginSmoothScroll). - typedef base::Callback<void()> SyntheticGestureCompletionCallback; - - // Send a synthetic gesture to the browser to be queued to the synthetic - // gesture controller. - void QueueSyntheticGesture( - std::unique_ptr<SyntheticGestureParams> gesture_params, - const SyntheticGestureCompletionCallback& callback); - // Deliveres |message| together with compositor state change updates. The // exact behavior depends on |policy|. // This mechanism is not a drop-in replacement for IPC: messages sent this way @@ -548,7 +538,6 @@ virtual void OnDeviceScaleFactorChanged(); void OnRepaint(gfx::Size size_to_paint); - void OnSyntheticGestureCompleted(); void OnSetTextDirection(blink::WebTextDirection direction); void OnGetFPS(); void OnUpdateScreenRects(const gfx::Rect& view_screen_rect, @@ -790,12 +779,6 @@ // |screen_info_| on some platforms, and defaults to 1 on other platforms. float device_scale_factor_; - // State associated with synthetic gestures. Synthetic gestures are processed - // in-order, so a queue is sufficient to identify the correct state for a - // completed gesture. - std::queue<SyntheticGestureCompletionCallback> - pending_synthetic_gesture_callbacks_; - // True if the IME requests updated composition info. bool monitor_composition_info_;
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc index 6c3847a..5759285 100644 --- a/content/zygote/zygote_main_linux.cc +++ b/content/zygote/zygote_main_linux.cc
@@ -477,9 +477,11 @@ ZygotePreSandboxInit(); - // Check that the pre-sandbox initialization didn't spawn threads. +// Check that the pre-sandbox initialization didn't spawn threads. +// It's not just our code which may do so - some system-installed libraries +// are known to be culprits, e.g. lttng. #if !defined(THREAD_SANITIZER) - DCHECK(sandbox::ThreadHelpers::IsSingleThreaded()); + CHECK(sandbox::ThreadHelpers::IsSingleThreaded()); #endif sandbox::SetuidSandboxClient* setuid_sandbox =
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos.cc b/extensions/browser/api/networking_private/networking_private_chromeos.cc index a056533..59dcbc9 100644 --- a/extensions/browser/api/networking_private/networking_private_chromeos.cc +++ b/extensions/browser/api/networking_private/networking_private_chromeos.cc
@@ -151,9 +151,15 @@ if (device && state == private_api::DEVICE_STATE_TYPE_ENABLED) properties->scanning.reset(new bool(device->scanning())); if (device && type == ::onc::network_config::kCellular) { - properties->sim_present.reset(new bool(!device->IsSimAbsent())); - if (!device->sim_lock_type().empty()) - properties->sim_lock_type.reset(new std::string(device->sim_lock_type())); + bool sim_present = !device->IsSimAbsent(); + properties->sim_present = std::make_unique<bool>(sim_present); + if (sim_present) { + auto sim_lock_status = base::MakeUnique<private_api::SIMLockStatus>(); + sim_lock_status->lock_enabled = device->sim_lock_enabled(); + sim_lock_status->lock_type = device->sim_lock_type(); + sim_lock_status->retries_left.reset(new int(device->sim_retries_left())); + properties->sim_lock_status = std::move(sim_lock_status); + } } device_state_list->push_back(std::move(properties)); }
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index e8bb112..5bf78370 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -303,7 +303,7 @@ // process. We use a filter here so that only event listeners for a particular // <webview> will fire. if (is_web_view_guest) { - event_filtering_info.instance_id = is_web_view_guest; + event_filtering_info.instance_id = web_view_instance_id; histogram_value = events::WEB_VIEW_INTERNAL_ON_MESSAGE; event_name = webview::kEventMessage; } else {
diff --git a/extensions/common/api/bluetooth_private.idl b/extensions/common/api/bluetooth_private.idl index b2d760b9..f1b56c6 100644 --- a/extensions/common/api/bluetooth_private.idl +++ b/extensions/common/api/bluetooth_private.idl
@@ -79,6 +79,9 @@ DOMString? name; // Whether or not the adapter has power. + // Setting the bluetooth power by setting this property is not recommended, + // instead a user pref (ash::prefs::kUserBluetoothAdapterEnabled) should be + // set. boolean? powered; // Whether the adapter is discoverable by other devices.
diff --git a/extensions/common/api/networking_onc.idl b/extensions/common/api/networking_onc.idl index cee468c..024d4d4 100644 --- a/extensions/common/api/networking_onc.idl +++ b/extensions/common/api/networking_onc.idl
@@ -818,12 +818,11 @@ // Set if the device is enabled. True if the device is currently scanning. boolean? Scanning; - // Set to the SIM lock type if the device type is Cellular and the device - // is locked. - DOMString? SimLockType; + // The SIM lock status if Type = Cellular and SIMPresent = True. + SIMLockStatus? SIMLockStatus; // Set to the SIM present state if the device type is Cellular. - boolean? SimPresent; + boolean? SIMPresent; // The current state of the device. DeviceStateType State;
diff --git a/extensions/common/api/networking_private.idl b/extensions/common/api/networking_private.idl index 2ec75df..00afb36 100644 --- a/extensions/common/api/networking_private.idl +++ b/extensions/common/api/networking_private.idl
@@ -761,12 +761,11 @@ // Set if the device is enabled. True if the device is currently scanning. boolean? Scanning; - // Set to the SIM lock type if the device type is Cellular and the device - // is locked. - DOMString? SimLockType; + // The SIM lock status if Type = Cellular and SIMPresent = True. + SIMLockStatus? SIMLockStatus; // Set to the SIM present state if the device type is Cellular. - boolean? SimPresent; + boolean? SIMPresent; // The current state of the device. DeviceStateType State;
diff --git a/extensions/renderer/extension_bindings_system.cc b/extensions/renderer/extension_bindings_system.cc index ffee346..c7fd2d5 100644 --- a/extensions/renderer/extension_bindings_system.cc +++ b/extensions/renderer/extension_bindings_system.cc
@@ -4,6 +4,7 @@ #include "extensions/renderer/extension_bindings_system.h" +#include "base/metrics/histogram_macros.h" #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/externally_connectable.h" #include "extensions/renderer/renderer_extension_registry.h" @@ -11,6 +12,12 @@ namespace extensions { +namespace { + +const int kHistogramBucketCount = 50; + +} // namespace + // static bool ExtensionBindingsSystem::IsRuntimeAvailableToContext( ScriptContext* context) { @@ -29,4 +36,67 @@ "app", "webstore", "dashboardPrivate", }; +void ExtensionBindingsSystem::LogUpdateBindingsForContextTime( + Feature::Context context_type, + base::TimeDelta elapsed) { + static const int kTenSecondsInMicroseconds = 10000000; + switch (context_type) { + case Feature::UNSPECIFIED_CONTEXT: + break; + case Feature::WEB_PAGE_CONTEXT: + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Extensions.Bindings.UpdateBindingsForContextTime.WebPageContext", + elapsed.InMicroseconds(), 1, kTenSecondsInMicroseconds, + kHistogramBucketCount); + break; + case Feature::BLESSED_WEB_PAGE_CONTEXT: + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Extensions.Bindings.UpdateBindingsForContextTime." + "BlessedWebPageContext", + elapsed.InMicroseconds(), 1, kTenSecondsInMicroseconds, + kHistogramBucketCount); + break; + case Feature::SERVICE_WORKER_CONTEXT: + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Extensions.Bindings.UpdateBindingsForContextTime." + "ServiceWorkerContext", + elapsed.InMicroseconds(), 1, kTenSecondsInMicroseconds, + kHistogramBucketCount); + break; + case Feature::BLESSED_EXTENSION_CONTEXT: + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Extensions.Bindings.UpdateBindingsForContextTime." + "BlessedExtensionContext", + elapsed.InMicroseconds(), 1, kTenSecondsInMicroseconds, + kHistogramBucketCount); + break; + case Feature::LOCK_SCREEN_EXTENSION_CONTEXT: + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Extensions.Bindings.UpdateBindingsForContextTime." + "LockScreenExtensionContext", + elapsed.InMicroseconds(), 1, kTenSecondsInMicroseconds, + kHistogramBucketCount); + break; + case Feature::UNBLESSED_EXTENSION_CONTEXT: + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Extensions.Bindings.UpdateBindingsForContextTime." + "UnblessedExtensionContext", + elapsed.InMicroseconds(), 1, kTenSecondsInMicroseconds, + kHistogramBucketCount); + break; + case Feature::CONTENT_SCRIPT_CONTEXT: + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Extensions.Bindings.UpdateBindingsForContextTime." + "ContentScriptContext", + elapsed.InMicroseconds(), 1, kTenSecondsInMicroseconds, + kHistogramBucketCount); + break; + case Feature::WEBUI_CONTEXT: + UMA_HISTOGRAM_CUSTOM_COUNTS( + "Extensions.Bindings.UpdateBindingsForContextTime.WebUIContext", + elapsed.InMicroseconds(), 1, kTenSecondsInMicroseconds, + kHistogramBucketCount); + } +} + } // namespace extensions
diff --git a/extensions/renderer/extension_bindings_system.h b/extensions/renderer/extension_bindings_system.h index 6791fcab..d1e0d6ef 100644 --- a/extensions/renderer/extension_bindings_system.h +++ b/extensions/renderer/extension_bindings_system.h
@@ -7,7 +7,9 @@ #include <string> +#include "base/time/time.h" #include "extensions/common/extension_id.h" +#include "extensions/common/features/feature.h" namespace base { class ListValue; @@ -76,6 +78,11 @@ // case of extensions communicating with external websites). static bool IsRuntimeAvailableToContext(ScriptContext* context); + // Logs the amount of time taken to update the bindings for a given context + // (i.e., UpdateBindingsForContext()). + static void LogUpdateBindingsForContextTime(Feature::Context context_type, + base::TimeDelta elapsed); + // The APIs that could potentially be available to webpage-like contexts. // This is the list of possible features; most web pages will not have access // to these APIs.
diff --git a/extensions/renderer/js_extension_bindings_system.cc b/extensions/renderer/js_extension_bindings_system.cc index 457eb570..dd73b13 100644 --- a/extensions/renderer/js_extension_bindings_system.cc +++ b/extensions/renderer/js_extension_bindings_system.cc
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/strings/string_split.h" +#include "base/timer/elapsed_timer.h" #include "content/public/child/v8_value_converter.h" #include "content/public/common/content_switches.h" #include "extensions/common/extension.h" @@ -158,6 +159,8 @@ void JsExtensionBindingsSystem::UpdateBindingsForContext( ScriptContext* context) { + base::ElapsedTimer timer; + v8::HandleScope handle_scope(context->isolate()); v8::Context::Scope context_scope(context->v8_context()); @@ -223,6 +226,8 @@ break; } } + + LogUpdateBindingsForContextTime(context->context_type(), timer.Elapsed()); } void JsExtensionBindingsSystem::HandleResponse(int request_id,
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc index 439ce42b..8ef8369 100644 --- a/extensions/renderer/native_extension_bindings_system.cc +++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -7,6 +7,8 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" +#include "base/timer/elapsed_timer.h" #include "content/public/child/worker_thread.h" #include "content/public/common/console_message_level.h" #include "content/public/common/content_switches.h" @@ -452,6 +454,7 @@ void NativeExtensionBindingsSystem::UpdateBindingsForContext( ScriptContext* context) { + base::ElapsedTimer timer; v8::Isolate* isolate = context->isolate(); v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> v8_context = context->v8_context(); @@ -509,6 +512,7 @@ if (IsRuntimeAvailableToContext(context) && !set_accessor("runtime")) LOG(ERROR) << "Failed to create API on Chrome object."; + LogUpdateBindingsForContextTime(context->context_type(), timer.Elapsed()); return; } @@ -540,6 +544,8 @@ return; } } + + LogUpdateBindingsForContextTime(context->context_type(), timer.Elapsed()); } void NativeExtensionBindingsSystem::DispatchEventInContext( @@ -647,6 +653,7 @@ CHECK( gin::Converter<std::string>::FromV8(isolate, api_name, &api_name_string)); + base::ElapsedTimer timer; v8::Local<v8::Object> root_binding = CreateFullBinding( context, script_context, &data->bindings_system->api_system_, FeatureProvider::GetAPIFeatures(), api_name_string); @@ -658,6 +665,9 @@ if (!success.IsJust() || !success.FromJust()) return v8::Local<v8::Object>(); + UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.Bindings.NativeBindingCreationTime", + timer.Elapsed().InMicroseconds(), 1, 10000000, + 50); return root_binding; }
diff --git a/ios/chrome/browser/ui/history/BUILD.gn b/ios/chrome/browser/ui/history/BUILD.gn index 4f71d1c..83decf6b 100644 --- a/ios/chrome/browser/ui/history/BUILD.gn +++ b/ios/chrome/browser/ui/history/BUILD.gn
@@ -15,8 +15,6 @@ "history_collection_view_controller.mm", "history_entries_status_item.h", "history_entries_status_item.mm", - "history_entry.cc", - "history_entry.h", "history_entry_inserter.h", "history_entry_inserter.mm", "history_entry_item.h", @@ -27,11 +25,10 @@ "history_search_view.mm", "history_search_view_controller.h", "history_search_view_controller.mm", - "history_service_facade.h", - "history_service_facade.mm", - "history_service_facade_delegate.h", "history_util.h", "history_util.mm", + "ios_browsing_history_driver.h", + "ios_browsing_history_driver.mm", ] deps = [ "//base", @@ -93,8 +90,6 @@ "history_entry_inserter_unittest.mm", "history_entry_item_unittest.mm", "history_search_view_controller_unittest.mm", - "history_service_facade_unittest.mm", - "history_util_unittest.mm", ] deps = [ ":history",
diff --git a/ios/chrome/browser/ui/history/history_collection_view_controller.mm b/ios/chrome/browser/ui/history/history_collection_view_controller.mm index 9d5f9ebd..fd8c1fe 100644 --- a/ios/chrome/browser/ui/history/history_collection_view_controller.mm +++ b/ios/chrome/browser/ui/history/history_collection_view_controller.mm
@@ -13,13 +13,19 @@ #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "components/browser_sync/profile_sync_service.h" #include "components/browsing_data/core/history_notice_utils.h" +#include "components/history/core/browser/browsing_history_driver.h" +#include "components/history/core/browser/browsing_history_service.h" +#include "components/keyed_service/core/service_access_type.h" #include "components/strings/grit/components_strings.h" #include "components/url_formatter/url_formatter.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" +#include "ios/chrome/browser/history/history_service_factory.h" #import "ios/chrome/browser/signin/authentication_service.h" #include "ios/chrome/browser/signin/authentication_service_factory.h" +#include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" @@ -29,12 +35,10 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h" #include "ios/chrome/browser/ui/history/history_entries_status_item.h" -#include "ios/chrome/browser/ui/history/history_entry.h" #include "ios/chrome/browser/ui/history/history_entry_inserter.h" #import "ios/chrome/browser/ui/history/history_entry_item.h" -#include "ios/chrome/browser/ui/history/history_service_facade.h" -#include "ios/chrome/browser/ui/history/history_service_facade_delegate.h" #include "ios/chrome/browser/ui/history/history_util.h" +#include "ios/chrome/browser/ui/history/ios_browsing_history_driver.h" #import "ios/chrome/browser/ui/url_loader.h" #import "ios/chrome/browser/ui/util/pasteboard_util.h" #include "ios/chrome/grit/ios_strings.h" @@ -51,6 +55,8 @@ #error "This file requires ARC support." #endif +using history::BrowsingHistoryService; + namespace { typedef NS_ENUM(NSInteger, ItemType) { ItemTypeHistoryEntry = kItemTypeEnumZero, @@ -68,9 +74,11 @@ @interface HistoryCollectionViewController ()<HistoryEntriesStatusItemDelegate, HistoryEntryInserterDelegate, HistoryEntryItemDelegate, - HistoryServiceFacadeDelegate> { - // Facade for communicating with HistoryService and WebHistoryService. - std::unique_ptr<HistoryServiceFacade> _historyServiceFacade; + BrowsingHistoryDriverDelegate> { + // Abstraction to communicate with HistoryService and WebHistoryService. + std::unique_ptr<BrowsingHistoryService> _browsingHistoryService; + // Provides dependencies and funnels callbacks from BrowsingHistoryService. + std::unique_ptr<IOSBrowsingHistoryDriver> _browsingHistoryDriver; // The main browser state. Not owned by HistoryCollectionViewController. ios::ChromeBrowserState* _browserState; // Backing ivar for delegate property. @@ -151,7 +159,13 @@ self = [super initWithLayout:layout style:CollectionViewControllerStyleDefault]; if (self) { - _historyServiceFacade.reset(new HistoryServiceFacade(browserState, self)); + _browsingHistoryDriver = + std::make_unique<IOSBrowsingHistoryDriver>(browserState, self); + _browsingHistoryService = std::make_unique<BrowsingHistoryService>( + _browsingHistoryDriver.get(), + ios::HistoryServiceFactory::GetForBrowserState( + browserState, ServiceAccessType::EXPLICIT_ACCESS), + IOSChromeProfileSyncServiceFactory::GetForBrowserState(browserState)); _browserState = browserState; _delegate = delegate; _URLLoader = loader; @@ -215,14 +229,16 @@ - (void)deleteSelectedItemsFromHistory { NSArray* deletedIndexPaths = self.collectionView.indexPathsForSelectedItems; - std::vector<HistoryServiceFacade::RemovedEntry> entries; + std::vector<BrowsingHistoryService::HistoryEntry> entries; for (NSIndexPath* indexPath in deletedIndexPaths) { HistoryEntryItem* object = base::mac::ObjCCastStrict<HistoryEntryItem>( [self.collectionViewModel itemAtIndexPath:indexPath]); - entries.push_back( - HistoryServiceFacade::RemovedEntry(object.URL, object.timestamp)); + BrowsingHistoryService::HistoryEntry entry; + entry.url = object.URL; + entry.all_timestamps.insert(object.timestamp.ToInternalValue()); + entries.push_back(entry); } - _historyServiceFacade->RemoveHistoryEntries(entries); + _browsingHistoryService->RemoveVisits(entries); [self removeSelectedItemsFromCollection]; } @@ -315,47 +331,52 @@ } } -#pragma mark - HistoryServiceFacadeDelegate +#pragma mark - BrowsingHistoryDriverDelegate -- (void)historyServiceFacade:(HistoryServiceFacade*)facade - didReceiveQueryResult:(HistoryServiceFacade::QueryResult)result { +- (void)onQueryCompleteWithResults: + (const std::vector<BrowsingHistoryService::HistoryEntry>&)results + queryResultsInfo: + (const BrowsingHistoryService::QueryResultsInfo&) + queryResultsInfo { self.loading = NO; + // If history sync is enabled and there hasn't been a response from synced // history, try fetching again. SyncSetupService* syncSetupService = SyncSetupServiceFactory::GetForBrowserState(_browserState); if (syncSetupService->IsSyncEnabled() && syncSetupService->IsDataTypeEnabled(syncer::HISTORY_DELETE_DIRECTIVES) && - !result.sync_returned) { + queryResultsInfo.sync_timed_out) { [self showHistoryMatchingQuery:_currentQuery]; return; } // If there are no results and no URLs have been loaded, report that no // history entries were found. - if (result.entries.empty() && !self.hasHistoryEntries) { + if (results.empty() && !self.hasHistoryEntries) { DCHECK(self.entriesType == NO_ENTRIES); [self updateEntriesStatusMessage]; [self.delegate historyCollectionViewControllerDidChangeEntries:self]; return; } - self.finishedLoading = result.has_synced_results - ? result.finished && result.sync_finished - : result.finished; - self.entriesType = result.has_synced_results ? SYNCED_ENTRIES : LOCAL_ENTRIES; - std::vector<history::HistoryEntry> entries = result.entries; + self.finishedLoading = queryResultsInfo.reached_beginning_of_local && + (!queryResultsInfo.has_synced_results || + queryResultsInfo.reached_beginning_of_sync); + self.entriesType = + queryResultsInfo.has_synced_results ? SYNCED_ENTRIES : LOCAL_ENTRIES; // Header section should be updated outside of batch updates, otherwise // loading indicator removal will not be observed. [self updateEntriesStatusMessage]; - __block NSMutableArray* filterResults = [NSMutableArray array]; - __block NSString* searchQuery = [base::SysUTF16ToNSString(result.query) copy]; + NSMutableArray* filterResults = [NSMutableArray array]; + NSString* searchQuery = + [base::SysUTF16ToNSString(queryResultsInfo.search_text) copy]; [self.collectionView performBatchUpdates:^{ // There should always be at least a header section present. DCHECK([[self collectionViewModel] numberOfSections]); - for (const history::HistoryEntry& entry : entries) { + for (const BrowsingHistoryService::HistoryEntry& entry : results) { HistoryEntryItem* item = [[HistoryEntryItem alloc] initWithType:ItemTypeHistoryEntry historyEntry:entry @@ -372,16 +393,16 @@ if (([self isSearching] && [searchQuery length] > 0 && [self.currentQuery isEqualToString:searchQuery]) || self.filterQueryResult) { - // If in search mode, filter out entries that are not - // part of the search result. + // If in search mode, filter out entries that are not part of the + // search result. [self filterForHistoryEntries:filterResults]; self.filterQueryResult = NO; } }]; } -- (void)historyServiceFacade:(HistoryServiceFacade*)facade - shouldShowNoticeAboutOtherFormsOfBrowsingHistory:(BOOL)shouldShowNotice { +- (void)shouldShowNoticeAboutOtherFormsOfBrowsingHistory: + (BOOL)shouldShowNotice { self.shouldShowNoticeAboutOtherFormsOfBrowsingHistory = shouldShowNotice; // Update the history entries status message if there is no query in progress. if (!self.isLoading) { @@ -389,8 +410,7 @@ } } -- (void)historyServiceFacadeDidObserveHistoryDeletion: - (HistoryServiceFacade*)facade { +- (void)didObserverHistoryDeletion { // If history has been deleted, reload history filtering for the current // results. This only observes local changes to history, i.e. removing // history via the clear browsing data page. @@ -555,10 +575,7 @@ options.max_count = kMaxFetchCount; options.matching_algorithm = query_parser::MatchingAlgorithm::ALWAYS_PREFIX_SEARCH; - _historyServiceFacade->QueryHistory(queryString, options); - // Also determine whether notice regarding other forms of browsing history - // should be shown. - _historyServiceFacade->QueryOtherFormsOfBrowsingHistory(); + _browsingHistoryService->QueryHistory(queryString, options); } - (void)updateEntriesStatusMessage {
diff --git a/ios/chrome/browser/ui/history/history_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/history/history_collection_view_controller_unittest.mm index 8454850..3b264ce 100644 --- a/ios/chrome/browser/ui/history/history_collection_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/history/history_collection_view_controller_unittest.mm
@@ -10,6 +10,7 @@ #include "base/strings/string16.h" #import "base/test/ios/wait_util.h" #include "base/time/time.h" +#include "components/history/core/browser/browsing_history_service.h" #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #include "ios/chrome/browser/signin/authentication_service_factory.h" #include "ios/chrome/browser/signin/authentication_service_fake.h" @@ -18,9 +19,7 @@ #include "ios/chrome/browser/sync/sync_setup_service.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" #include "ios/chrome/browser/sync/sync_setup_service_mock.h" -#import "ios/chrome/browser/ui/history/history_entry.h" -#import "ios/chrome/browser/ui/history/history_service_facade.h" -#import "ios/chrome/browser/ui/history/history_service_facade_delegate.h" +#import "ios/chrome/browser/ui/history/ios_browsing_history_driver.h" #import "ios/chrome/browser/ui/url_loader.h" #include "ios/chrome/test/block_cleanup_test.h" #include "ios/web/public/test/test_web_thread.h" @@ -29,21 +28,25 @@ #import "third_party/ocmock/OCMock/OCMock.h" #import "third_party/ocmock/gtest_support.h" +using base::Time; +using base::TimeDelta; +using history::BrowsingHistoryService; + namespace { -HistoryServiceFacade::QueryResult QueryResultWithVisits( - std::vector<std::pair<const GURL&, base::Time>> visits) { - std::vector<history::HistoryEntry> entries{}; - for (std::pair<const GURL&, base::Time> visit : visits) { - history::HistoryEntry entry = history::HistoryEntry(); +const char kTestUrl1[] = "http://test1/"; +const char kTestUrl2[] = "http://test2/"; + +std::vector<BrowsingHistoryService::HistoryEntry> QueryResultWithVisits( + std::vector<std::pair<const GURL&, Time>> visits) { + std::vector<BrowsingHistoryService::HistoryEntry> entries; + for (std::pair<const GURL&, Time> visit : visits) { + BrowsingHistoryService::HistoryEntry entry; entry.url = visit.first; entry.time = visit.second; entries.push_back(entry); } - HistoryServiceFacade::QueryResult result{}; - result.entries = entries; - result.finished = true; - return result; + return entries; } std::unique_ptr<KeyedService> BuildMockSyncSetupService( @@ -59,7 +62,7 @@ } // namespace @interface HistoryCollectionViewController ( - Testing)<HistoryServiceFacadeDelegate> + Testing)<BrowsingHistoryDriverDelegate> - (void)didPressClearBrowsingBar; @end @@ -95,6 +98,16 @@ BlockCleanupTest::TearDown(); } + void QueryHistory(std::vector<std::pair<const GURL&, Time>> visits) { + std::vector<BrowsingHistoryService::HistoryEntry> results = + QueryResultWithVisits(visits); + BrowsingHistoryService::QueryResultsInfo query_results_info; + query_results_info.reached_beginning_of_local = true; + [history_collection_view_controller_ + onQueryCompleteWithResults:results + queryResultsInfo:query_results_info]; + } + protected: web::TestWebThreadBundle thread_bundle_; id<UrlLoader> mock_url_loader_; @@ -109,11 +122,7 @@ // Tests that hasHistoryEntries property returns YES after entries have been // received. TEST_F(HistoryCollectionViewControllerTest, HasHistoryEntries) { - GURL url_1("http://test1"); - HistoryServiceFacade::QueryResult query_result = - QueryResultWithVisits({{url_1, base::Time::Now()}}); - [history_collection_view_controller_ historyServiceFacade:nil - didReceiveQueryResult:query_result]; + QueryHistory({{GURL(kTestUrl1), Time::Now()}}); EXPECT_TRUE([history_collection_view_controller_ hasHistoryEntries]); } @@ -122,30 +131,21 @@ // This ensures that when HISTORY_DELETE_DIRECTIVES is disabled, // only local device history items are shown. TEST_F(HistoryCollectionViewControllerTest, HasHistoryEntriesWhenSyncEnabled) { - GURL url_1("http://test1"); EXPECT_CALL(*sync_setup_service_mock_, IsSyncEnabled()) .WillRepeatedly(testing::Return(true)); EXPECT_CALL(*sync_setup_service_mock_, IsDataTypeEnabled(syncer::HISTORY_DELETE_DIRECTIVES)) .WillRepeatedly(testing::Return(false)); - HistoryServiceFacade::QueryResult query_result = - QueryResultWithVisits({{url_1, base::Time::Now()}}); - [history_collection_view_controller_ historyServiceFacade:nil - didReceiveQueryResult:query_result]; + QueryHistory({{GURL(kTestUrl1), Time::Now()}}); EXPECT_TRUE([history_collection_view_controller_ hasHistoryEntries]); } // Tests adding two entries to history from the same day, then deleting the // first of them results in one history entry in the collection. TEST_F(HistoryCollectionViewControllerTest, DeleteSingleEntry) { - // Add history entries - GURL url_1("http://test1"); - GURL url_2("http://test2"); - HistoryServiceFacade::QueryResult query_result = QueryResultWithVisits( - {{url_1, base::Time::Now()}, {url_2, base::Time::Now()}}); - [history_collection_view_controller_ historyServiceFacade:nil - didReceiveQueryResult:query_result]; + QueryHistory( + {{GURL(kTestUrl1), Time::Now()}, {GURL(kTestUrl2), Time::Now()}}); UICollectionView* collection_view = [history_collection_view_controller_ collectionView]; @@ -164,13 +164,8 @@ // Tests that adding two entries to history from the same day then deleting // both of them results in only the header section in the collection. TEST_F(HistoryCollectionViewControllerTest, DeleteMultipleEntries) { - // Add history entries. - GURL url_1("http://test1"); - GURL url_2("http://test2"); - HistoryServiceFacade::QueryResult query_result = QueryResultWithVisits( - {{url_1, base::Time::Now()}, {url_2, base::Time::Now()}}); - [history_collection_view_controller_ historyServiceFacade:nil - didReceiveQueryResult:query_result]; + QueryHistory( + {{GURL(kTestUrl1), Time::Now()}, {GURL(kTestUrl2), Time::Now()}}); // Select history entries and tap delete. UICollectionView* collection_view = @@ -195,14 +190,9 @@ // Tests that adding two entries to history from different days then deleting // both of them results in only the header section in the collection. TEST_F(HistoryCollectionViewControllerTest, DeleteMultipleSections) { - GURL url_1("http://test1"); - GURL url_2("http://test2"); + QueryHistory({{GURL(kTestUrl1), Time::Now() - TimeDelta::FromDays(1)}, + {GURL(kTestUrl2), Time::Now()}}); - HistoryServiceFacade::QueryResult query_result = QueryResultWithVisits( - {{url_1, base::Time::Now() - base::TimeDelta::FromDays(1)}, - {url_2, base::Time::Now()}}); - [history_collection_view_controller_ historyServiceFacade:nil - didReceiveQueryResult:query_result]; UICollectionView* collection_view = [history_collection_view_controller_ collectionView]; // Expect two history sections in addition to the header section.
diff --git a/ios/chrome/browser/ui/history/history_entry.cc b/ios/chrome/browser/ui/history/history_entry.cc deleted file mode 100644 index 32e8f0a..0000000 --- a/ios/chrome/browser/ui/history/history_entry.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/history/history_entry.h" - -namespace history { - -HistoryEntry::HistoryEntry(HistoryEntry::EntryType entry_type, - const GURL& url, - const base::string16& title, - base::Time time, - const std::string& client_id, - bool is_search_result, - const base::string16& snippet, - bool blocked_visit) - : entry_type(entry_type), - url(url), - title(title), - time(time), - client_id(client_id), - is_search_result(is_search_result), - snippet(snippet), - blocked_visit(blocked_visit) { - all_timestamps.insert(time.ToInternalValue()); -} - -HistoryEntry::HistoryEntry() - : entry_type(EMPTY_ENTRY), is_search_result(false), blocked_visit(false) {} - -HistoryEntry::HistoryEntry(const HistoryEntry& other) = default; - -HistoryEntry::~HistoryEntry() {} - -bool HistoryEntry::SortByTimeDescending(const HistoryEntry& entry1, - const HistoryEntry& entry2) { - return entry1.time > entry2.time; -} - -} // namespace history
diff --git a/ios/chrome/browser/ui/history/history_entry.h b/ios/chrome/browser/ui/history/history_entry.h deleted file mode 100644 index 715900f..0000000 --- a/ios/chrome/browser/ui/history/history_entry.h +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_ENTRY_H_ -#define IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_ENTRY_H_ - -#include <set> -#include <string> - -#include "base/strings/string16.h" -#include "base/time/time.h" -#include "url/gurl.h" - -namespace history { - -// Represents a history entry to be shown to the user, representing either -// a local or remote visit. A single entry can represent multiple visits, -// since only the most recent visit on a particular day is shown. -struct HistoryEntry { - // Values indicating whether an entry represents only local visits, only - // remote visits, or a mixture of both. - enum EntryType { EMPTY_ENTRY = 0, LOCAL_ENTRY, REMOTE_ENTRY, COMBINED_ENTRY }; - - HistoryEntry(EntryType type, - const GURL& url, - const base::string16& title, - base::Time time, - const std::string& client_id, - bool is_search_result, - const base::string16& snippet, - bool blocked_visit); - HistoryEntry(); - HistoryEntry(const HistoryEntry&); - ~HistoryEntry(); - - // Comparison function for sorting HistoryEntries from newest to oldest. - static bool SortByTimeDescending(const HistoryEntry& entry1, - const HistoryEntry& entry2); - - // The type of visits this entry represents: local, remote, or both. - EntryType entry_type; - - // URL of the entry. - GURL url; - - // Title of the entry. May be empty. - base::string16 title; - - // Time of the entry. Usually this will be the time of the most recent - // visit to |url| on a particular day as defined in the local timezone. - base::Time time; - - // Sync ID of the client on which the most recent visit occurred. - std::string client_id; - - // Timestamps of all local or remote visits to the same URL on the same day. - std::set<int64_t> all_timestamps; - - // If true, this entry is a history query result. - bool is_search_result; - - // The entry's search snippet, if this entry is a history query result. - base::string16 snippet; - - // Whether this entry was blocked when it was attempted. - bool blocked_visit; -}; -} // namespace history - -#endif // IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_ENTRY_H_
diff --git a/ios/chrome/browser/ui/history/history_entry_inserter_unittest.mm b/ios/chrome/browser/ui/history/history_entry_inserter_unittest.mm index f85a6b3..0df59900 100644 --- a/ios/chrome/browser/ui/history/history_entry_inserter_unittest.mm +++ b/ios/chrome/browser/ui/history/history_entry_inserter_unittest.mm
@@ -7,8 +7,8 @@ #import "base/mac/foundation_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "components/history/core/browser/browsing_history_service.h" #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" -#import "ios/chrome/browser/ui/history/history_entry.h" #import "ios/chrome/browser/ui/history/history_entry_item.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" @@ -20,12 +20,14 @@ #error "This file requires ARC support." #endif +using history::BrowsingHistoryService; + HistoryEntryItem* TestHistoryEntryItem(base::Time timestamp, const std::string& name) { - history::HistoryEntry entry = history::HistoryEntry( - history::HistoryEntry::LOCAL_ENTRY, GURL(("http://" + name).c_str()), - base::UTF8ToUTF16(name.c_str()), timestamp, std::string(), false, - base::string16(), false); + BrowsingHistoryService::HistoryEntry entry( + BrowsingHistoryService::HistoryEntry::LOCAL_ENTRY, + GURL(("http://" + name).c_str()), base::UTF8ToUTF16(name.c_str()), + timestamp, std::string(), false, base::string16(), false); return [[HistoryEntryItem alloc] initWithType:kItemTypeEnumZero historyEntry:entry browserState:nil
diff --git a/ios/chrome/browser/ui/history/history_entry_item.h b/ios/chrome/browser/ui/history/history_entry_item.h index 103d0be..367191e 100644 --- a/ios/chrome/browser/ui/history/history_entry_item.h +++ b/ios/chrome/browser/ui/history/history_entry_item.h
@@ -5,6 +5,7 @@ #ifndef IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_ENTRY_ITEM_H_ #define IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_ENTRY_ITEM_H_ +#include "components/history/core/browser/browsing_history_service.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" #import "ios/third_party/material_components_ios/src/components/Collections/src/MaterialCollections.h" @@ -12,10 +13,6 @@ class Time; } // namespace base -namespace history { -struct HistoryEntry; -} // namespace history - namespace ios { class ChromeBrowserState; } // namespace ios @@ -59,7 +56,8 @@ // The |delegate| is notified when the favicon has loaded, and may be nil. - (instancetype)initWithType:(NSInteger)type - historyEntry:(const history::HistoryEntry&)entry + historyEntry: + (const history::BrowsingHistoryService::HistoryEntry&)entry browserState:(ios::ChromeBrowserState*)browserState delegate:(id<HistoryEntryItemDelegate>)delegate NS_DESIGNATED_INITIALIZER;
diff --git a/ios/chrome/browser/ui/history/history_entry_item.mm b/ios/chrome/browser/ui/history/history_entry_item.mm index b917582..f5d15d8 100644 --- a/ios/chrome/browser/ui/history/history_entry_item.mm +++ b/ios/chrome/browser/ui/history/history_entry_item.mm
@@ -14,7 +14,6 @@ #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h" #import "ios/chrome/browser/ui/history/favicon_view.h" #import "ios/chrome/browser/ui/history/favicon_view_provider.h" -#import "ios/chrome/browser/ui/history/history_entry.h" #include "ios/chrome/browser/ui/rtl_geometry.h" #import "ios/chrome/browser/ui/util/constraints_ui_util.h" #include "ios/chrome/grit/ios_strings.h" @@ -91,7 +90,8 @@ @synthesize timestamp = _timestamp; - (instancetype)initWithType:(NSInteger)type - historyEntry:(const history::HistoryEntry&)entry + historyEntry: + (const history::BrowsingHistoryService::HistoryEntry&)entry browserState:(ios::ChromeBrowserState*)browserState delegate:(id<HistoryEntryItemDelegate>)delegate { self = [super initWithType:type];
diff --git a/ios/chrome/browser/ui/history/history_entry_item_unittest.mm b/ios/chrome/browser/ui/history/history_entry_item_unittest.mm index 9a86ef07..eacffdf1 100644 --- a/ios/chrome/browser/ui/history/history_entry_item_unittest.mm +++ b/ios/chrome/browser/ui/history/history_entry_item_unittest.mm
@@ -8,7 +8,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" -#include "ios/chrome/browser/ui/history/history_entry.h" +#include "components/history/core/browser/browsing_history_service.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" @@ -16,6 +16,8 @@ #error "This file requires ARC support." #endif +using history::BrowsingHistoryService; + namespace { const char kTestUrl[] = "http://test/"; const char kTestUrl2[] = "http://test2/"; @@ -25,9 +27,9 @@ HistoryEntryItem* GetHistoryEntryItem(const GURL& url, const char title[], base::Time timestamp) { - history::HistoryEntry entry = history::HistoryEntry( - history::HistoryEntry::LOCAL_ENTRY, GURL(url), base::UTF8ToUTF16(title), - timestamp, "", false, base::string16(), false); + BrowsingHistoryService::HistoryEntry entry( + BrowsingHistoryService::HistoryEntry::LOCAL_ENTRY, GURL(url), + base::UTF8ToUTF16(title), timestamp, "", false, base::string16(), false); HistoryEntryItem* item = [[HistoryEntryItem alloc] initWithType:0 historyEntry:entry browserState:nil
diff --git a/ios/chrome/browser/ui/history/history_service_facade.h b/ios/chrome/browser/ui/history/history_service_facade.h deleted file mode 100644 index cb037786..0000000 --- a/ios/chrome/browser/ui/history/history_service_facade.h +++ /dev/null
@@ -1,174 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_SERVICE_FACADE_H_ -#define IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_SERVICE_FACADE_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/scoped_observer.h" -#include "base/strings/string16.h" -#include "base/task/cancelable_task_tracker.h" -#include "base/timer/timer.h" -#include "base/values.h" -#include "components/history/core/browser/history_service_observer.h" -#include "components/history/core/browser/url_row.h" -#include "components/history/core/browser/web_history_service.h" -#include "url/gurl.h" - -namespace history { -struct HistoryEntry; -class HistoryService; -struct QueryOptions; -class QueryResults; -} - -namespace ios { -class ChromeBrowserState; -} - -@protocol HistoryServiceFacadeDelegate; - -// Facade for HistoryService and WebHistoryService. Handles history querying and -// deletion actions. -class HistoryServiceFacade : public history::HistoryServiceObserver { - public: - // Represents the result of a query to history service. - struct QueryResult { - QueryResult(); - QueryResult(const QueryResult&); - ~QueryResult(); - base::string16 query; - base::string16 query_start_time; - base::string16 query_end_time; - // true if all local history from History service has been retrieved. - bool finished; - // true if a query to WebHistoryService has returned successfully. - bool sync_returned; - // true if results from WebHistoryService have been retrieved. - bool has_synced_results; - // true if all remote history from WebHistoryService has been retrieved. - bool sync_finished; - std::vector<history::HistoryEntry> entries; - }; - - // Represents a history entry removed by the client. - struct RemovedEntry { - RemovedEntry(const GURL& url, const base::Time& timestamp); - RemovedEntry(const GURL& url, const std::vector<base::Time>& timestamps); - RemovedEntry(const RemovedEntry&); - ~RemovedEntry(); - GURL url; - std::vector<base::Time> timestamps; - }; - - HistoryServiceFacade(ios::ChromeBrowserState* browser_state, - id<HistoryServiceFacadeDelegate> delegate); - ~HistoryServiceFacade() override; - - // Performs history query with query |search_text| and |options|; - void QueryHistory(const base::string16& search_text, - const history::QueryOptions& options); - - // Removes history entries in HistoryService and WebHistoryService. - void RemoveHistoryEntries(const std::vector<RemovedEntry>& entries); - - // Queries WebHistoryService to determine whether notice about other forms - // of browsing history should be shown. The response is returned via the - // historyServiceFacade:shouldShowNoticeAboutOtherFormsOfBrowsingHistory: - // delegate callback. - void QueryOtherFormsOfBrowsingHistory(); - - private: - // The range for which to return results: - // - ALLTIME: allows access to all the results in a paginated way. - // - WEEK: the last 7 days. - // - MONTH: the last calendar month. - enum Range { ALL_TIME = 0, WEEK = 1, MONTH = 2 }; - - // Callback from |web_history_timer_| when a response from web history has - // not been received in time. - void WebHistoryTimeout(); - - // Callback from the history system when a history query has completed. - void QueryComplete(const base::string16& search_text, - const history::QueryOptions& options, - history::QueryResults* results); - - // Callback from the WebHistoryService when a query has completed. - void WebHistoryQueryComplete(const base::string16& search_text, - const history::QueryOptions& options, - base::TimeTicks start_time, - history::WebHistoryService::Request* request, - const base::DictionaryValue* results_value); - - // Callback from the history system when visits were deleted. - void RemoveComplete(); - - // Callback from history server when visits were deleted. - void RemoveWebHistoryComplete(bool success); - - // Callback telling whether other forms of browsing history were found - // on the history server. - void OtherFormsOfBrowsingHistoryQueryComplete( - bool found_other_forms_of_browsing_history); - - // Combines the query results from the local history database and the history - // server, and sends the combined results to the front end. - void ReturnResultsToFrontEnd(); - - // history::HistoryServiceObserver method. - void OnURLsDeleted(history::HistoryService* history_service, - bool all_history, - bool expired, - const history::URLRows& deleted_rows, - const std::set<GURL>& favicon_urls) override; - - // Tracker for search requests to the history service. - base::CancelableTaskTracker query_task_tracker_; - - // The currently-executing request for synced history results. - // Deleting the request will cancel it. - std::unique_ptr<history::WebHistoryService::Request> web_history_request_; - - // True if there is a pending delete requests to the history service. - bool has_pending_delete_request_; - - // Tracker for delete requests to the history service. - base::CancelableTaskTracker delete_task_tracker_; - - // The list of URLs that are in the process of being deleted. - std::set<GURL> urls_to_be_deleted_; - - // Information that is returned to the front end with the query results. - QueryResult results_info_value_; - - // The list of query results received from the history service. - std::vector<history::HistoryEntry> query_results_; - - // The list of query results received from the history server. - std::vector<history::HistoryEntry> web_history_query_results_; - - // Timer used to implement a timeout on a Web History response. - base::OneShotTimer web_history_timer_; - - // Observer for HistoryService. - ScopedObserver<history::HistoryService, history::HistoryServiceObserver> - history_service_observer_; - - // The current browser state. - ios::ChromeBrowserState* browser_state_; // weak - - // Delegate for HistoryServiceFacade. Serves as client for HistoryService. - __weak id<HistoryServiceFacadeDelegate> delegate_; - - base::WeakPtrFactory<HistoryServiceFacade> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(HistoryServiceFacade); -}; - -#endif // IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_SERVICE_FACADE_H_
diff --git a/ios/chrome/browser/ui/history/history_service_facade.mm b/ios/chrome/browser/ui/history/history_service_facade.mm deleted file mode 100644 index d6b391e3..0000000 --- a/ios/chrome/browser/ui/history/history_service_facade.mm +++ /dev/null
@@ -1,473 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/history/history_service_facade.h" - -#include <stddef.h> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/i18n/time_formatting.h" -#include "base/mac/bind_objc_block.h" -#include "base/memory/weak_ptr.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string16.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "base/values.h" -#include "components/browser_sync/profile_sync_service.h" -#include "components/browsing_data/core/history_notice_utils.h" -#include "components/history/core/browser/history_service.h" -#include "components/history/core/browser/history_types.h" -#include "components/history/core/browser/web_history_service.h" -#include "components/keyed_service/core/service_access_type.h" -#include "components/prefs/pref_service.h" -#include "components/query_parser/snippet.h" -#include "components/sync/protocol/history_delete_directive_specifics.pb.h" -#include "components/sync/protocol/sync_enums.pb.h" -#include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/history/history_service_factory.h" -#include "ios/chrome/browser/history/history_utils.h" -#include "ios/chrome/browser/history/web_history_service_factory.h" -#include "ios/chrome/browser/pref_names.h" -#include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h" -#include "ios/chrome/browser/ui/history/history_entry.h" -#include "ios/chrome/browser/ui/history/history_service_facade_delegate.h" -#include "ios/chrome/browser/ui/history/history_util.h" -#include "net/traffic_annotation/network_traffic_annotation.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -// The amount of time to wait for a response from the WebHistoryService. -static const int kWebHistoryTimeoutSeconds = 3; - -namespace { - -// Buckets for UMA histograms. -enum WebHistoryQueryBuckets { - WEB_HISTORY_QUERY_FAILED = 0, - WEB_HISTORY_QUERY_SUCCEEDED, - WEB_HISTORY_QUERY_TIMED_OUT, - NUM_WEB_HISTORY_QUERY_BUCKETS -}; - -// Returns true if |entry| represents a local visit that had no corresponding -// visit on the server. -bool IsLocalOnlyResult(const history::HistoryEntry& entry) { - return entry.entry_type == history::HistoryEntry::LOCAL_ENTRY; -} - -// Returns true if there are any differences between the URLs observed deleted -// and the ones we are expecting to be deleted. -static bool DeletionsDiffer(const history::URLRows& observed_deletions, - const std::set<GURL>& expected_deletions) { - if (observed_deletions.size() != expected_deletions.size()) - return true; - for (const auto& i : observed_deletions) { - if (expected_deletions.find(i.url()) == expected_deletions.end()) - return true; - } - return false; -} - -} // namespace - -#pragma mark - QueryResult - -HistoryServiceFacade::QueryResult::QueryResult() - : query(base::string16()), - query_start_time(base::string16()), - query_end_time(base::string16()), - finished(false), - sync_returned(false), - has_synced_results(false), - sync_finished(false), - entries(std::vector<history::HistoryEntry>()) {} - -HistoryServiceFacade::QueryResult::QueryResult(const QueryResult& other) = - default; - -HistoryServiceFacade::QueryResult::~QueryResult() {} - -#pragma mark - RemovedEntry - -HistoryServiceFacade::RemovedEntry::RemovedEntry(const GURL& url, - const base::Time& timestamp) - : url(url) { - timestamps = std::vector<base::Time>(); - timestamps.push_back(timestamp); -} - -HistoryServiceFacade::RemovedEntry::RemovedEntry( - const GURL& url, - const std::vector<base::Time>& timestamps) - : url(url), timestamps(timestamps) {} - -HistoryServiceFacade::RemovedEntry::RemovedEntry(const RemovedEntry& other) = - default; - -HistoryServiceFacade::RemovedEntry::~RemovedEntry() {} - -#pragma mark - HistoryServiceFacade - -HistoryServiceFacade::HistoryServiceFacade( - ios::ChromeBrowserState* browser_state, - id<HistoryServiceFacadeDelegate> delegate) - : has_pending_delete_request_(false), - history_service_observer_(this), - browser_state_(browser_state), - delegate_(delegate), - weak_factory_(this) { - // Register as observer of HistoryService. - history::HistoryService* history_service = - ios::HistoryServiceFactory::GetForBrowserState( - browser_state, ServiceAccessType::EXPLICIT_ACCESS); - if (history_service) - history_service_observer_.Add(history_service); -} - -HistoryServiceFacade::~HistoryServiceFacade() { - query_task_tracker_.TryCancelAll(); - web_history_request_.reset(); - delegate_ = nil; -} - -void HistoryServiceFacade::QueryHistory(const base::string16& search_text, - const history::QueryOptions& options) { - // Anything in-flight is invalid. - query_task_tracker_.TryCancelAll(); - web_history_request_.reset(); - - // Reset results. - query_results_.clear(); - results_info_value_ = QueryResult(); - - // Query synced history. - history::WebHistoryService* web_history = - ios::WebHistoryServiceFactory::GetForBrowserState(browser_state_); - if (web_history) { - web_history_query_results_.clear(); - web_history_request_ = web_history->QueryHistory( - search_text, options, - base::Bind(&HistoryServiceFacade::WebHistoryQueryComplete, - base::Unretained(this), search_text, options, - base::TimeTicks::Now()), - NO_PARTIAL_TRAFFIC_ANNOTATION_YET); - // Start a timer so we know when to give up. - web_history_timer_.Start( - FROM_HERE, base::TimeDelta::FromSeconds(kWebHistoryTimeoutSeconds), - this, &HistoryServiceFacade::WebHistoryTimeout); - } - - // Query local history. - history::HistoryService* history_service = - ios::HistoryServiceFactory::GetForBrowserState( - browser_state_, ServiceAccessType::EXPLICIT_ACCESS); - if (history_service) { - history_service->QueryHistory( - search_text, options, - base::Bind(&HistoryServiceFacade::QueryComplete, base::Unretained(this), - search_text, options), - &query_task_tracker_); - } -} - -void HistoryServiceFacade::RemoveHistoryEntries( - const std::vector<RemovedEntry>& entries) { - // Early return if there is a deletion in progress. - if (delete_task_tracker_.HasTrackedTasks() || has_pending_delete_request_) { - return; - } - - history::HistoryService* history_service = - ios::HistoryServiceFactory::GetForBrowserState( - browser_state_, ServiceAccessType::EXPLICIT_ACCESS); - history::WebHistoryService* web_history = - ios::WebHistoryServiceFactory::GetForBrowserState(browser_state_); - - base::Time now = base::Time::Now(); - std::vector<history::ExpireHistoryArgs> expire_list; - expire_list.reserve(entries.size()); - - DCHECK(urls_to_be_deleted_.empty()); - for (const RemovedEntry& entry : entries) { - GURL url = entry.url; - DCHECK(entry.timestamps.size() > 0); - - // In order to ensure that visits will be deleted from the server and other - // clients (even if they are offline), create a sync delete directive for - // each visit to be deleted. - sync_pb::HistoryDeleteDirectiveSpecifics delete_directive; - sync_pb::GlobalIdDirective* global_id_directive = - delete_directive.mutable_global_id_directive(); - - expire_list.resize(expire_list.size() + 1); - history::ExpireHistoryArgs* expire_args = &expire_list.back(); - expire_args->SetTimeRangeForOneDay(entry.timestamps.front()); - expire_args->urls.insert(entry.url); - urls_to_be_deleted_.insert(entry.url); - - for (base::Time visit_time : entry.timestamps) { - // The local visit time is treated as a global ID for the visit. - global_id_directive->add_global_id(visit_time.ToInternalValue()); - } - - // Set the start and end time in microseconds since the Unix epoch. - global_id_directive->set_start_time_usec( - (expire_args->begin_time - base::Time::UnixEpoch()).InMicroseconds()); - - // Delete directives shouldn't have an end time in the future. - base::Time end_time = std::min(expire_args->end_time, now); - - // -1 because end time in delete directives is inclusive. - global_id_directive->set_end_time_usec( - (end_time - base::Time::UnixEpoch()).InMicroseconds() - 1); - - if (web_history) - history_service->ProcessLocalDeleteDirective(delete_directive); - } - - if (history_service) { - history_service->ExpireHistory( - expire_list, base::Bind(&HistoryServiceFacade::RemoveComplete, - base::Unretained(this)), - &delete_task_tracker_); - } - - if (web_history) { - has_pending_delete_request_ = true; - web_history->ExpireHistory( - expire_list, - base::Bind(&HistoryServiceFacade::RemoveWebHistoryComplete, - weak_factory_.GetWeakPtr()), - NO_PARTIAL_TRAFFIC_ANNOTATION_YET); - } -} - -void HistoryServiceFacade::QueryOtherFormsOfBrowsingHistory() { - browser_sync::ProfileSyncService* sync_service = - IOSChromeProfileSyncServiceFactory::GetForBrowserState(browser_state_); - history::WebHistoryService* history_service = - ios::WebHistoryServiceFactory::GetForBrowserState(browser_state_); - browsing_data::ShouldShowNoticeAboutOtherFormsOfBrowsingHistory( - sync_service, history_service, - base::Bind( - &HistoryServiceFacade::OtherFormsOfBrowsingHistoryQueryComplete, - weak_factory_.GetWeakPtr())); -} - -#pragma mark - Private methods - -void HistoryServiceFacade::WebHistoryTimeout() { - // If there are no outstanding tasks, send results to front end. Would also - // be good to communicate the failure to the front end. - if (!query_task_tracker_.HasTrackedTasks()) - ReturnResultsToFrontEnd(); - - UMA_HISTOGRAM_ENUMERATION("WebHistory.QueryCompletion", - WEB_HISTORY_QUERY_TIMED_OUT, - NUM_WEB_HISTORY_QUERY_BUCKETS); -} - -void HistoryServiceFacade::QueryComplete(const base::string16& search_text, - const history::QueryOptions& options, - history::QueryResults* results) { - DCHECK_EQ(0U, query_results_.size()); - query_results_.reserve(results->size()); - - for (const auto& result : *results) { - query_results_.push_back(history::HistoryEntry( - history::HistoryEntry::LOCAL_ENTRY, result.url(), result.title(), - result.visit_time(), std::string(), !search_text.empty(), - result.snippet().text(), result.blocked_visit())); - } - - results_info_value_.query = search_text; - results_info_value_.finished = results->reached_beginning(); - results_info_value_.query_start_time = - history::GetRelativeDateLocalized((options.begin_time)); - - // Add the specific dates that were searched to display them. - // Should put today if the start is in the future. - if (!options.end_time.is_null()) { - results_info_value_.query_end_time = history::GetRelativeDateLocalized( - options.end_time - base::TimeDelta::FromDays(1)); - } else { - results_info_value_.query_end_time = - history::GetRelativeDateLocalized(base::Time::Now()); - } - if (!web_history_timer_.IsRunning()) - ReturnResultsToFrontEnd(); -} - -void HistoryServiceFacade::WebHistoryQueryComplete( - const base::string16& search_text, - const history::QueryOptions& options, - base::TimeTicks start_time, - history::WebHistoryService::Request* request, - const base::DictionaryValue* results_value) { - base::TimeDelta delta = base::TimeTicks::Now() - start_time; - UMA_HISTOGRAM_TIMES("WebHistory.ResponseTime", delta); - - // If the response came in too late, do nothing. - if (!web_history_timer_.IsRunning()) - return; - web_history_timer_.Stop(); - - UMA_HISTOGRAM_ENUMERATION( - "WebHistory.QueryCompletion", - results_value ? WEB_HISTORY_QUERY_SUCCEEDED : WEB_HISTORY_QUERY_FAILED, - NUM_WEB_HISTORY_QUERY_BUCKETS); - - DCHECK_EQ(0U, web_history_query_results_.size()); - const base::ListValue* events = NULL; - if (results_value && results_value->GetList("event", &events)) { - web_history_query_results_.reserve(events->GetSize()); - for (unsigned int i = 0; i < events->GetSize(); ++i) { - const base::DictionaryValue* event = NULL; - const base::DictionaryValue* result = NULL; - const base::ListValue* results = NULL; - const base::ListValue* ids = NULL; - base::string16 url; - base::string16 title; - base::Time visit_time; - - if (!(events->GetDictionary(i, &event) && - event->GetList("result", &results) && - results->GetDictionary(0, &result) && - result->GetString("url", &url) && result->GetList("id", &ids) && - ids->GetSize() > 0)) { - LOG(WARNING) << "Improperly formed JSON response from history server."; - continue; - } - - // Ignore any URLs that should not be shown in the history page. - GURL gurl(url); - if (!ios::CanAddURLToHistory(gurl)) - continue; - - // Title is optional, so the return value is ignored here. - result->GetString("title", &title); - - // Extract the timestamps of all the visits to this URL. - // They are referred to as "IDs" by the server. - for (int j = 0; j < static_cast<int>(ids->GetSize()); ++j) { - const base::DictionaryValue* id = NULL; - std::string timestamp_string; - int64_t timestamp_usec = 0; - - if (!ids->GetDictionary(j, &id) || - !id->GetString("timestamp_usec", ×tamp_string) || - !base::StringToInt64(timestamp_string, ×tamp_usec)) { - NOTREACHED() << "Unable to extract timestamp."; - continue; - } - // The timestamp on the server is a Unix time. - base::Time time = base::Time::UnixEpoch() + - base::TimeDelta::FromMicroseconds(timestamp_usec); - - // Get the ID of the client that this visit came from. - std::string client_id; - id->GetString("client_id", &client_id); - - web_history_query_results_.push_back(history::HistoryEntry( - history::HistoryEntry::REMOTE_ENTRY, gurl, title, time, client_id, - !search_text.empty(), base::string16(), - /* blocked_visit */ false)); - } - } - } - - results_info_value_.has_synced_results = results_value != NULL; - results_info_value_.sync_returned = true; - if (results_value) { - std::string continuation_token; - results_value->GetString("continuation_token", &continuation_token); - results_info_value_.sync_finished = continuation_token.empty(); - } - if (!query_task_tracker_.HasTrackedTasks()) - ReturnResultsToFrontEnd(); -} - -void HistoryServiceFacade::RemoveComplete() { - urls_to_be_deleted_.clear(); - - // Notify the delegate that the deletion request is complete, but only if a - // web history delete request is not still pending. - if (has_pending_delete_request_) - return; - if ([delegate_ respondsToSelector: - @selector(historyServiceFacadeDidCompleteEntryRemoval:)]) { - [delegate_ historyServiceFacadeDidCompleteEntryRemoval:this]; - } -} - -void HistoryServiceFacade::RemoveWebHistoryComplete(bool success) { - has_pending_delete_request_ = false; - if (!delete_task_tracker_.HasTrackedTasks()) - RemoveComplete(); -} - -void HistoryServiceFacade::OtherFormsOfBrowsingHistoryQueryComplete( - bool found_other_forms_of_browsing_history) { - if ([delegate_ respondsToSelector: - @selector(historyServiceFacade: - shouldShowNoticeAboutOtherFormsOfBrowsingHistory:)]) { - [delegate_ historyServiceFacade:this - shouldShowNoticeAboutOtherFormsOfBrowsingHistory: - found_other_forms_of_browsing_history]; - } -} - -void HistoryServiceFacade::ReturnResultsToFrontEnd() { - // Combine the local and remote results into |query_results_|, and remove - // any duplicates. - if (!web_history_query_results_.empty()) { - int local_result_count = query_results_.size(); - query_results_.insert(query_results_.end(), - web_history_query_results_.begin(), - web_history_query_results_.end()); - history::MergeDuplicateHistoryEntries(&query_results_); - - if (local_result_count) { - // In the best case, we expect that all local results are duplicated on - // the server. Keep track of how many are missing. - int missing_count = std::count_if( - query_results_.begin(), query_results_.end(), IsLocalOnlyResult); - UMA_HISTOGRAM_PERCENTAGE("WebHistory.LocalResultMissingOnServer", - missing_count * 100.0 / local_result_count); - } - } - - // Send results to delegate. Results may be empty. - results_info_value_.entries = query_results_; - if ([delegate_ respondsToSelector:@selector(historyServiceFacade: - didReceiveQueryResult:)]) { - [delegate_ historyServiceFacade:this - didReceiveQueryResult:results_info_value_]; - } - - // Reset results variables. - results_info_value_ = QueryResult(); - query_results_.clear(); - web_history_query_results_.clear(); -} - -void HistoryServiceFacade::OnURLsDeleted( - history::HistoryService* history_service, - bool all_history, - bool expired, - const history::URLRows& deleted_rows, - const std::set<GURL>& favicon_urls) { - if (all_history || DeletionsDiffer(deleted_rows, urls_to_be_deleted_)) { - if ([delegate_ - respondsToSelector: - @selector(historyServiceFacadeDidObserveHistoryDeletion:)]) { - [delegate_ historyServiceFacadeDidObserveHistoryDeletion:this]; - } - } -}
diff --git a/ios/chrome/browser/ui/history/history_service_facade_delegate.h b/ios/chrome/browser/ui/history/history_service_facade_delegate.h deleted file mode 100644 index 5bea82c7..0000000 --- a/ios/chrome/browser/ui/history/history_service_facade_delegate.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_SERVICE_FACADE_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_SERVICE_FACADE_DELEGATE_H_ - -#include "ios/chrome/browser/ui/history/history_service_facade.h" - -// Delegate for HistoryServiceFacade. Defines methods to manage history query -// results and deletion actions. -@protocol HistoryServiceFacadeDelegate<NSObject> - -@optional - -// Notifies the delegate that the result of a history query has been retrieved. -// Entries in |result| are already sorted. -- (void)historyServiceFacade:(HistoryServiceFacade*)facade - didReceiveQueryResult:(HistoryServiceFacade::QueryResult)result; - -// Notifies the delegate that history entries have been deleted by a different -// client and that the UI should be updated. -- (void)historyServiceFacadeDidObserveHistoryDeletion: - (HistoryServiceFacade*)facade; - -// Indicates to the delegate whether to show notice about other forms of -// browsing history. -- (void)historyServiceFacade:(HistoryServiceFacade*)facade - shouldShowNoticeAboutOtherFormsOfBrowsingHistory:(BOOL)shouldShowNotice; - -// Notifies the delegate that history entry deletion has completed. -- (void)historyServiceFacadeDidCompleteEntryRemoval: - (HistoryServiceFacade*)facade; - -@end - -#endif // IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_SERVICE_FACADE_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/history/history_service_facade_unittest.mm b/ios/chrome/browser/ui/history/history_service_facade_unittest.mm deleted file mode 100644 index ed735d3..0000000 --- a/ios/chrome/browser/ui/history/history_service_facade_unittest.mm +++ /dev/null
@@ -1,222 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/history/history_service_facade.h" - -#include <memory> - -#include "base/run_loop.h" -#include "base/strings/string16.h" -#include "components/history/core/browser/history_service.h" -#include "components/history/core/browser/history_service_observer.h" -#include "components/keyed_service/core/service_access_type.h" -#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" -#include "ios/chrome/browser/history/history_service_factory.h" -#import "ios/chrome/browser/ui/history/history_entry.h" -#import "ios/chrome/browser/ui/history/history_service_facade_delegate.h" -#include "ios/web/public/test/test_web_thread.h" -#include "ios/web/public/test/test_web_thread_bundle.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" -#import "third_party/ocmock/OCMock/OCMock.h" -#include "third_party/ocmock/gtest_support.h" - -namespace { - -struct TestResult { - GURL url; - int64_t hour_offset; // Visit time in hours past the baseline time. -}; - -// Duplicates on the same day in the local timezone are removed, so set a -// baseline time in local time. -const base::Time baseline_time = base::Time::UnixEpoch().LocalMidnight(); - -// Returns true if |result| matches the test data given by |correct_result|, -// otherwise returns false. -bool ResultEquals(const history::HistoryEntry& result, - const TestResult& correct_result) { - base::Time correct_time = - baseline_time + base::TimeDelta::FromHours(correct_result.hour_offset); - - return result.time == correct_time && result.url == correct_result.url; -} - -// Returns RemovedEntry using |time_offset| -HistoryServiceFacade::RemovedEntry EntryForRemoval(const GURL& url, - int64_t time_offset) { - return HistoryServiceFacade::RemovedEntry( - url, baseline_time + base::TimeDelta::FromHours(time_offset)); -} -} // namespace - -// Mock delegate for verifying callback behavior. -@interface MockHistoryServiceFacadeDelegate - : NSObject<HistoryServiceFacadeDelegate> { - std::vector<history::HistoryEntry> _received_entries; -} -@property BOOL didCompleteRemoval; -@property BOOL didReceiveOtherBrowsingHistoryCallback; -- (BOOL)delegateDidReceiveResult:(const TestResult&)expected_result; -@end - -@implementation MockHistoryServiceFacadeDelegate -@synthesize didCompleteRemoval = _didCompleteRemoval; -@synthesize didReceiveOtherBrowsingHistoryCallback = - _didReceiveOtherBrowsingHistoryCallback; - -- (void)historyServiceFacade:(HistoryServiceFacade*)facade - didReceiveQueryResult:(HistoryServiceFacade::QueryResult)result { - _received_entries = result.entries; -} - -- (void)historyServiceFacade:(HistoryServiceFacade*)facade - shouldShowNoticeAboutOtherFormsOfBrowsingHistory:(BOOL)shouldShowNotice { - _didReceiveOtherBrowsingHistoryCallback = YES; -} - -// Notifies the delegate that history entry deletion has completed. -- (void)historyServiceFacadeDidCompleteEntryRemoval: - (HistoryServiceFacade*)facade { - _didCompleteRemoval = YES; -} - -- (BOOL)delegateDidReceiveResult:(const TestResult&)expected_result { - for (history::HistoryEntry entry : _received_entries) { - if (ResultEquals(entry, expected_result)) - return YES; - } - return NO; -} - -@end - -class HistoryServiceFacadeTest : public PlatformTest, - public history::HistoryServiceObserver { - public: - HistoryServiceFacadeTest() {} - ~HistoryServiceFacadeTest() override {} - - void SetUp() override { - DCHECK_CURRENTLY_ON(web::WebThread::UI); - TestChromeBrowserState::Builder builder; - browser_state_ = builder.Build(); - bool success = browser_state_->CreateHistoryService(true); - EXPECT_TRUE(success); - - mock_delegate_ = [[MockHistoryServiceFacadeDelegate alloc] init]; - history_service_facade_.reset( - new HistoryServiceFacade(browser_state_.get(), mock_delegate_)); - } - - // Cycles the runloop until the condition is met (up to 10 seconds). - typedef base::Callback<bool(void)> WaitCondition; - bool WaitUntilLoop(WaitCondition condition) { - DCHECK_CURRENTLY_ON(web::WebThread::UI); - base::Time maxDate = base::Time::Now() + base::TimeDelta::FromSeconds(10); - while (!condition.Run()) { - if (base::Time::Now() > maxDate) - return false; - base::RunLoop().RunUntilIdle(); - base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); - } - return true; - } - - // Adds a visit to history. - void AddVisit(const GURL& url, int64_t time_offset) { - history::HistoryService* history_service = - ios::HistoryServiceFactory::GetForBrowserStateIfExists( - browser_state_.get(), ServiceAccessType::EXPLICIT_ACCESS); - EXPECT_TRUE(history_service); - - history_service->AddObserver(this); - base::Time time = baseline_time + base::TimeDelta::FromHours(time_offset); - history_service->AddPage(url, time, history::VisitSource::SOURCE_BROWSED); - - // Wait until the data is in the db. - EXPECT_TRUE(WaitUntilLoop(base::Bind(&HistoryServiceFacadeTest::VerifyVisit, - base::Unretained(this), url, time))); - - history_service->RemoveObserver(this); - } - - // history::HistoryServiceObserver - void OnURLVisited(history::HistoryService* history_service, - ui::PageTransition transition, - const history::URLRow& row, - const history::RedirectList& redirects, - base::Time visit_time) override { - visited_url_ = row.url(); - visited_time_ = row.last_visit(); - } - - // Verify visit to |url| at |time| was observed. - bool VerifyVisit(const GURL& url, const base::Time& time) { - return visited_url_ == url && visited_time_ == time; - } - - // Verify that a query result was received by delegate callback. - bool VerifyQueryResult(const TestResult& result) { - return [mock_delegate_ delegateDidReceiveResult:result]; - } - - // Verify that entry removal completion delegate callback was called. - bool VerifyEntryRemoval() { return [mock_delegate_ didCompleteRemoval]; } - - // Verify that the - // historyServiceFacade:shouldShowNoticeAboutOtherFormsOfBrowsingHistory - // delegate callback was called. - bool VerifyOtherHistoryCallback() { - return [mock_delegate_ didReceiveOtherBrowsingHistoryCallback]; - } - - protected: - web::TestWebThreadBundle thread_bundle_; - std::unique_ptr<TestChromeBrowserState> browser_state_; - MockHistoryServiceFacadeDelegate* mock_delegate_; - std::unique_ptr<HistoryServiceFacade> history_service_facade_; - GURL visited_url_; - base::Time visited_time_; - DISALLOW_COPY_AND_ASSIGN(HistoryServiceFacadeTest); -}; - -// Tests that invoking QueryHistory results in the delegate receiving an added -// history entry. -TEST_F(HistoryServiceFacadeTest, TestQueryHistory) { - GURL url("http://www.testurl.com"); - AddVisit(url, 0); - - base::string16 query = base::string16(); - history::QueryOptions options; - history_service_facade_->QueryHistory(query, options); - - TestResult expected_result = {url, 0}; - EXPECT_TRUE( - WaitUntilLoop(base::Bind(&HistoryServiceFacadeTest::VerifyQueryResult, - base::Unretained(this), expected_result))); -} - -// Tests that invoking RemoveHistoryEntries completes with callback to delegate -// method historyServiceFacadeDidCompleteEntryRemoval. -TEST_F(HistoryServiceFacadeTest, TestRemoveHistoryEntries) { - GURL url("http://www.testurl.com"); - AddVisit(url, 0); - - std::vector<HistoryServiceFacade::RemovedEntry> entries_to_remove{ - EntryForRemoval(url, 0)}; - history_service_facade_->RemoveHistoryEntries(entries_to_remove); - EXPECT_TRUE(WaitUntilLoop(base::Bind( - &HistoryServiceFacadeTest::VerifyEntryRemoval, base::Unretained(this)))); -} - -// Tests that invoking QueryOtherFormsOfBrowsingHistory completes with callback -// to delegate method -// historyServiceFacade:shouldShowNoticeAboutOtherFormsOfBrowsingHistory:. -TEST_F(HistoryServiceFacadeTest, TestQueryOtherFormsOfBrowsingHistory) { - history_service_facade_->QueryOtherFormsOfBrowsingHistory(); - EXPECT_TRUE(WaitUntilLoop( - base::Bind(&HistoryServiceFacadeTest::VerifyOtherHistoryCallback, - base::Unretained(this)))); -}
diff --git a/ios/chrome/browser/ui/history/history_util.h b/ios/chrome/browser/ui/history/history_util.h index f6831cf2..04b99ac 100644 --- a/ios/chrome/browser/ui/history/history_util.h +++ b/ios/chrome/browser/ui/history/history_util.h
@@ -5,8 +5,6 @@ #ifndef IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_UTIL_H_ #define IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_UTIL_H_ -#include <vector> - #include "base/strings/string16.h" namespace base { @@ -15,16 +13,10 @@ namespace history { -struct HistoryEntry; - // Returns a localized version of |visit_time| including a relative // indicator (e.g. today, yesterday). base::string16 GetRelativeDateLocalized(const base::Time& visit_time); -// Sorts and merges duplicate entries from the query results, only retaining the -// most recent visit to a URL on a particular day. That visit contains the -// timestamps of the other visits. -void MergeDuplicateHistoryEntries(std::vector<history::HistoryEntry>* entries); } // namespace history #endif // IOS_CHROME_BROWSER_UI_HISTORY_HISTORY_UTIL_H_
diff --git a/ios/chrome/browser/ui/history/history_util.mm b/ios/chrome/browser/ui/history/history_util.mm index 6a206ad..f9b6b3a 100644 --- a/ios/chrome/browser/ui/history/history_util.mm +++ b/ios/chrome/browser/ui/history/history_util.mm
@@ -4,15 +4,11 @@ #include "ios/chrome/browser/ui/history/history_util.h" -#include <map> - #include "base/i18n/time_formatting.h" #include "base/time/time.h" #include "components/strings/grit/components_strings.h" -#include "ios/chrome/browser/ui/history/history_entry.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/time_format.h" -#include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -33,44 +29,4 @@ return date_str; } -void MergeDuplicateHistoryEntries(std::vector<history::HistoryEntry>* entries) { - std::vector<history::HistoryEntry> new_entries; - // Pre-reserve the size of the new vector. Since we're working with pointers - // later on not doing this could lead to the vector being resized and to - // pointers to invalid locations. - new_entries.reserve(entries->size()); - // Maps a URL to the most recent entry on a particular day. - std::map<GURL, history::HistoryEntry*> current_day_entries; - - // Keeps track of the day that |current_day_urls| is holding the URLs for, - // in order to handle removing per-day duplicates. - base::Time current_day_midnight; - - std::sort(entries->begin(), entries->end(), - history::HistoryEntry::SortByTimeDescending); - - for (const history::HistoryEntry& entry : *entries) { - // Reset the list of found URLs when a visit from a new day is encountered. - if (current_day_midnight != entry.time.LocalMidnight()) { - current_day_entries.clear(); - current_day_midnight = entry.time.LocalMidnight(); - } - - // Keep this visit if it's the first visit to this URL on the current day. - if (current_day_entries.count(entry.url) == 0) { - new_entries.push_back(entry); - current_day_entries[entry.url] = &new_entries.back(); - } else { - // Keep track of the timestamps of all visits to the URL on the same day. - history::HistoryEntry* combined_entry = current_day_entries[entry.url]; - combined_entry->all_timestamps.insert(entry.all_timestamps.begin(), - entry.all_timestamps.end()); - - if (combined_entry->entry_type != entry.entry_type) { - combined_entry->entry_type = history::HistoryEntry::COMBINED_ENTRY; - } - } - } - entries->swap(new_entries); -} } // namespace history
diff --git a/ios/chrome/browser/ui/history/history_util_unittest.mm b/ios/chrome/browser/ui/history/history_util_unittest.mm deleted file mode 100644 index 5ff62d3..0000000 --- a/ios/chrome/browser/ui/history/history_util_unittest.mm +++ /dev/null
@@ -1,137 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/history/history_util.h" - -#include <stdint.h> - -#include "base/macros.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "ios/chrome/browser/ui/history/history_entry.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -struct TestResult { - std::string url; - int64_t hour_offset; // Visit time in hours past the baseline time. -}; - -// Duplicates on the same day in the local timezone are removed, so set a -// baseline time in local time. -const base::Time baseline_time = base::Time::UnixEpoch().LocalMidnight(); - -// For each item in |results|, create a new Value representing the visit, and -// insert it into |list_value|. -void AddQueryResults(TestResult* test_results, - int test_results_size, - std::vector<history::HistoryEntry>* results) { - for (int i = 0; i < test_results_size; ++i) { - history::HistoryEntry entry; - entry.time = - baseline_time + base::TimeDelta::FromHours(test_results[i].hour_offset); - entry.url = GURL(test_results[i].url); - entry.all_timestamps.insert(entry.time.ToInternalValue()); - results->push_back(entry); - } -} - -// Returns true if |result| matches the test data given by |correct_result|, -// otherwise returns false. -bool ResultEquals(const history::HistoryEntry& result, - const TestResult& correct_result) { - base::Time correct_time = - baseline_time + base::TimeDelta::FromHours(correct_result.hour_offset); - - return result.time == correct_time && result.url == GURL(correct_result.url); -} - -} // namespace - -// Tests that the MergeDuplicateResults method correctly removes duplicate -// visits to the same URL on the same day. -TEST(HistoryUtilTest, MergeDuplicateResults) { - { - // Basic test that duplicates on the same day are removed. - TestResult test_data[] = { - {"http://testurl.com", 0}, - {"http://testurl.de", 1}, - {"http://testurl.com", 2}, - {"http://testurl.com", 3} // Most recent. - }; - std::vector<history::HistoryEntry> results; - AddQueryResults(test_data, arraysize(test_data), &results); - history::MergeDuplicateHistoryEntries(&results); - - ASSERT_EQ(2U, results.size()); - EXPECT_TRUE(ResultEquals(results[0], test_data[3])); - EXPECT_TRUE(ResultEquals(results[1], test_data[1])); - } - - { - // Test that a duplicate URL on the next day is not removed. - TestResult test_data[] = { - {"http://testurl.com", 0}, - {"http://testurl.com", 23}, - {"http://testurl.com", 24}, // Most recent. - }; - std::vector<history::HistoryEntry> results; - AddQueryResults(test_data, arraysize(test_data), &results); - history::MergeDuplicateHistoryEntries(&results); - - ASSERT_EQ(2U, results.size()); - EXPECT_TRUE(ResultEquals(results[0], test_data[2])); - EXPECT_TRUE(ResultEquals(results[1], test_data[1])); - } - - { - // Test multiple duplicates across multiple days. - TestResult test_data[] = { - // First day. - {"http://testurl.de", 0}, - {"http://testurl.com", 1}, - {"http://testurl.de", 2}, - {"http://testurl.com", 3}, - - // Second day. - {"http://testurl.de", 24}, - {"http://testurl.com", 25}, - {"http://testurl.de", 26}, - {"http://testurl.com", 27}, // Most recent. - }; - std::vector<history::HistoryEntry> results; - AddQueryResults(test_data, arraysize(test_data), &results); - history::MergeDuplicateHistoryEntries(&results); - - ASSERT_EQ(4U, results.size()); - EXPECT_TRUE(ResultEquals(results[0], test_data[7])); - EXPECT_TRUE(ResultEquals(results[1], test_data[6])); - EXPECT_TRUE(ResultEquals(results[2], test_data[3])); - EXPECT_TRUE(ResultEquals(results[3], test_data[2])); - } - - { - // Test that timestamps for duplicates are properly saved. - TestResult test_data[] = { - {"http://testurl.com", 0}, - {"http://testurl.de", 1}, - {"http://testurl.com", 2}, - {"http://testurl.com", 3} // Most recent. - }; - std::vector<history::HistoryEntry> results; - AddQueryResults(test_data, arraysize(test_data), &results); - history::MergeDuplicateHistoryEntries(&results); - - ASSERT_EQ(2U, results.size()); - EXPECT_TRUE(ResultEquals(results[0], test_data[3])); - EXPECT_TRUE(ResultEquals(results[1], test_data[1])); - EXPECT_EQ(3u, results[0].all_timestamps.size()); - EXPECT_EQ(1u, results[1].all_timestamps.size()); - } -}
diff --git a/ios/chrome/browser/ui/history/ios_browsing_history_driver.h b/ios/chrome/browser/ui/history/ios_browsing_history_driver.h new file mode 100644 index 0000000..e625c1e4c --- /dev/null +++ b/ios/chrome/browser/ui/history/ios_browsing_history_driver.h
@@ -0,0 +1,84 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_HISTORY_IOS_BROWSING_HISTORY_DRIVER_H_ +#define IOS_CHROME_BROWSER_UI_HISTORY_IOS_BROWSING_HISTORY_DRIVER_H_ + +#include <vector> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/history/core/browser/browsing_history_driver.h" +#include "components/history/core/browser/browsing_history_service.h" +#include "url/gurl.h" + +namespace history { +class HistoryService; +} + +namespace ios { +class ChromeBrowserState; +} + +// Defines methods to manage history query results and deletion actions. +@protocol BrowsingHistoryDriverDelegate<NSObject> + +// Notifies the delegate that the result of a history query has been retrieved. +// Entries in |result| are already sorted. +- (void)onQueryCompleteWithResults: + (const std::vector<history::BrowsingHistoryService::HistoryEntry>&) + results + queryResultsInfo: + (const history::BrowsingHistoryService::QueryResultsInfo&) + queryResultsInfo; + +// Notifies the delegate that history entries have been deleted by a different +// client and that the UI should be updated. +- (void)didObserverHistoryDeletion; + +// Indicates to the delegate whether to show notice about other forms of +// browsing history. +- (void)shouldShowNoticeAboutOtherFormsOfBrowsingHistory:(BOOL)shouldShowNotice; + +@end + +// A simple implementation of BrowsingHistoryServiceHandler that delegates to +// objective-c object BrowsingHistoryDriverDelegate for most actions. +class IOSBrowsingHistoryDriver : public history::BrowsingHistoryDriver { + public: + IOSBrowsingHistoryDriver(ios::ChromeBrowserState* browser_state, + id<BrowsingHistoryDriverDelegate> delegate); + ~IOSBrowsingHistoryDriver() override; + + private: + // history::BrowsingHistoryDriver implementation. + void OnQueryComplete( + const std::vector<history::BrowsingHistoryService::HistoryEntry>& results, + const history::BrowsingHistoryService::QueryResultsInfo& + query_results_info) override; + void OnRemoveVisitsComplete() override; + void OnRemoveVisitsFailed() override; + void OnRemoveVisits( + const std::vector<history::ExpireHistoryArgs>& expire_list) override; + void HistoryDeleted() override; + void HasOtherFormsOfBrowsingHistory(bool has_other_forms, + bool has_synced_results) override; + bool AllowHistoryDeletions() override; + bool ShouldHideWebHistoryUrl(const GURL& url) override; + history::WebHistoryService* GetWebHistoryService() override; + void ShouldShowNoticeAboutOtherFormsOfBrowsingHistory( + const syncer::SyncService* sync_service, + history::WebHistoryService* history_service, + base::Callback<void(bool)> callback) override; + + // The current browser state. + ios::ChromeBrowserState* browser_state_; // weak + + // Delegate for IOSBrowsingHistoryDriver. Serves as client for HistoryService. + __weak id<BrowsingHistoryDriverDelegate> delegate_; + + DISALLOW_COPY_AND_ASSIGN(IOSBrowsingHistoryDriver); +}; + +#endif // IOS_CHROME_BROWSER_UI_HISTORY_IOS_BROWSING_HISTORY_DRIVER_H_
diff --git a/ios/chrome/browser/ui/history/ios_browsing_history_driver.mm b/ios/chrome/browser/ui/history/ios_browsing_history_driver.mm new file mode 100644 index 0000000..01a3770f --- /dev/null +++ b/ios/chrome/browser/ui/history/ios_browsing_history_driver.mm
@@ -0,0 +1,89 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/history/ios_browsing_history_driver.h" + +#include <utility> + +#include "base/logging.h" +#include "base/mac/bind_objc_block.h" +#include "base/strings/utf_string_conversions.h" +#include "components/browsing_data/core/history_notice_utils.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/history/history_utils.h" +#include "ios/chrome/browser/history/web_history_service_factory.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using history::BrowsingHistoryService; + +#pragma mark - IOSBrowsingHistoryDriver + +IOSBrowsingHistoryDriver::IOSBrowsingHistoryDriver( + ios::ChromeBrowserState* browser_state, + id<BrowsingHistoryDriverDelegate> delegate) + : browser_state_(browser_state), delegate_(delegate) { + DCHECK(browser_state_); +} + +IOSBrowsingHistoryDriver::~IOSBrowsingHistoryDriver() { + delegate_ = nil; +} + +#pragma mark - Private methods + +void IOSBrowsingHistoryDriver::OnQueryComplete( + const std::vector<BrowsingHistoryService::HistoryEntry>& results, + const BrowsingHistoryService::QueryResultsInfo& query_results_info) { + [delegate_ onQueryCompleteWithResults:results + queryResultsInfo:query_results_info]; +} + +void IOSBrowsingHistoryDriver::OnRemoveVisitsComplete() { + // Ignored. +} + +void IOSBrowsingHistoryDriver::OnRemoveVisitsFailed() { + // Ignored. +} + +void IOSBrowsingHistoryDriver::OnRemoveVisits( + const std::vector<history::ExpireHistoryArgs>& expire_list) { + // Ignored. +} + +void IOSBrowsingHistoryDriver::HistoryDeleted() { + [delegate_ didObserverHistoryDeletion]; +} + +void IOSBrowsingHistoryDriver::HasOtherFormsOfBrowsingHistory( + bool has_other_forms, + bool has_synced_results) { + [delegate_ shouldShowNoticeAboutOtherFormsOfBrowsingHistory:has_other_forms]; +} + +bool IOSBrowsingHistoryDriver::AllowHistoryDeletions() { + // Current reasons for suppressing history deletions are from features that + // are not currently supported on iOS. Reasons being administrator policy and + // supervised users. + return true; +} + +bool IOSBrowsingHistoryDriver::ShouldHideWebHistoryUrl(const GURL& url) { + return !ios::CanAddURLToHistory(url); +} + +history::WebHistoryService* IOSBrowsingHistoryDriver::GetWebHistoryService() { + return ios::WebHistoryServiceFactory::GetForBrowserState(browser_state_); +} + +void IOSBrowsingHistoryDriver::ShouldShowNoticeAboutOtherFormsOfBrowsingHistory( + const syncer::SyncService* sync_service, + history::WebHistoryService* history_service, + base::Callback<void(bool)> callback) { + browsing_data::ShouldShowNoticeAboutOtherFormsOfBrowsingHistory( + sync_service, history_service, std::move(callback)); +}
diff --git a/ipc/handle_attachment_fuchsia.cc b/ipc/handle_attachment_fuchsia.cc index 9d4d13f..88cf518 100644 --- a/ipc/handle_attachment_fuchsia.cc +++ b/ipc/handle_attachment_fuchsia.cc
@@ -13,13 +13,12 @@ HandleAttachmentFuchsia::HandleAttachmentFuchsia(const mx_handle_t& handle) { mx_status_t result = mx_handle_duplicate(handle, MX_RIGHT_SAME_RIGHTS, handle_.receive()); - DLOG_IF(ERROR, result == MX_OK) + DLOG_IF(ERROR, result != MX_OK) << "mx_handle_duplicate: " << mx_status_get_string(result); } -HandleAttachmentFuchsia::HandleAttachmentFuchsia(const mx_handle_t& handle, - FromWire from_wire) - : handle_(handle) {} +HandleAttachmentFuchsia::HandleAttachmentFuchsia(base::ScopedMxHandle handle) + : handle_(std::move(handle)) {} HandleAttachmentFuchsia::~HandleAttachmentFuchsia() {}
diff --git a/ipc/handle_attachment_fuchsia.h b/ipc/handle_attachment_fuchsia.h index 072df0c3..915e4166 100644 --- a/ipc/handle_attachment_fuchsia.h +++ b/ipc/handle_attachment_fuchsia.h
@@ -22,12 +22,9 @@ // result. Should only be called by the sender of a Chrome IPC message. explicit HandleAttachmentFuchsia(const mx_handle_t& handle); - enum FromWire { - FROM_WIRE, - }; // This constructor takes ownership of |handle|. Should only be called by the // receiver of a Chrome IPC message. - HandleAttachmentFuchsia(const mx_handle_t& handle, FromWire from_wire); + explicit HandleAttachmentFuchsia(base::ScopedMxHandle handle); Type GetType() const override;
diff --git a/ipc/ipc_channel_mojo.cc b/ipc/ipc_channel_mojo.cc index 006a9ab6..af5b86b 100644 --- a/ipc/ipc_channel_mojo.cc +++ b/ipc/ipc_channel_mojo.cc
@@ -40,6 +40,10 @@ #include "ipc/handle_attachment_win.h" #endif +#if defined(OS_FUCHSIA) +#include "ipc/handle_attachment_fuchsia.h" +#endif + namespace IPC { namespace { @@ -92,7 +96,6 @@ } #if defined(OS_MACOSX) - MojoResult WrapMachPort(mach_port_t mach_port, mojom::SerializedHandlePtr* serialized) { MojoPlatformHandle platform_handle = { @@ -110,17 +113,31 @@ mojom::SerializedHandle::Type::MACH_PORT); return MOJO_RESULT_OK; } +#elif defined(OS_FUCHSIA) +MojoResult WrapMxHandle(mx_handle_t handle, + mojom::SerializedHandlePtr* serialized) { + MojoPlatformHandle platform_handle = { + sizeof(MojoPlatformHandle), MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE, + static_cast<uint64_t>(handle)}; -#endif + MojoHandle wrapped_handle; + MojoResult result = MojoWrapPlatformHandle(&platform_handle, &wrapped_handle); + if (result != MOJO_RESULT_OK) + return result; + + *serialized = CreateSerializedHandle( + mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)), + mojom::SerializedHandle::Type::FUCHSIA_HANDLE); + return MOJO_RESULT_OK; +} +#endif // defined(OS_FUCHSIA) #if defined(OS_POSIX) - base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) { return attachment->Owns() ? base::ScopedFD(attachment->TakePlatformFile()) : base::ScopedFD(dup(attachment->file())); } - -#endif +#endif // defined(OS_POSIX) MojoResult WrapAttachmentImpl(MessageAttachment* attachment, mojom::SerializedHandlePtr* serialized) { @@ -146,7 +163,7 @@ mojom::SerializedHandle::Type::PLATFORM_FILE, serialized); } -#endif +#endif // defined(OS_POSIX) #if defined(OS_MACOSX) DCHECK_EQ(attachment->GetType(), MessageAttachment::Type::MACH_PORT); internal::MachPortAttachmentMac& mach_port_attachment = @@ -155,6 +172,12 @@ serialized); mach_port_attachment.reset_mach_port_ownership(); return result; +#elif defined(OS_FUCHSIA) + DCHECK_EQ(attachment->GetType(), MessageAttachment::Type::FUCHSIA_HANDLE); + internal::HandleAttachmentFuchsia& handle_attachment = + static_cast<internal::HandleAttachmentFuchsia&>(*attachment); + MojoResult result = WrapMxHandle(handle_attachment.Take(), serialized); + return result; #elif defined(OS_WIN) DCHECK_EQ(attachment->GetType(), MessageAttachment::Type::WIN_HANDLE); internal::HandleAttachmentWin& handle_attachment = @@ -211,8 +234,15 @@ mach_port, internal::MachPortAttachmentMac::FROM_WIRE); return MOJO_RESULT_OK; } -#endif // defined(OS_MACOSX) -#if defined(OS_WIN) +#elif defined(OS_FUCHSIA) + if (handle->type == mojom::SerializedHandle::Type::FUCHSIA_HANDLE) { + base::ScopedMxHandle handle; + if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE) + handle.reset(static_cast<mx_handle_t>(platform_handle.value)); + *attachment = new internal::HandleAttachmentFuchsia(std::move(handle)); + return MOJO_RESULT_OK; + } +#elif defined(OS_WIN) if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) { base::PlatformFile handle = base::kInvalidPlatformFile; if (platform_handle.type == MOJO_PLATFORM_HANDLE_TYPE_WINDOWS_HANDLE)
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 23da3b9..deda35a 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -234,6 +234,10 @@ const base::Feature kNewRemotePlaybackPipeline{ "NewRemotePlaybackPipeline", base::FEATURE_DISABLED_BY_DEFAULT}; +// Set preload to "metadata" by default for <video> and <audio>. +const base::Feature kPreloadDefaultIsMetadata{ + "PreloadDefaultIsMetadata", base::FEATURE_DISABLED_BY_DEFAULT}; + // CanPlayThrough issued according to standard. const base::Feature kSpecCompliantCanPlayThrough{ "SpecCompliantCanPlayThrough", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 900679b9..37f6c9ef 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -116,6 +116,7 @@ MEDIA_EXPORT extern const base::Feature kNewAudioRenderingMixingStrategy; MEDIA_EXPORT extern const base::Feature kNewRemotePlaybackPipeline; MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo; +MEDIA_EXPORT extern const base::Feature kPreloadDefaultIsMetadata; MEDIA_EXPORT extern const base::Feature kResumeBackgroundVideo; MEDIA_EXPORT extern const base::Feature kSpecCompliantCanPlayThrough; MEDIA_EXPORT extern const base::Feature kSupportExperimentalCdmInterface;
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc index f1e1e1e..8bdd7ee 100644 --- a/media/blink/webmediaplayer_impl.cc +++ b/media/blink/webmediaplayer_impl.cc
@@ -183,7 +183,9 @@ network_state_(WebMediaPlayer::kNetworkStateEmpty), ready_state_(WebMediaPlayer::kReadyStateHaveNothing), highest_ready_state_(WebMediaPlayer::kReadyStateHaveNothing), - preload_(MultibufferDataSource::AUTO), + preload_(base::FeatureList::IsEnabled(kPreloadDefaultIsMetadata) + ? MultibufferDataSource::METADATA + : MultibufferDataSource::AUTO), main_task_runner_(frame->LoadingTaskRunner()), media_task_runner_(params->media_task_runner()), worker_task_runner_(params->worker_task_runner()),
diff --git a/media/formats/mp2t/es_parser_h264.cc b/media/formats/mp2t/es_parser_h264.cc index efcc248..340153de 100644 --- a/media/formats/mp2t/es_parser_h264.cc +++ b/media/formats/mp2t/es_parser_h264.cc
@@ -491,10 +491,18 @@ if (natural_size.width() == 0) return false; + VideoCodecProfile profile = + H264Parser::ProfileIDCToVideoCodecProfile(sps->profile_idc); + if (profile == VIDEO_CODEC_PROFILE_UNKNOWN) { + DVLOG(1) << "Unrecognized SPS profile_idc 0x" << std::hex + << sps->profile_idc; + return false; + } + VideoDecoderConfig video_decoder_config( - kCodecH264, H264Parser::ProfileIDCToVideoCodecProfile(sps->profile_idc), - PIXEL_FORMAT_YV12, COLOR_SPACE_HD_REC709, coded_size.value(), - visible_rect.value(), natural_size, EmptyExtraData(), scheme); + kCodecH264, profile, PIXEL_FORMAT_YV12, COLOR_SPACE_HD_REC709, + coded_size.value(), visible_rect.value(), natural_size, EmptyExtraData(), + scheme); if (!video_decoder_config.Matches(last_video_decoder_config_)) { DVLOG(1) << "Profile IDC: " << sps->profile_idc;
diff --git a/media/formats/mp4/box_definitions.cc b/media/formats/mp4/box_definitions.cc index cb63b77..7e978c2d 100644 --- a/media/formats/mp4/box_definitions.cc +++ b/media/formats/mp4/box_definitions.cc
@@ -733,6 +733,7 @@ video_codec = kCodecH264; video_codec_profile = H264Parser::ProfileIDCToVideoCodecProfile( avcConfig->profile_indication); + frame_bitstream_converter = make_scoped_refptr(new AVCBitstreamConverter(std::move(avcConfig))); #if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING) @@ -823,6 +824,11 @@ return false; } + if (video_codec_profile == VIDEO_CODEC_PROFILE_UNKNOWN) { + MEDIA_LOG(ERROR, reader->media_log()) << "Unrecognized video codec profile"; + return false; + } + return true; }
diff --git a/media/gpu/android_video_decode_accelerator.cc b/media/gpu/android_video_decode_accelerator.cc index 152a4ec..c0fdbc00 100644 --- a/media/gpu/android_video_decode_accelerator.cc +++ b/media/gpu/android_video_decode_accelerator.cc
@@ -1502,10 +1502,10 @@ codec_config_->media_crypto = std::move(media_crypto); codec_config_->requires_secure_codec = requires_secure_video_codec; - // Require a secure surface in all cases, even if we don't require a secure - // video codec. This will send L3 content to a secure surface, if one is - // available, as well as L1. + // Request a secure surface in all cases. For L3, it's okay if we fall back + // to SurfaceTexture rather than fail composition. For L1, it's required. surface_chooser_state_.is_secure = true; + surface_chooser_state_.is_required = requires_secure_video_codec; // After receiving |media_crypto_| we can start with surface creation. StartSurfaceChooser();
diff --git a/media/gpu/android_video_surface_chooser.h b/media/gpu/android_video_surface_chooser.h index aa0c57c..b444846 100644 --- a/media/gpu/android_video_surface_chooser.h +++ b/media/gpu/android_video_surface_chooser.h
@@ -20,9 +20,13 @@ public: // Input state used for choosing the surface type. struct State { + // Is an overlay required? + bool is_required = false; + + // Is the player currently in fullscreen? bool is_fullscreen = false; - // Does playback require a secure surface? + // Should the overlay be marked as secure? bool is_secure = false; // Is the player's frame hidden / closed?
diff --git a/media/gpu/android_video_surface_chooser_impl.cc b/media/gpu/android_video_surface_chooser_impl.cc index 06839d1..66ff4d93 100644 --- a/media/gpu/android_video_surface_chooser_impl.cc +++ b/media/gpu/android_video_surface_chooser_impl.cc
@@ -44,7 +44,8 @@ // Pre-M, we choose now. This lets Choose() never worry about the pre-M path. if (!allow_dynamic_) { if (overlay_factory_ && - (current_state_.is_fullscreen || current_state_.is_secure)) { + (current_state_.is_fullscreen || current_state_.is_secure || + current_state_.is_required)) { SwitchToOverlay(); } else { SwitchToSurfaceTexture(); @@ -106,6 +107,12 @@ if (current_state_.is_fullscreen) new_overlay_state = kUsingOverlay; + // Try to use an overlay if possible for protected content. If the compositor + // won't promote, though, it's okay if we switch out. Set |is_required| in + // addition, if you don't want this behavior. + if (current_state_.is_secure) + new_overlay_state = kUsingOverlay; + // If the compositor won't promote, then don't. if (!current_state_.is_compositor_promotable) new_overlay_state = kUsingSurfaceTexture; @@ -118,15 +125,6 @@ client_overlay_state_ != kUsingOverlay) new_overlay_state = kUsingSurfaceTexture; - // If we need a secure surface, then we must choose an overlay. The only way - // we won't is if we don't have a factory or our request fails. If the - // compositor won't promote, then we still use the overlay, since hopefully - // it's a temporary restriction. If we drop the overlay, then playback will - // fail (L1) or be insecure on SurfaceTexture (L3). For L3, that's still - // preferable to failing. - if (current_state_.is_secure) - new_overlay_state = kUsingOverlay; - // If we're requesting an overlay, check that we haven't asked too recently // since the last failure. This includes L1. We don't bother to check for // our current state, since using an overlay would imply that our most recent @@ -142,6 +140,11 @@ if (current_state_.is_frame_hidden) new_overlay_state = kUsingSurfaceTexture; + // If an overlay is required, then choose one. The only way we won't is if we + // don't have a factory or our request fails. + if (current_state_.is_required) + new_overlay_state = kUsingOverlay; + // If we have no factory, then we definitely don't want to use overlays. if (!overlay_factory_) new_overlay_state = kUsingSurfaceTexture;
diff --git a/media/gpu/android_video_surface_chooser_impl_unittest.cc b/media/gpu/android_video_surface_chooser_impl_unittest.cc index 958ba4f..8a63e125 100644 --- a/media/gpu/android_video_surface_chooser_impl_unittest.cc +++ b/media/gpu/android_video_surface_chooser_impl_unittest.cc
@@ -59,6 +59,7 @@ enum class ShouldUseOverlay { No, Yes }; enum class AllowDynamic { No, Yes }; enum class IsFullscreen { No, Yes }; +enum class IsRequired { No, Yes }; enum class IsSecure { No, Yes }; enum class IsFrameHidden { No, Yes }; enum class IsCCPromotable { No, Yes }; @@ -66,6 +67,7 @@ using TestParams = std::tuple<ShouldUseOverlay, AllowDynamic, + IsRequired, IsFullscreen, IsSecure, IsFrameHidden, @@ -339,11 +341,12 @@ const bool should_use_overlay = IsYes(ShouldUseOverlay, 0); allow_dynamic_ = IsYes(AllowDynamic, 1); - chooser_state_.is_fullscreen = IsYes(IsFullscreen, 2); - chooser_state_.is_secure = IsYes(IsSecure, 3); - chooser_state_.is_frame_hidden = IsYes(IsFrameHidden, 4); - chooser_state_.is_compositor_promotable = IsYes(IsCCPromotable, 5); - chooser_state_.is_expecting_relayout = IsYes(IsExpectingRelayout, 6); + chooser_state_.is_required = IsYes(IsRequired, 2); + chooser_state_.is_fullscreen = IsYes(IsFullscreen, 3); + chooser_state_.is_secure = IsYes(IsSecure, 4); + chooser_state_.is_frame_hidden = IsYes(IsFrameHidden, 5); + chooser_state_.is_compositor_promotable = IsYes(IsCCPromotable, 6); + chooser_state_.is_expecting_relayout = IsYes(IsExpectingRelayout, 7); if (should_use_overlay) { EXPECT_CALL(client_, UseSurfaceTexture()).Times(0); @@ -366,62 +369,85 @@ AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::No), Either(AllowDynamic), + Values(IsRequired::No), Values(IsFullscreen::No), Values(IsSecure::No), Either(IsFrameHidden), Either(IsCCPromotable), Either(IsExpectingRelayout))); + INSTANTIATE_TEST_CASE_P(FullscreenUsesOverlay, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::Yes), Either(AllowDynamic), + Either(IsRequired), Values(IsFullscreen::Yes), Values(IsSecure::No), Values(IsFrameHidden::No), Values(IsCCPromotable::Yes), Values(IsExpectingRelayout::No))); -INSTANTIATE_TEST_CASE_P(SecureUsesOverlay, + +INSTANTIATE_TEST_CASE_P(RequiredUsesOverlay, + AndroidVideoSurfaceChooserImplTest, + Combine(Values(ShouldUseOverlay::Yes), + Values(AllowDynamic::Yes), + Values(IsRequired::Yes), + Either(IsFullscreen), + Either(IsSecure), + Either(IsFrameHidden), + Either(IsCCPromotable), + Either(IsExpectingRelayout))); + +// Secure textures should use an overlay if the compositor will promote them. +// We don't care about relayout, since it's transient; either behavior is okay +// if a relayout is epected. Similarly, hidden frames are fine either way. +INSTANTIATE_TEST_CASE_P(SecureUsesOverlayIfPromotable, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::Yes), Either(AllowDynamic), + Either(IsRequired), Either(IsFullscreen), Values(IsSecure::Yes), Values(IsFrameHidden::No), Values(IsCCPromotable::Yes), - Either(IsExpectingRelayout))); + Values(IsExpectingRelayout::No))); INSTANTIATE_TEST_CASE_P(HiddenFramesUseSurfaceTexture, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::No), Values(AllowDynamic::Yes), + Values(IsRequired::No), Either(IsFullscreen), Either(IsSecure), Values(IsFrameHidden::Yes), Either(IsCCPromotable), Either(IsExpectingRelayout))); + // For all dynamic cases, we shouldn't use an overlay if the compositor won't -// promote it. For L1, it will fail either way until the CC supports "must -// promote" overlays, so we ignore those cases. Non-dynamic is excluded, since +// promote it, unless it's marked as required. This includes secure surfaces, +// so that L3 will fall back to SurfaceTexture. Non-dynamic is excluded, since // we don't get (or use) compositor feedback before the first frame. At that // point, we've already chosen the output surface and can't switch it. -INSTANTIATE_TEST_CASE_P(NotCCPromotableNotSecureUsesSurfaceTexture, +INSTANTIATE_TEST_CASE_P(NotCCPromotableNotRequiredUsesSurfaceTexture, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::No), Values(AllowDynamic::Yes), + Values(IsRequired::No), Either(IsFullscreen), - Values(IsSecure::No), + Either(IsSecure), Values(IsFrameHidden::No), Values(IsCCPromotable::No), Either(IsExpectingRelayout))); // If we're expecting a relayout, then we should never use an overlay unless -// it's required for a secure output. +// it's required. INSTANTIATE_TEST_CASE_P(InsecureExpectingRelayoutUsesSurfaceTexture, AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::No), Values(AllowDynamic::Yes), + Values(IsRequired::No), Either(IsFullscreen), - Values(IsSecure::No), + Either(IsSecure), Either(IsFrameHidden), Either(IsCCPromotable), Values(IsExpectingRelayout::Yes))); @@ -431,6 +457,7 @@ AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::Yes), Values(AllowDynamic::No), + Either(IsRequired), Values(IsFullscreen::Yes), Either(IsSecure), Either(IsFrameHidden), @@ -442,10 +469,23 @@ AndroidVideoSurfaceChooserImplTest, Combine(Values(ShouldUseOverlay::Yes), Values(AllowDynamic::No), + Either(IsRequired), Either(IsFullscreen), Values(IsSecure::Yes), Either(IsFrameHidden), Either(IsCCPromotable), Either(IsExpectingRelayout))); +// "is_required" should be enough to trigger an overlay pre-M. +INSTANTIATE_TEST_CASE_P(NotDynamicRequiredUsesOverlay, + AndroidVideoSurfaceChooserImplTest, + Combine(Values(ShouldUseOverlay::Yes), + Values(AllowDynamic::No), + Values(IsRequired::Yes), + Either(IsFullscreen), + Either(IsSecure), + Either(IsFrameHidden), + Either(IsCCPromotable), + Either(IsExpectingRelayout))); + } // namespace media
diff --git a/media/video/h264_parser.cc b/media/video/h264_parser.cc index 5e1f657..d32a85a 100644 --- a/media/video/h264_parser.cc +++ b/media/video/h264_parser.cc
@@ -426,7 +426,7 @@ case H264SPS::kProfileIDSMultiviewHigh: return H264PROFILE_MULTIVIEWHIGH; } - NOTREACHED() << "unknown video profile: " << profile_idc; + DVLOG(1) << "unknown video profile: " << profile_idc; return VIDEO_CODEC_PROFILE_UNKNOWN; }
diff --git a/mojo/edk/embedder/platform_handle.h b/mojo/edk/embedder/platform_handle.h index 2624a65..aa86621 100644 --- a/mojo/edk/embedder/platform_handle.h +++ b/mojo/edk/embedder/platform_handle.h
@@ -16,8 +16,11 @@ #include <mach/mach.h> #elif defined(OS_FUCHSIA) #include <magenta/syscalls.h> +#include <mxio/limits.h> #endif +#include "base/logging.h" + namespace mojo { namespace edk { @@ -34,6 +37,7 @@ } static PlatformHandle ForFd(int fd) { PlatformHandle platform_handle; + DCHECK_LT(fd, MAX_MXIO_FD); platform_handle.fd = fd; return platform_handle; }
diff --git a/mojo/public/cpp/bindings/README.md b/mojo/public/cpp/bindings/README.md index 0b2657a4..e27d13f 100644 --- a/mojo/public/cpp/bindings/README.md +++ b/mojo/public/cpp/bindings/README.md
@@ -620,7 +620,7 @@ ```cpp union Value { int64 int_value; - float32 float_vlaue; + float32 float_value; string string_value; };
diff --git a/net/BUILD.gn b/net/BUILD.gn index 7e6622a..fbb0b0da 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -2657,7 +2657,7 @@ public_deps += [ "//crypto:platform" ] } - if (is_android) { + if (is_android || is_fuchsia) { sources += [ "test/spawned_test_server/remote_test_server.cc", "test/spawned_test_server/remote_test_server.h", @@ -5358,6 +5358,10 @@ ] } + if (is_fuchsia) { + use_test_server = true + } + if (!use_nss_certs) { sources -= [ "cert/internal/trust_store_nss_unittest.cc",
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 1eb2d28..568fc05 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -258,8 +258,6 @@ UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfJobController", job_controller_set_.size()); - int alt_job_count = 0; - int main_job_count = 0; size_t num_controllers_with_request = 0; size_t num_controllers_for_preconnect = 0; for (const auto& job_controller : job_controller_set_) { @@ -277,10 +275,6 @@ // For non-preconnects. if (job_controller->HasPendingRequest()) num_controllers_with_request++; - if (job_controller->HasPendingAltJob()) - alt_job_count++; - if (job_controller->HasPendingMainJob()) - main_job_count++; } UMA_HISTOGRAM_COUNTS_1M( "Net.JobControllerSet.CountOfJobController.Preconnect", @@ -288,16 +282,10 @@ UMA_HISTOGRAM_COUNTS_1M( "Net.JobControllerSet.CountOfJobController.NonPreconnect.PendingRequest", num_controllers_with_request); - UMA_HISTOGRAM_COUNTS_1M( "Net.JobControllerSet.CountOfJobController.NonPreconnect.RequestGone", job_controller_set_.size() - num_controllers_for_preconnect - num_controllers_with_request); - - UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfNonPreconnectAltJob", - alt_job_count); - UMA_HISTOGRAM_COUNTS_1M("Net.JobControllerSet.CountOfNonPreconnectMainJob", - main_job_count); } void HttpStreamFactoryImpl::DumpMemoryStats(
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index 2f73ecc..f8c3d5b 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -34884,6 +34884,7 @@ "expect_staple": true, "include_subdomains_for_expect_staple": true, "expect_staple_report_uri": "https://photistic.report-uri.io/r/default/staple/reportOnly" }, + { "name": "ccu.plus", "include_subdomains": true, "mode": "force-https" }, // END OF MANUAL ENTRIES // TODO(lgarron): hstspreload.org can't scan IPv6-only sites due to Google
diff --git a/net/quic/chromium/quic_chromium_client_session.cc b/net/quic/chromium/quic_chromium_client_session.cc index f7292b5..0caa4719 100644 --- a/net/quic/chromium/quic_chromium_client_session.cc +++ b/net/quic/chromium/quic_chromium_client_session.cc
@@ -1211,6 +1211,9 @@ base::ResetAndReturn(&callback_).Run(OK); } if (event == HANDSHAKE_CONFIRMED) { + if (stream_factory_) + stream_factory_->set_require_confirmation(false); + // Update |connect_end| only when handshake is confirmed. This should also // take care of any failed 0-RTT request. connect_timing_.connect_end = base::TimeTicks::Now();
diff --git a/net/quic/chromium/quic_stream_factory.cc b/net/quic/chromium/quic_stream_factory.cc index b0bc10e9..b5ac9c0c8 100644 --- a/net/quic/chromium/quic_stream_factory.cc +++ b/net/quic/chromium/quic_stream_factory.cc
@@ -1487,6 +1487,10 @@ if (http_server_properties_->GetSupportsQuic(&last_address) && last_address == local_address_.address()) { require_confirmation_ = false; + // Clear the persisted IP address, in case the network no longer supports + // QUIC so the next restart will require confirmation. It will be + // re-persisted when the first job completes successfully. + http_server_properties_->SetSupportsQuic(false, last_address); } }
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index aed21a2a..06b4389 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -892,9 +892,14 @@ /*cert_verify_flags=*/0, url_, "GET", net_log_, &net_error_details_, callback_.callback())); + IPAddress last_address; + EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address)); + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( QuicSession::HANDSHAKE_CONFIRMED); + EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address)); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); std::unique_ptr<HttpStream> stream = request.CreateStream(); EXPECT_TRUE(stream.get()); @@ -927,11 +932,19 @@ &net_error_details_, callback_.callback()), IsOk()); + IPAddress last_address; + EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address)); + std::unique_ptr<HttpStream> stream = request.CreateStream(); EXPECT_TRUE(stream.get()); QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); EXPECT_FALSE(session->require_confirmation()); + + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + QuicSession::HANDSHAKE_CONFIRMED); + + EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address)); } TEST_P(QuicStreamFactoryTest, CachedInitialRtt) { @@ -1782,11 +1795,14 @@ EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY, net_log_, CompletionCallback())); + IPAddress last_address; + EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address)); // Change the IP address and verify that stream saw the error. NotifyIPAddressChanged(); EXPECT_EQ(ERR_NETWORK_CHANGED, stream->ReadResponseHeaders(callback_.callback())); EXPECT_TRUE(factory_->require_confirmation()); + EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address)); // Now attempting to request a stream to the same origin should create // a new session.
diff --git a/net/spdy/chromium/spdy_session.cc b/net/spdy/chromium/spdy_session.cc index d80326d..a2b3d32 100644 --- a/net/spdy/chromium/spdy_session.cc +++ b/net/spdy/chromium/spdy_session.cc
@@ -2388,10 +2388,14 @@ return nullptr; } + SpdyStream* stream = active_it->second; net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_ADOPTED_PUSH_STREAM, base::Bind(&NetLogSpdyAdoptedPushStreamCallback, - active_it->second->stream_id(), &url)); - return active_it->second; + stream->stream_id(), &url)); + // A stream is in reserved remote state until response headers arrive. + UMA_HISTOGRAM_BOOLEAN("Net.PushedStreamAlreadyHasResponseHeaders", + !stream->IsReservedRemote()); + return stream; } void SpdySession::RecordPingRTTHistogram(base::TimeDelta duration) {
diff --git a/net/test/spawned_test_server/spawned_test_server.h b/net/test/spawned_test_server/spawned_test_server.h index aa4e37a..47232ba 100644 --- a/net/test/spawned_test_server/spawned_test_server.h +++ b/net/test/spawned_test_server/spawned_test_server.h
@@ -7,7 +7,7 @@ #include "build/build_config.h" -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_FUCHSIA) #include "net/test/spawned_test_server/remote_test_server.h" #else #include "net/test/spawned_test_server/local_test_server.h" @@ -15,7 +15,7 @@ namespace net { -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_FUCHSIA) typedef RemoteTestServer SpawnedTestServer; #else typedef LocalTestServer SpawnedTestServer;
diff --git a/printing/backend/print_backend_cups.cc b/printing/backend/print_backend_cups.cc index 66d6590..22737da 100644 --- a/printing/backend/print_backend_cups.cc +++ b/printing/backend/print_backend_cups.cc
@@ -11,7 +11,6 @@ #include <string> -#include "base/debug/leak_annotations.h" #include "base/files/file_util.h" #include "base/lazy_instance.h" #include "base/logging.h" @@ -217,15 +216,8 @@ #endif // !defined(OS_CHROMEOS) int PrintBackendCUPS::GetDests(cups_dest_t** dests) { - if (print_server_url_.is_empty()) { // Use default (local) print server. - // GnuTLS has a genuine small memory leak that is easier to annotate - // than suppress. See http://crbug.com/176888#c7 - // In theory any CUPS function can trigger this leak, but in - // PrintBackendCUPS, this is the most likely spot. - // TODO(eugenis): remove this once the leak is fixed. - ANNOTATE_SCOPED_MEMORY_LEAK; + if (print_server_url_.is_empty()) // Use default (local) print server. return cupsGetDests(dests); - } HttpConnectionCUPS http(print_server_url_, cups_encryption_); http.SetBlocking(blocking_);
diff --git a/remoting/client/gesture_interpreter.cc b/remoting/client/gesture_interpreter.cc index bb20d21..1dcec9f 100644 --- a/remoting/client/gesture_interpreter.cc +++ b/remoting/client/gesture_interpreter.cc
@@ -13,7 +13,7 @@ namespace { -const float kOneFingerFlingTimeConstant = 325.f; +const float kOneFingerFlingTimeConstant = 180.f; const float kScrollFlingTimeConstant = 250.f; } // namespace
diff --git a/remoting/client/ui/fling_tracker.cc b/remoting/client/ui/fling_tracker.cc index 28c59fd5..29fc8363 100644 --- a/remoting/client/ui/fling_tracker.cc +++ b/remoting/client/ui/fling_tracker.cc
@@ -14,15 +14,13 @@ // TODO(yuweih): May need to tweak these numbers to get better smoothness. -// Stop flinging if the speed drops below this. -// 0.5px per 16ms. i.e. 0.5px/frame. -// TODO(yuweih): The screen unit may not be in pixel. This needs to be -// normalized with the DPI. -const float kMinTrackSpeed = 0.03125f; +// Stop flinging if the speed drops below this. This is a small speed to make +// sure the animation stops smoothly. +const float kMinTrackSpeed = 0.01f; // The minimum displacement needed to trigger the fling animation. This is to // prevent unintentional fling with low velocity. -const float kMinDisplacement = 50.f; +const float kMinDisplacement = 20.f; float GetDisplacement(float time_constant, float initial_speed_rate,
diff --git a/services/catalog/entry.cc b/services/catalog/entry.cc index de4a3eb..3b6427a2 100644 --- a/services/catalog/entry.cc +++ b/services/catalog/entry.cc
@@ -158,6 +158,11 @@ } entry->set_display_name(std::move(display_name)); + // Sandbox type, optional. + std::string sandbox_type; + if (value.GetString(Store::kSandboxTypeKey, &sandbox_type)) + entry->set_sandbox_type(std::move(sandbox_type)); + // InterfaceProvider specs. const base::DictionaryValue* interface_provider_specs = nullptr; if (!value.GetDictionary(Store::kInterfaceProviderSpecsKey, @@ -221,8 +226,8 @@ } bool Entry::operator==(const Entry& other) const { - return other.name_ == name_ && - other.display_name_ == display_name_ && + return other.name_ == name_ && other.display_name_ == display_name_ && + other.sandbox_type_ == sandbox_type_ && other.interface_provider_specs_ == interface_provider_specs_; }
diff --git a/services/catalog/entry.h b/services/catalog/entry.h index 8a62ab9..2320f25c 100644 --- a/services/catalog/entry.h +++ b/services/catalog/entry.h
@@ -44,6 +44,11 @@ display_name_ = std::move(display_name); } + const std::string& sandbox_type() const { return sandbox_type_; } + void set_sandbox_type(std::string sandbox_type) { + sandbox_type_ = std::move(sandbox_type); + } + const Entry* parent() const { return parent_; } void set_parent(const Entry* parent) { parent_ = parent; } @@ -71,6 +76,7 @@ std::string name_; base::FilePath path_; std::string display_name_; + std::string sandbox_type_; service_manager::InterfaceProviderSpecMap interface_provider_specs_; std::map<std::string, base::FilePath> required_file_paths_; const Entry* parent_ = nullptr;
diff --git a/services/catalog/entry_unittest.cc b/services/catalog/entry_unittest.cc index e5dba1b..3406c4e 100644 --- a/services/catalog/entry_unittest.cc +++ b/services/catalog/entry_unittest.cc
@@ -58,12 +58,14 @@ std::unique_ptr<Entry> entry = ReadEntry("simple", nullptr); EXPECT_EQ("foo", entry->name()); EXPECT_EQ("Foo", entry->display_name()); + EXPECT_EQ("none", entry->sandbox_type()); } TEST_F(EntryTest, Instance) { std::unique_ptr<Entry> entry = ReadEntry("instance", nullptr); EXPECT_EQ("foo", entry->name()); EXPECT_EQ("Foo", entry->display_name()); + EXPECT_EQ("", entry->sandbox_type()); } TEST_F(EntryTest, ConnectionSpec) {
diff --git a/services/catalog/store.cc b/services/catalog/store.cc index 70d73ac1..f59e6d8 100644 --- a/services/catalog/store.cc +++ b/services/catalog/store.cc
@@ -11,6 +11,8 @@ // static const char Store::kDisplayNameKey[] = "display_name"; // static +const char Store::kSandboxTypeKey[] = "sandbox_type"; +// static const char Store::kInterfaceProviderSpecsKey[] = "interface_provider_specs"; // static const char Store::kInterfaceProviderSpecs_ProvidesKey[] = "provides";
diff --git a/services/catalog/store.h b/services/catalog/store.h index 6bef188..831ee9f 100644 --- a/services/catalog/store.h +++ b/services/catalog/store.h
@@ -15,6 +15,8 @@ static const char kNameKey[]; // Value is a string. static const char kDisplayNameKey[]; + // Value is a string. + static const char kSandboxTypeKey[]; // Value is a dictionary. static const char kInterfaceProviderSpecsKey[]; // Value is a dictionary.
diff --git a/services/catalog/test_data/simple b/services/catalog/test_data/simple index 3fa31be..04cd6fe 100644 --- a/services/catalog/test_data/simple +++ b/services/catalog/test_data/simple
@@ -1,5 +1,6 @@ { "name": "foo", "display_name": "Foo", + "sandbox_type": "none", "interface_provider_specs": { } }
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index 65ae037..d7a4b74 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -204,6 +204,10 @@ # define SK_USE_LEGACY_DISTANCE_FIELDS #endif +#ifndef SK_SUPPORT_LEGACY_LINEAR_GRADIENT +#define SK_SUPPORT_LEGACY_LINEAR_GRADIENT +#endif + #ifndef SK_SUPPORT_LEGACY_STREAM_API #define SK_SUPPORT_LEGACY_STREAM_API #endif
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index b1c86a29..60433e5 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -1036,7 +1036,7 @@ ], "dimension_sets": [ { - "android_devices": "4", + "android_devices": "1", "device_os": "MMB29Q", "device_type": "bullhead" } @@ -1051,7 +1051,8 @@ ], "name": "shard #${SHARD_INDEX} logcats" } - ] + ], + "shards": 6 }, "test": "content_browsertests" }, @@ -6859,7 +6860,7 @@ ], "dimension_sets": [ { - "android_devices": "4", + "android_devices": "1", "device_os": "MMB29Q", "device_type": "bullhead" } @@ -6874,7 +6875,8 @@ ], "name": "shard #${SHARD_INDEX} logcats" } - ] + ], + "shards": 6 }, "test": "content_browsertests" }, @@ -6903,7 +6905,7 @@ ], "dimension_sets": [ { - "android_devices": "4", + "android_devices": "1", "device_os": "MMB29Q", "device_type": "bullhead" } @@ -6918,7 +6920,8 @@ ], "name": "shard #${SHARD_INDEX} logcats" } - ] + ], + "shards": 6 }, "test": "content_browsertests" },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index a7acd2143..b708ca22 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -746,6 +746,16 @@ "test": "base_unittests" }, { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/browser_tests_cros_asan.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "shards": 10 + }, + "test": "browser_tests" + }, + { "swarming": { "can_use_on_swarming_builders": true }, @@ -1000,6 +1010,15 @@ "test": "ui_touch_selection_unittests" }, { + "args": [ + "--test-launcher-filter-file=../../testing/buildbot/filters/unit_tests_cros_asan.filter" + ], + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "unit_tests" + }, + { "swarming": { "can_use_on_swarming_builders": true },
diff --git a/testing/buildbot/filters/browser_tests_cros_asan.filter b/testing/buildbot/filters/browser_tests_cros_asan.filter new file mode 100644 index 0000000..94c0b93 --- /dev/null +++ b/testing/buildbot/filters/browser_tests_cros_asan.filter
@@ -0,0 +1,2 @@ +# TODO(crbug.com/759291): Test is flakey with ASan. +-SamlTest.ScrapedMultiple
diff --git a/testing/buildbot/filters/fuchsia.content_unittests.filter b/testing/buildbot/filters/fuchsia.content_unittests.filter index 064debb..19d3b20 100644 --- a/testing/buildbot/filters/fuchsia.content_unittests.filter +++ b/testing/buildbot/filters/fuchsia.content_unittests.filter
@@ -1,6 +1,5 @@ # Being ported, https://crbug.com/754861. --AudioRendererMixerManagerTest.MixerParamsLatencyRtc -AudioRendererSinkCacheTest.SmokeTest -BaseFileTest.ReadonlyBaseFile -BaseFileTest.RenameWithError
diff --git a/testing/buildbot/filters/fuchsia.net_unittests.filter b/testing/buildbot/filters/fuchsia.net_unittests.filter index 619c9dc..cf21bd1d 100644 --- a/testing/buildbot/filters/fuchsia.net_unittests.filter +++ b/testing/buildbot/filters/fuchsia.net_unittests.filter
@@ -15,6 +15,7 @@ -EmbeddedTestServer* -HostResolverImplDnsTest.DnsTask -HttpCache.RangeGET_ParallelValidationDifferentRanges # https://crbug.com/755552 +-HttpCache.RangeGET_ParallelValidationOverlappingRanges # https://crbug.com/758221 -HttpNetworkTransactionTest.UploadUnreadableFile -HttpServerTest.* -NetworkInterfacesTest.GetNetworkList
diff --git a/testing/buildbot/filters/mus.browser_tests.filter b/testing/buildbot/filters/mus.browser_tests.filter index 1137157..853337c4 100644 --- a/testing/buildbot/filters/mus.browser_tests.filter +++ b/testing/buildbot/filters/mus.browser_tests.filter
@@ -56,3 +56,6 @@ -WebViewTests/WebViewSizeTest.Shim_TestResizeWebviewWithDisplayNoneResizesContent/0 -WebViewTests/WebViewSizeTest.Shim_TestResizeWebviewWithDisplayNoneResizesContent/1 -WebViewTests/WebViewTest.InterstitialPageFocusedWidget/1 + +# TODO: fix, http://crbug.com/759721 +-VirtualKeyboardBrowserTest.HideKeyboardKeyTest
diff --git a/testing/buildbot/filters/unit_tests_cros_asan.filter b/testing/buildbot/filters/unit_tests_cros_asan.filter new file mode 100644 index 0000000..a0bb500 --- /dev/null +++ b/testing/buildbot/filters/unit_tests_cros_asan.filter
@@ -0,0 +1,2 @@ +# TODO(crbug.com/756844): Fix memory leaks. +-SafeBrowsingBlockingQuietPageTests.*
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/preload-conditions.html b/third_party/WebKit/LayoutTests/http/tests/media/preload-conditions.html index 1a67d6e..f958b2e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/media/preload-conditions.html +++ b/third_party/WebKit/LayoutTests/http/tests/media/preload-conditions.html
@@ -120,7 +120,7 @@ assert_false(media.hasAttribute('preload')); // Test allowed values. - [ '', 'none', 'metadata', 'auto' ].forEach(t.step_func(preload => { + [ 'none', 'metadata', 'auto' ].forEach(t.step_func(preload => { var expected = test.expectations.allowed.includes(preload) ? preload : test.expectations.default; checkPreloadAttribute(media, preload, expected); }));
diff --git a/third_party/WebKit/Source/core/editing/BUILD.gn b/third_party/WebKit/Source/core/editing/BUILD.gn index ece2de7..f14c3796 100644 --- a/third_party/WebKit/Source/core/editing/BUILD.gn +++ b/third_party/WebKit/Source/core/editing/BUILD.gn
@@ -220,12 +220,12 @@ "markers/DocumentMarkerController.h", "markers/DocumentMarkerList.cpp", "markers/DocumentMarkerList.h", - "markers/DocumentMarkerListEditor.cpp", - "markers/DocumentMarkerListEditor.h", "markers/GrammarMarker.cpp", "markers/GrammarMarker.h", "markers/GrammarMarkerListImpl.cpp", "markers/GrammarMarkerListImpl.h", + "markers/SortedDocumentMarkerListEditor.cpp", + "markers/SortedDocumentMarkerListEditor.h", "markers/SpellCheckMarker.cpp", "markers/SpellCheckMarker.h", "markers/SpellCheckMarkerListImpl.cpp", @@ -358,10 +358,10 @@ "markers/CompositionMarkerListImplTest.cpp", "markers/CompositionMarkerTest.cpp", "markers/DocumentMarkerControllerTest.cpp", - "markers/DocumentMarkerListEditorTest.cpp", "markers/DocumentMarkerTest.cpp", "markers/GrammarMarkerListImplTest.cpp", "markers/GrammarMarkerTest.cpp", + "markers/SortedDocumentMarkerListEditorTest.cpp", "markers/SpellingMarkerListImplTest.cpp", "markers/SpellingMarkerTest.cpp", "markers/SuggestionMarkerListImplTest.cpp",
diff --git a/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp index be35da3..a053005 100644 --- a/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/ActiveSuggestionMarkerListImpl.cpp
@@ -4,7 +4,7 @@ #include "core/editing/markers/ActiveSuggestionMarkerListImpl.h" -#include "core/editing/markers/DocumentMarkerListEditor.h" +#include "core/editing/markers/SortedDocumentMarkerListEditor.h" namespace blink { @@ -17,8 +17,8 @@ } void ActiveSuggestionMarkerListImpl::Add(DocumentMarker* marker) { - DocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, - marker); + SortedDocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, + marker); } void ActiveSuggestionMarkerListImpl::Clear() { @@ -33,7 +33,7 @@ DocumentMarker* ActiveSuggestionMarkerListImpl::FirstMarkerIntersectingRange( unsigned start_offset, unsigned end_offset) const { - return DocumentMarkerListEditor::FirstMarkerIntersectingRange( + return SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange( markers_, start_offset, end_offset); } @@ -41,27 +41,28 @@ ActiveSuggestionMarkerListImpl::MarkersIntersectingRange( unsigned start_offset, unsigned end_offset) const { - return DocumentMarkerListEditor::MarkersIntersectingRange( + return SortedDocumentMarkerListEditor::MarkersIntersectingRange( markers_, start_offset, end_offset); } bool ActiveSuggestionMarkerListImpl::MoveMarkers( int length, DocumentMarkerList* dst_markers_) { - return DocumentMarkerListEditor::MoveMarkers(&markers_, length, dst_markers_); + return SortedDocumentMarkerListEditor::MoveMarkers(&markers_, length, + dst_markers_); } bool ActiveSuggestionMarkerListImpl::RemoveMarkers(unsigned start_offset, int length) { - return DocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, - length); + return SortedDocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, + length); } bool ActiveSuggestionMarkerListImpl::ShiftMarkers(const String&, unsigned offset, unsigned old_length, unsigned new_length) { - return DocumentMarkerListEditor::ShiftMarkersContentIndependent( + return SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent( &markers_, offset, old_length, new_length); }
diff --git a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp index b709959..abcee75 100644 --- a/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/CompositionMarkerListImpl.cpp
@@ -4,7 +4,7 @@ #include "core/editing/markers/CompositionMarkerListImpl.h" -#include "core/editing/markers/DocumentMarkerListEditor.h" +#include "core/editing/markers/SortedDocumentMarkerListEditor.h" namespace blink { @@ -17,8 +17,8 @@ } void CompositionMarkerListImpl::Add(DocumentMarker* marker) { - DocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, - marker); + SortedDocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, + marker); } void CompositionMarkerListImpl::Clear() { @@ -33,33 +33,34 @@ DocumentMarker* CompositionMarkerListImpl::FirstMarkerIntersectingRange( unsigned start_offset, unsigned end_offset) const { - return DocumentMarkerListEditor::FirstMarkerIntersectingRange( + return SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange( markers_, start_offset, end_offset); } HeapVector<Member<DocumentMarker>> CompositionMarkerListImpl::MarkersIntersectingRange(unsigned start_offset, unsigned end_offset) const { - return DocumentMarkerListEditor::MarkersIntersectingRange( + return SortedDocumentMarkerListEditor::MarkersIntersectingRange( markers_, start_offset, end_offset); } bool CompositionMarkerListImpl::MoveMarkers(int length, DocumentMarkerList* dst_markers_) { - return DocumentMarkerListEditor::MoveMarkers(&markers_, length, dst_markers_); + return SortedDocumentMarkerListEditor::MoveMarkers(&markers_, length, + dst_markers_); } bool CompositionMarkerListImpl::RemoveMarkers(unsigned start_offset, int length) { - return DocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, - length); + return SortedDocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, + length); } bool CompositionMarkerListImpl::ShiftMarkers(const String&, unsigned offset, unsigned old_length, unsigned new_length) { - return DocumentMarkerListEditor::ShiftMarkersContentIndependent( + return SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent( &markers_, offset, old_length, new_length); }
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp index d940bbb..83ac6f1 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp +++ b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerController.cpp
@@ -38,9 +38,9 @@ #include "core/editing/markers/ActiveSuggestionMarkerListImpl.h" #include "core/editing/markers/CompositionMarker.h" #include "core/editing/markers/CompositionMarkerListImpl.h" -#include "core/editing/markers/DocumentMarkerListEditor.h" #include "core/editing/markers/GrammarMarker.h" #include "core/editing/markers/GrammarMarkerListImpl.h" +#include "core/editing/markers/SortedDocumentMarkerListEditor.h" #include "core/editing/markers/SpellingMarker.h" #include "core/editing/markers/SpellingMarkerListImpl.h" #include "core/editing/markers/SuggestionMarker.h"
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditorTest.cpp b/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditorTest.cpp deleted file mode 100644 index 0dcb40b..0000000 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditorTest.cpp +++ /dev/null
@@ -1,561 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/editing/markers/DocumentMarkerListEditor.h" - -#include "core/editing/markers/TextMatchMarker.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace blink { - -class DocumentMarkerListEditorTest : public ::testing::Test { - protected: - DocumentMarker* CreateMarker(unsigned startOffset, unsigned endOffset) { - return new TextMatchMarker(startOffset, endOffset, - TextMatchMarker::MatchStatus::kInactive); - } -}; - -TEST_F(DocumentMarkerListEditorTest, RemoveMarkersEmptyList) { - DocumentMarkerListEditor::MarkerList markers; - DocumentMarkerListEditor::RemoveMarkers(&markers, 0, 10); - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, RemoveMarkersTouchingEndpoints) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - markers.push_back(CreateMarker(10, 20)); - markers.push_back(CreateMarker(20, 30)); - - DocumentMarkerListEditor::RemoveMarkers(&markers, 10, 10); - - EXPECT_EQ(2u, markers.size()); - - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(10u, markers[0]->EndOffset()); - - EXPECT_EQ(20u, markers[1]->StartOffset()); - EXPECT_EQ(30u, markers[1]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, RemoveMarkersOneCharacterIntoInterior) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - markers.push_back(CreateMarker(10, 20)); - markers.push_back(CreateMarker(20, 30)); - - DocumentMarkerListEditor::RemoveMarkers(&markers, 9, 12); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_ReplaceStartOfMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 5, 5); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_ReplaceStartOfMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - // Replace with shorter text - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 5, 4); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(9u, markers[0]->EndOffset()); - - // Replace with longer text - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 4, 5); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(10u, markers[0]->EndOffset()); - - // Replace with text of same length - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 5, 5); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(10u, markers[0]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_ReplaceContainsStartOfMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 15)); - - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 10, 10); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_ReplaceContainsStartOfMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 15)); - - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 10, 10); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(10u, markers[0]->StartOffset()); - EXPECT_EQ(15u, markers[0]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_ReplaceEndOfMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 5, 5, 5); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_ReplaceEndOfMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - // Replace with shorter text - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 5, 4); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(9u, markers[0]->EndOffset()); - - // Replace with longer text - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 4, 5); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(10u, markers[0]->EndOffset()); - - // Replace with text of same length - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 5, 5); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(10u, markers[0]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_ReplaceContainsEndOfMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 5, 10, 10); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_ReplaceContainsEndOfMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 10, 10); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(5u, markers[0]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_ReplaceEntireMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 10, 10); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_ReplaceEntireMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - // Replace with shorter text - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 10, 9); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(9u, markers[0]->EndOffset()); - - // Replace with longer text - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 9, 10); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(10u, markers[0]->EndOffset()); - - // Replace with text of same length - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 10, 10); - - EXPECT_EQ(1u, markers.size()); - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(10u, markers[0]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_ReplaceTextWithMarkerAtBeginning) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 15, 15); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_ReplaceTextWithMarkerAtBeginning) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 15, 15); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_ReplaceTextWithMarkerAtEnd) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 15)); - - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 15, 15); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_ReplaceTextWithMarkerAtEnd) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 15)); - - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 15, 15); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, ContentDependentMarker_Deletions) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - markers.push_back(CreateMarker(5, 10)); - markers.push_back(CreateMarker(10, 15)); - markers.push_back(CreateMarker(15, 20)); - markers.push_back(CreateMarker(20, 25)); - - // Delete range containing the end of the second marker, the entire third - // marker, and the start of the fourth marker - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 8, 9, 0); - - EXPECT_EQ(2u, markers.size()); - - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(5u, markers[0]->EndOffset()); - - EXPECT_EQ(11u, markers[1]->StartOffset()); - EXPECT_EQ(16u, markers[1]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, ContentIndependentMarker_Deletions) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - markers.push_back(CreateMarker(5, 10)); - markers.push_back(CreateMarker(10, 15)); - markers.push_back(CreateMarker(15, 20)); - markers.push_back(CreateMarker(20, 25)); - - // Delete range containing the end of the second marker, the entire third - // marker, and the start of the fourth marker - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 8, 9, 0); - - EXPECT_EQ(4u, markers.size()); - - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(5u, markers[0]->EndOffset()); - - EXPECT_EQ(5u, markers[1]->StartOffset()); - EXPECT_EQ(8u, markers[1]->EndOffset()); - - EXPECT_EQ(8u, markers[2]->StartOffset()); - EXPECT_EQ(11u, markers[2]->EndOffset()); - - EXPECT_EQ(11u, markers[3]->StartOffset()); - EXPECT_EQ(16u, markers[3]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_DeleteExactlyOnMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 10, 0); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_DeleteExactlyOnMarker) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 10)); - - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 10, 0); - - EXPECT_EQ(0u, markers.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_InsertInMarkerInterior) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - markers.push_back(CreateMarker(5, 10)); - markers.push_back(CreateMarker(10, 15)); - - // insert in middle of second marker - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 7, 0, 5); - - EXPECT_EQ(2u, markers.size()); - - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(5u, markers[0]->EndOffset()); - - EXPECT_EQ(15u, markers[1]->StartOffset()); - EXPECT_EQ(20u, markers[1]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_InsertInMarkerInterior) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - markers.push_back(CreateMarker(5, 10)); - markers.push_back(CreateMarker(10, 15)); - - // insert in middle of second marker - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 7, 0, 5); - - EXPECT_EQ(3u, markers.size()); - - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(5u, markers[0]->EndOffset()); - - EXPECT_EQ(5u, markers[1]->StartOffset()); - EXPECT_EQ(15u, markers[1]->EndOffset()); - - EXPECT_EQ(15u, markers[2]->StartOffset()); - EXPECT_EQ(20u, markers[2]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentDependentMarker_InsertBetweenMarkers) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - markers.push_back(CreateMarker(5, 10)); - markers.push_back(CreateMarker(10, 15)); - - // insert before second marker - DocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 5, 0, 5); - - EXPECT_EQ(3u, markers.size()); - - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(5u, markers[0]->EndOffset()); - - EXPECT_EQ(10u, markers[1]->StartOffset()); - EXPECT_EQ(15u, markers[1]->EndOffset()); - - EXPECT_EQ(15u, markers[2]->StartOffset()); - EXPECT_EQ(20u, markers[2]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - ContentIndependentMarker_InsertBetweenMarkers) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - markers.push_back(CreateMarker(5, 10)); - markers.push_back(CreateMarker(10, 15)); - - // insert before second marker - DocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 0, 5); - - EXPECT_EQ(3u, markers.size()); - - EXPECT_EQ(0u, markers[0]->StartOffset()); - EXPECT_EQ(5u, markers[0]->EndOffset()); - - EXPECT_EQ(10u, markers[1]->StartOffset()); - EXPECT_EQ(15u, markers[1]->EndOffset()); - - EXPECT_EQ(15u, markers[2]->StartOffset()); - EXPECT_EQ(20u, markers[2]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, FirstMarkerIntersectingRange_Empty) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - - DocumentMarker* marker = - DocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 10, 15); - EXPECT_EQ(nullptr, marker); -} - -TEST_F(DocumentMarkerListEditorTest, - FirstMarkerIntersectingRange_TouchingAfter) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - - DocumentMarker* marker = - DocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 5, 10); - EXPECT_EQ(nullptr, marker); -} - -TEST_F(DocumentMarkerListEditorTest, - FirstMarkerIntersectingRange_TouchingBefore) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 10)); - - DocumentMarker* marker = - DocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 0, 5); - EXPECT_EQ(nullptr, marker); -} - -TEST_F(DocumentMarkerListEditorTest, - FirstMarkerIntersectingRange_IntersectingAfter) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 10)); - - DocumentMarker* marker = - DocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 0, 6); - EXPECT_NE(nullptr, marker); - - EXPECT_EQ(5u, marker->StartOffset()); - EXPECT_EQ(10u, marker->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - FirstMarkerIntersectingRange_IntersectingBefore) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 10)); - - DocumentMarker* marker = - DocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 9, 15); - EXPECT_NE(nullptr, marker); - - EXPECT_EQ(5u, marker->StartOffset()); - EXPECT_EQ(10u, marker->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - FirstMarkerIntersectingRange_MultipleMarkers) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - markers.push_back(CreateMarker(5, 10)); - markers.push_back(CreateMarker(10, 15)); - markers.push_back(CreateMarker(15, 20)); - markers.push_back(CreateMarker(20, 25)); - - DocumentMarker* marker = - DocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 7, 17); - EXPECT_NE(nullptr, marker); - - EXPECT_EQ(5u, marker->StartOffset()); - EXPECT_EQ(10u, marker->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_Empty) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - - DocumentMarkerListEditor::MarkerList markers_intersecting_range = - DocumentMarkerListEditor::MarkersIntersectingRange(markers, 10, 15); - EXPECT_EQ(0u, markers_intersecting_range.size()); -} - -TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_TouchingAfter) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - - DocumentMarkerListEditor::MarkerList markers_intersecting_range = - DocumentMarkerListEditor::MarkersIntersectingRange(markers, 5, 10); - EXPECT_EQ(0u, markers_intersecting_range.size()); -} - -TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_TouchingBefore) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 10)); - - DocumentMarkerListEditor::MarkerList markers_intersecting_range = - DocumentMarkerListEditor::MarkersIntersectingRange(markers, 0, 5); - EXPECT_EQ(0u, markers_intersecting_range.size()); -} - -TEST_F(DocumentMarkerListEditorTest, - MarkersIntersectingRange_IntersectingAfter) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 10)); - - DocumentMarkerListEditor::MarkerList markers_intersecting_range = - DocumentMarkerListEditor::MarkersIntersectingRange(markers, 0, 6); - EXPECT_EQ(1u, markers_intersecting_range.size()); - - EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); - EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, - MarkersIntersectingRange_IntersectingBefore) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 10)); - - DocumentMarkerListEditor::MarkerList markers_intersecting_range = - DocumentMarkerListEditor::MarkersIntersectingRange(markers, 9, 15); - EXPECT_EQ(1u, markers_intersecting_range.size()); - - EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); - EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_CollapsedRange) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(5, 10)); - - DocumentMarkerListEditor::MarkerList markers_intersecting_range = - DocumentMarkerListEditor::MarkersIntersectingRange(markers, 7, 7); - EXPECT_EQ(1u, markers_intersecting_range.size()); - - EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); - EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); -} - -TEST_F(DocumentMarkerListEditorTest, MarkersIntersectingRange_MultipleMarkers) { - DocumentMarkerListEditor::MarkerList markers; - markers.push_back(CreateMarker(0, 5)); - markers.push_back(CreateMarker(5, 10)); - markers.push_back(CreateMarker(10, 15)); - markers.push_back(CreateMarker(15, 20)); - markers.push_back(CreateMarker(20, 25)); - - DocumentMarkerListEditor::MarkerList markers_intersecting_range = - DocumentMarkerListEditor::MarkersIntersectingRange(markers, 7, 17); - EXPECT_EQ(3u, markers_intersecting_range.size()); - - EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); - EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); - - EXPECT_EQ(10u, markers_intersecting_range[1]->StartOffset()); - EXPECT_EQ(15u, markers_intersecting_range[1]->EndOffset()); - - EXPECT_EQ(15u, markers_intersecting_range[2]->StartOffset()); - EXPECT_EQ(20u, markers_intersecting_range[2]->EndOffset()); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.cpp b/third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditor.cpp similarity index 87% rename from third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.cpp rename to third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditor.cpp index a65f41c..b98934b 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.cpp +++ b/third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditor.cpp
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "core/editing/markers/DocumentMarkerListEditor.h" +#include "core/editing/markers/SortedDocumentMarkerListEditor.h" #include "core/editing/markers/SpellCheckMarkerListImpl.h" namespace blink { -void DocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping( +void SortedDocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping( MarkerList* list, DocumentMarker* marker) { if (list->IsEmpty() || list->back()->EndOffset() <= marker->StartOffset()) { @@ -34,9 +34,9 @@ list->insert(pos - list->begin(), marker); } -bool DocumentMarkerListEditor::MoveMarkers(MarkerList* src_list, - int length, - DocumentMarkerList* dst_list) { +bool SortedDocumentMarkerListEditor::MoveMarkers(MarkerList* src_list, + int length, + DocumentMarkerList* dst_list) { DCHECK_GT(length, 0); bool didMoveMarker = false; unsigned end_offset = length - 1; @@ -61,9 +61,9 @@ return didMoveMarker; } -bool DocumentMarkerListEditor::RemoveMarkers(MarkerList* list, - unsigned start_offset, - int length) { +bool SortedDocumentMarkerListEditor::RemoveMarkers(MarkerList* list, + unsigned start_offset, + int length) { const unsigned end_offset = start_offset + length; MarkerList::iterator start_pos = std::upper_bound( list->begin(), list->end(), start_offset, @@ -81,7 +81,7 @@ return start_pos != end_pos; } -bool DocumentMarkerListEditor::ShiftMarkersContentDependent( +bool SortedDocumentMarkerListEditor::ShiftMarkersContentDependent( MarkerList* list, unsigned offset, unsigned old_length, @@ -122,7 +122,7 @@ return did_shift_marker; } -bool DocumentMarkerListEditor::ShiftMarkersContentIndependent( +bool SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent( MarkerList* list, unsigned offset, unsigned old_length, @@ -166,7 +166,7 @@ return did_shift_marker; } -DocumentMarker* DocumentMarkerListEditor::FirstMarkerIntersectingRange( +DocumentMarker* SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange( const MarkerList& list, unsigned start_offset, unsigned end_offset) { @@ -187,9 +187,9 @@ } HeapVector<Member<DocumentMarker>> -DocumentMarkerListEditor::MarkersIntersectingRange(const MarkerList& list, - unsigned start_offset, - unsigned end_offset) { +SortedDocumentMarkerListEditor::MarkersIntersectingRange(const MarkerList& list, + unsigned start_offset, + unsigned end_offset) { DCHECK_LE(start_offset, end_offset); const auto& start_it =
diff --git a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.h b/third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditor.h similarity index 93% rename from third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.h rename to third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditor.h index f6aaf30..a224f05 100644 --- a/third_party/WebKit/Source/core/editing/markers/DocumentMarkerListEditor.h +++ b/third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditor.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef DocumentMarkerListEditor_h -#define DocumentMarkerListEditor_h +#ifndef SortedDocumentMarkerListEditor_h +#define SortedDocumentMarkerListEditor_h #include "core/editing/markers/DocumentMarkerList.h" #include "platform/heap/Handle.h" @@ -12,7 +12,7 @@ class DocumentMarker; -class CORE_EXPORT DocumentMarkerListEditor final { +class CORE_EXPORT SortedDocumentMarkerListEditor final { public: using MarkerList = HeapVector<Member<DocumentMarker>>; @@ -61,4 +61,4 @@ } // namespace blink -#endif // DocumentMarkerListEditor_h +#endif // SortedDocumentMarkerListEditor_h
diff --git a/third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditorTest.cpp b/third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditorTest.cpp new file mode 100644 index 0000000..ba952032 --- /dev/null +++ b/third_party/WebKit/Source/core/editing/markers/SortedDocumentMarkerListEditorTest.cpp
@@ -0,0 +1,600 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/editing/markers/SortedDocumentMarkerListEditor.h" + +#include "core/editing/markers/TextMatchMarker.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +class SortedDocumentMarkerListEditorTest : public ::testing::Test { + protected: + DocumentMarker* CreateMarker(unsigned startOffset, unsigned endOffset) { + return new TextMatchMarker(startOffset, endOffset, + TextMatchMarker::MatchStatus::kInactive); + } +}; + +TEST_F(SortedDocumentMarkerListEditorTest, RemoveMarkersEmptyList) { + SortedDocumentMarkerListEditor::MarkerList markers; + SortedDocumentMarkerListEditor::RemoveMarkers(&markers, 0, 10); + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, RemoveMarkersTouchingEndpoints) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + markers.push_back(CreateMarker(10, 20)); + markers.push_back(CreateMarker(20, 30)); + + SortedDocumentMarkerListEditor::RemoveMarkers(&markers, 10, 10); + + EXPECT_EQ(2u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); + + EXPECT_EQ(20u, markers[1]->StartOffset()); + EXPECT_EQ(30u, markers[1]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + RemoveMarkersOneCharacterIntoInterior) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + markers.push_back(CreateMarker(10, 20)); + markers.push_back(CreateMarker(20, 30)); + + SortedDocumentMarkerListEditor::RemoveMarkers(&markers, 9, 12); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_ReplaceStartOfMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 5, + 5); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceStartOfMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + // Replace with shorter text + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 5, + 4); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(9u, markers[0]->EndOffset()); + + // Replace with longer text + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 4, + 5); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); + + // Replace with text of same length + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 5, + 5); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_ReplaceContainsStartOfMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 15)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 10, + 10); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceContainsStartOfMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 15)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 10, 10); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(10u, markers[0]->StartOffset()); + EXPECT_EQ(15u, markers[0]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_ReplaceEndOfMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 5, 5, + 5); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceEndOfMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + // Replace with shorter text + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 5, + 4); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(9u, markers[0]->EndOffset()); + + // Replace with longer text + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 4, + 5); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); + + // Replace with text of same length + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 5, + 5); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_ReplaceContainsEndOfMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 5, 10, + 10); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceContainsEndOfMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, + 10, 10); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_ReplaceEntireMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 10, + 10); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceEntireMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + // Replace with shorter text + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 10, 9); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(9u, markers[0]->EndOffset()); + + // Replace with longer text + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, 9, + 10); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); + + // Replace with text of same length + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 10, 10); + + EXPECT_EQ(1u, markers.size()); + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(10u, markers[0]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_ReplaceTextWithMarkerAtBeginning) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 15, + 15); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceTextWithMarkerAtBeginning) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 15, 15); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_ReplaceTextWithMarkerAtEnd) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 15)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 15, + 15); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_ReplaceTextWithMarkerAtEnd) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 15)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 15, 15); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, ContentDependentMarker_Deletions) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + markers.push_back(CreateMarker(15, 20)); + markers.push_back(CreateMarker(20, 25)); + + // Delete range containing the end of the second marker, the entire third + // marker, and the start of the fourth marker + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 8, 9, + 0); + + EXPECT_EQ(2u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(11u, markers[1]->StartOffset()); + EXPECT_EQ(16u, markers[1]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, ContentIndependentMarker_Deletions) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + markers.push_back(CreateMarker(15, 20)); + markers.push_back(CreateMarker(20, 25)); + + // Delete range containing the end of the second marker, the entire third + // marker, and the start of the fourth marker + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 8, 9, + 0); + + EXPECT_EQ(4u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(5u, markers[1]->StartOffset()); + EXPECT_EQ(8u, markers[1]->EndOffset()); + + EXPECT_EQ(8u, markers[2]->StartOffset()); + EXPECT_EQ(11u, markers[2]->EndOffset()); + + EXPECT_EQ(11u, markers[3]->StartOffset()); + EXPECT_EQ(16u, markers[3]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_DeleteExactlyOnMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 0, 10, + 0); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_DeleteExactlyOnMarker) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 10)); + + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0, + 10, 0); + + EXPECT_EQ(0u, markers.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_InsertInMarkerInterior) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + + // insert in middle of second marker + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 7, 0, + 5); + + EXPECT_EQ(2u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(15u, markers[1]->StartOffset()); + EXPECT_EQ(20u, markers[1]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_InsertInMarkerInterior) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + + // insert in middle of second marker + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 7, 0, + 5); + + EXPECT_EQ(3u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(5u, markers[1]->StartOffset()); + EXPECT_EQ(15u, markers[1]->EndOffset()); + + EXPECT_EQ(15u, markers[2]->StartOffset()); + EXPECT_EQ(20u, markers[2]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentDependentMarker_InsertBetweenMarkers) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + + // insert before second marker + SortedDocumentMarkerListEditor::ShiftMarkersContentDependent(&markers, 5, 0, + 5); + + EXPECT_EQ(3u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(10u, markers[1]->StartOffset()); + EXPECT_EQ(15u, markers[1]->EndOffset()); + + EXPECT_EQ(15u, markers[2]->StartOffset()); + EXPECT_EQ(20u, markers[2]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + ContentIndependentMarker_InsertBetweenMarkers) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + + // insert before second marker + SortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5, 0, + 5); + + EXPECT_EQ(3u, markers.size()); + + EXPECT_EQ(0u, markers[0]->StartOffset()); + EXPECT_EQ(5u, markers[0]->EndOffset()); + + EXPECT_EQ(10u, markers[1]->StartOffset()); + EXPECT_EQ(15u, markers[1]->EndOffset()); + + EXPECT_EQ(15u, markers[2]->StartOffset()); + EXPECT_EQ(20u, markers[2]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, FirstMarkerIntersectingRange_Empty) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + + DocumentMarker* marker = + SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 10, + 15); + EXPECT_EQ(nullptr, marker); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + FirstMarkerIntersectingRange_TouchingAfter) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + + DocumentMarker* marker = + SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 5, + 10); + EXPECT_EQ(nullptr, marker); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + FirstMarkerIntersectingRange_TouchingBefore) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + DocumentMarker* marker = + SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 0, + 5); + EXPECT_EQ(nullptr, marker); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + FirstMarkerIntersectingRange_IntersectingAfter) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + DocumentMarker* marker = + SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 0, + 6); + EXPECT_NE(nullptr, marker); + + EXPECT_EQ(5u, marker->StartOffset()); + EXPECT_EQ(10u, marker->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + FirstMarkerIntersectingRange_IntersectingBefore) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + DocumentMarker* marker = + SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 9, + 15); + EXPECT_NE(nullptr, marker); + + EXPECT_EQ(5u, marker->StartOffset()); + EXPECT_EQ(10u, marker->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + FirstMarkerIntersectingRange_MultipleMarkers) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + markers.push_back(CreateMarker(15, 20)); + markers.push_back(CreateMarker(20, 25)); + + DocumentMarker* marker = + SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 7, + 17); + EXPECT_NE(nullptr, marker); + + EXPECT_EQ(5u, marker->StartOffset()); + EXPECT_EQ(10u, marker->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, MarkersIntersectingRange_Empty) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + + SortedDocumentMarkerListEditor::MarkerList markers_intersecting_range = + SortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 10, 15); + EXPECT_EQ(0u, markers_intersecting_range.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + MarkersIntersectingRange_TouchingAfter) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + + SortedDocumentMarkerListEditor::MarkerList markers_intersecting_range = + SortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 5, 10); + EXPECT_EQ(0u, markers_intersecting_range.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + MarkersIntersectingRange_TouchingBefore) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + SortedDocumentMarkerListEditor::MarkerList markers_intersecting_range = + SortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 0, 5); + EXPECT_EQ(0u, markers_intersecting_range.size()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + MarkersIntersectingRange_IntersectingAfter) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + SortedDocumentMarkerListEditor::MarkerList markers_intersecting_range = + SortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 0, 6); + EXPECT_EQ(1u, markers_intersecting_range.size()); + + EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); + EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + MarkersIntersectingRange_IntersectingBefore) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + SortedDocumentMarkerListEditor::MarkerList markers_intersecting_range = + SortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 9, 15); + EXPECT_EQ(1u, markers_intersecting_range.size()); + + EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); + EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + MarkersIntersectingRange_CollapsedRange) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(5, 10)); + + SortedDocumentMarkerListEditor::MarkerList markers_intersecting_range = + SortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 7, 7); + EXPECT_EQ(1u, markers_intersecting_range.size()); + + EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); + EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); +} + +TEST_F(SortedDocumentMarkerListEditorTest, + MarkersIntersectingRange_MultipleMarkers) { + SortedDocumentMarkerListEditor::MarkerList markers; + markers.push_back(CreateMarker(0, 5)); + markers.push_back(CreateMarker(5, 10)); + markers.push_back(CreateMarker(10, 15)); + markers.push_back(CreateMarker(15, 20)); + markers.push_back(CreateMarker(20, 25)); + + SortedDocumentMarkerListEditor::MarkerList markers_intersecting_range = + SortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 7, 17); + EXPECT_EQ(3u, markers_intersecting_range.size()); + + EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset()); + EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset()); + + EXPECT_EQ(10u, markers_intersecting_range[1]->StartOffset()); + EXPECT_EQ(15u, markers_intersecting_range[1]->EndOffset()); + + EXPECT_EQ(15u, markers_intersecting_range[2]->StartOffset()); + EXPECT_EQ(20u, markers_intersecting_range[2]->EndOffset()); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp index df924c1..5a1ec40 100644 --- a/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/SpellCheckMarkerListImpl.cpp
@@ -4,7 +4,7 @@ #include "core/editing/markers/SpellCheckMarkerListImpl.h" -#include "core/editing/markers/DocumentMarkerListEditor.h" +#include "core/editing/markers/SortedDocumentMarkerListEditor.h" namespace blink { @@ -69,33 +69,34 @@ DocumentMarker* SpellCheckMarkerListImpl::FirstMarkerIntersectingRange( unsigned start_offset, unsigned end_offset) const { - return DocumentMarkerListEditor::FirstMarkerIntersectingRange( + return SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange( markers_, start_offset, end_offset); } HeapVector<Member<DocumentMarker>> SpellCheckMarkerListImpl::MarkersIntersectingRange(unsigned start_offset, unsigned end_offset) const { - return DocumentMarkerListEditor::MarkersIntersectingRange( + return SortedDocumentMarkerListEditor::MarkersIntersectingRange( markers_, start_offset, end_offset); } bool SpellCheckMarkerListImpl::MoveMarkers(int length, DocumentMarkerList* dst_list) { - return DocumentMarkerListEditor::MoveMarkers(&markers_, length, dst_list); + return SortedDocumentMarkerListEditor::MoveMarkers(&markers_, length, + dst_list); } bool SpellCheckMarkerListImpl::RemoveMarkers(unsigned start_offset, int length) { - return DocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, - length); + return SortedDocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, + length); } bool SpellCheckMarkerListImpl::ShiftMarkers(const String&, unsigned offset, unsigned old_length, unsigned new_length) { - return DocumentMarkerListEditor::ShiftMarkersContentDependent( + return SortedDocumentMarkerListEditor::ShiftMarkersContentDependent( &markers_, offset, old_length, new_length); }
diff --git a/third_party/WebKit/Source/core/editing/markers/SuggestionMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/SuggestionMarkerListImpl.cpp index ae31e37..419bda24 100644 --- a/third_party/WebKit/Source/core/editing/markers/SuggestionMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/SuggestionMarkerListImpl.cpp
@@ -4,7 +4,7 @@ #include "core/editing/markers/SuggestionMarkerListImpl.h" -#include "core/editing/markers/DocumentMarkerListEditor.h" +#include "core/editing/markers/SortedDocumentMarkerListEditor.h" #include "core/editing/markers/SuggestionMarker.h" #include "core/editing/markers/SuggestionMarkerReplacementScope.h"
diff --git a/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp b/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp index 1db3b60a..ddc337dc 100644 --- a/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp +++ b/third_party/WebKit/Source/core/editing/markers/TextMatchMarkerListImpl.cpp
@@ -7,7 +7,7 @@ #include "core/dom/Node.h" #include "core/dom/Range.h" #include "core/editing/EphemeralRange.h" -#include "core/editing/markers/DocumentMarkerListEditor.h" +#include "core/editing/markers/SortedDocumentMarkerListEditor.h" #include "core/editing/markers/TextMatchMarker.h" #include "third_party/WebKit/Source/core/editing/VisibleUnits.h" @@ -22,8 +22,8 @@ } void TextMatchMarkerListImpl::Add(DocumentMarker* marker) { - DocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, - marker); + SortedDocumentMarkerListEditor::AddMarkerWithoutMergingOverlapping(&markers_, + marker); } void TextMatchMarkerListImpl::Clear() { @@ -38,32 +38,33 @@ DocumentMarker* TextMatchMarkerListImpl::FirstMarkerIntersectingRange( unsigned start_offset, unsigned end_offset) const { - return DocumentMarkerListEditor::FirstMarkerIntersectingRange( + return SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange( markers_, start_offset, end_offset); } HeapVector<Member<DocumentMarker>> TextMatchMarkerListImpl::MarkersIntersectingRange(unsigned start_offset, unsigned end_offset) const { - return DocumentMarkerListEditor::MarkersIntersectingRange( + return SortedDocumentMarkerListEditor::MarkersIntersectingRange( markers_, start_offset, end_offset); } bool TextMatchMarkerListImpl::MoveMarkers(int length, DocumentMarkerList* dst_list) { - return DocumentMarkerListEditor::MoveMarkers(&markers_, length, dst_list); + return SortedDocumentMarkerListEditor::MoveMarkers(&markers_, length, + dst_list); } bool TextMatchMarkerListImpl::RemoveMarkers(unsigned start_offset, int length) { - return DocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, - length); + return SortedDocumentMarkerListEditor::RemoveMarkers(&markers_, start_offset, + length); } bool TextMatchMarkerListImpl::ShiftMarkers(const String&, unsigned offset, unsigned old_length, unsigned new_length) { - return DocumentMarkerListEditor::ShiftMarkersContentDependent( + return SortedDocumentMarkerListEditor::ShiftMarkersContentDependent( &markers_, offset, old_length, new_length); }
diff --git a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp index 354a374..ed0120c 100644 --- a/third_party/WebKit/Source/core/exported/WebFrameTest.cpp +++ b/third_party/WebKit/Source/core/exported/WebFrameTest.cpp
@@ -103,6 +103,7 @@ #include "platform/bindings/Microtask.h" #include "platform/geometry/FloatRect.h" #include "platform/graphics/GraphicsLayer.h" +#include "platform/graphics/compositing/PaintArtifactCompositor.h" #include "platform/loader/fetch/FetchParameters.h" #include "platform/loader/fetch/MemoryCache.h" #include "platform/loader/fetch/ResourceError.h" @@ -11678,7 +11679,6 @@ tester.ExpectTotalCount(histogramName, 3); } -// TODO(pdr): Create a version of this test for SPV2 (crbug.com.758028). TEST_P(ParameterizedWebFrameTest, DidScrollCallbackAfterScrollableAreaChanges) { FrameTestHelpers::WebViewHelper web_view_helper; web_view_helper.Initialize(); @@ -11713,6 +11713,8 @@ scrollable_area->LayerForScrolling()->PlatformLayer(); EXPECT_NE(nullptr, web_scroll_layer); + // Ensure a synthetic impl-side scroll offset propagates to the scrollable + // area using the DidScroll callback. EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset()); web_scroll_layer->SetScrollOffsetFromImplSideForTesting( gfx::ScrollOffset(0, 1)); @@ -11737,4 +11739,124 @@ gfx::ScrollOffset(0, 3)); } +class SlimmingPaintWebFrameTest + : public ::testing::WithParamInterface<TestParamRootLayerScrolling>, + private ScopedRootLayerScrollingForTest, + private ScopedSlimmingPaintV2ForTest, + public WebFrameTest { + public: + SlimmingPaintWebFrameTest() + : ScopedRootLayerScrollingForTest(GetParam()), + ScopedSlimmingPaintV2ForTest(true) {} + + void SetUp() override { + web_view_helper_ = WTF::MakeUnique<FrameTestHelpers::WebViewHelper>(); + web_view_helper_->Initialize(nullptr, &web_view_client_, nullptr, + &ConfigureCompositingWebView); + web_view_helper_->Resize(WebSize(200, 200)); + + // The paint artifact compositor should have been created as part of the + // web view helper setup. + DCHECK(paint_artifact_compositor()); + paint_artifact_compositor()->EnableExtraDataForTesting(); + } + + WebLocalFrame* LocalMainFrame() { return web_view_helper_->LocalMainFrame(); } + + WebViewImpl* WebView() { return web_view_helper_->WebView(); } + + size_t ContentLayerCount() { + return paint_artifact_compositor() + ->GetExtraDataForTesting() + ->content_layers.size(); + } + + size_t ScrollHitTestLayerCount() { + return paint_artifact_compositor() + ->GetExtraDataForTesting() + ->scroll_hit_test_layers.size(); + } + + std::unique_ptr<WebLayer> ContentLayerAt(unsigned index) { + return paint_artifact_compositor() + ->GetExtraDataForTesting() + ->ContentWebLayerAt(index); + } + + std::unique_ptr<WebLayer> ScrollHitTestLayerAt(unsigned index) { + return paint_artifact_compositor() + ->GetExtraDataForTesting() + ->ScrollHitTestWebLayerAt(index); + } + + private: + PaintArtifactCompositor* paint_artifact_compositor() { + auto* frame_view = web_view_helper_->LocalMainFrame()->GetFrameView(); + return frame_view->GetPaintArtifactCompositorForTesting(); + } + FrameTestHelpers::TestWebViewClient web_view_client_; + std::unique_ptr<FrameTestHelpers::WebViewHelper> web_view_helper_; +}; + +INSTANTIATE_TEST_CASE_P(All, SlimmingPaintWebFrameTest, ::testing::Bool()); + +TEST_P(SlimmingPaintWebFrameTest, DidScrollCallbackAfterScrollableAreaChanges) { + DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled()); + + InitializeWithHTML(*WebView()->MainFrameImpl()->GetFrame(), + "<style>" + " #scrollable {" + " height: 100px;" + " width: 100px;" + " overflow: scroll;" + " will-change: transform;" + " }" + " #forceScroll { height: 120px; width: 50px; }" + "</style>" + "<div id='scrollable'>" + " <div id='forceScroll'></div>" + "</div>"); + + WebView()->UpdateAllLifecyclePhases(); + + Document* document = WebView()->MainFrameImpl()->GetFrame()->GetDocument(); + Element* scrollable = document->getElementById("scrollable"); + + auto* scrollable_area = + ToLayoutBox(scrollable->GetLayoutObject())->GetScrollableArea(); + EXPECT_NE(nullptr, scrollable_area); + + EXPECT_EQ(ContentLayerCount(), 2u); + EXPECT_EQ(ScrollHitTestLayerCount(), 1u); + + // Ensure a synthetic impl-side scroll offset propagates to the scrollable + // area using the DidScroll callback. + EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset()); + ScrollHitTestLayerAt(0)->SetScrollOffsetFromImplSideForTesting( + gfx::ScrollOffset(0, 1)); + WebView()->UpdateAllLifecyclePhases(); + EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset()); + + // Make the scrollable area non-scrollable. + scrollable->setAttribute(HTMLNames::styleAttr, "overflow: visible"); + + // Update layout without updating compositing state. + LocalMainFrame()->ExecuteScript( + WebScriptSource("var forceLayoutFromScript = scrollable.offsetTop;")); + EXPECT_EQ(document->Lifecycle().GetState(), DocumentLifecycle::kLayoutClean); + + EXPECT_EQ(nullptr, + ToLayoutBox(scrollable->GetLayoutObject())->GetScrollableArea()); + + // The web scroll layer has not been deleted yet and we should be able to + // apply impl-side offsets without crashing. + EXPECT_EQ(ScrollHitTestLayerCount(), 1u); + ScrollHitTestLayerAt(0)->SetScrollOffsetFromImplSideForTesting( + gfx::ScrollOffset(0, 3)); + + WebView()->UpdateAllLifecyclePhases(); + EXPECT_EQ(ContentLayerCount(), 1u); + EXPECT_EQ(ScrollHitTestLayerCount(), 0u); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.h b/third_party/WebKit/Source/core/frame/LocalFrameView.h index 4b5997d3..471714f 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.h +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.h
@@ -853,6 +853,11 @@ // LocalFrameView (or possibly the LocalFrameView itself). ScrollableArea* ScrollableAreaWithElementId(const CompositorElementId&); + PaintArtifactCompositor* GetPaintArtifactCompositorForTesting() { + DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled()); + return paint_artifact_compositor_.get(); + } + protected: // Scroll the content via the compositor. bool ScrollContentsFastPath(const IntSize& scroll_delta);
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index 058da4b9..d16fe4b 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -2223,11 +2223,10 @@ // The spec does not define an invalid value default: // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28950 - - // TODO(foolip): Try to make "metadata" the default preload state: - // https://crbug.com/310450 UseCounter::Count(GetDocument(), WebFeature::kHTMLMediaElementPreloadDefault); - return WebMediaPlayer::kPreloadAuto; + return RuntimeEnabledFeatures::PreloadDefaultIsMetadataEnabled() + ? WebMediaPlayer::kPreloadMetaData + : WebMediaPlayer::kPreloadAuto; } String HTMLMediaElement::EffectivePreload() const {
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElementTest.cpp index e76e744..ca214541 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElementTest.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElementTest.cpp
@@ -114,8 +114,8 @@ {false, false, true, TestURLScheme::kHttp, "auto", "metadata"}, {false, false, true, TestURLScheme::kHttp, "scheme", "metadata"}, {false, false, true, TestURLScheme::kHttp, "none", "none"}, - // Tests that the preload is overriden to "auto" - {false, false, false, TestURLScheme::kHttp, "foo", "auto"}, + // Tests that the preload is overriden to "metadata". + {false, false, false, TestURLScheme::kHttp, "foo", "metadata"}, }; int index = 0;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index d818073b..b687b078 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -5100,7 +5100,7 @@ TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset, zoffset, format, type, canvas - ->CopiedImage(kFrontBuffer, kPreferAcceleration, + ->CopiedImage(kBackBuffer, kPreferAcceleration, FunctionIDToSnapshotReason(function_id)) .Get(), WebGLImageConversion::kHtmlDomCanvas, unpack_flip_y_, @@ -5134,7 +5134,7 @@ TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset, zoffset, format, type, canvas - ->CopiedImage(kFrontBuffer, kPreferAcceleration, + ->CopiedImage(kBackBuffer, kPreferAcceleration, FunctionIDToSnapshotReason(function_id)) .Get(), WebGLImageConversion::kHtmlDomCanvas, unpack_flip_y_,
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 index ae8c81a..4c10cdc 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5 +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.json5
@@ -853,6 +853,10 @@ status: "stable", }, { + name: "PreloadDefaultIsMetadata", + status: "experimental", + }, + { name: "Presentation", status: "stable", },
diff --git a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp index 13153174..506a84f7 100644 --- a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp +++ b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
@@ -248,6 +248,10 @@ RuntimeEnabledFeatures::SetPermissionsEnabled(enable); } +void WebRuntimeFeatures::EnablePreloadDefaultIsMetadata(bool enable) { + RuntimeEnabledFeatures::SetPreloadDefaultIsMetadataEnabled(enable); +} + void WebRuntimeFeatures::EnableScriptedSpeech(bool enable) { RuntimeEnabledFeatures::SetScriptedSpeechEnabled(enable); }
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp index badb2a7..eafaa72 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -754,6 +754,19 @@ } } +std::unique_ptr<WebLayer> +PaintArtifactCompositor::ExtraDataForTesting::ContentWebLayerAt( + unsigned index) { + return Platform::Current()->CompositorSupport()->CreateLayerFromCCLayer( + content_layers[index].get()); +} +std::unique_ptr<WebLayer> +PaintArtifactCompositor::ExtraDataForTesting::ScrollHitTestWebLayerAt( + unsigned index) { + return Platform::Current()->CompositorSupport()->CreateLayerFromCCLayer( + scroll_hit_test_layers[index].get()); +} + #ifndef NDEBUG void PaintArtifactCompositor::ShowDebugData() { LOG(ERROR) << LayersAsJSON(kLayerTreeIncludesDebugInfo)
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h index 0ce1663..d343547 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.h
@@ -77,6 +77,9 @@ // way of locating the layers of interest, since there are still a slew of // placeholder layers required. struct ExtraDataForTesting { + std::unique_ptr<WebLayer> ContentWebLayerAt(unsigned index); + std::unique_ptr<WebLayer> ScrollHitTestWebLayerAt(unsigned index); + Vector<scoped_refptr<cc::Layer>> content_layers; Vector<scoped_refptr<cc::Layer>> synthesized_clip_layers; Vector<scoped_refptr<cc::Layer>> scroll_hit_test_layers;
diff --git a/third_party/WebKit/public/platform/WebRuntimeFeatures.h b/third_party/WebKit/public/platform/WebRuntimeFeatures.h index a9c0596f..aac83b5 100644 --- a/third_party/WebKit/public/platform/WebRuntimeFeatures.h +++ b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
@@ -113,6 +113,7 @@ BLINK_PLATFORM_EXPORT static void EnablePaymentRequest(bool); BLINK_PLATFORM_EXPORT static void EnablePermissionsAPI(bool); BLINK_PLATFORM_EXPORT static void EnablePreciseMemoryInfo(bool); + BLINK_PLATFORM_EXPORT static void EnablePreloadDefaultIsMetadata(bool); BLINK_PLATFORM_EXPORT static void EnablePrintBrowser(bool); BLINK_PLATFORM_EXPORT static void EnablePresentationAPI(bool); BLINK_PLATFORM_EXPORT static void EnablePushMessaging(bool);
diff --git a/third_party/android_support_test_runner/rules_java.info b/third_party/android_support_test_runner/rules_java.info new file mode 100644 index 0000000..28c8330 --- /dev/null +++ b/third_party/android_support_test_runner/rules_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/values/values.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/third_party/closure_compiler/externs/networking_private.js b/third_party/closure_compiler/externs/networking_private.js index 961262a..4e63c9e 100644 --- a/third_party/closure_compiler/externs/networking_private.js +++ b/third_party/closure_compiler/externs/networking_private.js
@@ -999,8 +999,8 @@ /** * @typedef {{ * Scanning: (boolean|undefined), - * SimLockType: (string|undefined), - * SimPresent: (boolean|undefined), + * SIMLockStatus: (!chrome.networkingPrivate.SIMLockStatus|undefined), + * SIMPresent: (boolean|undefined), * State: !chrome.networkingPrivate.DeviceStateType, * Type: !chrome.networkingPrivate.NetworkType * }}
diff --git a/third_party/gvr-android-sdk/controller_test_api_java.info b/third_party/gvr-android-sdk/controller_test_api_java.info new file mode 100644 index 0000000..a2ebd4a --- /dev/null +++ b/third_party/gvr-android-sdk/controller_test_api_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/third_party/gvr-android-sdk/gvr_common_java.info b/third_party/gvr-android-sdk/gvr_common_java.info new file mode 100644 index 0000000..aacf1d9 --- /dev/null +++ b/third_party/gvr-android-sdk/gvr_common_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = true +is_manifest_empty = true +resources = [ "res/drawable-hdpi-v4/quantum_ic_close_white_24.png", "res/drawable-hdpi-v4/quantum_ic_settings_white_24.png", "res/drawable-hdpi-v4/transition.png", "res/drawable-mdpi-v4/quantum_ic_close_white_24.png", "res/drawable-mdpi-v4/quantum_ic_settings_white_24.png", "res/drawable-mdpi-v4/transition.png", "res/drawable-v21/rippleable.xml", "res/drawable-xhdpi-v4/quantum_ic_close_white_24.png", "res/drawable-xhdpi-v4/quantum_ic_settings_white_24.png", "res/drawable-xxhdpi-v4/quantum_ic_close_white_24.png", "res/drawable-xxhdpi-v4/quantum_ic_settings_white_24.png", "res/drawable-xxxhdpi-v4/quantum_ic_close_white_24.png", "res/drawable-xxxhdpi-v4/quantum_ic_settings_white_24.png", "res/drawable/rippleable.xml", "res/layout-land/back_button.xml", "res/layout-land/settings_button.xml", "res/layout-land/ui_layer_with_portrait_support.xml", "res/layout-ldrtl-land-v17/back_button.xml", "res/layout-ldrtl-land-v17/settings_button.xml", "res/layout-ldrtl-v17/back_button.xml", "res/layout-ldrtl-v17/settings_button.xml", "res/layout/back_button.xml", "res/layout/settings_button.xml", "res/layout/transition_view.xml", "res/layout/ui_layer.xml", "res/layout/ui_layer_with_portrait_support.xml", "res/values-ar/values.xml", "res/values-bg/values.xml", "res/values-ca/values.xml", "res/values-cs/values.xml", "res/values-da/values.xml", "res/values-de/values.xml", "res/values-el/values.xml", "res/values-en-rGB/values.xml", "res/values-es-rUS/values.xml", "res/values-es/values.xml", "res/values-fa/values.xml", "res/values-fi/values.xml", "res/values-fr-rCA/values.xml", "res/values-fr/values.xml", "res/values-hi/values.xml", "res/values-hr/values.xml", "res/values-hu/values.xml", "res/values-id/values.xml", "res/values-it/values.xml", "res/values-iw/values.xml", "res/values-ja/values.xml", "res/values-ko/values.xml", "res/values-land/values.xml", "res/values-lt/values.xml", "res/values-lv/values.xml", "res/values-nl/values.xml", "res/values-no/values.xml", "res/values-pl/values.xml", "res/values-pt-rBR/values.xml", "res/values-pt-rPT/values.xml", "res/values-ro/values.xml", "res/values-ru/values.xml", "res/values-sk/values.xml", "res/values-sl/values.xml", "res/values-sr/values.xml", "res/values-sv/values.xml", "res/values-th/values.xml", "res/values-tl/values.xml", "res/values-tr/values.xml", "res/values-uk/values.xml", "res/values-v19/values.xml", "res/values-v21/values.xml", "res/values-vi/values.xml", "res/values-zh-rCN/values.xml", "res/values-zh-rTW/values.xml", "res/values/values.xml" ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/third_party/gvr-android-sdk/gvr_controller_java.info b/third_party/gvr-android-sdk/gvr_controller_java.info new file mode 100644 index 0000000..a2ebd4a --- /dev/null +++ b/third_party/gvr-android-sdk/gvr_controller_java.info
@@ -0,0 +1,13 @@ +# Generated by //build/android/gyp/aar.py +# To regenerate, use "update_android_aar_prebuilts = true" and run "gn gen". + +aidl = [ ] +assets = [ ] +has_classes_jar = true +has_native_libraries = false +has_proguard_flags = false +has_r_text_file = false +is_manifest_empty = true +resources = [ ] +subjar_tuples = [ ] +subjars = [ ]
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index 6ed060d9..6093bfc 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -5,9 +5,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Tuesday August 15 2017 +Date: Wednesday August 23 2017 Branch: master -Commit: 6b9c691dafc884424e05b5294b6e0e4996d533a5 +Commit: 30c261b1ebe8f06d687cac5b3b442d51a7839d00 Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/libvpx_srcs.gni b/third_party/libvpx/libvpx_srcs.gni index 53d01a5..4ac157ee 100644 --- a/third_party/libvpx/libvpx_srcs.gni +++ b/third_party/libvpx/libvpx_srcs.gni
@@ -444,10 +444,14 @@ libvpx_srcs_x86_sse4_1 = [ "//third_party/libvpx/source/libvpx/vp8/encoder/x86/quantize_sse4.c", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse4.c", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse4.c", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse4.c", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse4.c", ] -libvpx_srcs_x86_avx = [ "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_diamond_search_sad_avx.c" ] +libvpx_srcs_x86_avx = [ + "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_diamond_search_sad_avx.c", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_avx.c", +] libvpx_srcs_x86_avx2 = [ "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_error_avx2.c", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_txfm_avx2.c", @@ -906,10 +910,14 @@ libvpx_srcs_x86_64_sse4_1 = [ "//third_party/libvpx/source/libvpx/vp8/encoder/x86/quantize_sse4.c", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct16x16_add_sse4.c", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct32x32_add_sse4.c", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct4x4_add_sse4.c", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/highbd_idct8x8_add_sse4.c", ] -libvpx_srcs_x86_64_avx = [ "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_diamond_search_sad_avx.c" ] +libvpx_srcs_x86_64_avx = [ + "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_diamond_search_sad_avx.c", + "//third_party/libvpx/source/libvpx/vpx_dsp/x86/quantize_avx.c", +] libvpx_srcs_x86_64_avx2 = [ "//third_party/libvpx/source/libvpx/vp9/encoder/x86/vp9_error_avx2.c", "//third_party/libvpx/source/libvpx/vpx_dsp/x86/fwd_txfm_avx2.c", @@ -2789,6 +2797,7 @@ "//third_party/libvpx/source/libvpx/vpx_mem/include/vpx_mem_intrnl.h", "//third_party/libvpx/source/libvpx/vpx_mem/vpx_mem.c", "//third_party/libvpx/source/libvpx/vpx_mem/vpx_mem.h", + "//third_party/libvpx/source/libvpx/vpx_ports/asmdefs_mmi.h", "//third_party/libvpx/source/libvpx/vpx_ports/bitops.h", "//third_party/libvpx/source/libvpx/vpx_ports/emmintrin_compat.h", "//third_party/libvpx/source/libvpx/vpx_ports/mem.h",
diff --git a/third_party/libvpx/source/config/ios/arm-neon/vp9_rtcd.h b/third_party/libvpx/source/config/ios/arm-neon/vp9_rtcd.h index 8eedae1..8cd3c19 100644 --- a/third_party/libvpx/source/config/ios/arm-neon/vp9_rtcd.h +++ b/third_party/libvpx/source/config/ios/arm-neon/vp9_rtcd.h
@@ -199,7 +199,18 @@ uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan); -#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c +void vp9_quantize_fp_32x32_neon(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* round_ptr, + const int16_t* quant_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); +#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_neon void vp9_scale_and_extend_frame_c(const struct yv12_buffer_config* src, struct yv12_buffer_config* dst,
diff --git a/third_party/libvpx/source/config/ios/arm64/vp9_rtcd.h b/third_party/libvpx/source/config/ios/arm64/vp9_rtcd.h index 8eedae1..8cd3c19 100644 --- a/third_party/libvpx/source/config/ios/arm64/vp9_rtcd.h +++ b/third_party/libvpx/source/config/ios/arm64/vp9_rtcd.h
@@ -199,7 +199,18 @@ uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan); -#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c +void vp9_quantize_fp_32x32_neon(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* round_ptr, + const int16_t* quant_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); +#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_neon void vp9_scale_and_extend_frame_c(const struct yv12_buffer_config* src, struct yv12_buffer_config* dst,
diff --git a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vp9_rtcd.h b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vp9_rtcd.h index 4c485fb8..7a339e5 100644 --- a/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vp9_rtcd.h +++ b/third_party/libvpx/source/config/linux/arm-neon-cpu-detect/vp9_rtcd.h
@@ -237,7 +237,28 @@ uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan); -#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c +void vp9_quantize_fp_32x32_neon(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* round_ptr, + const int16_t* quant_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); +RTCD_EXTERN void (*vp9_quantize_fp_32x32)(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* round_ptr, + const int16_t* quant_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); void vp9_scale_and_extend_frame_c(const struct yv12_buffer_config* src, struct yv12_buffer_config* dst, @@ -274,6 +295,9 @@ vp9_quantize_fp = vp9_quantize_fp_c; if (flags & HAS_NEON) vp9_quantize_fp = vp9_quantize_fp_neon; + vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_c; + if (flags & HAS_NEON) + vp9_quantize_fp_32x32 = vp9_quantize_fp_32x32_neon; } #endif
diff --git a/third_party/libvpx/source/config/linux/arm-neon/vp9_rtcd.h b/third_party/libvpx/source/config/linux/arm-neon/vp9_rtcd.h index 8eedae1..8cd3c19 100644 --- a/third_party/libvpx/source/config/linux/arm-neon/vp9_rtcd.h +++ b/third_party/libvpx/source/config/linux/arm-neon/vp9_rtcd.h
@@ -199,7 +199,18 @@ uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan); -#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c +void vp9_quantize_fp_32x32_neon(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* round_ptr, + const int16_t* quant_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); +#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_neon void vp9_scale_and_extend_frame_c(const struct yv12_buffer_config* src, struct yv12_buffer_config* dst,
diff --git a/third_party/libvpx/source/config/linux/arm64/vp9_rtcd.h b/third_party/libvpx/source/config/linux/arm64/vp9_rtcd.h index 8eedae1..8cd3c19 100644 --- a/third_party/libvpx/source/config/linux/arm64/vp9_rtcd.h +++ b/third_party/libvpx/source/config/linux/arm64/vp9_rtcd.h
@@ -199,7 +199,18 @@ uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan); -#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_c +void vp9_quantize_fp_32x32_neon(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* round_ptr, + const int16_t* quant_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); +#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_neon void vp9_scale_and_extend_frame_c(const struct yv12_buffer_config* src, struct yv12_buffer_config* dst,
diff --git a/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h index 90eff41..10f0c335 100644 --- a/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/linux/ia32/vpx_dsp_rtcd.h
@@ -4345,13 +4345,35 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c +void vpx_highbd_idct32x32_1024_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_1024_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_1024_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_135_add_c(const tran_low_t* input, uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_135_add vpx_highbd_idct32x32_135_add_c +void vpx_highbd_idct32x32_135_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_135_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_135_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_1_add_c(const tran_low_t* input, uint16_t* dest, @@ -4370,7 +4392,18 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_34_add vpx_highbd_idct32x32_34_add_c +void vpx_highbd_idct32x32_34_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_34_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_34_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct4x4_16_add_c(const tran_low_t* input, uint16_t* dest, @@ -6089,6 +6122,19 @@ uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan); +void vpx_quantize_b_avx(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* zbin_ptr, + const int16_t* round_ptr, + const int16_t* quant_ptr, + const int16_t* quant_shift_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); RTCD_EXTERN void (*vpx_quantize_b)(const tran_low_t* coeff_ptr, intptr_t n_coeffs, int skip_block, @@ -8956,9 +9002,24 @@ vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse4_1; + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse4_1; + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse4_1; vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_c; if (flags & HAS_SSE2) vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_sse2; + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse4_1; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_c; if (flags & HAS_SSE2) vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse2; @@ -9280,6 +9341,8 @@ vpx_quantize_b = vpx_quantize_b_sse2; if (flags & HAS_SSSE3) vpx_quantize_b = vpx_quantize_b_ssse3; + if (flags & HAS_AVX) + vpx_quantize_b = vpx_quantize_b_avx; vpx_sad16x16 = vpx_sad16x16_c; if (flags & HAS_SSE2) vpx_sad16x16 = vpx_sad16x16_sse2;
diff --git a/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h index 5aa8e2e..76174db 100644 --- a/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/linux/x64/vpx_dsp_rtcd.h
@@ -3695,13 +3695,35 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c +void vpx_highbd_idct32x32_1024_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_1024_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_1024_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_135_add_c(const tran_low_t* input, uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_135_add vpx_highbd_idct32x32_135_add_c +void vpx_highbd_idct32x32_135_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_135_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_135_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_1_add_c(const tran_low_t* input, uint16_t* dest, @@ -3717,7 +3739,18 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_34_add vpx_highbd_idct32x32_34_add_c +void vpx_highbd_idct32x32_34_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_34_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_34_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct4x4_16_add_c(const tran_low_t* input, uint16_t* dest, @@ -7218,6 +7251,15 @@ vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse4_1; + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse4_1; + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse4_1; + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse4_1; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse4_1;
diff --git a/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h index 90eff41..10f0c335 100644 --- a/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/mac/ia32/vpx_dsp_rtcd.h
@@ -4345,13 +4345,35 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c +void vpx_highbd_idct32x32_1024_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_1024_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_1024_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_135_add_c(const tran_low_t* input, uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_135_add vpx_highbd_idct32x32_135_add_c +void vpx_highbd_idct32x32_135_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_135_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_135_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_1_add_c(const tran_low_t* input, uint16_t* dest, @@ -4370,7 +4392,18 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_34_add vpx_highbd_idct32x32_34_add_c +void vpx_highbd_idct32x32_34_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_34_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_34_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct4x4_16_add_c(const tran_low_t* input, uint16_t* dest, @@ -6089,6 +6122,19 @@ uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan); +void vpx_quantize_b_avx(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* zbin_ptr, + const int16_t* round_ptr, + const int16_t* quant_ptr, + const int16_t* quant_shift_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); RTCD_EXTERN void (*vpx_quantize_b)(const tran_low_t* coeff_ptr, intptr_t n_coeffs, int skip_block, @@ -8956,9 +9002,24 @@ vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse4_1; + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse4_1; + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse4_1; vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_c; if (flags & HAS_SSE2) vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_sse2; + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse4_1; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_c; if (flags & HAS_SSE2) vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse2; @@ -9280,6 +9341,8 @@ vpx_quantize_b = vpx_quantize_b_sse2; if (flags & HAS_SSSE3) vpx_quantize_b = vpx_quantize_b_ssse3; + if (flags & HAS_AVX) + vpx_quantize_b = vpx_quantize_b_avx; vpx_sad16x16 = vpx_sad16x16_c; if (flags & HAS_SSE2) vpx_sad16x16 = vpx_sad16x16_sse2;
diff --git a/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h index 5aa8e2e..76174db 100644 --- a/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/mac/x64/vpx_dsp_rtcd.h
@@ -3695,13 +3695,35 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c +void vpx_highbd_idct32x32_1024_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_1024_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_1024_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_135_add_c(const tran_low_t* input, uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_135_add vpx_highbd_idct32x32_135_add_c +void vpx_highbd_idct32x32_135_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_135_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_135_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_1_add_c(const tran_low_t* input, uint16_t* dest, @@ -3717,7 +3739,18 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_34_add vpx_highbd_idct32x32_34_add_c +void vpx_highbd_idct32x32_34_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_34_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_34_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct4x4_16_add_c(const tran_low_t* input, uint16_t* dest, @@ -7218,6 +7251,15 @@ vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse4_1; + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse4_1; + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse4_1; + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse4_1; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse4_1;
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index f27b67d..7b71ebe0 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -1,7 +1,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 6 #define VERSION_PATCH 1 -#define VERSION_EXTRA "1074-g6b9c691da" +#define VERSION_EXTRA "1117-g30c261b1e" #define VERSION_PACKED ((VERSION_MAJOR<<16)|(VERSION_MINOR<<8)|(VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.6.1-1074-g6b9c691da" -#define VERSION_STRING " v1.6.1-1074-g6b9c691da" +#define VERSION_STRING_NOSP "v1.6.1-1117-g30c261b1e" +#define VERSION_STRING " v1.6.1-1117-g30c261b1e"
diff --git a/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h index 90eff41..10f0c335 100644 --- a/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/win/ia32/vpx_dsp_rtcd.h
@@ -4345,13 +4345,35 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c +void vpx_highbd_idct32x32_1024_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_1024_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_1024_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_135_add_c(const tran_low_t* input, uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_135_add vpx_highbd_idct32x32_135_add_c +void vpx_highbd_idct32x32_135_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_135_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_135_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_1_add_c(const tran_low_t* input, uint16_t* dest, @@ -4370,7 +4392,18 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_34_add vpx_highbd_idct32x32_34_add_c +void vpx_highbd_idct32x32_34_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_34_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_34_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct4x4_16_add_c(const tran_low_t* input, uint16_t* dest, @@ -6089,6 +6122,19 @@ uint16_t* eob_ptr, const int16_t* scan, const int16_t* iscan); +void vpx_quantize_b_avx(const tran_low_t* coeff_ptr, + intptr_t n_coeffs, + int skip_block, + const int16_t* zbin_ptr, + const int16_t* round_ptr, + const int16_t* quant_ptr, + const int16_t* quant_shift_ptr, + tran_low_t* qcoeff_ptr, + tran_low_t* dqcoeff_ptr, + const int16_t* dequant_ptr, + uint16_t* eob_ptr, + const int16_t* scan, + const int16_t* iscan); RTCD_EXTERN void (*vpx_quantize_b)(const tran_low_t* coeff_ptr, intptr_t n_coeffs, int skip_block, @@ -8956,9 +9002,24 @@ vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse4_1; + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse4_1; + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse4_1; vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_c; if (flags & HAS_SSE2) vpx_highbd_idct32x32_1_add = vpx_highbd_idct32x32_1_add_sse2; + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_c; + if (flags & HAS_SSE2) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse4_1; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_c; if (flags & HAS_SSE2) vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse2; @@ -9280,6 +9341,8 @@ vpx_quantize_b = vpx_quantize_b_sse2; if (flags & HAS_SSSE3) vpx_quantize_b = vpx_quantize_b_ssse3; + if (flags & HAS_AVX) + vpx_quantize_b = vpx_quantize_b_avx; vpx_sad16x16 = vpx_sad16x16_c; if (flags & HAS_SSE2) vpx_sad16x16 = vpx_sad16x16_sse2;
diff --git a/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h b/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h index 5aa8e2e..76174db 100644 --- a/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h +++ b/third_party/libvpx/source/config/win/x64/vpx_dsp_rtcd.h
@@ -3695,13 +3695,35 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_1024_add vpx_highbd_idct32x32_1024_add_c +void vpx_highbd_idct32x32_1024_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_1024_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_1024_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_135_add_c(const tran_low_t* input, uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_135_add vpx_highbd_idct32x32_135_add_c +void vpx_highbd_idct32x32_135_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_135_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_135_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct32x32_1_add_c(const tran_low_t* input, uint16_t* dest, @@ -3717,7 +3739,18 @@ uint16_t* dest, int stride, int bd); -#define vpx_highbd_idct32x32_34_add vpx_highbd_idct32x32_34_add_c +void vpx_highbd_idct32x32_34_add_sse2(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +void vpx_highbd_idct32x32_34_add_sse4_1(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); +RTCD_EXTERN void (*vpx_highbd_idct32x32_34_add)(const tran_low_t* input, + uint16_t* dest, + int stride, + int bd); void vpx_highbd_idct4x4_16_add_c(const tran_low_t* input, uint16_t* dest, @@ -7218,6 +7251,15 @@ vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct16x16_38_add = vpx_highbd_idct16x16_38_add_sse4_1; + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_1024_add = vpx_highbd_idct32x32_1024_add_sse4_1; + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_135_add = vpx_highbd_idct32x32_135_add_sse4_1; + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse2; + if (flags & HAS_SSE4_1) + vpx_highbd_idct32x32_34_add = vpx_highbd_idct32x32_34_add_sse4_1; vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse2; if (flags & HAS_SSE4_1) vpx_highbd_idct4x4_16_add = vpx_highbd_idct4x4_16_add_sse4_1;
diff --git a/third_party/snappy/README.chromium b/third_party/snappy/README.chromium index 9cf4e95..c89b74a 100644 --- a/third_party/snappy/README.chromium +++ b/third_party/snappy/README.chromium
@@ -1,7 +1,7 @@ Name: Snappy: A fast compressor/decompressor Short Name: snappy URL: http://google.github.io/snappy/ -Version: 1.1.6.git.77c12adc192ac6620a0f0d340c99149ec56a97a3 +Version: 1.1.7 License: New BSD License File: src/COPYING Security Critical: yes
diff --git a/third_party/snappy/linux/config.h b/third_party/snappy/linux/config.h index 6c51dba..2595d0e 100644 --- a/third_party/snappy/linux/config.h +++ b/third_party/snappy/linux/config.h
@@ -55,8 +55,8 @@ /* Define to 1 if you have the <windows.h> header file. */ /* #undef HAVE_WINDOWS_H */ -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef SNAPPY_IS_BIG_ENDIAN */ #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_CMAKE_CONFIG_H_
diff --git a/third_party/snappy/linux/snappy-stubs-public.h b/third_party/snappy/linux/snappy-stubs-public.h index 394d512..590cae0 100644 --- a/third_party/snappy/linux/snappy-stubs-public.h +++ b/third_party/snappy/linux/snappy-stubs-public.h
@@ -50,7 +50,7 @@ #define SNAPPY_MAJOR 1 #define SNAPPY_MINOR 1 -#define SNAPPY_PATCHLEVEL 6 +#define SNAPPY_PATCHLEVEL 7 #define SNAPPY_VERSION \ ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL)
diff --git a/third_party/snappy/mac/config.h b/third_party/snappy/mac/config.h index bedcfb7a..16bb031 100644 --- a/third_party/snappy/mac/config.h +++ b/third_party/snappy/mac/config.h
@@ -55,8 +55,8 @@ /* Define to 1 if you have the <windows.h> header file. */ /* #undef HAVE_WINDOWS_H */ -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef SNAPPY_IS_BIG_ENDIAN */ #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_CMAKE_CONFIG_H_
diff --git a/third_party/snappy/mac/snappy-stubs-public.h b/third_party/snappy/mac/snappy-stubs-public.h index 91c3de97..442d599 100644 --- a/third_party/snappy/mac/snappy-stubs-public.h +++ b/third_party/snappy/mac/snappy-stubs-public.h
@@ -50,7 +50,7 @@ #define SNAPPY_MAJOR 1 #define SNAPPY_MINOR 1 -#define SNAPPY_PATCHLEVEL 6 +#define SNAPPY_PATCHLEVEL 7 #define SNAPPY_VERSION \ ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL)
diff --git a/third_party/snappy/win32/config.h b/third_party/snappy/win32/config.h index 75fcea87..d0db90f0 100644 --- a/third_party/snappy/win32/config.h +++ b/third_party/snappy/win32/config.h
@@ -55,8 +55,8 @@ /* Define to 1 if you have the <windows.h> header file. */ #define HAVE_WINDOWS_H 1 -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef SNAPPY_IS_BIG_ENDIAN */ #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_CMAKE_CONFIG_H_
diff --git a/third_party/snappy/win32/snappy-stubs-public.h b/third_party/snappy/win32/snappy-stubs-public.h index afe3c84..b3fddd3 100644 --- a/third_party/snappy/win32/snappy-stubs-public.h +++ b/third_party/snappy/win32/snappy-stubs-public.h
@@ -50,7 +50,7 @@ #define SNAPPY_MAJOR 1 #define SNAPPY_MINOR 1 -#define SNAPPY_PATCHLEVEL 6 +#define SNAPPY_PATCHLEVEL 7 #define SNAPPY_VERSION \ ((SNAPPY_MAJOR << 16) | (SNAPPY_MINOR << 8) | SNAPPY_PATCHLEVEL)
diff --git a/third_party/zlib/0003-arm-inffast.patch b/third_party/zlib/0003-arm-inffast.patch new file mode 100644 index 0000000..9f758c8 --- /dev/null +++ b/third_party/zlib/0003-arm-inffast.patch
@@ -0,0 +1,2248 @@ +From 1ca9400d89deb0fd8d234cd02c9fd9359dad7a9e Mon Sep 17 00:00:00 2001 +From: Adenilson Cavalcanti <adenilson.cavalcanti@arm.com> +Date: Fri, 11 Aug 2017 15:37:44 -0700 +Subject: [PATCH] zlib: inflate using wider loads and stores + +In inflate_fast() the output pointer always has plenty of room to write. This +means that so long as the target is capable, wide un-aligned loads and stores +can be used to transfer several bytes at once. + +When the reference distance is too short simply unroll the data a little to +increase the distance. Patch by Simon Rosie. + +BUG=697280 +Change-Id: I59854eb25d2b1e43561c8a2afaf9175bf10cf674 +--- + third_party/zlib/BUILD.gn | 18 + + third_party/zlib/README.chromium | 1 + + third_party/zlib/contrib/arm/chunkcopy.h | 279 ++++++ + third_party/zlib/contrib/arm/inffast.c | 307 ++++++ + third_party/zlib/contrib/arm/inflate.c | 1571 ++++++++++++++++++++++++++++++ + 5 files changed, 2176 insertions(+) + create mode 100644 third_party/zlib/contrib/arm/chunkcopy.h + create mode 100644 third_party/zlib/contrib/arm/inffast.c + create mode 100644 third_party/zlib/contrib/arm/inflate.c + +diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn +index 4b4db15..8c57ad4 100644 +--- a/third_party/zlib/BUILD.gn ++++ b/third_party/zlib/BUILD.gn +@@ -2,6 +2,10 @@ + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + ++if (current_cpu == "arm" || current_cpu == "arm64") { ++ import("//build/config/arm.gni") ++} ++ + config("zlib_config") { + include_dirs = [ "." ] + } +@@ -71,6 +75,20 @@ static_library("zlib") { + "zutil.h", + ] + ++ if (current_cpu == "arm" || current_cpu == "arm64") { ++ if (arm_use_neon) { ++ sources -= [ ++ "inflate.c", ++ "inffast.c", ++ ] ++ sources += [ ++ "contrib/arm/inflate.c", ++ "contrib/arm/inffast.c", ++ "contrib/arm/chunkcopy.h", ++ ] ++ } ++ } ++ + if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) { + sources += [ "x86.c" ] + } +diff --git a/third_party/zlib/README.chromium b/third_party/zlib/README.chromium +index 8658580..ff5c6ab 100644 +--- a/third_party/zlib/README.chromium ++++ b/third_party/zlib/README.chromium +@@ -28,3 +28,4 @@ Local Modifications: + https://github.com/jtkukunas/zlib/ + - 0002-uninitializedcheck.patch: default-initialize state->check, see + crbug.com/697481 ++ - 0003-arm-inffast.patch: ARM optimized inflate using NEON. +diff --git a/third_party/zlib/contrib/arm/chunkcopy.h b/third_party/zlib/contrib/arm/chunkcopy.h +new file mode 100644 +index 0000000..2d6fd6f +--- /dev/null ++++ b/third_party/zlib/contrib/arm/chunkcopy.h +@@ -0,0 +1,279 @@ ++/* chunkcopy.h -- fast copies and sets ++ * Copyright (C) 2017 ARM, Inc. ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#ifndef CHUNKCOPY_H ++#define CHUNKCOPY_H ++ ++#include "zutil.h" ++#include <arm_neon.h> ++ ++#if __STDC_VERSION__ >= 199901L ++#define Z_RESTRICT restrict ++#else ++#define Z_RESTRICT ++#endif ++ ++typedef uint8x16_t chunkcopy_chunk_t; ++#define CHUNKCOPY_CHUNK_SIZE sizeof(chunkcopy_chunk_t) ++ ++/* ++ Ask the compiler to perform a wide, unaligned load with an machine ++ instruction appropriate for the chunkcopy_chunk_t type. ++ */ ++static inline chunkcopy_chunk_t loadchunk(const unsigned char FAR *s) { ++ chunkcopy_chunk_t c; ++ __builtin_memcpy(&c, s, sizeof(c)); ++ return c; ++} ++ ++/* ++ Ask the compiler to perform a wide, unaligned store with an machine ++ instruction appropriate for the chunkcopy_chunk_t type. ++ */ ++static inline void storechunk(unsigned char FAR *d, chunkcopy_chunk_t c) { ++ __builtin_memcpy(d, &c, sizeof(c)); ++} ++ ++/* ++ Perform a memcpy-like operation, but assume that length is non-zero and that ++ it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if ++ the length is shorter than this. ++ ++ It also guarantees that it will properly unroll the data if the distance ++ between `out` and `from` is at least CHUNKCOPY_CHUNK_SIZE, which we rely on ++ in chunkcopy_relaxed(). ++ ++ Aside from better memory bus utilisation, this means that short copies ++ (CHUNKCOPY_CHUNK_SIZE bytes or fewer) will fall straight through the loop ++ without iteration, which will hopefully make the branch prediction more ++ reliable. ++ */ ++static inline unsigned char FAR *chunkcopy_core(unsigned char FAR *out, ++ const unsigned char FAR *from, ++ unsigned len) { ++ int bump = (--len % CHUNKCOPY_CHUNK_SIZE) + 1; ++ storechunk(out, loadchunk(from)); ++ out += bump; ++ from += bump; ++ len /= CHUNKCOPY_CHUNK_SIZE; ++ while (len-- > 0) { ++ storechunk(out, loadchunk(from)); ++ out += CHUNKCOPY_CHUNK_SIZE; ++ from += CHUNKCOPY_CHUNK_SIZE; ++ } ++ return out; ++} ++ ++/* ++ Like chunkcopy_core, but avoid writing beyond of legal output. ++ ++ Accepts an additional pointer to the end of safe output. A generic safe ++ copy would use (out + len), but it's normally the case that the end of the ++ output buffer is beyond the end of the current copy, and this can still be ++ exploited. ++ */ ++static inline unsigned char FAR *chunkcopy_core_safe(unsigned char FAR *out, ++ const unsigned char FAR * from, ++ unsigned len, ++ unsigned char FAR *limit) { ++ Assert(out + len <= limit, "chunk copy exceeds safety limit"); ++ if (limit - out < CHUNKCOPY_CHUNK_SIZE) { ++ const unsigned char FAR * Z_RESTRICT rfrom = from; ++ if (len & 8) { __builtin_memcpy(out, rfrom, 8); out += 8; rfrom += 8; } ++ if (len & 4) { __builtin_memcpy(out, rfrom, 4); out += 4; rfrom += 4; } ++ if (len & 2) { __builtin_memcpy(out, rfrom, 2); out += 2; rfrom += 2; } ++ if (len & 1) { *out++ = *rfrom++; } ++ return out; ++ } ++ return chunkcopy_core(out, from, len); ++} ++ ++/* ++ Perform short copies until distance can be rewritten as being at least ++ CHUNKCOPY_CHUNK_SIZE. ++ ++ This assumes that it's OK to overwrite at least the first ++ 2*CHUNKCOPY_CHUNK_SIZE bytes of output even if the copy is shorter than ++ this. This assumption holds within inflate_fast() which starts every ++ iteration with at least 258 bytes of output space available (258 being the ++ maximum length output from a single token; see inffast.c). ++ */ ++static inline unsigned char FAR *chunkunroll_relaxed(unsigned char FAR *out, ++ unsigned FAR *dist, ++ unsigned FAR *len) { ++ const unsigned char FAR *from = out - *dist; ++ while (*dist < *len && *dist < CHUNKCOPY_CHUNK_SIZE) { ++ storechunk(out, loadchunk(from)); ++ out += *dist; ++ *len -= *dist; ++ *dist += *dist; ++ } ++ return out; ++} ++ ++ ++static inline uint8x16_t chunkset_vld1q_dup_u8x8(const unsigned char FAR * Z_RESTRICT from) { ++#if defined(__clang__) || defined(__aarch64__) ++ return vreinterpretq_u8_u64(vld1q_dup_u64((void *)from)); ++#else ++ /* 32-bit GCC uses an alignment hint for vld1q_dup_u64, even when given a ++ * void pointer, so here's an alternate implementation. ++ */ ++ uint8x8_t h = vld1_u8(from); ++ return vcombine_u8(h, h); ++#endif ++} ++ ++/* ++ Perform an overlapping copy which behaves as a memset() operation, but ++ supporting periods other than one, and assume that length is non-zero and ++ that it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE*3 bytes of output ++ even if the length is shorter than this. ++ */ ++static inline unsigned char FAR *chunkset_core(unsigned char FAR *out, ++ unsigned period, ++ unsigned len) { ++ uint8x16_t f; ++ int bump = ((len - 1) % sizeof(f)) + 1; ++ ++ switch (period) { ++ case 1: ++ f = vld1q_dup_u8(out - 1); ++ vst1q_u8(out, f); ++ out += bump; ++ len -= bump; ++ while (len > 0) { ++ vst1q_u8(out, f); ++ out += sizeof(f); ++ len -= sizeof(f); ++ } ++ return out; ++ case 2: ++ f = vreinterpretq_u8_u16(vld1q_dup_u16((void *)(out - 2))); ++ vst1q_u8(out, f); ++ out += bump; ++ len -= bump; ++ if (len > 0) { ++ f = vreinterpretq_u8_u16(vld1q_dup_u16((void *)(out - 2))); ++ do { ++ vst1q_u8(out, f); ++ out += sizeof(f); ++ len -= sizeof(f); ++ } while (len > 0); ++ } ++ return out; ++ case 4: ++ f = vreinterpretq_u8_u32(vld1q_dup_u32((void *)(out - 4))); ++ vst1q_u8(out, f); ++ out += bump; ++ len -= bump; ++ if (len > 0) { ++ f = vreinterpretq_u8_u32(vld1q_dup_u32((void *)(out - 4))); ++ do { ++ vst1q_u8(out, f); ++ out += sizeof(f); ++ len -= sizeof(f); ++ } while (len > 0); ++ } ++ return out; ++ case 8: ++ f = chunkset_vld1q_dup_u8x8(out - 8); ++ vst1q_u8(out, f); ++ out += bump; ++ len -= bump; ++ if (len > 0) { ++ f = chunkset_vld1q_dup_u8x8(out - 8); ++ do { ++ vst1q_u8(out, f); ++ out += sizeof(f); ++ len -= sizeof(f); ++ } while (len > 0); ++ } ++ return out; ++ } ++ out = chunkunroll_relaxed(out, &period, &len); ++ return chunkcopy_core(out, out - period, len); ++} ++ ++/* ++ Perform a memcpy-like operation, but assume that length is non-zero and that ++ it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if ++ the length is shorter than this. ++ ++ Unlike chunkcopy_core() above, no guarantee is made regarding the behaviour ++ of overlapping buffers, regardless of the distance between the pointers. ++ This is reflected in the `restrict`-qualified pointers, allowing the ++ compiler to reorder loads and stores. ++ */ ++static inline unsigned char FAR *chunkcopy_relaxed(unsigned char FAR * Z_RESTRICT out, ++ const unsigned char FAR * Z_RESTRICT from, ++ unsigned len) { ++ return chunkcopy_core(out, from, len); ++} ++ ++/* ++ Like chunkcopy_relaxed, but avoid writing beyond of legal output. ++ ++ Unlike chunkcopy_core_safe() above, no guarantee is made regarding the ++ behaviour of overlapping buffers, regardless of the distance between the ++ pointers. This is reflected in the `restrict`-qualified pointers, allowing ++ the compiler to reorder loads and stores. ++ ++ Accepts an additional pointer to the end of safe output. A generic safe ++ copy would use (out + len), but it's normally the case that the end of the ++ output buffer is beyond the end of the current copy, and this can still be ++ exploited. ++ */ ++static inline unsigned char FAR *chunkcopy_safe(unsigned char FAR *out, ++ const unsigned char FAR * Z_RESTRICT from, ++ unsigned len, ++ unsigned char FAR *limit) { ++ Assert(out + len <= limit, "chunk copy exceeds safety limit"); ++ return chunkcopy_core_safe(out, from, len, limit); ++} ++ ++/* ++ Perform chunky copy within the same buffer, where the source and destination ++ may potentially overlap. ++ ++ Assumes that len > 0 on entry, and that it's safe to write at least ++ CHUNKCOPY_CHUNK_SIZE*3 bytes to the output. ++ */ ++static inline unsigned char FAR *chunkcopy_lapped_relaxed(unsigned char FAR *out, ++ unsigned dist, ++ unsigned len) { ++ if (dist < len && dist < CHUNKCOPY_CHUNK_SIZE) { ++ return chunkset_core(out, dist, len); ++ } ++ return chunkcopy_core(out, out - dist, len); ++} ++ ++/* ++ Behave like chunkcopy_lapped_relaxed, but avoid writing beyond of legal output. ++ ++ Accepts an additional pointer to the end of safe output. A generic safe ++ copy would use (out + len), but it's normally the case that the end of the ++ output buffer is beyond the end of the current copy, and this can still be ++ exploited. ++ */ ++static inline unsigned char FAR *chunkcopy_lapped_safe(unsigned char FAR *out, ++ unsigned dist, ++ unsigned len, ++ unsigned char FAR *limit) { ++ Assert(out + len <= limit, "chunk copy exceeds safety limit"); ++ if (limit - out < CHUNKCOPY_CHUNK_SIZE * 3) { ++ /* TODO: try harder to optimise this */ ++ while (len-- > 0) { ++ *out = *(out - dist); ++ out++; ++ } ++ return out; ++ } ++ return chunkcopy_lapped_relaxed(out, dist, len); ++} ++ ++#undef Z_RESTRICT ++ ++#endif /* CHUNKCOPY_H */ +diff --git a/third_party/zlib/contrib/arm/inffast.c b/third_party/zlib/contrib/arm/inffast.c +new file mode 100644 +index 0000000..f7f5007 +--- /dev/null ++++ b/third_party/zlib/contrib/arm/inffast.c +@@ -0,0 +1,307 @@ ++/* inffast.c -- fast decoding ++ * Copyright (C) 1995-2017 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++#include "zutil.h" ++#include "inftrees.h" ++#include "inflate.h" ++#include "inffast.h" ++#include "chunkcopy.h" ++ ++#ifdef ASMINF ++# pragma message("Assembler code may have bugs -- use at your own risk") ++#else ++ ++/* ++ Decode literal, length, and distance codes and write out the resulting ++ literal and match bytes until either not enough input or output is ++ available, an end-of-block is encountered, or a data error is encountered. ++ When large enough input and output buffers are supplied to inflate(), for ++ example, a 16K input buffer and a 64K output buffer, more than 95% of the ++ inflate execution time is spent in this routine. ++ ++ Entry assumptions: ++ ++ state->mode == LEN ++ strm->avail_in >= 6 ++ strm->avail_out >= 258 ++ start >= strm->avail_out ++ state->bits < 8 ++ ++ On return, state->mode is one of: ++ ++ LEN -- ran out of enough output space or enough available input ++ TYPE -- reached end of block code, inflate() to interpret next block ++ BAD -- error in block data ++ ++ Notes: ++ ++ - The maximum input bits used by a length/distance pair is 15 bits for the ++ length code, 5 bits for the length extra, 15 bits for the distance code, ++ and 13 bits for the distance extra. This totals 48 bits, or six bytes. ++ Therefore if strm->avail_in >= 6, then there is enough input to avoid ++ checking for available input while decoding. ++ ++ - The maximum bytes that a single length/distance pair can output is 258 ++ bytes, which is the maximum length that can be coded. inflate_fast() ++ requires strm->avail_out >= 258 for each loop to avoid checking for ++ output space. ++ */ ++void ZLIB_INTERNAL inflate_fast(strm, start) ++z_streamp strm; ++unsigned start; /* inflate()'s starting value for strm->avail_out */ ++{ ++ struct inflate_state FAR *state; ++ z_const unsigned char FAR *in; /* local strm->next_in */ ++ z_const unsigned char FAR *last; /* have enough input while in < last */ ++ unsigned char FAR *out; /* local strm->next_out */ ++ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ ++ unsigned char FAR *end; /* while out < end, enough space available */ ++ unsigned char FAR *limit; /* safety limit for chunky copies */ ++#ifdef INFLATE_STRICT ++ unsigned dmax; /* maximum distance from zlib header */ ++#endif ++ unsigned wsize; /* window size or zero if not using window */ ++ unsigned whave; /* valid bytes in the window */ ++ unsigned wnext; /* window write index */ ++ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ ++ unsigned long hold; /* local strm->hold */ ++ unsigned bits; /* local strm->bits */ ++ code const FAR *lcode; /* local strm->lencode */ ++ code const FAR *dcode; /* local strm->distcode */ ++ unsigned lmask; /* mask for first level of length codes */ ++ unsigned dmask; /* mask for first level of distance codes */ ++ code here; /* retrieved table entry */ ++ unsigned op; /* code bits, operation, extra bits, or */ ++ /* window position, window bytes to copy */ ++ unsigned len; /* match length, unused bytes */ ++ unsigned dist; /* match distance */ ++ unsigned char FAR *from; /* where to copy match from */ ++ ++ /* copy state to local variables */ ++ state = (struct inflate_state FAR *)strm->state; ++ in = strm->next_in; ++ last = in + (strm->avail_in - 5); ++ out = strm->next_out; ++ beg = out - (start - strm->avail_out); ++ end = out + (strm->avail_out - 257); ++ limit = out + strm->avail_out; ++#ifdef INFLATE_STRICT ++ dmax = state->dmax; ++#endif ++ wsize = state->wsize; ++ whave = state->whave; ++ wnext = (state->wnext == 0 && whave >= wsize) ? wsize : state->wnext; ++ window = state->window; ++ hold = state->hold; ++ bits = state->bits; ++ lcode = state->lencode; ++ dcode = state->distcode; ++ lmask = (1U << state->lenbits) - 1; ++ dmask = (1U << state->distbits) - 1; ++ ++ /* decode literals and length/distances until end-of-block or not enough ++ input data or output space */ ++ do { ++ if (bits < 15) { ++ hold += (unsigned long)(*in++) << bits; ++ bits += 8; ++ hold += (unsigned long)(*in++) << bits; ++ bits += 8; ++ } ++ here = lcode[hold & lmask]; ++ dolen: ++ op = (unsigned)(here.bits); ++ hold >>= op; ++ bits -= op; ++ op = (unsigned)(here.op); ++ if (op == 0) { /* literal */ ++ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? ++ "inflate: literal '%c'\n" : ++ "inflate: literal 0x%02x\n", here.val)); ++ *out++ = (unsigned char)(here.val); ++ } ++ else if (op & 16) { /* length base */ ++ len = (unsigned)(here.val); ++ op &= 15; /* number of extra bits */ ++ if (op) { ++ if (bits < op) { ++ hold += (unsigned long)(*in++) << bits; ++ bits += 8; ++ } ++ len += (unsigned)hold & ((1U << op) - 1); ++ hold >>= op; ++ bits -= op; ++ } ++ Tracevv((stderr, "inflate: length %u\n", len)); ++ if (bits < 15) { ++ hold += (unsigned long)(*in++) << bits; ++ bits += 8; ++ hold += (unsigned long)(*in++) << bits; ++ bits += 8; ++ } ++ here = dcode[hold & dmask]; ++ dodist: ++ op = (unsigned)(here.bits); ++ hold >>= op; ++ bits -= op; ++ op = (unsigned)(here.op); ++ if (op & 16) { /* distance base */ ++ dist = (unsigned)(here.val); ++ op &= 15; /* number of extra bits */ ++ if (bits < op) { ++ hold += (unsigned long)(*in++) << bits; ++ bits += 8; ++ if (bits < op) { ++ hold += (unsigned long)(*in++) << bits; ++ bits += 8; ++ } ++ } ++ dist += (unsigned)hold & ((1U << op) - 1); ++#ifdef INFLATE_STRICT ++ if (dist > dmax) { ++ strm->msg = (char *)"invalid distance too far back"; ++ state->mode = BAD; ++ break; ++ } ++#endif ++ hold >>= op; ++ bits -= op; ++ Tracevv((stderr, "inflate: distance %u\n", dist)); ++ op = (unsigned)(out - beg); /* max distance in output */ ++ if (dist > op) { /* see if copy from window */ ++ op = dist - op; /* distance back in window */ ++ if (op > whave) { ++ if (state->sane) { ++ strm->msg = ++ (char *)"invalid distance too far back"; ++ state->mode = BAD; ++ break; ++ } ++#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR ++ if (len <= op - whave) { ++ do { ++ *out++ = 0; ++ } while (--len); ++ continue; ++ } ++ len -= op - whave; ++ do { ++ *out++ = 0; ++ } while (--op > whave); ++ if (op == 0) { ++ from = out - dist; ++ do { ++ *out++ = *from++; ++ } while (--len); ++ continue; ++ } ++#endif ++ } ++ from = window; ++ if (wnext >= op) { /* contiguous in window */ ++ from += wnext - op; ++ } ++ else { /* wrap around window */ ++ op -= wnext; ++ from += wsize - op; ++ if (op < len) { /* some from end of window */ ++ len -= op; ++ out = chunkcopy_safe(out, from, op, limit); ++ from = window; /* more from start of window */ ++ op = wnext; ++ /* This (rare) case can create a situation where ++ the first chunkcopy below must be checked. ++ */ ++ } ++ } ++ if (op < len) { /* still need some from output */ ++ out = chunkcopy_safe(out, from, op, limit); ++ len -= op; ++ /* When dist is small the amount of data that can be ++ copied from the window is also small, and progress ++ towards the dangerous end of the output buffer is ++ also small. This means that for trivial memsets and ++ for chunkunroll_relaxed() a safety check is ++ unnecessary. However, these conditions may not be ++ entered at all, and in that case it's possible that ++ the main copy is near the end. ++ */ ++ out = chunkunroll_relaxed(out, &dist, &len); ++ out = chunkcopy_safe(out, out - dist, len, limit); ++ } else { ++ /* from points to window, so there is no risk of ++ overlapping pointers requiring memset-like behaviour ++ */ ++ out = chunkcopy_safe(out, from, len, limit); ++ } ++ } ++ else { ++ /* Whole reference is in range of current output. No ++ range checks are necessary because we start with room ++ for at least 258 bytes of output, so unroll and roundoff ++ operations can write beyond `out+len` so long as they ++ stay within 258 bytes of `out`. ++ */ ++ out = chunkcopy_lapped_relaxed(out, dist, len); ++ } ++ } ++ else if ((op & 64) == 0) { /* 2nd level distance code */ ++ here = dcode[here.val + (hold & ((1U << op) - 1))]; ++ goto dodist; ++ } ++ else { ++ strm->msg = (char *)"invalid distance code"; ++ state->mode = BAD; ++ break; ++ } ++ } ++ else if ((op & 64) == 0) { /* 2nd level length code */ ++ here = lcode[here.val + (hold & ((1U << op) - 1))]; ++ goto dolen; ++ } ++ else if (op & 32) { /* end-of-block */ ++ Tracevv((stderr, "inflate: end of block\n")); ++ state->mode = TYPE; ++ break; ++ } ++ else { ++ strm->msg = (char *)"invalid literal/length code"; ++ state->mode = BAD; ++ break; ++ } ++ } while (in < last && out < end); ++ ++ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ ++ len = bits >> 3; ++ in -= len; ++ bits -= len << 3; ++ hold &= (1U << bits) - 1; ++ ++ /* update state and return */ ++ strm->next_in = in; ++ strm->next_out = out; ++ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); ++ strm->avail_out = (unsigned)(out < end ? ++ 257 + (end - out) : 257 - (out - end)); ++ state->hold = hold; ++ state->bits = bits; ++ return; ++} ++ ++/* ++ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): ++ - Using bit fields for code structure ++ - Different op definition to avoid & for extra bits (do & for table bits) ++ - Three separate decoding do-loops for direct, window, and wnext == 0 ++ - Special case for distance > 1 copies to do overlapped load and store copy ++ - Explicit branch predictions (based on measured branch probabilities) ++ - Deferring match copy and interspersed it with decoding subsequent codes ++ - Swapping literal/length else ++ - Swapping window/direct else ++ - Larger unrolled copy loops (three is about right) ++ - Moving len -= 3 statement into middle of loop ++ */ ++ ++#endif /* !ASMINF */ +diff --git a/third_party/zlib/contrib/arm/inflate.c b/third_party/zlib/contrib/arm/inflate.c +new file mode 100644 +index 0000000..e40322c +--- /dev/null ++++ b/third_party/zlib/contrib/arm/inflate.c +@@ -0,0 +1,1571 @@ ++/* inflate.c -- zlib decompression ++ * Copyright (C) 1995-2016 Mark Adler ++ * For conditions of distribution and use, see copyright notice in zlib.h ++ */ ++ ++/* ++ * Change history: ++ * ++ * 1.2.beta0 24 Nov 2002 ++ * - First version -- complete rewrite of inflate to simplify code, avoid ++ * creation of window when not needed, minimize use of window when it is ++ * needed, make inffast.c even faster, implement gzip decoding, and to ++ * improve code readability and style over the previous zlib inflate code ++ * ++ * 1.2.beta1 25 Nov 2002 ++ * - Use pointers for available input and output checking in inffast.c ++ * - Remove input and output counters in inffast.c ++ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 ++ * - Remove unnecessary second byte pull from length extra in inffast.c ++ * - Unroll direct copy to three copies per loop in inffast.c ++ * ++ * 1.2.beta2 4 Dec 2002 ++ * - Change external routine names to reduce potential conflicts ++ * - Correct filename to inffixed.h for fixed tables in inflate.c ++ * - Make hbuf[] unsigned char to match parameter type in inflate.c ++ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) ++ * to avoid negation problem on Alphas (64 bit) in inflate.c ++ * ++ * 1.2.beta3 22 Dec 2002 ++ * - Add comments on state->bits assertion in inffast.c ++ * - Add comments on op field in inftrees.h ++ * - Fix bug in reuse of allocated window after inflateReset() ++ * - Remove bit fields--back to byte structure for speed ++ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths ++ * - Change post-increments to pre-increments in inflate_fast(), PPC biased? ++ * - Add compile time option, POSTINC, to use post-increments instead (Intel?) ++ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used ++ * - Use local copies of stream next and avail values, as well as local bit ++ * buffer and bit count in inflate()--for speed when inflate_fast() not used ++ * ++ * 1.2.beta4 1 Jan 2003 ++ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings ++ * - Move a comment on output buffer sizes from inffast.c to inflate.c ++ * - Add comments in inffast.c to introduce the inflate_fast() routine ++ * - Rearrange window copies in inflate_fast() for speed and simplification ++ * - Unroll last copy for window match in inflate_fast() ++ * - Use local copies of window variables in inflate_fast() for speed ++ * - Pull out common wnext == 0 case for speed in inflate_fast() ++ * - Make op and len in inflate_fast() unsigned for consistency ++ * - Add FAR to lcode and dcode declarations in inflate_fast() ++ * - Simplified bad distance check in inflate_fast() ++ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new ++ * source file infback.c to provide a call-back interface to inflate for ++ * programs like gzip and unzip -- uses window as output buffer to avoid ++ * window copying ++ * ++ * 1.2.beta5 1 Jan 2003 ++ * - Improved inflateBack() interface to allow the caller to provide initial ++ * input in strm. ++ * - Fixed stored blocks bug in inflateBack() ++ * ++ * 1.2.beta6 4 Jan 2003 ++ * - Added comments in inffast.c on effectiveness of POSTINC ++ * - Typecasting all around to reduce compiler warnings ++ * - Changed loops from while (1) or do {} while (1) to for (;;), again to ++ * make compilers happy ++ * - Changed type of window in inflateBackInit() to unsigned char * ++ * ++ * 1.2.beta7 27 Jan 2003 ++ * - Changed many types to unsigned or unsigned short to avoid warnings ++ * - Added inflateCopy() function ++ * ++ * 1.2.0 9 Mar 2003 ++ * - Changed inflateBack() interface to provide separate opaque descriptors ++ * for the in() and out() functions ++ * - Changed inflateBack() argument and in_func typedef to swap the length ++ * and buffer address return values for the input function ++ * - Check next_in and next_out for Z_NULL on entry to inflate() ++ * ++ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. ++ */ ++ ++#include "zutil.h" ++#include "inftrees.h" ++#include "inflate.h" ++#include "inffast.h" ++#include "contrib/arm/chunkcopy.h" ++ ++#ifdef MAKEFIXED ++# ifndef BUILDFIXED ++# define BUILDFIXED ++# endif ++#endif ++ ++/* function prototypes */ ++local int inflateStateCheck OF((z_streamp strm)); ++local void fixedtables OF((struct inflate_state FAR *state)); ++local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, ++ unsigned copy)); ++#ifdef BUILDFIXED ++ void makefixed OF((void)); ++#endif ++local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, ++ unsigned len)); ++ ++local int inflateStateCheck(strm) ++z_streamp strm; ++{ ++ struct inflate_state FAR *state; ++ if (strm == Z_NULL || ++ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) ++ return 1; ++ state = (struct inflate_state FAR *)strm->state; ++ if (state == Z_NULL || state->strm != strm || ++ state->mode < HEAD || state->mode > SYNC) ++ return 1; ++ return 0; ++} ++ ++int ZEXPORT inflateResetKeep(strm) ++z_streamp strm; ++{ ++ struct inflate_state FAR *state; ++ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ strm->total_in = strm->total_out = state->total = 0; ++ strm->msg = Z_NULL; ++ if (state->wrap) /* to support ill-conceived Java test suite */ ++ strm->adler = state->wrap & 1; ++ state->mode = HEAD; ++ state->last = 0; ++ state->havedict = 0; ++ state->dmax = 32768U; ++ state->head = Z_NULL; ++ state->hold = 0; ++ state->bits = 0; ++ state->lencode = state->distcode = state->next = state->codes; ++ state->sane = 1; ++ state->back = -1; ++ Tracev((stderr, "inflate: reset\n")); ++ return Z_OK; ++} ++ ++int ZEXPORT inflateReset(strm) ++z_streamp strm; ++{ ++ struct inflate_state FAR *state; ++ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ state->wsize = 0; ++ state->whave = 0; ++ state->wnext = 0; ++ return inflateResetKeep(strm); ++} ++ ++int ZEXPORT inflateReset2(strm, windowBits) ++z_streamp strm; ++int windowBits; ++{ ++ int wrap; ++ struct inflate_state FAR *state; ++ ++ /* get the state */ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ ++ /* extract wrap request from windowBits parameter */ ++ if (windowBits < 0) { ++ wrap = 0; ++ windowBits = -windowBits; ++ } ++ else { ++ wrap = (windowBits >> 4) + 5; ++#ifdef GUNZIP ++ if (windowBits < 48) ++ windowBits &= 15; ++#endif ++ } ++ ++ /* set number of window bits, free window if different */ ++ if (windowBits && (windowBits < 8 || windowBits > 15)) ++ return Z_STREAM_ERROR; ++ if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { ++ ZFREE(strm, state->window); ++ state->window = Z_NULL; ++ } ++ ++ /* update state and reset the rest of it */ ++ state->wrap = wrap; ++ state->wbits = (unsigned)windowBits; ++ return inflateReset(strm); ++} ++ ++int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) ++z_streamp strm; ++int windowBits; ++const char *version; ++int stream_size; ++{ ++ int ret; ++ struct inflate_state FAR *state; ++ ++ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || ++ stream_size != (int)(sizeof(z_stream))) ++ return Z_VERSION_ERROR; ++ if (strm == Z_NULL) return Z_STREAM_ERROR; ++ strm->msg = Z_NULL; /* in case we return an error */ ++ if (strm->zalloc == (alloc_func)0) { ++#ifdef Z_SOLO ++ return Z_STREAM_ERROR; ++#else ++ strm->zalloc = zcalloc; ++ strm->opaque = (voidpf)0; ++#endif ++ } ++ if (strm->zfree == (free_func)0) ++#ifdef Z_SOLO ++ return Z_STREAM_ERROR; ++#else ++ strm->zfree = zcfree; ++#endif ++ state = (struct inflate_state FAR *) ++ ZALLOC(strm, 1, sizeof(struct inflate_state)); ++ if (state == Z_NULL) return Z_MEM_ERROR; ++ Tracev((stderr, "inflate: allocated\n")); ++ strm->state = (struct internal_state FAR *)state; ++ state->strm = strm; ++ state->window = Z_NULL; ++ state->mode = HEAD; /* to pass state test in inflateReset2() */ ++ ret = inflateReset2(strm, windowBits); ++ if (ret != Z_OK) { ++ ZFREE(strm, state); ++ strm->state = Z_NULL; ++ } ++ return ret; ++} ++ ++int ZEXPORT inflateInit_(strm, version, stream_size) ++z_streamp strm; ++const char *version; ++int stream_size; ++{ ++ return inflateInit2_(strm, DEF_WBITS, version, stream_size); ++} ++ ++int ZEXPORT inflatePrime(strm, bits, value) ++z_streamp strm; ++int bits; ++int value; ++{ ++ struct inflate_state FAR *state; ++ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ if (bits < 0) { ++ state->hold = 0; ++ state->bits = 0; ++ return Z_OK; ++ } ++ if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; ++ value &= (1L << bits) - 1; ++ state->hold += (unsigned)value << state->bits; ++ state->bits += (uInt)bits; ++ return Z_OK; ++} ++ ++/* ++ Return state with length and distance decoding tables and index sizes set to ++ fixed code decoding. Normally this returns fixed tables from inffixed.h. ++ If BUILDFIXED is defined, then instead this routine builds the tables the ++ first time it's called, and returns those tables the first time and ++ thereafter. This reduces the size of the code by about 2K bytes, in ++ exchange for a little execution time. However, BUILDFIXED should not be ++ used for threaded applications, since the rewriting of the tables and virgin ++ may not be thread-safe. ++ */ ++local void fixedtables(state) ++struct inflate_state FAR *state; ++{ ++#ifdef BUILDFIXED ++ static int virgin = 1; ++ static code *lenfix, *distfix; ++ static code fixed[544]; ++ ++ /* build fixed huffman tables if first call (may not be thread safe) */ ++ if (virgin) { ++ unsigned sym, bits; ++ static code *next; ++ ++ /* literal/length table */ ++ sym = 0; ++ while (sym < 144) state->lens[sym++] = 8; ++ while (sym < 256) state->lens[sym++] = 9; ++ while (sym < 280) state->lens[sym++] = 7; ++ while (sym < 288) state->lens[sym++] = 8; ++ next = fixed; ++ lenfix = next; ++ bits = 9; ++ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); ++ ++ /* distance table */ ++ sym = 0; ++ while (sym < 32) state->lens[sym++] = 5; ++ distfix = next; ++ bits = 5; ++ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); ++ ++ /* do this just once */ ++ virgin = 0; ++ } ++#else /* !BUILDFIXED */ ++# include "inffixed.h" ++#endif /* BUILDFIXED */ ++ state->lencode = lenfix; ++ state->lenbits = 9; ++ state->distcode = distfix; ++ state->distbits = 5; ++} ++ ++#ifdef MAKEFIXED ++#include <stdio.h> ++ ++/* ++ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also ++ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes ++ those tables to stdout, which would be piped to inffixed.h. A small program ++ can simply call makefixed to do this: ++ ++ void makefixed(void); ++ ++ int main(void) ++ { ++ makefixed(); ++ return 0; ++ } ++ ++ Then that can be linked with zlib built with MAKEFIXED defined and run: ++ ++ a.out > inffixed.h ++ */ ++void makefixed() ++{ ++ unsigned low, size; ++ struct inflate_state state; ++ ++ fixedtables(&state); ++ puts(" /* inffixed.h -- table for decoding fixed codes"); ++ puts(" * Generated automatically by makefixed()."); ++ puts(" */"); ++ puts(""); ++ puts(" /* WARNING: this file should *not* be used by applications."); ++ puts(" It is part of the implementation of this library and is"); ++ puts(" subject to change. Applications should only use zlib.h."); ++ puts(" */"); ++ puts(""); ++ size = 1U << 9; ++ printf(" static const code lenfix[%u] = {", size); ++ low = 0; ++ for (;;) { ++ if ((low % 7) == 0) printf("\n "); ++ printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, ++ state.lencode[low].bits, state.lencode[low].val); ++ if (++low == size) break; ++ putchar(','); ++ } ++ puts("\n };"); ++ size = 1U << 5; ++ printf("\n static const code distfix[%u] = {", size); ++ low = 0; ++ for (;;) { ++ if ((low % 6) == 0) printf("\n "); ++ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, ++ state.distcode[low].val); ++ if (++low == size) break; ++ putchar(','); ++ } ++ puts("\n };"); ++} ++#endif /* MAKEFIXED */ ++ ++/* ++ Update the window with the last wsize (normally 32K) bytes written before ++ returning. If window does not exist yet, create it. This is only called ++ when a window is already in use, or when output has been written during this ++ inflate call, but the end of the deflate stream has not been reached yet. ++ It is also called to create a window for dictionary data when a dictionary ++ is loaded. ++ ++ Providing output buffers larger than 32K to inflate() should provide a speed ++ advantage, since only the last 32K of output is copied to the sliding window ++ upon return from inflate(), and since all distances after the first 32K of ++ output will fall in the output data, making match copies simpler and faster. ++ The advantage may be dependent on the size of the processor's data caches. ++ */ ++local int updatewindow(strm, end, copy) ++z_streamp strm; ++const Bytef *end; ++unsigned copy; ++{ ++ struct inflate_state FAR *state; ++ unsigned dist; ++ ++ state = (struct inflate_state FAR *)strm->state; ++ ++ /* if it hasn't been done already, allocate space for the window */ ++ if (state->window == Z_NULL) { ++ unsigned wsize = 1U << state->wbits; ++ state->window = (unsigned char FAR *) ++ ZALLOC(strm, wsize + CHUNKCOPY_CHUNK_SIZE, ++ sizeof(unsigned char)); ++ if (state->window == Z_NULL) return 1; ++#ifdef INFLATE_CLEAR_UNUSED_UNDEFINED ++ /* Copies from the overflow portion of this buffer are undefined and ++ may cause analysis tools to raise a warning if we don't initialize ++ it. However, this undefined data overwrites other undefined data ++ and is subsequently either overwritten or left deliberately ++ undefined at the end of decode; so there's really no point. ++ */ ++ memset(state->window + wsize, 0, CHUNKCOPY_CHUNK_SIZE); ++#endif ++ } ++ ++ /* if window not in use yet, initialize */ ++ if (state->wsize == 0) { ++ state->wsize = 1U << state->wbits; ++ state->wnext = 0; ++ state->whave = 0; ++ } ++ ++ /* copy state->wsize or less output bytes into the circular window */ ++ if (copy >= state->wsize) { ++ zmemcpy(state->window, end - state->wsize, state->wsize); ++ state->wnext = 0; ++ state->whave = state->wsize; ++ } ++ else { ++ dist = state->wsize - state->wnext; ++ if (dist > copy) dist = copy; ++ zmemcpy(state->window + state->wnext, end - copy, dist); ++ copy -= dist; ++ if (copy) { ++ zmemcpy(state->window, end - copy, copy); ++ state->wnext = copy; ++ state->whave = state->wsize; ++ } ++ else { ++ state->wnext += dist; ++ if (state->wnext == state->wsize) state->wnext = 0; ++ if (state->whave < state->wsize) state->whave += dist; ++ } ++ } ++ return 0; ++} ++ ++/* Macros for inflate(): */ ++ ++/* check function to use adler32() for zlib or crc32() for gzip */ ++#ifdef GUNZIP ++# define UPDATE(check, buf, len) \ ++ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) ++#else ++# define UPDATE(check, buf, len) adler32(check, buf, len) ++#endif ++ ++/* check macros for header crc */ ++#ifdef GUNZIP ++# define CRC2(check, word) \ ++ do { \ ++ hbuf[0] = (unsigned char)(word); \ ++ hbuf[1] = (unsigned char)((word) >> 8); \ ++ check = crc32(check, hbuf, 2); \ ++ } while (0) ++ ++# define CRC4(check, word) \ ++ do { \ ++ hbuf[0] = (unsigned char)(word); \ ++ hbuf[1] = (unsigned char)((word) >> 8); \ ++ hbuf[2] = (unsigned char)((word) >> 16); \ ++ hbuf[3] = (unsigned char)((word) >> 24); \ ++ check = crc32(check, hbuf, 4); \ ++ } while (0) ++#endif ++ ++/* Load registers with state in inflate() for speed */ ++#define LOAD() \ ++ do { \ ++ put = strm->next_out; \ ++ left = strm->avail_out; \ ++ next = strm->next_in; \ ++ have = strm->avail_in; \ ++ hold = state->hold; \ ++ bits = state->bits; \ ++ } while (0) ++ ++/* Restore state from registers in inflate() */ ++#define RESTORE() \ ++ do { \ ++ strm->next_out = put; \ ++ strm->avail_out = left; \ ++ strm->next_in = next; \ ++ strm->avail_in = have; \ ++ state->hold = hold; \ ++ state->bits = bits; \ ++ } while (0) ++ ++/* Clear the input bit accumulator */ ++#define INITBITS() \ ++ do { \ ++ hold = 0; \ ++ bits = 0; \ ++ } while (0) ++ ++/* Get a byte of input into the bit accumulator, or return from inflate() ++ if there is no input available. */ ++#define PULLBYTE() \ ++ do { \ ++ if (have == 0) goto inf_leave; \ ++ have--; \ ++ hold += (unsigned long)(*next++) << bits; \ ++ bits += 8; \ ++ } while (0) ++ ++/* Assure that there are at least n bits in the bit accumulator. If there is ++ not enough available input to do that, then return from inflate(). */ ++#define NEEDBITS(n) \ ++ do { \ ++ while (bits < (unsigned)(n)) \ ++ PULLBYTE(); \ ++ } while (0) ++ ++/* Return the low n bits of the bit accumulator (n < 16) */ ++#define BITS(n) \ ++ ((unsigned)hold & ((1U << (n)) - 1)) ++ ++/* Remove n bits from the bit accumulator */ ++#define DROPBITS(n) \ ++ do { \ ++ hold >>= (n); \ ++ bits -= (unsigned)(n); \ ++ } while (0) ++ ++/* Remove zero to seven bits as needed to go to a byte boundary */ ++#define BYTEBITS() \ ++ do { \ ++ hold >>= bits & 7; \ ++ bits -= bits & 7; \ ++ } while (0) ++ ++/* ++ inflate() uses a state machine to process as much input data and generate as ++ much output data as possible before returning. The state machine is ++ structured roughly as follows: ++ ++ for (;;) switch (state) { ++ ... ++ case STATEn: ++ if (not enough input data or output space to make progress) ++ return; ++ ... make progress ... ++ state = STATEm; ++ break; ++ ... ++ } ++ ++ so when inflate() is called again, the same case is attempted again, and ++ if the appropriate resources are provided, the machine proceeds to the ++ next state. The NEEDBITS() macro is usually the way the state evaluates ++ whether it can proceed or should return. NEEDBITS() does the return if ++ the requested bits are not available. The typical use of the BITS macros ++ is: ++ ++ NEEDBITS(n); ++ ... do something with BITS(n) ... ++ DROPBITS(n); ++ ++ where NEEDBITS(n) either returns from inflate() if there isn't enough ++ input left to load n bits into the accumulator, or it continues. BITS(n) ++ gives the low n bits in the accumulator. When done, DROPBITS(n) drops ++ the low n bits off the accumulator. INITBITS() clears the accumulator ++ and sets the number of available bits to zero. BYTEBITS() discards just ++ enough bits to put the accumulator on a byte boundary. After BYTEBITS() ++ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. ++ ++ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return ++ if there is no input available. The decoding of variable length codes uses ++ PULLBYTE() directly in order to pull just enough bytes to decode the next ++ code, and no more. ++ ++ Some states loop until they get enough input, making sure that enough ++ state information is maintained to continue the loop where it left off ++ if NEEDBITS() returns in the loop. For example, want, need, and keep ++ would all have to actually be part of the saved state in case NEEDBITS() ++ returns: ++ ++ case STATEw: ++ while (want < need) { ++ NEEDBITS(n); ++ keep[want++] = BITS(n); ++ DROPBITS(n); ++ } ++ state = STATEx; ++ case STATEx: ++ ++ As shown above, if the next state is also the next case, then the break ++ is omitted. ++ ++ A state may also return if there is not enough output space available to ++ complete that state. Those states are copying stored data, writing a ++ literal byte, and copying a matching string. ++ ++ When returning, a "goto inf_leave" is used to update the total counters, ++ update the check value, and determine whether any progress has been made ++ during that inflate() call in order to return the proper return code. ++ Progress is defined as a change in either strm->avail_in or strm->avail_out. ++ When there is a window, goto inf_leave will update the window with the last ++ output written. If a goto inf_leave occurs in the middle of decompression ++ and there is no window currently, goto inf_leave will create one and copy ++ output to the window for the next call of inflate(). ++ ++ In this implementation, the flush parameter of inflate() only affects the ++ return code (per zlib.h). inflate() always writes as much as possible to ++ strm->next_out, given the space available and the provided input--the effect ++ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers ++ the allocation of and copying into a sliding window until necessary, which ++ provides the effect documented in zlib.h for Z_FINISH when the entire input ++ stream available. So the only thing the flush parameter actually does is: ++ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it ++ will return Z_BUF_ERROR if it has not reached the end of the stream. ++ */ ++ ++int ZEXPORT inflate(strm, flush) ++z_streamp strm; ++int flush; ++{ ++ struct inflate_state FAR *state; ++ z_const unsigned char FAR *next; /* next input */ ++ unsigned char FAR *put; /* next output */ ++ unsigned have, left; /* available input and output */ ++ unsigned long hold; /* bit buffer */ ++ unsigned bits; /* bits in bit buffer */ ++ unsigned in, out; /* save starting available input and output */ ++ unsigned copy; /* number of stored or match bytes to copy */ ++ unsigned char FAR *from; /* where to copy match bytes from */ ++ code here; /* current decoding table entry */ ++ code last; /* parent table entry */ ++ unsigned len; /* length to copy for repeats, bits to drop */ ++ int ret; /* return code */ ++#ifdef GUNZIP ++ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ ++#endif ++ static const unsigned short order[19] = /* permutation of code lengths */ ++ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; ++ ++ if (inflateStateCheck(strm) || strm->next_out == Z_NULL || ++ (strm->next_in == Z_NULL && strm->avail_in != 0)) ++ return Z_STREAM_ERROR; ++ ++ state = (struct inflate_state FAR *)strm->state; ++ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ ++ LOAD(); ++ in = have; ++ out = left; ++ ret = Z_OK; ++ for (;;) ++ switch (state->mode) { ++ case HEAD: ++ if (state->wrap == 0) { ++ state->mode = TYPEDO; ++ break; ++ } ++ NEEDBITS(16); ++#ifdef GUNZIP ++ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ ++ if (state->wbits == 0) ++ state->wbits = 15; ++ state->check = crc32(0L, Z_NULL, 0); ++ CRC2(state->check, hold); ++ INITBITS(); ++ state->mode = FLAGS; ++ break; ++ } ++ state->flags = 0; /* expect zlib header */ ++ if (state->head != Z_NULL) ++ state->head->done = -1; ++ if (!(state->wrap & 1) || /* check if zlib header allowed */ ++#else ++ if ( ++#endif ++ ((BITS(8) << 8) + (hold >> 8)) % 31) { ++ strm->msg = (char *)"incorrect header check"; ++ state->mode = BAD; ++ break; ++ } ++ if (BITS(4) != Z_DEFLATED) { ++ strm->msg = (char *)"unknown compression method"; ++ state->mode = BAD; ++ break; ++ } ++ DROPBITS(4); ++ len = BITS(4) + 8; ++ if (state->wbits == 0) ++ state->wbits = len; ++ if (len > 15 || len > state->wbits) { ++ strm->msg = (char *)"invalid window size"; ++ state->mode = BAD; ++ break; ++ } ++ state->dmax = 1U << len; ++ Tracev((stderr, "inflate: zlib header ok\n")); ++ strm->adler = state->check = adler32(0L, Z_NULL, 0); ++ state->mode = hold & 0x200 ? DICTID : TYPE; ++ INITBITS(); ++ break; ++#ifdef GUNZIP ++ case FLAGS: ++ NEEDBITS(16); ++ state->flags = (int)(hold); ++ if ((state->flags & 0xff) != Z_DEFLATED) { ++ strm->msg = (char *)"unknown compression method"; ++ state->mode = BAD; ++ break; ++ } ++ if (state->flags & 0xe000) { ++ strm->msg = (char *)"unknown header flags set"; ++ state->mode = BAD; ++ break; ++ } ++ if (state->head != Z_NULL) ++ state->head->text = (int)((hold >> 8) & 1); ++ if ((state->flags & 0x0200) && (state->wrap & 4)) ++ CRC2(state->check, hold); ++ INITBITS(); ++ state->mode = TIME; ++ case TIME: ++ NEEDBITS(32); ++ if (state->head != Z_NULL) ++ state->head->time = hold; ++ if ((state->flags & 0x0200) && (state->wrap & 4)) ++ CRC4(state->check, hold); ++ INITBITS(); ++ state->mode = OS; ++ case OS: ++ NEEDBITS(16); ++ if (state->head != Z_NULL) { ++ state->head->xflags = (int)(hold & 0xff); ++ state->head->os = (int)(hold >> 8); ++ } ++ if ((state->flags & 0x0200) && (state->wrap & 4)) ++ CRC2(state->check, hold); ++ INITBITS(); ++ state->mode = EXLEN; ++ case EXLEN: ++ if (state->flags & 0x0400) { ++ NEEDBITS(16); ++ state->length = (unsigned)(hold); ++ if (state->head != Z_NULL) ++ state->head->extra_len = (unsigned)hold; ++ if ((state->flags & 0x0200) && (state->wrap & 4)) ++ CRC2(state->check, hold); ++ INITBITS(); ++ } ++ else if (state->head != Z_NULL) ++ state->head->extra = Z_NULL; ++ state->mode = EXTRA; ++ case EXTRA: ++ if (state->flags & 0x0400) { ++ copy = state->length; ++ if (copy > have) copy = have; ++ if (copy) { ++ if (state->head != Z_NULL && ++ state->head->extra != Z_NULL) { ++ len = state->head->extra_len - state->length; ++ zmemcpy(state->head->extra + len, next, ++ len + copy > state->head->extra_max ? ++ state->head->extra_max - len : copy); ++ } ++ if ((state->flags & 0x0200) && (state->wrap & 4)) ++ state->check = crc32(state->check, next, copy); ++ have -= copy; ++ next += copy; ++ state->length -= copy; ++ } ++ if (state->length) goto inf_leave; ++ } ++ state->length = 0; ++ state->mode = NAME; ++ case NAME: ++ if (state->flags & 0x0800) { ++ if (have == 0) goto inf_leave; ++ copy = 0; ++ do { ++ len = (unsigned)(next[copy++]); ++ if (state->head != Z_NULL && ++ state->head->name != Z_NULL && ++ state->length < state->head->name_max) ++ state->head->name[state->length++] = (Bytef)len; ++ } while (len && copy < have); ++ if ((state->flags & 0x0200) && (state->wrap & 4)) ++ state->check = crc32(state->check, next, copy); ++ have -= copy; ++ next += copy; ++ if (len) goto inf_leave; ++ } ++ else if (state->head != Z_NULL) ++ state->head->name = Z_NULL; ++ state->length = 0; ++ state->mode = COMMENT; ++ case COMMENT: ++ if (state->flags & 0x1000) { ++ if (have == 0) goto inf_leave; ++ copy = 0; ++ do { ++ len = (unsigned)(next[copy++]); ++ if (state->head != Z_NULL && ++ state->head->comment != Z_NULL && ++ state->length < state->head->comm_max) ++ state->head->comment[state->length++] = (Bytef)len; ++ } while (len && copy < have); ++ if ((state->flags & 0x0200) && (state->wrap & 4)) ++ state->check = crc32(state->check, next, copy); ++ have -= copy; ++ next += copy; ++ if (len) goto inf_leave; ++ } ++ else if (state->head != Z_NULL) ++ state->head->comment = Z_NULL; ++ state->mode = HCRC; ++ case HCRC: ++ if (state->flags & 0x0200) { ++ NEEDBITS(16); ++ if ((state->wrap & 4) && hold != (state->check & 0xffff)) { ++ strm->msg = (char *)"header crc mismatch"; ++ state->mode = BAD; ++ break; ++ } ++ INITBITS(); ++ } ++ if (state->head != Z_NULL) { ++ state->head->hcrc = (int)((state->flags >> 9) & 1); ++ state->head->done = 1; ++ } ++ strm->adler = state->check = crc32(0L, Z_NULL, 0); ++ state->mode = TYPE; ++ break; ++#endif ++ case DICTID: ++ NEEDBITS(32); ++ strm->adler = state->check = ZSWAP32(hold); ++ INITBITS(); ++ state->mode = DICT; ++ case DICT: ++ if (state->havedict == 0) { ++ RESTORE(); ++ return Z_NEED_DICT; ++ } ++ strm->adler = state->check = adler32(0L, Z_NULL, 0); ++ state->mode = TYPE; ++ case TYPE: ++ if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; ++ case TYPEDO: ++ if (state->last) { ++ BYTEBITS(); ++ state->mode = CHECK; ++ break; ++ } ++ NEEDBITS(3); ++ state->last = BITS(1); ++ DROPBITS(1); ++ switch (BITS(2)) { ++ case 0: /* stored block */ ++ Tracev((stderr, "inflate: stored block%s\n", ++ state->last ? " (last)" : "")); ++ state->mode = STORED; ++ break; ++ case 1: /* fixed block */ ++ fixedtables(state); ++ Tracev((stderr, "inflate: fixed codes block%s\n", ++ state->last ? " (last)" : "")); ++ state->mode = LEN_; /* decode codes */ ++ if (flush == Z_TREES) { ++ DROPBITS(2); ++ goto inf_leave; ++ } ++ break; ++ case 2: /* dynamic block */ ++ Tracev((stderr, "inflate: dynamic codes block%s\n", ++ state->last ? " (last)" : "")); ++ state->mode = TABLE; ++ break; ++ case 3: ++ strm->msg = (char *)"invalid block type"; ++ state->mode = BAD; ++ } ++ DROPBITS(2); ++ break; ++ case STORED: ++ BYTEBITS(); /* go to byte boundary */ ++ NEEDBITS(32); ++ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { ++ strm->msg = (char *)"invalid stored block lengths"; ++ state->mode = BAD; ++ break; ++ } ++ state->length = (unsigned)hold & 0xffff; ++ Tracev((stderr, "inflate: stored length %u\n", ++ state->length)); ++ INITBITS(); ++ state->mode = COPY_; ++ if (flush == Z_TREES) goto inf_leave; ++ case COPY_: ++ state->mode = COPY; ++ case COPY: ++ copy = state->length; ++ if (copy) { ++ if (copy > have) copy = have; ++ if (copy > left) copy = left; ++ if (copy == 0) goto inf_leave; ++ zmemcpy(put, next, copy); ++ have -= copy; ++ next += copy; ++ left -= copy; ++ put += copy; ++ state->length -= copy; ++ break; ++ } ++ Tracev((stderr, "inflate: stored end\n")); ++ state->mode = TYPE; ++ break; ++ case TABLE: ++ NEEDBITS(14); ++ state->nlen = BITS(5) + 257; ++ DROPBITS(5); ++ state->ndist = BITS(5) + 1; ++ DROPBITS(5); ++ state->ncode = BITS(4) + 4; ++ DROPBITS(4); ++#ifndef PKZIP_BUG_WORKAROUND ++ if (state->nlen > 286 || state->ndist > 30) { ++ strm->msg = (char *)"too many length or distance symbols"; ++ state->mode = BAD; ++ break; ++ } ++#endif ++ Tracev((stderr, "inflate: table sizes ok\n")); ++ state->have = 0; ++ state->mode = LENLENS; ++ case LENLENS: ++ while (state->have < state->ncode) { ++ NEEDBITS(3); ++ state->lens[order[state->have++]] = (unsigned short)BITS(3); ++ DROPBITS(3); ++ } ++ while (state->have < 19) ++ state->lens[order[state->have++]] = 0; ++ state->next = state->codes; ++ state->lencode = (const code FAR *)(state->next); ++ state->lenbits = 7; ++ ret = inflate_table(CODES, state->lens, 19, &(state->next), ++ &(state->lenbits), state->work); ++ if (ret) { ++ strm->msg = (char *)"invalid code lengths set"; ++ state->mode = BAD; ++ break; ++ } ++ Tracev((stderr, "inflate: code lengths ok\n")); ++ state->have = 0; ++ state->mode = CODELENS; ++ case CODELENS: ++ while (state->have < state->nlen + state->ndist) { ++ for (;;) { ++ here = state->lencode[BITS(state->lenbits)]; ++ if ((unsigned)(here.bits) <= bits) break; ++ PULLBYTE(); ++ } ++ if (here.val < 16) { ++ DROPBITS(here.bits); ++ state->lens[state->have++] = here.val; ++ } ++ else { ++ if (here.val == 16) { ++ NEEDBITS(here.bits + 2); ++ DROPBITS(here.bits); ++ if (state->have == 0) { ++ strm->msg = (char *)"invalid bit length repeat"; ++ state->mode = BAD; ++ break; ++ } ++ len = state->lens[state->have - 1]; ++ copy = 3 + BITS(2); ++ DROPBITS(2); ++ } ++ else if (here.val == 17) { ++ NEEDBITS(here.bits + 3); ++ DROPBITS(here.bits); ++ len = 0; ++ copy = 3 + BITS(3); ++ DROPBITS(3); ++ } ++ else { ++ NEEDBITS(here.bits + 7); ++ DROPBITS(here.bits); ++ len = 0; ++ copy = 11 + BITS(7); ++ DROPBITS(7); ++ } ++ if (state->have + copy > state->nlen + state->ndist) { ++ strm->msg = (char *)"invalid bit length repeat"; ++ state->mode = BAD; ++ break; ++ } ++ while (copy--) ++ state->lens[state->have++] = (unsigned short)len; ++ } ++ } ++ ++ /* handle error breaks in while */ ++ if (state->mode == BAD) break; ++ ++ /* check for end-of-block code (better have one) */ ++ if (state->lens[256] == 0) { ++ strm->msg = (char *)"invalid code -- missing end-of-block"; ++ state->mode = BAD; ++ break; ++ } ++ ++ /* build code tables -- note: do not change the lenbits or distbits ++ values here (9 and 6) without reading the comments in inftrees.h ++ concerning the ENOUGH constants, which depend on those values */ ++ state->next = state->codes; ++ state->lencode = (const code FAR *)(state->next); ++ state->lenbits = 9; ++ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), ++ &(state->lenbits), state->work); ++ if (ret) { ++ strm->msg = (char *)"invalid literal/lengths set"; ++ state->mode = BAD; ++ break; ++ } ++ state->distcode = (const code FAR *)(state->next); ++ state->distbits = 6; ++ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, ++ &(state->next), &(state->distbits), state->work); ++ if (ret) { ++ strm->msg = (char *)"invalid distances set"; ++ state->mode = BAD; ++ break; ++ } ++ Tracev((stderr, "inflate: codes ok\n")); ++ state->mode = LEN_; ++ if (flush == Z_TREES) goto inf_leave; ++ case LEN_: ++ state->mode = LEN; ++ case LEN: ++ if (have >= 6 && left >= 258) { ++ RESTORE(); ++ inflate_fast(strm, out); ++ LOAD(); ++ if (state->mode == TYPE) ++ state->back = -1; ++ break; ++ } ++ state->back = 0; ++ for (;;) { ++ here = state->lencode[BITS(state->lenbits)]; ++ if ((unsigned)(here.bits) <= bits) break; ++ PULLBYTE(); ++ } ++ if (here.op && (here.op & 0xf0) == 0) { ++ last = here; ++ for (;;) { ++ here = state->lencode[last.val + ++ (BITS(last.bits + last.op) >> last.bits)]; ++ if ((unsigned)(last.bits + here.bits) <= bits) break; ++ PULLBYTE(); ++ } ++ DROPBITS(last.bits); ++ state->back += last.bits; ++ } ++ DROPBITS(here.bits); ++ state->back += here.bits; ++ state->length = (unsigned)here.val; ++ if ((int)(here.op) == 0) { ++ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? ++ "inflate: literal '%c'\n" : ++ "inflate: literal 0x%02x\n", here.val)); ++ state->mode = LIT; ++ break; ++ } ++ if (here.op & 32) { ++ Tracevv((stderr, "inflate: end of block\n")); ++ state->back = -1; ++ state->mode = TYPE; ++ break; ++ } ++ if (here.op & 64) { ++ strm->msg = (char *)"invalid literal/length code"; ++ state->mode = BAD; ++ break; ++ } ++ state->extra = (unsigned)(here.op) & 15; ++ state->mode = LENEXT; ++ case LENEXT: ++ if (state->extra) { ++ NEEDBITS(state->extra); ++ state->length += BITS(state->extra); ++ DROPBITS(state->extra); ++ state->back += state->extra; ++ } ++ Tracevv((stderr, "inflate: length %u\n", state->length)); ++ state->was = state->length; ++ state->mode = DIST; ++ case DIST: ++ for (;;) { ++ here = state->distcode[BITS(state->distbits)]; ++ if ((unsigned)(here.bits) <= bits) break; ++ PULLBYTE(); ++ } ++ if ((here.op & 0xf0) == 0) { ++ last = here; ++ for (;;) { ++ here = state->distcode[last.val + ++ (BITS(last.bits + last.op) >> last.bits)]; ++ if ((unsigned)(last.bits + here.bits) <= bits) break; ++ PULLBYTE(); ++ } ++ DROPBITS(last.bits); ++ state->back += last.bits; ++ } ++ DROPBITS(here.bits); ++ state->back += here.bits; ++ if (here.op & 64) { ++ strm->msg = (char *)"invalid distance code"; ++ state->mode = BAD; ++ break; ++ } ++ state->offset = (unsigned)here.val; ++ state->extra = (unsigned)(here.op) & 15; ++ state->mode = DISTEXT; ++ case DISTEXT: ++ if (state->extra) { ++ NEEDBITS(state->extra); ++ state->offset += BITS(state->extra); ++ DROPBITS(state->extra); ++ state->back += state->extra; ++ } ++#ifdef INFLATE_STRICT ++ if (state->offset > state->dmax) { ++ strm->msg = (char *)"invalid distance too far back"; ++ state->mode = BAD; ++ break; ++ } ++#endif ++ Tracevv((stderr, "inflate: distance %u\n", state->offset)); ++ state->mode = MATCH; ++ case MATCH: ++ if (left == 0) goto inf_leave; ++ copy = out - left; ++ if (state->offset > copy) { /* copy from window */ ++ copy = state->offset - copy; ++ if (copy > state->whave) { ++ if (state->sane) { ++ strm->msg = (char *)"invalid distance too far back"; ++ state->mode = BAD; ++ break; ++ } ++#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR ++ Trace((stderr, "inflate.c too far\n")); ++ copy -= state->whave; ++ if (copy > state->length) copy = state->length; ++ if (copy > left) copy = left; ++ left -= copy; ++ state->length -= copy; ++ do { ++ *put++ = 0; ++ } while (--copy); ++ if (state->length == 0) state->mode = LEN; ++ break; ++#endif ++ } ++ if (copy > state->wnext) { ++ copy -= state->wnext; ++ from = state->window + (state->wsize - copy); ++ } ++ else ++ from = state->window + (state->wnext - copy); ++ if (copy > state->length) copy = state->length; ++ if (copy > left) copy = left; ++ put = chunkcopy_safe(put, from, copy, put + left); ++ } ++ else { /* copy from output */ ++ copy = state->length; ++ if (copy > left) copy = left; ++ put = chunkcopy_lapped_safe(put, state->offset, copy, put + left); ++ } ++ left -= copy; ++ state->length -= copy; ++ if (state->length == 0) state->mode = LEN; ++ break; ++ case LIT: ++ if (left == 0) goto inf_leave; ++ *put++ = (unsigned char)(state->length); ++ left--; ++ state->mode = LEN; ++ break; ++ case CHECK: ++ if (state->wrap) { ++ NEEDBITS(32); ++ out -= left; ++ strm->total_out += out; ++ state->total += out; ++ if ((state->wrap & 4) && out) ++ strm->adler = state->check = ++ UPDATE(state->check, put - out, out); ++ out = left; ++ if ((state->wrap & 4) && ( ++#ifdef GUNZIP ++ state->flags ? hold : ++#endif ++ ZSWAP32(hold)) != state->check) { ++ strm->msg = (char *)"incorrect data check"; ++ state->mode = BAD; ++ break; ++ } ++ INITBITS(); ++ Tracev((stderr, "inflate: check matches trailer\n")); ++ } ++#ifdef GUNZIP ++ state->mode = LENGTH; ++ case LENGTH: ++ if (state->wrap && state->flags) { ++ NEEDBITS(32); ++ if (hold != (state->total & 0xffffffffUL)) { ++ strm->msg = (char *)"incorrect length check"; ++ state->mode = BAD; ++ break; ++ } ++ INITBITS(); ++ Tracev((stderr, "inflate: length matches trailer\n")); ++ } ++#endif ++ state->mode = DONE; ++ case DONE: ++ ret = Z_STREAM_END; ++ goto inf_leave; ++ case BAD: ++ ret = Z_DATA_ERROR; ++ goto inf_leave; ++ case MEM: ++ return Z_MEM_ERROR; ++ case SYNC: ++ default: ++ return Z_STREAM_ERROR; ++ } ++ ++ /* ++ Return from inflate(), updating the total counts and the check value. ++ If there was no progress during the inflate() call, return a buffer ++ error. Call updatewindow() to create and/or update the window state. ++ Note: a memory error from inflate() is non-recoverable. ++ */ ++ inf_leave: ++ RESTORE(); ++ if (state->wsize || (out != strm->avail_out && state->mode < BAD && ++ (state->mode < CHECK || flush != Z_FINISH))) ++ if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { ++ state->mode = MEM; ++ return Z_MEM_ERROR; ++ } ++ in -= strm->avail_in; ++ out -= strm->avail_out; ++ strm->total_in += in; ++ strm->total_out += out; ++ state->total += out; ++ if ((state->wrap & 4) && out) ++ strm->adler = state->check = ++ UPDATE(state->check, strm->next_out - out, out); ++ strm->data_type = (int)state->bits + (state->last ? 64 : 0) + ++ (state->mode == TYPE ? 128 : 0) + ++ (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); ++ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ++ ret = Z_BUF_ERROR; ++ return ret; ++} ++ ++int ZEXPORT inflateEnd(strm) ++z_streamp strm; ++{ ++ struct inflate_state FAR *state; ++ if (inflateStateCheck(strm)) ++ return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ if (state->window != Z_NULL) ZFREE(strm, state->window); ++ ZFREE(strm, strm->state); ++ strm->state = Z_NULL; ++ Tracev((stderr, "inflate: end\n")); ++ return Z_OK; ++} ++ ++int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) ++z_streamp strm; ++Bytef *dictionary; ++uInt *dictLength; ++{ ++ struct inflate_state FAR *state; ++ ++ /* check state */ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ ++ /* copy dictionary */ ++ if (state->whave && dictionary != Z_NULL) { ++ zmemcpy(dictionary, state->window + state->wnext, ++ state->whave - state->wnext); ++ zmemcpy(dictionary + state->whave - state->wnext, ++ state->window, state->wnext); ++ } ++ if (dictLength != Z_NULL) ++ *dictLength = state->whave; ++ return Z_OK; ++} ++ ++int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) ++z_streamp strm; ++const Bytef *dictionary; ++uInt dictLength; ++{ ++ struct inflate_state FAR *state; ++ unsigned long dictid; ++ int ret; ++ ++ /* check state */ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ if (state->wrap != 0 && state->mode != DICT) ++ return Z_STREAM_ERROR; ++ ++ /* check for correct dictionary identifier */ ++ if (state->mode == DICT) { ++ dictid = adler32(0L, Z_NULL, 0); ++ dictid = adler32(dictid, dictionary, dictLength); ++ if (dictid != state->check) ++ return Z_DATA_ERROR; ++ } ++ ++ /* copy dictionary to window using updatewindow(), which will amend the ++ existing dictionary if appropriate */ ++ ret = updatewindow(strm, dictionary + dictLength, dictLength); ++ if (ret) { ++ state->mode = MEM; ++ return Z_MEM_ERROR; ++ } ++ state->havedict = 1; ++ Tracev((stderr, "inflate: dictionary set\n")); ++ return Z_OK; ++} ++ ++int ZEXPORT inflateGetHeader(strm, head) ++z_streamp strm; ++gz_headerp head; ++{ ++ struct inflate_state FAR *state; ++ ++ /* check state */ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; ++ ++ /* save header structure */ ++ state->head = head; ++ head->done = 0; ++ return Z_OK; ++} ++ ++/* ++ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found ++ or when out of input. When called, *have is the number of pattern bytes ++ found in order so far, in 0..3. On return *have is updated to the new ++ state. If on return *have equals four, then the pattern was found and the ++ return value is how many bytes were read including the last byte of the ++ pattern. If *have is less than four, then the pattern has not been found ++ yet and the return value is len. In the latter case, syncsearch() can be ++ called again with more data and the *have state. *have is initialized to ++ zero for the first call. ++ */ ++local unsigned syncsearch(have, buf, len) ++unsigned FAR *have; ++const unsigned char FAR *buf; ++unsigned len; ++{ ++ unsigned got; ++ unsigned next; ++ ++ got = *have; ++ next = 0; ++ while (next < len && got < 4) { ++ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) ++ got++; ++ else if (buf[next]) ++ got = 0; ++ else ++ got = 4 - got; ++ next++; ++ } ++ *have = got; ++ return next; ++} ++ ++int ZEXPORT inflateSync(strm) ++z_streamp strm; ++{ ++ unsigned len; /* number of bytes to look at or looked at */ ++ unsigned long in, out; /* temporary to save total_in and total_out */ ++ unsigned char buf[4]; /* to restore bit buffer to byte string */ ++ struct inflate_state FAR *state; ++ ++ /* check parameters */ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; ++ ++ /* if first time, start search in bit buffer */ ++ if (state->mode != SYNC) { ++ state->mode = SYNC; ++ state->hold <<= state->bits & 7; ++ state->bits -= state->bits & 7; ++ len = 0; ++ while (state->bits >= 8) { ++ buf[len++] = (unsigned char)(state->hold); ++ state->hold >>= 8; ++ state->bits -= 8; ++ } ++ state->have = 0; ++ syncsearch(&(state->have), buf, len); ++ } ++ ++ /* search available input */ ++ len = syncsearch(&(state->have), strm->next_in, strm->avail_in); ++ strm->avail_in -= len; ++ strm->next_in += len; ++ strm->total_in += len; ++ ++ /* return no joy or set up to restart inflate() on a new block */ ++ if (state->have != 4) return Z_DATA_ERROR; ++ in = strm->total_in; out = strm->total_out; ++ inflateReset(strm); ++ strm->total_in = in; strm->total_out = out; ++ state->mode = TYPE; ++ return Z_OK; ++} ++ ++/* ++ Returns true if inflate is currently at the end of a block generated by ++ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP ++ implementation to provide an additional safety check. PPP uses ++ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored ++ block. When decompressing, PPP checks that at the end of input packet, ++ inflate is waiting for these length bytes. ++ */ ++int ZEXPORT inflateSyncPoint(strm) ++z_streamp strm; ++{ ++ struct inflate_state FAR *state; ++ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ return state->mode == STORED && state->bits == 0; ++} ++ ++int ZEXPORT inflateCopy(dest, source) ++z_streamp dest; ++z_streamp source; ++{ ++ struct inflate_state FAR *state; ++ struct inflate_state FAR *copy; ++ unsigned char FAR *window; ++ unsigned wsize; ++ ++ /* check input */ ++ if (inflateStateCheck(source) || dest == Z_NULL) ++ return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)source->state; ++ ++ /* allocate space */ ++ copy = (struct inflate_state FAR *) ++ ZALLOC(source, 1, sizeof(struct inflate_state)); ++ if (copy == Z_NULL) return Z_MEM_ERROR; ++ window = Z_NULL; ++ if (state->window != Z_NULL) { ++ window = (unsigned char FAR *) ++ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); ++ if (window == Z_NULL) { ++ ZFREE(source, copy); ++ return Z_MEM_ERROR; ++ } ++ } ++ ++ /* copy state */ ++ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); ++ zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); ++ copy->strm = dest; ++ if (state->lencode >= state->codes && ++ state->lencode <= state->codes + ENOUGH - 1) { ++ copy->lencode = copy->codes + (state->lencode - state->codes); ++ copy->distcode = copy->codes + (state->distcode - state->codes); ++ } ++ copy->next = copy->codes + (state->next - state->codes); ++ if (window != Z_NULL) { ++ wsize = 1U << state->wbits; ++ zmemcpy(window, state->window, wsize); ++ } ++ copy->window = window; ++ dest->state = (struct internal_state FAR *)copy; ++ return Z_OK; ++} ++ ++int ZEXPORT inflateUndermine(strm, subvert) ++z_streamp strm; ++int subvert; ++{ ++ struct inflate_state FAR *state; ++ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR ++ state->sane = !subvert; ++ return Z_OK; ++#else ++ (void)subvert; ++ state->sane = 1; ++ return Z_DATA_ERROR; ++#endif ++} ++ ++int ZEXPORT inflateValidate(strm, check) ++z_streamp strm; ++int check; ++{ ++ struct inflate_state FAR *state; ++ ++ if (inflateStateCheck(strm)) return Z_STREAM_ERROR; ++ state = (struct inflate_state FAR *)strm->state; ++ if (check) ++ state->wrap |= 4; ++ else ++ state->wrap &= ~4; ++ return Z_OK; ++} ++ ++long ZEXPORT inflateMark(strm) ++z_streamp strm; ++{ ++ struct inflate_state FAR *state; ++ ++ if (inflateStateCheck(strm)) ++ return -(1L << 16); ++ state = (struct inflate_state FAR *)strm->state; ++ return (long)(((unsigned long)((long)state->back)) << 16) + ++ (state->mode == COPY ? state->length : ++ (state->mode == MATCH ? state->was - state->length : 0)); ++} ++ ++unsigned long ZEXPORT inflateCodesUsed(strm) ++z_streamp strm; ++{ ++ struct inflate_state FAR *state; ++ if (inflateStateCheck(strm)) return (unsigned long)-1; ++ state = (struct inflate_state FAR *)strm->state; ++ return (unsigned long)(state->next - state->codes); ++} +-- +2.7.4 +
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn index 4b4db15b..8c57ad49 100644 --- a/third_party/zlib/BUILD.gn +++ b/third_party/zlib/BUILD.gn
@@ -2,6 +2,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +if (current_cpu == "arm" || current_cpu == "arm64") { + import("//build/config/arm.gni") +} + config("zlib_config") { include_dirs = [ "." ] } @@ -71,6 +75,20 @@ "zutil.h", ] + if (current_cpu == "arm" || current_cpu == "arm64") { + if (arm_use_neon) { + sources -= [ + "inflate.c", + "inffast.c", + ] + sources += [ + "contrib/arm/inflate.c", + "contrib/arm/inffast.c", + "contrib/arm/chunkcopy.h", + ] + } + } + if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) { sources += [ "x86.c" ] }
diff --git a/third_party/zlib/README.chromium b/third_party/zlib/README.chromium index 8658580..ff5c6ab 100644 --- a/third_party/zlib/README.chromium +++ b/third_party/zlib/README.chromium
@@ -28,3 +28,4 @@ https://github.com/jtkukunas/zlib/ - 0002-uninitializedcheck.patch: default-initialize state->check, see crbug.com/697481 + - 0003-arm-inffast.patch: ARM optimized inflate using NEON.
diff --git a/third_party/zlib/contrib/arm/chunkcopy.h b/third_party/zlib/contrib/arm/chunkcopy.h new file mode 100644 index 0000000..2d6fd6f --- /dev/null +++ b/third_party/zlib/contrib/arm/chunkcopy.h
@@ -0,0 +1,279 @@ +/* chunkcopy.h -- fast copies and sets + * Copyright (C) 2017 ARM, Inc. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef CHUNKCOPY_H +#define CHUNKCOPY_H + +#include "zutil.h" +#include <arm_neon.h> + +#if __STDC_VERSION__ >= 199901L +#define Z_RESTRICT restrict +#else +#define Z_RESTRICT +#endif + +typedef uint8x16_t chunkcopy_chunk_t; +#define CHUNKCOPY_CHUNK_SIZE sizeof(chunkcopy_chunk_t) + +/* + Ask the compiler to perform a wide, unaligned load with an machine + instruction appropriate for the chunkcopy_chunk_t type. + */ +static inline chunkcopy_chunk_t loadchunk(const unsigned char FAR *s) { + chunkcopy_chunk_t c; + __builtin_memcpy(&c, s, sizeof(c)); + return c; +} + +/* + Ask the compiler to perform a wide, unaligned store with an machine + instruction appropriate for the chunkcopy_chunk_t type. + */ +static inline void storechunk(unsigned char FAR *d, chunkcopy_chunk_t c) { + __builtin_memcpy(d, &c, sizeof(c)); +} + +/* + Perform a memcpy-like operation, but assume that length is non-zero and that + it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if + the length is shorter than this. + + It also guarantees that it will properly unroll the data if the distance + between `out` and `from` is at least CHUNKCOPY_CHUNK_SIZE, which we rely on + in chunkcopy_relaxed(). + + Aside from better memory bus utilisation, this means that short copies + (CHUNKCOPY_CHUNK_SIZE bytes or fewer) will fall straight through the loop + without iteration, which will hopefully make the branch prediction more + reliable. + */ +static inline unsigned char FAR *chunkcopy_core(unsigned char FAR *out, + const unsigned char FAR *from, + unsigned len) { + int bump = (--len % CHUNKCOPY_CHUNK_SIZE) + 1; + storechunk(out, loadchunk(from)); + out += bump; + from += bump; + len /= CHUNKCOPY_CHUNK_SIZE; + while (len-- > 0) { + storechunk(out, loadchunk(from)); + out += CHUNKCOPY_CHUNK_SIZE; + from += CHUNKCOPY_CHUNK_SIZE; + } + return out; +} + +/* + Like chunkcopy_core, but avoid writing beyond of legal output. + + Accepts an additional pointer to the end of safe output. A generic safe + copy would use (out + len), but it's normally the case that the end of the + output buffer is beyond the end of the current copy, and this can still be + exploited. + */ +static inline unsigned char FAR *chunkcopy_core_safe(unsigned char FAR *out, + const unsigned char FAR * from, + unsigned len, + unsigned char FAR *limit) { + Assert(out + len <= limit, "chunk copy exceeds safety limit"); + if (limit - out < CHUNKCOPY_CHUNK_SIZE) { + const unsigned char FAR * Z_RESTRICT rfrom = from; + if (len & 8) { __builtin_memcpy(out, rfrom, 8); out += 8; rfrom += 8; } + if (len & 4) { __builtin_memcpy(out, rfrom, 4); out += 4; rfrom += 4; } + if (len & 2) { __builtin_memcpy(out, rfrom, 2); out += 2; rfrom += 2; } + if (len & 1) { *out++ = *rfrom++; } + return out; + } + return chunkcopy_core(out, from, len); +} + +/* + Perform short copies until distance can be rewritten as being at least + CHUNKCOPY_CHUNK_SIZE. + + This assumes that it's OK to overwrite at least the first + 2*CHUNKCOPY_CHUNK_SIZE bytes of output even if the copy is shorter than + this. This assumption holds within inflate_fast() which starts every + iteration with at least 258 bytes of output space available (258 being the + maximum length output from a single token; see inffast.c). + */ +static inline unsigned char FAR *chunkunroll_relaxed(unsigned char FAR *out, + unsigned FAR *dist, + unsigned FAR *len) { + const unsigned char FAR *from = out - *dist; + while (*dist < *len && *dist < CHUNKCOPY_CHUNK_SIZE) { + storechunk(out, loadchunk(from)); + out += *dist; + *len -= *dist; + *dist += *dist; + } + return out; +} + + +static inline uint8x16_t chunkset_vld1q_dup_u8x8(const unsigned char FAR * Z_RESTRICT from) { +#if defined(__clang__) || defined(__aarch64__) + return vreinterpretq_u8_u64(vld1q_dup_u64((void *)from)); +#else + /* 32-bit GCC uses an alignment hint for vld1q_dup_u64, even when given a + * void pointer, so here's an alternate implementation. + */ + uint8x8_t h = vld1_u8(from); + return vcombine_u8(h, h); +#endif +} + +/* + Perform an overlapping copy which behaves as a memset() operation, but + supporting periods other than one, and assume that length is non-zero and + that it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE*3 bytes of output + even if the length is shorter than this. + */ +static inline unsigned char FAR *chunkset_core(unsigned char FAR *out, + unsigned period, + unsigned len) { + uint8x16_t f; + int bump = ((len - 1) % sizeof(f)) + 1; + + switch (period) { + case 1: + f = vld1q_dup_u8(out - 1); + vst1q_u8(out, f); + out += bump; + len -= bump; + while (len > 0) { + vst1q_u8(out, f); + out += sizeof(f); + len -= sizeof(f); + } + return out; + case 2: + f = vreinterpretq_u8_u16(vld1q_dup_u16((void *)(out - 2))); + vst1q_u8(out, f); + out += bump; + len -= bump; + if (len > 0) { + f = vreinterpretq_u8_u16(vld1q_dup_u16((void *)(out - 2))); + do { + vst1q_u8(out, f); + out += sizeof(f); + len -= sizeof(f); + } while (len > 0); + } + return out; + case 4: + f = vreinterpretq_u8_u32(vld1q_dup_u32((void *)(out - 4))); + vst1q_u8(out, f); + out += bump; + len -= bump; + if (len > 0) { + f = vreinterpretq_u8_u32(vld1q_dup_u32((void *)(out - 4))); + do { + vst1q_u8(out, f); + out += sizeof(f); + len -= sizeof(f); + } while (len > 0); + } + return out; + case 8: + f = chunkset_vld1q_dup_u8x8(out - 8); + vst1q_u8(out, f); + out += bump; + len -= bump; + if (len > 0) { + f = chunkset_vld1q_dup_u8x8(out - 8); + do { + vst1q_u8(out, f); + out += sizeof(f); + len -= sizeof(f); + } while (len > 0); + } + return out; + } + out = chunkunroll_relaxed(out, &period, &len); + return chunkcopy_core(out, out - period, len); +} + +/* + Perform a memcpy-like operation, but assume that length is non-zero and that + it's OK to overwrite at least CHUNKCOPY_CHUNK_SIZE bytes of output even if + the length is shorter than this. + + Unlike chunkcopy_core() above, no guarantee is made regarding the behaviour + of overlapping buffers, regardless of the distance between the pointers. + This is reflected in the `restrict`-qualified pointers, allowing the + compiler to reorder loads and stores. + */ +static inline unsigned char FAR *chunkcopy_relaxed(unsigned char FAR * Z_RESTRICT out, + const unsigned char FAR * Z_RESTRICT from, + unsigned len) { + return chunkcopy_core(out, from, len); +} + +/* + Like chunkcopy_relaxed, but avoid writing beyond of legal output. + + Unlike chunkcopy_core_safe() above, no guarantee is made regarding the + behaviour of overlapping buffers, regardless of the distance between the + pointers. This is reflected in the `restrict`-qualified pointers, allowing + the compiler to reorder loads and stores. + + Accepts an additional pointer to the end of safe output. A generic safe + copy would use (out + len), but it's normally the case that the end of the + output buffer is beyond the end of the current copy, and this can still be + exploited. + */ +static inline unsigned char FAR *chunkcopy_safe(unsigned char FAR *out, + const unsigned char FAR * Z_RESTRICT from, + unsigned len, + unsigned char FAR *limit) { + Assert(out + len <= limit, "chunk copy exceeds safety limit"); + return chunkcopy_core_safe(out, from, len, limit); +} + +/* + Perform chunky copy within the same buffer, where the source and destination + may potentially overlap. + + Assumes that len > 0 on entry, and that it's safe to write at least + CHUNKCOPY_CHUNK_SIZE*3 bytes to the output. + */ +static inline unsigned char FAR *chunkcopy_lapped_relaxed(unsigned char FAR *out, + unsigned dist, + unsigned len) { + if (dist < len && dist < CHUNKCOPY_CHUNK_SIZE) { + return chunkset_core(out, dist, len); + } + return chunkcopy_core(out, out - dist, len); +} + +/* + Behave like chunkcopy_lapped_relaxed, but avoid writing beyond of legal output. + + Accepts an additional pointer to the end of safe output. A generic safe + copy would use (out + len), but it's normally the case that the end of the + output buffer is beyond the end of the current copy, and this can still be + exploited. + */ +static inline unsigned char FAR *chunkcopy_lapped_safe(unsigned char FAR *out, + unsigned dist, + unsigned len, + unsigned char FAR *limit) { + Assert(out + len <= limit, "chunk copy exceeds safety limit"); + if (limit - out < CHUNKCOPY_CHUNK_SIZE * 3) { + /* TODO: try harder to optimise this */ + while (len-- > 0) { + *out = *(out - dist); + out++; + } + return out; + } + return chunkcopy_lapped_relaxed(out, dist, len); +} + +#undef Z_RESTRICT + +#endif /* CHUNKCOPY_H */
diff --git a/third_party/zlib/contrib/arm/inffast.c b/third_party/zlib/contrib/arm/inffast.c new file mode 100644 index 0000000..f7f5007 --- /dev/null +++ b/third_party/zlib/contrib/arm/inffast.c
@@ -0,0 +1,307 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" +#include "chunkcopy.h" + +#ifdef ASMINF +# pragma message("Assembler code may have bugs -- use at your own risk") +#else + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ + unsigned char FAR *limit; /* safety limit for chunky copies */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - 5); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); + limit = out + strm->avail_out; +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = (state->wnext == 0 && whave >= wsize) ? wsize : state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + *out++ = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(*in++) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext >= op) { /* contiguous in window */ + from += wnext - op; + } + else { /* wrap around window */ + op -= wnext; + from += wsize - op; + if (op < len) { /* some from end of window */ + len -= op; + out = chunkcopy_safe(out, from, op, limit); + from = window; /* more from start of window */ + op = wnext; + /* This (rare) case can create a situation where + the first chunkcopy below must be checked. + */ + } + } + if (op < len) { /* still need some from output */ + out = chunkcopy_safe(out, from, op, limit); + len -= op; + /* When dist is small the amount of data that can be + copied from the window is also small, and progress + towards the dangerous end of the output buffer is + also small. This means that for trivial memsets and + for chunkunroll_relaxed() a safety check is + unnecessary. However, these conditions may not be + entered at all, and in that case it's possible that + the main copy is near the end. + */ + out = chunkunroll_relaxed(out, &dist, &len); + out = chunkcopy_safe(out, out - dist, len, limit); + } else { + /* from points to window, so there is no risk of + overlapping pointers requiring memset-like behaviour + */ + out = chunkcopy_safe(out, from, len, limit); + } + } + else { + /* Whole reference is in range of current output. No + range checks are necessary because we start with room + for at least 258 bytes of output, so unroll and roundoff + operations can write beyond `out+len` so long as they + stay within 258 bytes of `out`. + */ + out = chunkcopy_lapped_relaxed(out, dist, len); + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */
diff --git a/third_party/zlib/contrib/arm/inflate.c b/third_party/zlib/contrib/arm/inflate.c new file mode 100644 index 0000000..e40322c --- /dev/null +++ b/third_party/zlib/contrib/arm/inflate.c
@@ -0,0 +1,1571 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" +#include "contrib/arm/chunkcopy.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local int inflateStateCheck OF((z_streamp strm)); +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, + unsigned copy)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, + unsigned len)); + +local int inflateStateCheck(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + state = (struct inflate_state FAR *)strm->state; + if (state == Z_NULL || state->strm != strm || + state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int ZEXPORT inflateResetKeep(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; +#endif + } + if (strm->zfree == (free_func)0) +#ifdef Z_SOLO + return Z_STREAM_ERROR; +#else + strm->zfree = zcfree; +#endif + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->strm = strm; + state->window = Z_NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (uInt)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include <stdio.h> + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, end, copy) +z_streamp strm; +const Bytef *end; +unsigned copy; +{ + struct inflate_state FAR *state; + unsigned dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + unsigned wsize = 1U << state->wbits; + state->window = (unsigned char FAR *) + ZALLOC(strm, wsize + CHUNKCOPY_CHUNK_SIZE, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; +#ifdef INFLATE_CLEAR_UNUSED_UNDEFINED + /* Copies from the overflow portion of this buffer are undefined and + may cause analysis tools to raise a warning if we don't initialize + it. However, this undefined data overwrites other undefined data + and is subsequently either overwritten or left deliberately + undefined at the end of decode; so there's really no point. + */ + memset(state->window + wsize, 0, CHUNKCOPY_CHUNK_SIZE); +#endif + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = 15; + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > 15 || len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = (Bytef)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + put = chunkcopy_safe(put, from, copy, put + left); + } + else { /* copy from output */ + copy = state->length; + if (copy > left) copy = left; + put = chunkcopy_lapped_safe(put, state->offset, copy, put + left); + } + left -= copy; + state->length -= copy; + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if ((state->wrap & 4) && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) +z_streamp strm; +Bytef *dictionary; +uInt *dictLength; +{ + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long dictid; + int ret; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +const unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + copy->strm = dest; + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + (void)subvert; + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int ZEXPORT inflateValidate(strm, check) +z_streamp strm; +int check; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (check) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (inflateStateCheck(strm)) + return -(1L << 16); + state = (struct inflate_state FAR *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long ZEXPORT inflateCodesUsed(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (inflateStateCheck(strm)) return (unsigned long)-1; + state = (struct inflate_state FAR *)strm->state; + return (unsigned long)(state->next - state->codes); +}
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl index e42891d..ff89d5a 100644 --- a/tools/gritsettings/translation_expectations.pyl +++ b/tools/gritsettings/translation_expectations.pyl
@@ -61,8 +61,8 @@ "android_webview/java/strings/android_webview_strings.grd", "chrome/android/java/strings/android_chrome_strings.grd", "chrome/android/webapk/strings/android_webapk_strings.grd", - "components/autofill/android/autofill_strings.grd", - "components/web_contents_delegate_android/web_contents_delegate_android_strings.grd", + "components/autofill/android/java/strings/autofill_strings.grd", + "components/web_contents_delegate_android/java/strings/web_contents_delegate_android_strings.grd", "content/public/android/java/strings/android_content_strings.grd", "ui/android/java/strings/android_ui_strings.grd", ],
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc index ddf911d..e901db8 100644 --- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc +++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -738,84 +738,6 @@ }; template <> -struct FuzzTraits<content::SyntheticGesturePacket> { - static bool Fuzz(content::SyntheticGesturePacket* p, - Fuzzer* fuzzer) { - // TODO(mbarbella): Support mutation. - if (!fuzzer->ShouldGenerate()) - return true; - - std::unique_ptr<content::SyntheticGestureParams> gesture_params; - switch (RandInRange( - content::SyntheticGestureParams::SYNTHETIC_GESTURE_TYPE_MAX + 1)) { - case content::SyntheticGestureParams::GestureType:: - SMOOTH_SCROLL_GESTURE: { - content::SyntheticSmoothScrollGestureParams* params = - new content::SyntheticSmoothScrollGestureParams(); - if (!FuzzParam(¶ms->anchor, fuzzer)) - return false; - if (!FuzzParam(¶ms->distances, fuzzer)) - return false; - if (!FuzzParam(¶ms->prevent_fling, fuzzer)) - return false; - if (!FuzzParam(¶ms->speed_in_pixels_s, fuzzer)) - return false; - gesture_params.reset(params); - break; - } - case content::SyntheticGestureParams::GestureType::SMOOTH_DRAG_GESTURE: { - content::SyntheticSmoothDragGestureParams* params = - new content::SyntheticSmoothDragGestureParams(); - if (!FuzzParam(¶ms->start_point, fuzzer)) - return false; - if (!FuzzParam(¶ms->distances, fuzzer)) - return false; - if (!FuzzParam(¶ms->speed_in_pixels_s, fuzzer)) - return false; - gesture_params.reset(params); - break; - } - case content::SyntheticGestureParams::GestureType::PINCH_GESTURE: { - content::SyntheticPinchGestureParams* params = - new content::SyntheticPinchGestureParams(); - if (!FuzzParam(¶ms->scale_factor, fuzzer)) - return false; - if (!FuzzParam(¶ms->anchor, fuzzer)) - return false; - if (!FuzzParam(¶ms->relative_pointer_speed_in_pixels_s, - fuzzer)) - return false; - gesture_params.reset(params); - break; - } - case content::SyntheticGestureParams::GestureType::TAP_GESTURE: { - content::SyntheticTapGestureParams* params = - new content::SyntheticTapGestureParams(); - if (!FuzzParam(¶ms->position, fuzzer)) - return false; - if (!FuzzParam(¶ms->duration_ms, fuzzer)) - return false; - gesture_params.reset(params); - break; - } - case content::SyntheticGestureParams::GestureType::POINTER_ACTION_LIST: { - std::vector<content::SyntheticPointerActionListParams::ParamList> - param_list; - if (!FuzzParam(¶m_list, fuzzer)) - return false; - content::SyntheticPointerActionListParams* params = - new content::SyntheticPointerActionListParams(); - params->params = param_list; - gesture_params.reset(params); - break; - } - } - p->set_gesture_params(std::move(gesture_params)); - return true; - } -}; - -template <> struct FuzzTraits<content::WebCursor> { static bool Fuzz(content::WebCursor* p, Fuzzer* fuzzer) { content::CursorInfo info;
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 73b8d36..2ad57d7 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -20617,6 +20617,24 @@ </summary> </histogram> +<histogram name="Extensions.Bindings.NativeBindingCreationTime" + units="microseconds"> + <owner>rdevlin.cronin@chromium.org</owner> + <summary> + The elapsed time to create a new full instance of an extension API's + bindings using native bindings. + </summary> +</histogram> + +<histogram name="Extensions.Bindings.UpdateBindingsForContextTime" + units="microseconds"> + <owner>rdevlin.cronin@chromium.org</owner> + <summary> + The elapsed time to update the bindings for a new or existing v8::Context. + The suffix indicates which type of context the bindings are for. + </summary> +</histogram> + <histogram name="Extensions.BookmarkAppLaunchContainer" enum="AppLaunchContainer"> <owner>benwells@chromium.org</owner> @@ -40041,6 +40059,9 @@ <histogram name="Net.JobControllerSet.CountOfNonPreconnectAltJob" units="alt_jobs"> + <obsolete> + Deprecated 08/2017. + </obsolete> <owner>zhongyi@chromium.org</owner> <summary> This counts number of alternative jobs which are still alive. @@ -40049,6 +40070,9 @@ <histogram name="Net.JobControllerSet.CountOfNonPreconnectMainJob" units="main_jobs"> + <obsolete> + Deprecated 08/2017. + </obsolete> <owner>zhongyi@chromium.org</owner> <summary>This counts number of main jobs which are still alive.</summary> </histogram> @@ -41015,6 +41039,15 @@ </summary> </histogram> +<histogram name="Net.PushedStreamAlreadyHasResponseHeaders" enum="Boolean"> + <owner>bnc@chromium.org</owner> + <summary> + Records whether HTTP/2 response headers have already arrived on a pushed + stream at the time the stream is matched up with a request. See + https://crbug.com/554220. + </summary> +</histogram> + <histogram name="Net.QuicActiveSessions"> <owner>rch@chromium.org</owner> <summary> @@ -94241,6 +94274,19 @@ name="RendererScheduler.QueueingDurationWhenExpectedQueueingTime"/> </histogram_suffixes> +<histogram_suffixes name="ExtensionContextType" separator="."> + <suffix name="BlessedExtensionContext" label="Blessed Extension Context"/> + <suffix name="BlessedWebPageContext" label="Blessed Web Page Context"/> + <suffix name="ContentScriptContext" label="Content Script Context"/> + <suffix name="LockScreenExtensionContext" + label="Lock Screen Extension Context"/> + <suffix name="WebPageContext" label="(unblessed) Web Page Context"/> + <suffix name="ServiceWorkerContext" label="Service Worker Context"/> + <suffix name="UnblessedExtensionContext" label="Unblessed Extension Context"/> + <suffix name="WebUIContext" label="WebUI Context"/> + <affected-histogram name="Extensions.Bindings.UpdateBindingsForContextTime"/> +</histogram_suffixes> + <histogram_suffixes name="ExtensionFunctionExecutionTime" separator="."> <suffix name="1msTo5ms" label="Execution took between 1ms and 5ms (tolerable)."/>
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index 5ab0fd6..076628e 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -148,8 +148,9 @@ prominent_colors[static_cast<int>(ColorProfileType::DARK_MUTED)]; if (SK_ColorTRANSPARENT == dark_muted) return app_list::AppListView::kDefaultBackgroundColor; - return color_utils::AlphaBlend(SK_ColorBLACK, dark_muted, - app_list::AppListView::kDarkMutedBlendAlpha); + return color_utils::GetResultingPaintColor( + SkColorSetA(SK_ColorBLACK, AppListView::kAppListColorDarkenAlpha), + dark_muted); } DEFINE_UI_CLASS_PROPERTY_KEY(bool, kExcludeWindowFromEventHandling, false);
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h index f6ae8988..2534b91 100644 --- a/ui/app_list/views/app_list_view.h +++ b/ui/app_list/views/app_list_view.h
@@ -60,7 +60,7 @@ static constexpr float kAppListOpacityWithBlur = 0.7; // The preferred blend alpha with wallpaper color for background. - static constexpr int kDarkMutedBlendAlpha = 0x3f; + static constexpr int kAppListColorDarkenAlpha = 178; // The defualt color of the app list background. static constexpr SkColor kDefaultBackgroundColor = SK_ColorBLACK;
diff --git a/ui/views/controls/button/checkbox.cc b/ui/views/controls/button/checkbox.cc index d3535f0..cba9fbd6 100644 --- a/ui/views/controls/button/checkbox.cc +++ b/ui/views/controls/button/checkbox.cc
@@ -27,6 +27,8 @@ namespace views { +constexpr int kFocusRingThicknessDip = 2; + // View used to paint the focus ring around the Checkbox icon. // The icon is painted separately. class IconFocusRing : public View { @@ -50,7 +52,7 @@ void IconFocusRing::Layout() { gfx::Rect focus_bounds = checkbox_->image()->bounds(); - focus_bounds.Inset(gfx::Insets(-2.f)); + focus_bounds.Inset(-kFocusRingThicknessDip, -kFocusRingThicknessDip); SetBoundsRect(focus_bounds); } @@ -248,7 +250,9 @@ void Checkbox::PaintFocusRing(View* view, gfx::Canvas* canvas, const cc::PaintFlags& flags) { - canvas->DrawRoundRect(view->GetLocalBounds(), 2.f, flags); + gfx::RectF bounds(view->GetLocalBounds()); + bounds.Inset(kFocusRingThicknessDip, kFocusRingThicknessDip); + canvas->DrawRoundRect(bounds, kFocusRingThicknessDip, flags); } const gfx::VectorIcon& Checkbox::GetVectorIcon() const {
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html index 98bc7ed..80e7d76 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.html
@@ -27,6 +27,7 @@ border: 2px solid rgba(66, 133, 244, 0.6); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.17); margin: 4px; + outline: none; } iron-icon { @@ -51,7 +52,7 @@ } </style> - <div id="container" tabindex="0"> + <div id="container"> <iron-a11y-keys keys="up down left right space enter" on-keys-pressed="onKeysPressed_"> </iron-a11y-keys>
diff --git a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js index 46a462b..990aaf67 100644 --- a/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js +++ b/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_picture_list.js
@@ -39,6 +39,7 @@ selectedItem: { type: Object, notify: true, + observer: 'onImageSelected_', }, /** @@ -92,7 +93,21 @@ fallbackImage_: null, setFocus: function() { - this.$.container.focus(); + if (this.selectedItem) { + this.selectedItem.focus(); + } + }, + + onImageSelected_: function(newImg, oldImg) { + if (newImg) { + newImg.setAttribute('tabindex', '0'); + newImg.setAttribute('aria-checked', 'true'); + newImg.focus(); + } + if (oldImg) { + oldImg.removeAttribute('tabindex'); + oldImg.removeAttribute('aria-checked'); + } }, /**