diff --git a/DEPS b/DEPS index b62fcb3..39509e7 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,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': 'c7165c239a0068b0b79b1bbe63e2a22bcb53ae38', + 'skia_revision': 'a634b742320ae1c14ddb296e45569947daced9fc', # 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': '55eb1195b010521a1e005f2aad1494cef0c3d1d4', + 'v8_revision': 'ec7987147a99c0102a282559cd18a4a6b75d8a5c', # 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. @@ -63,7 +63,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': '6c659ab22988716c0f578460a2048663ab93805a', + 'pdfium_revision': 'd66f9d0b1fb0af57960f9c7163c475968505ee4a', # 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. @@ -95,7 +95,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '5b5774b1223d05518b1d75da409297ebcf93e24a', + 'catapult_revision': 'e310b666b43f0ac98d4c9c46e0e9df3569ef69aa', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/ash/common/wm/forwarding_layer_delegate.cc b/ash/common/wm/forwarding_layer_delegate.cc index 55a1204..50d33c4 100644 --- a/ash/common/wm/forwarding_layer_delegate.cc +++ b/ash/common/wm/forwarding_layer_delegate.cc
@@ -5,7 +5,6 @@ #include "ash/common/wm/forwarding_layer_delegate.h" #include "ash/common/wm_window.h" -#include "base/callback.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_owner.h" @@ -36,10 +35,6 @@ // on cloned layer because the original layer is still on the same display. } -base::Closure ForwardingLayerDelegate::PrepareForLayerBoundsChange() { - return base::Closure(); -} - void ForwardingLayerDelegate::DidPaintLayer(ui::Layer* layer, const gfx::Rect& rect) { client_layer_->SchedulePaint(rect);
diff --git a/ash/common/wm/forwarding_layer_delegate.h b/ash/common/wm/forwarding_layer_delegate.h index 446db9c..7c68f18 100644 --- a/ash/common/wm/forwarding_layer_delegate.h +++ b/ash/common/wm/forwarding_layer_delegate.h
@@ -33,7 +33,6 @@ void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; // ui::LayerObserver: void DidPaintLayer(ui::Layer* layer, const gfx::Rect& rect) override;
diff --git a/ash/magnifier/partial_magnification_controller.cc b/ash/magnifier/partial_magnification_controller.cc index d9abb5c..784ed1f5 100644 --- a/ash/magnifier/partial_magnification_controller.cc +++ b/ash/magnifier/partial_magnification_controller.cc
@@ -129,10 +129,6 @@ // Redrawing will take care of scale factor change. } - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - ui::Layer layer_; bool is_border_; DISALLOW_COPY_AND_ASSIGN(ContentMask); @@ -201,10 +197,6 @@ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - gfx::Rect magnifier_window_bounds_; std::vector<gfx::ShadowValue> magnifier_shadows_;
diff --git a/ash/utility/screenshot_controller.cc b/ash/utility/screenshot_controller.cc index e0c8d43..7411372 100644 --- a/ash/utility/screenshot_controller.cc +++ b/ash/utility/screenshot_controller.cc
@@ -145,10 +145,6 @@ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - // Mouse cursor may move sub DIP, so paint pseudo cursor instead of // using platform cursor so that it's aliend with the region. void DrawPseudoCursor(gfx::Canvas* canvas) {
diff --git a/ash/wm/boot_splash_screen_chromeos.cc b/ash/wm/boot_splash_screen_chromeos.cc index 2e4fd783..7582ae09 100644 --- a/ash/wm/boot_splash_screen_chromeos.cc +++ b/ash/wm/boot_splash_screen_chromeos.cc
@@ -55,10 +55,6 @@ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - private: #if defined(USE_X11) aura::WindowTreeHost* host_; // not owned
diff --git a/ash/wm/drag_window_resizer_unittest.cc b/ash/wm/drag_window_resizer_unittest.cc index 56ed6a36..e0bca7e 100644 --- a/ash/wm/drag_window_resizer_unittest.cc +++ b/ash/wm/drag_window_resizer_unittest.cc
@@ -53,9 +53,6 @@ } void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } int paint_count_ = 0;
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc index 45ee22d..4f3e0c76 100644 --- a/base/metrics/field_trial.cc +++ b/base/metrics/field_trial.cc
@@ -7,7 +7,10 @@ #include <algorithm> #include <utility> +#include "base/base_switches.h" #include "base/build_time.h" +#include "base/command_line.h" +#include "base/feature_list.h" #include "base/logging.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" @@ -28,6 +31,14 @@ // command line which forces its activation. const char kActivationMarker = '*'; +// Use shared memory to communicate field trial (experiment) state. Set to false +// for now while the implementation is fleshed out (e.g. data format, single +// shared memory segment). See https://codereview.chromium.org/2365273004/ and +// crbug.com/653874 +#if defined(OS_WIN) +const bool kUseSharedMemoryForFieldTrials = false; +#endif + // Created a time value based on |year|, |month| and |day_of_month| parameters. Time CreateTimeFromParams(int year, int month, int day_of_month) { DCHECK_GT(year, 1970); @@ -558,6 +569,77 @@ } // static +void FieldTrialList::CreateTrialsFromCommandLine( + const base::CommandLine& cmd_line, + const char* field_trial_handle_switch) { + DCHECK(global_); + +#if defined(OS_WIN) + if (cmd_line.HasSwitch(field_trial_handle_switch)) { + std::string arg = cmd_line.GetSwitchValueASCII(field_trial_handle_switch); + size_t token = arg.find(","); + int field_trial_handle = std::stoi(arg.substr(0, token)); + int field_trial_length = std::stoi(arg.substr(token + 1, arg.length())); + + HANDLE handle = reinterpret_cast<HANDLE>(field_trial_handle); + base::SharedMemoryHandle shm_handle = + base::SharedMemoryHandle(handle, base::GetCurrentProcId()); + + // Gets deleted when it gets out of scope, but that's OK because we need it + // only for the duration of this call currently anyway. + base::SharedMemory shared_memory(shm_handle, false); + shared_memory.Map(field_trial_length); + + char* field_trial_state = static_cast<char*>(shared_memory.memory()); + bool result = FieldTrialList::CreateTrialsFromString( + std::string(field_trial_state), std::set<std::string>()); + DCHECK(result); + return; + } +#endif + + if (cmd_line.HasSwitch(switches::kForceFieldTrials)) { + bool result = FieldTrialList::CreateTrialsFromString( + cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials), + std::set<std::string>()); + DCHECK(result); + } +} + +// static +std::unique_ptr<base::SharedMemory> FieldTrialList::CopyFieldTrialStateToFlags( + const char* field_trial_handle_switch, + base::CommandLine* cmd_line) { + std::string field_trial_states; + base::FieldTrialList::AllStatesToString(&field_trial_states); + if (!field_trial_states.empty()) { +// Use shared memory to pass the state if the feature is enabled, otherwise +// fallback to passing it via the command line as a string. +#if defined(OS_WIN) + if (kUseSharedMemoryForFieldTrials) { + std::unique_ptr<base::SharedMemory> shm(new base::SharedMemory()); + size_t length = field_trial_states.size() + 1; + shm->CreateAndMapAnonymous(length); + memcpy(shm->memory(), field_trial_states.c_str(), length); + + // HANDLE is just typedef'd to void * + auto uintptr_handle = + reinterpret_cast<std::uintptr_t>(shm->handle().GetHandle()); + std::string field_trial_handle = + std::to_string(uintptr_handle) + "," + std::to_string(length); + + cmd_line->AppendSwitchASCII(field_trial_handle_switch, + field_trial_handle); + return shm; + } +#endif + cmd_line->AppendSwitchASCII(switches::kForceFieldTrials, + field_trial_states); + } + return std::unique_ptr<base::SharedMemory>(nullptr); +} + +// static FieldTrial* FieldTrialList::CreateFieldTrial( const std::string& name, const std::string& group_name) {
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h index 2b88949..99e705a1 100644 --- a/base/metrics/field_trial.h +++ b/base/metrics/field_trial.h
@@ -64,9 +64,11 @@ #include <vector> #include "base/base_export.h" +#include "base/command_line.h" #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/shared_memory.h" #include "base/observer_list_threadsafe.h" #include "base/strings/string_piece.h" #include "base/synchronization/lock.h" @@ -464,6 +466,28 @@ const std::string& trials_string, const std::set<std::string>& ignored_trial_names); + // Achieves the same thing as CreateTrialsFromString, except wraps the logic + // by taking in the trials from the command line, either via shared memory + // handle or command line argument. + // If using shared memory to pass around the list of field trials, then + // expects |field_trial_handle_switch| command line argument to + // contain the shared memory handle. + // If not, then create the trials as before (using the kForceFieldTrials + // switch). Needs the |field_trial_handle_switch| argument to be passed in + // since base/ can't depend on content/. + static void CreateTrialsFromCommandLine( + const base::CommandLine& cmd_line, + const char* field_trial_handle_switch); + + // Adds a switch to the command line containing the field trial state as a + // string (if not using shared memory to share field trial state), or the + // shared memory handle + length. + // Needs the |field_trial_handle_switch| argument to be passed in since base/ + // can't depend on content/. + static std::unique_ptr<base::SharedMemory> CopyFieldTrialStateToFlags( + const char* field_trial_handle_switch, + base::CommandLine* cmd_line); + // Create a FieldTrial with the given |name| and using 100% probability for // the FieldTrial, force FieldTrial to have the same group string as // |group_name|. This is commonly used in a non-browser process, to carry
diff --git a/base/metrics/field_trial_unittest.cc b/base/metrics/field_trial_unittest.cc index caa00e8..bb45bd71 100644 --- a/base/metrics/field_trial_unittest.cc +++ b/base/metrics/field_trial_unittest.cc
@@ -6,14 +6,18 @@ #include <stddef.h> +#include "base/base_switches.h" #include "base/build_time.h" +#include "base/feature_list.h" #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/rand_util.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/test/gtest_util.h" +#include "base/test/mock_entropy_provider.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -1132,4 +1136,19 @@ ""); } +TEST(FieldTrialListTest, TestCopyFieldTrialStateToFlags) { + base::FieldTrialList field_trial_list( + base::MakeUnique<base::MockEntropyProvider>()); + base::FieldTrialList::CreateFieldTrial("Trial1", "Group1"); + base::FilePath test_file_path = base::FilePath(FILE_PATH_LITERAL("Program")); + base::CommandLine cmd_line = base::CommandLine(test_file_path); + + std::unique_ptr<base::SharedMemory> field_trial_state = + base::FieldTrialList::CopyFieldTrialStateToFlags("field-trial-handle", + &cmd_line); + + EXPECT_TRUE(field_trial_state.get() == nullptr); + EXPECT_TRUE(cmd_line.HasSwitch(switches::kForceFieldTrials)); +} + } // namespace base
diff --git a/base/synchronization/lock_impl_win.cc b/base/synchronization/lock_impl_win.cc index ef03267..31f95f4 100644 --- a/base/synchronization/lock_impl_win.cc +++ b/base/synchronization/lock_impl_win.cc
@@ -18,8 +18,7 @@ } void LockImpl::Lock() { - // Commented out pending https://crbug.com/652432 - // base::debug::ScopedLockAcquireActivity lock_activity(this); + base::debug::ScopedLockAcquireActivity lock_activity(this); ::AcquireSRWLockExclusive(&native_handle_); }
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index e6880fa54f..1e2a95b0 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -90,6 +90,10 @@ // the infrastructure. const size_t kOutputSnippetLinesLimit = 5000; +// Limit of output snippet size. Exceeding this limit +// results in truncating the output and failing the test. +const size_t kOutputSnippetBytesLimit = 2.5 * 1024 * 1024; + // Set of live launch test processes with corresponding lock (it is allowed // for callers to launch processes on different threads). LazyInstance<std::map<ProcessHandle, CommandLine> > g_live_processes @@ -568,9 +572,21 @@ launched_callback)); } -void TestLauncher::OnTestFinished(const TestResult& result) { +void TestLauncher::OnTestFinished(const TestResult& original_result) { ++test_finished_count_; + TestResult result(original_result); + + if (result.output_snippet.length() > kOutputSnippetBytesLimit) { + if (result.status == TestResult::TEST_SUCCESS) + result.status = TestResult::TEST_EXCESSIVE_OUTPUT; + result.output_snippet = StringPrintf( + "<truncated (%" PRIuS " bytes)>\n", result.output_snippet.length()) + + result.output_snippet.substr( + result.output_snippet.length() - kOutputSnippetLinesLimit) + + "\n"; + } + bool print_snippet = false; std::string print_test_stdio("auto"); if (CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/base/test/launcher/test_result.cc b/base/test/launcher/test_result.cc index e7320258..39e20e7 100644 --- a/base/test/launcher/test_result.cc +++ b/base/test/launcher/test_result.cc
@@ -32,6 +32,8 @@ return "TIMEOUT"; case TEST_SKIPPED: return "SKIPPED"; + case TEST_EXCESSIVE_OUTPUT: + return "EXCESSIVE_OUTPUT"; // Rely on compiler warnings to ensure all possible values are handled. }
diff --git a/base/test/launcher/test_result.h b/base/test/launcher/test_result.h index b61cdd4..19c6ba5 100644 --- a/base/test/launcher/test_result.h +++ b/base/test/launcher/test_result.h
@@ -14,13 +14,14 @@ // Structure containing result of a single test. struct TestResult { enum Status { - TEST_UNKNOWN, // Status not set. - TEST_SUCCESS, // Test passed. - TEST_FAILURE, // Assertion failure (think EXPECT_TRUE, not DCHECK). - TEST_FAILURE_ON_EXIT, // Test passed but executable exit code was non-zero. - TEST_TIMEOUT, // Test timed out and was killed. - TEST_CRASH, // Test crashed (includes CHECK/DCHECK failures). - TEST_SKIPPED, // Test skipped (not run at all). + TEST_UNKNOWN, // Status not set. + TEST_SUCCESS, // Test passed. + TEST_FAILURE, // Assertion failure (e.g. EXPECT_TRUE, not DCHECK). + TEST_FAILURE_ON_EXIT, // Passed but executable exit code was non-zero. + TEST_TIMEOUT, // Test timed out and was killed. + TEST_CRASH, // Test crashed (includes CHECK/DCHECK failures). + TEST_SKIPPED, // Test skipped (not run at all). + TEST_EXCESSIVE_OUTPUT, // Test exceeded output limit. }; TestResult(); @@ -41,7 +42,8 @@ bool completed() const { return status == TEST_SUCCESS || status == TEST_FAILURE || - status == TEST_FAILURE_ON_EXIT; + status == TEST_FAILURE_ON_EXIT || + status == TEST_EXCESSIVE_OUTPUT; } // Full name of the test (e.g. "A.B").
diff --git a/base/test/launcher/test_results_tracker.cc b/base/test/launcher/test_results_tracker.cc index a8611ae..6b56761 100644 --- a/base/test/launcher/test_results_tracker.cc +++ b/base/test/launcher/test_results_tracker.cc
@@ -65,6 +65,7 @@ case TestResult::TEST_FAILURE: failures++; break; + case TestResult::TEST_EXCESSIVE_OUTPUT: case TestResult::TEST_FAILURE_ON_EXIT: case TestResult::TEST_TIMEOUT: case TestResult::TEST_CRASH: @@ -247,6 +248,9 @@ PrintTests(tests_by_status[TestResult::TEST_FAILURE_ON_EXIT].begin(), tests_by_status[TestResult::TEST_FAILURE_ON_EXIT].end(), "failed on exit"); + PrintTests(tests_by_status[TestResult::TEST_EXCESSIVE_OUTPUT].begin(), + tests_by_status[TestResult::TEST_EXCESSIVE_OUTPUT].end(), + "produced excessive output"); PrintTests(tests_by_status[TestResult::TEST_TIMEOUT].begin(), tests_by_status[TestResult::TEST_TIMEOUT].end(), "timed out"); @@ -275,6 +279,9 @@ PrintTests(tests_by_status[TestResult::TEST_FAILURE_ON_EXIT].begin(), tests_by_status[TestResult::TEST_FAILURE_ON_EXIT].end(), "failed on exit"); + PrintTests(tests_by_status[TestResult::TEST_EXCESSIVE_OUTPUT].begin(), + tests_by_status[TestResult::TEST_EXCESSIVE_OUTPUT].end(), + "produced excessive output"); PrintTests(tests_by_status[TestResult::TEST_TIMEOUT].begin(), tests_by_status[TestResult::TEST_TIMEOUT].end(), "timed out");
diff --git a/base/trace_event/common/trace_event_common.h b/base/trace_event/common/trace_event_common.h index 182ed5f..e87665b8 100644 --- a/base/trace_event/common/trace_event_common.h +++ b/base/trace_event/common/trace_event_common.h
@@ -953,15 +953,15 @@ INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) // Macro to specify that two trace IDs are identical. For example, -// TRACE_BIND_IDS( +// TRACE_LINK_IDS( // "category", "name", // TRACE_ID_WITH_SCOPE("net::URLRequest", 0x1000), // TRACE_ID_WITH_SCOPE("blink::ResourceFetcher::FetchRequest", 0x2000)) // tells the trace consumer that events with ID ("net::URLRequest", 0x1000) from // the current process have the same ID as events with ID // ("blink::ResourceFetcher::FetchRequest", 0x2000). -#define TRACE_BIND_IDS(category_group, name, id, bind_id) \ - INTERNAL_TRACE_EVENT_ADD_BIND_IDS(category_group, name, id, bind_id); +#define TRACE_LINK_IDS(category_group, name, id, linked_id) \ + INTERNAL_TRACE_EVENT_ADD_LINK_IDS(category_group, name, id, linked_id); // Macro to efficiently determine if a given category group is enabled. #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret) \ @@ -1028,7 +1028,7 @@ #define TRACE_EVENT_PHASE_CLOCK_SYNC ('c') #define TRACE_EVENT_PHASE_ENTER_CONTEXT ('(') #define TRACE_EVENT_PHASE_LEAVE_CONTEXT (')') -#define TRACE_EVENT_PHASE_BIND_IDS ('=') +#define TRACE_EVENT_PHASE_LINK_IDS ('=') // Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT. #define TRACE_EVENT_FLAG_NONE (static_cast<unsigned int>(0))
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h index eca7c070..20ce662e 100644 --- a/base/trace_event/trace_event.h +++ b/base/trace_event/trace_event.h
@@ -335,29 +335,20 @@ } \ } while (0) -// This macro ignores whether the bind_id is local, global, or mangled. -#define INTERNAL_TRACE_EVENT_ADD_BIND_IDS(category_group, name, id, bind_id, \ - ...) \ +// The linked ID will not be mangled. +#define INTERNAL_TRACE_EVENT_ADD_LINK_IDS(category_group, name, id1, id2) \ do { \ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \ - trace_event_internal::TraceID source_id((id)); \ + trace_event_internal::TraceID source_id((id1)); \ unsigned int source_flags = source_id.id_flags(); \ - trace_event_internal::TraceID target_id((bind_id)); \ - if (target_id.scope() == trace_event_internal::kGlobalScope) { \ - trace_event_internal::AddTraceEvent( \ - TRACE_EVENT_PHASE_BIND_IDS, \ - INTERNAL_TRACE_EVENT_UID(category_group_enabled), \ - name, source_id.scope(), source_id.raw_id(), \ - source_flags, target_id.raw_id(), ##__VA_ARGS__); \ - } else { \ - trace_event_internal::AddTraceEvent( \ - TRACE_EVENT_PHASE_BIND_IDS, \ - INTERNAL_TRACE_EVENT_UID(category_group_enabled), \ - name, source_id.scope(), source_id.raw_id(), \ - source_flags, target_id.raw_id(), \ - "bind_scope", target_id.scope(), ##__VA_ARGS__); \ - } \ + trace_event_internal::TraceID target_id((id2)); \ + trace_event_internal::AddTraceEvent( \ + TRACE_EVENT_PHASE_LINK_IDS, \ + INTERNAL_TRACE_EVENT_UID(category_group_enabled), \ + name, source_id.scope(), source_id.raw_id(), source_flags, \ + trace_event_internal::kNoId, \ + "linked_id", target_id.AsConvertableToTraceFormat()); \ } \ } while (0) @@ -415,7 +406,7 @@ // TraceID encapsulates an ID that can either be an integer or pointer. Pointers // are by default mangled with the Process ID so that they are unlikely to // collide when the same pointer is used on different processes. -class TraceID { +class BASE_EXPORT TraceID { public: // Can be combined with WithScope. class LocalId { @@ -541,6 +532,9 @@ const char* scope() const { return scope_; } unsigned int id_flags() const { return id_flags_; } + std::unique_ptr<base::trace_event::ConvertableToTraceFormat> + AsConvertableToTraceFormat() const; + private: const char* scope_ = nullptr; unsigned long long raw_id_;
diff --git a/base/trace_event/trace_event_impl.cc b/base/trace_event/trace_event_impl.cc index d41500d..f9792d0d 100644 --- a/base/trace_event/trace_event_impl.cc +++ b/base/trace_event/trace_event_impl.cc
@@ -8,6 +8,7 @@ #include "base/format_macros.h" #include "base/json/string_escape.h" +#include "base/memory/ptr_util.h" #include "base/process/process_handle.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" @@ -15,6 +16,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" +#include "base/trace_event/trace_event_argument.h" #include "base/trace_event/trace_log.h" namespace base { @@ -391,8 +393,7 @@ StringAppendF(out, ",\"bp\":\"e\""); if ((flags_ & TRACE_EVENT_FLAG_FLOW_OUT) || - (flags_ & TRACE_EVENT_FLAG_FLOW_IN) || - phase_ == TRACE_EVENT_PHASE_BIND_IDS) { + (flags_ & TRACE_EVENT_FLAG_FLOW_IN)) { StringAppendF(out, ",\"bind_id\":\"0x%" PRIx64 "\"", static_cast<uint64_t>(bind_id_)); } @@ -448,3 +449,40 @@ } // namespace trace_event } // namespace base + +namespace trace_event_internal { + +std::unique_ptr<base::trace_event::ConvertableToTraceFormat> +TraceID::AsConvertableToTraceFormat() const { + auto value = base::MakeUnique<base::trace_event::TracedValue>(); + + if (scope_ != kGlobalScope) + value->SetString("scope", scope_); + switch (id_flags_) { + case TRACE_EVENT_FLAG_HAS_ID: + value->SetString( + "id", + base::StringPrintf("0x%" PRIx64, static_cast<uint64_t>(raw_id_))); + break; + case TRACE_EVENT_FLAG_HAS_GLOBAL_ID: + value->BeginDictionary("id2"); + value->SetString( + "global", + base::StringPrintf("0x%" PRIx64, static_cast<uint64_t>(raw_id_))); + value->EndDictionary(); + break; + case TRACE_EVENT_FLAG_HAS_LOCAL_ID: + value->BeginDictionary("id2"); + value->SetString( + "local", + base::StringPrintf("0x%" PRIx64, static_cast<uint64_t>(raw_id_))); + value->EndDictionary(); + break; + default: + NOTREACHED() << "Unrecognized ID flag"; + } + + return std::move(value); +} + +} // namespace trace_event_internal
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc index cec48b78..84553781 100644 --- a/base/trace_event/trace_event_unittest.cc +++ b/base/trace_event/trace_event_unittest.cc
@@ -31,6 +31,7 @@ #include "base/threading/thread.h" #include "base/time/time.h" #include "base/trace_event/trace_buffer.h" +#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_synthetic_delay.h" #include "base/values.h" #include "testing/gmock/include/gmock/gmock.h" @@ -520,10 +521,14 @@ TRACE_EVENT_SCOPED_CONTEXT("all", "TRACE_EVENT_SCOPED_CONTEXT call", context_id); - TRACE_BIND_IDS("all", "TRACE_BIND_IDS simple call", 0x1000, 0x2000); - TRACE_BIND_IDS("all", "TRACE_BIND_IDS scoped call", + TRACE_LINK_IDS("all", "TRACE_LINK_IDS simple call", 0x1000, 0x2000); + TRACE_LINK_IDS("all", "TRACE_LINK_IDS scoped call", TRACE_ID_WITH_SCOPE("scope 1", 0x1000), TRACE_ID_WITH_SCOPE("scope 2", 0x2000)); + TRACE_LINK_IDS("all", "TRACE_LINK_IDS to a local ID", 0x1000, + TRACE_ID_LOCAL(0x2000)); + TRACE_LINK_IDS("all", "TRACE_LINK_IDS to a global ID", 0x1000, + TRACE_ID_GLOBAL(0x2000)); TRACE_EVENT_ASYNC_BEGIN0("all", "async default process scope", 0x1000); TRACE_EVENT_ASYNC_BEGIN0("all", "async local id", TRACE_ID_LOCAL(0x2000)); @@ -972,42 +977,76 @@ EXPECT_EQ("0x20151021", id); } - EXPECT_FIND_("TRACE_BIND_IDS simple call"); + EXPECT_FIND_("TRACE_LINK_IDS simple call"); { std::string ph; EXPECT_TRUE((item && item->GetString("ph", &ph))); EXPECT_EQ("=", ph); EXPECT_FALSE((item && item->HasKey("scope"))); - std::string id; - EXPECT_TRUE((item && item->GetString("id", &id))); - EXPECT_EQ("0x1000", id); + std::string id1; + EXPECT_TRUE((item && item->GetString("id", &id1))); + EXPECT_EQ("0x1000", id1); - EXPECT_FALSE((item && item->HasKey("args.bind_scope"))); - std::string bind_id; - EXPECT_TRUE((item && item->GetString("bind_id", &id))); - EXPECT_EQ("0x2000", id); + EXPECT_FALSE((item && item->HasKey("args.linked_id.scope"))); + std::string id2; + EXPECT_TRUE((item && item->GetString("args.linked_id.id", &id2))); + EXPECT_EQ("0x2000", id2); } - EXPECT_FIND_("TRACE_BIND_IDS scoped call"); + EXPECT_FIND_("TRACE_LINK_IDS scoped call"); { std::string ph; EXPECT_TRUE((item && item->GetString("ph", &ph))); EXPECT_EQ("=", ph); - std::string id_scope; - EXPECT_TRUE((item && item->GetString("scope", &id_scope))); - EXPECT_EQ("scope 1", id_scope); - std::string id; - EXPECT_TRUE((item && item->GetString("id", &id))); - EXPECT_EQ("0x1000", id); + std::string scope1; + EXPECT_TRUE((item && item->GetString("scope", &scope1))); + EXPECT_EQ("scope 1", scope1); + std::string id1; + EXPECT_TRUE((item && item->GetString("id", &id1))); + EXPECT_EQ("0x1000", id1); - std::string bind_scope; - EXPECT_TRUE((item && item->GetString("args.bind_scope", &bind_scope))); - EXPECT_EQ("scope 2", bind_scope); - std::string bind_id; - EXPECT_TRUE((item && item->GetString("bind_id", &id))); - EXPECT_EQ("0x2000", id); + std::string scope2; + EXPECT_TRUE((item && item->GetString("args.linked_id.scope", &scope2))); + EXPECT_EQ("scope 2", scope2); + std::string id2; + EXPECT_TRUE((item && item->GetString("args.linked_id.id", &id2))); + EXPECT_EQ("0x2000", id2); + } + + EXPECT_FIND_("TRACE_LINK_IDS to a local ID"); + { + std::string ph; + EXPECT_TRUE((item && item->GetString("ph", &ph))); + EXPECT_EQ("=", ph); + + EXPECT_FALSE((item && item->HasKey("scope"))); + std::string id1; + EXPECT_TRUE((item && item->GetString("id", &id1))); + EXPECT_EQ("0x1000", id1); + + EXPECT_FALSE((item && item->HasKey("args.linked_id.scope"))); + std::string id2; + EXPECT_TRUE((item && item->GetString("args.linked_id.id2.local", &id2))); + EXPECT_EQ("0x2000", id2); + } + + EXPECT_FIND_("TRACE_LINK_IDS to a global ID"); + { + std::string ph; + EXPECT_TRUE((item && item->GetString("ph", &ph))); + EXPECT_EQ("=", ph); + + EXPECT_FALSE((item && item->HasKey("scope"))); + std::string id1; + EXPECT_TRUE((item && item->GetString("id", &id1))); + EXPECT_EQ("0x1000", id1); + + EXPECT_FALSE((item && item->HasKey("args.linked_id.scope"))); + std::string id2; + EXPECT_TRUE((item && item->GetString("args.linked_id.id2.global", &id2))); + EXPECT_EQ("0x2000", id2); } EXPECT_FIND_("async default process scope");
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index 4bf52d5..9b96db7 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h
@@ -155,6 +155,7 @@ virtual void MouseMoveAt(const gfx::Point& mouse_position) = 0; virtual void MouseDown() = 0; virtual void MouseUp() = 0; + virtual void MouseLeave() = 0; // Stop scrolling the selected layer. Should only be called if ScrollBegin() // returned SCROLL_STARTED.
diff --git a/cc/input/scrollbar_animation_controller_thinning.cc b/cc/input/scrollbar_animation_controller_thinning.cc index 4324a43..74352996 100644 --- a/cc/input/scrollbar_animation_controller_thinning.cc +++ b/cc/input/scrollbar_animation_controller_thinning.cc
@@ -82,6 +82,9 @@ } void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar() { + if (!mouse_is_over_scrollbar_ && !mouse_is_near_scrollbar_) + return; + mouse_is_over_scrollbar_ = false; mouse_is_near_scrollbar_ = false;
diff --git a/cc/input/scrollbar_animation_controller_thinning_unittest.cc b/cc/input/scrollbar_animation_controller_thinning_unittest.cc index 4824879..64096b7 100644 --- a/cc/input/scrollbar_animation_controller_thinning_unittest.cc +++ b/cc/input/scrollbar_animation_controller_thinning_unittest.cc
@@ -518,5 +518,40 @@ } } +// Move mouse on scrollbar and capture then move out of window. Confirm that +// the bar stays thick and dark. +TEST_F(ScrollbarAnimationControllerThinningTest, + MouseCapturedAndExitWindowFromScrollbar) { + base::TimeTicks time; + time += base::TimeDelta::FromSeconds(1); + + // Move in + scrollbar_controller_->DidMouseMoveNear(0); + + scrollbar_controller_->Animate(time); + time += base::TimeDelta::FromSeconds(kDuration); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + + // Capture + scrollbar_controller_->DidCaptureScrollbarBegin(); + time += base::TimeDelta::FromSeconds(1); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + + // move out of window + scrollbar_controller_->DidMouseMoveOffScrollbar(); + + // test for 10 seconds, stay thick and dark + for (int i = 0; i < 10; ++i) { + time += base::TimeDelta::FromSeconds(1); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + } +} + } // namespace } // namespace cc
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h index 16ee4d6b..e320425 100644 --- a/cc/scheduler/scheduler_state_machine.h +++ b/cc/scheduler/scheduler_state_machine.h
@@ -322,7 +322,6 @@ int prepare_tiles_funnel_; int consecutive_checkerboard_animations_; - int max_pending_swaps_; int pending_swaps_; int swaps_with_current_compositor_frame_sink_; bool needs_redraw_;
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 784693e8..1ed7cfb 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -3279,6 +3279,13 @@ active_tree_->device_scale_factor()); } +void LayerTreeHostImpl::MouseLeave() { + for (auto& pair : scrollbar_animation_controllers_) + pair.second->DidMouseMoveOffScrollbar(); + + scroll_layer_id_when_mouse_over_scrollbar_ = Layer::INVALID_ID; +} + void LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl) { int new_id = Layer::INVALID_ID; if (layer_impl && layer_impl->ToScrollbarLayer())
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 23db006..cdb2573 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -180,6 +180,7 @@ void MouseDown() override; void MouseUp() override; void MouseMoveAt(const gfx::Point& viewport_point) override; + void MouseLeave() override; void PinchGestureBegin() override; void PinchGestureUpdate(float magnify_delta,
diff --git a/chrome/android/java/res/layout/bottom_control_container.xml b/chrome/android/java/res/layout/bottom_control_container.xml new file mode 100644 index 0000000..4c433af --- /dev/null +++ b/chrome/android/java/res/layout/bottom_control_container.xml
@@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="match_parent" + android:layout_width="wrap_content"> + <org.chromium.chrome.browser.toolbar.ToolbarControlContainer + android:id="@+id/control_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:gravity="bottom" + android:minHeight="@dimen/control_container_height" > + <view + class="org.chromium.chrome.browser.toolbar.ToolbarControlContainer$ToolbarViewResourceFrameLayout" + android:id="@+id/toolbar_container" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <ImageView + android:id="@+id/toolbar_shadow" + android:layout_width="match_parent" + android:layout_height="@dimen/toolbar_shadow_height" + android:src="@drawable/toolbar_shadow" + android:scaleType="fitXY" + android:scaleY="-1" + android:contentDescription="@null" /> + <ViewStub + android:id="@+id/toolbar_stub" + android:layout_width="match_parent" + android:layout_height="@dimen/toolbar_height_no_shadow" + android:layout_marginTop="@dimen/toolbar_shadow_height" /> + <ViewStub + android:id="@+id/find_toolbar_stub" + android:inflatedId="@+id/find_toolbar" + android:visibility="gone" + android:layout_marginTop="@dimen/toolbar_shadow_height" + android:layout_width="match_parent" + android:layout_height="@dimen/toolbar_height_no_shadow" + android:layout="@layout/find_toolbar" /> + </view> + </org.chromium.chrome.browser.toolbar.ToolbarControlContainer> +</RelativeLayout>
diff --git a/chrome/android/java/res/layout/control_container.xml b/chrome/android/java/res/layout/control_container.xml index a771aff..03f5294 100644 --- a/chrome/android/java/res/layout/control_container.xml +++ b/chrome/android/java/res/layout/control_container.xml
@@ -12,12 +12,11 @@ android:id="@+id/toolbar_container" android:layout_width="match_parent" android:layout_height="wrap_content"> - <include - android:id="@+id/toolbar" + <ViewStub + android:id="@+id/toolbar_stub" android:layout_width="match_parent" android:layout_marginTop="@dimen/tab_strip_height" - android:layout_height="@dimen/toolbar_height_no_shadow" - layout="@layout/toolbar" /> + android:layout_height="@dimen/toolbar_height_no_shadow" /> <ImageView android:id="@+id/toolbar_shadow" android:src="@drawable/toolbar_shadow"
diff --git a/chrome/android/java/res/layout/custom_tabs_control_container.xml b/chrome/android/java/res/layout/custom_tabs_control_container.xml index 87b45c7..1b2662db 100644 --- a/chrome/android/java/res/layout/custom_tabs_control_container.xml +++ b/chrome/android/java/res/layout/custom_tabs_control_container.xml
@@ -12,11 +12,10 @@ android:id="@+id/toolbar_container" android:layout_width="match_parent" android:layout_height="wrap_content"> - <include - android:id="@+id/toolbar" + <ViewStub + android:id="@+id/toolbar_stub" android:layout_width="match_parent" - android:layout_height="@dimen/custom_tabs_control_container_height" - layout="@layout/custom_tabs_toolbar" /> + android:layout_height="@dimen/custom_tabs_control_container_height" /> <ImageView android:id="@+id/toolbar_shadow" android:src="@drawable/toolbar_shadow"
diff --git a/chrome/android/java/res/layout/custom_tabs_toolbar.xml b/chrome/android/java/res/layout/custom_tabs_toolbar.xml index c2d9ce5..ae41340 100644 --- a/chrome/android/java/res/layout/custom_tabs_toolbar.xml +++ b/chrome/android/java/res/layout/custom_tabs_toolbar.xml
@@ -5,7 +5,10 @@ <org.chromium.chrome.browser.toolbar.CustomTabToolbar xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:chrome="http://schemas.android.com/apk/res-auto" > + xmlns:chrome="http://schemas.android.com/apk/res-auto" + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="@dimen/custom_tabs_control_container_height" > <ImageButton android:id="@+id/close_button" style="@style/ToolbarButton"
diff --git a/chrome/android/java/res/layout/toolbar.xml b/chrome/android/java/res/layout/toolbar_phone.xml similarity index 86% rename from chrome/android/java/res/layout/toolbar.xml rename to chrome/android/java/res/layout/toolbar_phone.xml index 6c26288f..6c6fbfd 100644 --- a/chrome/android/java/res/layout/toolbar.xml +++ b/chrome/android/java/res/layout/toolbar_phone.xml
@@ -8,9 +8,10 @@ <org.chromium.chrome.browser.toolbar.ToolbarPhone xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="@dimen/toolbar_height_no_shadow" > - <include layout="@layout/toolbar_common"/> + <include layout="@layout/toolbar_phone_common"/> </org.chromium.chrome.browser.toolbar.ToolbarPhone>
diff --git a/chrome/android/java/res/layout/toolbar_common.xml b/chrome/android/java/res/layout/toolbar_phone_common.xml similarity index 100% rename from chrome/android/java/res/layout/toolbar_common.xml rename to chrome/android/java/res/layout/toolbar_phone_common.xml
diff --git a/chrome/android/java/res/layout-sw600dp/toolbar.xml b/chrome/android/java/res/layout/toolbar_tablet.xml similarity index 98% rename from chrome/android/java/res/layout-sw600dp/toolbar.xml rename to chrome/android/java/res/layout/toolbar_tablet.xml index f93f93f7..9699ff3 100644 --- a/chrome/android/java/res/layout-sw600dp/toolbar.xml +++ b/chrome/android/java/res/layout/toolbar_tablet.xml
@@ -8,6 +8,7 @@ <org.chromium.chrome.browser.toolbar.ToolbarTablet xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="@dimen/toolbar_height_no_shadow" android:layout_marginTop="@dimen/tab_strip_height"
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index de2c8202..a1b5e3dd 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -218,6 +218,7 @@ <dimen name="toolbar_tab_count_text_size_1_digit">12dp</dimen> <dimen name="toolbar_tab_count_text_size_2_digit">10dp</dimen> <dimen name="toolbar_height_no_shadow">56dp</dimen> + <dimen name="toolbar_shadow_height">8dp</dimen> <dimen name="toolbar_progress_bar_height">2dp</dimen> <dimen name="toolbar_button_width">48dp</dimen>
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 3c7cb47..da94f43 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -166,6 +166,11 @@ */ static final int NO_CONTROL_CONTAINER = -1; + /** + * No toolbar layout to inflate during initialization. + */ + static final int NO_TOOLBAR_LAYOUT = -1; + private static final int RECORD_MULTI_WINDOW_SCREEN_WIDTH_DELAY_MS = 5000; /** @@ -351,12 +356,19 @@ // of our control, so we have to disable StrictMode to work. See crbug.com/639352. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); try { + ControlContainer controlContainer = null; setContentView(R.layout.main); if (controlContainerLayoutId != NO_CONTROL_CONTAINER) { ViewStub toolbarContainerStub = ((ViewStub) findViewById(R.id.control_container_stub)); toolbarContainerStub.setLayoutResource(controlContainerLayoutId); - toolbarContainerStub.inflate(); + controlContainer = (ControlContainer) toolbarContainerStub.inflate(); + } + + // Inflate the correct toolbar layout for the device. + int toolbarLayoutId = getToolbarLayoutId(); + if (toolbarLayoutId != NO_TOOLBAR_LAYOUT && controlContainer != null) { + controlContainer.initWithToolbar(toolbarLayoutId); } } finally { StrictMode.setThreadPolicy(oldPolicy); @@ -464,6 +476,13 @@ } /** + * @return The layout ID for the toolbar to use. + */ + protected int getToolbarLayoutId() { + return NO_TOOLBAR_LAYOUT; + } + + /** * @return Whether contextual search is allowed for this activity or not. */ protected boolean isContextualSearchAllowed() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index aca7c21..b288ecbe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -416,7 +416,7 @@ } mMergeTabsOnResume = false; } - if (mVrShellDelegate.isInVR()) mVrShellDelegate.resumeVR(); + mVrShellDelegate.maybeResumeVR(); mLocaleManager.setSnackbarManager(getSnackbarManager()); mLocaleManager.startObservingPhoneChanges(); @@ -426,7 +426,7 @@ public void onPauseWithNative() { mTabModelSelectorImpl.commitAllTabClosures(); CookiesFetcher.persistCookies(this); - if (mVrShellDelegate.isInVR()) mVrShellDelegate.pauseVR(); + mVrShellDelegate.maybePauseVR(); mLocaleManager.setSnackbarManager(null); mLocaleManager.stopObservingPhoneChanges(); @@ -937,10 +937,22 @@ @Override protected int getControlContainerLayoutId() { + if (FeatureUtilities.isChromeHomeEnabled()) { + return R.layout.bottom_control_container; + } return R.layout.control_container; } @Override + protected int getToolbarLayoutId() { + if (DeviceFormFactor.isTablet(getApplicationContext())) return R.layout.toolbar_tablet; + + // TODO(mdjones): Replace with bottom_toolbar layout when available. + if (FeatureUtilities.isChromeHomeEnabled()) return R.layout.toolbar_phone; + return R.layout.toolbar_phone; + } + + @Override public void postInflationStartup() { super.postInflationStartup();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java index 2594698..4bda45b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.widget.ControlContainer; import org.chromium.content_public.browser.WebContents; import java.net.InetAddress; @@ -69,8 +70,10 @@ * Inflates and constructs the view hierarchy that the app will use. * @param baseContext The base context to use for creating the ContextWrapper. * @param toolbarContainerId Id of the toolbar container. + * @param toolbarId The toolbar's layout ID. */ - public void initializeViewHierarchy(Context baseContext, int toolbarContainerId) { + public void initializeViewHierarchy(Context baseContext, int toolbarContainerId, + int toolbarId) { TraceEvent.begin("WarmupManager.initializeViewHierarchy"); // Inflating the view hierarchy causes StrictMode violations on some // devices. Since layout inflation should happen on the UI thread, allow @@ -88,7 +91,8 @@ if (toolbarContainerId != ChromeActivity.NO_CONTROL_CONTAINER) { ViewStub stub = (ViewStub) mMainView.findViewById(R.id.control_container_stub); stub.setLayoutResource(toolbarContainerId); - stub.inflate(); + ControlContainer controlContainer = (ControlContainer) stub.inflate(); + controlContainer.initWithToolbar(toolbarId); } } catch (InflateException e) { // See crbug.com/606715.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 49875c2..e9e8d15 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -609,6 +609,11 @@ } @Override + protected int getToolbarLayoutId() { + return R.layout.custom_tabs_toolbar; + } + + @Override public int getControlContainerHeightResource() { return R.dimen.custom_tabs_control_container_height; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java index 641729d..16c6ff0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java
@@ -128,10 +128,13 @@ pageLoadFinishedTimestamp - mIntentReceivedTimestamp; String histogramPrefix = mOpenedByChrome ? "ChromeGeneratedCustomTab" : "CustomTabs"; - // Same bounds and bucket count as "Startup.FirstCommitNavigationTime" RecordHistogram.recordCustomTimesHistogram( - histogramPrefix + ".IntentToFirstCommitNavigationTime", timeToPageLoadStartedMs, - 1, TimeUnit.MINUTES.toMillis(1), TimeUnit.MILLISECONDS, 225); + histogramPrefix + ".IntentToFirstCommitNavigationTime2.ZoomedOut", + timeToPageLoadStartedMs, + 50, TimeUnit.MINUTES.toMillis(10), TimeUnit.MILLISECONDS, 50); + RecordHistogram.recordCustomTimesHistogram( + histogramPrefix + ".IntentToFirstCommitNavigationTime2.ZoomedIn", + timeToPageLoadStartedMs, 200, 1000, TimeUnit.MILLISECONDS, 100); // Same bounds and bucket count as PLT histograms. RecordHistogram.recordCustomTimesHistogram(histogramPrefix + ".IntentToPageLoadedTime", timeToPageLoadFinishedMs, 10, TimeUnit.MINUTES.toMillis(10),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index a8f48e9..c0c7e0c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -205,7 +205,7 @@ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); ChromeBrowserInitializer.initNetworkChangeNotifier(context); WarmupManager.getInstance().initializeViewHierarchy( - context, R.layout.custom_tabs_control_container); + context, R.layout.custom_tabs_control_container, R.layout.custom_tabs_toolbar); } public boolean warmup(long flags) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java index edf2894e..a452147 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
@@ -556,6 +556,7 @@ // Add a PendingIntent so that the intent used to launch Chrome will be resent when // first run is completed or canceled. FirstRunFlowSequencer.addPendingIntent(this, freIntent, getIntent()); + freIntent.putExtra(FirstRunActivity.EXTRA_FINISH_ON_TOUCH_OUTSIDE, !forTabbedMode); startActivity(freIntent); } else { Intent newIntent = new Intent(getIntent());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java index 2fe285a..16bfa081 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
@@ -160,11 +160,6 @@ return OverrideUrlLoadingResult.NO_OVERRIDE; } - // http://crbug.com/605302 : Allow Chrome to handle all pdf file downloads. - if (mDelegate.isPdfDownload(params.getUrl())) { - return OverrideUrlLoadingResult.NO_OVERRIDE; - } - // pageTransition is a combination of an enumeration (core value) and bitmask. int pageTransitionCore = params.getPageTransition() & PageTransition.CORE_MASK; boolean isLink = pageTransitionCore == PageTransition.LINK; @@ -195,6 +190,11 @@ return OverrideUrlLoadingResult.NO_OVERRIDE; } + // http://crbug.com/605302 : Allow Chrome to handle all pdf file downloads. + if (!isExternalProtocol && mDelegate.isPdfDownload(params.getUrl())) { + return OverrideUrlLoadingResult.NO_OVERRIDE; + } + // If accessing a file URL, ensure that the user has granted the necessary file access // to Chrome. This check should happen for reloads, navigations, etc..., which is why // it occurs before the subsequent blocks.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java index 6f4d9827..d1e8033 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -53,6 +53,7 @@ public static final String EXTRA_USE_FRE_FLOW_SEQUENCER = "Extra.UseFreFlowSequencer"; public static final String EXTRA_START_LIGHTWEIGHT_FRE = "Extra.StartLightweightFRE"; public static final String EXTRA_CHROME_LAUNCH_INTENT = "Extra.FreChromeLaunchIntent"; + public static final String EXTRA_FINISH_ON_TOUCH_OUTSIDE = "Extra.FreFinishOnTouchOutside"; static final String SHOW_WELCOME_PAGE = "ShowWelcome"; static final String SHOW_SIGNIN_PAGE = "ShowSignIn"; @@ -145,7 +146,6 @@ initializeBrowserProcess(); super.onCreate(savedInstanceState); - setFinishOnTouchOutside(false); if (savedInstanceState != null) { mFreProperties = savedInstanceState; @@ -155,6 +155,9 @@ mFreProperties = new Bundle(); } + setFinishOnTouchOutside( + mFreProperties.getBoolean(FirstRunActivity.EXTRA_FINISH_ON_TOUCH_OUTSIDE)); + // Skip creating content view if it is to start a lightweight First Run Experience. if (mFreProperties.getBoolean(FirstRunActivity.EXTRA_START_LIGHTWEIGHT_FRE)) { return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java b/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java index 4242795..ce971ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java
@@ -30,6 +30,8 @@ public static final String PREF_WAS_IN_SPECIAL_LOCALE = "LocaleManager_WAS_IN_SPECIAL_LOCALE"; public static final String SPECIAL_LOCALE_ID = "US"; + private static final int SNACKBAR_DURATION_MS = 6000; + private static LocaleManager sInstance; // LocaleManager is a singleton and it should not have strong reference to UI objects. @@ -199,6 +201,7 @@ Context context = ContextUtils.getApplicationContext(); Snackbar snackbar = Snackbar.make(title, mSnackbarController, Snackbar.TYPE_NOTIFICATION, Snackbar.UMA_SPECIAL_LOCALE); + snackbar.setDuration(SNACKBAR_DURATION_MS); snackbar.setAction(context.getString(R.string.preferences), null); manager.showSnackbar(snackbar); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/locale/SearchEnginePromoDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/locale/SearchEnginePromoDialog.java index ee88c1f61..bc11aca1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/locale/SearchEnginePromoDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/locale/SearchEnginePromoDialog.java
@@ -10,6 +10,7 @@ import android.content.DialogInterface.OnDismissListener; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.IntDef; import android.text.SpannableString; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; @@ -17,6 +18,7 @@ import android.widget.TextView; import org.chromium.base.ContextUtils; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.preferences.SearchEnginePreference; @@ -24,25 +26,38 @@ import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier.SpanInfo; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * A promotion dialog showing that the default search provider will be set to Sogou. */ public class SearchEnginePromoDialog extends Dialog implements View.OnClickListener, OnDismissListener { + // These constants are here to back a uma histogram. Append new constants at the end of this + // list (do not rearrange) and don't forget to update CHOICE_ENUM_COUNT. + @Retention(RetentionPolicy.SOURCE) + @IntDef({CHOICE_USE_SOGOU, CHOICE_KEEP_GOOGLE, CHOICE_SETTINGS, CHOICE_BACK_KEY}) + private @interface UserChoice {} private static final int CHOICE_USE_SOGOU = 0; private static final int CHOICE_KEEP_GOOGLE = 1; + private static final int CHOICE_SETTINGS = 2; + private static final int CHOICE_BACK_KEY = 3; + + private static final int CHOICE_ENUM_COUNT = 4; private final LocaleManager mLocaleManager; private final ClickableSpan mSpan = new NoUnderlineClickableSpan() { @Override public void onClick(View widget) { + mChoice = CHOICE_SETTINGS; Intent intent = PreferencesLauncher.createIntentForSettingsPage(getContext(), SearchEnginePreference.class.getName()); getContext().startActivity(intent); } }; - private int mChoice = CHOICE_USE_SOGOU; + @UserChoice private int mChoice = CHOICE_BACK_KEY; /** * Creates an instance of the dialog. @@ -51,6 +66,7 @@ super(context, R.style.SimpleDialog); mLocaleManager = localeManager; setOnDismissListener(this); + setCanceledOnTouchOutside(false); } @Override @@ -100,12 +116,21 @@ @Override public void onDismiss(DialogInterface dialog) { - if (mChoice == CHOICE_KEEP_GOOGLE) { - keepGoogle(); - } else if (mChoice == CHOICE_USE_SOGOU) { - useSogou(); + switch (mChoice) { + case CHOICE_KEEP_GOOGLE: + case CHOICE_SETTINGS: + case CHOICE_BACK_KEY: + keepGoogle(); + break; + case CHOICE_USE_SOGOU: + useSogou(); + break; + default: + assert false : "Unexpected choice"; } ContextUtils.getAppSharedPreferences().edit() .putBoolean(LocaleManager.PREF_PROMO_SHOWN, true).apply(); + RecordHistogram.recordEnumeratedHistogram("SpecialLocale.PromotionDialog", mChoice, + CHOICE_ENUM_COUNT); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java index 20ce6a6..9bac136 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaSessionTabHelper.java
@@ -44,7 +44,12 @@ private WebContentsObserver mWebContentsObserver; private int mPreviousVolumeControlStream = AudioManager.USE_DEFAULT_STREAM_TYPE; private MediaNotificationInfo.Builder mNotificationInfoBuilder = null; - private MediaMetadata mFallbackMetadata; + // The fallback title if |mPageMetadata| is null or its title is empty. + private String mFallbackTitle = null; + // The metadata set by the page. + private MediaMetadata mPageMetadata = null; + // The currently showing metadata. + private MediaMetadata mCurrentMetadata = null; private MediaNotificationListener mControlsListener = new MediaNotificationListener() { @Override @@ -93,34 +98,22 @@ } @Override - public void mediaSessionStateChanged(boolean isControllable, boolean isPaused, - MediaMetadata metadata) { + public void mediaSessionStateChanged(boolean isControllable, boolean isPaused) { if (!isControllable) { hideNotification(); return; } - mFallbackMetadata = null; - - // The page's title is used as a placeholder if no title is specified in the - // metadata. - if (metadata == null || TextUtils.isEmpty(metadata.getTitle())) { - mFallbackMetadata = new MediaMetadata( - sanitizeMediaTitle(mTab.getTitle()), - metadata == null ? "" : metadata.getArtist(), - metadata == null ? "" : metadata.getAlbum()); - metadata = mFallbackMetadata; - } - Intent contentIntent = Tab.createBringTabToFrontIntent(mTab.getId()); if (contentIntent != null) { contentIntent.putExtra(MediaNotificationUma.INTENT_EXTRA_NAME, MediaNotificationUma.SOURCE_MEDIA); } + mCurrentMetadata = getMetadata(); mNotificationInfoBuilder = new MediaNotificationInfo.Builder() - .setMetadata(metadata) + .setMetadata(mCurrentMetadata) .setPaused(isPaused) .setOrigin(mOrigin) .setTabId(mTab.getId()) @@ -142,6 +135,12 @@ activity.setVolumeControlStream(AudioManager.STREAM_MUSIC); } } + + @Override + public void mediaSessionMetadataChanged(MediaMetadata metadata) { + mPageMetadata = metadata; + updateNotificationMetadata(); + } }; } @@ -206,14 +205,11 @@ @Override public void onTitleUpdated(Tab tab) { assert tab == mTab; - if (mNotificationInfoBuilder == null || mFallbackMetadata == null) return; - - mFallbackMetadata = new MediaMetadata(mFallbackMetadata); - mFallbackMetadata.setTitle(sanitizeMediaTitle(mTab.getTitle())); - mNotificationInfoBuilder.setMetadata(mFallbackMetadata); - - MediaNotificationManager.show(ContextUtils.getApplicationContext(), - mNotificationInfoBuilder.build()); + String newFallbackTitle = sanitizeMediaTitle(tab.getTitle()); + if (!TextUtils.equals(mFallbackTitle, newFallbackTitle)) { + mFallbackTitle = newFallbackTitle; + updateNotificationMetadata(); + } } @Override @@ -303,4 +299,45 @@ mFavicon = MediaNotificationManager.scaleIconForDisplay(icon); return true; } + + /** + * Updates the metadata in media notification. This method should be called whenever + * |mPageMetadata| or |mFallbackTitle| is changed. + */ + private void updateNotificationMetadata() { + if (mNotificationInfoBuilder == null) return; + + MediaMetadata newMetadata = getMetadata(); + if (mCurrentMetadata.equals(newMetadata)) return; + + mCurrentMetadata = newMetadata; + mNotificationInfoBuilder.setMetadata(mCurrentMetadata); + MediaNotificationManager.show( + ContextUtils.getApplicationContext(), mNotificationInfoBuilder.build()); + } + + /** + * @return The up-to-date MediaSession metadata. Returns the cached object like |mPageMetadata| + * or |mCurrentMetadata| if it reflects the current state. Otherwise will return a new + * {@link MediaMetadata} object. + */ + private MediaMetadata getMetadata() { + String title = mFallbackTitle; + String artist = ""; + String album = ""; + if (mPageMetadata != null) { + if (!TextUtils.isEmpty(mPageMetadata.getTitle())) return mPageMetadata; + + artist = mPageMetadata.getArtist(); + album = mPageMetadata.getAlbum(); + } + + if (mCurrentMetadata != null && TextUtils.equals(title, mCurrentMetadata.getTitle()) + && TextUtils.equals(artist, mCurrentMetadata.getArtist()) + && TextUtils.equals(album, mCurrentMetadata.getAlbum())) { + return mCurrentMetadata; + } + + return new MediaMetadata(title, artist, album); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java index 173f594..c9a7aef1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java
@@ -12,6 +12,7 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; +import android.view.ViewStub; import android.widget.FrameLayout; import org.chromium.chrome.R; @@ -81,9 +82,14 @@ } @Override - public void onFinishInflate() { + public void initWithToolbar(int toolbarLayoutId) { + ViewStub toolbarStub = (ViewStub) findViewById(R.id.toolbar_stub); + toolbarStub.setLayoutResource(toolbarLayoutId); + toolbarStub.inflate(); + mToolbar = (Toolbar) findViewById(R.id.toolbar); mToolbarContainer = (ToolbarViewResourceFrameLayout) findViewById(R.id.toolbar_container); + mToolbarContainer.setToolbar(mToolbar); mMenuBtn = findViewById(R.id.menu_button); if (mToolbar instanceof ToolbarTablet) { @@ -95,8 +101,6 @@ assert mToolbar != null; assert mMenuBtn != null; - - super.onFinishInflate(); } @Override @@ -141,8 +145,11 @@ @Override protected ViewResourceAdapter createResourceAdapter() { - return new ToolbarViewResourceAdapter( - this, (Toolbar) findViewById(R.id.toolbar)); + return new ToolbarViewResourceAdapter(this); + } + + public void setToolbar(Toolbar toolbar) { + ((ToolbarViewResourceAdapter) getResourceAdapter()).setToolbar(toolbar); } @Override @@ -152,26 +159,32 @@ } private static class ToolbarViewResourceAdapter extends ViewResourceAdapter { - private final int mToolbarActualHeightPx; - private final int mTabStripHeightPx; private final int[] mTempPosition = new int[2]; - private final View mToolbarContainer; - private final Toolbar mToolbar; + + private Toolbar mToolbar; + private int mToolbarActualHeightPx; + private int mTabStripHeightPx; /** Builds the resource adapter for the toolbar. */ - public ToolbarViewResourceAdapter(View toolbarContainer, Toolbar toolbar) { + public ToolbarViewResourceAdapter(View toolbarContainer) { super(toolbarContainer); - mToolbarContainer = toolbarContainer; + } + + /** + * Set the toolbar after it has been dynamically inflated. + * @param toolbar The browser's toolbar. + */ + public void setToolbar(Toolbar toolbar) { mToolbar = toolbar; int containerHeightResId = R.dimen.control_container_height; if (mToolbar instanceof CustomTabToolbar) { containerHeightResId = R.dimen.custom_tabs_control_container_height; } - mToolbarActualHeightPx = toolbarContainer.getResources().getDimensionPixelSize( + mToolbarActualHeightPx = mToolbarContainer.getResources().getDimensionPixelSize( containerHeightResId); - mTabStripHeightPx = toolbarContainer.getResources().getDimensionPixelSize( + mTabStripHeightPx = mToolbarContainer.getResources().getDimensionPixelSize( R.dimen.tab_strip_height); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContext.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContext.java new file mode 100644 index 0000000..99f30f2f --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContext.java
@@ -0,0 +1,57 @@ +// 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. + +package org.chromium.chrome.browser.vr_shell; + +import android.app.Activity; +import android.os.StrictMode; + +import com.google.vr.ndk.base.GvrLayout; + +import org.chromium.base.Log; +import org.chromium.base.annotations.UsedByReflection; + +/** + * Creates an active GvrContext from a detached GvrLayout. This is used by magic window mode. + */ +@UsedByReflection("VrShellDelegate.java") +public class NonPresentingGvrContext implements NonPresentingGvrContextInterface { + private static final String TAG = "NPGvrContext"; + private GvrLayout mGvrLayout; + + @UsedByReflection("VrShellDelegate.java") + public NonPresentingGvrContext(Activity activity) { + mGvrLayout = new GvrLayout(activity); + } + + @Override + public long getNativeGvrContext() { + long nativeGvrContext = 0; + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + try { + nativeGvrContext = mGvrLayout.getGvrApi().getNativeGvrContext(); + } catch (Exception ex) { + Log.e(TAG, "Unable to instantiate GvrApi", ex); + return 0; + } finally { + StrictMode.setThreadPolicy(oldPolicy); + } + return nativeGvrContext; + } + + @Override + public void resume() { + mGvrLayout.onResume(); + } + + @Override + public void pause() { + mGvrLayout.onPause(); + } + + @Override + public void shutdown() { + mGvrLayout.shutdown(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContextInterface.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContextInterface.java new file mode 100644 index 0000000..614e6fe6 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContextInterface.java
@@ -0,0 +1,31 @@ +// 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. + +package org.chromium.chrome.browser.vr_shell; + +/** + * Abstracts away the NonPresentingGvrContext class, which may or may not be present at runtime + * depending on compile flags. + */ +public interface NonPresentingGvrContextInterface { + /** + * Returns the native gvr context. + */ + long getNativeGvrContext(); + + /** + * Must be called when activity resumes. + */ + void resume(); + + /** + * Must be called when activity pauses. + */ + void pause(); + + /** + * Shutdown the native gvr context. + */ + void shutdown(); +}
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 e7e2499..ec33e49 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
@@ -11,6 +11,7 @@ import static android.opengl.GLES20.glGenTextures; import static android.opengl.GLES20.glTexParameteri; +import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture.OnFrameAvailableListener; @@ -26,9 +27,11 @@ import com.google.vr.ndk.base.AndroidCompat; import com.google.vr.ndk.base.GvrLayout; +import org.chromium.base.CommandLine; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.UsedByReflection; +import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeVersionInfo; import org.chromium.chrome.browser.WebContentsFactory; import org.chromium.chrome.browser.tab.Tab; @@ -127,6 +130,18 @@ mNativeVrShell = nativeInit(mContentCVC.getWebContents(), mContentVrWindowAndroid.getNativePointer(), mUiContents, mUiVrWindowAndroid.getNativePointer()); + mGlSurfaceView.setOnTouchListener(new View.OnTouchListener() { + @Override + @SuppressLint("ClickableViewAccessibility") + public boolean onTouch(View v, MotionEvent event) { + if (!CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_VR_SHELL_DEV) + && event.getActionMasked() == MotionEvent.ACTION_DOWN) { + nativeOnTriggerEvent(mNativeVrShell); + return true; + } + return false; + } + }); uiContentView.setVisibility(View.VISIBLE); mUiCVC.onShow(); @@ -251,11 +266,14 @@ @Override public boolean dispatchTouchEvent(MotionEvent event) { - if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { + // Normally, touch event is dispatched to presentation view only if the phone is paired with + // a Cardboard viewer. This is annoying when we just want to quickly verify a Cardboard + // behavior. This allows us to trigger cardboard trigger event without pair to a Cardboard. + if (CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_VR_SHELL_DEV) + && event.getActionMasked() == MotionEvent.ACTION_DOWN) { nativeOnTriggerEvent(mNativeVrShell); } - // Don't mark this as handled so that Daydream screen alignment still functions. - return false; + return super.dispatchTouchEvent(event); } @Override @@ -286,6 +304,7 @@ super.shutdown(); if (mNativeVrShell != 0) { nativeDestroy(mNativeVrShell); + mNativeVrShell = 0; } if (mContentFrameListener != null && mContentFrameListener.mSurfaceTexture != null) { mContentFrameListener.mSurfaceTexture.release();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index 85cef3a..4ff15e4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -32,10 +32,12 @@ private ChromeTabbedActivity mActivity; - private boolean mVrShellEnabled; + private boolean mVrEnabled; private Class<? extends VrShellInterface> mVrShellClass; + private Class<? extends NonPresentingGvrContextInterface> mNonPresentingGvrContextClass; private VrShellInterface mVrShell; + private NonPresentingGvrContextInterface mNonPresentingGvrContext; private boolean mInVr; private int mRestoreSystemUiVisibilityFlag = -1; private String mVrExtra; @@ -44,14 +46,13 @@ public VrShellDelegate(ChromeTabbedActivity activity) { mActivity = activity; - mVrShellClass = maybeFindVrShell(); - if (mVrShellClass != null) { - mVrShellEnabled = true; + mVrEnabled = maybeFindVrClasses(); + if (mVrEnabled) { try { mVrExtra = (String) mVrShellClass.getField("VR_EXTRA").get(null); } catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException e) { Log.e(TAG, "Unable to read VR_EXTRA field", e); - mVrShellEnabled = false; + mVrEnabled = false; } } } @@ -61,18 +62,24 @@ * class can be initialized. */ public void onNativeLibraryReady() { - if (mVrShellEnabled) { + if (mVrEnabled) { mNativeVrShellDelegate = nativeInit(); } } @SuppressWarnings("unchecked") - private Class<? extends VrShellInterface> maybeFindVrShell() { + private boolean maybeFindVrClasses() { try { - return (Class<? extends VrShellInterface>) Class - .forName("org.chromium.chrome.browser.vr_shell.VrShell"); + mVrShellClass = (Class<? extends VrShellInterface>) Class.forName( + "org.chromium.chrome.browser.vr_shell.VrShell"); + mNonPresentingGvrContextClass = + (Class<? extends NonPresentingGvrContextInterface>) Class.forName( + "org.chromium.chrome.browser.vr_shell.NonPresentingGvrContext"); + return true; } catch (ClassNotFoundException e) { - return null; + mVrShellClass = null; + mNonPresentingGvrContextClass = null; + return false; } } @@ -86,7 +93,7 @@ */ @CalledByNative public boolean enterVRIfNecessary(boolean inWebVR) { - if (!mVrShellEnabled || mNativeVrShellDelegate == 0) return false; + if (!mVrEnabled || mNativeVrShellDelegate == 0) return false; Tab tab = mActivity.getActivityTab(); // TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow VR Shell to be // entered without any current tabs. @@ -124,23 +131,44 @@ /** * Resumes VR Shell. */ - public void resumeVR() { - setupVrModeWindowFlags(); - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - try { - mVrShell.resume(); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Unable to resume VrShell", e); - } finally { - StrictMode.setThreadPolicy(oldPolicy); + public void maybeResumeVR() { + // TODO(bshe): Ideally, we do not need two gvr context exist at the same time. We can + // probably shutdown non presenting gvr when presenting and create a new one after exit + // presenting. See crbug.com/655242 + if (mNonPresentingGvrContext != null) { + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); + try { + mNonPresentingGvrContext.resume(); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Unable to resume mNonPresentingGvrContext", e); + } finally { + StrictMode.setThreadPolicy(oldPolicy); + } + } + + if (mInVr) { + setupVrModeWindowFlags(); + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); + try { + mVrShell.resume(); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Unable to resume VrShell", e); + } finally { + StrictMode.setThreadPolicy(oldPolicy); + } } } /** * Pauses VR Shell. */ - public void pauseVR() { - mVrShell.pause(); + public void maybePauseVR() { + if (mNonPresentingGvrContext != null) { + mNonPresentingGvrContext.pause(); + } + if (mInVr) { + mVrShell.pause(); + } } /** @@ -159,6 +187,30 @@ return true; } + @CalledByNative + private long createNonPresentingNativeContext() { + if (!mVrEnabled) return 0; + + try { + Constructor<?> nonPresentingGvrContextConstructor = + mNonPresentingGvrContextClass.getConstructor(Activity.class); + mNonPresentingGvrContext = + (NonPresentingGvrContextInterface) + nonPresentingGvrContextConstructor.newInstance(mActivity); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException e) { + Log.e(TAG, "Unable to instantiate NonPresentingGvrContext", e); + return 0; + } + return mNonPresentingGvrContext.getNativeGvrContext(); + } + + @CalledByNative + private void shutdownNonPresentingNativeContext() { + mNonPresentingGvrContext.shutdown(); + mNonPresentingGvrContext = null; + } + /** * Exits VR Shell, performing all necessary cleanup. */ @@ -256,7 +308,7 @@ * @return Whether or not VR Shell is currently enabled. */ public boolean isVrShellEnabled() { - return mVrShellEnabled; + return mVrEnabled; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappControlContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappControlContainer.java index ff13184..abbe8098 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappControlContainer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappControlContainer.java
@@ -27,6 +27,10 @@ } @Override + public void initWithToolbar(int toolbarLayoutId) { + } + + @Override public ViewResourceAdapter getToolbarResourceAdapter() { return getResourceAdapter(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ControlContainer.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ControlContainer.java index 23cb16d..ff803c5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ControlContainer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ControlContainer.java
@@ -16,6 +16,12 @@ */ public interface ControlContainer { /** + * Initialize the control container with the specified toolbar. + * @param toolbarLayoutId The ID of the toolbar layout to use. + */ + void initWithToolbar(int toolbarLayoutId); + + /** * @return The {@link ViewResourceAdapter} that exposes this {@link View} as a CC resource. */ ViewResourceAdapter getToolbarResourceAdapter();
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 64e6b67..e9185f68 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -981,6 +981,7 @@ "java/src/org/chromium/chrome/browser/util/PlatformUtil.java", "java/src/org/chromium/chrome/browser/util/UrlUtilities.java", "java/src/org/chromium/chrome/browser/util/ViewUtils.java", + "java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContextInterface.java", "java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java", "java/src/org/chromium/chrome/browser/vr_shell/VrShellInterface.java", "java/src/org/chromium/chrome/browser/webapps/ActivityAssigner.java", @@ -1084,6 +1085,7 @@ ] chrome_vr_java_sources = [ + "java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContext.java", "java/src/org/chromium/chrome/browser/vr_shell/VrShell.java", "java/src/org/chromium/chrome/browser/vr_shell/VrWindowAndroid.java", ]
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java index 92420e8b..de7a9ad9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
@@ -785,6 +785,21 @@ .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE); } + + @SmallTest + public void testPdfDownloadHappensInChrome() { + checkUrl(CALENDAR_URL + "/file.pdf") + .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE); + } + + @SmallTest + public void testIntentToPdfFileOpensApp() { + checkUrl("intent://yoursite.com/mypdf.pdf#Intent;action=VIEW;category=BROWSABLE;" + + "scheme=http;package=com.adobe.reader;end;") + .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, + START_OTHER_ACTIVITY); + } + @SmallTest public void testReferrerExtra() { String referrer = "http://www.google.com"; @@ -1161,7 +1176,7 @@ @Override public boolean isPdfDownload(String url) { - return false; + return url.endsWith(".pdf"); } @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java index 3ebaf1e..2720de1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/NotificationTitleUpdatedTest.java
@@ -70,12 +70,14 @@ } private void doTestMediaMetadataSetsTitle() throws InterruptedException { - simulateMediaSessionStateChanged(mTab, true, false, new MediaMetadata("title2", "", "")); + simulateMediaSessionStateChanged(mTab, true, false); + simulateMediaSessionMetadataChanged(mTab, new MediaMetadata("title2", "", "")); assertTitleMatches("title2"); } private void doTestMediaMetadataOverridesTitle() throws InterruptedException { - simulateMediaSessionStateChanged(mTab, true, false, new MediaMetadata("title2", "", "")); + simulateMediaSessionStateChanged(mTab, true, false); + simulateMediaSessionMetadataChanged(mTab, new MediaMetadata("title2", "", "")); assertTitleMatches("title2"); simulateUpdateTitle(mTab, "title3"); @@ -145,25 +147,31 @@ private void simulateMediaSessionStateChanged( final Tab tab, final boolean isControllable, final boolean isSuspended) { - simulateMediaSessionStateChanged( - tab, isControllable, isSuspended, new MediaMetadata("", "", "")); - } - - private void simulateMediaSessionStateChanged(final Tab tab, final boolean isControllable, - final boolean isSuspended, final MediaMetadata metadata) { ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { ObserverList.RewindableIterator<WebContentsObserver> observers = tab.getWebContents().getObserversForTesting(); while (observers.hasNext()) { - observers.next().mediaSessionStateChanged( - isControllable, isSuspended, metadata); + observers.next().mediaSessionStateChanged(isControllable, isSuspended); } } }); } + private void simulateMediaSessionMetadataChanged(final Tab tab, final MediaMetadata metadata) { + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + ObserverList.RewindableIterator<WebContentsObserver> observers = + tab.getWebContents().getObserversForTesting(); + while (observers.hasNext()) { + observers.next().mediaSessionMetadataChanged(metadata); + } + } + }); + } + private void simulateUpdateTitle(Tab tab, String title) { try { TabTitleObserver observer = new TabTitleObserver(tab, title);
diff --git a/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc b/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc index fd9e2c4..178d7d1 100644 --- a/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc +++ b/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc
@@ -46,16 +46,6 @@ namespace { -void SavePageCallback(const DownloadUIItem& item, - OfflinePageModel::SavePageResult result, - int64_t offline_id) { - OfflinePageNotificationBridge notification_bridge; - if (result == SavePageResult::SUCCESS) - notification_bridge.NotifyDownloadSuccessful(item); - else - notification_bridge.NotifyDownloadFailed(item); -} - // TODO(dewittj): Move to Download UI Adapter. content::WebContents* GetWebContentsFromJavaTab( const ScopedJavaGlobalRef<jobject>& j_tab_ref) { @@ -81,74 +71,65 @@ return OfflinePageModelFactory::GetForBrowserContext(profile); } -void SavePageIfNavigatedToURL(const GURL& query_url, - const ScopedJavaGlobalRef<jobject>& j_tab_ref) { +void SavePageIfNotNavigatedAway(const GURL& original_url, + const ScopedJavaGlobalRef<jobject>& j_tab_ref) { content::WebContents* web_contents = GetWebContentsFromJavaTab(j_tab_ref); if (!web_contents) return; - // This doesn't detect navigations to the same URL, only that we are looking - // at a completely different page. + // This ignores fragment differences in URLs, bails out only if tab has + // navigated away and not just scrolled to a fragment. GURL url = web_contents->GetLastCommittedURL(); - if (!OfflinePageUtils::EqualsIgnoringFragment(url, query_url)) + if (!OfflinePageUtils::EqualsIgnoringFragment(url, original_url)) return; offline_pages::ClientId client_id; client_id.name_space = offline_pages::kDownloadNamespace; client_id.id = base::GenerateGUID(); + int64_t request_id = OfflinePageModel::kInvalidOfflineId; - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()) - ->GetOriginalProfile(); - - OfflinePageNotificationBridge notification_bridge; - - // If the page is not loaded enough to be captured, submit a background loader - // request instead. - offline_pages::RecentTabHelper* tab_helper = - RecentTabHelper::FromWebContents(web_contents); - if (tab_helper && !tab_helper->is_page_ready_for_snapshot() && - offline_pages::IsBackgroundLoaderForDownloadsEnabled()) { - // TODO(dimich): Improve this to wait for the page load if it is still going - // on. Pre-submit the request and if the load finishes and capture happens, - // remove request. + if (offline_pages::IsBackgroundLoaderForDownloadsEnabled()) { + // Post disabled request before passing the download task to the tab helper. + // This will keep the request persisted in case Chrome is evicted from RAM + // or closed by the user. + // Note: the 'disabled' status is not persisted (stored in memory) so it + // automatically resets if Chrome is re-started. offline_pages::RequestCoordinator* request_coordinator = - offline_pages::RequestCoordinatorFactory::GetForBrowserContext(profile); - request_coordinator->SavePageLater( + offline_pages::RequestCoordinatorFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + request_id = request_coordinator->SavePageLater( url, client_id, true, - RequestCoordinator::RequestAvailability::ENABLED_FOR_OFFLINER); - - notification_bridge.ShowDownloadingToast(); - return; + RequestCoordinator::RequestAvailability::DISABLED_FOR_OFFLINER); } - // Page is ready, capture it right from the tab. - offline_pages::OfflinePageModel* offline_page_model = - OfflinePageModelFactory::GetForBrowserContext(profile); - if (!offline_page_model) + // Pass request_id to the current tab's helper to attempt download right from + // the tab. If unsuccessful, it'll enable the already-queued request for + // background offliner. Same will happen if Chrome is terminated since + // 'disabled' status of the request is RAM-stored info. + offline_pages::RecentTabHelper* tab_helper = + RecentTabHelper::FromWebContents(web_contents); + if (!tab_helper) { + if (request_id != OfflinePageModel::kInvalidOfflineId) { + offline_pages::RequestCoordinator* request_coordinator = + offline_pages::RequestCoordinatorFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + request_coordinator->EnableForOffliner(request_id); + } return; + } + tab_helper->ObserveAndDownloadCurrentPage(client_id, request_id); - auto archiver = - base::MakeUnique<offline_pages::OfflinePageMHTMLArchiver>(web_contents); - - DownloadUIItem item; - item.guid = client_id.id; - item.url = url; - - notification_bridge.NotifyDownloadProgress(item); - + OfflinePageNotificationBridge notification_bridge; notification_bridge.ShowDownloadingToast(); - offline_page_model->SavePage(url, client_id, 0l, std::move(archiver), - base::Bind(&SavePageCallback, item)); } -void OnDeletePagesForInfoBar(const GURL& query_url, +void OnDeletePagesForInfoBar(const GURL& original_url, const ScopedJavaGlobalRef<jobject>& j_tab_ref, DeletePageResult result) { - SavePageIfNavigatedToURL(query_url, j_tab_ref); + SavePageIfNotNavigatedAway(original_url, j_tab_ref); } -void DeletePagesForOverwrite(const GURL& query_url, +void DeletePagesForOverwrite(const GURL& original_url, const ScopedJavaGlobalRef<jobject>& j_tab_ref, const MultipleOfflinePageItemResult& pages) { OfflinePageModel* model = GetOfflinePageModelFromJavaTab(j_tab_ref); @@ -164,15 +145,16 @@ } model->DeletePagesByOfflineId( - offline_ids, base::Bind(&OnDeletePagesForInfoBar, query_url, j_tab_ref)); + offline_ids, base::Bind( + &OnDeletePagesForInfoBar, original_url, j_tab_ref)); } -void OnInfoBarAction(const GURL& query_url, +void OnInfoBarAction(const GURL& original_url, const ScopedJavaGlobalRef<jobject>& j_tab_ref, OfflinePageInfoBarDelegate::Action action) { switch (action) { case OfflinePageInfoBarDelegate::Action::CREATE_NEW: - SavePageIfNavigatedToURL(query_url, j_tab_ref); + SavePageIfNotNavigatedAway(original_url, j_tab_ref); break; case OfflinePageInfoBarDelegate::Action::OVERWRITE: OfflinePageModel* offline_page_model = @@ -181,14 +163,14 @@ return; offline_page_model->GetPagesByOnlineURL( - query_url, - base::Bind(&DeletePagesForOverwrite, query_url, j_tab_ref)); + original_url, + base::Bind(&DeletePagesForOverwrite, original_url, j_tab_ref)); break; } } void RequestQueueDuplicateCheckDone( - const GURL& query_url, + const GURL& original_url, const ScopedJavaGlobalRef<jobject>& j_tab_ref, bool has_duplicates) { if (has_duplicates) { @@ -202,10 +184,10 @@ return; } - SavePageIfNavigatedToURL(query_url, j_tab_ref); + SavePageIfNotNavigatedAway(original_url, j_tab_ref); } -void ModelDuplicateCheckDone(const GURL& query_url, +void ModelDuplicateCheckDone(const GURL& original_url, const ScopedJavaGlobalRef<jobject>& j_tab_ref, const std::string& downloads_label, bool has_duplicates) { @@ -215,16 +197,16 @@ if (has_duplicates) { OfflinePageInfoBarDelegate::Create( - base::Bind(&OnInfoBarAction, query_url, j_tab_ref), downloads_label, - query_url.spec(), web_contents); + base::Bind(&OnInfoBarAction, original_url, j_tab_ref), downloads_label, + original_url.spec(), web_contents); return; } OfflinePageUtils::CheckExistenceOfRequestsWithURL( Profile::FromBrowserContext(web_contents->GetBrowserContext()) ->GetOriginalProfile(), - kDownloadNamespace, query_url, - base::Bind(&RequestQueueDuplicateCheckDone, query_url, j_tab_ref)); + kDownloadNamespace, original_url, + base::Bind(&RequestQueueDuplicateCheckDone, original_url, j_tab_ref)); } void ToJavaOfflinePageDownloadItemList(
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper.cc b/chrome/browser/android/offline_pages/recent_tab_helper.cc index dd4badbc..9ab53f9 100644 --- a/chrome/browser/android/offline_pages/recent_tab_helper.cc +++ b/chrome/browser/android/offline_pages/recent_tab_helper.cc
@@ -15,9 +15,12 @@ #include "base/strings/string_number_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" +#include "chrome/browser/android/offline_pages/downloads/offline_page_notification_bridge.h" #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h" #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" #include "chrome/browser/android/offline_pages/offline_page_utils.h" +#include "chrome/browser/android/offline_pages/request_coordinator_factory.h" +#include "components/offline_pages/background/request_coordinator.h" #include "components/offline_pages/client_namespace_constants.h" #include "components/offline_pages/offline_page_feature.h" #include "components/offline_pages/offline_page_item.h" @@ -70,6 +73,33 @@ delegate_ = std::move(delegate); } +void RecentTabHelper::ObserveAndDownloadCurrentPage( + const ClientId& client_id, int64_t request_id) { + EnsureInitialized(); + download_info_ = base::MakeUnique<DownloadPageInfo>(client_id, request_id); + + // If this tab helper is not enabled, immediately give the job back to + // RequestCoordinator. + if (!snapshots_enabled_ || !page_model_) { + ReportDownloadStatusToRequestCoordinator(); + download_info_.reset(); + return; + } + + // No snapshots yet happened on the current page - return and wait for some. + if (!is_page_ready_for_snapshot_) + return; + + // If snapshot already happened and we missed it, go ahead and snapshot now. + page_model_->SavePage( + web_contents()->GetLastCommittedURL(), + client_id, + request_id, + delegate_->CreatePageArchiver(web_contents()), + base::Bind(&RecentTabHelper::SavePageCallback, + weak_ptr_factory_.GetWeakPtr())); +} + // Initialize lazily. It needs TabAndroid for initialization, which is also a // TabHelper - so can't initialize in constructor because of uncertain order // of creation of TabHelpers. @@ -108,12 +138,26 @@ // Cancel tasks in flight that relate to the previous page. weak_ptr_factory_.InvalidateWeakPtrs(); - is_page_ready_for_snapshot_ = false; EnsureInitialized(); if (!snapshots_enabled_) return; + // We navigated to a different page, lets report progress to Background + // Offliner. + if (download_info_ && !navigation_handle->IsSamePage()) { + ReportDownloadStatusToRequestCoordinator(); + } + + if (offline_pages::IsOffliningRecentPagesEnabled()) { + int64_t proposed_id = OfflinePageModel::kInvalidOfflineId; + download_info_ = base::MakeUnique<DownloadPageInfo>( + GetRecentPagesClientId(), proposed_id); + } else { + download_info_.reset(); + } + + is_page_ready_for_snapshot_ = false; // New navigation, new snapshot session. snapshot_url_ = web_contents()->GetLastCommittedURL(); @@ -141,6 +185,14 @@ snapshot_controller_->DocumentOnLoadCompletedInMainFrame(); } +void RecentTabHelper::WebContentsDestroyed() { + // WebContents (and maybe Tab) is destroyed, report status to Offliner. + if (!download_info_) + return; + ReportDownloadStatusToRequestCoordinator(); +} + + // This starts a sequence of async operations chained through callbacks: // - compute the set of old 'last_n' pages that have to be purged // - delete the pages found in the previous step @@ -152,39 +204,44 @@ if (!snapshots_enabled_ || !page_model_ || - !offline_pages::IsOffliningRecentPagesEnabled()) { + !download_info_) { ReportSnapshotCompleted(); return; } // Remove previously captured pages for this tab. page_model_->GetOfflineIdsForClientId( - client_id(), + GetRecentPagesClientId(), base::Bind(&RecentTabHelper::ContinueSnapshotWithIdsToPurge, weak_ptr_factory_.GetWeakPtr())); } void RecentTabHelper::ContinueSnapshotWithIdsToPurge( const std::vector<int64_t>& page_ids) { + if (!download_info_) + return; + + // Also remove the download page if this is not a first snapshot. + std::vector<int64_t> ids(page_ids); + ids.push_back(download_info_->request_id_); + page_model_->DeletePagesByOfflineId( - page_ids, base::Bind(&RecentTabHelper::ContinueSnapshotAfterPurge, - weak_ptr_factory_.GetWeakPtr())); + ids, base::Bind(&RecentTabHelper::ContinueSnapshotAfterPurge, + weak_ptr_factory_.GetWeakPtr())); } void RecentTabHelper::ContinueSnapshotAfterPurge( OfflinePageModel::DeletePageResult result) { - if (result != OfflinePageModel::DeletePageResult::SUCCESS) { - // If previous pages can't be deleted, don't add new ones. + if (!download_info_ || + result != OfflinePageModel::DeletePageResult::SUCCESS || + !IsSamePage()) { ReportSnapshotCompleted(); return; } - if (!IsSamePage()) { - ReportSnapshotCompleted(); - return; - } - - page_model_->SavePage(snapshot_url_, client_id(), 0l, + page_model_->SavePage(snapshot_url_, + download_info_->client_id_, + download_info_->request_id_, delegate_->CreatePageArchiver(web_contents()), base::Bind(&RecentTabHelper::SavePageCallback, weak_ptr_factory_.GetWeakPtr())); @@ -192,11 +249,39 @@ void RecentTabHelper::SavePageCallback(OfflinePageModel::SavePageResult result, int64_t offline_id) { + if (!download_info_) + return; + download_info_->page_snapshot_completed_ = + (result == SavePageResult::SUCCESS); ReportSnapshotCompleted(); } void RecentTabHelper::ReportSnapshotCompleted() { snapshot_controller_->PendingSnapshotCompleted(); + // Tell RequestCoordinator how the request should be processed further. + ReportDownloadStatusToRequestCoordinator(); +} + +void RecentTabHelper::ReportDownloadStatusToRequestCoordinator() { + if (!download_info_) + return; + + if (download_info_->request_id_ == OfflinePageModel::kInvalidOfflineId) + return; + + RequestCoordinator* request_coordinator = + RequestCoordinatorFactory::GetForBrowserContext( + web_contents()->GetBrowserContext()); + if (!request_coordinator) + return; + + // It is OK to call these methods more then once, depending on + // number of snapshots attempted in this tab helper. If the request_id is not + // in the list of RequestCoordinator, these calls have no effect. + if (download_info_->page_snapshot_completed_) + request_coordinator->MarkRequestCompleted(download_info_->request_id_); + else + request_coordinator->EnableForOffliner(download_info_->request_id_); } bool RecentTabHelper::IsSamePage() const { @@ -204,7 +289,7 @@ (web_contents()->GetLastCommittedURL() == snapshot_url_); } -ClientId RecentTabHelper::client_id() const { +ClientId RecentTabHelper::GetRecentPagesClientId() const { return ClientId(kLastNNamespace, tab_id_); }
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper.h b/chrome/browser/android/offline_pages/recent_tab_helper.h index ceb9571..1aeffb1 100644 --- a/chrome/browser/android/offline_pages/recent_tab_helper.h +++ b/chrome/browser/android/offline_pages/recent_tab_helper.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/memory/weak_ptr.h" +#include "components/offline_pages/downloads/download_ui_item.h" #include "components/offline_pages/offline_page_model.h" #include "components/offline_pages/snapshot_controller.h" #include "content/public/browser/web_contents_observer.h" @@ -38,6 +39,7 @@ content::NavigationHandle* navigation_handle) override; void DocumentAvailableInMainFrame() override; void DocumentOnLoadCompletedInMainFrame() override; + void WebContentsDestroyed() override; // SnapshotController::Client void StartSnapshot() override; @@ -55,34 +57,69 @@ }; void SetDelegate(std::unique_ptr<RecentTabHelper::Delegate> delegate); - bool is_page_ready_for_snapshot() const { - return is_page_ready_for_snapshot_; - } + // Support for Download Page feature. The Download Page button does this: + // 1. Creates suspended request for Background Offliner. + // 2. Calls this method with properly filled ClientId. + // 3. This tab helper observes the page load and captures the page + // if the load progresses far enough, as indicated by SnapshotController. + // 4. If capture is successful, this tab helper removes the suspended request. + // Otherwise (navigation to other page, close tab) tab helper un-suspends + // the request so the Background Offliner starts working on it. + // 5. If Chrome is killed at any point, next time Background Offliner loads + // it converts all suspended requests from last session into active. + void ObserveAndDownloadCurrentPage(const ClientId& client_id, + int64_t request_id); private: + // Keeps client_id/request_id that will be used for the offline snapshot. + struct DownloadPageInfo { + public: + DownloadPageInfo(const ClientId& client_id, + int64_t request_id) + : client_id_(client_id), + request_id_(request_id), + page_snapshot_completed_(false) {} + + // The ClientID to go with the offline page. + ClientId client_id_; + // Id of the suspended request in Background Offliner. Used to un-suspend + // the request if the capture of the current page was not possible (e.g. + // the user navigated to another page before current one was loaded). + // 0 if this is a "last_1" info. + int64_t request_id_; + // True if there was at least one snapshot successfully completed. + bool page_snapshot_completed_; + }; + explicit RecentTabHelper(content::WebContents* web_contents); friend class content::WebContentsUserData<RecentTabHelper>; - void EnsureInitialized(); void ContinueSnapshotWithIdsToPurge(const std::vector<int64_t>& page_ids); void ContinueSnapshotAfterPurge(OfflinePageModel::DeletePageResult result); void SavePageCallback(OfflinePageModel::SavePageResult result, int64_t offline_id); - void ReportSnapshotCompleted(); + void ReportDownloadStatusToRequestCoordinator(); bool IsSamePage() const; - ClientId client_id() const; + ClientId GetRecentPagesClientId() const; // Page model is a service, no ownership. Can be null - for example, in // case when tab is in incognito profile. OfflinePageModel* page_model_; + // If false, never make snapshots off the attached WebContents. // Not page-specific. bool snapshots_enabled_; + // Becomes true during navigation if the page is ready for snapshot as // indicated by at least one callback from SnapshotController. bool is_page_ready_for_snapshot_; + + // Info for the offline page to capture. Null if the tab is not capturing + // current page. + std::unique_ptr<DownloadPageInfo> download_info_; + // If empty, the tab does not have AndroidId and can not capture pages. std::string tab_id_;
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc index cc40733..8d484ebf2 100644 --- a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc +++ b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc
@@ -211,10 +211,8 @@ TEST_F(RecentTabHelperTest, SimpleCapture) { NavigateAndCommit(kTestPageUrl); - EXPECT_FALSE(recent_tab_helper()->is_page_ready_for_snapshot()); recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(); RunUntilIdle(); - EXPECT_TRUE(recent_tab_helper()->is_page_ready_for_snapshot()); EXPECT_TRUE(model()->is_loaded()); GetAllPages(); EXPECT_EQ(1U, all_pages().size()); @@ -313,4 +311,20 @@ EXPECT_EQ(0U, all_pages().size()); } +TEST_F(RecentTabHelperTest, DownloadRequest) { + NavigateAndCommit(kTestPageUrl); + recent_tab_helper()->ObserveAndDownloadCurrentPage( + ClientId("download", "id1"), 153l); + recent_tab_helper()->DocumentOnLoadCompletedInMainFrame(); + RunUntilIdle(); + EXPECT_TRUE(model()->is_loaded()); + GetAllPages(); + EXPECT_EQ(1U, all_pages().size()); + const OfflinePageItem& page = all_pages()[0]; + EXPECT_EQ(kTestPageUrl, page.url); + EXPECT_EQ("download", page.client_id.name_space); + EXPECT_EQ("id1", page.client_id.id); + EXPECT_EQ(153l, page.offline_id); +} + } // namespace offline_pages
diff --git a/chrome/browser/android/vr_shell/vr_shell_delegate.cc b/chrome/browser/android/vr_shell/vr_shell_delegate.cc index 606a6417..af69ba1 100644 --- a/chrome/browser/android/vr_shell/vr_shell_delegate.cc +++ b/chrome/browser/android/vr_shell/vr_shell_delegate.cc
@@ -13,6 +13,32 @@ namespace vr_shell { +// A non presenting delegate for magic window mode. +class GvrNonPresentingDelegate : public device::GvrDelegate { + public: + explicit GvrNonPresentingDelegate(jlong context) { + gvr_api_ = + gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(context)); + } + + virtual ~GvrNonPresentingDelegate() = default; + + // GvrDelegate implementation + void SetWebVRSecureOrigin(bool secure_origin) override {} + void SubmitWebVRFrame() override {} + void UpdateWebVRTextureBounds(int eye, + float left, + float top, + float width, + float height) override {} + void SetGvrPoseForWebVr(const gvr::Mat4f& pose, + uint32_t pose_index) override {} + gvr::GvrApi* gvr_api() override { return gvr_api_.get(); } + + private: + std::unique_ptr<gvr::GvrApi> gvr_api_; +}; + VrShellDelegate::VrShellDelegate(JNIEnv* env, jobject obj) : device_provider_(nullptr) { j_vr_shell_delegate_.Reset(env, obj); @@ -62,6 +88,26 @@ Java_VrShellDelegate_exitWebVR(env, j_vr_shell_delegate_.obj()); } +device::GvrDelegate* VrShellDelegate::GetNonPresentingDelegate() { + if (!non_presenting_delegate_) { + JNIEnv* env = AttachCurrentThread(); + jlong context = Java_VrShellDelegate_createNonPresentingNativeContext( + env, j_vr_shell_delegate_.obj()); + if (!context) + return nullptr; + + non_presenting_delegate_.reset(new GvrNonPresentingDelegate(context)); + } + return non_presenting_delegate_.get(); +} + +void VrShellDelegate::DestroyNonPresentingDelegate() { + non_presenting_delegate_.reset(nullptr); + JNIEnv* env = AttachCurrentThread(); + Java_VrShellDelegate_shutdownNonPresentingNativeContext( + env, j_vr_shell_delegate_.obj()); +} + void VrShellDelegate::OnVrShellReady(VrShell* vr_shell) { if (device_provider_) device_provider_->OnGvrDelegateReady(vr_shell);
diff --git a/chrome/browser/android/vr_shell/vr_shell_delegate.h b/chrome/browser/android/vr_shell/vr_shell_delegate.h index 99fb77afd..bf591cc 100644 --- a/chrome/browser/android/vr_shell/vr_shell_delegate.h +++ b/chrome/browser/android/vr_shell/vr_shell_delegate.h
@@ -29,11 +29,14 @@ // device::vrDelegateProvider implementation bool RequestWebVRPresent(device::GvrDeviceProvider* device_provider) override; void ExitWebVRPresent() override; + device::GvrDelegate* GetNonPresentingDelegate() override; + void DestroyNonPresentingDelegate() override; // Called from VRShell void OnVrShellReady(VrShell* vr_shell); private: + std::unique_ptr<device::GvrDelegate> non_presenting_delegate_; base::android::ScopedJavaGlobalRef<jobject> j_vr_shell_delegate_; device::GvrDeviceProvider* device_provider_;
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 617072d4..b4f0b7b 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -237,6 +237,12 @@ "arc/arc_tts_service.h", "arc/arc_wallpaper_service.cc", "arc/arc_wallpaper_service.h", + "arc/fileapi/arc_content_file_system_async_file_util.cc", + "arc/fileapi/arc_content_file_system_async_file_util.h", + "arc/fileapi/arc_content_file_system_backend_delegate.cc", + "arc/fileapi/arc_content_file_system_backend_delegate.h", + "arc/fileapi/arc_content_file_system_file_stream_reader.cc", + "arc/fileapi/arc_content_file_system_file_stream_reader.h", "arc/gpu_arc_video_service_host.cc", "arc/gpu_arc_video_service_host.h", "arc/page_transition_util.cc",
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc index ac4dfc4..147172f 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -259,8 +259,9 @@ policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); connector->GetInstallAttributes()->LockDevice( - std::string(), // user policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH, + std::string(), // domain + std::string(), // realm std::string(), // device_id base::Bind( &KioskAppManager::OnLockDevice, base::Unretained(this), callback));
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc index 6f47d91..7218eac 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -292,8 +292,9 @@ policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); connector->GetInstallAttributes()->LockDevice( - "user@domain.com", policy::DEVICE_MODE_ENTERPRISE, + "domain.com", + std::string(), // realm "device-id", base::Bind( &OnEnterpriseDeviceLock, lock_result.get(), runner->QuitClosure()));
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.cc new file mode 100644 index 0000000..07a160b --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.cc
@@ -0,0 +1,163 @@ +// 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 "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.h" + +#include "base/threading/thread_task_runner_handle.h" +#include "net/base/net_errors.h" +#include "storage/browser/blob/shareable_file_reference.h" + +namespace arc { + +ArcContentFileSystemAsyncFileUtil::ArcContentFileSystemAsyncFileUtil() = + default; + +ArcContentFileSystemAsyncFileUtil::~ArcContentFileSystemAsyncFileUtil() = + default; + +void ArcContentFileSystemAsyncFileUtil::CreateOrOpen( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + int file_flags, + const CreateOrOpenCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(callback, base::Passed(base::File()), base::Closure())); +} + +void ArcContentFileSystemAsyncFileUtil::EnsureFileExists( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const EnsureFileExistsCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED, false)); +} + +void ArcContentFileSystemAsyncFileUtil::CreateDirectory( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + bool exclusive, + bool recursive, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::GetFileInfo( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + int fields, + const GetFileInfoCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(callback, base::File::FILE_ERROR_FAILED, base::File::Info())); +} + +void ArcContentFileSystemAsyncFileUtil::ReadDirectory( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const ReadDirectoryCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(callback, base::File::FILE_ERROR_FAILED, EntryList(), false)); +} + +void ArcContentFileSystemAsyncFileUtil::Touch( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const base::Time& last_access_time, + const base::Time& last_modified_time, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::Truncate( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + int64_t length, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::CopyFileLocal( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& src_url, + const storage::FileSystemURL& dest_url, + CopyOrMoveOption option, + const CopyFileProgressCallback& progress_callback, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::MoveFileLocal( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& src_url, + const storage::FileSystemURL& dest_url, + CopyOrMoveOption option, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::CopyInForeignFile( + std::unique_ptr<storage::FileSystemOperationContext> context, + const base::FilePath& src_file_path, + const storage::FileSystemURL& dest_url, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::DeleteFile( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::DeleteDirectory( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::DeleteRecursively( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const StatusCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED)); +} + +void ArcContentFileSystemAsyncFileUtil::CreateSnapshotFile( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const CreateSnapshotFileCallback& callback) { + NOTIMPLEMENTED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_FAILED, + base::File::Info(), base::FilePath(), + scoped_refptr<storage::ShareableFileReference>())); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.h b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.h new file mode 100644 index 0000000..550c1ba --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.h
@@ -0,0 +1,90 @@ +// 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 CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_ASYNC_FILE_UTIL_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_ASYNC_FILE_UTIL_H_ + +#include "storage/browser/fileapi/async_file_util.h" + +namespace arc { + +class ArcContentFileSystemAsyncFileUtil : public storage::AsyncFileUtil { + public: + ArcContentFileSystemAsyncFileUtil(); + ~ArcContentFileSystemAsyncFileUtil() override; + + // storage::AsyncFileUtil overrides. + void CreateOrOpen( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + int file_flags, + const CreateOrOpenCallback& callback) override; + void EnsureFileExists( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const EnsureFileExistsCallback& callback) override; + void CreateDirectory( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + bool exclusive, + bool recursive, + const StatusCallback& callback) override; + void GetFileInfo(std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + int fields, + const GetFileInfoCallback& callback) override; + void ReadDirectory( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const ReadDirectoryCallback& callback) override; + void Touch(std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const base::Time& last_access_time, + const base::Time& last_modified_time, + const StatusCallback& callback) override; + void Truncate(std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + int64_t length, + const StatusCallback& callback) override; + void CopyFileLocal( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& src_url, + const storage::FileSystemURL& dest_url, + CopyOrMoveOption option, + const CopyFileProgressCallback& progress_callback, + const StatusCallback& callback) override; + void MoveFileLocal( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& src_url, + const storage::FileSystemURL& dest_url, + CopyOrMoveOption option, + const StatusCallback& callback) override; + void CopyInForeignFile( + std::unique_ptr<storage::FileSystemOperationContext> context, + const base::FilePath& src_file_path, + const storage::FileSystemURL& dest_url, + const StatusCallback& callback) override; + void DeleteFile(std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const StatusCallback& callback) override; + void DeleteDirectory( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const StatusCallback& callback) override; + void DeleteRecursively( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const StatusCallback& callback) override; + void CreateSnapshotFile( + std::unique_ptr<storage::FileSystemOperationContext> context, + const storage::FileSystemURL& url, + const CreateSnapshotFileCallback& callback) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ArcContentFileSystemAsyncFileUtil); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_ASYNC_FILE_UTIL_H_
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.cc new file mode 100644 index 0000000..b003e70 --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.cc
@@ -0,0 +1,62 @@ +// 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 "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.h" + +#include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util.h" +#include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h" +#include "content/public/browser/browser_thread.h" +#include "storage/browser/fileapi/file_stream_writer.h" +#include "storage/browser/fileapi/file_system_url.h" + +namespace arc { + +ArcContentFileSystemBackendDelegate::ArcContentFileSystemBackendDelegate() + : async_file_util_(new ArcContentFileSystemAsyncFileUtil()) {} + +ArcContentFileSystemBackendDelegate::~ArcContentFileSystemBackendDelegate() = + default; + +storage::AsyncFileUtil* ArcContentFileSystemBackendDelegate::GetAsyncFileUtil( + storage::FileSystemType type) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_EQ(storage::kFileSystemTypeArcContent, type); + return async_file_util_.get(); +} + +std::unique_ptr<storage::FileStreamReader> +ArcContentFileSystemBackendDelegate::CreateFileStreamReader( + const storage::FileSystemURL& url, + int64_t offset, + int64_t max_bytes_to_read, + const base::Time& expected_modification_time, + storage::FileSystemContext* context) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_EQ(storage::kFileSystemTypeArcContent, url.type()); + return std::unique_ptr<storage::FileStreamReader>( + new ArcContentFileSystemFileStreamReader(url, offset, max_bytes_to_read)); +} + +std::unique_ptr<storage::FileStreamWriter> +ArcContentFileSystemBackendDelegate::CreateFileStreamWriter( + const storage::FileSystemURL& url, + int64_t offset, + storage::FileSystemContext* context) { + NOTIMPLEMENTED(); + return std::unique_ptr<storage::FileStreamWriter>(); +} + +storage::WatcherManager* ArcContentFileSystemBackendDelegate::GetWatcherManager( + storage::FileSystemType type) { + NOTIMPLEMENTED(); + return nullptr; +} + +void ArcContentFileSystemBackendDelegate::GetRedirectURLForContents( + const storage::FileSystemURL& url, + const storage::URLCallback& callback) { + NOTIMPLEMENTED(); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.h b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.h new file mode 100644 index 0000000..66a6503d --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.h
@@ -0,0 +1,49 @@ +// 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 CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_BACKEND_DELEGATE_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_BACKEND_DELEGATE_H_ + +#include <memory> + +#include "base/macros.h" +#include "chrome/browser/chromeos/fileapi/file_system_backend_delegate.h" + +namespace arc { + +// Delegate implementation of the some methods in chromeos::FileSystemBackend +// for ARC content file system. +class ArcContentFileSystemBackendDelegate + : public chromeos::FileSystemBackendDelegate { + public: + ArcContentFileSystemBackendDelegate(); + ~ArcContentFileSystemBackendDelegate() override; + + // FileSystemBackend::Delegate overrides. + storage::AsyncFileUtil* GetAsyncFileUtil( + storage::FileSystemType type) override; + std::unique_ptr<storage::FileStreamReader> CreateFileStreamReader( + const storage::FileSystemURL& url, + int64_t offset, + int64_t max_bytes_to_read, + const base::Time& expected_modification_time, + storage::FileSystemContext* context) override; + std::unique_ptr<storage::FileStreamWriter> CreateFileStreamWriter( + const storage::FileSystemURL& url, + int64_t offset, + storage::FileSystemContext* context) override; + storage::WatcherManager* GetWatcherManager( + storage::FileSystemType type) override; + void GetRedirectURLForContents(const storage::FileSystemURL& url, + const storage::URLCallback& callback) override; + + private: + std::unique_ptr<storage::AsyncFileUtil> async_file_util_; + + DISALLOW_COPY_AND_ASSIGN(ArcContentFileSystemBackendDelegate); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_BACKEND_DELEGATE_H_
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc new file mode 100644 index 0000000..fb41b95 --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc
@@ -0,0 +1,33 @@ +// 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 "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h" + +#include "net/base/net_errors.h" + +namespace arc { + +ArcContentFileSystemFileStreamReader::ArcContentFileSystemFileStreamReader( + const storage::FileSystemURL& url, + int64_t offset, + int64_t max_bytes_to_read) {} + +ArcContentFileSystemFileStreamReader::~ArcContentFileSystemFileStreamReader() = + default; + +int ArcContentFileSystemFileStreamReader::Read( + net::IOBuffer* buffer, + int buffer_length, + const net::CompletionCallback& callback) { + NOTIMPLEMENTED(); + return net::ERR_NOT_IMPLEMENTED; +} + +int64_t ArcContentFileSystemFileStreamReader::GetLength( + const net::Int64CompletionCallback& callback) { + NOTIMPLEMENTED(); + return net::ERR_NOT_IMPLEMENTED; +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h new file mode 100644 index 0000000..2d946744 --- /dev/null +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.h
@@ -0,0 +1,31 @@ +// 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 CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_FILE_STREAM_READER_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_FILE_STREAM_READER_H_ + +#include "storage/browser/fileapi/file_stream_reader.h" + +namespace arc { + +class ArcContentFileSystemFileStreamReader : public storage::FileStreamReader { + public: + ArcContentFileSystemFileStreamReader(const storage::FileSystemURL& url, + int64_t offset, + int64_t max_bytes_to_read); + ~ArcContentFileSystemFileStreamReader() override; + + // storage::FileStreamReader override: + int Read(net::IOBuffer* buffer, + int buffer_length, + const net::CompletionCallback& callback) override; + int64_t GetLength(const net::Int64CompletionCallback& callback) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ArcContentFileSystemFileStreamReader); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_FILEAPI_ARC_CONTENT_FILE_SYSTEM_FILE_STREAM_READER_H_
diff --git a/chrome/browser/chromeos/display/overscan_calibrator.cc b/chrome/browser/chromeos/display/overscan_calibrator.cc index c2c7155b..9163dbfb 100644 --- a/chrome/browser/chromeos/display/overscan_calibrator.cc +++ b/chrome/browser/chromeos/display/overscan_calibrator.cc
@@ -12,7 +12,6 @@ #include "ash/display/display_manager.h" #include "ash/display/window_tree_host_manager.h" #include "ash/shell.h" -#include "base/callback.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkPath.h" @@ -159,8 +158,4 @@ // configuration has changed. } -base::Closure OverscanCalibrator::PrepareForLayerBoundsChange() { - return base::Closure(); -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/display/overscan_calibrator.h b/chrome/browser/chromeos/display/overscan_calibrator.h index cd4973cf..94765e8 100644 --- a/chrome/browser/chromeos/display/overscan_calibrator.h +++ b/chrome/browser/chromeos/display/overscan_calibrator.h
@@ -45,7 +45,6 @@ void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; // The target display. const display::Display display_;
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc index 706e039..edc3b62 100644 --- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc +++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -722,10 +722,7 @@ class WizardControllerDeviceStateTest : public WizardControllerFlowTest { protected: WizardControllerDeviceStateTest() - : install_attributes_(std::string(), - std::string(), - std::string(), - policy::DEVICE_MODE_NOT_SET) { + : install_attributes_(ScopedStubInstallAttributes::CreateUnset()) { fake_statistics_provider_.SetMachineStatistic( system::kSerialNumberKey, "test"); fake_statistics_provider_.SetMachineStatistic(
diff --git a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc index 2eb118e..b2f0134b 100644 --- a/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc +++ b/chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl_unittest.cc
@@ -193,10 +193,9 @@ profile_invalidation_service_(nullptr), fake_user_manager_(new chromeos::FakeChromeUserManager), user_manager_enabler_(fake_user_manager_), - install_attributes_("example.com", - "user@example.com", - "device_id", - DEVICE_MODE_ENTERPRISE), + install_attributes_( + chromeos::ScopedStubInstallAttributes::CreateEnterprise( + "example.com", "device_id")), profile_manager_(TestingBrowserProcess::GetGlobal()) { }
diff --git a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc index bac4402..ca55ceb 100644 --- a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc +++ b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
@@ -138,11 +138,11 @@ ->browser_policy_connector_chromeos(); } - void EnrollDevice(const std::string& username) { + void EnrollDevice(const std::string& domain) { base::RunLoop loop; InstallAttributes::LockResult result; browser_policy_connector()->GetInstallAttributes()->LockDevice( - username, policy::DEVICE_MODE_ENTERPRISE, "100200300", + policy::DEVICE_MODE_ENTERPRISE, domain, std::string(), "100200300", base::Bind(&CopyLockResult, &loop, &result)); loop.Run(); EXPECT_EQ(InstallAttributes::LOCK_SUCCESS, result); @@ -249,7 +249,7 @@ // Enroll the device, if enrollment is enabled for this test instance. if (GetParam().enroll_device) { - EnrollDevice(kUsername); + EnrollDevice(kDomain); EXPECT_FALSE(user_manager->IsUserLoggedIn()); EXPECT_TRUE(browser_policy_connector()->IsEnterpriseManaged());
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc index a29cdcc..775d26b 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc
@@ -171,8 +171,7 @@ // If the device is enterprise-managed, the management domain gets pulled from // install attributes. - install_attributes_.SetRegistrationUser("user@example.com"); - install_attributes_.SetDomain("example.com"); + install_attributes_.SetEnterprise("example.com", "fake-id"); config = device_cloud_policy_initializer_.GetPrescribedEnrollmentConfig(); EXPECT_EQ(EnrollmentConfig::MODE_NONE, config.mode); EXPECT_EQ("example.com", config.management_domain);
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc index 77b76ef..441197a 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -197,8 +197,9 @@ base::RunLoop loop; chromeos::InstallAttributes::LockResult result; install_attributes_->LockDevice( - PolicyBuilder::kFakeUsername, DEVICE_MODE_ENTERPRISE, + PolicyBuilder::kFakeDomain, + std::string(), // realm PolicyBuilder::kFakeDeviceId, base::Bind(&CopyLockResult, &loop, &result)); loop.Run();
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc index 61d39ee..fdbb0b2 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc
@@ -63,8 +63,9 @@ base::RunLoop loop; chromeos::InstallAttributes::LockResult result; install_attributes_->LockDevice( - PolicyBuilder::kFakeUsername, DEVICE_MODE_ENTERPRISE, + PolicyBuilder::kFakeDomain, + std::string(), // realm PolicyBuilder::kFakeDeviceId, base::Bind(&CopyLockResult, &loop, &result)); loop.Run();
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc index 711ecb1..65293fc 100644 --- a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc +++ b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc
@@ -423,7 +423,10 @@ break; case chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED: waiting_for_cros_settings_ = true; - return; + // Purposely break to allow initialization with temporarily untrusted + // settings so that a crash-n-restart public session have its loader + // properly registered as ExtensionService's external provider. + break; case chromeos::CrosSettingsProvider::PERMANENTLY_UNTRUSTED: waiting_for_cros_settings_ = false; return;
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc index 4802538..56bbbf3 100644 --- a/chrome/browser/chromeos/policy/device_status_collector.cc +++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -472,6 +472,8 @@ running_kiosk_app_subscription_ = cros_settings_->AddSettingsObserver( chromeos::kReportRunningKioskApp, callback); + report_arc_status_pref_.Init(prefs::kReportArcStatus, local_state_, callback); + // Fetch the current values of the policies. UpdateReportingSettings(); @@ -498,6 +500,7 @@ void DeviceStatusCollector::RegisterPrefs(PrefRegistrySimple* registry) { registry->RegisterDictionaryPref(prefs::kDeviceActivityTimes, new base::DictionaryValue); + registry->RegisterBooleanPref(prefs::kReportArcStatus, true); } void DeviceStatusCollector::CheckIdleState() { @@ -551,8 +554,7 @@ report_kiosk_session_status_ = true; } - // TODO(phweiss): Create policy to control this, and turn it on by default. - report_android_status_ = false; + report_android_status_ = local_state_->GetBoolean(prefs::kReportArcStatus); if (!report_hardware_status_) { ClearCachedResourceUsage();
diff --git a/chrome/browser/chromeos/policy/device_status_collector.h b/chrome/browser/chromeos/policy/device_status_collector.h index 0d8ae27..702c78b 100644 --- a/chrome/browser/chromeos/policy/device_status_collector.h +++ b/chrome/browser/chromeos/policy/device_status_collector.h
@@ -27,6 +27,7 @@ #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chromeos/system/version_loader.h" #include "components/policy/proto/device_management_backend.pb.h" +#include "components/prefs/pref_member.h" #include "mojo/public/cpp/bindings/string.h" #include "ui/base/idle/idle.h" @@ -284,6 +285,7 @@ os_update_status_subscription_; std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> running_kiosk_app_subscription_; + BooleanPrefMember report_arc_status_pref_; // Task runner in the creation thread where responses are sent to. scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc index 284cd440..a2629d0e 100644 --- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -27,6 +27,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_data.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" +#include "chrome/browser/chromeos/arc/arc_auth_service.h" #include "chrome/browser/chromeos/login/users/mock_user_manager.h" #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" #include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h" @@ -80,6 +81,12 @@ const char kKioskAppId[] = "kiosk_app_id"; const char kExternalMountPoint[] = "/a/b/c"; const char kPublicAccountId[] = "public_user@localhost"; +const char kArcStatus[] = "{\"applications\":[ { " + "\"packageName\":\"com.android.providers.telephony\"," + "\"versionName\":\"6.0.1\"," + "\"permissions\": [\"android.permission.INTERNET\"] }]," + "\"userEmail\":\"xxx@google.com\"}"; +const char kDroidGuardInfo[] = "{\"droid_guard_info\":42}"; class TestingDeviceStatusCollector : public policy::DeviceStatusCollector { public: @@ -225,6 +232,17 @@ receiver.Run(status, droid_guard_info); } +bool GetFakeAndroidStatus( + mojo::String status, + mojo::String droid_guard_info, + const policy::DeviceStatusCollector::AndroidStatusReceiver& receiver) { + // Post it to the thread because this call is expected to be asynchronous. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&CallAndroidStatusReceiver, receiver, + status, droid_guard_info)); + return true; +} + bool GetEmptyAndroidStatus( const policy::DeviceStatusCollector::AndroidStatusReceiver& receiver) { // Post it to the thread because this call is expected to be asynchronous. @@ -251,10 +269,10 @@ : ui_thread_(content::BrowserThread::UI, &message_loop_), file_thread_(content::BrowserThread::FILE, &message_loop_), io_thread_(content::BrowserThread::IO, &message_loop_), - install_attributes_("managed.com", - "user@managed.com", - "device_id", - DEVICE_MODE_ENTERPRISE), + install_attributes_( + chromeos::ScopedStubInstallAttributes::CreateEnterprise( + "managed.com", + "device_id")), settings_helper_(false), user_manager_(new chromeos::MockUserManager()), user_manager_enabler_(user_manager_), @@ -982,9 +1000,40 @@ EXPECT_EQ(0, device_status_.cpu_temp_info_size()); } -TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfNotKioskMode) { +TEST_F(DeviceStatusCollectorTest, TestAndroidReporting) { + RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo), + base::Bind(&GetEmptyCPUStatistics), + base::Bind(&GetEmptyCPUTempInfo), + base::Bind(&GetFakeAndroidStatus, kArcStatus, + kDroidGuardInfo)); + GetStatus(); + EXPECT_EQ(kArcStatus, session_status_.android_status().status_payload()); + EXPECT_EQ(kDroidGuardInfo, + session_status_.android_status().droid_guard_info()); +} + +TEST_F(DeviceStatusCollectorTest, NoAndroidReportingWhenDisabled) { + RestartStatusCollector(base::Bind(&GetEmptyVolumeInfo), + base::Bind(&GetEmptyCPUStatistics), + base::Bind(&GetEmptyCPUTempInfo), + base::Bind(&GetFakeAndroidStatus, kArcStatus, + kDroidGuardInfo)); + + prefs_.SetBoolean(prefs::kReportArcStatus, false); + // Mock Kiosk app, so some session status is reported + status_collector_->set_kiosk_account( + base::MakeUnique<DeviceLocalAccount>(fake_device_local_account_)); + MockRunningKioskApp(fake_device_local_account_); + + GetStatus(); + EXPECT_TRUE(got_session_status_); + EXPECT_FALSE(session_status_.has_android_status()); +} + +TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfNotKioskAndNoArcReporting) { // Should not report session status if we don't have an active kiosk app. settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, true); + prefs_.SetBoolean(prefs::kReportArcStatus, false); GetStatus(); EXPECT_FALSE(got_session_status_); } @@ -992,6 +1041,9 @@ TEST_F(DeviceStatusCollectorTest, NoSessionStatusIfSessionReportingDisabled) { // Should not report session status if session status reporting is disabled. settings_helper_.SetBoolean(chromeos::kReportDeviceSessionStatus, false); + // ReportDeviceSessionStatus only controls Kiosk reporting, ARC reporting + // has to be disabled serarately. + prefs_.SetBoolean(prefs::kReportArcStatus, false); status_collector_->set_kiosk_account( base::MakeUnique<policy::DeviceLocalAccount>(fake_device_local_account_)); // Set up a device-local account for single-app kiosk mode.
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc index f62fb55e..384259c 100644 --- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc +++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chromeos/attestation/attestation_flow.h" +#include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/gaia_urls.h" #include "net/http/http_status_code.h" @@ -316,9 +317,10 @@ DeviceCloudPolicyValidator* validator) { CHECK_EQ(STEP_VALIDATION, enrollment_step_); if (validator->success()) { - policy_ = std::move(validator->policy()); - username_ = validator->policy_data()->username(); + std::string username = validator->policy_data()->username(); + domain_ = gaia::ExtractDomainName(gaia::CanonicalizeEmail(username)); device_id_ = validator->policy_data()->device_id(); + policy_ = std::move(validator->policy()); request_token_ = validator->policy_data()->request_token(); enrollment_step_ = STEP_ROBOT_AUTH_FETCH; client_->FetchRobotAuthCodes(auth_token_); @@ -405,7 +407,7 @@ weak_ptr_factory_.InvalidateWeakPtrs(); install_attributes_->LockDevice( - username_, device_mode_, device_id_, + device_mode_, domain_, std::string() /* realm */, device_id_, base::Bind(&EnrollmentHandlerChromeOS::HandleLockDeviceResult, weak_ptr_factory_.GetWeakPtr())); }
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h index e12bfa8..4331f07 100644 --- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h +++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h
@@ -187,7 +187,7 @@ // The validated policy response info to be installed in the store. std::unique_ptr<enterprise_management::PolicyFetchResponse> policy_; - std::string username_; + std::string domain_; std::string device_id_; std::string request_token_;
diff --git a/chrome/browser/chromeos/settings/install_attributes.cc b/chrome/browser/chromeos/settings/install_attributes.cc index 45039d2..50eb658 100644 --- a/chrome/browser/chromeos/settings/install_attributes.cc +++ b/chrome/browser/chromeos/settings/install_attributes.cc
@@ -25,6 +25,8 @@ namespace chromeos { +namespace cu = cryptohome_util; + namespace { // Number of TPM lock state query retries during consistency check. @@ -33,15 +35,20 @@ // Interval of TPM lock state query retries during consistency check. int kDbusRetryIntervalInSeconds = 5; -bool ReadMapKey(const std::map<std::string, std::string>& map, - const std::string& key, - std::string* value) { +std::string ReadMapKey(const std::map<std::string, std::string>& map, + const std::string& key) { std::map<std::string, std::string>::const_iterator entry = map.find(key); - if (entry == map.end()) - return false; + if (entry != map.end()) { + return entry->second; + } + return std::string(); +} - *value = entry->second; - return true; +void WarnIfNonempty(const std::map<std::string, std::string>& map, + const std::string& key) { + if (!ReadMapKey(map, key).empty()) { + LOG(WARNING) << key << " expected to be empty."; + } } } // namespace @@ -65,11 +72,7 @@ } InstallAttributes::InstallAttributes(CryptohomeClient* cryptohome_client) - : device_locked_(false), - consistency_check_running_(false), - device_lock_running_(false), - registration_mode_(policy::DEVICE_MODE_PENDING), - cryptohome_client_(cryptohome_client), + : cryptohome_client_(cryptohome_client), weak_ptr_factory_(this) { } @@ -110,8 +113,8 @@ for (entry = install_attrs_proto.attributes().begin(); entry != install_attrs_proto.attributes().end(); ++entry) { - // The protobuf values unfortunately contain terminating null characters, so - // we have to sanitize the value here. + // The protobuf values contain terminating null characters, so we have to + // sanitize the value here. attr_map.insert(std::make_pair(entry->name(), std::string(entry->value().c_str()))); } @@ -135,13 +138,14 @@ bool result) { if (call_status == DBUS_METHOD_CALL_SUCCESS && result) { registration_mode_ = policy::DEVICE_MODE_NOT_SET; - if (!cryptohome_util::InstallAttributesIsInvalid() && - !cryptohome_util::InstallAttributesIsFirstInstall()) { + if (!cu::InstallAttributesIsInvalid() && + !cu::InstallAttributesIsFirstInstall()) { device_locked_ = true; static const char* const kEnterpriseAttributes[] = { kAttrEnterpriseDeviceId, kAttrEnterpriseDomain, + kAttrEnterpriseRealm, kAttrEnterpriseMode, kAttrEnterpriseOwned, kAttrEnterpriseUser, @@ -150,8 +154,7 @@ std::map<std::string, std::string> attr_map; for (size_t i = 0; i < arraysize(kEnterpriseAttributes); ++i) { std::string value; - if (cryptohome_util::InstallAttributesGet(kEnterpriseAttributes[i], - &value)) + if (cu::InstallAttributesGet(kEnterpriseAttributes[i], &value)) attr_map[kEnterpriseAttributes[i]] = value; } @@ -161,42 +164,34 @@ callback.Run(); } -void InstallAttributes::LockDevice(const std::string& user, - policy::DeviceMode device_mode, +void InstallAttributes::LockDevice(policy::DeviceMode device_mode, + const std::string& domain, + const std::string& realm, const std::string& device_id, const LockResultCallback& callback) { + CHECK((device_mode == policy::DEVICE_MODE_ENTERPRISE && + !domain.empty() && realm.empty() && !device_id.empty()) || + (device_mode == policy::DEVICE_MODE_ENTERPRISE_AD && + domain.empty() && !realm.empty() && !device_id.empty()) || + (device_mode == policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH && + domain.empty() && realm.empty() && device_id.empty())); DCHECK(!callback.is_null()); CHECK_EQ(device_lock_running_, false); - CHECK_NE(device_mode, policy::DEVICE_MODE_PENDING); - CHECK_NE(device_mode, policy::DEVICE_MODE_NOT_SET); // Check for existing lock first. if (device_locked_) { if (device_mode != registration_mode_) { + LOG(ERROR) << "Trying to re-lock with wrong mode."; callback.Run(LOCK_WRONG_MODE); return; } - switch (registration_mode_) { - case policy::DEVICE_MODE_ENTERPRISE: - case policy::DEVICE_MODE_LEGACY_RETAIL_MODE: { - // Check domain match for enterprise devices. - std::string domain = gaia::ExtractDomainName(user); - if (registration_domain_.empty() || domain != registration_domain_) { - callback.Run(LOCK_WRONG_DOMAIN); - return; - } - break; - } - case policy::DEVICE_MODE_NOT_SET: - case policy::DEVICE_MODE_PENDING: - // This case can't happen due to the CHECK_NE asserts above. - NOTREACHED(); - break; - case policy::DEVICE_MODE_CONSUMER: - case policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH: - // The user parameter is ignored for consumer devices. - break; + if (domain != registration_domain_ || + realm != registration_realm_ || + device_id != registration_device_id_) { + LOG(ERROR) << "Trying to re-lock with non-matching parameters."; + callback.Run(LOCK_WRONG_DOMAIN); + return; } // Already locked in the right mode, signal success. @@ -211,8 +206,9 @@ CHECK(post_check_action_.is_null()); post_check_action_ = base::Bind(&InstallAttributes::LockDevice, weak_ptr_factory_.GetWeakPtr(), - user, device_mode, + domain, + realm, device_id, callback); return; @@ -222,15 +218,17 @@ cryptohome_client_->InstallAttributesIsReady( base::Bind(&InstallAttributes::LockDeviceIfAttributesIsReady, weak_ptr_factory_.GetWeakPtr(), - user, device_mode, + domain, + realm, device_id, callback)); } void InstallAttributes::LockDeviceIfAttributesIsReady( - const std::string& user, policy::DeviceMode device_mode, + const std::string& domain, + const std::string& realm, const std::string& device_id, const LockResultCallback& callback, DBusMethodCallStatus call_status, @@ -242,60 +240,47 @@ } // Clearing the TPM password seems to be always a good deal. - if (cryptohome_util::TpmIsEnabled() && - !cryptohome_util::TpmIsBeingOwned() && - cryptohome_util::TpmIsOwned()) { + if (cu::TpmIsEnabled() && !cu::TpmIsBeingOwned() && cu::TpmIsOwned()) { cryptohome_client_->CallTpmClearStoredPasswordAndBlock(); } // Make sure we really have a working InstallAttrs. - if (cryptohome_util::InstallAttributesIsInvalid()) { + if (cu::InstallAttributesIsInvalid()) { LOG(ERROR) << "Install attributes invalid."; device_lock_running_ = false; callback.Run(LOCK_BACKEND_INVALID); return; } - if (!cryptohome_util::InstallAttributesIsFirstInstall()) { + if (!cu::InstallAttributesIsFirstInstall()) { LOG(ERROR) << "Install attributes already installed."; device_lock_running_ = false; callback.Run(LOCK_ALREADY_LOCKED); return; } - std::string mode = GetDeviceModeString(device_mode); - std::string registration_user; - if (!user.empty()) - registration_user = gaia::CanonicalizeEmail(user); - + // Set values in the InstallAttrs. + std::string kiosk_enabled, enterprise_owned; if (device_mode == policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH) { - // Set values in the InstallAttrs and lock it. - if (!cryptohome_util::InstallAttributesSet(kAttrConsumerKioskEnabled, - "true")) { - LOG(ERROR) << "Failed writing attributes."; - device_lock_running_ = false; - callback.Run(LOCK_SET_ERROR); - return; - } + kiosk_enabled = "true"; } else { - std::string domain = gaia::ExtractDomainName(registration_user); - // Set values in the InstallAttrs and lock it. - if (!cryptohome_util::InstallAttributesSet(kAttrEnterpriseOwned, "true") || - !cryptohome_util::InstallAttributesSet(kAttrEnterpriseUser, - registration_user) || - !cryptohome_util::InstallAttributesSet(kAttrEnterpriseDomain, domain) || - !cryptohome_util::InstallAttributesSet(kAttrEnterpriseMode, mode) || - !cryptohome_util::InstallAttributesSet(kAttrEnterpriseDeviceId, - device_id)) { - LOG(ERROR) << "Failed writing attributes."; - device_lock_running_ = false; - callback.Run(LOCK_SET_ERROR); - return; - } + enterprise_owned = "true"; + } + std::string mode = GetDeviceModeString(device_mode); + if (!cu::InstallAttributesSet(kAttrConsumerKioskEnabled, kiosk_enabled) || + !cu::InstallAttributesSet(kAttrEnterpriseOwned, enterprise_owned) || + !cu::InstallAttributesSet(kAttrEnterpriseMode, mode) || + !cu::InstallAttributesSet(kAttrEnterpriseDomain, domain) || + !cu::InstallAttributesSet(kAttrEnterpriseRealm, realm) || + !cu::InstallAttributesSet(kAttrEnterpriseDeviceId, device_id)) { + LOG(ERROR) << "Failed writing attributes."; + device_lock_running_ = false; + callback.Run(LOCK_SET_ERROR); + return; } - if (!cryptohome_util::InstallAttributesFinalize() || - cryptohome_util::InstallAttributesIsFirstInstall()) { + if (!cu::InstallAttributesFinalize() || + cu::InstallAttributesIsFirstInstall()) { LOG(ERROR) << "Failed locking."; device_lock_running_ = false; callback.Run(LOCK_FINALIZE_ERROR); @@ -305,27 +290,39 @@ ReadImmutableAttributes( base::Bind(&InstallAttributes::OnReadImmutableAttributes, weak_ptr_factory_.GetWeakPtr(), - registration_user, + device_mode, + domain, + realm, + device_id, callback)); } void InstallAttributes::OnReadImmutableAttributes( - const std::string& registration_user, + policy::DeviceMode mode, + const std::string& domain, + const std::string& realm, + const std::string& device_id, const LockResultCallback& callback) { + device_lock_running_ = false; - if (GetRegistrationUser() != registration_user) { + if (registration_mode_ != mode || + registration_domain_ != domain || + registration_realm_ != realm || + registration_device_id_ != device_id) { LOG(ERROR) << "Locked data doesn't match."; - device_lock_running_ = false; callback.Run(LOCK_READBACK_ERROR); return; } - device_lock_running_ = false; callback.Run(LOCK_SUCCESS); } bool InstallAttributes::IsEnterpriseDevice() const { - return device_locked_ && !registration_user_.empty(); + if (!device_locked_) { + return false; + } + return registration_mode_ == policy::DEVICE_MODE_ENTERPRISE || + registration_mode_ == policy::DEVICE_MODE_ENTERPRISE_AD; } bool InstallAttributes::IsConsumerKioskDeviceWithAutoLaunch() { @@ -333,24 +330,6 @@ registration_mode_ == policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH; } -std::string InstallAttributes::GetDomain() const { - if (!IsEnterpriseDevice()) - return std::string(); - - return registration_domain_; -} - -std::string InstallAttributes::GetDeviceId() { - if (!IsEnterpriseDevice()) - return std::string(); - - return registration_device_id_; -} - -policy::DeviceMode InstallAttributes::GetMode() { - return registration_mode_; -} - void InstallAttributes::TriggerConsistencyCheck(int dbus_retries) { cryptohome_client_->TpmIsOwned( base::Bind(&InstallAttributes::OnTpmOwnerCheckCompleted, @@ -394,13 +373,14 @@ // that all changes to the constants are reflected there as well. const char InstallAttributes::kConsumerDeviceMode[] = "consumer"; const char InstallAttributes::kEnterpriseDeviceMode[] = "enterprise"; +const char InstallAttributes::kEnterpriseADDeviceMode[] = "enterprise_ad"; const char InstallAttributes::kLegacyRetailDeviceMode[] = "kiosk"; const char InstallAttributes::kConsumerKioskDeviceMode[] = "consumer_kiosk"; -const char InstallAttributes::kUnknownDeviceMode[] = "unknown"; const char InstallAttributes::kAttrEnterpriseDeviceId[] = "enterprise.device_id"; const char InstallAttributes::kAttrEnterpriseDomain[] = "enterprise.domain"; +const char InstallAttributes::kAttrEnterpriseRealm[] = "enterprise.realm"; const char InstallAttributes::kAttrEnterpriseMode[] = "enterprise.mode"; const char InstallAttributes::kAttrEnterpriseOwned[] = "enterprise.owned"; const char InstallAttributes::kAttrEnterpriseUser[] = "enterprise.user"; @@ -423,6 +403,8 @@ return InstallAttributes::kConsumerDeviceMode; case policy::DEVICE_MODE_ENTERPRISE: return InstallAttributes::kEnterpriseDeviceMode; + case policy::DEVICE_MODE_ENTERPRISE_AD: + return InstallAttributes::kEnterpriseADDeviceMode; case policy::DEVICE_MODE_LEGACY_RETAIL_MODE: return InstallAttributes::kLegacyRetailDeviceMode; case policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH: @@ -432,7 +414,7 @@ break; } NOTREACHED() << "Invalid device mode: " << mode; - return InstallAttributes::kUnknownDeviceMode; + return std::string(); } policy::DeviceMode InstallAttributes::GetDeviceModeFromString( @@ -441,59 +423,86 @@ return policy::DEVICE_MODE_CONSUMER; else if (mode == InstallAttributes::kEnterpriseDeviceMode) return policy::DEVICE_MODE_ENTERPRISE; + else if (mode == InstallAttributes::kEnterpriseADDeviceMode) + return policy::DEVICE_MODE_ENTERPRISE_AD; else if (mode == InstallAttributes::kLegacyRetailDeviceMode) return policy::DEVICE_MODE_LEGACY_RETAIL_MODE; else if (mode == InstallAttributes::kConsumerKioskDeviceMode) return policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH; - NOTREACHED() << "Unknown device mode string: " << mode; return policy::DEVICE_MODE_NOT_SET; } void InstallAttributes::DecodeInstallAttributes( const std::map<std::string, std::string>& attr_map) { - std::string enterprise_owned; - std::string enterprise_user; - std::string consumer_kiosk_enabled; - if (ReadMapKey(attr_map, kAttrEnterpriseOwned, &enterprise_owned) && - ReadMapKey(attr_map, kAttrEnterpriseUser, &enterprise_user) && - enterprise_owned == "true" && - !enterprise_user.empty()) { - registration_user_ = gaia::CanonicalizeEmail(enterprise_user); + // Start from a clean slate. + registration_mode_ = policy::DEVICE_MODE_NOT_SET; + registration_domain_.clear(); + registration_realm_.clear(); + registration_device_id_.clear(); - // Initialize the mode to the legacy enterprise mode here and update - // below if more information is present. - registration_mode_ = policy::DEVICE_MODE_ENTERPRISE; + const std::string enterprise_owned = + ReadMapKey(attr_map, kAttrEnterpriseOwned); + const std::string consumer_kiosk_enabled = + ReadMapKey(attr_map, kAttrConsumerKioskEnabled); + const std::string mode = ReadMapKey(attr_map, kAttrEnterpriseMode); + const std::string domain = ReadMapKey(attr_map, kAttrEnterpriseDomain); + const std::string realm = ReadMapKey(attr_map, kAttrEnterpriseRealm); + const std::string device_id = ReadMapKey(attr_map, kAttrEnterpriseDeviceId); + const std::string user_deprecated = ReadMapKey(attr_map, kAttrEnterpriseUser); - // If we could extract basic setting we should try to extract the - // extended ones too. We try to set these to defaults as good as - // as possible if present, which could happen for device enrolled in - // pre 19 revisions of the code, before these new attributes were added. - if (ReadMapKey(attr_map, kAttrEnterpriseDomain, ®istration_domain_)) - registration_domain_ = gaia::CanonicalizeDomain(registration_domain_); - else - registration_domain_ = gaia::ExtractDomainName(registration_user_); + if (enterprise_owned == "true") { + WarnIfNonempty(attr_map, kAttrConsumerKioskEnabled); + registration_device_id_ = device_id; - ReadMapKey(attr_map, kAttrEnterpriseDeviceId, ®istration_device_id_); + // Set registration_mode_. + registration_mode_ = GetDeviceModeFromString(mode); + if (registration_mode_ != policy::DEVICE_MODE_ENTERPRISE && + registration_mode_ != policy::DEVICE_MODE_ENTERPRISE_AD) { + if (!mode.empty()) { + LOG(WARNING) << "Bad " << kAttrEnterpriseMode << ": " << mode; + } + registration_mode_ = policy::DEVICE_MODE_ENTERPRISE; + } - std::string mode; - if (ReadMapKey(attr_map, kAttrEnterpriseMode, &mode)) - registration_mode_ = GetDeviceModeFromString(mode); - } else if (ReadMapKey(attr_map, - kAttrConsumerKioskEnabled, - &consumer_kiosk_enabled) && - consumer_kiosk_enabled == "true") { + if (registration_mode_ == policy::DEVICE_MODE_ENTERPRISE) { + // Either set registration_domain_ ... + WarnIfNonempty(attr_map, kAttrEnterpriseRealm); + if (!domain.empty()) { + // The canonicalization is for compatibility with earlier versions. + registration_domain_ = gaia::CanonicalizeDomain(domain); + } else if (!user_deprecated.empty()) { + // Compatibility for pre M19 code. + registration_domain_ = gaia::ExtractDomainName(user_deprecated); + } else { + LOG(WARNING) << "Couldn't read domain."; + } + } else { + // ... or set registration_realm_. + WarnIfNonempty(attr_map, kAttrEnterpriseDomain); + if (!realm.empty()) { + registration_realm_ = realm; + } else { + LOG(WARNING) << "Couldn't read realm."; + } + } + + return; + } + + WarnIfNonempty(attr_map, kAttrEnterpriseOwned); + WarnIfNonempty(attr_map, kAttrEnterpriseDomain); + WarnIfNonempty(attr_map, kAttrEnterpriseRealm); + WarnIfNonempty(attr_map, kAttrEnterpriseDeviceId); + WarnIfNonempty(attr_map, kAttrEnterpriseUser); + if (consumer_kiosk_enabled == "true") { registration_mode_ = policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH; - } else if (enterprise_user.empty() && enterprise_owned != "true") { - // |registration_user_| is empty on consumer devices. + return; + } + + WarnIfNonempty(attr_map, kAttrConsumerKioskEnabled); + if (user_deprecated.empty()) { registration_mode_ = policy::DEVICE_MODE_CONSUMER; } } -std::string InstallAttributes::GetRegistrationUser() const { - if (!device_locked_) - return std::string(); - - return registration_user_; -} - } // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/install_attributes.h b/chrome/browser/chromeos/settings/install_attributes.h index ba20b0c8..94ba7e4 100644 --- a/chrome/browser/chromeos/settings/install_attributes.h +++ b/chrome/browser/chromeos/settings/install_attributes.h
@@ -35,7 +35,8 @@ LOCK_SET_ERROR = 5, // Failed to set attributes. LOCK_FINALIZE_ERROR = 6, // Backend failed to lock. LOCK_READBACK_ERROR = 7, // Inconsistency reading back registration data. - LOCK_WRONG_DOMAIN = 8, // Device already registered to another domain. + LOCK_WRONG_DOMAIN = 8, // Device already registered to another domain or + // other mismatch of other attributes. LOCK_WRONG_MODE = 9, // Device already locked to a different mode. }; @@ -51,7 +52,7 @@ // Tries to read install attributes from the cache file which is created early // during the boot process. The cache file is used to work around slow - // cryptohome startup, which takes a while to register its DBus interface. + // cryptohome startup, which takes a while to register its D-Bus interface. // (See http://crosbug.com/37367 for background on this.) void Init(const base::FilePath& cache_file); @@ -61,13 +62,15 @@ // ReadAttributesIfReady(). void ReadImmutableAttributes(const base::Closure& callback); - // Locks the device to be an enterprise device registered by the given user. - // This can also be called after the lock has already been taken, in which - // case it checks that the passed user agrees with the locked attribute. + // Locks the device into |device_mode|. Depending on |device_mode|, a + // specific subset of |domain|, |realm| and |device_id| must be set. Can also + // be called after the lock has already been taken, in which case it checks + // that the passed parameters fully agree with the locked attributes. // |callback| must not be null and is called with the result. Must not be // called while a previous LockDevice() invocation is still pending. - void LockDevice(const std::string& user, - policy::DeviceMode device_mode, + void LockDevice(policy::DeviceMode device_mode, + const std::string& domain, + const std::string& realm, const std::string& device_id, const LockResultCallback& callback); @@ -77,41 +80,46 @@ // Checks whether this is a consumer kiosk enabled device. bool IsConsumerKioskDeviceWithAutoLaunch(); - // Gets the domain this device belongs to or an empty string if the device is - // not an enterprise device. - std::string GetDomain() const; + // Return the mode the device was enrolled to. The return value for devices + // that are not locked yet is DEVICE_MODE_UNKNOWN. + policy::DeviceMode GetMode() const { return registration_mode_; } - // Gets the device id that was generated when the device was registered. + // Return the domain this device belongs to or an empty string if the device + // is not a cloud-managed enterprise device. + std::string GetDomain() const { return registration_domain_; } + + // Return the realm this device belongs to or an empty string if the device is + // not an AD enterprise device. + std::string GetRealm() const { return registration_realm_; } + + // Return the device id that was generated when the device was registered. // Returns an empty string if the device is not an enterprise device or the // device id was not stored in the lockbox (prior to R19). - std::string GetDeviceId(); - - // Gets the mode the device was enrolled to. The return value for devices that - // are not locked yet will be DEVICE_MODE_UNKNOWN. - policy::DeviceMode GetMode(); + std::string GetDeviceId() const { return registration_device_id_; } protected: // True if install attributes have been read successfully. False if read // failed or no read attempt was made. - bool device_locked_; + bool device_locked_ = false; // Whether the TPM / install attributes consistency check is running. - bool consistency_check_running_; + bool consistency_check_running_ = false; // To be run after the consistency check has finished. base::Closure post_check_action_; // Wether the LockDevice() initiated TPM calls are running. - bool device_lock_running_; + bool device_lock_running_ = false; - std::string registration_user_; + // The actual install attributes. Populated by DecodeInstallAttributes() + // exclusively. + policy::DeviceMode registration_mode_ = policy::DEVICE_MODE_PENDING; std::string registration_domain_; + std::string registration_realm_; std::string registration_device_id_; - policy::DeviceMode registration_mode_; private: FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, DeviceLockedFromOlderVersion); - FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, GetRegistrationUser); FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, Init); FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, InitForConsumerKiosk); FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, LockCanonicalize); @@ -121,13 +129,14 @@ // Constants for the possible device modes that can be stored in the lockbox. static const char kConsumerDeviceMode[]; static const char kEnterpriseDeviceMode[]; + static const char kEnterpriseADDeviceMode[]; static const char kLegacyRetailDeviceMode[]; static const char kConsumerKioskDeviceMode[]; - static const char kUnknownDeviceMode[]; // Field names in the lockbox. static const char kAttrEnterpriseDeviceId[]; static const char kAttrEnterpriseDomain[]; + static const char kAttrEnterpriseRealm[]; static const char kAttrEnterpriseMode[]; static const char kAttrEnterpriseOwned[]; static const char kAttrEnterpriseUser[]; @@ -143,7 +152,9 @@ // Translates strings used in the lockbox to DeviceMode values. policy::DeviceMode GetDeviceModeFromString(const std::string& mode); - // Decodes the install attributes provided in |attr_map|. + // Decode the install attributes provided in |attr_map| (including some + // normalization and processing for backward compatibility) and guarantee that + // |registration_*| members are set self-consistently. void DecodeInstallAttributes( const std::map<std::string, std::string>& attr_map); @@ -154,15 +165,19 @@ // Helper for LockDevice(). Handles the result of InstallAttributesIsReady() // and continue processing LockDevice if the result is true. - void LockDeviceIfAttributesIsReady(const std::string& user, - policy::DeviceMode device_mode, + void LockDeviceIfAttributesIsReady(policy::DeviceMode device_mode, + const std::string& domain, + const std::string& realm, const std::string& device_id, const LockResultCallback& callback, DBusMethodCallStatus call_status, bool result); // Confirms the registered user and invoke the callback. - void OnReadImmutableAttributes(const std::string& user, + void OnReadImmutableAttributes(policy::DeviceMode mode, + const std::string& domain, + const std::string& realm, + const std::string& device_id, const LockResultCallback& callback); // Check state of install attributes against TPM lock state and generate UMA @@ -176,10 +191,6 @@ DBusMethodCallStatus call_status, bool result); - // Gets the user that registered the device. Returns an empty string if the - // device is not an enterprise device. - std::string GetRegistrationUser() const; - CryptohomeClient* cryptohome_client_; base::WeakPtrFactory<InstallAttributes> weak_ptr_factory_;
diff --git a/chrome/browser/chromeos/settings/install_attributes_unittest.cc b/chrome/browser/chromeos/settings/install_attributes_unittest.cc index c9c85bf..f5f5702 100644 --- a/chrome/browser/chromeos/settings/install_attributes_unittest.cc +++ b/chrome/browser/chromeos/settings/install_attributes_unittest.cc
@@ -34,10 +34,10 @@ } // namespace -static const char kTestUser[] = "test@example.com"; -static const char kTestUserCanonicalize[] = "UPPER.CASE@example.com"; static const char kTestDomain[] = "example.com"; +static const char kTestRealm[] = "realm.example.com"; static const char kTestDeviceId[] = "133750519"; +static const char kTestUserDeprecated[] = "test@example.com"; class InstallAttributesTest : public testing::Test { protected: @@ -74,14 +74,16 @@ std::unique_ptr<InstallAttributes> install_attributes_; InstallAttributes::LockResult LockDeviceAndWaitForResult( - const std::string& user, policy::DeviceMode device_mode, + const std::string& domain, + const std::string& realm, const std::string& device_id) { base::RunLoop loop; InstallAttributes::LockResult result; install_attributes_->LockDevice( - user, device_mode, + domain, + realm, device_id, base::Bind(&CopyLockResult, &loop, &result)); loop.Run(); @@ -91,96 +93,92 @@ TEST_F(InstallAttributesTest, Lock) { EXPECT_EQ(InstallAttributes::LOCK_SUCCESS, - LockDeviceAndWaitForResult(kTestUser, - policy::DEVICE_MODE_ENTERPRISE, + LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE, + kTestDomain, + std::string(), // realm kTestDeviceId)); // Locking an already locked device should succeed if the parameters match. EXPECT_EQ(InstallAttributes::LOCK_SUCCESS, - LockDeviceAndWaitForResult(kTestUser, - policy::DEVICE_MODE_ENTERPRISE, - kTestDeviceId)); - - // Another user from the same domain should also succeed. - EXPECT_EQ(InstallAttributes::LOCK_SUCCESS, - LockDeviceAndWaitForResult("test1@example.com", - policy::DEVICE_MODE_ENTERPRISE, + LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE, + kTestDomain, + std::string(), // realm kTestDeviceId)); // But another domain should fail. EXPECT_EQ(InstallAttributes::LOCK_WRONG_DOMAIN, - LockDeviceAndWaitForResult("test@bluebears.com", - policy::DEVICE_MODE_ENTERPRISE, + LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE, + "anotherexample.com", + std::string(), // realm kTestDeviceId)); // A non-matching mode should fail as well. EXPECT_EQ(InstallAttributes::LOCK_WRONG_MODE, - LockDeviceAndWaitForResult(kTestUser, policy::DEVICE_MODE_CONSUMER, - kTestDeviceId)); -} - -TEST_F(InstallAttributesTest, LockCanonicalize) { - EXPECT_EQ(InstallAttributes::LOCK_SUCCESS, LockDeviceAndWaitForResult( - kTestUserCanonicalize, - policy::DEVICE_MODE_ENTERPRISE, - kTestDeviceId)); - EXPECT_EQ(gaia::CanonicalizeEmail(kTestUserCanonicalize), - install_attributes_->GetRegistrationUser()); + policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH, + std::string(), // domain + std::string(), // realm + std::string())); // device id } -TEST_F(InstallAttributesTest, IsEnterpriseDevice) { +TEST_F(InstallAttributesTest, IsEnterpriseDeviceCloud) { install_attributes_->Init(GetTempPath()); EXPECT_FALSE(install_attributes_->IsEnterpriseDevice()); ASSERT_EQ(InstallAttributes::LOCK_SUCCESS, LockDeviceAndWaitForResult( - kTestUser, policy::DEVICE_MODE_ENTERPRISE, + kTestDomain, + std::string(), // realm kTestDeviceId)); EXPECT_TRUE(install_attributes_->IsEnterpriseDevice()); } -TEST_F(InstallAttributesTest, GetDomain) { +TEST_F(InstallAttributesTest, IsEnterpriseDeviceRealm) { install_attributes_->Init(GetTempPath()); + EXPECT_FALSE(install_attributes_->IsEnterpriseDevice()); + ASSERT_EQ(InstallAttributes::LOCK_SUCCESS, + LockDeviceAndWaitForResult( + policy::DEVICE_MODE_ENTERPRISE_AD, + std::string(), // domain + kTestRealm, + kTestDeviceId)); + EXPECT_TRUE(install_attributes_->IsEnterpriseDevice()); +} + +TEST_F(InstallAttributesTest, GettersCloud) { + install_attributes_->Init(GetTempPath()); + EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode()); EXPECT_EQ(std::string(), install_attributes_->GetDomain()); - ASSERT_EQ(InstallAttributes::LOCK_SUCCESS, - LockDeviceAndWaitForResult( - kTestUser, - policy::DEVICE_MODE_ENTERPRISE, - kTestDeviceId)); - EXPECT_EQ(kTestDomain, install_attributes_->GetDomain()); -} - -TEST_F(InstallAttributesTest, GetRegistrationUser) { - install_attributes_->Init(GetTempPath()); - EXPECT_EQ(std::string(), install_attributes_->GetRegistrationUser()); - ASSERT_EQ(InstallAttributes::LOCK_SUCCESS, - LockDeviceAndWaitForResult( - kTestUser, - policy::DEVICE_MODE_ENTERPRISE, - kTestDeviceId)); - EXPECT_EQ(kTestUser, install_attributes_->GetRegistrationUser()); -} - -TEST_F(InstallAttributesTest, GetDeviceId) { - install_attributes_->Init(GetTempPath()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); EXPECT_EQ(std::string(), install_attributes_->GetDeviceId()); ASSERT_EQ(InstallAttributes::LOCK_SUCCESS, LockDeviceAndWaitForResult( - kTestUser, policy::DEVICE_MODE_ENTERPRISE, + kTestDomain, + std::string(), // realm kTestDeviceId)); + EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode()); + EXPECT_EQ(kTestDomain, install_attributes_->GetDomain()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); EXPECT_EQ(kTestDeviceId, install_attributes_->GetDeviceId()); } -TEST_F(InstallAttributesTest, GetMode) { +TEST_F(InstallAttributesTest, GettersAD) { install_attributes_->Init(GetTempPath()); EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode()); + EXPECT_EQ(std::string(), install_attributes_->GetDomain()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); + EXPECT_EQ(std::string(), install_attributes_->GetDeviceId()); ASSERT_EQ(InstallAttributes::LOCK_SUCCESS, - LockDeviceAndWaitForResult(kTestUser, - policy::DEVICE_MODE_ENTERPRISE, - kTestDeviceId)); - EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode()); + LockDeviceAndWaitForResult( + policy::DEVICE_MODE_ENTERPRISE_AD, + std::string(), // domain + kTestRealm, + kTestDeviceId)); + EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE_AD, install_attributes_->GetMode()); + EXPECT_EQ(std::string(), install_attributes_->GetDomain()); + EXPECT_EQ(kTestRealm, install_attributes_->GetRealm()); + EXPECT_EQ(kTestDeviceId, install_attributes_->GetDeviceId()); } TEST_F(InstallAttributesTest, ConsumerDevice) { @@ -194,6 +192,9 @@ ASSERT_FALSE(cryptohome_util::InstallAttributesIsFirstInstall()); EXPECT_EQ(policy::DEVICE_MODE_CONSUMER, install_attributes_->GetMode()); + EXPECT_EQ(std::string(), install_attributes_->GetDomain()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); + EXPECT_EQ(std::string(), install_attributes_->GetDeviceId()); } TEST_F(InstallAttributesTest, ConsumerKioskDevice) { @@ -202,13 +203,17 @@ // Lock the attributes for consumer kiosk. ASSERT_EQ(InstallAttributes::LOCK_SUCCESS, LockDeviceAndWaitForResult( - std::string(), policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH, + std::string(), + std::string(), std::string())); ASSERT_FALSE(cryptohome_util::InstallAttributesIsFirstInstall()); EXPECT_EQ(policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH, install_attributes_->GetMode()); + EXPECT_EQ(std::string(), install_attributes_->GetDomain()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); + EXPECT_EQ(std::string(), install_attributes_->GetDeviceId()); ASSERT_TRUE(install_attributes_->IsConsumerKioskDeviceWithAutoLaunch()); } @@ -219,7 +224,7 @@ ASSERT_TRUE(cryptohome_util::InstallAttributesSet( InstallAttributes::kAttrEnterpriseOwned, "true")); ASSERT_TRUE(cryptohome_util::InstallAttributesSet( - InstallAttributes::kAttrEnterpriseUser, kTestUser)); + InstallAttributes::kAttrEnterpriseUser, kTestUserDeprecated)); ASSERT_TRUE(cryptohome_util::InstallAttributesFinalize()); base::RunLoop loop; install_attributes_->ReadImmutableAttributes(loop.QuitClosure()); @@ -228,8 +233,8 @@ ASSERT_FALSE(cryptohome_util::InstallAttributesIsFirstInstall()); EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode()); EXPECT_EQ(kTestDomain, install_attributes_->GetDomain()); - EXPECT_EQ(kTestUser, install_attributes_->GetRegistrationUser()); - EXPECT_EQ("", install_attributes_->GetDeviceId()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); + EXPECT_EQ(std::string(), install_attributes_->GetDeviceId()); } TEST_F(InstallAttributesTest, Init) { @@ -237,15 +242,15 @@ SetAttribute(&install_attrs_proto, InstallAttributes::kAttrEnterpriseOwned, "true"); SetAttribute(&install_attrs_proto, - InstallAttributes::kAttrEnterpriseUser, kTestUser); + InstallAttributes::kAttrEnterpriseUser, kTestUserDeprecated); const std::string blob(install_attrs_proto.SerializeAsString()); ASSERT_EQ(static_cast<int>(blob.size()), base::WriteFile(GetTempPath(), blob.c_str(), blob.size())); install_attributes_->Init(GetTempPath()); EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode()); EXPECT_EQ(kTestDomain, install_attributes_->GetDomain()); - EXPECT_EQ(kTestUser, install_attributes_->GetRegistrationUser()); - EXPECT_EQ("", install_attributes_->GetDeviceId()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); + EXPECT_EQ(std::string(), install_attributes_->GetDeviceId()); } TEST_F(InstallAttributesTest, InitForConsumerKiosk) { @@ -258,9 +263,9 @@ install_attributes_->Init(GetTempPath()); EXPECT_EQ(policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH, install_attributes_->GetMode()); - EXPECT_EQ("", install_attributes_->GetDomain()); - EXPECT_EQ("", install_attributes_->GetRegistrationUser()); - EXPECT_EQ("", install_attributes_->GetDeviceId()); + EXPECT_EQ(std::string(), install_attributes_->GetDomain()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); + EXPECT_EQ(std::string(), install_attributes_->GetDeviceId()); } TEST_F(InstallAttributesTest, VerifyFakeInstallAttributesCache) { @@ -269,18 +274,21 @@ // Verify that no attributes are initially set. install_attributes_->Init(GetTempPath()); - EXPECT_EQ("", install_attributes_->GetRegistrationUser()); + EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode()); // Write test values. ASSERT_TRUE(cryptohome_util::InstallAttributesSet( InstallAttributes::kAttrEnterpriseOwned, "true")); ASSERT_TRUE(cryptohome_util::InstallAttributesSet( - InstallAttributes::kAttrEnterpriseUser, kTestUser)); + InstallAttributes::kAttrEnterpriseUser, kTestUserDeprecated)); ASSERT_TRUE(cryptohome_util::InstallAttributesFinalize()); // Verify that InstallAttributes correctly decodes the stub cache file. install_attributes_->Init(GetTempPath()); - EXPECT_EQ(kTestUser, install_attributes_->GetRegistrationUser()); + EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode()); + EXPECT_EQ(kTestDomain, install_attributes_->GetDomain()); + EXPECT_EQ(std::string(), install_attributes_->GetRealm()); + EXPECT_EQ(std::string(), install_attributes_->GetDeviceId()); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/stub_install_attributes.cc b/chrome/browser/chromeos/settings/stub_install_attributes.cc index 348b4fa1..aaafadcf 100644 --- a/chrome/browser/chromeos/settings/stub_install_attributes.cc +++ b/chrome/browser/chromeos/settings/stub_install_attributes.cc
@@ -15,34 +15,58 @@ device_locked_ = true; } -void StubInstallAttributes::SetDomain(const std::string& domain) { +void StubInstallAttributes::Clear() { + registration_mode_ = policy::DEVICE_MODE_NOT_SET; + registration_domain_.clear(); + registration_realm_.clear(); + registration_device_id_.clear(); +} + +void StubInstallAttributes::SetConsumer() { + registration_mode_ = policy::DEVICE_MODE_CONSUMER; + registration_domain_.clear(); + registration_realm_.clear(); + registration_device_id_.clear(); +} + +void StubInstallAttributes::SetEnterprise(const std::string& domain, + const std::string& device_id) { + registration_mode_ = policy::DEVICE_MODE_ENTERPRISE; registration_domain_ = domain; + registration_realm_.clear(); + registration_device_id_ = device_id; } -void StubInstallAttributes::SetRegistrationUser(const std::string& user) { - registration_user_ = user; -} - -void StubInstallAttributes::SetDeviceId(const std::string& id) { - registration_device_id_ = id; -} - -void StubInstallAttributes::SetMode(policy::DeviceMode mode) { - registration_mode_ = mode; -} - -ScopedStubInstallAttributes::ScopedStubInstallAttributes( - const std::string& domain, - const std::string& registration_user, - const std::string& device_id, - policy::DeviceMode mode) { +// static +ScopedStubInstallAttributes ScopedStubInstallAttributes::CreateUnset() { StubInstallAttributes* attributes = new StubInstallAttributes(); - attributes->SetDomain(domain); - attributes->SetRegistrationUser(registration_user); - attributes->SetDeviceId(device_id); - attributes->SetMode(mode); + attributes->Clear(); policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( attributes); + return ScopedStubInstallAttributes(); +} + +// static +ScopedStubInstallAttributes ScopedStubInstallAttributes::CreateConsumer() { + StubInstallAttributes* attributes = new StubInstallAttributes(); + attributes->SetConsumer(); + policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( + attributes); + return ScopedStubInstallAttributes(); +} + +// static +ScopedStubInstallAttributes ScopedStubInstallAttributes::CreateEnterprise( + const std::string& domain, + const std::string& device_id) { + StubInstallAttributes* attributes = new StubInstallAttributes(); + attributes->SetEnterprise(domain, device_id); + policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( + attributes); + return ScopedStubInstallAttributes(); +} + +ScopedStubInstallAttributes::ScopedStubInstallAttributes() { } ScopedStubInstallAttributes::~ScopedStubInstallAttributes() {
diff --git a/chrome/browser/chromeos/settings/stub_install_attributes.h b/chrome/browser/chromeos/settings/stub_install_attributes.h index 86a943a7..2358c2c3 100644 --- a/chrome/browser/chromeos/settings/stub_install_attributes.h +++ b/chrome/browser/chromeos/settings/stub_install_attributes.h
@@ -13,17 +13,19 @@ namespace chromeos { -// This class allows tests to override specific values for easier testing. -// To make IsEnterpriseDevice() return true, set a non-empty registration -// user. +// This class allows tests to set specific configurations for testing. class StubInstallAttributes : public InstallAttributes { public: StubInstallAttributes(); - void SetDomain(const std::string& domain); - void SetRegistrationUser(const std::string& user); - void SetDeviceId(const std::string& id); - void SetMode(policy::DeviceMode mode); + // Setup as not-yet enrolled. + void Clear(); + + // Setup as consumer device. (Clears existing configuration.) + void SetConsumer(); + + // Setup as enterprise enrolled. (Clears existing configuration.) + void SetEnterprise(const std::string& domain, const std::string& device_id); private: DISALLOW_COPY_AND_ASSIGN(StubInstallAttributes); @@ -32,11 +34,21 @@ // Helper class to set install attributes in the scope of a test. class ScopedStubInstallAttributes { public: - ScopedStubInstallAttributes(const std::string& domain, - const std::string& registration_user, - const std::string& device_id, - policy::DeviceMode mode); ~ScopedStubInstallAttributes(); + + // Factory for empty (unset) ScopedStubInstallAttributes. + static ScopedStubInstallAttributes CreateUnset(); + + // Factory for consumer-type ScopedStubInstallAttributes. + static ScopedStubInstallAttributes CreateConsumer(); + + // Factory for enterprise-type ScopedStubInstallAttributes. + static ScopedStubInstallAttributes CreateEnterprise( + const std::string& domain, + const std::string& device_id); + + private: + ScopedStubInstallAttributes(); }; } // namespace chromeos
diff --git a/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc b/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc index c8c5fa3..97482ca 100644 --- a/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc +++ b/chrome/browser/chromeos/system/device_disabling_manager_unittest.cc
@@ -56,10 +56,6 @@ virtual void CreateDeviceDisablingManager(); virtual void DestroyDeviceDisablingManager(); - - void UpdateInstallAttributes(const std::string& enrollment_domain, - const std::string& registration_user, - policy::DeviceMode device_mode); void LogIn(); // DeviceDisablingManager::Delegate: @@ -70,7 +66,14 @@ return device_disabling_manager_.get(); } + // Configure install attributes. + void SetUnowned(); + void SetEnterpriseOwned(); + void SetConsumerOwned(); + private: + chromeos::StubInstallAttributes* GetInstallAttributes(); + chromeos::ScopedStubInstallAttributes install_attributes_; chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; chromeos::ScopedTestCrosSettings test_cros_settings_; @@ -81,7 +84,7 @@ }; DeviceDisablingManagerTestBase::DeviceDisablingManagerTestBase() - : install_attributes_("", "", "", policy::DEVICE_MODE_NOT_SET) { + : install_attributes_(ScopedStubInstallAttributes::CreateUnset()) { } void DeviceDisablingManagerTestBase::TearDown() { @@ -99,25 +102,31 @@ device_disabling_manager_.reset(); } -void DeviceDisablingManagerTestBase::UpdateInstallAttributes( - const std::string& enrollment_domain, - const std::string& registration_user, - policy::DeviceMode device_mode) { - chromeos::StubInstallAttributes* install_attributes = - static_cast<chromeos::StubInstallAttributes*>( - TestingBrowserProcess::GetGlobal() - ->platform_part() - ->browser_policy_connector_chromeos() - ->GetInstallAttributes()); - install_attributes->SetDomain(enrollment_domain); - install_attributes->SetRegistrationUser(registration_user); - install_attributes->SetMode(device_mode); -} - void DeviceDisablingManagerTestBase::LogIn() { fake_user_manager_.AddUser(AccountId::FromUserEmail(kTestUser)); } +void DeviceDisablingManagerTestBase::SetUnowned() { + GetInstallAttributes()->Clear(); +} + +void DeviceDisablingManagerTestBase::SetEnterpriseOwned() { + GetInstallAttributes()->SetEnterprise(kEnrollmentDomain, "fake-id"); +} + +void DeviceDisablingManagerTestBase::SetConsumerOwned() { + GetInstallAttributes()->SetConsumer(); +} + +chromeos::StubInstallAttributes* +DeviceDisablingManagerTestBase::GetInstallAttributes() { + return static_cast<chromeos::StubInstallAttributes*>( + TestingBrowserProcess::GetGlobal() + ->platform_part() + ->browser_policy_connector_chromeos() + ->GetInstallAttributes()); +} + // Base class for tests that verify device disabling behavior during OOBE, when // the device is not owned yet. class DeviceDisablingManagerOOBETest : public DeviceDisablingManagerTestBase { @@ -216,9 +225,7 @@ // Verifies that the device is not considered disabled during OOBE when it is // already enrolled, even if the device is marked as disabled. TEST_F(DeviceDisablingManagerOOBETest, NotDisabledWhenEnterpriseOwned) { - UpdateInstallAttributes(kEnrollmentDomain, - kTestUser, - policy::DEVICE_MODE_ENTERPRISE); + SetEnterpriseOwned(); SetDeviceDisabled(true); CheckWhetherDeviceDisabledDuringOOBE(); EXPECT_FALSE(device_disabled()); @@ -227,9 +234,7 @@ // Verifies that the device is not considered disabled during OOBE when it is // already owned by a consumer, even if the device is marked as disabled. TEST_F(DeviceDisablingManagerOOBETest, NotDisabledWhenConsumerOwned) { - UpdateInstallAttributes(std::string() /* enrollment_domain */, - std::string() /* registration_user */, - policy::DEVICE_MODE_CONSUMER); + SetConsumerOwned(); SetDeviceDisabled(true); CheckWhetherDeviceDisabledDuringOOBE(); EXPECT_FALSE(device_disabled()); @@ -262,9 +267,6 @@ // DeviceDisablingManager::Observer: MOCK_METHOD1(OnDisabledMessageChanged, void(const std::string&)); - void SetUnowned(); - void SetEnterpriseOwned(); - void SetConsumerOwned(); void MakeCrosSettingsTrusted(); void SetDeviceDisabled(bool disabled); @@ -299,24 +301,6 @@ DeviceDisablingManagerTestBase::DestroyDeviceDisablingManager(); } -void DeviceDisablingManagerTest::SetUnowned() { - UpdateInstallAttributes(std::string() /* enrollment_domain */, - std::string() /* registration_user */, - policy::DEVICE_MODE_NOT_SET); -} - -void DeviceDisablingManagerTest::SetEnterpriseOwned() { - UpdateInstallAttributes(kEnrollmentDomain, - kTestUser, - policy::DEVICE_MODE_ENTERPRISE); -} - -void DeviceDisablingManagerTest::SetConsumerOwned() { - UpdateInstallAttributes(std::string() /* enrollment_domain */, - std::string() /* registration_user */, - policy::DEVICE_MODE_CONSUMER); -} - void DeviceDisablingManagerTest::MakeCrosSettingsTrusted() { scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util( new ownership::MockOwnerKeyUtil);
diff --git a/chrome/browser/chromeos/ui/focus_ring_layer.cc b/chrome/browser/chromeos/ui/focus_ring_layer.cc index 81b4c675..39de53d 100644 --- a/chrome/browser/chromeos/ui/focus_ring_layer.cc +++ b/chrome/browser/chromeos/ui/focus_ring_layer.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/chromeos/ui/focus_ring_layer.h" -#include "base/bind.h" #include "ui/aura/window.h" #include "ui/compositor/compositor_animation_observer.h" #include "ui/compositor/layer.h" @@ -117,10 +116,6 @@ delegate_->OnDeviceScaleFactorChanged(); } -base::Closure FocusRingLayer::PrepareForLayerBoundsChange() { - return base::Bind(&base::DoNothing); -} - void FocusRingLayer::OnAnimationStep(base::TimeTicks timestamp) { delegate_->OnAnimationStep(timestamp); }
diff --git a/chrome/browser/chromeos/ui/focus_ring_layer.h b/chrome/browser/chromeos/ui/focus_ring_layer.h index ea6d3def..0b17813 100644 --- a/chrome/browser/chromeos/ui/focus_ring_layer.h +++ b/chrome/browser/chromeos/ui/focus_ring_layer.h
@@ -68,7 +68,6 @@ void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; // CompositorAnimationObserver overrides: void OnAnimationStep(base::TimeTicks timestamp) override;
diff --git a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc index 329d1cc..626984f2 100644 --- a/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc +++ b/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc
@@ -100,7 +100,7 @@ std::unique_ptr<chromeos::StubInstallAttributes> attributes = base::MakeUnique<chromeos::StubInstallAttributes>(); - attributes->SetRegistrationUser(affiliated_account_id_.GetUserEmail()); + attributes->SetEnterprise("fake-domain", "fake-id"); policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( attributes.release());
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc index 01e84795..4a71583 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_unittest.cc
@@ -161,11 +161,7 @@ ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _)) .WillByDefault(Invoke(GetCertificateCallbackTrue)); - // Set the Enterprise install attributes. - stub_install_attributes_.SetDomain("google.com"); - stub_install_attributes_.SetRegistrationUser(kUserEmail); - stub_install_attributes_.SetDeviceId("device_id"); - stub_install_attributes_.SetMode(policy::DEVICE_MODE_ENTERPRISE); + stub_install_attributes_.SetEnterprise("google.com", "device_id"); settings_helper_.ReplaceProvider(chromeos::kDeviceAttestationEnabled); settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, true); @@ -277,7 +273,7 @@ }; TEST_F(EPKChallengeMachineKeyTest, NonEnterpriseDevice) { - stub_install_attributes_.SetRegistrationUser(""); + stub_install_attributes_.SetConsumer(); EXPECT_EQ(EPKPChallengeMachineKey::kNonEnterpriseDeviceError, RunFunctionAndReturnError(func_.get(), CreateArgs(), browser())); @@ -496,7 +492,7 @@ } TEST_F(EPKChallengeUserKeyTest, PersonalDevice) { - stub_install_attributes_.SetRegistrationUser(""); + stub_install_attributes_.SetConsumer(); // Currently personal devices are not supported. EXPECT_EQ(GetCertificateError(kUserRejected),
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc index b3c78fbe..6d9e269 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc
@@ -170,11 +170,7 @@ ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _)) .WillByDefault(Invoke(GetCertificateCallbackTrue)); - // Set the Enterprise install attributes. - stub_install_attributes_.SetDomain("google.com"); - stub_install_attributes_.SetRegistrationUser(kUserEmail); - stub_install_attributes_.SetDeviceId("device_id"); - stub_install_attributes_.SetMode(policy::DEVICE_MODE_ENTERPRISE); + stub_install_attributes_.SetEnterprise("google.com", "device_id"); settings_helper_.ReplaceProvider(chromeos::kDeviceAttestationEnabled); settings_helper_.SetBoolean(chromeos::kDeviceAttestationEnabled, true); @@ -262,7 +258,7 @@ } TEST_F(EPKPChallengeMachineKeyTest, NonEnterpriseDevice) { - stub_install_attributes_.SetRegistrationUser(""); + stub_install_attributes_.SetConsumer(); EXPECT_EQ(EPKPChallengeMachineKey::kNonEnterpriseDeviceError, utils::RunFunctionAndReturnError(func_.get(), kArgs, browser())); @@ -477,7 +473,7 @@ } TEST_F(EPKPChallengeUserKeyTest, PersonalDevice) { - stub_install_attributes_.SetRegistrationUser(""); + stub_install_attributes_.SetConsumer(); // Currently personal devices are not supported. EXPECT_EQ(GetCertificateError(kUserRejected),
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc index 06d8037..22f056d 100644 --- a/chrome/browser/extensions/api/identity/identity_apitest.cc +++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -1597,8 +1597,7 @@ // enterprise-managed. std::unique_ptr<chromeos::StubInstallAttributes> attributes = base::MakeUnique<chromeos::StubInstallAttributes>(); - attributes->SetDomain("example.com"); - attributes->SetRegistrationUser("user@example.com"); + attributes->SetEnterprise("example.com", "fake-id"); policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( attributes.release()); }
diff --git a/chrome/browser/extensions/extension_commands_global_registry.cc b/chrome/browser/extensions/extension_commands_global_registry.cc index c98051c4..f43caa1d 100644 --- a/chrome/browser/extensions/extension_commands_global_registry.cc +++ b/chrome/browser/extensions/extension_commands_global_registry.cc
@@ -83,10 +83,6 @@ continue; const ui::Accelerator& accelerator = iter->second.accelerator(); - VLOG(0) << "Adding global keybinding for " << extension->name().c_str() - << " " << command_name.c_str() - << " key: " << accelerator.GetShortcutText(); - if (!IsAcceleratorRegistered(accelerator)) { if (!GlobalShortcutListener::GetInstance()->RegisterAccelerator( accelerator, this)) @@ -100,8 +96,6 @@ void ExtensionCommandsGlobalRegistry::RemoveExtensionKeybindingImpl( const ui::Accelerator& accelerator, const std::string& command_name) { - VLOG(0) << "Removing keybinding for " << command_name.c_str(); - GlobalShortcutListener::GetInstance()->UnregisterAccelerator( accelerator, this); }
diff --git a/chrome/browser/net/errorpage_browsertest.cc b/chrome/browser/net/errorpage_browsertest.cc index 6b20ce24..ed86cca 100644 --- a/chrome/browser/net/errorpage_browsertest.cc +++ b/chrome/browser/net/errorpage_browsertest.cc
@@ -1301,8 +1301,7 @@ // Set up fake install attributes. std::unique_ptr<chromeos::StubInstallAttributes> attributes = base::MakeUnique<chromeos::StubInstallAttributes>(); - attributes->SetDomain("example.com"); - attributes->SetRegistrationUser("user@example.com"); + attributes->SetEnterprise("example.com", "fake-id"); policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( attributes.release()); }
diff --git a/chrome/browser/notifications/native_notification_display_service.cc b/chrome/browser/notifications/native_notification_display_service.cc index c09e118e..d7271b0 100644 --- a/chrome/browser/notifications/native_notification_display_service.cc +++ b/chrome/browser/notifications/native_notification_display_service.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/notifications/native_notification_display_service.h" #include "base/memory/ptr_util.h" +#include "base/strings/nullable_string16.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/notifications/non_persistent_notification_handler.h" #include "chrome/browser/notifications/notification.h" @@ -84,7 +85,8 @@ CHECK(handler); switch (operation) { case NotificationCommon::CLICK: - handler->OnClick(profile_, origin, notification_id, action_index); + handler->OnClick(profile_, origin, notification_id, action_index, + base::NullableString16() /* reply */); break; case NotificationCommon::CLOSE: handler->OnClose(profile_, origin, notification_id, true /* by_user */);
diff --git a/chrome/browser/notifications/non_persistent_notification_handler.cc b/chrome/browser/notifications/non_persistent_notification_handler.cc index 3e21f926..e2c5d87 100644 --- a/chrome/browser/notifications/non_persistent_notification_handler.cc +++ b/chrome/browser/notifications/non_persistent_notification_handler.cc
@@ -25,9 +25,12 @@ Profile* profile, const std::string& origin, const std::string& notification_id, - int action_index) { - // Buttons not supported for non persistent notifications. + int action_index, + const base::NullableString16& reply) { + // Buttons and replies not supported for non persistent notifications. DCHECK_EQ(action_index, -1); + DCHECK(reply.is_null()); + if (notifications_.find(notification_id) != notifications_.end()) { notifications_[notification_id]->Click(); }
diff --git a/chrome/browser/notifications/non_persistent_notification_handler.h b/chrome/browser/notifications/non_persistent_notification_handler.h index 51b8d36..78ad623 100644 --- a/chrome/browser/notifications/non_persistent_notification_handler.h +++ b/chrome/browser/notifications/non_persistent_notification_handler.h
@@ -28,7 +28,8 @@ void OnClick(Profile* profile, const std::string& origin, const std::string& notification_id, - int action_index) override; + int action_index, + const base::NullableString16& reply) override; void OpenSettings(Profile* profile) override;
diff --git a/chrome/browser/notifications/notification_handler.h b/chrome/browser/notifications/notification_handler.h index b410d49..851e76b 100644 --- a/chrome/browser/notifications/notification_handler.h +++ b/chrome/browser/notifications/notification_handler.h
@@ -8,6 +8,10 @@ #include <memory> #include <string> +namespace base { +class NullableString16; +} + class NotificationDelegate; class Profile; @@ -28,7 +32,8 @@ virtual void OnClick(Profile* profile, const std::string& origin, const std::string& notification_id, - int action_index) = 0; + int action_index, + const base::NullableString16& reply) = 0; // Open notification settings. virtual void OpenSettings(Profile* profile) = 0;
diff --git a/chrome/browser/notifications/persistent_notification_delegate.cc b/chrome/browser/notifications/persistent_notification_delegate.cc index 1e05cbf..b38f3c1 100644 --- a/chrome/browser/notifications/persistent_notification_delegate.cc +++ b/chrome/browser/notifications/persistent_notification_delegate.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/notifications/persistent_notification_delegate.h" +#include "base/strings/nullable_string16.h" #include "chrome/browser/notifications/platform_notification_service_impl.h" #include "url/gurl.h" @@ -26,7 +27,8 @@ void PersistentNotificationDelegate::Click() { PlatformNotificationServiceImpl::GetInstance()->OnPersistentNotificationClick( - browser_context(), id(), origin(), -1 /* action_index */); + browser_context(), id(), origin(), -1 /* action_index */, + base::NullableString16() /* reply */); } void PersistentNotificationDelegate::ButtonClick(int button_index) { @@ -37,5 +39,16 @@ } PlatformNotificationServiceImpl::GetInstance()->OnPersistentNotificationClick( - browser_context(), id(), origin(), button_index); + browser_context(), id(), origin(), button_index, + base::NullableString16() /* reply */); +} + +void PersistentNotificationDelegate::ButtonClickWithReply( + int button_index, + const base::string16& reply) { + DCHECK_GE(button_index, 0); + DCHECK_NE(button_index, notification_settings_index_); + PlatformNotificationServiceImpl::GetInstance()->OnPersistentNotificationClick( + browser_context(), id(), origin(), button_index, + base::NullableString16(reply, false /* is_null */)); }
diff --git a/chrome/browser/notifications/persistent_notification_delegate.h b/chrome/browser/notifications/persistent_notification_delegate.h index 932dc5f..ace6d1b 100644 --- a/chrome/browser/notifications/persistent_notification_delegate.h +++ b/chrome/browser/notifications/persistent_notification_delegate.h
@@ -31,6 +31,8 @@ void Close(bool by_user) override; void Click() override; void ButtonClick(int button_index) override; + void ButtonClickWithReply(int button_index, + const base::string16& reply) override; protected: ~PersistentNotificationDelegate() override;
diff --git a/chrome/browser/notifications/persistent_notification_handler.cc b/chrome/browser/notifications/persistent_notification_handler.cc index 810b0f1..16b62654d 100644 --- a/chrome/browser/notifications/persistent_notification_handler.cc +++ b/chrome/browser/notifications/persistent_notification_handler.cc
@@ -25,15 +25,17 @@ profile, notification_id, notification_origin, by_user); } -void PersistentNotificationHandler::OnClick(Profile* profile, - const std::string& origin, - const std::string& notification_id, - int action_index) { +void PersistentNotificationHandler::OnClick( + Profile* profile, + const std::string& origin, + const std::string& notification_id, + int action_index, + const base::NullableString16& reply) { const GURL notification_origin(origin); DCHECK(notification_origin.is_valid()); PlatformNotificationServiceImpl::GetInstance()->OnPersistentNotificationClick( - profile, notification_id, notification_origin, action_index); + profile, notification_id, notification_origin, action_index, reply); } void PersistentNotificationHandler::OpenSettings(Profile* profile) {
diff --git a/chrome/browser/notifications/persistent_notification_handler.h b/chrome/browser/notifications/persistent_notification_handler.h index c251a0e..577f8ba4 100644 --- a/chrome/browser/notifications/persistent_notification_handler.h +++ b/chrome/browser/notifications/persistent_notification_handler.h
@@ -25,7 +25,8 @@ void OnClick(Profile* profile, const std::string& origin, const std::string& notification_id, - int action_index) override; + int action_index, + const base::NullableString16& reply) override; void OpenSettings(Profile* profile) override; void RegisterNotification(const std::string& notification_id, NotificationDelegate* delegate) override;
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index 13d772a..aa0683af 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -107,7 +107,8 @@ BrowserContext* browser_context, const std::string& notification_id, const GURL& origin, - int action_index) { + int action_index, + const base::NullableString16& reply) { DCHECK_CURRENTLY_ON(BrowserThread::UI); blink::mojom::PermissionStatus permission_status = CheckPermissionOnUIThread(browser_context, origin, @@ -140,7 +141,7 @@ content::NotificationEventDispatcher::GetInstance() ->DispatchNotificationClickEvent( - browser_context, notification_id, origin, action_index, + browser_context, notification_id, origin, action_index, reply, base::Bind( &PlatformNotificationServiceImpl::OnClickEventDispatchComplete, base::Unretained(this)));
diff --git a/chrome/browser/notifications/platform_notification_service_impl.h b/chrome/browser/notifications/platform_notification_service_impl.h index 88642b37..31482d9 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.h +++ b/chrome/browser/notifications/platform_notification_service_impl.h
@@ -29,6 +29,10 @@ class NotificationDisplayService; class ScopedKeepAlive; +namespace base { +class NullableString16; +} + namespace content { class BrowserContext; struct NotificationResources; @@ -53,7 +57,8 @@ void OnPersistentNotificationClick(content::BrowserContext* browser_context, const std::string& notification_id, const GURL& origin, - int action_index); + int action_index, + const base::NullableString16& reply); // To be called when a persistent notification has been closed. The data // associated with the notification has to be pruned from the database in this
diff --git a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc index b967394..f88f16f 100644 --- a/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc +++ b/chrome/browser/notifications/platform_notification_service_interactive_uitest.cc
@@ -557,6 +557,25 @@ } IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest, + DisplayPersistentNotificationWithReplyButton) { + ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest()); + + std::string script_result; + ASSERT_TRUE(RunScript("DisplayPersistentNotificationWithReplyButton()", + &script_result)); + EXPECT_EQ("ok", script_result); + ASSERT_EQ(1u, ui_manager()->GetNotificationCount()); + + const Notification& notification = ui_manager()->GetNotificationAt(0); + ASSERT_EQ(1u, notification.buttons().size()); + EXPECT_EQ("actionTitle1", base::UTF16ToUTF8(notification.buttons()[0].title)); + + notification.delegate()->ButtonClickWithReply(0, base::ASCIIToUTF16("hello")); + ASSERT_TRUE(RunScript("GetMessageFromWorker()", &script_result)); + EXPECT_EQ("action_button_click actionId1 hello", script_result); +} + +IN_PROC_BROWSER_TEST_F(PlatformNotificationServiceBrowserTest, TestShouldDisplayNormal) { ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest()); EnableFullscreenNotifications();
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index 48b7d03b..53b2055 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -336,7 +336,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), url); chrome::Navigate(¶ms); - EXPECT_TRUE(manager.WaitForWillStartRequest()); + EXPECT_TRUE(manager.WaitForRequestStart()); GURL url2(embedded_test_server()->GetURL("/title2.html")); chrome::NavigateParams params2(browser(), url2, @@ -359,7 +359,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), url); chrome::Navigate(¶ms); - EXPECT_TRUE(manager.WaitForWillStartRequest()); + EXPECT_TRUE(manager.WaitForRequestStart()); chrome::NavigateParams params2(browser(), url, ui::PAGE_TRANSITION_RELOAD); content::TestNavigationManager manager2( @@ -380,7 +380,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), url); chrome::Navigate(¶ms); - EXPECT_TRUE(manager.WaitForWillStartRequest()); + EXPECT_TRUE(manager.WaitForRequestStart()); browser()->tab_strip_model()->GetActiveWebContents()->Close(); @@ -399,7 +399,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), url); chrome::Navigate(¶ms); - EXPECT_TRUE(manager.WaitForWillStartRequest()); + EXPECT_TRUE(manager.WaitForRequestStart()); GURL url2(embedded_test_server()->GetURL("/title2.html")); chrome::NavigateParams params2(browser(), url2, ui::PAGE_TRANSITION_TYPED); @@ -407,7 +407,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), url2); chrome::Navigate(¶ms2); - EXPECT_TRUE(manager2.WaitForWillStartRequest()); + EXPECT_TRUE(manager2.WaitForRequestStart()); manager.WaitForNavigationFinished(); GURL url3(embedded_test_server()->GetURL("/title3.html")); @@ -416,7 +416,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), url3); chrome::Navigate(¶ms3); - EXPECT_TRUE(manager3.WaitForWillStartRequest()); + EXPECT_TRUE(manager3.WaitForRequestStart()); manager2.WaitForNavigationFinished(); manager3.WaitForNavigationFinished(); @@ -437,7 +437,7 @@ content::TestNavigationManager manager( browser()->tab_strip_model()->GetActiveWebContents(), second_url); chrome::Navigate(¶ms); - EXPECT_TRUE(manager.WaitForWillStartRequest()); + EXPECT_TRUE(manager.WaitForRequestStart()); { content::TestNavigationManager reload_manager(
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index b5c1210..c0b7e83 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -539,6 +539,9 @@ { key::kArcBackupRestoreEnabled, prefs::kArcBackupRestoreEnabled, base::Value::TYPE_BOOLEAN }, + { key::kReportArcStatus, + prefs::kReportArcStatus, + base::Value::TYPE_BOOLEAN }, #endif // defined(OS_CHROMEOS) // Metrics reporting is controlled by a platform specific policy for ChromeOS
diff --git a/chrome/browser/resources/inline_login/inline_login.js b/chrome/browser/resources/inline_login/inline_login.js index 7e67cbc0..17f1c43 100644 --- a/chrome/browser/resources/inline_login/inline_login.js +++ b/chrome/browser/resources/inline_login/inline_login.js
@@ -20,6 +20,11 @@ */ var authReadyFired; + /** + * Whether the login UI is loaded for signing in primary account. + */ + var isLoginPrimaryAccount; + function onResize(e) { chrome.send('switchToFullTab', [e.detail]); } @@ -27,7 +32,8 @@ function onAuthReady(e) { $('contents').classList.toggle('loading', false); authReadyFired = true; - chrome.send('metricsHandler:recordAction', ['Signin_SigninPage_Shown']); + if (isLoginPrimaryAccount) + chrome.send('metricsHandler:recordAction', ['Signin_SigninPage_Shown']); } function onDropLink(e) { @@ -74,6 +80,7 @@ $('contents').classList.toggle('loading', data.authMode != cr.login.GaiaAuthHost.AuthMode.DESKTOP || data.constrained == '1'); + isLoginPrimaryAccount = data.isLoginPrimaryAccount; } /**
diff --git a/chrome/browser/resources/translate_internals/translate_internals.css b/chrome/browser/resources/translate_internals/translate_internals.css index 11626b4..9d9a7f9 100644 --- a/chrome/browser/resources/translate_internals/translate_internals.css +++ b/chrome/browser/resources/translate_internals/translate_internals.css
@@ -138,3 +138,7 @@ .prefs-setting-disabled { display: none; } + +#country-override input { + margin-bottom: 1px; +}
diff --git a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc b/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc index 64a9b83d..2b2cff2 100644 --- a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc +++ b/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc
@@ -966,13 +966,9 @@ // Tests that when an invisible password field is present on an HTTP page // load, and when the command-line flag is set, the security level is -// downgraded to HTTP_SHOW_WARNING. -// -// TODO(estark): this will eventually be refined so that the warning -// will not show up for invisible password -// inputs. https://codereview.chromium.org/2378503002/ +// *not* downgraded to HTTP_SHOW_WARNING. IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTestWithPasswordCcSwitch, - PasswordSecurityLevelDowngradedForInvisibleInput) { + PasswordSecurityLevelNotDowngradedForInvisibleInput) { content::WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(contents); @@ -987,13 +983,13 @@ "/password/invisible_password.html")); security_state::SecurityStateModel::SecurityInfo security_info; model_client->GetSecurityInfo(&security_info); - EXPECT_EQ(security_state::SecurityStateModel::HTTP_SHOW_WARNING, + EXPECT_EQ(security_state::SecurityStateModel::NONE, security_info.security_level); content::NavigationEntry* entry = contents->GetController().GetVisibleEntry(); ASSERT_TRUE(entry); - EXPECT_TRUE(entry->GetSSL().content_status & - content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); + EXPECT_FALSE(entry->GetSSL().content_status & + content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP); } // Tests that when a visible password field is detected inside an iframe
diff --git a/chrome/browser/task_manager/task_manager_interface.cc b/chrome/browser/task_manager/task_manager_interface.cc index 624f241..9cdecf1e 100644 --- a/chrome/browser/task_manager/task_manager_interface.cc +++ b/chrome/browser/task_manager/task_manager_interface.cc
@@ -76,12 +76,11 @@ // Recalculate the minimum refresh rate and the enabled resource flags. int64_t flags = 0; base::TimeDelta min_time = base::TimeDelta::Max(); - base::ObserverList<TaskManagerObserver>::Iterator itr(&observers_); - while (TaskManagerObserver* obs = itr.GetNext()) { - if (obs->desired_refresh_time() < min_time) - min_time = obs->desired_refresh_time(); + for (auto& observer : observers_) { + if (observer.desired_refresh_time() < min_time) + min_time = observer.desired_refresh_time(); - flags |= obs->desired_resources_flags(); + flags |= observer.desired_resources_flags(); } if (min_time == base::TimeDelta::Max()) { @@ -97,9 +96,8 @@ void TaskManagerInterface::RecalculateRefreshFlags() { int64_t flags = 0; - base::ObserverList<TaskManagerObserver>::Iterator itr(&observers_); - while (TaskManagerObserver* obs = itr.GetNext()) - flags |= obs->desired_resources_flags(); + for (auto& observer : observers_) + flags |= observer.desired_resources_flags(); SetEnabledResourceFlags(flags); }
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index 6d6262c..abc8082 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -10,8 +10,8 @@ #include <string> #include "base/macros.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/defaults.h" @@ -109,7 +109,7 @@ WebContents* CloseTracker::Next() { if (observers_.empty()) - return NULL; + return nullptr; DeletionObserver* observer = observers_[0]; WebContents* web_contents = observer->web_contents(); @@ -210,8 +210,8 @@ : content::WebContentsObserver(contents), contents_(contents), tab_strip_model_(tab_strip_model), - group_(NULL), - opener_(NULL), + group_(nullptr), + opener_(nullptr), reset_group_on_select_(false), pinned_(false), blocked_(false) {} @@ -245,7 +245,7 @@ } TabStripModel::~TabStripModel() { - base::STLDeleteElements(&contents_data_); + contents_data_.clear(); order_controller_.reset(); } @@ -287,7 +287,8 @@ // otherwise we run into problems when we try to change the active contents // since the old contents and the new contents will be the same... WebContents* active_contents = GetActiveWebContents(); - WebContentsData* data = new WebContentsData(this, contents); + std::unique_ptr<WebContentsData> data = + base::MakeUnique<WebContentsData>(this, contents); data->set_pinned(pin); if ((add_types & ADD_INHERIT_GROUP) && active_contents) { if (active) { @@ -315,12 +316,13 @@ if (manager) data->set_blocked(manager->IsDialogActive()); - contents_data_.insert(contents_data_.begin() + index, data); + contents_data_.insert(contents_data_.begin() + index, std::move(data)); selection_model_.IncrementFrom(index); - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabInsertedAt(this, contents, index, active)); + for (auto& observer : observers_) + observer.TabInsertedAt(this, contents, index, active); + if (active) { ui::ListSelectionModel new_model; new_model.Copy(selection_model_); @@ -340,20 +342,16 @@ contents_data_[index]->SetWebContents(new_contents); - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabReplacedAt(this, old_contents, new_contents, index)); + for (auto& observer : observers_) + observer.TabReplacedAt(this, old_contents, new_contents, index); // When the active WebContents is replaced send out a selection notification // too. We do this as nearly all observers need to treat a replacement of the // selected contents as the selection changing. if (active_index() == index) { - FOR_EACH_OBSERVER( - TabStripModelObserver, - observers_, - ActiveTabChanged(old_contents, - new_contents, - active_index(), - TabStripModelObserver::CHANGE_REASON_REPLACED)); + for (auto& observer : observers_) + observer.ActiveTabChanged(old_contents, new_contents, active_index(), + TabStripModelObserver::CHANGE_REASON_REPLACED); } return old_contents; } @@ -361,7 +359,7 @@ WebContents* TabStripModel::DetachWebContentsAt(int index) { CHECK(!in_notify_); if (contents_data_.empty()) - return NULL; + return nullptr; DCHECK(ContainsIndex(index)); FixOpenersAndGroupsReferencing(index); @@ -369,17 +367,17 @@ WebContents* removed_contents = GetWebContentsAtImpl(index); bool was_selected = IsTabSelected(index); int next_selected_index = order_controller_->DetermineNewSelectedIndex(index); - delete contents_data_[index]; contents_data_.erase(contents_data_.begin() + index); if (empty()) closing_all_ = true; - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabDetachedAt(removed_contents, index)); + for (auto& observer : observers_) + observer.TabDetachedAt(removed_contents, index); if (empty()) { selection_model_.Clear(); // TabDetachedAt() might unregister observers, so send |TabStripEmpty()| in // a second pass. - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, TabStripEmpty()); + for (auto& observer : observers_) + observer.TabStripEmpty(); } else { int old_active = active_index(); selection_model_.DecrementFrom(index); @@ -405,8 +403,8 @@ // notification is sent even though the tab selection has changed because // |old_model| is stored after calling DecrementFrom(). if (was_selected) { - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabSelectionChanged(this, old_model)); + for (auto& observer : observers_) + observer.TabSelectionChanged(this, old_model); } } return removed_contents; @@ -486,7 +484,7 @@ WebContents* TabStripModel::GetWebContentsAt(int index) const { if (ContainsIndex(index)) return GetWebContentsAtImpl(index); - return NULL; + return nullptr; } int TabStripModel::GetIndexOfWebContents(const WebContents* contents) const { @@ -501,8 +499,8 @@ TabStripModelObserver::TabChangeType change_type) { DCHECK(ContainsIndex(index)); - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabChangedAt(GetWebContentsAtImpl(index), index, change_type)); + for (auto& observer : observers_) + observer.TabChangedAt(GetWebContentsAtImpl(index), index, change_type); } void TabStripModel::CloseAllTabs() { @@ -524,11 +522,11 @@ } bool TabStripModel::TabsAreLoading() const { - for (WebContentsDataVector::const_iterator iter = contents_data_.begin(); - iter != contents_data_.end(); ++iter) { - if ((*iter)->web_contents()->IsLoading()) + for (const auto& data : contents_data_) { + if (data->web_contents()->IsLoading()) return true; } + return false; } @@ -612,16 +610,15 @@ void TabStripModel::ForgetAllOpeners() { // Forget all opener memories so we don't do anything weird with tab // re-selection ordering. - for (WebContentsDataVector::const_iterator iter = contents_data_.begin(); - iter != contents_data_.end(); ++iter) - (*iter)->set_opener(NULL); + for (const auto& data : contents_data_) + data->set_opener(nullptr); } void TabStripModel::ForgetGroup(WebContents* contents) { int index = GetIndexOfWebContents(contents); DCHECK(ContainsIndex(index)); - contents_data_[index]->set_group(NULL); - contents_data_[index]->set_opener(NULL); + contents_data_[index]->set_group(nullptr); + contents_data_[index]->set_opener(nullptr); } bool TabStripModel::ShouldResetGroupOnSelect(WebContents* contents) const { @@ -635,10 +632,9 @@ if (contents_data_[index]->blocked() == blocked) return; contents_data_[index]->set_blocked(blocked); - FOR_EACH_OBSERVER( - TabStripModelObserver, observers_, - TabBlockedStateChanged(contents_data_[index]->web_contents(), - index)); + for (auto& observer : observers_) + observer.TabBlockedStateChanged(contents_data_[index]->web_contents(), + index); } void TabStripModel::SetTabPinned(int index, bool pinned) { @@ -657,9 +653,9 @@ index = non_pinned_tab_index - 1; } - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabPinnedStateChanged( - this, contents_data_[index]->web_contents(), index)); + for (auto& observer : observers_) + observer.TabPinnedStateChanged(this, contents_data_[index]->web_contents(), + index); } bool TabStripModel::IsTabPinned(int index) const { @@ -1154,7 +1150,8 @@ base::WeakPtr<TabStripModel> ref(weak_factory_.GetWeakPtr()); const bool closing_all = indices.size() == contents_data_.size(); if (closing_all) - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, WillCloseAllTabs()); + for (auto& observer : observers_) + observer.WillCloseAllTabs(); // We only try the fast shutdown path if the whole browser process is *not* // shutting down. Fast shutdown during browser termination is handled in @@ -1210,10 +1207,9 @@ (close_types & CLOSE_CREATE_HISTORICAL_TAB) != 0); } - if (ref && closing_all && !retval) { - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - CloseAllTabsCanceled()); - } + if (ref && closing_all && !retval) + for (auto& observer : observers_) + observer.CloseAllTabsCanceled(); return retval; } @@ -1221,8 +1217,8 @@ void TabStripModel::InternalCloseTab(WebContents* contents, int index, bool create_historical_tabs) { - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabClosingAt(this, contents, index)); + for (auto& observer : observers_) + observer.TabClosingAt(this, contents, index); // Ask the delegate to save an entry for this tab in the historical tab // database if applicable. @@ -1242,8 +1238,8 @@ void TabStripModel::NotifyIfTabDeactivated(WebContents* contents) { if (contents) { - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabDeactivated(contents)); + for (auto& observer : observers_) + observer.TabDeactivated(contents); } } @@ -1256,11 +1252,9 @@ : TabStripModelObserver::CHANGE_REASON_NONE; CHECK(!in_notify_); in_notify_ = true; - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - ActiveTabChanged(old_contents, - new_contents, - active_index(), - reason)); + for (auto& observer : observers_) + observer.ActiveTabChanged(old_contents, new_contents, active_index(), + reason); in_notify_ = false; } } @@ -1272,8 +1266,8 @@ NotifyIfActiveTabChanged(old_contents, notify_types); if (!selection_model().Equals(old_model)) { - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabSelectionChanged(this, old_model)); + for (auto& observer : observers_) + observer.TabSelectionChanged(this, old_model); } } @@ -1306,9 +1300,12 @@ bool select_after_move) { FixOpenersAndGroupsReferencing(index); - WebContentsData* moved_data = contents_data_[index]; + std::unique_ptr<WebContentsData> moved_data = + std::move(contents_data_[index]); + WebContents* web_contents = moved_data->web_contents(); contents_data_.erase(contents_data_.begin() + index); - contents_data_.insert(contents_data_.begin() + to_position, moved_data); + contents_data_.insert(contents_data_.begin() + to_position, + std::move(moved_data)); selection_model_.Move(index, to_position); if (!selection_model_.IsSelected(to_position) && select_after_move) { @@ -1316,8 +1313,8 @@ selection_model_.SetSelectedIndex(to_position); } - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabMoved(moved_data->web_contents(), index, to_position)); + for (auto& observer : observers_) + observer.TabMoved(web_contents, index, to_position); } void TabStripModel::MoveSelectedTabsToImpl(int index, @@ -1357,7 +1354,7 @@ } // static -bool TabStripModel::OpenerMatches(const WebContentsData* data, +bool TabStripModel::OpenerMatches(const std::unique_ptr<WebContentsData>& data, const WebContents* opener, bool use_group) { return data->opener() == opener || (use_group && data->group() == opener); @@ -1365,7 +1362,7 @@ void TabStripModel::FixOpenersAndGroupsReferencing(int index) { WebContents* old_contents = GetWebContentsAtImpl(index); - for (WebContentsData* data : contents_data_) { + for (auto& data : contents_data_) { if (data->group() == old_contents) data->set_group(contents_data_[index]->group()); if (data->opener() == old_contents)
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h index fd49bdb0..703850fa 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.h +++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -518,7 +518,7 @@ // Returns true if the tab represented by the specified data has an opener // that matches the specified one. If |use_group| is true, then this will // fall back to check the group relationship as well. - static bool OpenerMatches(const WebContentsData* data, + static bool OpenerMatches(const std::unique_ptr<WebContentsData>& data, const content::WebContents* opener, bool use_group); @@ -530,8 +530,7 @@ TabStripModelDelegate* delegate_; // The WebContents data currently hosted within this TabStripModel. - typedef std::vector<WebContentsData*> WebContentsDataVector; - WebContentsDataVector contents_data_; + std::vector<std::unique_ptr<WebContentsData>> contents_data_; // A profile associated with this TabStripModel. Profile* profile_; @@ -544,8 +543,7 @@ std::unique_ptr<TabStripModelOrderController> order_controller_; // Our observers. - typedef base::ObserverList<TabStripModelObserver> TabStripModelObservers; - TabStripModelObservers observers_; + base::ObserverList<TabStripModelObserver> observers_; ui::ListSelectionModel selection_model_;
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc index 66aa2136..d5bd241 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -290,7 +290,7 @@ bool DesktopMediaPickerDialogView::IsDialogButtonEnabled( ui::DialogButton button) const { if (button == ui::DIALOG_BUTTON_OK) - return list_views_[pane_->selected_tab_index()]->GetSelection() != nullptr; + return list_views_[pane_->GetSelectedTabIndex()]->GetSelection() != nullptr; return true; } @@ -315,7 +315,7 @@ bool DesktopMediaPickerDialogView::Accept() { DesktopMediaSourceView* selection = - list_views_[pane_->selected_tab_index()]->GetSelection(); + list_views_[pane_->GetSelectedTabIndex()]->GetSelection(); // Ok button should only be enabled when a source is selected. DCHECK(selection); @@ -373,16 +373,16 @@ DesktopMediaListView* DesktopMediaPickerDialogView::GetMediaListViewForTesting() const { - return list_views_[pane_->selected_tab_index()]; + return list_views_[pane_->GetSelectedTabIndex()]; } DesktopMediaSourceView* DesktopMediaPickerDialogView::GetMediaSourceViewForTesting(int index) const { - if (list_views_[pane_->selected_tab_index()]->child_count() <= index) + if (list_views_[pane_->GetSelectedTabIndex()]->child_count() <= index) return nullptr; return reinterpret_cast<DesktopMediaSourceView*>( - list_views_[pane_->selected_tab_index()]->child_at(index)); + list_views_[pane_->GetSelectedTabIndex()]->child_at(index)); } views::Checkbox* DesktopMediaPickerDialogView::GetCheckboxForTesting() const {
diff --git a/chrome/browser/ui/webui/options/preferences_browsertest.cc b/chrome/browser/ui/webui/options/preferences_browsertest.cc index 444c9db..8883127 100644 --- a/chrome/browser/ui/webui/options/preferences_browsertest.cc +++ b/chrome/browser/ui/webui/options/preferences_browsertest.cc
@@ -725,8 +725,7 @@ // Set up fake install attributes. std::unique_ptr<chromeos::StubInstallAttributes> attributes = base::MakeUnique<chromeos::StubInstallAttributes>(); - attributes->SetDomain("example.com"); - attributes->SetRegistrationUser("user@example.com"); + attributes->SetEnterprise("example.com", "fake-id"); policy::BrowserPolicyConnectorChromeOS::SetInstallAttributesForTesting( attributes.release());
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler.cc b/chrome/browser/ui/webui/signin/inline_login_handler.cc index 3f7b633e..e9a1901 100644 --- a/chrome/browser/ui/webui/signin/inline_login_handler.cc +++ b/chrome/browser/ui/webui/signin/inline_login_handler.cc
@@ -198,13 +198,14 @@ signin_metrics::Reason reason = signin::GetSigninReasonForPromoURL(current_url); - if (reason != signin_metrics::Reason::REASON_REAUTHENTICATION || - reason != signin_metrics::Reason::REASON_UNLOCK || + if (reason != signin_metrics::Reason::REASON_REAUTHENTICATION && + reason != signin_metrics::Reason::REASON_UNLOCK && reason != signin_metrics::Reason::REASON_ADD_SECONDARY_ACCOUNT) { signin_metrics::LogSigninAccessPointStarted(access_point); + RecordSigninUserActionForAccessPoint(access_point); + content::RecordAction(base::UserMetricsAction("Signin_SigninPage_Loading")); + params.SetBoolean("isLoginPrimaryAccount", true); } - RecordSigninUserActionForAccessPoint(access_point); - content::RecordAction(base::UserMetricsAction("Signin_SigninPage_Loading")); params.SetString("continueUrl", signin::GetLandingURL(access_point).spec());
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index c1302453b..ecb95d0 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1856,6 +1856,9 @@ // be an Android app). const char kIsBootstrappingSlave[] = "is_oobe_bootstrapping_slave"; +// A preference that controlles Android status reporting. +const char kReportArcStatus[] = "arc.status_reporting"; + #endif // defined(OS_CHROMEOS) // Whether there is a Flash version installed that supports clearing LSO data.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index e9467454..e7f91db 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -650,6 +650,7 @@ extern const char kLogoutStartedLast[]; extern const char kConsumerManagementStage[]; extern const char kIsBootstrappingSlave[]; +extern const char kReportArcStatus[]; #endif // defined(OS_CHROMEOS) extern const char kClearPluginLSODataEnabled[];
diff --git a/chrome/test/data/notifications/platform_notification_service.html b/chrome/test/data/notifications/platform_notification_service.html index 60e4763..88b2ac3 100644 --- a/chrome/test/data/notifications/platform_notification_service.html +++ b/chrome/test/data/notifications/platform_notification_service.html
@@ -116,6 +116,17 @@ }); } + // Displays a persistent notification with a reply button. + function DisplayPersistentNotificationWithReplyButton() { + DisplayPersistentNotification('action_button_click', { + body: 'Contents', + actions: [ + { action: 'actionId1', title: 'actionTitle1', icon: 'icon.png', + type: 'text' } + ] + }); + } + // Returns the latest received message from the worker. If no message has // been received, nothing will be done. For successfully registered // Service Workers this is OK, however, since the "message" event handler
diff --git a/chrome/test/data/notifications/platform_notification_service.js b/chrome/test/data/notifications/platform_notification_service.js index e7a3bf2..07a15b1 100644 --- a/chrome/test/data/notifications/platform_notification_service.js +++ b/chrome/test/data/notifications/platform_notification_service.js
@@ -21,7 +21,8 @@ if (message == 'action_button_click') message += ' ' + event.action; - + if (event.reply) + message += ' ' + event.reply; messagePort.postMessage(message); });
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index a886d4a..1c8acf6 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -2613,6 +2613,16 @@ ] }, + "ReportArcStatus": { + "os": ["chromeos"], + "can_be_recommended": false, + "test_policy": { "ReportArcStatus": false }, + "pref_mappings": [ + { "pref": "arc.status_reporting", + "local_state": true } + ] + }, + "----- Chrome OS device policies ---------------------------------------": {}, "DevicePolicyRefreshRate": {
diff --git a/chromecast/browser/cast_media_blocker.cc b/chromecast/browser/cast_media_blocker.cc index dfc371e..935dec5 100644 --- a/chromecast/browser/cast_media_blocker.cc +++ b/chromecast/browser/cast_media_blocker.cc
@@ -47,10 +47,8 @@ } } -void CastMediaBlocker::MediaSessionStateChanged( - bool is_controllable, - bool is_suspended, - const base::Optional<content::MediaMetadata>& metadata) { +void CastMediaBlocker::MediaSessionStateChanged(bool is_controllable, + bool is_suspended) { controllable_ = is_controllable; suspended_ = is_suspended; UpdateMediaBlockedState();
diff --git a/chromecast/browser/cast_media_blocker.h b/chromecast/browser/cast_media_blocker.h index 2bb9ab8..042742b 100644 --- a/chromecast/browser/cast_media_blocker.h +++ b/chromecast/browser/cast_media_blocker.h
@@ -41,10 +41,8 @@ }; // content::WebContentsObserver implementation: - void MediaSessionStateChanged( - bool is_controllable, - bool is_suspended, - const base::Optional<content::MediaMetadata>& metadata) override; + void MediaSessionStateChanged(bool is_controllable, + bool is_suspended) override; // Whether or not media in the app can be controlled and if media is currently // suspended. These variables cache arguments from MediaSessionStateChanged().
diff --git a/chromecast/public/avsettings.h b/chromecast/public/avsettings.h index 4bd29c7..53d012b 100644 --- a/chromecast/public/avsettings.h +++ b/chromecast/public/avsettings.h
@@ -295,18 +295,32 @@ // Sets the HDMI video mode according to the given parameters: // |allow_4k|: if false, the resolution set will not be a 4K resolution. // |optimize_for_fps|: *Attempts* to pick a refresh rate optimal for the - // given content frame rate. |optimize_for_fps| is expressed as framerate + // given content frame rate. |optimize_for_fps| is expressed as framerate // * 100. I.e. 24hz -> 2400, 23.98hz -> 2398, etc. Values <= 0 are ignored. + // |output_type|: if set to HDR_OUTPUT_DOLBYVISION, the video mode set will + // be a DV supported resolution. If set to HDR_OUTPUT_HDR, the video mode set + // will be a 10-bit or greater video mode. // // Returns: // - true if HDMI video mode change is beginning. Caller should wait for // SCREEN_INFO_CHANGED event for mode change to complete. // - false if no HDMI video mode change has begun. This could be because // HDMI is disconnected, or the current resolution is already good for the - // given parameters. + // given parameters, or no valid resolution with the given parameters is + // found (ie. setting require_dolby_vision/require_hdr to true when the + // sink doesn't support those features). // // Non-HDMI devices should return false. - virtual bool SetHdmiVideoMode(bool allow_4k, int optimize_for_fps) = 0; + virtual bool SetHdmiVideoMode(bool allow_4k, + int optimize_for_fps, + HdrOutputType output_type) = 0; + + // Returns true if the HDMI sink supports the specified HDR output type in + // the current HDMI mode. Returns false otherwise. + // + // Non-HDMI devices should return false. + virtual bool IsHdrOutputSupportedByCurrentHdmiVideoMode( + HdrOutputType output_type) = 0; }; } // namespace chromecast
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc index 317807f..d41ac97f 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils.cc +++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -13,9 +13,12 @@ #include "base/lazy_instance.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" +#include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/content/renderer/form_autofill_util.h" +#include "components/autofill/core/common/autofill_util.h" #include "components/autofill/core/common/password_form.h" #include "components/autofill/core/common/password_form_field_prediction_map.h" #include "google_apis/gaia/gaia_urls.h" @@ -702,9 +705,11 @@ bool HasAutocompleteAttributeValue(const blink::WebInputElement& element, const char* value_in_lowercase) { - return base::LowerCaseEqualsASCII( - base::StringPiece16(element.getAttribute("autocomplete")), - value_in_lowercase); + base::string16 autocomplete_attribute(element.getAttribute("autocomplete")); + std::vector<std::string> tokens = LowercaseAndTokenizeAttributeString( + base::UTF16ToUTF8(autocomplete_attribute)); + + return base::ContainsValue(tokens, value_in_lowercase); } } // namespace autofill
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index fb0c4954..3b2d93a 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -897,17 +897,14 @@ // section names. field->set_section(kDefaultSection); - // Canonicalize the attribute value by trimming whitespace, collapsing - // non-space characters (e.g. tab) to spaces, and converting to lowercase. - std::string autocomplete_attribute = - base::CollapseWhitespaceASCII(field->autocomplete_attribute, false); - autocomplete_attribute = base::ToLowerASCII(autocomplete_attribute); + std::vector<std::string> tokens = + LowercaseAndTokenizeAttributeString(field->autocomplete_attribute); // The autocomplete attribute is overloaded: it can specify either a field // type hint or whether autocomplete should be enabled at all. Ignore the // latter type of attribute value. - if (autocomplete_attribute.empty() || autocomplete_attribute == "on" || - autocomplete_attribute == "off") { + if (tokens.empty() || + (tokens.size() == 1 && (tokens[0] == "on" || tokens[0] == "off"))) { continue; } @@ -917,15 +914,11 @@ // the form. has_author_specified_types_ = true; - // Tokenize the attribute value. Per the spec, the tokens are parsed in - // reverse order. - std::vector<std::string> tokens = - base::SplitString(autocomplete_attribute, " ", base::KEEP_WHITESPACE, - base::SPLIT_WANT_NONEMPTY); - // The final token must be the field type. // If it is not one of the known types, abort. DCHECK(!tokens.empty()); + + // Per the spec, the tokens are parsed in reverse order. std::string field_type_token = tokens.back(); tokens.pop_back(); HtmlFieldType field_type =
diff --git a/components/autofill/core/common/autofill_util.cc b/components/autofill/core/common/autofill_util.cc index faf019e8..bc458a96 100644 --- a/components/autofill/core/common/autofill_util.cc +++ b/components/autofill/core/common/autofill_util.cc
@@ -5,7 +5,6 @@ #include "components/autofill/core/common/autofill_util.h" #include <algorithm> -#include <vector> #include "base/command_line.h" #include "base/i18n/case_conversion.h" @@ -132,4 +131,11 @@ } } +std::vector<std::string> LowercaseAndTokenizeAttributeString( + const std::string& attribute) { + return base::SplitString(base::ToLowerASCII(attribute), + base::kWhitespaceASCII, base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); +} + } // namespace autofill
diff --git a/components/autofill/core/common/autofill_util.h b/components/autofill/core/common/autofill_util.h index 519b3cbe..fccd473a 100644 --- a/components/autofill/core/common/autofill_util.h +++ b/components/autofill/core/common/autofill_util.h
@@ -7,6 +7,9 @@ #include <stddef.h> +#include <string> +#include <vector> + #include "base/strings/string16.h" #include "components/autofill/core/common/form_field_data.h" @@ -51,6 +54,12 @@ bool isCheckable, bool isChecked); +// Lowercases and tokenizes a given |attribute| string. +// Considers any ASCII whitespace character as a possible separator. +// Also ignores empty tokens, resulting in a collapsing of whitespace. +std::vector<std::string> LowercaseAndTokenizeAttributeString( + const std::string& attribute); + } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_COMMON_AUTOFILL_UTIL_H_
diff --git a/components/autofill/core/common/autofill_util_unittest.cc b/components/autofill/core/common/autofill_util_unittest.cc index 823be3d4..60c5010 100644 --- a/components/autofill/core/common/autofill_util_unittest.cc +++ b/components/autofill/core/common/autofill_util_unittest.cc
@@ -99,4 +99,33 @@ } } +// Tests for LowercaseAndTokenizeAttributeString +TEST(AutofillUtilTest, LowercaseAndTokenizeAttributeString) { + const struct { + const char* const attribute; + std::vector<std::string> tokens; + } kTestCases[] = { + // Test leading and trailing whitespace, test tabs and newlines + {"foo bar baz", {"foo", "bar", "baz"}}, + {" foo bar baz ", {"foo", "bar", "baz"}}, + {"foo\tbar baz ", {"foo", "bar", "baz"}}, + {"foo\nbar baz ", {"foo", "bar", "baz"}}, + + // Test different forms of capitalization + {"FOO BAR BAZ", {"foo", "bar", "baz"}}, + {"foO baR bAz", {"foo", "bar", "baz"}}, + + // Test collapsing of multiple whitespace characters in a row + {" \t\t\n\n ", std::vector<std::string>()}, + {"foO baR bAz", {"foo", "bar", "baz"}}, + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + SCOPED_TRACE(testing::Message() << "attribute = " + << kTestCases[i].attribute); + + EXPECT_EQ(kTestCases[i].tokens, + LowercaseAndTokenizeAttributeString(kTestCases[i].attribute)); + } +} } // namespace autofill
diff --git a/components/nacl/browser/nacl_broker_host_win.cc b/components/nacl/browser/nacl_broker_host_win.cc index 21bd188a..501ba6c6 100644 --- a/components/nacl/browser/nacl_broker_host_win.cc +++ b/components/nacl/browser/nacl_broker_host_win.cc
@@ -73,9 +73,8 @@ if (NaClBrowser::GetDelegate()->DialogsAreSuppressed()) cmd_line->AppendSwitch(switches::kNoErrorDialogs); - process_->Launch(new NaClBrokerSandboxedProcessLauncherDelegate, - cmd_line, - true); + process_->Launch(new NaClBrokerSandboxedProcessLauncherDelegate, cmd_line, + nullptr, true); return true; }
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index 7f23abe..ecd66b01 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc
@@ -668,8 +668,7 @@ #endif process_->Launch( new NaClSandboxedProcessLauncherDelegate(process_->GetHost()), - cmd_line.release(), - true); + cmd_line.release(), nullptr, true); return true; }
diff --git a/components/offline_pages/background/request_coordinator.cc b/components/offline_pages/background/request_coordinator.cc index c4d602e..087be6f 100644 --- a/components/offline_pages/background/request_coordinator.cc +++ b/components/offline_pages/background/request_coordinator.cc
@@ -638,12 +638,22 @@ } void RequestCoordinator::EnableForOffliner(int64_t request_id) { - disabled_requests_.erase(request_id); - // If we are not busy, start processing right away. - StartProcessingIfConnected(); + // Since the recent tab helper might call multiple times, ignore subsequent + // calls for a particular request_id. + if (disabled_requests_.find(request_id) == disabled_requests_.end()) + return; + disabled_requests_.erase(request_id); + // If we are not busy, start processing right away. + StartProcessingIfConnected(); } void RequestCoordinator::MarkRequestCompleted(int64_t request_id) { + // Since the recent tab helper might call multiple times, ignore subsequent + // calls for a particular request_id. + if (disabled_requests_.find(request_id) == disabled_requests_.end()) + return; + disabled_requests_.erase(request_id); + // Remove the request, but send out SUCCEEDED instead of removed. std::vector<int64_t> request_ids { request_id }; queue_->RemoveRequests(
diff --git a/components/offline_pages/background/request_coordinator_unittest.cc b/components/offline_pages/background/request_coordinator_unittest.cc index 18b0e675..06614b0d 100644 --- a/components/offline_pages/background/request_coordinator_unittest.cc +++ b/components/offline_pages/background/request_coordinator_unittest.cc
@@ -948,10 +948,11 @@ // Add a request to the queue. offline_pages::SavePageRequest request1(kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested); - coordinator()->queue()->AddRequest( - request1, base::Bind(&RequestCoordinatorTest::AddRequestDone, - base::Unretained(this))); + int64_t request_id = coordinator()->SavePageLater( + kUrl1, kClientId1, kUserRequested, + RequestCoordinator::RequestAvailability::DISABLED_FOR_OFFLINER); PumpLoop(); + EXPECT_NE(request_id, 0l); // Ensure the start processing request stops before the completion callback. EnableOfflinerCallback(false); @@ -963,7 +964,7 @@ EXPECT_TRUE(coordinator()->StartProcessing(device_conditions, callback)); // Call the method under test, making sure we send SUCCESS to the observer. - coordinator()->MarkRequestCompleted(kRequestId1); + coordinator()->MarkRequestCompleted(request_id); PumpLoop(); // Our observer should have seen SUCCESS instead of REMOVED.
diff --git a/components/offline_pages/background/request_queue_in_memory_store.cc b/components/offline_pages/background/request_queue_in_memory_store.cc index e2d79ed2..f46f9a10 100644 --- a/components/offline_pages/background/request_queue_in_memory_store.cc +++ b/components/offline_pages/background/request_queue_in_memory_store.cc
@@ -4,6 +4,8 @@ #include "components/offline_pages/background/request_queue_in_memory_store.h" +#include <unordered_set> + #include "base/bind.h" #include "base/location.h" #include "base/threading/thread_task_runner_handle.h" @@ -28,6 +30,33 @@ base::Bind(callback, true, base::Passed(std::move(result_requests)))); } +void RequestQueueInMemoryStore::GetRequestsByIds( + const std::vector<int64_t>& request_ids, + const UpdateCallback& callback) { + std::unique_ptr<UpdateRequestsResult> result( + new UpdateRequestsResult(state())); + + ItemActionStatus status; + // Make sure not to include the same request multiple times, while preserving + // the order of non-duplicated IDs in the result. + std::unordered_set<int64_t> processed_ids; + for (const auto& request_id : request_ids) { + if (!processed_ids.insert(request_id).second) + continue; + RequestsMap::iterator iter = requests_.find(request_id); + if (iter != requests_.end()) { + status = ItemActionStatus::SUCCESS; + result->updated_items.push_back(iter->second); + } else { + status = ItemActionStatus::NOT_FOUND; + } + result->item_statuses.push_back(std::make_pair(request_id, status)); + } + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, base::Passed(&result))); +} + void RequestQueueInMemoryStore::AddRequest(const SavePageRequest& request, const AddCallback& callback) { RequestsMap::iterator iter = requests_.find(request.request_id());
diff --git a/components/offline_pages/background/request_queue_in_memory_store.h b/components/offline_pages/background/request_queue_in_memory_store.h index 7c8b138..63b18e3d 100644 --- a/components/offline_pages/background/request_queue_in_memory_store.h +++ b/components/offline_pages/background/request_queue_in_memory_store.h
@@ -23,6 +23,8 @@ // RequestQueueStore implementaiton. void GetRequests(const GetRequestsCallback& callback) override; + void GetRequestsByIds(const std::vector<int64_t>& request_ids, + const UpdateCallback& callback) override; void AddRequest(const SavePageRequest& offline_page, const AddCallback& callback) override; void UpdateRequests(const std::vector<SavePageRequest>& requests,
diff --git a/components/offline_pages/background/request_queue_store.h b/components/offline_pages/background/request_queue_store.h index b661ea0..bb2e5966 100644 --- a/components/offline_pages/background/request_queue_store.h +++ b/components/offline_pages/background/request_queue_store.h
@@ -38,6 +38,11 @@ // Gets all of the requests from the store. virtual void GetRequests(const GetRequestsCallback& callback) = 0; + // Gets requests with specified IDs from the store. UpdateCallback is used + // instead of GetRequestsCallback to indicate which requests where not found. + virtual void GetRequestsByIds(const std::vector<int64_t>& request_ids, + const UpdateCallback& callback) = 0; + // Asynchronously adds request in store. Fails if request with the same // offline ID already exists. virtual void AddRequest(const SavePageRequest& offline_page,
diff --git a/components/offline_pages/background/request_queue_store_sql.cc b/components/offline_pages/background/request_queue_store_sql.cc index f88872be..b008ed3 100644 --- a/components/offline_pages/background/request_queue_store_sql.cc +++ b/components/offline_pages/background/request_queue_store_sql.cc
@@ -4,6 +4,8 @@ #include "components/offline_pages/background/request_queue_store_sql.h" +#include <unordered_set> + #include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -22,7 +24,6 @@ namespace { -using UpdateStatus = RequestQueueStore::UpdateStatus; using StoreStateCallback = base::Callback<void(StoreState)>; // This is a macro instead of a const so that @@ -109,8 +110,9 @@ sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); statement.BindInt64(0, request_id); - statement.Run(); - return MakeSavePageRequest(statement); + if (statement.Step()) + return MakeSavePageRequest(statement); + return std::unique_ptr<SavePageRequest>(nullptr); } ItemActionStatus DeleteRequestById(sql::Connection* db, int64_t request_id) { @@ -247,6 +249,44 @@ base::Passed(&requests))); } +void GetRequestsByIdsSync(sql::Connection* db, + scoped_refptr<base::SingleThreadTaskRunner> runner, + const std::vector<int64_t>& request_ids, + const RequestQueueStore::UpdateCallback& callback) { + // TODO(fgorski): Perhaps add metrics here. + std::unique_ptr<UpdateRequestsResult> result( + new UpdateRequestsResult(StoreState::LOADED)); + + // If you create a transaction but don't Commit() it is automatically + // rolled back by its destructor when it falls out of scope. + sql::Transaction transaction(db); + if (!transaction.Begin()) { + PostStoreErrorForAllIds(runner, request_ids, callback); + return; + } + + // Make sure not to include the same request multiple times, preserving the + // order of non-duplicated IDs in the result. + std::unordered_set<int64_t> processed_ids; + for (int64_t request_id : request_ids) { + if (!processed_ids.insert(request_id).second) + continue; + std::unique_ptr<SavePageRequest> request = GetOneRequest(db, request_id); + if (request.get()) + result->updated_items.push_back(*request); + ItemActionStatus status = + request.get() ? ItemActionStatus::SUCCESS : ItemActionStatus::NOT_FOUND; + result->item_statuses.push_back(std::make_pair(request_id, status)); + } + + if (!transaction.Commit()) { + PostStoreErrorForAllIds(runner, request_ids, callback); + return; + } + + runner->PostTask(FROM_HERE, base::Bind(callback, base::Passed(&result))); +} + void AddRequestSync(sql::Connection* db, scoped_refptr<base::SingleThreadTaskRunner> runner, const SavePageRequest& request, @@ -385,6 +425,21 @@ base::ThreadTaskRunnerHandle::Get(), callback)); } +void RequestQueueStoreSQL::GetRequestsByIds( + const std::vector<int64_t>& request_ids, + const UpdateCallback& callback) { + if (!db_.get()) { + PostStoreErrorForAllIds(base::ThreadTaskRunnerHandle::Get(), request_ids, + callback); + return; + } + + background_task_runner_->PostTask( + FROM_HERE, + base::Bind(&GetRequestsByIdsSync, db_.get(), + base::ThreadTaskRunnerHandle::Get(), request_ids, callback)); +} + void RequestQueueStoreSQL::AddRequest(const SavePageRequest& request, const AddCallback& callback) { if (!CheckDb(base::Bind(callback, ItemActionStatus::STORE_ERROR)))
diff --git a/components/offline_pages/background/request_queue_store_sql.h b/components/offline_pages/background/request_queue_store_sql.h index d67d14f..0be2eb5 100644 --- a/components/offline_pages/background/request_queue_store_sql.h +++ b/components/offline_pages/background/request_queue_store_sql.h
@@ -33,6 +33,11 @@ // RequestQueueStore implementation. void GetRequests(const GetRequestsCallback& callback) override; + // Note: current implementation of this method makes a SQL query per ID. This + // is OK as long as number of IDs stays low, which is a typical case. + // Implementation should be revisited in case that presumption changes. + void GetRequestsByIds(const std::vector<int64_t>& request_ids, + const UpdateCallback& callback) override; void AddRequest(const SavePageRequest& offline_page, const AddCallback& callback) override; void UpdateRequests(const std::vector<SavePageRequest>& requests,
diff --git a/components/offline_pages/background/request_queue_store_unittest.cc b/components/offline_pages/background/request_queue_store_unittest.cc index 0a20dfb4..c4264c4 100644 --- a/components/offline_pages/background/request_queue_store_unittest.cc +++ b/components/offline_pages/background/request_queue_store_unittest.cc
@@ -24,6 +24,7 @@ namespace { const int64_t kRequestId = 42; const int64_t kRequestId2 = 44; +const int64_t kRequestId3 = 47; const GURL kUrl("http://example.com"); const GURL kUrl2("http://another-example.com"); const ClientId kClientId("bookmark", "1234"); @@ -198,6 +199,65 @@ ASSERT_TRUE(this->last_requests().empty()); } +TYPED_TEST(RequestQueueStoreTest, GetRequestsByIds) { + std::unique_ptr<RequestQueueStore> store(this->BuildStore()); + base::Time creation_time = base::Time::Now(); + SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time, + kUserRequested); + store->AddRequest(request1, + base::Bind(&RequestQueueStoreTestBase::AddRequestDone, + base::Unretained(this))); + SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time, + kUserRequested); + store->AddRequest(request2, + base::Bind(&RequestQueueStoreTestBase::AddRequestDone, + base::Unretained(this))); + this->PumpLoop(); + this->ClearResults(); + + std::vector<int64_t> request_ids{kRequestId, kRequestId2}; + store->GetRequestsByIds( + request_ids, base::Bind(&RequestQueueStoreTestBase::UpdateRequestDone, + base::Unretained(this))); + + ASSERT_FALSE(this->last_update_result()); + this->PumpLoop(); + ASSERT_TRUE(this->last_update_result()); + EXPECT_EQ(2UL, this->last_update_result()->item_statuses.size()); + EXPECT_EQ(kRequestId, this->last_update_result()->item_statuses[0].first); + EXPECT_EQ(ItemActionStatus::SUCCESS, + this->last_update_result()->item_statuses[0].second); + EXPECT_EQ(kRequestId2, this->last_update_result()->item_statuses[1].first); + EXPECT_EQ(ItemActionStatus::SUCCESS, + this->last_update_result()->item_statuses[1].second); + EXPECT_EQ(2UL, this->last_update_result()->updated_items.size()); + EXPECT_EQ(request1, this->last_update_result()->updated_items.at(0)); + EXPECT_EQ(request2, this->last_update_result()->updated_items.at(1)); + this->ClearResults(); + + request_ids.clear(); + request_ids.push_back(kRequestId); + request_ids.push_back(kRequestId3); + request_ids.push_back(kRequestId); + + store->GetRequestsByIds( + request_ids, base::Bind(&RequestQueueStoreTestBase::UpdateRequestDone, + base::Unretained(this))); + + ASSERT_FALSE(this->last_update_result()); + this->PumpLoop(); + ASSERT_TRUE(this->last_update_result()); + EXPECT_EQ(2UL, this->last_update_result()->item_statuses.size()); + EXPECT_EQ(kRequestId, this->last_update_result()->item_statuses[0].first); + EXPECT_EQ(ItemActionStatus::SUCCESS, + this->last_update_result()->item_statuses[0].second); + EXPECT_EQ(kRequestId3, this->last_update_result()->item_statuses[1].first); + EXPECT_EQ(ItemActionStatus::NOT_FOUND, + this->last_update_result()->item_statuses[1].second); + EXPECT_EQ(1UL, this->last_update_result()->updated_items.size()); + EXPECT_EQ(request1, this->last_update_result()->updated_items.at(0)); +} + TYPED_TEST(RequestQueueStoreTest, AddRequest) { std::unique_ptr<RequestQueueStore> store(this->BuildStore()); base::Time creation_time = base::Time::Now();
diff --git a/components/offline_pages/offline_page_model.h b/components/offline_pages/offline_page_model.h index c1036b7..cf6ef74 100644 --- a/components/offline_pages/offline_page_model.h +++ b/components/offline_pages/offline_page_model.h
@@ -81,10 +81,13 @@ virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; + static const int64_t kInvalidOfflineId = 0; + // Attempts to save a page addressed by |url| offline. Requires that the model // is loaded. Generates a new offline id and returns // it. |proposed_offline_id| is used for the offline_id for the saved file if - // it is non-zero. If it is zero, a new, random ID will be generated. + // it is non-zero. If it is kInvalidOfflineId, a new, random ID will be + // generated. virtual void SavePage(const GURL& url, const ClientId& client_id, int64_t proposed_offline_id,
diff --git a/components/offline_pages/offline_page_model_impl.cc b/components/offline_pages/offline_page_model_impl.cc index e16d547..0a5094fb 100644 --- a/components/offline_pages/offline_page_model_impl.cc +++ b/components/offline_pages/offline_page_model_impl.cc
@@ -357,7 +357,7 @@ } // If we already have an offline id, use it. If not, generate one. - if (proposed_offline_id == 0l) + if (proposed_offline_id == kInvalidOfflineId) proposed_offline_id = GenerateOfflineId(); archiver->CreateArchive(
diff --git a/components/offline_pages/offline_page_model_impl.h b/components/offline_pages/offline_page_model_impl.h index 194fa206..a805f1b 100644 --- a/components/offline_pages/offline_page_model_impl.h +++ b/components/offline_pages/offline_page_model_impl.h
@@ -44,8 +44,6 @@ namespace offline_pages { -static const int64_t kInvalidOfflineId = 0; - struct ClientId; struct OfflinePageItem;
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc index c9854058..b658e0bd 100644 --- a/components/password_manager/content/browser/content_password_manager_driver.cc +++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -174,7 +174,6 @@ void ContentPasswordManagerDriver::OnPasswordFormsParsedNoRenderCheck( const std::vector<autofill::PasswordForm>& forms) { - MaybeNotifyPasswordInputShownOnHttp(render_frame_host_); GetPasswordManager()->OnPasswordFormsParsed(this, forms); GetPasswordGenerationManager()->CheckIfFormClassifierShouldRun(); } @@ -209,9 +208,7 @@ } void ContentPasswordManagerDriver::PasswordFieldVisibleInInsecureContext() { - // TODO(estark): notify the WebContents that a password field was - // shown, which will downgrade the security UI - // appropriately. https://crbug.com/647560 + MaybeNotifyPasswordInputShownOnHttp(render_frame_host_); } void ContentPasswordManagerDriver::DidNavigateFrame(
diff --git a/components/password_manager/content/browser/content_password_manager_driver_unittest.cc b/components/password_manager/content/browser/content_password_manager_driver_unittest.cc index 06e21b3..7bdd57d4 100644 --- a/components/password_manager/content/browser/content_password_manager_driver_unittest.cc +++ b/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
@@ -10,6 +10,8 @@ #include "components/autofill/core/browser/test_autofill_client.h" #include "components/password_manager/core/browser/stub_log_manager.h" #include "components/password_manager/core/browser/stub_password_manager_client.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/ssl_status.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_renderer_host.h" #include "mojo/public/cpp/bindings/binding.h" @@ -167,6 +169,35 @@ EXPECT_EQ(should_allow_logging, logging_activated); } +// Tests that password visibility notifications are forwarded to the +// WebContents. +TEST_P(ContentPasswordManagerDriverTest, PasswordVisibility) { + std::unique_ptr<ContentPasswordManagerDriver> driver( + new ContentPasswordManagerDriver(main_rfh(), &password_manager_client_, + &autofill_client_)); + + // Do a mock navigation so that there is a navigation entry on which + // password visibility gets recorded. + GURL url("http://example.test"); + NavigateAndCommit(url); + content::NavigationEntry* entry = + web_contents()->GetController().GetVisibleEntry(); + ASSERT_TRUE(entry); + EXPECT_EQ(url, entry->GetURL()); + EXPECT_FALSE(!!(entry->GetSSL().content_status & + content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP)); + + driver->PasswordFieldVisibleInInsecureContext(); + + // Check that the password visibility notification was passed on to + // the WebContents (and from there to the SSLStatus). + entry = web_contents()->GetController().GetVisibleEntry(); + ASSERT_TRUE(entry); + EXPECT_EQ(url, entry->GetURL()); + EXPECT_TRUE(!!(entry->GetSSL().content_status & + content::SSLStatus::DISPLAYED_PASSWORD_FIELD_ON_HTTP)); +} + INSTANTIATE_TEST_CASE_P(, ContentPasswordManagerDriverTest, testing::Values(true, false));
diff --git a/components/password_manager/content/browser/credential_manager_impl_unittest.cc b/components/password_manager/content/browser/credential_manager_impl_unittest.cc index a4492d3..a03315ec 100644 --- a/components/password_manager/content/browser/credential_manager_impl_unittest.cc +++ b/components/password_manager/content/browser/credential_manager_impl_unittest.cc
@@ -40,6 +40,7 @@ using content::WebContents; using testing::_; +using testing::ElementsAre; using testing::Pointee; using testing::UnorderedElementsAre; @@ -450,6 +451,41 @@ EXPECT_EQ(autofill::PasswordForm::SCHEME_HTML, new_form.scheme); } +TEST_F(CredentialManagerImplTest, StoreFederatedAfterPassword) { + // Populate the PasswordStore with a form. + store_->AddLogin(form_); + + autofill::PasswordForm federated = form_; + federated.password_value.clear(); + federated.type = autofill::PasswordForm::TYPE_API; + federated.preferred = true; + federated.federation_origin = url::Origin(GURL("https://google.com/")); + federated.signon_realm = "federation://example.com/google.com"; + CredentialInfo info(federated, CredentialType::CREDENTIAL_TYPE_FEDERATED); + EXPECT_CALL(*client_, PromptUserToSavePasswordPtr( + _, CredentialSourceType::CREDENTIAL_SOURCE_API)); + EXPECT_CALL(*client_, NotifyStorePasswordCalled()); + + bool called = false; + CallStore(info, base::Bind(&RespondCallback, &called)); + + // Allow the PasswordFormManager to talk to the password store, determine + // that the form is new, and set it as pending. + RunAllPendingTasks(); + + EXPECT_TRUE(called); + EXPECT_TRUE(client_->pending_manager()->HasCompletedMatching()); + client_->pending_manager()->Save(); + + RunAllPendingTasks(); + TestPasswordStore::PasswordMap passwords = store_->stored_passwords(); + EXPECT_THAT(passwords["https://example.com/"], ElementsAre(form_)); + federated.date_created = + passwords["federation://example.com/google.com"][0].date_created; + EXPECT_THAT(passwords["federation://example.com/google.com"], + ElementsAre(federated)); +} + TEST_F(CredentialManagerImplTest, CredentialManagerStoreOverwrite) { // Populate the PasswordStore with a form. store_->AddLogin(form_);
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index 59d9c0a..919f1713 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -1218,6 +1218,8 @@ const PasswordForm* PasswordFormManager::FindBestSavedMatch( const PasswordForm* form) const { + if (!form->federation_origin.unique()) + return nullptr; auto it = best_matches_.find(form->username_value); if (it != best_matches_.end()) return it->second;
diff --git a/components/policy/core/browser/configuration_policy_handler_list.cc b/components/policy/core/browser/configuration_policy_handler_list.cc index 8fb0ed5..9cdfc2aa 100644 --- a/components/policy/core/browser/configuration_policy_handler_list.cc +++ b/components/policy/core/browser/configuration_policy_handler_list.cc
@@ -32,6 +32,10 @@ const PolicyMap& policies, PrefValueMap* prefs, PolicyErrorMap* errors) const { + // This function is used both to apply the policy settings, and to check them + // and list errors. As such it must get all the errors even if it isn't + // applying the policies. + // TODO (aberent) split into two functions. PolicyErrorMap scoped_errors; if (!errors) errors = &scoped_errors; @@ -39,13 +43,11 @@ policy::PolicyHandlerParameters parameters; parameters_callback_.Run(¶meters); - if (prefs) { - std::vector<ConfigurationPolicyHandler*>::const_iterator handler; - for (handler = handlers_.begin(); handler != handlers_.end(); ++handler) { - if ((*handler)->CheckPolicySettings(policies, errors)) { - (*handler) - ->ApplyPolicySettingsWithParameters(policies, parameters, prefs); - } + std::vector<ConfigurationPolicyHandler*>::const_iterator handler; + for (handler = handlers_.begin(); handler != handlers_.end(); ++handler) { + if ((*handler)->CheckPolicySettings(policies, errors) && prefs) { + (*handler) + ->ApplyPolicySettingsWithParameters(policies, parameters, prefs); } }
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index 1b68c94..ea5ba54e 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -32,6 +32,8 @@ return DEVICE_MODE_ENTERPRISE; case em::DeviceRegisterResponse::RETAIL: return DEVICE_MODE_LEGACY_RETAIL_MODE; + case em::DeviceRegisterResponse::CHROME_AD: + return DEVICE_MODE_ENTERPRISE_AD; } LOG(ERROR) << "Unknown enrollment mode in registration response: " << mode; return DEVICE_MODE_NOT_SET;
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.cc b/components/policy/core/common/cloud/cloud_policy_constants.cc index 380ec12..0dd4e7df 100644 --- a/components/policy/core/common/cloud/cloud_policy_constants.cc +++ b/components/policy/core/common/cloud/cloud_policy_constants.cc
@@ -24,9 +24,11 @@ const char kParamAppType[] = "apptype"; const char kParamDeviceID[] = "deviceid"; const char kParamDeviceType[] = "devicetype"; +const char kParamLastError[] = "lasterror"; const char kParamOAuthToken[] = "oauth_token"; const char kParamPlatform[] = "platform"; const char kParamRequest[] = "request"; +const char kParamRetry[] = "retry"; // String constants for the device and app type we report to the server. const char kValueAppType[] = "Chrome";
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.h b/components/policy/core/common/cloud/cloud_policy_constants.h index b960620..b767bf3c 100644 --- a/components/policy/core/common/cloud/cloud_policy_constants.h +++ b/components/policy/core/common/cloud/cloud_policy_constants.h
@@ -23,9 +23,11 @@ POLICY_EXPORT extern const char kParamAppType[]; POLICY_EXPORT extern const char kParamDeviceID[]; POLICY_EXPORT extern const char kParamDeviceType[]; +POLICY_EXPORT extern const char kParamLastError[]; POLICY_EXPORT extern const char kParamOAuthToken[]; POLICY_EXPORT extern const char kParamPlatform[]; POLICY_EXPORT extern const char kParamRequest[]; +POLICY_EXPORT extern const char kParamRetry[]; // String extern constants for the device and app type we report to the server. POLICY_EXPORT extern const char kValueAppType[]; @@ -117,6 +119,7 @@ // device. DEVICE_MODE_ENTERPRISE, // The device is enrolled as an enterprise // device. + DEVICE_MODE_ENTERPRISE_AD, // The device has joined AD. DEVICE_MODE_LEGACY_RETAIL_MODE, // The device is enrolled as a retail kiosk // device. Even though retail mode is // deprecated, we still check for this device
diff --git a/components/policy/core/common/cloud/device_management_service.cc b/components/policy/core/common/cloud/device_management_service.cc index c2790e83..b84cfcf5 100644 --- a/components/policy/core/common/cloud/device_management_service.cc +++ b/components/policy/core/common/cloud/device_management_service.cc
@@ -220,6 +220,9 @@ // Number of times that this job has been retried due to connection errors. int retries_count_; + // The last error why we had to retry. + int last_error_ = 0; + // The request context to use for this job. scoped_refptr<net::URLRequestContextGetter> request_context_; @@ -328,10 +331,20 @@ const std::string& server_url) { std::string result(server_url); result += '?'; - for (ParameterMap::const_iterator entry(query_params_.begin()); - entry != query_params_.end(); - ++entry) { - if (entry != query_params_.begin()) + ParameterMap current_query_params(query_params_); + if (last_error_ == 0) { + // Not a retry. + current_query_params.push_back( + std::make_pair(dm_protocol::kParamRetry, "false")); + } else { + current_query_params.push_back( + std::make_pair(dm_protocol::kParamRetry, "true")); + current_query_params.push_back(std::make_pair(dm_protocol::kParamLastError, + std::to_string(last_error_))); + } + for (ParameterMap::const_iterator entry(current_query_params.begin()); + entry != current_query_params.end(); ++entry) { + if (entry != current_query_params.begin()) result += '&'; result += net::EscapeQueryParamValue(entry->first, true); result += '='; @@ -362,6 +375,7 @@ DeviceManagementRequestJobImpl::RetryMethod DeviceManagementRequestJobImpl::ShouldRetry(const net::URLFetcher* fetcher) { + last_error_ = fetcher->GetStatus().error(); if (FailedWithProxy(fetcher) && !bypass_proxy_) { // Retry the job immediately if it failed due to a broken proxy, by // bypassing the proxy on the next try.
diff --git a/components/policy/core/common/cloud/device_management_service_unittest.cc b/components/policy/core/common/cloud/device_management_service_unittest.cc index 075a978..5a0bb4e 100644 --- a/components/policy/core/common/cloud/device_management_service_unittest.cc +++ b/components/policy/core/common/cloud/device_management_service_unittest.cc
@@ -402,7 +402,8 @@ protected: void CheckURLAndQueryParams(const GURL& request_url, const std::string& request_type, - const std::string& device_id) { + const std::string& device_id, + const std::string& last_error) { const GURL service_url(kServiceUrl); EXPECT_EQ(service_url.scheme(), request_url.scheme()); EXPECT_EQ(service_url.host(), request_url.host()); @@ -416,6 +417,12 @@ dm_protocol::kValueDeviceType)); EXPECT_TRUE(query_params.Check(dm_protocol::kParamAppType, dm_protocol::kValueAppType)); + if (last_error == "") { + EXPECT_TRUE(query_params.Check(dm_protocol::kParamRetry, "false")); + } else { + EXPECT_TRUE(query_params.Check(dm_protocol::kParamRetry, "true")); + EXPECT_TRUE(query_params.Check(dm_protocol::kParamLastError, last_error)); + } } }; @@ -440,8 +447,7 @@ ASSERT_TRUE(fetcher); CheckURLAndQueryParams(fetcher->GetOriginalURL(), - dm_protocol::kValueRequestRegister, - kClientID); + dm_protocol::kValueRequestRegister, kClientID, ""); std::string expected_data; ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data)); @@ -466,8 +472,8 @@ ASSERT_TRUE(fetcher); CheckURLAndQueryParams(fetcher->GetOriginalURL(), - dm_protocol::kValueRequestCertBasedRegister, - kClientID); + dm_protocol::kValueRequestCertBasedRegister, kClientID, + ""); std::string expected_data; ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data)); @@ -492,8 +498,8 @@ ASSERT_TRUE(fetcher); CheckURLAndQueryParams(fetcher->GetOriginalURL(), - dm_protocol::kValueRequestApiAuthorization, - kClientID); + dm_protocol::kValueRequestApiAuthorization, kClientID, + ""); std::string expected_data; ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data)); @@ -525,8 +531,7 @@ EXPECT_EQ(service_url.path(), request_url.path()); CheckURLAndQueryParams(fetcher->GetOriginalURL(), - dm_protocol::kValueRequestUnregister, - kClientID); + dm_protocol::kValueRequestUnregister, kClientID, ""); std::string expected_data; ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data)); @@ -672,7 +677,9 @@ net::TestURLFetcher* fetcher = GetFetcher(); ASSERT_TRUE(fetcher); EXPECT_EQ(0, fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY); - const GURL original_url(fetcher->GetOriginalURL()); + // Not a retry. + CheckURLAndQueryParams(fetcher->GetOriginalURL(), + dm_protocol::kValueRequestRegister, kClientID, ""); const std::string upload_data(fetcher->upload_data()); // Generate a callback with a proxy failure. @@ -683,8 +690,11 @@ fetcher = GetFetcher(); ASSERT_TRUE(fetcher); EXPECT_TRUE(fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY); - EXPECT_EQ(original_url, fetcher->GetOriginalURL()); EXPECT_EQ(upload_data, fetcher->upload_data()); + // Retry with last error net::ERR_PROXY_CONNECTION_FAILED. + CheckURLAndQueryParams(fetcher->GetOriginalURL(), + dm_protocol::kValueRequestRegister, kClientID, + std::to_string(net::ERR_PROXY_CONNECTION_FAILED)); } TEST_F(DeviceManagementServiceTest, RetryOnBadResponseFromProxy) { @@ -727,7 +737,9 @@ StartRegistrationJob()); net::TestURLFetcher* fetcher = GetFetcher(); ASSERT_TRUE(fetcher); - const GURL original_url(fetcher->GetOriginalURL()); + // Not a retry. + CheckURLAndQueryParams(fetcher->GetOriginalURL(), + dm_protocol::kValueRequestRegister, kClientID, ""); const std::string original_upload_data(fetcher->upload_data()); // Make it fail with ERR_NETWORK_CHANGED. @@ -742,9 +754,12 @@ Mock::VerifyAndClearExpectations(this); fetcher = GetFetcher(); ASSERT_TRUE(fetcher); - EXPECT_EQ(original_url, fetcher->GetOriginalURL()); EXPECT_EQ(original_upload_data, fetcher->upload_data()); EXPECT_EQ(net::URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); + // Retry with last error net::ERR_NETWORK_CHANGED. + CheckURLAndQueryParams(fetcher->GetOriginalURL(), + dm_protocol::kValueRequestRegister, kClientID, + std::to_string(net::ERR_NETWORK_CHANGED)); } TEST_F(DeviceManagementServiceTest, PolicyFetchRetryImmediately) { @@ -759,7 +774,9 @@ StartPolicyFetchJob()); net::TestURLFetcher* fetcher = GetFetcher(); ASSERT_TRUE(fetcher); - const GURL original_url(fetcher->GetOriginalURL()); + // Not a retry. + CheckURLAndQueryParams(fetcher->GetOriginalURL(), + dm_protocol::kValueRequestPolicy, kClientID, ""); const std::string original_upload_data(fetcher->upload_data()); // Make it fail with ERR_NETWORK_CHANGED. @@ -774,9 +791,12 @@ Mock::VerifyAndClearExpectations(this); fetcher = GetFetcher(); ASSERT_TRUE(fetcher); - EXPECT_EQ(original_url, fetcher->GetOriginalURL()); EXPECT_EQ(original_upload_data, fetcher->upload_data()); EXPECT_EQ(net::URLRequestStatus::SUCCESS, fetcher->GetStatus().status()); + // Retry with last error net::ERR_NETWORK_CHANGED. + CheckURLAndQueryParams(fetcher->GetOriginalURL(), + dm_protocol::kValueRequestPolicy, kClientID, + std::to_string(net::ERR_NETWORK_CHANGED)); } TEST_F(DeviceManagementServiceTest, RetryLimit) { @@ -793,6 +813,16 @@ fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_NETWORK_CHANGED)); fetcher->set_url(GURL(kServiceUrl)); + if (i == 0) { + // Not a retry. + CheckURLAndQueryParams(fetcher->GetOriginalURL(), + dm_protocol::kValueRequestRegister, kClientID, ""); + } else { + // Retry with last error net::ERR_NETWORK_CHANGED. + CheckURLAndQueryParams(fetcher->GetOriginalURL(), + dm_protocol::kValueRequestRegister, kClientID, + std::to_string(net::ERR_NETWORK_CHANGED)); + } fetcher->delegate()->OnURLFetchComplete(fetcher); base::RunLoop().RunUntilIdle(); Mock::VerifyAndClearExpectations(this);
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index 388e331..b70bacd 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -19,14 +19,14 @@ optional int32 extra_data_bytes = 3; } -// Request from device to server to register device. +// Request from device to server to register a device, user or browser. message DeviceRegisterRequest { // Reregister device without erasing server state. It can be used // to refresh dmtoken etc. Client MUST set this value to true if it // reuses an existing device id. optional bool reregister = 1; - // Device register type. This field does not exist for TT release. + // Register type. This field does not exist for TT release. // When a client requests for policies, server should verify the // client has been registered properly. For example, a client must // register with type DEVICE in order to retrieve device policies. @@ -125,8 +125,16 @@ // settings from the cloud, but additionally this mode enables the demo // account on the device. RETAIL = 1; + // Devices in CHROME_AD mode are in enterprises with AD. Device settings + // are controlled through the AD policy infrastructure. + CHROME_AD = 2; } optional DeviceMode enrollment_type = 3 [default = ENTERPRISE]; + + // An opaque configuration string for devices that require it. CHROME_AD + // devices, for example, may use this string for AD discovery. Must be at + // most a few kBytes. + optional string configuration_seed = 4; } // Request from device to server to unregister device. @@ -163,10 +171,6 @@ message DeviceServiceApiAccessResponse { // The OAuth2 authorization code for the requested scope(s). // This can be exchanged for a refresh token. - // - // The server may send a successful response but not set this field or set an - // empty string to reject the auth code request and instruct the client to - // skip robot account auth setup. optional string auth_code = 1; } @@ -235,6 +239,24 @@ optional string verification_key_hash = 9; } +// This message contains the information which is signed by the verification +// key during policy key rotation. It is included in serialized form in +// PolicyFetchResponse below. A signature of the serialized form is included +// in the new_public_key_verification_data_signature field. For backward +// compatibility reasons, a signature over just {new_public_key, domain} fields +// is included in new_public_key_verification_signature_DEPRECATED field. +message PublicKeyVerificationData { + // The new public policy key after a key rotation. + optional bytes new_public_key = 1; + + // The domain of the device/user. + optional string domain = 2; + + // The version number of the new_public_key. This must be monotonically + // increasing (within a domain). + optional int32 new_public_key_version = 3; +} + // This message customizes how the device behaves when it is disabled by its // owner. The message will be sent as part of the DeviceState fetched during // normal operation and as part of the DeviceStateRetrievalResponse fetched when @@ -262,9 +284,8 @@ optional DisabledState disabled_state = 2; } -// This message is included in serialized form in PolicyFetchResponse -// below. It may also be signed, with the signature being created for -// the serialized form. +// This message is included in serialized form in PolicyFetchResponse below. It +// may also be signed, with the signature being created for the serialized form. message PolicyData { // See PolicyFetchRequest.policy_type. optional string policy_type = 1; @@ -349,7 +370,7 @@ // Server-provided identifier of the fetched policy. This is to be used // by the client when requesting Policy Posture assertion through an API - // call or SAML flow. + // call or SAML flow. For details, see http://go/chrome-nac-server-design. optional string policy_token = 15; // Indicates the management mode of the device. Note that old policies do not @@ -434,6 +455,34 @@ optional bytes new_public_key = 5; optional bytes new_public_key_signature = 6; + // DEPRECATED ON THE SERVER: Exists only to support older clients. This + // signature is similar to new_public_key_verification_data_signature, but is + // computed over PublicKeyVerificationData proto with version field unset. In + // other words, we set the new public key value, and domain value and then + // produce this signature. + optional bytes new_public_key_verification_signature = 7; + + // This is a serialized |PublicKeyVerificationData| protobuf + // (defined above). See comments for |new_public_key_verification_signature| + // field for details on how this data is signed. + // Please note that |new_public_key| is also included inside this data + // field. Thus we have new public key signed with old version of private key + // (if client indicated to us that it has old key version), and + // new public key data signed by master verification key (if client told + // us that it has public verification key - see |verification_key_id| field + // of |PolicyFetchRequest|). In most cases, both signatures will be provided. + // However, client might not have old policy signing key - for example, when + // new profile is being set up. In this case, only verification signature + // is supplied. + // Or, client might not have verification public key (legacy Chrome build + // before verification key was introduced, or outdated build which has + // old/compromised verification key). In that case, verification signature + // cannot be provided. + // If client is missing both public keys (old signing key and verification + // key), then we are unable to produce any valid signature and client must + // drop such PolicyFetchResponse. + optional bytes new_public_key_verification_data = 8; + // If new_public_key is specified, this field contains a signature // of a PolicyPublicKeyAndDomain protobuf, signed using a key only // available to DMServer. The public key portion of this well-known key is @@ -448,10 +497,11 @@ // and new_public_key_signature described above, Chrome also verifies // new_public_key with the embedded public key and // new_public_key_verification_signature. - optional bytes new_public_key_verification_signature = 7; + optional bytes new_public_key_verification_data_signature = 9; } -// Protobuf used to generate the new_public_key_verification_signature field. +// DEPRECATED ON THE SERVER: Protobuf used to generate the deprecated +// new_public_key_verification_signature field. message PolicyPublicKeyAndDomain { // The public key to sign (taken from the |new_public_key| field in // PolicyFetchResponse). @@ -1105,7 +1155,7 @@ message CheckAndroidManagementResponse {} // Request to register a new device (authenticated by enterprise enrollment -// certificate). +// certificate). See http://go/zero-touch-chrome for details. // The response message will be the DeviceRegisterReponse. message CertificateBasedDeviceRegisterRequest { // Signed request to register with a certificate. The signed_request.data @@ -1165,7 +1215,7 @@ // * devicetype: MUST BE "1" for Android or "2" for Chrome OS. // * apptype: MUST BE Android or Chrome. // * deviceid: MUST BE no more than 64-char in [\x21-\x7E]. -// * agent: MUST BE a string of characters. +// * agent: MUST BE no more than 64-char long. // * HTTP Authorization header MUST be in the following formats: // * For register, ping and check_android_management requests // Authorization: GoogleLogin auth=<auth cookie for Mobile Sync> @@ -1271,9 +1321,37 @@ // 491 Request Pending: the request is pending approval. // 500 Internal Server Error: most likely a bug in DM server. // 503 Service Unavailable: most likely a backend error. -// 901 Device Not Found: the device id is not found. // 902 Policy Not Found: the policy is not found. message DeviceManagementResponse { + // TODO(hong): move error handling to HTTP level. + // Error code to client. + enum ErrorCode { + SUCCESS = 0; + // Returned for register request when device management is not supported + // for the domain. + DEVICE_MANAGEMENT_NOT_SUPPORTED = 1; + // Returned when the device is not found. + DEVICE_NOT_FOUND = 2; + // Returned when passed in device management token doesn't match the token + // on server side. + DEVICE_MANAGEMENT_TOKEN_INVALID = 3; + // Returned when device registration is pending approval (if required). + ACTIVATION_PENDING = 4; + // Returned when the policy is not found. + POLICY_NOT_FOUND = 5; + } + + // Error code for this reponse. + // + // For responses to TT clients, this field MUST be set, since it WAS + // a required field. For special error code listed above, we return + // 200 in HTTP Status Code and set the real error code here. + // + // For release clients, we plan to move all error code to HTTP + // Status Code, so it is much easier for log analysis. If possible, + // we plan to remove this field once Chrome OS TT phase is over. + optional ErrorCode error = 1 [default = SUCCESS]; + // Error message. optional string error_message = 2;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index ca1023a7..cf07596 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -120,6 +120,8 @@ # 'can_be_recommended' can be set to True to include that policy in the # recommended policies templates. This only affects the template generation; # all policies can be at the recommended level. The default is False. +# 'per_profile' controls whether a user policy applies to every user logging +# into the browser or only one profile. # # The 'max_size' key is used to specify the maximal size of the external data # that a policy can reference, in bytes. This annotation is compulsory for @@ -137,7 +139,7 @@ # persistent IDs for all fields (but not for groups!) are needed. These are # specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs, # because doing so would break the deployed wire format! -# For your editing convenience: highest ID currently used: 348 +# For your editing convenience: highest ID currently used: 349 # # Placeholders: # The following placeholder strings are automatically substituted: @@ -4994,8 +4996,8 @@ 'desc': '''Report information about the active kiosk session, such as application ID and version. - If the policy is set to false, the session information will not be - reported. If set to true or left unset, session information will be + If the policy is set to false, the kiosk session information will not be + reported. If set to true or left unset, kiosk session information will be reported.''', 'arc_support': 'This policy has no effect on the logging done by Android.', }, @@ -5019,6 +5021,27 @@ 'arc_support': 'This policy has no effect on the logging done by Android.', }, { + 'name': 'ReportArcStatus', + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:55-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'example_value': False, + 'id': 349, + 'caption': '''Report information about status of Android''', + 'tags': ['admin-sharing'], + 'desc': '''Report information about the status of Android is send back to + the server. + + If the policy is set to false, the information will not be reported. + If set to true or left unset, the information will be reported. + + This policy only applies if Android apps are enabled.''', + }, + { 'name': 'HeartbeatEnabled', 'type': 'main', 'schema': { 'type': 'boolean' },
diff --git a/components/search_engines/default_search_policy_handler.cc b/components/search_engines/default_search_policy_handler.cc index a2837ee8..7c742da5 100644 --- a/components/search_engines/default_search_policy_handler.cc +++ b/components/search_engines/default_search_policy_handler.cc
@@ -301,11 +301,13 @@ bool DefaultSearchPolicyHandler::CheckIndividualPolicies( const PolicyMap& policies, PolicyErrorMap* errors) { + bool all_ok = true; for (const auto& handler : handlers_) { - if (!handler->CheckPolicySettings(policies, errors)) - return false; + // It's important to call CheckPolicySettings() on all handlers and not just + // exit on the first error, so we report all policy errors. + all_ok &= handler->CheckPolicySettings(policies, errors); } - return true; + return all_ok; } bool DefaultSearchPolicyHandler::HasDefaultSearchPolicy(
diff --git a/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java b/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java index 679b2111..0804e14 100644 --- a/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java +++ b/components/spellcheck/browser/android/java/src/org/chromium/components/spellcheck/SpellCheckerSessionBridge.java
@@ -100,6 +100,12 @@ ArrayList<Integer> lengths = new ArrayList<Integer>(); for (SentenceSuggestionsInfo result : results) { + if (result == null) { + // In some cases null can be returned by the selected spellchecking service, + // see crbug.com/651458. In this case skip to next result to avoid a + // NullPointerException later on. + continue; + } for (int i = 0; i < result.getSuggestionsCount(); i++) { // If a word looks like a typo, record its offset and length. if ((result.getSuggestionsInfoAt(i).getSuggestionsAttributes()
diff --git a/components/sync/engine_impl/syncer.cc b/components/sync/engine_impl/syncer.cc index 3b783c2a..76b7da3 100644 --- a/components/sync/engine_impl/syncer.cc +++ b/components/sync/engine_impl/syncer.cc
@@ -7,30 +7,22 @@ #include <memory> #include "base/auto_reset.h" -#include "base/location.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "components/sync/base/cancelation_signal.h" -#include "components/sync/base/syncer_error.h" -#include "components/sync/base/unique_position.h" #include "components/sync/engine_impl/apply_control_data_updates.h" #include "components/sync/engine_impl/clear_server_data.h" #include "components/sync/engine_impl/commit.h" #include "components/sync/engine_impl/commit_processor.h" #include "components/sync/engine_impl/cycle/nudge_tracker.h" +#include "components/sync/engine_impl/cycle/sync_cycle.h" #include "components/sync/engine_impl/get_updates_delegate.h" #include "components/sync/engine_impl/get_updates_processor.h" #include "components/sync/engine_impl/net/server_connection_manager.h" #include "components/sync/syncable/directory.h" #include "components/sync/syncable/mutable_entry.h" -using base::Time; -using base::TimeDelta; -using sync_pb::ClientCommand; - namespace syncer { // TODO(akalin): We may want to propagate this switch up @@ -145,7 +137,7 @@ return !ExitRequested(); } -SyncerError Syncer::BuildAndPostCommits(ModelTypeSet requested_types, +SyncerError Syncer::BuildAndPostCommits(ModelTypeSet request_types, NudgeTracker* nudge_tracker, SyncCycle* cycle, CommitProcessor* commit_processor) { @@ -154,7 +146,7 @@ // However, it doesn't hurt to check it anyway. while (!ExitRequested()) { std::unique_ptr<Commit> commit( - Commit::Init(requested_types, cycle->context()->GetEnabledTypes(), + Commit::Init(request_types, cycle->context()->GetEnabledTypes(), cycle->context()->max_commit_batch_size(), cycle->context()->account_name(), cycle->context()->directory()->cache_guid(),
diff --git a/components/sync/engine_impl/syncer.h b/components/sync/engine_impl/syncer.h index 1d40991..dcea8f7 100644 --- a/components/sync/engine_impl/syncer.h +++ b/components/sync/engine_impl/syncer.h
@@ -7,24 +7,21 @@ #include <stdint.h> -#include <utility> #include <vector> -#include "base/callback.h" #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "base/synchronization/lock.h" -#include "components/sync/base/extensions_activity.h" #include "components/sync/base/model_type.h" -#include "components/sync/engine_impl/conflict_resolver.h" -#include "components/sync/engine_impl/cycle/sync_cycle.h" -#include "components/sync/engine_impl/syncer_types.h" +#include "components/sync/base/syncer_error.h" +#include "components/sync/protocol/sync.pb.h" namespace syncer { class CancelationSignal; class CommitProcessor; class GetUpdatesProcessor; +class NudgeTracker; +class SyncCycle; // A Syncer provides a control interface for driving the sync cycle. These // cycles consist of downloading updates, parsing the response (aka. process
diff --git a/components/sync/engine_impl/syncer_unittest.cc b/components/sync/engine_impl/syncer_unittest.cc index 34b2564..2acd8e0c 100644 --- a/components/sync/engine_impl/syncer_unittest.cc +++ b/components/sync/engine_impl/syncer_unittest.cc
@@ -28,6 +28,7 @@ #include "build/build_config.h" #include "components/sync/base/cancelation_signal.h" #include "components/sync/base/cryptographer.h" +#include "components/sync/base/extensions_activity.h" #include "components/sync/base/fake_encryptor.h" #include "components/sync/base/time.h" #include "components/sync/engine/cycle/commit_counters.h" @@ -44,7 +45,6 @@ #include "components/sync/protocol/bookmark_specifics.pb.h" #include "components/sync/protocol/nigori_specifics.pb.h" #include "components/sync/protocol/preference_specifics.pb.h" -#include "components/sync/protocol/sync.pb.h" #include "components/sync/syncable/mutable_entry.h" #include "components/sync/syncable/nigori_util.h" #include "components/sync/syncable/syncable_delete_journal.h" @@ -302,7 +302,7 @@ syncer_)); syncable::ReadTransaction trans(FROM_HERE, directory()); - syncable::Directory::Metahandles children; + Directory::Metahandles children; directory()->GetChildHandlesById(&trans, trans.root_id(), &children); ASSERT_EQ(0u, children.size()); root_id_ = TestIdFactory::root(); @@ -529,7 +529,7 @@ mock_server_->ExpectGetUpdatesRequestTypes(enabled_datatypes_); } - Cryptographer* GetCryptographer(syncable::BaseTransaction* trans) { + Cryptographer* GetCryptographer(BaseTransaction* trans) { return directory()->GetCryptographer(trans); } @@ -629,7 +629,7 @@ { // Nothing should have been committed as bookmarks is throttled. syncable::ReadTransaction rtrans(FROM_HERE, directory()); - Entry entryA(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(1)); + Entry entryA(&rtrans, GET_BY_ID, ids_.FromNumber(1)); ASSERT_TRUE(entryA.good()); EXPECT_TRUE(entryA.GetIsUnsynced()); } @@ -640,7 +640,7 @@ { // It should have been committed. syncable::ReadTransaction rtrans(FROM_HERE, directory()); - Entry entryA(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(1)); + Entry entryA(&rtrans, GET_BY_ID, ids_.FromNumber(1)); ASSERT_TRUE(entryA.good()); EXPECT_FALSE(entryA.GetIsUnsynced()); } @@ -759,7 +759,7 @@ #define VERIFY_ENTRY(id, is_unapplied, is_unsynced, prev_initialized, \ parent_id, version, server_version, id_fac, rtrans) \ do { \ - Entry entryA(rtrans, syncable::GET_BY_ID, id_fac.FromNumber(id)); \ + Entry entryA(rtrans, GET_BY_ID, id_fac.FromNumber(id)); \ ASSERT_TRUE(entryA.good()); \ /* We don't use EXPECT_EQ here because if the left side param is false,*/ \ /* gcc 4.6 warns converting 'false' to pointer type for argument 1.*/ \ @@ -1005,7 +1005,7 @@ { // Run GetCommitIds, the function being tested. - syncable::Directory::Metahandles result_handles; + Directory::Metahandles result_handles; syncable::ReadTransaction trans(FROM_HERE, directory()); GetCommitIdsForType(&trans, BOOKMARKS, 100, &result_handles); @@ -1051,7 +1051,7 @@ { // Run GetCommitIds with a limit of 2 entries to commit. - syncable::Directory::Metahandles result_handles; + Directory::Metahandles result_handles; syncable::ReadTransaction trans(FROM_HERE, directory()); GetCommitIdsForType(&trans, BOOKMARKS, 2, &result_handles); @@ -1118,13 +1118,13 @@ VERIFY_ENTRY(3, false, false, false, 1, 10, 10, ids_, &rtrans); VERIFY_ENTRY(4, false, false, false, 0, 10, 10, ids_, &rtrans); - Entry entry1(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(1)); + Entry entry1(&rtrans, GET_BY_ID, ids_.FromNumber(1)); ASSERT_TRUE( entry1.GetUniquePosition().Equals(entry1.GetServerUniquePosition())); pos1 = entry1.GetUniquePosition(); - Entry entry2(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(2)); + Entry entry2(&rtrans, GET_BY_ID, ids_.FromNumber(2)); pos2 = entry2.GetUniquePosition(); - Entry entry3(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(3)); + Entry entry3(&rtrans, GET_BY_ID, ids_.FromNumber(3)); pos3 = entry3.GetUniquePosition(); } @@ -1292,7 +1292,7 @@ EXPECT_EQ(child_id_, mock_server_->committed_ids()[1]); { syncable::ReadTransaction rt(FROM_HERE, directory()); - Entry entry(&rt, syncable::GET_BY_ID, child_id_); + Entry entry(&rt, GET_BY_ID, child_id_); ASSERT_TRUE(entry.good()); VerifyTestDataInEntry(&rt, &entry); } @@ -1339,14 +1339,14 @@ EXPECT_EQ(child_id_, mock_server_->committed_ids()[1]); { syncable::ReadTransaction rt(FROM_HERE, directory()); - Entry entry(&rt, syncable::GET_BY_ID, child_id_); + Entry entry(&rt, GET_BY_ID, child_id_); ASSERT_TRUE(entry.good()); VerifyTestDataInEntry(&rt, &entry); } directory()->SaveChanges(); { syncable::ReadTransaction rt(FROM_HERE, directory()); - Entry entry(&rt, syncable::GET_BY_ID, pref_node_id); + Entry entry(&rt, GET_BY_ID, pref_node_id); ASSERT_FALSE(entry.good()); } } @@ -1373,7 +1373,7 @@ directory()->SaveChanges(); { syncable::ReadTransaction rt(FROM_HERE, directory()); - Entry entry(&rt, syncable::GET_BY_ID, parent_id_); + Entry entry(&rt, GET_BY_ID, parent_id_); ASSERT_FALSE(entry.good()); } } @@ -1866,13 +1866,13 @@ { syncable::ReadTransaction rtrans(FROM_HERE, directory()); // Check that things committed correctly. - Entry entry_1(&rtrans, syncable::GET_BY_ID, parent_id_); + Entry entry_1(&rtrans, GET_BY_ID, parent_id_); EXPECT_EQ(parent1_name, entry_1.GetNonUniqueName()); // Check that parent2 is a subfolder of parent1. EXPECT_EQ(1, CountEntriesWithName(&rtrans, parent_id_, parent2_name)); // Parent2 was a local ID and thus should have changed on commit! - Entry pre_commit_entry_parent2(&rtrans, syncable::GET_BY_ID, parent2_id); + Entry pre_commit_entry_parent2(&rtrans, GET_BY_ID, parent2_id); ASSERT_FALSE(pre_commit_entry_parent2.good()); // Look up the new ID. @@ -1880,7 +1880,7 @@ GetOnlyEntryWithName(&rtrans, parent_id_, parent2_name); EXPECT_TRUE(parent2_committed_id.ServerKnows()); - Entry child(&rtrans, syncable::GET_BY_ID, child_id); + Entry child(&rtrans, GET_BY_ID, child_id); EXPECT_EQ(parent2_committed_id, child.GetParentId()); } } @@ -1933,22 +1933,21 @@ { syncable::ReadTransaction rtrans(FROM_HERE, directory()); - Entry parent(&rtrans, syncable::GET_BY_ID, + Entry parent(&rtrans, GET_BY_ID, GetOnlyEntryWithName(&rtrans, rtrans.root_id(), parent_name)); ASSERT_TRUE(parent.good()); EXPECT_TRUE(parent.GetId().ServerKnows()); - Entry parent2(&rtrans, syncable::GET_BY_ID, + Entry parent2(&rtrans, GET_BY_ID, GetOnlyEntryWithName(&rtrans, parent.GetId(), parent2_name)); ASSERT_TRUE(parent2.good()); EXPECT_TRUE(parent2.GetId().ServerKnows()); // Id changed on commit, so this should fail. - Entry local_parent2_id_entry(&rtrans, syncable::GET_BY_ID, - parent2_local_id); + Entry local_parent2_id_entry(&rtrans, GET_BY_ID, parent2_local_id); ASSERT_FALSE(local_parent2_id_entry.good()); - Entry entry_b(&rtrans, syncable::GET_BY_HANDLE, meta_handle_b); + Entry entry_b(&rtrans, GET_BY_HANDLE, meta_handle_b); EXPECT_TRUE(entry_b.GetId().ServerKnows()); EXPECT_TRUE(parent2.GetId() == entry_b.GetParentId()); } @@ -2181,7 +2180,7 @@ syncable::Id entry_id; { syncable::ReadTransaction trans(FROM_HERE, directory()); - Entry entry(&trans, syncable::GET_BY_HANDLE, metahandle_entry); + Entry entry(&trans, GET_BY_HANDLE, metahandle_entry); ASSERT_TRUE(entry.good()); EXPECT_EQ(folder_id, entry.GetParentId()); EXPECT_EQ("new_entry", entry.GetNonUniqueName()); @@ -2223,7 +2222,7 @@ EXPECT_FALSE(old_dead_folder.good()); // The child's parent should have changed. - Entry entry(&trans, syncable::GET_BY_HANDLE, metahandle_entry); + Entry entry(&trans, GET_BY_HANDLE, metahandle_entry); ASSERT_TRUE(entry.good()); EXPECT_EQ("new_entry", entry.GetNonUniqueName()); EXPECT_EQ(new_folder_id, entry.GetParentId()); @@ -2454,7 +2453,7 @@ void CreateFolderInBob() { WriteTransaction trans(FROM_HERE, UNITTEST, directory()); MutableEntry bob( - &trans, syncable::GET_BY_ID, + &trans, GET_BY_ID, GetOnlyEntryWithName(&trans, TestIdFactory::root(), "bob")); ASSERT_TRUE(bob.good()); @@ -2484,12 +2483,12 @@ { syncable::ReadTransaction trans(FROM_HERE, directory()); Entry parent_entry( - &trans, syncable::GET_BY_ID, + &trans, GET_BY_ID, GetOnlyEntryWithName(&trans, TestIdFactory::root(), "bob")); ASSERT_TRUE(parent_entry.good()); Id child_id = GetOnlyEntryWithName(&trans, parent_entry.GetId(), "bob"); - Entry child(&trans, syncable::GET_BY_ID, child_id); + Entry child(&trans, GET_BY_ID, child_id); ASSERT_TRUE(child.good()); EXPECT_EQ(parent_entry.GetId(), child.GetParentId()); } @@ -2564,12 +2563,12 @@ local_cache_guid(), local_id.GetServerId()); mock_server_->set_conflict_all_commits(true); EXPECT_FALSE(SyncShareNudge()); - syncable::Directory::Metahandles children; + Directory::Metahandles children; { syncable::ReadTransaction trans(FROM_HERE, directory()); directory()->GetChildHandlesById(&trans, parent_id_, &children); // We expect the conflict resolver to preserve the local entry. - Entry child(&trans, syncable::GET_BY_ID, child_id_); + Entry child(&trans, GET_BY_ID, child_id_); ASSERT_TRUE(child.good()); EXPECT_TRUE(child.GetIsUnsynced()); EXPECT_FALSE(child.GetIsUnappliedUpdate()); @@ -2605,7 +2604,7 @@ int64_t version; { syncable::ReadTransaction trans(FROM_HERE, directory()); - Entry entry(&trans, syncable::GET_BY_HANDLE, entry_metahandle); + Entry entry(&trans, GET_BY_HANDLE, entry_metahandle); ASSERT_TRUE(entry.good()); id = entry.GetId(); EXPECT_TRUE(id.ServerKnows()); @@ -2621,7 +2620,7 @@ EXPECT_TRUE(SyncShareNudge()); { syncable::ReadTransaction trans(FROM_HERE, directory()); - Entry entry(&trans, syncable::GET_BY_ID, id); + Entry entry(&trans, GET_BY_ID, id); ASSERT_TRUE(entry.good()); EXPECT_EQ(test_time, entry.GetMtime()); } @@ -2679,7 +2678,7 @@ std::vector<int64_t> unapplied; directory()->GetUnappliedUpdateMetaHandles(&trans, all_types, &unapplied); EXPECT_EQ(0u, unapplied.size()); - syncable::Directory::Metahandles unsynced; + Directory::Metahandles unsynced; directory()->GetUnsyncedMetaHandles(&trans, &unsynced); EXPECT_EQ(0u, unsynced.size()); } @@ -3004,7 +3003,7 @@ SyncShareConfigure(); { syncable::ReadTransaction trans(FROM_HERE, directory()); - Entry entry(&trans, syncable::GET_BY_HANDLE, newfolder_metahandle); + Entry entry(&trans, GET_BY_HANDLE, newfolder_metahandle); ASSERT_TRUE(entry.good()); } } @@ -4000,10 +3999,10 @@ EXPECT_TRUE(SyncShareNudge()); { syncable::ReadTransaction rtrans(FROM_HERE, directory()); - Entry good_entry(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(1)); + Entry good_entry(&rtrans, GET_BY_ID, ids_.FromNumber(1)); ASSERT_TRUE(good_entry.good()); EXPECT_FALSE(good_entry.GetIsUnappliedUpdate()); - Entry bad_parent(&rtrans, syncable::GET_BY_ID, ids_.FromNumber(2)); + Entry bad_parent(&rtrans, GET_BY_ID, ids_.FromNumber(2)); ASSERT_TRUE(bad_parent.good()); EXPECT_TRUE(bad_parent.GetIsUnappliedUpdate()); } @@ -4212,7 +4211,7 @@ } // Now read it back out and make sure the value is max int64_t. syncable::ReadTransaction rtrans(FROM_HERE, directory()); - Entry entry(&rtrans, syncable::GET_BY_HANDLE, item_metahandle); + Entry entry(&rtrans, GET_BY_HANDLE, item_metahandle); ASSERT_TRUE(entry.good()); EXPECT_EQ(really_big_int, entry.GetBaseVersion()); } @@ -4560,7 +4559,7 @@ Entry pref_root(&trans, GET_TYPE_ROOT, PREFERENCES); ASSERT_TRUE(pref_root.good()); - syncable::Directory::Metahandles children; + Directory::Metahandles children; directory()->GetChildHandlesById(&trans, pref_root.GetId(), &children); ASSERT_EQ(2U, children.size()); } @@ -4604,7 +4603,7 @@ Entry pref_root(&trans, GET_TYPE_ROOT, PREFERENCES); ASSERT_TRUE(pref_root.good()); - syncable::Directory::Metahandles children; + Directory::Metahandles children; directory()->GetChildHandlesById(&trans, pref_root.GetId(), &children); ASSERT_EQ(2U, children.size()); } @@ -4689,7 +4688,7 @@ ASSERT_TRUE(pref_root.good()); // Verify that we have exactly 3 tagged nodes under the type root. - syncable::Directory::Metahandles children; + Directory::Metahandles children; directory()->GetChildHandlesById(&trans, pref_root.GetId(), &children); ASSERT_EQ(3U, children.size()); } @@ -4749,7 +4748,7 @@ ASSERT_TRUE(pref_entry.GetParentId().IsNull()); // Verify that there is still one node under the type root. - syncable::Directory::Metahandles children; + Directory::Metahandles children; directory()->GetChildHandlesById(&trans, pref_root_id, &children); ASSERT_EQ(1U, children.size()); } @@ -5011,7 +5010,7 @@ { syncable::ReadTransaction trans(FROM_HERE, directory()); - syncable::Entry root(&trans, syncable::GET_TYPE_ROOT, PREFERENCES); + Entry root(&trans, GET_TYPE_ROOT, PREFERENCES); EXPECT_TRUE(root.good()); }
diff --git a/components/sync/engine_impl/syncer_util_unittest.cc b/components/sync/engine_impl/syncer_util_unittest.cc index 1ceeb1b0..89148c1d0 100644 --- a/components/sync/engine_impl/syncer_util_unittest.cc +++ b/components/sync/engine_impl/syncer_util_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/message_loop/message_loop.h" #include "base/rand_util.h" #include "components/sync/base/unique_position.h" #include "components/sync/core/test/test_entry_factory.h"
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index a8e8660..d46acd2 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc
@@ -32,6 +32,7 @@ #include "base/path_service.h" #include "base/process/launch.h" #include "base/process/memory.h" +#include "base/process/process.h" #include "base/process/process_handle.h" #include "base/profiler/scoped_tracker.h" #include "base/strings/string_number_conversions.h" @@ -142,12 +143,8 @@ // Ensure any field trials in browser are reflected into the child // process. - if (command_line.HasSwitch(switches::kForceFieldTrials)) { - bool result = base::FieldTrialList::CreateTrialsFromString( - command_line.GetSwitchValueASCII(switches::kForceFieldTrials), - std::set<std::string>()); - DCHECK(result); - } + base::FieldTrialList::CreateTrialsFromCommandLine( + command_line, switches::kFieldTrialHandle); std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); feature_list->InitializeFromCommandLine(
diff --git a/content/browser/DEPS b/content/browser/DEPS index ce4c81d..64329ac 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS
@@ -59,12 +59,14 @@ "+third_party/WebKit/public/platform/WebFocusType.h", "+third_party/WebKit/public/platform/WebGamepad.h", "+third_party/WebKit/public/platform/WebGamepads.h", + "+third_party/WebKit/public/platform/WebInputEvent.h", "+third_party/WebKit/public/platform/WebInsecureRequestPolicy.h", "+third_party/WebKit/public/platform/WebNavigationHintType.h", "+third_party/WebKit/public/platform/WebReferrerPolicy.h", "+third_party/WebKit/public/platform/WebScreenInfo.h", "+third_party/WebKit/public/platform/WebSecurityStyle.h", "+third_party/WebKit/public/platform/WebString.h", + "+third_party/WebKit/public/platform/WebTextInputType.h", "+third_party/WebKit/public/platform/mime_registry.mojom.h", "+third_party/WebKit/public/platform/modules/background_sync/background_sync.mojom.h", "+third_party/WebKit/public/platform/modules/broadcastchannel/broadcast_channel.mojom.h", @@ -108,7 +110,6 @@ "+third_party/WebKit/public/web/WebSharedWorkerCreationContextType.h", "+third_party/WebKit/public/web/WebSharedWorkerCreationErrors.h", "+third_party/WebKit/public/web/WebTextDirection.h", - "+third_party/WebKit/public/web/WebTextInputType.h", "+third_party/WebKit/public/web/WebTreeScopeType.h", "+third_party/WebKit/public/web/mac/WebScrollbarTheme.h",
diff --git a/content/browser/android/web_contents_observer_proxy.cc b/content/browser/android/web_contents_observer_proxy.cc index b9e23ac..ca274f8 100644 --- a/content/browser/android/web_contents_observer_proxy.cc +++ b/content/browser/android/web_contents_observer_proxy.cc
@@ -306,9 +306,17 @@ jstring_url); } -void WebContentsObserverProxy::MediaSessionStateChanged( - bool is_controllable, - bool is_suspended, +void WebContentsObserverProxy::MediaSessionStateChanged(bool is_controllable, + bool is_suspended) { + JNIEnv* env = AttachCurrentThread(); + + ScopedJavaLocalRef<jobject> obj(java_observer_); + + Java_WebContentsObserverProxy_mediaSessionStateChanged( + env, obj, is_controllable, is_suspended); +} + +void WebContentsObserverProxy::MediaSessionMetadataChanged( const base::Optional<MediaMetadata>& metadata) { JNIEnv* env = AttachCurrentThread(); @@ -318,8 +326,8 @@ if (metadata.has_value()) j_metadata = MediaMetadataAndroid::CreateJavaObject(env, metadata.value()); - Java_WebContentsObserverProxy_mediaSessionStateChanged( - env, obj, is_controllable, is_suspended, j_metadata); + Java_WebContentsObserverProxy_mediaSessionMetadataChanged(env, obj, + j_metadata); } void WebContentsObserverProxy::SetToBaseURLForDataURLIfNeeded(
diff --git a/content/browser/android/web_contents_observer_proxy.h b/content/browser/android/web_contents_observer_proxy.h index f6d546c6..0829acc 100644 --- a/content/browser/android/web_contents_observer_proxy.h +++ b/content/browser/android/web_contents_observer_proxy.h
@@ -72,9 +72,9 @@ void DidStartNavigationToPendingEntry( const GURL& url, ReloadType reload_type) override; - void MediaSessionStateChanged( - bool is_controllable, - bool is_suspended, + void MediaSessionStateChanged(bool is_controllable, + bool is_suspended) override; + void MediaSessionMetadataChanged( const base::Optional<MediaMetadata>& metadata) override; void SetToBaseURLForDataURLIfNeeded(std::string* url);
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index a8d19b0..bb6a646 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc
@@ -38,6 +38,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_data.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/mojo_channel_switches.h" #include "content/public/common/process_type.h" @@ -207,7 +208,8 @@ } // static -void BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags( +std::unique_ptr<base::SharedMemory> +BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags( base::CommandLine* cmd_line) { std::string enabled_features; std::string disabled_features; @@ -220,17 +222,14 @@ // If we run base::FieldTrials, we want to pass to their state to the // child process so that it can act in accordance with each state. - std::string field_trial_states; - base::FieldTrialList::AllStatesToString(&field_trial_states); - if (!field_trial_states.empty()) { - cmd_line->AppendSwitchASCII(switches::kForceFieldTrials, - field_trial_states); - } + return base::FieldTrialList::CopyFieldTrialStateToFlags( + switches::kFieldTrialHandle, cmd_line); } void BrowserChildProcessHostImpl::Launch( SandboxedProcessLauncherDelegate* delegate, base::CommandLine* cmd_line, + const base::SharedMemory* field_trial_state, bool terminate_on_shutdown) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -258,11 +257,7 @@ notify_child_disconnected_ = true; child_process_.reset(new ChildProcessLauncher( - delegate, - cmd_line, - data_.id, - this, - child_token_, + delegate, cmd_line, data_.id, this, field_trial_state, child_token_, base::Bind(&BrowserChildProcessHostImpl::OnMojoError, weak_factory_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()),
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h index c10b9adf..c88ec6e 100644 --- a/content/browser/browser_child_process_host_impl.h +++ b/content/browser/browser_child_process_host_impl.h
@@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "base/memory/shared_memory.h" #include "base/memory/weak_ptr.h" #include "base/process/process.h" #include "base/single_thread_task_runner.h" @@ -65,12 +66,14 @@ // Copies kEnableFeatures and kDisableFeatures to the command line. Generates // them from the FeatureList override state, to take into account overrides // from FieldTrials. - static void CopyFeatureAndFieldTrialFlags(base::CommandLine* cmd_line); + static std::unique_ptr<base::SharedMemory> CopyFeatureAndFieldTrialFlags( + base::CommandLine* cmd_line); // BrowserChildProcessHost implementation: bool Send(IPC::Message* message) override; void Launch(SandboxedProcessLauncherDelegate* delegate, base::CommandLine* cmd_line, + const base::SharedMemory* field_trial_state, bool terminate_on_shutdown) override; const ChildProcessData& GetData() const override; ChildProcessHost* GetHost() const override;
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc index 0d640fa..82d6744b 100644 --- a/content/browser/child_process_launcher.cc +++ b/content/browser/child_process_launcher.cc
@@ -121,6 +121,7 @@ #if defined(OS_ANDROID) base::ScopedFD ipcfd, #endif + const base::SharedMemory* field_trial_state, mojo::edk::ScopedPlatformHandle client_handle, base::CommandLine* cmd_line) { DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); @@ -152,6 +153,8 @@ } else { base::HandlesToInheritVector handles; handles.push_back(client_handle.get().handle); + if (field_trial_state) + handles.push_back(field_trial_state->handle().GetHandle()); cmd_line->AppendSwitchASCII( mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch, base::UintToString(base::win::HandleToUint32(handles[0]))); @@ -397,6 +400,7 @@ base::CommandLine* cmd_line, int child_process_id, Client* client, + const base::SharedMemory* field_trial_state, const std::string& mojo_child_token, const mojo::edk::ProcessErrorCallback& process_error_callback, bool terminate_on_shutdown) @@ -417,7 +421,7 @@ weak_factory_(this) { DCHECK(CalledOnValidThread()); CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); - Launch(delegate, cmd_line, child_process_id); + Launch(delegate, cmd_line, child_process_id, field_trial_state); } ChildProcessLauncher::~ChildProcessLauncher() { @@ -431,10 +435,10 @@ } } -void ChildProcessLauncher::Launch( - SandboxedProcessLauncherDelegate* delegate, - base::CommandLine* cmd_line, - int child_process_id) { +void ChildProcessLauncher::Launch(SandboxedProcessLauncherDelegate* delegate, + base::CommandLine* cmd_line, + int child_process_id, + const base::SharedMemory* field_trial_state) { DCHECK(CalledOnValidThread()); #if defined(OS_ANDROID) @@ -483,7 +487,7 @@ #if defined(OS_ANDROID) base::Passed(&ipcfd), #endif - base::Passed(&client_handle), cmd_line)); + field_trial_state, base::Passed(&client_handle), cmd_line)); } void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) {
diff --git a/content/browser/child_process_launcher.h b/content/browser/child_process_launcher.h index b0cf02ca..943aba2e 100644 --- a/content/browser/child_process_launcher.h +++ b/content/browser/child_process_launcher.h
@@ -7,6 +7,7 @@ #include "base/files/scoped_file.h" #include "base/macros.h" +#include "base/memory/shared_memory.h" #include "base/memory/weak_ptr.h" #include "base/process/kill.h" #include "base/process/launch.h" @@ -79,6 +80,7 @@ base::CommandLine* cmd_line, int child_process_id, Client* client, + const base::SharedMemory* field_trial_state, const std::string& mojo_child_token, const mojo::edk::ProcessErrorCallback& process_error_callback, bool terminate_on_shutdown = true); @@ -116,7 +118,8 @@ // Posts a task to the launcher thread to do the actual work. void Launch(SandboxedProcessLauncherDelegate* delegate, base::CommandLine* cmd_line, - int child_process_id); + int child_process_id, + const base::SharedMemory* field_trial_state); void UpdateTerminationStatus(bool known_dead);
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index 4ccab78..7259036a 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -1898,7 +1898,7 @@ "document.body.appendChild(iframe);"; EXPECT_TRUE(ExecuteScript(root, script)); } - EXPECT_TRUE(subframe_delayer.WaitForWillStartRequest()); + EXPECT_TRUE(subframe_delayer.WaitForRequestStart()); // Stop the request so that we can wait for load stop below, without ending up // with a commit for this frame. @@ -4568,7 +4568,7 @@ // second page, though, causes it to do a replaceState(). TestNavigationManager manager(shell()->web_contents(), start_url); controller.GoBack(); - EXPECT_TRUE(manager.WaitForWillStartRequest()); + EXPECT_TRUE(manager.WaitForRequestStart()); // The navigation that just happened was the replaceState(), which should not // have changed the position into the navigation entry list. Make sure that @@ -5491,9 +5491,9 @@ frame_url_a2); TestNavigationManager mainframe_delayer(shell()->web_contents(), url_b); controller.GoForward(); - EXPECT_TRUE(subframe_delayer.WaitForWillStartRequest()); + EXPECT_TRUE(subframe_delayer.WaitForRequestStart()); controller.GoForward(); - EXPECT_TRUE(mainframe_delayer.WaitForWillStartRequest()); + EXPECT_TRUE(mainframe_delayer.WaitForRequestStart()); EXPECT_EQ(2, controller.GetPendingEntryIndex()); // Let the subframe commit. @@ -5543,7 +5543,7 @@ TestNavigationManager delayer(shell()->web_contents(), embedded_test_server()->GetURL("/title3.html")); shell()->LoadURL(embedded_test_server()->GetURL("/title3.html")); - EXPECT_TRUE(delayer.WaitForWillStartRequest()); + EXPECT_TRUE(delayer.WaitForRequestStart()); NavigationController& controller = shell()->web_contents()->GetController();
diff --git a/content/browser/frame_host/navigation_handle_impl_browsertest.cc b/content/browser/frame_host/navigation_handle_impl_browsertest.cc index 37bfde7..ff6e2d5 100644 --- a/content/browser/frame_host/navigation_handle_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_handle_impl_browsertest.cc
@@ -695,7 +695,7 @@ // Starts and verifies the main frame navigation. shell()->LoadURL(main_url); - EXPECT_TRUE(main_manager.WaitForWillStartRequest()); + EXPECT_TRUE(main_manager.WaitForRequestStart()); // The throttle should not be null. EXPECT_NE(previous_throttle, installer.navigation_throttle()); // Checks the only URL recorded so far is the one expected for the main frame. @@ -709,7 +709,7 @@ // Ditto for frame b navigation. main_manager.WaitForNavigationFinished(); - EXPECT_TRUE(b_manager.WaitForWillStartRequest()); + EXPECT_TRUE(b_manager.WaitForRequestStart()); EXPECT_NE(previous_throttle, installer.navigation_throttle()); EXPECT_EQ(b_url, url_recorder.urls().back()); EXPECT_EQ(2ul, url_recorder.urls().size()); @@ -719,7 +719,7 @@ // Ditto for frame c navigation. b_manager.WaitForNavigationFinished(); - EXPECT_TRUE(c_manager.WaitForWillStartRequest()); + EXPECT_TRUE(c_manager.WaitForRequestStart()); EXPECT_NE(previous_throttle, installer.navigation_throttle()); EXPECT_EQ(c_url, url_recorder.urls().back()); EXPECT_EQ(3ul, url_recorder.urls().size()); @@ -757,7 +757,7 @@ shell(), "window.domAutomationController.send(clickSameSiteLink());", &success)); EXPECT_TRUE(success); - EXPECT_TRUE(link_manager.WaitForWillStartRequest()); + EXPECT_TRUE(link_manager.WaitForRequestStart()); EXPECT_EQ(link_url, url_recorder.urls().back()); EXPECT_EQ(2ul, url_recorder.urls().size()); EXPECT_EQ(REQUEST_CONTEXT_TYPE_HYPERLINK, @@ -790,7 +790,7 @@ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); GURL submit_url("javascript:submitForm('isubmit')"); shell()->LoadURL(submit_url); - EXPECT_TRUE(post_manager.WaitForWillStartRequest()); + EXPECT_TRUE(post_manager.WaitForRequestStart()); EXPECT_EQ(post_url, url_recorder.urls().back()); EXPECT_EQ(2ul, url_recorder.urls().size()); EXPECT_EQ(REQUEST_CONTEXT_TYPE_FORM, @@ -823,7 +823,7 @@ // iframe_secure_url never happened and the expected upgrade may not be // working. shell()->LoadURL(start_url); - EXPECT_TRUE(navigation_manager.WaitForWillStartRequest()); + EXPECT_TRUE(navigation_manager.WaitForRequestStart()); // The main frame should have finished navigating while the iframe should // have just started.
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 42307944..d444801 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -970,8 +970,11 @@ base::CommandLine* cmd_line = new base::CommandLine(exe_path); #endif + cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kGpuProcess); - BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(cmd_line); + + field_trial_state_ = + BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(cmd_line); #if defined(OS_WIN) cmd_line->AppendArg(switches::kPrefetchArgumentGpu); @@ -1015,10 +1018,8 @@ cmd_line->PrependWrapper(gpu_launcher); process_->Launch( - new GpuSandboxedProcessLauncherDelegate(cmd_line, - process_->GetHost()), - cmd_line, - true); + new GpuSandboxedProcessLauncherDelegate(cmd_line, process_->GetHost()), + cmd_line, field_trial_state_.get(), true); process_launched_ = true; UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index d42c354..c8e66825 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h
@@ -292,6 +292,12 @@ std::string shader_prefix_key_; + // Anonymous shared memory segment to share with subprocess containing list of + // field trials (represented as a string). + // TODO(crbug.com/653874): Eventually remove this and use single shared memory + // object across processes. + std::unique_ptr<base::SharedMemory> field_trial_state_; + DISALLOW_COPY_AND_ASSIGN(GpuProcessHost); };
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 14bfe17..29092f2 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1031,10 +1031,11 @@ GlobalRequestID id(filter_->child_id(), request_id); DelegateMap::iterator it = delegate_map_.find(id); if (it != delegate_map_.end()) { - base::ObserverList<ResourceMessageDelegate>::Iterator del_it(it->second); - ResourceMessageDelegate* delegate; - while (!handled && (delegate = del_it.GetNext()) != NULL) { - handled = delegate->OnMessageReceived(message); + for (auto& delegate : *it->second) { + if (delegate.OnMessageReceived(message)) { + handled = true; + break; + } } } @@ -1170,11 +1171,8 @@ DelegateMap::iterator it = delegate_map_.find(old_request_id); if (it != delegate_map_.end()) { // Tell each delegate that the request ID has changed. - base::ObserverList<ResourceMessageDelegate>::Iterator del_it(it->second); - ResourceMessageDelegate* delegate; - while ((delegate = del_it.GetNext()) != NULL) { - delegate->set_request_id(new_request_id); - } + for (auto& delegate : *it->second) + delegate.set_request_id(new_request_id); // Now store the observer list under the new request ID. delegate_map_[new_request_id] = delegate_map_[old_request_id]; delegate_map_.erase(old_request_id);
diff --git a/content/browser/media/encrypted_media_browsertest.cc b/content/browser/media/encrypted_media_browsertest.cc index aec2165..019f3d2 100644 --- a/content/browser/media/encrypted_media_browsertest.cc +++ b/content/browser/media/encrypted_media_browsertest.cc
@@ -206,7 +206,14 @@ TestConfigChange(); } -IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, FrameSizeChangeVideo) { +#if defined(OS_ANDROID) +// Flaky on android: https://crbug.com/655630 +#define MAYBE_FrameSizeChangeVideo DISABLED_FrameSizeChangeVideo +#else +#define MAYBE_FrameSizeChangeVideo FrameSizeChangeVideo +#endif + +IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, MAYBE_FrameSizeChangeVideo) { TestFrameSizeChange(); } #endif // !defined(DISABLE_ENCRYPTED_MEDIA_PLAYBACK_TESTS)
diff --git a/content/browser/media/session/media_session.cc b/content/browser/media/session/media_session.cc index 147b337..aa165b9 100644 --- a/content/browser/media/session/media_session.cc +++ b/content/browser/media/session/media_session.cc
@@ -75,10 +75,8 @@ void MediaSession::SetMetadata(const base::Optional<MediaMetadata>& metadata) { metadata_ = metadata; - // TODO(zqzhang): On Android, the metadata is sent though JNI everytime the - // media session play/pause state changes. Need to find a way to seprate the - // state change and Metadata update. See https://crbug.com/621855. - static_cast<WebContentsImpl*>(web_contents())->OnMediaSessionStateChanged(); + static_cast<WebContentsImpl*>(web_contents()) + ->OnMediaSessionMetadataChanged(); } bool MediaSession::AddPlayer(MediaSessionObserver* observer,
diff --git a/content/browser/media/session/media_session_browsertest.cc b/content/browser/media/session/media_session_browsertest.cc index 629c562..959bead1 100644 --- a/content/browser/media/session/media_session_browsertest.cc +++ b/content/browser/media/session/media_session_browsertest.cc
@@ -52,9 +52,8 @@ MockWebContentsObserver(WebContents* web_contents) : WebContentsObserver(web_contents) {} - MOCK_METHOD3(MediaSessionStateChanged, - void(bool is_controllable, bool is_suspended, - const base::Optional<content::MediaMetadata>& metadata)); + MOCK_METHOD2(MediaSessionStateChanged, + void(bool is_controllable, bool is_suspended)); }; } // namespace @@ -588,7 +587,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsShowForContent) { EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); std::unique_ptr<MockMediaSessionObserver> media_session_observer( new MockMediaSessionObserver); @@ -603,7 +602,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsNoShowForTransient) { EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(false, false, testing::_)); + MediaSessionStateChanged(false, false)); std::unique_ptr<MockMediaSessionObserver> media_session_observer( new MockMediaSessionObserver); @@ -618,9 +617,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsHideWhenStopped) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(false, true, testing::_)) + MediaSessionStateChanged(false, true)) .After(showControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -637,7 +636,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsShownAcceptTransient) { EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); std::unique_ptr<MockMediaSessionObserver> media_session_observer( new MockMediaSessionObserver); @@ -655,10 +654,10 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsShownAfterContentAdded) { - Expectation dontShowControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(false, false, testing::_)); + Expectation dontShowControls = EXPECT_CALL( + *mock_web_contents_observer(), MediaSessionStateChanged(false, false)); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)) + MediaSessionStateChanged(true, false)) .After(dontShowControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -678,7 +677,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsStayIfOnlyOnePlayerHasBeenPaused) { EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); std::unique_ptr<MockMediaSessionObserver> media_session_observer( new MockMediaSessionObserver); @@ -699,9 +698,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsHideWhenTheLastPlayerIsRemoved) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(false, true, testing::_)) + MediaSessionStateChanged(false, true)) .After(showControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( new MockMediaSessionObserver); @@ -725,9 +724,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsHideWhenAllThePlayersAreRemoved) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(false, true, testing::_)) + MediaSessionStateChanged(false, true)) .After(showControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -747,9 +746,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsNotHideWhenTheLastPlayerIsPaused) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)) + MediaSessionStateChanged(true, true)) .After(showControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -774,9 +773,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, SuspendTemporaryUpdatesControls) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)) + MediaSessionStateChanged(true, true)) .After(showControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -793,11 +792,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsUpdatedWhenResumed) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)).After(showControls); + MediaSessionStateChanged(true, true)) + .After(showControls); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)) + MediaSessionStateChanged(true, false)) .After(pauseControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -815,9 +815,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsHideWhenSessionSuspendedPermanently) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(false, true, testing::_)) + MediaSessionStateChanged(false, true)) .After(showControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -835,11 +835,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ConstrolsHideWhenSessionStops) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)).After(showControls); + MediaSessionStateChanged(true, true)) + .After(showControls); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(false, true, testing::_)) + MediaSessionStateChanged(false, true)) .After(pauseControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -857,11 +858,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsHideWhenSessionChangesFromContentToTransient) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)).After(showControls); + MediaSessionStateChanged(true, true)) + .After(showControls); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(false, false, testing::_)) + MediaSessionStateChanged(false, false)) .After(pauseControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -883,11 +885,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsUpdatedWhenNewPlayerResetsSession) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)).After(showControls); + MediaSessionStateChanged(true, true)) + .After(showControls); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)) + MediaSessionStateChanged(true, false)) .After(pauseControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -908,11 +911,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsResumedWhenPlayerIsResumed) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)).After(showControls); + MediaSessionStateChanged(true, true)) + .After(showControls); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)) + MediaSessionStateChanged(true, false)) .After(pauseControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -933,9 +937,9 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsUpdatedDueToResumeSessionAction) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)) + MediaSessionStateChanged(true, true)) .After(showControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer( @@ -952,11 +956,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, ControlsUpdatedDueToSuspendSessionAction) { Expectation showControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)); + MediaSessionStateChanged(true, false)); Expectation pauseControls = EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, true, testing::_)).After(showControls); + MediaSessionStateChanged(true, true)) + .After(showControls); EXPECT_CALL(*mock_web_contents_observer(), - MediaSessionStateChanged(true, false, testing::_)) + MediaSessionStateChanged(true, false)) .After(pauseControls); std::unique_ptr<MockMediaSessionObserver> media_session_observer(
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.cc b/content/browser/notifications/notification_event_dispatcher_impl.cc index 9eb1ade..5f097bc0 100644 --- a/content/browser/notifications/notification_event_dispatcher_impl.cc +++ b/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -203,6 +203,7 @@ const scoped_refptr<ServiceWorkerVersion>& service_worker, const NotificationDatabaseData& notification_database_data, int action_index, + const base::NullableString16& reply, const ServiceWorkerVersion::StatusCallback& callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); int request_id = service_worker->StartRequest( @@ -212,12 +213,13 @@ request_id, ServiceWorkerMsg_NotificationClickEvent( request_id, notification_database_data.notification_id, - notification_database_data.notification_data, action_index)); + notification_database_data.notification_data, action_index, reply)); } // Dispatches the notification click event on the |service_worker_registration|. void DoDispatchNotificationClickEvent( int action_index, + const base::NullableString16& reply, const NotificationDispatchCompleteCallback& dispatch_complete_callback, const scoped_refptr<PlatformNotificationContext>& notification_context, const ServiceWorkerRegistration* service_worker_registration, @@ -229,7 +231,7 @@ base::Bind( &DispatchNotificationClickEventOnWorker, make_scoped_refptr(service_worker_registration->active_version()), - notification_database_data, action_index, status_callback), + notification_database_data, action_index, reply, status_callback), status_callback); } @@ -360,10 +362,11 @@ const std::string& notification_id, const GURL& origin, int action_index, + const base::NullableString16& reply, const NotificationDispatchCompleteCallback& dispatch_complete_callback) { DispatchNotificationEvent( browser_context, notification_id, origin, - base::Bind(&DoDispatchNotificationClickEvent, action_index, + base::Bind(&DoDispatchNotificationClickEvent, action_index, reply, dispatch_complete_callback), dispatch_complete_callback); }
diff --git a/content/browser/notifications/notification_event_dispatcher_impl.h b/content/browser/notifications/notification_event_dispatcher_impl.h index 4c7f14d..a0b0399e 100644 --- a/content/browser/notifications/notification_event_dispatcher_impl.h +++ b/content/browser/notifications/notification_event_dispatcher_impl.h
@@ -24,6 +24,7 @@ const std::string& notification_id, const GURL& origin, int action_index, + const base::NullableString16& reply, const NotificationDispatchCompleteCallback& dispatch_complete_callback) override; void DispatchNotificationCloseEvent(
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index 1bdf4a96..b5e3335e 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc
@@ -444,11 +444,9 @@ // On posix, never use the zygote for the broker. Also, only use the zygote if // we are not using a plugin launcher - having a plugin launcher means we need // to use another process instead of just forking the zygote. - process_->Launch( - new PpapiPluginSandboxedProcessLauncherDelegate(is_broker_, - process_->GetHost()), - cmd_line, - true); + process_->Launch(new PpapiPluginSandboxedProcessLauncherDelegate( + is_broker_, process_->GetHost()), + cmd_line, nullptr, true); return true; }
diff --git a/content/browser/renderer_host/ime_adapter_android.cc b/content/browser/renderer_host/ime_adapter_android.cc index a49e2729..d441190 100644 --- a/content/browser/renderer_host/ime_adapter_android.cc +++ b/content/browser/renderer_host/ime_adapter_android.cc
@@ -29,9 +29,9 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" #include "jni/ImeAdapter_jni.h" +#include "third_party/WebKit/public/platform/WebInputEvent.h" +#include "third_party/WebKit/public/platform/WebTextInputType.h" #include "third_party/WebKit/public/web/WebCompositionUnderline.h" -#include "third_party/WebKit/public/web/WebInputEvent.h" -#include "third_party/WebKit/public/web/WebTextInputType.h" using base::android::AttachCurrentThread; using base::android::ConvertJavaStringToUTF16;
diff --git a/content/browser/renderer_host/input/touch_action_browsertest.cc b/content/browser/renderer_host/input/touch_action_browsertest.cc index 1c4a305e..33845ae9 100644 --- a/content/browser/renderer_host/input/touch_action_browsertest.cc +++ b/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -188,15 +188,11 @@ // Mac doesn't yet have a gesture recognizer, so can't support turning touch // events into scroll gestures. // Will be fixed with http://crbug.com/337142 -#if defined(OS_MACOSX) -#define MAYBE_DefaultAuto DISABLED_DefaultAuto -#else -#define MAYBE_DefaultAuto DefaultAuto -#endif +// Flaky on all platforms: https://crbug.com/376668 // // Verify the test infrastructure works - we can touch-scroll the page and get a // touchcancel as expected. -IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest, MAYBE_DefaultAuto) { +IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest, DISABLED_DefaultAuto) { LoadURL(); bool scrolled = DoTouchScroll(gfx::Point(50, 50), gfx::Vector2d(0, 45), true);
diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc index 28040d8c..b8aadb8 100644 --- a/content/browser/renderer_host/media/video_capture_manager.cc +++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -551,8 +551,9 @@ auto request = photo_request_queue_.begin(); while(request != photo_request_queue_.end()) { - if (GetDeviceEntryBySessionId(request->first)->video_capture_device()) { - request->second.Run(entry->video_capture_device()); + DeviceEntry* maybe_entry = GetDeviceEntryBySessionId(request->first); + if (maybe_entry && maybe_entry->video_capture_device()) { + request->second.Run(maybe_entry->video_capture_device()); photo_request_queue_.erase(request); } ++request;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 3c9fe8a..459e933 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -966,7 +966,7 @@ // at this stage. child_process_launcher_.reset(new ChildProcessLauncher( new RendererSandboxedProcessLauncherDelegate(channel_.get()), cmd_line, - GetID(), this, child_token_, + GetID(), this, field_trial_state_.get(), child_token_, base::Bind(&RenderProcessHostImpl::OnMojoError, id_))); channel_->Pause(); @@ -1579,7 +1579,7 @@ } void RenderProcessHostImpl::AppendRendererCommandLine( - base::CommandLine* command_line) const { + base::CommandLine* command_line) { // Pass the process type first, so it shows first in process listings. command_line->AppendSwitchASCII(switches::kProcessType, switches::kRendererProcess); @@ -1618,7 +1618,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( const base::CommandLine& browser_cmd, - base::CommandLine* renderer_cmd) const { + base::CommandLine* renderer_cmd) { // Propagate the following switches to the renderer command line (along // with any associated values) if present in the browser command line. static const char* const kSwitchNames[] = { @@ -1828,7 +1828,8 @@ renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames, arraysize(kSwitchNames)); - BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(renderer_cmd); + field_trial_state_ = + BrowserChildProcessHostImpl::CopyFeatureAndFieldTrialFlags(renderer_cmd); if (browser_cmd.HasSwitch(switches::kTraceStartup) && BrowserMainLoop::GetInstance()->is_tracing_startup_for_duration()) {
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index f07c487e..f97cd70a 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -336,14 +336,14 @@ // Generates a command line to be used to spawn a renderer and appends the // results to |*command_line|. - void AppendRendererCommandLine(base::CommandLine* command_line) const; + void AppendRendererCommandLine(base::CommandLine* command_line); // Copies applicable command line switches from the given |browser_cmd| line // flags to the output |renderer_cmd| line flags. Not all switches will be // copied over. void PropagateBrowserCommandLineToRenderer( const base::CommandLine& browser_cmd, - base::CommandLine* renderer_cmd) const; + base::CommandLine* renderer_cmd); // Inspects the current object state and sets/removes background priority if // appropriate. Should be called after any of the involved data members @@ -558,6 +558,12 @@ // The memory allocator, if any, in which the renderer will write its metrics. std::unique_ptr<base::SharedPersistentMemoryAllocator> metrics_allocator_; + // Anonymous shared memory segment to share with subprocess containing list of + // field trials (represented as a string). + // TODO(crbug.com/653874): Eventually remove this and use single shared memory + // object across processes. + std::unique_ptr<base::SharedMemory> field_trial_state_; + bool channel_connected_; bool sent_render_process_ready_;
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index 842a57a3..8e81ee9 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -775,9 +775,8 @@ } bool EmbeddedWorkerInstance::OnMessageReceived(const IPC::Message& message) { - ListenerList::Iterator it(&listener_list_); - while (Listener* listener = it.GetNext()) { - if (listener->OnMessageReceived(message)) + for (auto& listener : listener_list_) { + if (listener.OnMessageReceived(message)) return true; } return false;
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 9c9c424..5d97b9da 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -7960,7 +7960,7 @@ GURL stall_url(embedded_test_server()->GetURL("b.com", "/title2.html")); TestNavigationManager delayer(shell()->web_contents(), stall_url); shell()->LoadURL(stall_url); - EXPECT_TRUE(delayer.WaitForWillStartRequest()); + EXPECT_TRUE(delayer.WaitForRequestStart()); // The pending RFH should be in the same process as the popup. RenderFrameHostImpl* pending_rfh = @@ -8022,7 +8022,7 @@ GURL stall_url(embedded_test_server()->GetURL("b.com", "/title2.html")); TestNavigationManager delayer(shell()->web_contents(), stall_url); shell()->LoadURL(stall_url); - EXPECT_TRUE(delayer.WaitForWillStartRequest()); + EXPECT_TRUE(delayer.WaitForRequestStart()); // Kill the b.com process, currently in use by the pending RenderFrameHost // and the popup. @@ -8329,7 +8329,7 @@ cross_site_url_1); shell()->web_contents()->GetController().LoadURL( cross_site_url_1, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); - EXPECT_TRUE(cross_site_manager.WaitForWillProcessResponse()); + EXPECT_TRUE(cross_site_manager.WaitForResponse()); // Start a renderer-initiated navigation to a cross-process url and make sure // the navigation will be blocked before being transferred. @@ -8339,7 +8339,7 @@ cross_site_url_2); EXPECT_TRUE(ExecuteScript( root, "location.href = '" + cross_site_url_2.spec() + "';")); - EXPECT_TRUE(transfer_manager.WaitForWillProcessResponse()); + EXPECT_TRUE(transfer_manager.WaitForResponse()); // Now have the cross-process navigation commit and mark the current RFH as // pending deletion.
diff --git a/content/browser/utility_process_host_impl.cc b/content/browser/utility_process_host_impl.cc index 708a09d..8601a09c 100644 --- a/content/browser/utility_process_host_impl.cc +++ b/content/browser/utility_process_host_impl.cc
@@ -340,13 +340,10 @@ cmd_line->AppendSwitch(switches::kUtilityProcessRunningElevated); #endif - process_->Launch( - new UtilitySandboxedProcessLauncherDelegate(exposed_dir_, - run_elevated_, - no_sandbox_, env_, - process_->GetHost()), - cmd_line, - true); + process_->Launch(new UtilitySandboxedProcessLauncherDelegate( + exposed_dir_, run_elevated_, no_sandbox_, env_, + process_->GetHost()), + cmd_line, nullptr, true); } return true;
diff --git a/content/browser/web_contents/aura/gesture_nav_simple.cc b/content/browser/web_contents/aura/gesture_nav_simple.cc index 4ff4abe5..b826800 100644 --- a/content/browser/web_contents/aura/gesture_nav_simple.cc +++ b/content/browser/web_contents/aura/gesture_nav_simple.cc
@@ -110,10 +110,6 @@ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - const gfx::Image& image_; const bool left_arrow_;
diff --git a/content/browser/web_contents/aura/shadow_layer_delegate.cc b/content/browser/web_contents/aura/shadow_layer_delegate.cc index a4a1660..89ffa64 100644 --- a/content/browser/web_contents/aura/shadow_layer_delegate.cc +++ b/content/browser/web_contents/aura/shadow_layer_delegate.cc
@@ -4,7 +4,6 @@ #include "content/browser/web_contents/aura/shadow_layer_delegate.h" -#include "base/bind.h" #include "base/macros.h" #include "third_party/skia/include/effects/SkGradientShader.h" #include "ui/aura/window.h" @@ -59,8 +58,4 @@ void ShadowLayerDelegate::OnDeviceScaleFactorChanged(float scale_factor) { } -base::Closure ShadowLayerDelegate::PrepareForLayerBoundsChange() { - return base::Bind(&base::DoNothing); -} - } // namespace content
diff --git a/content/browser/web_contents/aura/shadow_layer_delegate.h b/content/browser/web_contents/aura/shadow_layer_delegate.h index 6c1729f..c3eab8e2 100644 --- a/content/browser/web_contents/aura/shadow_layer_delegate.h +++ b/content/browser/web_contents/aura/shadow_layer_delegate.h
@@ -37,7 +37,6 @@ void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; std::unique_ptr<ui::Layer> layer_;
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 6ceef42..9842629 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -675,16 +675,16 @@ return true; } - base::ObserverListBase<WebContentsObserver>::Iterator it(&observers_); - WebContentsObserver* observer; if (render_frame_host) { - while ((observer = it.GetNext()) != NULL) - if (observer->OnMessageReceived(message, render_frame_host)) + for (auto& observer : observers_) { + if (observer.OnMessageReceived(message, render_frame_host)) return true; + } } else { - while ((observer = it.GetNext()) != NULL) - if (observer->OnMessageReceived(message)) + for (auto& observer : observers_) { + if (observer.OnMessageReceived(message)) return true; + } } // Message handlers should be aware of which @@ -3818,10 +3818,17 @@ void WebContentsImpl::OnMediaSessionStateChanged() { MediaSession* session = MediaSession::Get(this); - FOR_EACH_OBSERVER(WebContentsObserver, observers_, - MediaSessionStateChanged(session->IsControllable(), - session->IsSuspended(), - session->metadata())); + for (auto& observer : observers_) { + observer.MediaSessionStateChanged(session->IsControllable(), + session->IsSuspended()); + } +} + +void WebContentsImpl::OnMediaSessionMetadataChanged() { + MediaSession* session = MediaSession::Get(this); + for (auto& observer : observers_) { + observer.MediaSessionMetadataChanged(session->metadata()); + } } void WebContentsImpl::ResumeMediaSession() {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 68278ee1..e57408e 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -414,7 +414,6 @@ void GetManifest(const GetManifestCallback& callback) override; void ExitFullscreen(bool will_cause_resize) override; void ResumeLoadingCreatedWebContents() override; - void OnMediaSessionStateChanged(); void ResumeMediaSession() override; void SuspendMediaSession() override; void StopMediaSession() override; @@ -432,6 +431,13 @@ bool GetAllowOtherViews() override; #endif + // This method is called when the MediaSession state has changed, and will + // notify the WebContents observers. + void OnMediaSessionStateChanged(); + // This method is called when the MediaSession metadata has changed, and will + // notify the WebContents observers. + void OnMediaSessionMetadataChanged(); + // Implementation of PageNavigator. WebContents* OpenURL(const OpenURLParams& params) override;
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 436d71b..a0f0555 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -899,17 +899,11 @@ // TODO(clamy): Make the test work on Windows and on Mac. On Mac and Windows, // there seem to be an issue with the ShellJavascriptDialogManager. -#if defined(OS_WIN) || defined(OS_MACOSX) -#define MAYBE_NoResetOnBeforeUnloadCanceledOnCommit \ - DISABLED_NoResetOnBeforeUnloadCanceledOnCommit -#else -#define MAYBE_NoResetOnBeforeUnloadCanceledOnCommit \ - NoResetOnBeforeUnloadCanceledOnCommit -#endif +// Flaky on all platforms: https://crbug.com/655628 // Test that if a BeforeUnload dialog is destroyed due to the commit of a // cross-site navigation, it will not reset the loading state. IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, - MAYBE_NoResetOnBeforeUnloadCanceledOnCommit) { + DISABLED_NoResetOnBeforeUnloadCanceledOnCommit) { ASSERT_TRUE(embedded_test_server()->Start()); const GURL kStartURL( embedded_test_server()->GetURL("/hang_before_unload.html")); @@ -923,7 +917,7 @@ TestNavigationManager cross_site_delayer(shell()->web_contents(), kCrossSiteURL); shell()->LoadURL(kCrossSiteURL); - EXPECT_TRUE(cross_site_delayer.WaitForWillStartRequest()); + EXPECT_TRUE(cross_site_delayer.WaitForRequestStart()); // Click on a link in the page. This will show the BeforeUnload dialog. // Ensure the dialog is not dismissed, which will cause it to still be
diff --git a/content/child/service_worker/web_service_worker_registration_impl.cc b/content/child/service_worker/web_service_worker_registration_impl.cc index ae2705ee..f9e18f9 100644 --- a/content/child/service_worker/web_service_worker_registration_impl.cc +++ b/content/child/service_worker/web_service_worker_registration_impl.cc
@@ -13,6 +13,7 @@ #include "content/child/service_worker/web_service_worker_impl.h" #include "content/child/service_worker/web_service_worker_provider_impl.h" #include "content/common/service_worker/service_worker_types.h" +#include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerError.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistrationProxy.h" namespace content { @@ -145,6 +146,24 @@ registration_id(), callbacks); } +void WebServiceWorkerRegistrationImpl::enableNavigationPreload( + WebEnableNavigationPreloadCallbacks* callbacks) { + std::unique_ptr<WebEnableNavigationPreloadCallbacks> owned_callbacks( + callbacks); + // TODO(falken): Implement this. + owned_callbacks->onError(blink::WebServiceWorkerError( + blink::WebServiceWorkerError::ErrorTypeAbort, "Not implemented")); +} + +void WebServiceWorkerRegistrationImpl::disableNavigationPreload( + WebDisableNavigationPreloadCallbacks* callbacks) { + std::unique_ptr<WebDisableNavigationPreloadCallbacks> owned_callbacks( + callbacks); + // TODO(falken): Implement this. + owned_callbacks->onError(blink::WebServiceWorkerError( + blink::WebServiceWorkerError::ErrorTypeAbort, "Not implemented")); +} + int64_t WebServiceWorkerRegistrationImpl::registration_id() const { return handle_ref_->registration_id(); }
diff --git a/content/child/service_worker/web_service_worker_registration_impl.h b/content/child/service_worker/web_service_worker_registration_impl.h index 49904748..7d6deade 100644 --- a/content/child/service_worker/web_service_worker_registration_impl.h +++ b/content/child/service_worker/web_service_worker_registration_impl.h
@@ -55,6 +55,10 @@ WebServiceWorkerUpdateCallbacks* callbacks) override; void unregister(blink::WebServiceWorkerProvider* provider, WebServiceWorkerUnregistrationCallbacks* callbacks) override; + void enableNavigationPreload( + WebEnableNavigationPreloadCallbacks* callbacks) override; + void disableNavigationPreload( + WebDisableNavigationPreloadCallbacks* callbacks) override; int64_t registration_id() const;
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h index 01ca941..37f2e18d 100644 --- a/content/common/service_worker/service_worker_messages.h +++ b/content/common/service_worker/service_worker_messages.h
@@ -487,11 +487,12 @@ IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_ExtendableMessageEvent, int /* request_id */, ServiceWorkerMsg_ExtendableMessageEvent_Params) -IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_NotificationClickEvent, +IPC_MESSAGE_CONTROL5(ServiceWorkerMsg_NotificationClickEvent, int /* request_id */, std::string /* notification_id */, content::PlatformNotificationData /* notification_data */, - int /* action_index */) + int /* action_index */, + base::NullableString16 /* notification reply */) IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_NotificationCloseEvent, int /* request_id */, std::string /* notification_id */,
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 682cc46..ee8ea271 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -56,10 +56,6 @@ "//ui/android:ui_java", ] - if (enable_webvr) { - deps += [ "//device/vr:java" ] - } - srcjar_deps = [ ":common_aidl", ":content_public_android_java_enums_srcjar",
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java index 2e9157f..f3e2c6a 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java
@@ -232,11 +232,17 @@ @Override @CalledByNative - public void mediaSessionStateChanged( - boolean isControllable, boolean isSuspended, MediaMetadata metadata) { + public void mediaSessionStateChanged(boolean isControllable, boolean isSuspended) { for (mObserversIterator.rewind(); mObserversIterator.hasNext();) { - mObserversIterator.next().mediaSessionStateChanged( - isControllable, isSuspended, metadata); + mObserversIterator.next().mediaSessionStateChanged(isControllable, isSuspended); + } + } + + @Override + @CalledByNative + public void mediaSessionMetadataChanged(MediaMetadata metadata) { + for (mObserversIterator.rewind(); mObserversIterator.hasNext();) { + mObserversIterator.next().mediaSessionMetadataChanged(metadata); } }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java index 85c8819e..0a42bb0 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java
@@ -166,10 +166,14 @@ * Called when the media session state changed. * @param isControllable if the session can be resumed or suspended. * @param isSuspended if the session currently suspended or not. - * @param metadata of the media session. */ - public void mediaSessionStateChanged( - boolean isControllable, boolean isSuspended, MediaMetadata metadata) {} + public void mediaSessionStateChanged(boolean isControllable, boolean isSuspended) {} + + /** + * Called when the media session metadata changed. + * @param metadata the new MediaMetadata after change. + */ + public void mediaSessionMetadataChanged(MediaMetadata metadata) {} /** * Stop observing the web contents and clean up associated references.
diff --git a/content/public/browser/browser_child_process_host.h b/content/public/browser/browser_child_process_host.h index e0f2d49e..e8506d8 100644 --- a/content/public/browser/browser_child_process_host.h +++ b/content/public/browser/browser_child_process_host.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_BROWSER_CHILD_PROCESS_HOST_H_ #include "base/environment.h" +#include "base/memory/shared_memory.h" #include "base/process/kill.h" #include "base/process/process_handle.h" #include "base/strings/string16.h" @@ -62,11 +63,13 @@ ~BrowserChildProcessHost() override {} // Derived classes call this to launch the child process asynchronously. - // Takes ownership of |cmd_line| and |delegate|. - virtual void Launch( - SandboxedProcessLauncherDelegate* delegate, - base::CommandLine* cmd_line, - bool terminate_on_shutdown) = 0; + // Takes ownership of |cmd_line| and |delegate|. Takes in |field_trial_state| + // to explicitly pass its handle to be inherited on Windows to the child + // process via the command line. + virtual void Launch(SandboxedProcessLauncherDelegate* delegate, + base::CommandLine* cmd_line, + const base::SharedMemory* field_trial_state, + bool terminate_on_shutdown) = 0; virtual const ChildProcessData& GetData() const = 0;
diff --git a/content/public/browser/notification_event_dispatcher.h b/content/public/browser/notification_event_dispatcher.h index 1c2289d..ce2261b3 100644 --- a/content/public/browser/notification_event_dispatcher.h +++ b/content/public/browser/notification_event_dispatcher.h
@@ -13,6 +13,10 @@ class GURL; +namespace base { +class NullableString16; +} + namespace content { class BrowserContext; @@ -36,6 +40,7 @@ const std::string& notification_id, const GURL& origin, int action_index, + const base::NullableString16& reply, const NotificationDispatchCompleteCallback& dispatch_complete_callback) = 0;
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h index ea27d243..704c509c 100644 --- a/content/public/browser/web_contents_observer.h +++ b/content/public/browser/web_contents_observer.h
@@ -469,9 +469,12 @@ virtual void MediaStoppedPlaying(const MediaPlayerId& id) {} // Invoked when media session has changed its state. - virtual void MediaSessionStateChanged( - bool is_controllable, - bool is_suspended, + virtual void MediaSessionStateChanged(bool is_controllable, + bool is_suspended) {} + + // Invoked when media session metadata has changed. When |metadata| is + // nullopt, it means the metadata is being unset. + virtual void MediaSessionMetadataChanged( const base::Optional<MediaMetadata>& metadata) {} // Invoked when the renderer process changes the page scale factor.
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 41c636f0..95d7544 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -530,6 +530,12 @@ // numbers. const char kExplicitlyAllowedPorts[] = "explicitly-allowed-ports"; +// Handle to the shared memory segment containing field trial state that is to +// be shared between processes. The argument to this switch is the handle id +// (pointer on Windows) as a string, followed by a comma, then the size of the +// shared memory segment as a string. +const char kFieldTrialHandle[] = "field-trial-handle"; + // Always use the Skia GPU backend for drawing layer tiles. Only valid with GPU // accelerated compositing + impl-side painting. Overrides the // kEnableGpuRasterization flag.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index dd1bc05..d6f16f47 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -162,6 +162,7 @@ CONTENT_EXPORT extern const char kEnableWebVR[]; CONTENT_EXPORT extern const char kEnableZeroCopy[]; CONTENT_EXPORT extern const char kExplicitlyAllowedPorts[]; +CONTENT_EXPORT extern const char kFieldTrialHandle[]; CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[]; CONTENT_EXPORT extern const char kForceGpuRasterization[]; CONTENT_EXPORT extern const char kForceOverlayFullscreenVideo[];
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 5e8bcb3..06cd0b3f 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -1645,63 +1645,34 @@ const GURL& url) : WebContentsObserver(web_contents), url_(url), - navigation_paused_in_will_start_(false), - navigation_paused_in_will_process_response_(false), handle_(nullptr), - handled_navigation_(false), + navigation_paused_(false), + current_state_(NavigationState::INITIAL), + desired_state_(NavigationState::STARTED), weak_factory_(this) {} TestNavigationManager::~TestNavigationManager() { - ResumeNavigation(); + if (navigation_paused_) + handle_->Resume(); } -bool TestNavigationManager::WaitForWillStartRequest() { - DCHECK(!did_finish_loop_runner_); - if (!handle_ && handled_navigation_) - return true; - if (navigation_paused_in_will_start_) - return true; - DCHECK(!navigation_paused_in_will_process_response_); - will_start_loop_runner_ = new MessageLoopRunner(); - will_start_loop_runner_->Run(); - will_start_loop_runner_ = nullptr; - - // This will only be false if DidFinishNavigation is called before - // OnWillStartRequest, which could occur if a throttle cancels the navigation - // before the TestNavigationManagerThrottle's method is called. - return !handled_navigation_; +bool TestNavigationManager::WaitForRequestStart() { + // This is the default desired state. In PlzNavigate, a browser-initiated + // navigation can reach this state synchronously, so the TestNavigationManager + // is set to always pause navigations at WillStartRequest. This ensures the + // user can always call WaitForWillStartRequest. + DCHECK(desired_state_ == NavigationState::STARTED); + return WaitForDesiredState(); } -bool TestNavigationManager::WaitForWillProcessResponse() { - DCHECK(!did_finish_loop_runner_); - if (!handle_ && handled_navigation_) - return true; - if (navigation_paused_in_will_process_response_) - return true; - // Ensure the navigation is resumed if the manager paused it previously. - if (navigation_paused_in_will_start_) - ResumeNavigation(); - will_process_response_loop_runner_ = new MessageLoopRunner(); - will_process_response_loop_runner_->Run(); - will_process_response_loop_runner_ = nullptr; - - // This will only be false if DidFinishNavigation is called before - // OnWillProcessResponse. - return !handled_navigation_; +bool TestNavigationManager::WaitForResponse() { + desired_state_ = NavigationState::RESPONSE; + return WaitForDesiredState(); } void TestNavigationManager::WaitForNavigationFinished() { - DCHECK(!will_start_loop_runner_); - if (!handle_ && handled_navigation_) - return; - // Ensure the navigation is resumed if the manager paused it previously. - if (navigation_paused_in_will_start_ || - navigation_paused_in_will_process_response_) { - ResumeNavigation(); - } - did_finish_loop_runner_ = new MessageLoopRunner(); - did_finish_loop_runner_->Run(); - did_finish_loop_runner_ = nullptr; + desired_state_ = NavigationState::FINISHED; + WaitForDesiredState(); } void TestNavigationManager::DidStartNavigation(NavigationHandle* handle) { @@ -1721,58 +1692,64 @@ void TestNavigationManager::DidFinishNavigation(NavigationHandle* handle) { if (handle != handle_) return; + current_state_ = NavigationState::FINISHED; + navigation_paused_ = false; handle_ = nullptr; - handled_navigation_ = true; - navigation_paused_in_will_start_ = false; - navigation_paused_in_will_process_response_ = false; - - // Resume any clients that are waiting for the end of the navigation. Note - // that |will_start_loop_runner_| can be running if the navigation was - // cancelled while it was deferred. - if (did_finish_loop_runner_) - did_finish_loop_runner_->Quit(); - if (will_start_loop_runner_) - will_start_loop_runner_->Quit(); - if (will_process_response_loop_runner_) - will_process_response_loop_runner_->Quit(); + OnNavigationStateChanged(); } void TestNavigationManager::OnWillStartRequest() { - navigation_paused_in_will_start_ = true; - if (will_start_loop_runner_) - will_start_loop_runner_->Quit(); - - // If waiting for further events in the navigation, resume the navigation. - if (did_finish_loop_runner_ || will_process_response_loop_runner_) - ResumeNavigation(); + current_state_ = NavigationState::STARTED; + navigation_paused_ = true; + OnNavigationStateChanged(); } void TestNavigationManager::OnWillProcessResponse() { - navigation_paused_in_will_process_response_ = true; - DCHECK(!will_start_loop_runner_); - if (will_process_response_loop_runner_) - will_process_response_loop_runner_->Quit(); - - // If waiting for further events in the navigation, resume the navigation. - if (did_finish_loop_runner_) - ResumeNavigation(); + current_state_ = NavigationState::RESPONSE; + navigation_paused_ = true; + OnNavigationStateChanged(); } -void TestNavigationManager::ResumeNavigation() { - if (!(navigation_paused_in_will_start_ || - navigation_paused_in_will_process_response_) || - !handle_) { +bool TestNavigationManager::WaitForDesiredState() { + // If the desired state has laready been reached, just return. + if (current_state_ == desired_state_) + return true; + + // Resume the navigation if it was paused. + if (navigation_paused_) + handle_->Resume(); + + // Wait for the desired state if needed. + if (current_state_ < desired_state_) { + DCHECK(!loop_runner_); + loop_runner_ = new MessageLoopRunner(); + loop_runner_->Run(); + loop_runner_ = nullptr; + } + + // Return false if the navigation did not reach the state specified by the + // user. + return current_state_ == desired_state_; +} + +void TestNavigationManager::OnNavigationStateChanged() { + // If the state the user was waiting for has been reached, exit the message + // loop. + if (current_state_ >= desired_state_) { + if (loop_runner_) + loop_runner_->Quit(); return; } - navigation_paused_in_will_start_ = false; - navigation_paused_in_will_process_response_ = false; - handle_->Resume(); + + // Otherwise, the navigation should be resumed if it was previously paused. + if (navigation_paused_) + handle_->Resume(); } bool TestNavigationManager::ShouldMonitorNavigation(NavigationHandle* handle) { if (handle_ || handle->GetURL() != url_) return false; - if (handled_navigation_) + if (current_state_ != NavigationState::INITIAL) return false; return true; }
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 4d02c44c..0429a1be 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -612,11 +612,11 @@ // Waits until the navigation request is ready to be sent to the network // stack. Returns false if the request was aborted before starting. - WARN_UNUSED_RESULT bool WaitForWillStartRequest(); + WARN_UNUSED_RESULT bool WaitForRequestStart(); // Waits until the navigation response has been sent received. Returns false // if the request was aborted before getting a response. - WARN_UNUSED_RESULT bool WaitForWillProcessResponse(); + WARN_UNUSED_RESULT bool WaitForResponse(); // Waits until the navigation has been finished. Will automatically resume // navigations paused before this point. @@ -628,6 +628,13 @@ virtual bool ShouldMonitorNavigation(NavigationHandle* handle); private: + enum class NavigationState { + INITIAL = 0, + STARTED = 1, + RESPONSE = 2, + FINISHED = 3, + }; + // WebContentsObserver: void DidStartNavigation(NavigationHandle* handle) override; void DidFinishNavigation(NavigationHandle* handle) override; @@ -640,17 +647,21 @@ // WillProcessResponse. void OnWillProcessResponse(); - // Resumes the navigation. - void ResumeNavigation(); + // Waits for the desired state. Returns false if the desired state cannot be + // reached (eg the navigation finishes before reaching this state). + bool WaitForDesiredState(); + + // Called when the state of the navigation has changed. This will either stop + // the message loop if the state specified by the user has been reached, or + // resume the navigation if it hasn't been reached yet. + void OnNavigationStateChanged(); const GURL url_; - bool navigation_paused_in_will_start_; - bool navigation_paused_in_will_process_response_; NavigationHandle* handle_; - bool handled_navigation_; - scoped_refptr<MessageLoopRunner> will_start_loop_runner_; - scoped_refptr<MessageLoopRunner> will_process_response_loop_runner_; - scoped_refptr<MessageLoopRunner> did_finish_loop_runner_; + bool navigation_paused_; + NavigationState current_state_; + NavigationState desired_state_; + scoped_refptr<MessageLoopRunner> loop_runner_; base::WeakPtrFactory<TestNavigationManager> weak_factory_;
diff --git a/content/public/test/mock_render_thread.cc b/content/public/test/mock_render_thread.cc index f28f88f..e93d645fb 100644 --- a/content/public/test/mock_render_thread.cc +++ b/content/public/test/mock_render_thread.cc
@@ -269,10 +269,8 @@ } bool MockRenderThread::OnControlMessageReceived(const IPC::Message& msg) { - base::ObserverListBase<RenderThreadObserver>::Iterator it(&observers_); - RenderThreadObserver* observer; - while ((observer = it.GetNext()) != NULL) { - if (observer->OnControlMessageReceived(msg)) + for (auto& observer : observers_) { + if (observer.OnControlMessageReceived(msg)) return true; } return OnMessageReceived(msg);
diff --git a/content/renderer/pepper/event_conversion.cc b/content/renderer/pepper/event_conversion.cc index 14cd388..d21f0cf 100644 --- a/content/renderer/pepper/event_conversion.cc +++ b/content/renderer/pepper/event_conversion.cc
@@ -99,18 +99,18 @@ PP_InputEvent_Type ConvertEventTypes(const WebInputEvent& event) { if (IsStylusEvent(event)) { + const WebMouseEvent& mouse_event = static_cast<const WebMouseEvent&>(event); + if (mouse_event.button != blink::WebMouseEvent::Button::Left && + !(mouse_event.modifiers & blink::WebInputEvent::LeftButtonDown)) + return PP_INPUTEVENT_TYPE_UNDEFINED; + switch (event.type) { case WebInputEvent::MouseDown: return PP_INPUTEVENT_TYPE_TOUCHSTART; case WebInputEvent::MouseUp: return PP_INPUTEVENT_TYPE_TOUCHEND; - case WebInputEvent::MouseMove: { - const WebMouseEvent& mouse_event = - static_cast<const WebMouseEvent&>(event); - return (mouse_event.modifiers & blink::WebInputEvent::LeftButtonDown) - ? PP_INPUTEVENT_TYPE_TOUCHMOVE - : PP_INPUTEVENT_TYPE_UNDEFINED; - } + case WebInputEvent::MouseMove: + return PP_INPUTEVENT_TYPE_TOUCHMOVE; default: return PP_INPUTEVENT_TYPE_UNDEFINED; } @@ -225,23 +225,21 @@ InputEventData result = GetEventWithCommonFieldsAndType(event); result.event_modifiers = ConvertEventModifiers(event.modifiers); + if (result.event_type == PP_INPUTEVENT_TYPE_UNDEFINED) + return; - if (mouse_event.modifiers & blink::WebInputEvent::LeftButtonDown && - (mouse_event.type == WebInputEvent::MouseDown || - mouse_event.type == WebInputEvent::MouseMove)) { - PP_TouchPoint touch_point; - touch_point.id = 0; - touch_point.position.x = mouse_event.x; - touch_point.position.y = mouse_event.y; - touch_point.pressure = mouse_event.force; + PP_TouchPoint touch_point; + touch_point.id = 0; + touch_point.position.x = mouse_event.x; + touch_point.position.y = mouse_event.y; + touch_point.pressure = mouse_event.force; + result.changed_touches.push_back(touch_point); + result.target_touches.push_back(touch_point); + if (result.event_type != PP_INPUTEVENT_TYPE_TOUCHEND) result.touches.push_back(touch_point); - result.changed_touches.push_back(touch_point); - result.target_touches.push_back(touch_point); - } - if (result.event_type != PP_INPUTEVENT_TYPE_UNDEFINED) - result_events->push_back(result); + result_events->push_back(result); } void AppendMouseEvent(const WebInputEvent& event,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index b13d2ca..348f57d 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1506,10 +1506,8 @@ if (!frame_->document().isNull()) GetContentClient()->SetActiveURL(frame_->document().url()); - base::ObserverListBase<RenderFrameObserver>::Iterator it(&observers_); - RenderFrameObserver* observer; - while ((observer = it.GetNext()) != NULL) { - if (observer->OnMessageReceived(msg)) + for (auto& observer : observers_) { + if (observer.OnMessageReceived(msg)) return true; }
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 2a737e2..9e7bf65 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1719,10 +1719,8 @@ } bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) { - base::ObserverListBase<RenderThreadObserver>::Iterator it(&observers_); - RenderThreadObserver* observer; - while ((observer = it.GetNext()) != nullptr) { - if (observer->OnControlMessageReceived(msg)) + for (auto& observer : observers_) { + if (observer.OnControlMessageReceived(msg)) return true; }
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 26b6bc91..2cd7b96 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1304,11 +1304,10 @@ if (is_swapped_out_ && IPC_MESSAGE_ID_CLASS(message.type()) == InputMsgStart) return false; - base::ObserverListBase<RenderViewObserver>::Iterator it(&observers_); - RenderViewObserver* observer; - while ((observer = it.GetNext()) != NULL) - if (observer->OnMessageReceived(message)) + for (auto& observer : observers_) { + if (observer.OnMessageReceived(message)) return true; + } bool handled = true; IPC_BEGIN_MESSAGE_MAP(RenderViewImpl, message)
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index bcbdffbd..0a9e9d1 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -35,12 +35,12 @@ #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" #include "third_party/WebKit/public/platform/WebDisplayMode.h" +#include "third_party/WebKit/public/platform/WebInputEvent.h" #include "third_party/WebKit/public/platform/WebRect.h" +#include "third_party/WebKit/public/platform/WebTextInputInfo.h" #include "third_party/WebKit/public/web/WebCompositionUnderline.h" -#include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebPopupType.h" #include "third_party/WebKit/public/web/WebTextDirection.h" -#include "third_party/WebKit/public/web/WebTextInputInfo.h" #include "third_party/WebKit/public/web/WebTouchAction.h" #include "third_party/WebKit/public/web/WebWidget.h" #include "third_party/WebKit/public/web/WebWidgetClient.h"
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 210bd3e..c840404 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -914,12 +914,14 @@ int request_id, const std::string& notification_id, const PlatformNotificationData& notification_data, - int action_index) { + int action_index, + const base::NullableString16& reply) { TRACE_EVENT0("ServiceWorker", "ServiceWorkerContextClient::OnNotificationClickEvent"); proxy_->dispatchNotificationClickEvent( request_id, blink::WebString::fromUTF8(notification_id), - ToWebNotificationData(notification_data), action_index); + ToWebNotificationData(notification_data), action_index, + blink::WebString(reply)); } void ServiceWorkerContextClient::OnNotificationCloseEvent(
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index dee3309..b425843 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -225,7 +225,8 @@ int request_id, const std::string& notification_id, const PlatformNotificationData& notification_data, - int action_index); + int action_index, + const base::NullableString16& reply); void OnPushEvent(int request_id, const PushEventPayload& payload); void OnNotificationCloseEvent( int request_id,
diff --git a/content/shell/browser/layout_test/layout_test_notification_manager.cc b/content/shell/browser/layout_test/layout_test_notification_manager.cc index 1fd856e1..81ec335 100644 --- a/content/shell/browser/layout_test/layout_test_notification_manager.cc +++ b/content/shell/browser/layout_test/layout_test_notification_manager.cc
@@ -5,6 +5,7 @@ #include "content/shell/browser/layout_test/layout_test_notification_manager.h" #include "base/guid.h" +#include "base/strings/nullable_string16.h" #include "base/strings/utf_string_conversions.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/desktop_notification_delegate.h" @@ -111,9 +112,10 @@ const PersistentNotification& notification = persistent_iter->second; content::NotificationEventDispatcher::GetInstance() - ->DispatchNotificationClickEvent( - notification.browser_context, notification_id, notification.origin, - action_index, base::Bind(&OnEventDispatchComplete)); + ->DispatchNotificationClickEvent(notification.browser_context, + notification_id, notification.origin, + action_index, base::NullableString16(), + base::Bind(&OnEventDispatchComplete)); } else if (non_persistent_iter != non_persistent_notifications_.end()) { DCHECK_EQ(action_index, -1) << "Action buttons are only supported for " "persistent notifications";
diff --git a/device/vr/BUILD.gn b/device/vr/BUILD.gn index 860b4881..317c898 100644 --- a/device/vr/BUILD.gn +++ b/device/vr/BUILD.gn
@@ -45,7 +45,6 @@ ] deps += [ - ":jni_headers", "//device/gamepad", "//third_party/WebKit/public:blink_headers", "//third_party/gvr-android-sdk:libgvr", @@ -79,22 +78,3 @@ use_new_wrapper_types = false } - -if (is_android) { - java_sources_needing_jni = - [ "android/java/src/org/chromium/device/vr/GvrDeviceProvider.java" ] - - generate_jni("jni_headers") { - sources = java_sources_needing_jni - jni_package = "vr" - } - - android_library("java") { - java_files = java_sources_needing_jni - deps = [ - "//base:base_java", - "//third_party/android_protobuf:protobuf_nano_javalib", - "//third_party/gvr-android-sdk:gvr_common_java", - ] - } -}
diff --git a/device/vr/android/gvr/gvr_delegate.h b/device/vr/android/gvr/gvr_delegate.h index 18be9b8..d7b4297 100644 --- a/device/vr/android/gvr/gvr_delegate.h +++ b/device/vr/android/gvr/gvr_delegate.h
@@ -15,18 +15,6 @@ namespace device { -class DEVICE_VR_EXPORT GvrDelegateProvider { - public: - static void SetInstance(GvrDelegateProvider* delegate_provider); - static GvrDelegateProvider* GetInstance(); - - virtual bool RequestWebVRPresent(GvrDeviceProvider* device_provider) = 0; - virtual void ExitWebVRPresent() = 0; - - private: - static GvrDelegateProvider* delegate_provider_; -}; - class DEVICE_VR_EXPORT GvrDelegate { public: virtual void SetWebVRSecureOrigin(bool secure_origin) = 0; @@ -41,6 +29,20 @@ virtual gvr::GvrApi* gvr_api() = 0; }; +class DEVICE_VR_EXPORT GvrDelegateProvider { + public: + static void SetInstance(GvrDelegateProvider* delegate_provider); + static GvrDelegateProvider* GetInstance(); + + virtual bool RequestWebVRPresent(GvrDeviceProvider* device_provider) = 0; + virtual void ExitWebVRPresent() = 0; + virtual GvrDelegate* GetNonPresentingDelegate() = 0; + virtual void DestroyNonPresentingDelegate() = 0; + + private: + static GvrDelegateProvider* delegate_provider_; +}; + } // namespace device #endif // DEVICE_VR_ANDROID_GVR_DELEGATE_H
diff --git a/device/vr/android/gvr/gvr_device_provider.cc b/device/vr/android/gvr/gvr_device_provider.cc index 1025ca4..252aa117 100644 --- a/device/vr/android/gvr/gvr_device_provider.cc +++ b/device/vr/android/gvr/gvr_device_provider.cc
@@ -14,7 +14,6 @@ #include "device/vr/android/gvr/gvr_device.h" #include "device/vr/android/gvr/gvr_gamepad_data_fetcher.h" #include "device/vr/vr_device_manager.h" -#include "jni/GvrDeviceProvider_jni.h" #include "third_party/gvr-android-sdk/src/ndk/include/vr/gvr/capi/include/gvr.h" #include "third_party/gvr-android-sdk/src/ndk/include/vr/gvr/capi/include/gvr_controller.h" #include "third_party/gvr-android-sdk/src/ndk/include/vr/gvr/capi/include/gvr_types.h" @@ -24,62 +23,16 @@ namespace device { -// A temporary delegate till a VrShell instance becomes available. -class GvrNonPresentingDelegate : public GvrDelegate { - public: - GvrNonPresentingDelegate() { Initialize(); } - - virtual ~GvrNonPresentingDelegate() { Shutdown(); } - - void Initialize() { - if (j_device_.is_null()) { - JNIEnv* env = AttachCurrentThread(); - - j_device_.Reset( - Java_GvrDeviceProvider_create(env, GetApplicationContext())); - jlong context = - Java_GvrDeviceProvider_getNativeContext(env, j_device_.obj()); - - if (!context) - return; - - gvr_api_ = - gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(context)); - } - } - - void Shutdown() { - if (!j_device_.is_null()) { - gvr_api_ = nullptr; - JNIEnv* env = AttachCurrentThread(); - Java_GvrDeviceProvider_shutdown(env, j_device_.obj()); - j_device_ = nullptr; - } - } - - // GvrDelegate implementation - void SetWebVRSecureOrigin(bool secure_origin) override {} - void SubmitWebVRFrame() override {} - void UpdateWebVRTextureBounds(int eye, - float left, - float top, - float width, - float height) override {} - void SetGvrPoseForWebVr(const gvr::Mat4f& pose, - uint32_t pose_index) override {} - - gvr::GvrApi* gvr_api() override { return gvr_api_.get(); } - - private: - base::android::ScopedJavaGlobalRef<jobject> j_device_; - std::unique_ptr<gvr::GvrApi> gvr_api_; -}; - GvrDeviceProvider::GvrDeviceProvider() : VRDeviceProvider(), main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} GvrDeviceProvider::~GvrDeviceProvider() { + device::GvrDelegateProvider* delegate_provider = + device::GvrDelegateProvider::GetInstance(); + if (delegate_provider) + delegate_provider->DestroyNonPresentingDelegate(); + ExitPresent(); } @@ -96,17 +49,25 @@ } void GvrDeviceProvider::Initialize() { + device::GvrDelegateProvider* delegate_provider = + device::GvrDelegateProvider::GetInstance(); + if (!delegate_provider) + return; + if (!vr_device_) { - vr_device_.reset(new GvrDevice(this, nullptr)); + vr_device_.reset( + new GvrDevice(this, delegate_provider->GetNonPresentingDelegate())); client_->OnDeviceConnectionStatusChanged(vr_device_.get(), true); } } bool GvrDeviceProvider::RequestPresent() { - GvrDelegateProvider* delegate_provider = GvrDelegateProvider::GetInstance(); + device::GvrDelegateProvider* delegate_provider = + device::GvrDelegateProvider::GetInstance(); if (!delegate_provider) return false; + // RequestWebVRPresent is async as a render thread may be created. return delegate_provider->RequestWebVRPresent(this); } @@ -116,14 +77,17 @@ if (!vr_device_) return; - vr_device_->SetDelegate(nullptr); + device::GvrDelegateProvider* delegate_provider = + device::GvrDelegateProvider::GetInstance(); + if (!delegate_provider) + return; + + vr_device_->SetDelegate(delegate_provider->GetNonPresentingDelegate()); GamepadDataFetcherManager::GetInstance()->RemoveSourceFactory( GAMEPAD_SOURCE_GVR); - GvrDelegateProvider* delegate_provider = GvrDelegateProvider::GetInstance(); - if (delegate_provider) - delegate_provider->ExitWebVRPresent(); + delegate_provider->ExitWebVRPresent(); if (client_) client_->OnPresentEnded(vr_device_.get()); @@ -137,12 +101,10 @@ } void GvrDeviceProvider::OnGvrDelegateRemoved() { + DCHECK(main_thread_task_runner_->BelongsToCurrentThread()); if (!vr_device_) return; - - main_thread_task_runner_->PostTask( - FROM_HERE, - base::Bind(&GvrDeviceProvider::ExitPresent, base::Unretained(this))); + ExitPresent(); } void GvrDeviceProvider::GvrDelegateReady(GvrDelegate* delegate) {
diff --git a/device/vr/android/gvr/gvr_device_provider.h b/device/vr/android/gvr/gvr_device_provider.h index bb64966..23f8cb0 100644 --- a/device/vr/android/gvr/gvr_device_provider.h +++ b/device/vr/android/gvr/gvr_device_provider.h
@@ -18,7 +18,6 @@ class GvrDelegate; class GvrDevice; -class GvrNonPresentingDelegate; class DEVICE_VR_EXPORT GvrDeviceProvider : public VRDeviceProvider { public:
diff --git a/device/vr/android/java/src/org/chromium/device/vr/GvrDeviceProvider.java b/device/vr/android/java/src/org/chromium/device/vr/GvrDeviceProvider.java deleted file mode 100644 index ba4f44c..0000000 --- a/device/vr/android/java/src/org/chromium/device/vr/GvrDeviceProvider.java +++ /dev/null
@@ -1,55 +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. - -package org.chromium.device.vr; - -import android.content.Context; -import android.os.StrictMode; - -import com.google.vr.ndk.base.GvrLayout; - -import org.chromium.base.Log; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.base.annotations.JNINamespace; - -/** - * This is the implementation of the C++ counterpart GvrDeviceProvider. - */ -@JNINamespace("device") -class GvrDeviceProvider { - private static final String TAG = "GvrDeviceProvider"; - private final GvrLayout mLayout; - - private GvrDeviceProvider(Context context) { - mLayout = new GvrLayout(context); - } - - @CalledByNative - private static GvrDeviceProvider create(Context context) { - return new GvrDeviceProvider(context); - } - - @CalledByNative - private long getNativeContext() { - long nativeGvrContext = 0; - - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - - try { - nativeGvrContext = mLayout.getGvrApi().getNativeGvrContext(); - } catch (Exception ex) { - Log.e(TAG, "Unable to instantiate GvrApi", ex); - return 0; - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } - - return nativeGvrContext; - } - - @CalledByNative - private void shutdown() { - mLayout.shutdown(); - } -}
diff --git a/extensions/browser/extension_navigation_throttle.cc b/extensions/browser/extension_navigation_throttle.cc index 4e511a5f..68c0a92 100644 --- a/extensions/browser/extension_navigation_throttle.cc +++ b/extensions/browser/extension_navigation_throttle.cc
@@ -4,18 +4,24 @@ #include "extensions/browser/extension_navigation_throttle.h" +#include "components/guest_view/browser/guest_view_base.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/url_constants.h" #include "extensions/browser/extension_registry.h" +#include "extensions/browser/guest_view/web_view/web_view_guest.h" +#include "extensions/browser/url_request_util.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/extension_set.h" #include "extensions/common/manifest_handlers/web_accessible_resources_info.h" +#include "extensions/common/manifest_handlers/webview_info.h" #include "extensions/common/permissions/api_permission.h" #include "extensions/common/permissions/permissions_data.h" +#include "ui/base/page_transition_types.h" namespace extensions { @@ -29,8 +35,9 @@ ExtensionNavigationThrottle::WillStartRequest() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); GURL url(navigation_handle()->GetURL()); - ExtensionRegistry* registry = ExtensionRegistry::Get( - navigation_handle()->GetWebContents()->GetBrowserContext()); + content::WebContents* web_contents = navigation_handle()->GetWebContents(); + ExtensionRegistry* registry = + ExtensionRegistry::Get(web_contents->GetBrowserContext()); if (navigation_handle()->IsInMainFrame()) { // Block top-level navigations to blob: or filesystem: URLs with extension @@ -57,6 +64,36 @@ return content::NavigationThrottle::CANCEL; } + if (content::IsBrowserSideNavigationEnabled() && + url.scheme() == extensions::kExtensionScheme) { + // This logic is performed for PlzNavigate sub-resources and for + // non-PlzNavigate in + // extensions::url_request_util::AllowCrossRendererResourceLoad. + const Extension* extension = + registry->enabled_extensions().GetExtensionOrAppByURL(url); + guest_view::GuestViewBase* guest = + guest_view::GuestViewBase::FromWebContents(web_contents); + if (guest) { + std::string owner_extension_id = guest->owner_host(); + const Extension* owner_extension = + registry->enabled_extensions().GetByID(owner_extension_id); + + std::string partition_domain, partition_id; + bool in_memory; + std::string resource_path = url.path(); + bool is_guest = WebViewGuest::GetGuestPartitionConfigForSite( + navigation_handle()->GetStartingSiteInstance()->GetSiteURL(), + &partition_domain, &partition_id, &in_memory); + + bool allowed = true; + url_request_util::AllowCrossRendererResourceLoadHelper( + is_guest, extension, owner_extension, partition_id, resource_path, + navigation_handle()->GetPageTransition(), &allowed); + if (!allowed) + return content::NavigationThrottle::CANCEL; + } + } + return content::NavigationThrottle::PROCEED; } @@ -76,7 +113,7 @@ // the ancestor chain, so find the current RenderFrameHost and use it to // traverse up to the main frame. content::RenderFrameHost* navigating_frame = nullptr; - for (auto* frame : navigation_handle()->GetWebContents()->GetAllFrames()) { + for (auto* frame : web_contents->GetAllFrames()) { if (frame->GetFrameTreeNodeId() == navigation_handle()->GetFrameTreeNodeId()) { navigating_frame = frame;
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc index 692e490..645d9af 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.cc +++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -23,6 +23,7 @@ #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" @@ -600,13 +601,12 @@ void WebViewGuest::LoadAbort(bool is_top_level, const GURL& url, - int error_code, - const std::string& error_type) { + int error_code) { std::unique_ptr<base::DictionaryValue> args(new base::DictionaryValue()); args->SetBoolean(guest_view::kIsTopLevel, is_top_level); args->SetString(guest_view::kUrl, url.possibly_invalid_spec()); args->SetInteger(guest_view::kCode, error_code); - args->SetString(guest_view::kReason, error_type); + args->SetString(guest_view::kReason, net::ErrorToShortString(error_code)); DispatchEventToView(base::MakeUnique<GuestViewEvent>(webview::kEventLoadAbort, std::move(args))); } @@ -806,11 +806,26 @@ WebViewGuest::~WebViewGuest() { } -void WebViewGuest::DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type) { - if (!render_frame_host->GetParent()) { +void WebViewGuest::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (navigation_handle->IsErrorPage() || !navigation_handle->HasCommitted()) { + // Suppress loadabort for "mailto" URLs. + // Also during destruction, owner_web_contents() is null so there's no point + // trying to send the event. + if (!navigation_handle->GetURL().SchemeIs(url::kMailToScheme) && + owner_web_contents()) { + // If it's not an error page, the request was blocked by the webrequest + // API. + int error_code = navigation_handle->IsErrorPage() + ? navigation_handle->GetNetErrorCode() + : net::ERR_BLOCKED_BY_CLIENT; + LoadAbort(navigation_handle->IsInMainFrame(), navigation_handle->GetURL(), + error_code); + } + return; + } + + if (navigation_handle->IsInMainFrame()) { // For LoadDataWithBaseURL loads, |url| contains the data URL, but the // virtual URL is needed in that case. So use WebContents::GetURL instead. src_ = web_contents()->GetURL(); @@ -822,7 +837,7 @@ } std::unique_ptr<base::DictionaryValue> args(new base::DictionaryValue()); args->SetString(guest_view::kUrl, src_.spec()); - args->SetBoolean(guest_view::kIsTopLevel, !render_frame_host->GetParent()); + args->SetBoolean(guest_view::kIsTopLevel, navigation_handle->IsInMainFrame()); args->SetString(webview::kInternalBaseURLForDataURL, web_contents() ->GetController() @@ -841,28 +856,11 @@ find_helper_.CancelAllFindSessions(); } -void WebViewGuest::DidFailProvisionalLoad( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - bool was_ignored_by_handler) { - // Suppress loadabort for "mailto" URLs. - if (validated_url.SchemeIs(url::kMailToScheme)) - return; - - LoadAbort(!render_frame_host->GetParent(), validated_url, error_code, - net::ErrorToShortString(error_code)); -} - -void WebViewGuest::DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page, - bool is_iframe_srcdoc) { +void WebViewGuest::DidStartNavigation( + content::NavigationHandle* navigation_handle) { std::unique_ptr<base::DictionaryValue> args(new base::DictionaryValue()); - args->SetString(guest_view::kUrl, validated_url.spec()); - args->SetBoolean(guest_view::kIsTopLevel, !render_frame_host->GetParent()); + args->SetString(guest_view::kUrl, navigation_handle->GetURL().spec()); + args->SetBoolean(guest_view::kIsTopLevel, navigation_handle->IsInMainFrame()); DispatchEventToView(base::MakeUnique<GuestViewEvent>(webview::kEventLoadStart, std::move(args))); } @@ -1381,8 +1379,7 @@ ui::PageTransition transition_type, bool force_navigation) { if (!url.is_valid()) { - LoadAbort(true /* is_top_level */, url, net::ERR_INVALID_URL, - net::ErrorToShortString(net::ERR_INVALID_URL)); + LoadAbort(true /* is_top_level */, url, net::ERR_INVALID_URL); NavigateGuest(url::kAboutBlankURL, false /* force_navigation */); return; } @@ -1397,8 +1394,7 @@ // This will block the embedder trying to load unwanted schemes, e.g. // chrome://. if (scheme_is_blocked) { - LoadAbort(true /* is_top_level */, url, net::ERR_DISALLOWED_URL_SCHEME, - net::ErrorToShortString(net::ERR_DISALLOWED_URL_SCHEME)); + LoadAbort(true /* is_top_level */, url, net::ERR_DISALLOWED_URL_SCHEME); NavigateGuest(url::kAboutBlankURL, false /* force_navigation */); return; }
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.h b/extensions/browser/guest_view/web_view/web_view_guest.h index 9ae9a4c..9ed2fbb 100644 --- a/extensions/browser/guest_view/web_view/web_view_guest.h +++ b/extensions/browser/guest_view/web_view/web_view_guest.h
@@ -255,20 +255,8 @@ const content::WebContents* web_contents) const final; // WebContentsObserver implementation. - void DidCommitProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& url, - ui::PageTransition transition_type) final; - void DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - int error_code, - const base::string16& error_description, - bool was_ignored_by_handler) final; - void DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page, - bool is_iframe_srcdoc) final; + void DidStartNavigation(content::NavigationHandle* navigation_handle) final; + void DidFinishNavigation(content::NavigationHandle* navigation_handle) final; void RenderProcessGone(base::TerminationStatus status) final; void UserAgentOverrideSet(const std::string& user_agent) final; void FrameNameChanged(content::RenderFrameHost* render_frame_host, @@ -308,10 +296,7 @@ // Notification that a load in the guest resulted in abort. Note that |url| // may be invalid. - void LoadAbort(bool is_top_level, - const GURL& url, - int error_code, - const std::string& error_type); + void LoadAbort(bool is_top_level, const GURL& url, int error_code); // Creates a new guest window owned by this WebViewGuest. void CreateNewGuestWebViewWindow(const content::OpenURLParams& params);
diff --git a/extensions/browser/url_request_util.cc b/extensions/browser/url_request_util.cc index 1e44115b..126f694 100644 --- a/extensions/browser/url_request_util.cc +++ b/extensions/browser/url_request_util.cc
@@ -7,6 +7,7 @@ #include <string> #include "content/public/browser/resource_request_info.h" +#include "content/public/common/browser_side_navigation_policy.h" #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" #include "extensions/browser/info_map.h" #include "extensions/common/extension.h" @@ -25,34 +26,31 @@ bool* allowed) { const content::ResourceRequestInfo* info = content::ResourceRequestInfo::ForRequest(request); - - // Extensions with webview: allow loading certain resources by guest renderers - // with privileged partition IDs as specified in owner's extension the - // manifest file. - std::string owner_extension_id; - int owner_process_id; - WebViewRendererState::GetInstance()->GetOwnerInfo( - info->GetChildID(), &owner_process_id, &owner_extension_id); - const Extension* owner_extension = - extension_info_map->extensions().GetByID(owner_extension_id); - std::string partition_id; - bool is_guest = WebViewRendererState::GetInstance()->GetPartitionID( - info->GetChildID(), &partition_id); std::string resource_path = request->url().path(); - // |owner_extension == extension| needs to be checked because extension - // resources should only be accessible to WebViews owned by that extension. - if (is_guest && owner_extension == extension && - WebviewInfo::IsResourceWebviewAccessible(extension, partition_id, - resource_path)) { - *allowed = true; - return true; - } + // PlzNavigate: this logic is performed for main frame requests in + // ExtensionNavigationThrottle::WillStartRequest. + if (info->GetChildID() != -1 || + info->GetResourceType() != content::RESOURCE_TYPE_MAIN_FRAME || + !content::IsBrowserSideNavigationEnabled()) { + // Extensions with webview: allow loading certain resources by guest + // renderers with privileged partition IDs as specified in owner's extension + // the manifest file. + std::string owner_extension_id; + int owner_process_id; + WebViewRendererState::GetInstance()->GetOwnerInfo( + info->GetChildID(), &owner_process_id, &owner_extension_id); + const Extension* owner_extension = + extension_info_map->extensions().GetByID(owner_extension_id); + std::string partition_id; + bool is_guest = WebViewRendererState::GetInstance()->GetPartitionID( + info->GetChildID(), &partition_id); - if (is_guest && - !ui::PageTransitionIsWebTriggerable(info->GetPageTransition())) { - *allowed = false; - return true; + if (AllowCrossRendererResourceLoadHelper( + is_guest, extension, owner_extension, partition_id, resource_path, + info->GetPageTransition(), allowed)) { + return true; + } } // The following checks require that we have an actual extension object. If we @@ -137,5 +135,29 @@ return WebViewRendererState::GetInstance()->IsGuest(info->GetChildID()); } +bool AllowCrossRendererResourceLoadHelper(bool is_guest, + const Extension* extension, + const Extension* owner_extension, + const std::string& partition_id, + const std::string& resource_path, + ui::PageTransition page_transition, + bool* allowed) { + // |owner_extension == extension| needs to be checked because extension + // resources should only be accessible to WebViews owned by that extension. + if (is_guest && owner_extension == extension && + WebviewInfo::IsResourceWebviewAccessible(extension, partition_id, + resource_path)) { + *allowed = true; + return true; + } + + if (is_guest && !ui::PageTransitionIsWebTriggerable(page_transition)) { + *allowed = false; + return true; + } + + return false; +} + } // namespace url_request_util } // namespace extensions
diff --git a/extensions/browser/url_request_util.h b/extensions/browser/url_request_util.h index afa0edb..e39fd87 100644 --- a/extensions/browser/url_request_util.h +++ b/extensions/browser/url_request_util.h
@@ -5,6 +5,10 @@ #ifndef EXTENSIONS_BROWSER_URL_REQUEST_UTIL_H_ #define EXTENSIONS_BROWSER_URL_REQUEST_UTIL_H_ +#include <string> + +#include "ui/base/page_transition_types.h" + namespace net { class URLRequest; } @@ -30,6 +34,19 @@ // <webview>. bool IsWebViewRequest(const net::URLRequest* request); +// Helper method that is called by both AllowCrossRendererResourceLoad and +// ExtensionNavigationThrottle to share logic. +// Sets allowed=true to allow a chrome-extension:// resource request coming from +// renderer A to access a resource in an extension running in renderer B. +// Returns false when it couldn't determine if the resource is allowed or not +bool AllowCrossRendererResourceLoadHelper(bool is_guest, + const Extension* extension, + const Extension* owner_extension, + const std::string& partition_id, + const std::string& resource_path, + ui::PageTransition page_transition, + bool* allowed); + } // namespace url_request_util } // namespace extensions
diff --git a/media/gpu/generic_v4l2_device.cc b/media/gpu/generic_v4l2_device.cc index e98ea72ed..830d004 100644 --- a/media/gpu/generic_v4l2_device.cc +++ b/media/gpu/generic_v4l2_device.cc
@@ -434,7 +434,7 @@ break; case Type::kJpegDecoder: device_pattern = kJpegDecoderDevicePattern; - buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT; break; }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index fd48067..47ba91e 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -3630,6 +3630,9 @@ "test": "unit_tests" }, { + "override_compile_targets": [ + "android_webview_test_apk" + ], "override_isolate_target": "android_webview_test_apk", "swarming": { "can_use_on_swarming_builders": true, @@ -3697,6 +3700,9 @@ "test": "blimp_test_apk" }, { + "override_compile_targets": [ + "chrome_public_test_apk" + ], "override_isolate_target": "chrome_public_test_apk", "swarming": { "can_use_on_swarming_builders": true, @@ -3729,6 +3735,9 @@ "test": "chrome_public_test_apk" }, { + "override_compile_targets": [ + "chrome_sync_shell_test_apk" + ], "override_isolate_target": "chrome_sync_shell_test_apk", "swarming": { "can_use_on_swarming_builders": true, @@ -3761,6 +3770,9 @@ "test": "chrome_sync_shell_test_apk" }, { + "override_compile_targets": [ + "content_shell_test_apk" + ], "override_isolate_target": "content_shell_test_apk", "swarming": { "can_use_on_swarming_builders": true,
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index 17b5648..a1e14c59 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -38,10 +38,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build171-b4" + "gpu": "1002:9874", + "id": "build171-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -65,10 +71,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build171-b4" + "gpu": "1002:9874", + "id": "build171-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -91,10 +103,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build171-b4" + "gpu": "1002:9874", + "id": "build171-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -118,10 +136,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build171-b4" + "gpu": "1002:9874", + "id": "build171-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -144,10 +168,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build186-b4" + "gpu": "1002:9874", + "id": "build171-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -171,10 +201,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build186-b4" + "gpu": "1002:9874", + "id": "build186-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -197,10 +233,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build186-b4" + "gpu": "1002:9874", + "id": "build186-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -224,10 +266,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build186-b4" + "gpu": "1002:9874", + "id": "build186-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -250,10 +298,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build171-b4" + "gpu": "1002:9874", + "id": "build186-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400 @@ -277,10 +331,16 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "id": "build187-b4" + "gpu": "8086:22b1", + "id": "build187-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" }, { - "id": "build171-b4" + "gpu": "1002:9874", + "id": "build186-b4", + "os": "Windows-10-10586", + "pool": "Chrome-perf" } ], "expiration": 14400
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation index 5439906..96f7ed13 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -127,7 +127,7 @@ crbug.com/648600 fast/overflow/overflow-height-float-not-removed-crash.html [ Failure ] crbug.com/648600 virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash.html [ Failure ] -# https://crbug.com/648608: Send the right cookies when loading a popup +# https://crbug.com/648608: Properly set the initator of the navigation. crbug.com/648608 http/tests/cookies/same-site/popup-same-site-post.html [ Failure ] crbug.com/648608 http/tests/cookies/same-site/popup-same-site.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index f4a6a8a..57605949 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1278,3 +1278,6 @@ crbug.com/655458 imported/wpt/workers/semantics/structured-clone/shared.html [ Crash Timeout ] crbug.com/652187 [ Win7 Debug ] http/tests/inspector/network/network-disable-cache-preloads.php [ Failure ] + +crbug.com/653424 inspector/console/console-format.html [ NeedsManualRebaseline ] +crbug.com/653424 inspector/console/console-log-side-effects.html [ NeedsManualRebaseline ]
diff --git a/third_party/WebKit/LayoutTests/W3CImportExpectations b/third_party/WebKit/LayoutTests/W3CImportExpectations index cc61764b..edea6c0 100644 --- a/third_party/WebKit/LayoutTests/W3CImportExpectations +++ b/third_party/WebKit/LayoutTests/W3CImportExpectations
@@ -325,7 +325,7 @@ # imported/wpt/webstorage [ Pass ] imported/wpt/webvtt [ Skip ] ## Owners: nhiroki@chromium.org -# imported/wpt/workers [ Pass ] +# imported/wpt/workers [ Skip ] # Exceptions for individual files that fail due to bugs in the # upstream tests that we shouldn't bother importing until they are
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-pointerup-exactly-once.html b/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-pointerup-exactly-once.html new file mode 100644 index 0000000..07db5fe --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-pointerup-exactly-once.html
@@ -0,0 +1,29 @@ +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<p> + Test that only a single popup is allowed in response to a single + pointer up user action. The test passes if only one popup is created. +</p> +<button id="button">Tap Here</button> +<div id="console"></div> +<script> + document.getElementById('button').addEventListener('pointerup', pointer_popup); + function pointer_popup() { + assert_not_equals(window.open("about:blank", "window1"), null, "Popup didn't open in pointerup handler."); + assert_equals(window.open("about:blank", "window2"), null, "Popup should open only once in pointerup handler."); + done(); + } + + if (window.testRunner) { + testRunner.setPopupBlockingEnabled(true); + testRunner.setCloseRemainingWindowsWhenComplete(true); + + if (window.eventSender) { + var button = document.getElementById("button"); + eventSender.addTouchPoint(button.offsetLeft + button.offsetWidth / 2, button.offsetTop + button.offsetHeight / 2); + eventSender.touchStart(); + eventSender.releaseTouchPoint(0); + eventSender.touchEnd(); + } + } +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/anchor-inside-iframe.html b/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/anchor-inside-iframe.html new file mode 100644 index 0000000..9407562 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/layout/scroll-anchoring/anchor-inside-iframe.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<script src="../../../resources/run-after-layout-and-paint.js"></script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<iframe width="700" height="500" srcdoc=" + <!DOCTYPE html> + <style> body { height: 1000px } div { height: 100px } </style> + <div id='block1'>abc</div> + <div id='block2'>def</div> +"></iframe> +<script> + async_test((t) => { + var iframeWindow = document.querySelector("iframe").contentWindow; + iframeWindow.addEventListener("load", () => { + var block1 = iframeWindow.document.querySelector("#block1"); + iframeWindow.scrollTo(0, 150); + + runAfterLayoutAndPaint(() => { + block1.style.height = "200px"; + assert_equals(iframeWindow.scrollY, 250); + t.done(); + }); + }); + }, "Scroll anchoring in an iframe."); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/webfont/crbug-655076-expected.txt b/third_party/WebKit/LayoutTests/http/tests/webfont/crbug-655076-expected.txt new file mode 100644 index 0000000..5b3b4a79 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/webfont/crbug-655076-expected.txt
@@ -0,0 +1 @@ +testtest
diff --git a/third_party/WebKit/LayoutTests/http/tests/webfont/crbug-655076.html b/third_party/WebKit/LayoutTests/http/tests/webfont/crbug-655076.html new file mode 100644 index 0000000..94fef68e3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/webfont/crbug-655076.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<style></style> +<div id="container"></div> +<script> +// Regression test for https://crbug.com/655076. Test passes by not crashing in +// debug build. + +if (window.testRunner) { + testRunner.dumpAsText(); + testRunner.waitUntilDone(); +} + +let container = document.getElementById('container'); +let font = 'slow-ahem-loading.cgi?delay=5000'; + +function makeSpan(family) { + document.styleSheets[0].insertRule( + '@font-face { font-family: ' + family + '; src: url(' + font + '); }', 0); + let span = document.createElement('span'); + span.style.fontFamily = family; + span.textContent = 'test'; + container.appendChild(span); +} + +window.onload = () => { + makeSpan('ahem-1'); + setTimeout(() => { + makeSpan('ahem-2'); + testRunner.notifyDone(); + }, 4000); +}; +</script>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames-expected.txt new file mode 100644 index 0000000..664dc9e --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames-expected.txt
@@ -0,0 +1,125 @@ + +{ + "method": "DOM.setChildNodes", + "params": { + "parentId": 13, + "nodes": [ + { + "nodeId": 14, + "nodeType": 1, + "nodeName": "DIV", + "localName": "div", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 15, + "nodeType": 1, + "nodeName": "DIV", + "localName": "div", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 16, + "nodeType": 1, + "nodeName": "DIV", + "localName": "div", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 17, + "nodeType": 1, + "nodeName": "IFRAME", + "localName": "iframe", + "nodeValue": "", + "childNodeCount": 0, + "children": [], + "attributes": [ + "src", + "resources/iframe.html" + ], + "frameId": "???", + "contentDocument": { + "nodeId": 18, + "nodeType": 9, + "nodeName": "#document", + "localName": "", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 19, + "nodeType": 1, + "nodeName": "HTML", + "localName": "html", + "nodeValue": "", + "childNodeCount": 2, + "children": [ + { + "nodeId": 20, + "nodeType": 1, + "nodeName": "HEAD", + "localName": "head", + "nodeValue": "", + "childNodeCount": 0, + "children": [], + "attributes": [] + }, + { + "nodeId": 21, + "nodeType": 1, + "nodeName": "BODY", + "localName": "body", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 22, + "nodeType": 1, + "nodeName": "DIV", + "localName": "div", + "nodeValue": "", + "childNodeCount": 0, + "children": [], + "attributes": [ + "id", + "element_in_an_iframe" + ] + } + ], + "attributes": [] + } + ], + "attributes": [], + "frameId": "???" + } + ], + "documentURL": "???", + "baseURL": "???", + "xmlVersion": "" + } + } + ], + "attributes": [ + "id", + "depth-3" + ] + } + ], + "attributes": [ + "id", + "depth-2" + ] + } + ], + "attributes": [ + "id", + "depth-1" + ] + } + ] + } +} +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames.html b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames.html new file mode 100644 index 0000000..e35f992 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-child-nodes-traverse-frames.html
@@ -0,0 +1,101 @@ +<html> +<head> +<script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-protocol-test.js"></script> +<script type="text/javascript"> + +function test() +{ + getDocument(); + + function getDocument() + { + InspectorTest.sendCommand("DOM.getDocument", {}, function(messageObject) { + if (messageObject.hasOwnProperty("error")) + InspectorTest.log("Backend error: " + messageObject.error.message + " (" + messageObject.error.code + ")\n"); + + var bodyId = messageObject.result.root.children[0].children[1].nodeId; + requestChildNodes(bodyId); + }); + }; + + function requestChildNodes(bodyId) + { + InspectorTest.sendCommand("DOM.requestChildNodes", {"nodeId": bodyId, "depth": -1}, function(messageObject) { + if (messageObject.hasOwnProperty("error")) + InspectorTest.log("Backend error: " + messageObject.error.message + " (" + messageObject.error.code + ")\n"); + }); + + InspectorTest.eventHandler["DOM.setChildNodes"] = function(messageObject) + { + var iframeContentDocument = messageObject.params.nodes[0].children[0].children[0].children[0].contentDocument; + if (iframeContentDocument.children) { + InspectorTest.log("Error IFrame node should not include children: " + JSON.stringify(iframeContentDocument, null, " ")); + InspectorTest.completeTest(); + } else { + getDocumentIncludingIframe(); + } + }; + }; + + function getDocumentIncludingIframe() + { + InspectorTest.sendCommand("DOM.getDocument", {"traverseFrames": true}, function(messageObject) { + if (messageObject.hasOwnProperty("error")) + InspectorTest.log("Backend error: " + messageObject.error.message + " (" + messageObject.error.code + ")\n"); + + var bodyId = messageObject.result.root.children[0].children[1].nodeId; + requestAllChildNodesIncludingIframe(bodyId); + }); + }; + + function replacePropertyRecursive(object, propertyNameToReplace) + { + for (var propertyName in object) { + if (!object.hasOwnProperty(propertyName)) + continue; + if (propertyName === propertyNameToReplace) { + object[propertyName] = "???"; + } else if (typeof object[propertyName] === "object") { + replacePropertyRecursive(object[propertyName], propertyNameToReplace); + } + } + } + + function requestAllChildNodesIncludingIframe(bodyId) + { + InspectorTest.sendCommand("DOM.requestChildNodes", {"nodeId": bodyId, "depth": -1, "traverseFrames": true}, function(messageObject) { + if (messageObject.hasOwnProperty("error")) + InspectorTest.log("Backend error: " + messageObject.error.message + " (" + messageObject.error.code + ")\n"); + }); + + InspectorTest.eventHandler["DOM.setChildNodes"] = function(messageObject) + { + // Replace properties that tend to change every run. + replacePropertyRecursive(messageObject, "frameId"); + replacePropertyRecursive(messageObject, "documentURL"); + replacePropertyRecursive(messageObject, "baseURL"); + + InspectorTest.log(JSON.stringify(messageObject, null, " ")); + InspectorTest.completeTest(); + }; + }; +}; + +window.addEventListener("DOMContentLoaded", function () { + runTest(); +}, false); + +</script> +</head> +<body> + +<div id="depth-1"> + <div id="depth-2"> + <div id="depth-3"> + <iframe src="resources/iframe.html"></iframe> + </div> + </div> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt new file mode 100644 index 0000000..97b1fba --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes-expected.txt
@@ -0,0 +1,128 @@ + +{ + "nodeId": 19, + "nodeType": 1, + "nodeName": "BODY", + "localName": "body", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 20, + "nodeType": 1, + "nodeName": "DIV", + "localName": "div", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 21, + "nodeType": 1, + "nodeName": "DIV", + "localName": "div", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 22, + "nodeType": 1, + "nodeName": "DIV", + "localName": "div", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 23, + "nodeType": 1, + "nodeName": "IFRAME", + "localName": "iframe", + "nodeValue": "", + "childNodeCount": 0, + "children": [], + "attributes": [ + "src", + "resources/iframe.html" + ], + "frameId": "???", + "contentDocument": { + "nodeId": 24, + "nodeType": 9, + "nodeName": "#document", + "localName": "", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 25, + "nodeType": 1, + "nodeName": "HTML", + "localName": "html", + "nodeValue": "", + "childNodeCount": 2, + "children": [ + { + "nodeId": 26, + "nodeType": 1, + "nodeName": "HEAD", + "localName": "head", + "nodeValue": "", + "childNodeCount": 0, + "children": [], + "attributes": [] + }, + { + "nodeId": 27, + "nodeType": 1, + "nodeName": "BODY", + "localName": "body", + "nodeValue": "", + "childNodeCount": 1, + "children": [ + { + "nodeId": 28, + "nodeType": 1, + "nodeName": "DIV", + "localName": "div", + "nodeValue": "", + "childNodeCount": 0, + "children": [], + "attributes": [ + "id", + "element_in_an_iframe" + ] + } + ], + "attributes": [] + } + ], + "attributes": [], + "frameId": "???" + } + ], + "documentURL": "???", + "baseURL": "???", + "xmlVersion": "" + } + } + ], + "attributes": [ + "id", + "depth-3" + ] + } + ], + "attributes": [ + "id", + "depth-2" + ] + } + ], + "attributes": [ + "id", + "depth-1" + ] + } + ], + "attributes": [] +} +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes.html b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes.html new file mode 100644 index 0000000..cf603ab --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/dom-request-document-with-child-nodes.html
@@ -0,0 +1,76 @@ +<html> +<head> +<script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-protocol-test.js"></script> +<script type="text/javascript"> + +function test() +{ + getDocument(); + + function getDocument() + { + InspectorTest.sendCommand("DOM.getDocument", {"depth": -1}, function(messageObject) { + if (messageObject.hasOwnProperty("error")) + InspectorTest.log("Backend error: " + messageObject.error.message + " (" + messageObject.error.code + ")\n"); + + var iframeOwner = messageObject.result.root.children[0].children[1].children[0].children[0].children[0].children[0]; + if (iframeOwner.contentDocument.children) { + InspectorTest.log("Error IFrame node should not include children: " + JSON.stringify(iframeOwner, null, " ")); + InspectorTest.completeTest(); + } else { + getDocumentPlusIframe(); + } + }); + }; + + function replacePropertyRecursive(object, propertyNameToReplace) + { + for (var propertyName in object) { + if (!object.hasOwnProperty(propertyName)) + continue; + if (propertyName === propertyNameToReplace) { + object[propertyName] = "???"; + } else if (typeof object[propertyName] === "object") { + replacePropertyRecursive(object[propertyName], propertyNameToReplace); + } + } + } + + function getDocumentPlusIframe() + { + InspectorTest.sendCommand("DOM.getDocument", {"depth": -1, "traverseFrames": true}, function(messageObject) { + if (messageObject.hasOwnProperty("error")) + InspectorTest.log("Backend error: " + messageObject.error.message + " (" + messageObject.error.code + ")\n"); + + var iframeOwner = messageObject.result.root.children[0].children[1].children[0].children[0].children[0].children[0]; + + // Replace properties that tend to change every run. + replacePropertyRecursive(messageObject, "frameId"); + replacePropertyRecursive(messageObject, "documentURL"); + replacePropertyRecursive(messageObject, "baseURL"); + + var bodyId = messageObject.result.root.children[0].children[1]; + InspectorTest.log(JSON.stringify(bodyId, null, " ")); + InspectorTest.completeTest(); + }); + }; +}; + +window.addEventListener("DOMContentLoaded", function () { + runTest(); +}, false); + +</script> +</head> +<body> + +<div id="depth-1"> + <div id="depth-2"> + <div id="depth-3"> + <iframe src="resources/iframe.html"></iframe> + </div> + </div> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/dom/resources/iframe.html b/third_party/WebKit/LayoutTests/inspector-protocol/dom/resources/iframe.html new file mode 100644 index 0000000..f416eb0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/dom/resources/iframe.html
@@ -0,0 +1,5 @@ +<html> +<body> +<div id="element_in_an_iframe"></div> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index 7030880..ce591860 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -4822,12 +4822,16 @@ method constructor interface RemotePlayback : EventTarget attribute @@toStringTag - getter onstatechange + getter onconnect + getter onconnecting + getter ondisconnect getter state method constructor method getAvailability method prompt - setter onstatechange + setter onconnect + setter onconnecting + setter ondisconnect interface RemotePlaybackAvailability : EventTarget attribute @@toStringTag getter onchange
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h index ea17b88..1b7688e 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
@@ -256,5 +256,68 @@ */ v8::EmbedderReachableReferenceReporter* m_reporter = nullptr; }; + +/** + * TraceWrapperMember is used for Member fields that should participate in + * wrapper tracing, i.e., strongly hold a ScriptWrappable alive. All + * TraceWrapperMember fields must be traced in the class' traceWrappers method. + */ +template <class T> +class TraceWrapperMember : public Member<T> { + DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + + public: + TraceWrapperMember(void* parent, T* raw) : Member<T>(raw), m_parent(parent) { +#if DCHECK_IS_ON() + DCHECK(!m_parent || HeapObjectHeader::fromPayload(m_parent)->checkHeader()); +#endif + ScriptWrappableVisitor::writeBarrier(m_parent, raw); + } + TraceWrapperMember(WTF::HashTableDeletedValueType x) + : Member<T>(x), m_parent(nullptr) {} + + /** + * Copying a TraceWrapperMember means that its backpointer will also be + * copied. + */ + TraceWrapperMember(const TraceWrapperMember& other) { *this = other; } + + template <typename U> + TraceWrapperMember& operator=(const TraceWrapperMember<U>& other) { + DCHECK(other.m_parent); + m_parent = other.m_parent; + Member<T>::operator=(other); + ScriptWrappableVisitor::writeBarrier(m_parent, other); + return *this; + } + + template <typename U> + TraceWrapperMember& operator=(const Member<U>& other) { + DCHECK(m_parent); + Member<T>::operator=(other); + ScriptWrappableVisitor::writeBarrier(m_parent, other); + return *this; + } + + template <typename U> + TraceWrapperMember& operator=(U* other) { + DCHECK(m_parent); + Member<T>::operator=(other); + ScriptWrappableVisitor::writeBarrier(m_parent, other); + return *this; + } + + TraceWrapperMember& operator=(std::nullptr_t) { + // No need for a write barrier when assigning nullptr. + Member<T>::operator=(nullptr); + return *this; + } + + private: + /** + * The parent object holding strongly onto the actual Member. + */ + void* m_parent; +}; } #endif
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp index 4e934d0..090e36c 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp
@@ -29,6 +29,15 @@ V8GCController::collectGarbage(isolate, false); } +static bool DequeContains(const WTF::Deque<WrapperMarkingData>& deque, + DeathAwareScriptWrappable* needle) { + for (auto item : deque) { + if (item.rawObjectPointer() == needle) + return true; + } + return false; +} + TEST(ScriptWrappableVisitorTest, ScriptWrappableVisitorTracesWrappers) { V8TestingScope scope; if (!RuntimeEnabledFeatures::traceWrappablesEnabled()) { @@ -40,7 +49,7 @@ DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::create(); DeathAwareScriptWrappable* dependency = DeathAwareScriptWrappable::create(); - target->setDependency(dependency); + target->setRawDependency(dependency); HeapObjectHeader* targetHeader = HeapObjectHeader::fromPayload(target); HeapObjectHeader* dependencyHeader = @@ -209,7 +218,7 @@ EXPECT_TRUE(visitor->getMarkingDeque()->isEmpty()); - target->setDependency(dependency); + target->setRawDependency(dependency); EXPECT_TRUE(visitor->getMarkingDeque()->isEmpty()); } @@ -225,14 +234,22 @@ V8PerIsolateData::from(scope.isolate())->scriptWrappableVisitor(); DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::create(); - DeathAwareScriptWrappable* dependency = DeathAwareScriptWrappable::create(); + DeathAwareScriptWrappable* dependencies[] = { + DeathAwareScriptWrappable::create(), DeathAwareScriptWrappable::create(), + DeathAwareScriptWrappable::create(), DeathAwareScriptWrappable::create(), + DeathAwareScriptWrappable::create()}; HeapObjectHeader::fromPayload(target)->markWrapperHeader(); - HeapObjectHeader::fromPayload(dependency)->markWrapperHeader(); + for (int i = 0; i < 5; i++) { + HeapObjectHeader::fromPayload(dependencies[i])->markWrapperHeader(); + } EXPECT_TRUE(visitor->getMarkingDeque()->isEmpty()); - target->setDependency(dependency); + target->setRawDependency(dependencies[0]); + target->setWrappedDependency(dependencies[1]); + target->addWrappedVectorDependency(dependencies[2]); + target->addWrappedHashMapDependency(dependencies[3], dependencies[4]); EXPECT_TRUE(visitor->getMarkingDeque()->isEmpty()); } @@ -248,15 +265,23 @@ V8PerIsolateData::from(scope.isolate())->scriptWrappableVisitor(); DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::create(); - DeathAwareScriptWrappable* dependency = DeathAwareScriptWrappable::create(); + DeathAwareScriptWrappable* dependencies[] = { + DeathAwareScriptWrappable::create(), DeathAwareScriptWrappable::create(), + DeathAwareScriptWrappable::create(), DeathAwareScriptWrappable::create(), + DeathAwareScriptWrappable::create()}; HeapObjectHeader::fromPayload(target)->markWrapperHeader(); EXPECT_TRUE(visitor->getMarkingDeque()->isEmpty()); - target->setDependency(dependency); + target->setRawDependency(dependencies[0]); + target->setWrappedDependency(dependencies[1]); + target->addWrappedVectorDependency(dependencies[2]); + target->addWrappedHashMapDependency(dependencies[3], dependencies[4]); - EXPECT_EQ(visitor->getMarkingDeque()->first().rawObjectPointer(), dependency); + for (int i = 0; i < 5; i++) { + EXPECT_TRUE(DequeContains(*visitor->getMarkingDeque(), dependencies[i])); + } visitor->getMarkingDeque()->clear(); visitor->getVerifierDeque()->clear();
diff --git a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp index 57e48b3..9c3f564 100644 --- a/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp +++ b/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
@@ -231,9 +231,10 @@ void RemoteFontFaceSource::beginLoadIfNeeded() { if (m_fontSelector->document() && m_font->stillNeedsLoad()) { m_fontSelector->document()->fetcher()->startLoad(m_font); + if (!m_font->isLoaded()) + m_font->startLoadLimitTimers(); m_histograms.loadStarted(); } - m_font->startLoadLimitTimersIfNeeded(); if (m_face) m_face->didBeginLoad();
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp index f1292c44..e7766f1 100644 --- a/third_party/WebKit/Source/core/dom/Node.cpp +++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -1816,7 +1816,7 @@ EventHandlerRegistry::didMoveBetweenFrameHosts( *this, oldDocument.frameHost(), document().frameHost()); - if (HeapVector<Member<MutationObserverRegistration>>* registry = + if (HeapVector<TraceWrapperMember<MutationObserverRegistration>>* registry = mutationObserverRegistry()) { for (size_t i = 0; i < registry->size(); ++i) { document().addMutationObserverTypes(registry->at(i)->mutationTypes()); @@ -1889,7 +1889,7 @@ return *data; } -HeapVector<Member<MutationObserverRegistration>>* +HeapVector<TraceWrapperMember<MutationObserverRegistration>>* Node::mutationObserverRegistry() { if (!hasRareData()) return nullptr; @@ -1961,7 +1961,7 @@ MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter) { MutationObserverRegistration* registration = nullptr; - HeapVector<Member<MutationObserverRegistration>>& registry = + HeapVector<TraceWrapperMember<MutationObserverRegistration>>& registry = ensureRareData().ensureMutationObserverData().registry; for (size_t i = 0; i < registry.size(); ++i) { if (®istry[i]->observer() == &observer) { @@ -1971,10 +1971,10 @@ } if (!registration) { - registry.append(MutationObserverRegistration::create( - observer, this, options, attributeFilter)); - registration = registry.last().get(); - ScriptWrappableVisitor::writeBarrier(this, registration); + registration = MutationObserverRegistration::create(observer, this, options, + attributeFilter); + registry.append( + TraceWrapperMember<MutationObserverRegistration>(this, registration)); } document().addMutationObserverTypes(registration->mutationTypes()); @@ -1982,7 +1982,7 @@ void Node::unregisterMutationObserver( MutationObserverRegistration* registration) { - HeapVector<Member<MutationObserverRegistration>>* registry = + HeapVector<TraceWrapperMember<MutationObserverRegistration>>* registry = mutationObserverRegistry(); DCHECK(registry); if (!registry) @@ -2024,7 +2024,7 @@ ScriptForbiddenScope forbidScriptDuringRawIteration; for (Node* node = parentNode(); node; node = node->parentNode()) { - if (HeapVector<Member<MutationObserverRegistration>>* registry = + if (HeapVector<TraceWrapperMember<MutationObserverRegistration>>* registry = node->mutationObserverRegistry()) { const size_t size = registry->size(); for (size_t i = 0; i < size; ++i)
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h index bca9099..d058ecf6 100644 --- a/third_party/WebKit/Source/core/dom/Node.h +++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -935,7 +935,8 @@ void trackForDebugging(); - HeapVector<Member<MutationObserverRegistration>>* mutationObserverRegistry(); + HeapVector<TraceWrapperMember<MutationObserverRegistration>>* + mutationObserverRegistry(); HeapHashSet<Member<MutationObserverRegistration>>* transientMutationObserverRegistry();
diff --git a/third_party/WebKit/Source/core/dom/NodeIntersectionObserverData.cpp b/third_party/WebKit/Source/core/dom/NodeIntersectionObserverData.cpp index 3041915..7a3fc71f 100644 --- a/third_party/WebKit/Source/core/dom/NodeIntersectionObserverData.cpp +++ b/third_party/WebKit/Source/core/dom/NodeIntersectionObserverData.cpp
@@ -4,7 +4,6 @@ #include "core/dom/NodeIntersectionObserverData.h" -#include "bindings/core/v8/ScriptWrappableVisitor.h" #include "core/dom/Document.h" #include "core/dom/IntersectionObservation.h" #include "core/dom/IntersectionObserver.h" @@ -24,8 +23,9 @@ void NodeIntersectionObserverData::addObservation( IntersectionObservation& observation) { - m_intersectionObservations.add(&observation.observer(), &observation); - ScriptWrappableVisitor::writeBarrier(this, &observation.observer()); + m_intersectionObservations.add( + TraceWrapperMember<IntersectionObserver>(this, &observation.observer()), + &observation); } void NodeIntersectionObserverData::removeObservation(
diff --git a/third_party/WebKit/Source/core/dom/NodeIntersectionObserverData.h b/third_party/WebKit/Source/core/dom/NodeIntersectionObserverData.h index 997d577..72b56bf3 100644 --- a/third_party/WebKit/Source/core/dom/NodeIntersectionObserverData.h +++ b/third_party/WebKit/Source/core/dom/NodeIntersectionObserverData.h
@@ -5,6 +5,7 @@ #ifndef NodeIntersectionObserverData_h #define NodeIntersectionObserverData_h +#include "bindings/core/v8/ScriptWrappableVisitor.h" #include "platform/heap/Handle.h" namespace blink { @@ -32,7 +33,8 @@ // IntersectionObservers for which the Node owning this data is root. HeapHashSet<WeakMember<IntersectionObserver>> m_intersectionObservers; // IntersectionObservations for which the Node owning this data is target. - HeapHashMap<Member<IntersectionObserver>, Member<IntersectionObservation>> + HeapHashMap<TraceWrapperMember<IntersectionObserver>, + Member<IntersectionObservation>> m_intersectionObservations; };
diff --git a/third_party/WebKit/Source/core/dom/NodeRareData.h b/third_party/WebKit/Source/core/dom/NodeRareData.h index 2e2de6c..cf78936 100644 --- a/third_party/WebKit/Source/core/dom/NodeRareData.h +++ b/third_party/WebKit/Source/core/dom/NodeRareData.h
@@ -35,7 +35,7 @@ WTF_MAKE_NONCOPYABLE(NodeMutationObserverData); public: - HeapVector<Member<MutationObserverRegistration>> registry; + HeapVector<TraceWrapperMember<MutationObserverRegistration>> registry; HeapHashSet<Member<MutationObserverRegistration>> transientRegistry; static NodeMutationObserverData* create() {
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp index 04d893e..0eee09a 100644 --- a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
@@ -52,33 +52,35 @@ template <typename Strategy> VisibleSelectionTemplate<Strategy>::VisibleSelectionTemplate( - const PositionTemplate<Strategy>& base, - const PositionTemplate<Strategy>& extent, - TextAffinity affinity, - bool isDirectional) - : m_base(base), - m_extent(extent), - m_affinity(affinity), - m_isDirectional(isDirectional), - m_granularity(CharacterGranularity), - m_hasTrailingWhitespace(false) { + const SelectionTemplate<Strategy>& selection) + : m_base(selection.base()), + m_extent(selection.extent()), + m_affinity(selection.affinity()), + m_isDirectional(selection.isDirectional()), + m_granularity(selection.granularity()), + m_hasTrailingWhitespace(selection.hasTrailingWhitespace()) { validate(); } template <typename Strategy> VisibleSelectionTemplate<Strategy> VisibleSelectionTemplate<Strategy>::create( - const PositionTemplate<Strategy>& base, - const PositionTemplate<Strategy>& extent, - TextAffinity affinity, - bool isDirectional) { - return VisibleSelectionTemplate(base, extent, affinity, isDirectional); + const SelectionTemplate<Strategy>& selection) { + return VisibleSelectionTemplate(selection); +} + +VisibleSelection createVisibleSelection(const SelectionInDOMTree& selection) { + return VisibleSelection::create(selection); } VisibleSelection createVisibleSelection(const Position& pos, TextAffinity affinity, bool isDirectional) { DCHECK(!needsLayoutTreeUpdate(pos)); - return VisibleSelection::create(pos, pos, affinity, isDirectional); + SelectionInDOMTree::Builder builder; + builder.setAffinity(affinity).setIsDirectional(isDirectional); + if (pos.isNotNull()) + builder.collapse(pos); + return createVisibleSelection(builder.build()); } VisibleSelection createVisibleSelection(const Position& base, @@ -87,23 +89,24 @@ bool isDirectional) { DCHECK(!needsLayoutTreeUpdate(base)); DCHECK(!needsLayoutTreeUpdate(extent)); - // TODO(xiaochengh): We should check |base.isNotNull() || extent.isNull()| - // after all call sites have ensured that. - return VisibleSelection::create(base, extent, affinity, isDirectional); + // TODO(yosin): We should use |Builder::setBaseAndExtent()| once we get rid + // of callers passing |base.istNull()| but |extent.isNotNull()|. + SelectionInDOMTree::Builder builder; + builder.setBaseAndExtentDeprecated(base, extent) + .setAffinity(affinity) + .setIsDirectional(isDirectional); + return createVisibleSelection(builder.build()); } VisibleSelection createVisibleSelection(const PositionWithAffinity& pos, bool isDirectional) { - DCHECK(!needsLayoutTreeUpdate(pos.position())); - return VisibleSelection::create(pos.position(), pos.position(), - pos.affinity(), isDirectional); + return createVisibleSelection(pos.position(), pos.affinity(), isDirectional); } VisibleSelection createVisibleSelection(const VisiblePosition& pos, bool isDirectional) { - DCHECK(pos.isValid()); - return VisibleSelection::create(pos.deepEquivalent(), pos.deepEquivalent(), - pos.affinity(), isDirectional); + return createVisibleSelection(pos.deepEquivalent(), pos.affinity(), + isDirectional); } VisibleSelection createVisibleSelection(const VisiblePosition& base, @@ -111,11 +114,8 @@ bool isDirectional) { DCHECK(base.isValid()); DCHECK(extent.isValid()); - // TODO(xiaochengh): We should check |base.isNotNull() || extent.isNull()| - // after all call sites have ensured that. - return VisibleSelection::create(base.deepEquivalent(), - extent.deepEquivalent(), base.affinity(), - isDirectional); + return createVisibleSelection(base.deepEquivalent(), extent.deepEquivalent(), + base.affinity(), isDirectional); } VisibleSelection createVisibleSelection(const EphemeralRange& range, @@ -123,15 +123,26 @@ bool isDirectional) { DCHECK(!needsLayoutTreeUpdate(range.startPosition())); DCHECK(!needsLayoutTreeUpdate(range.endPosition())); - return VisibleSelection::create(range.startPosition(), range.endPosition(), - affinity, isDirectional); + SelectionInDOMTree::Builder builder; + builder.setBaseAndExtent(range).setAffinity(affinity).setIsDirectional( + isDirectional); + return createVisibleSelection(builder.build()); +} + +VisibleSelectionInFlatTree createVisibleSelection( + const SelectionInFlatTree& selection) { + return VisibleSelectionInFlatTree::create(selection); } VisibleSelectionInFlatTree createVisibleSelection(const PositionInFlatTree& pos, TextAffinity affinity, bool isDirectional) { DCHECK(!needsLayoutTreeUpdate(pos)); - return VisibleSelectionInFlatTree::create(pos, pos, affinity, isDirectional); + SelectionInFlatTree::Builder builder; + builder.setAffinity(affinity).setIsDirectional(isDirectional); + if (pos.isNotNull()) + builder.collapse(pos); + return createVisibleSelection(builder.build()); } VisibleSelectionInFlatTree createVisibleSelection( @@ -141,27 +152,27 @@ bool isDirectional) { DCHECK(!needsLayoutTreeUpdate(base)); DCHECK(!needsLayoutTreeUpdate(extent)); - // TODO(xiaochengh): We should check |base.isNotNull() || extent.isNull()| - // after all call sites have ensured that. - return VisibleSelectionInFlatTree::create(base, extent, affinity, - isDirectional); + // TODO(yosin): We should use |Builder::setBaseAndExtent()| once we get rid + // of callers passing |base.istNull()| but |extent.isNotNull()|. + SelectionInFlatTree::Builder builder; + builder.setBaseAndExtentDeprecated(base, extent) + .setAffinity(affinity) + .setIsDirectional(isDirectional); + return createVisibleSelection(builder.build()); } VisibleSelectionInFlatTree createVisibleSelection( const PositionInFlatTreeWithAffinity& pos, bool isDirectional) { - DCHECK(!needsLayoutTreeUpdate(pos.position())); - return VisibleSelectionInFlatTree::create(pos.position(), pos.position(), - pos.affinity(), isDirectional); + return createVisibleSelection(pos.position(), pos.affinity(), isDirectional); } VisibleSelectionInFlatTree createVisibleSelection( const VisiblePositionInFlatTree& pos, bool isDirectional) { DCHECK(pos.isValid()); - return VisibleSelectionInFlatTree::create(pos.deepEquivalent(), - pos.deepEquivalent(), - pos.affinity(), isDirectional); + return createVisibleSelection(pos.deepEquivalent(), pos.affinity(), + isDirectional); } VisibleSelectionInFlatTree createVisibleSelection( @@ -172,9 +183,8 @@ DCHECK(extent.isValid()); // TODO(xiaochengh): We should check |base.isNotNull() || extent.isNull()| // after all call sites have ensured that. - return VisibleSelectionInFlatTree::create(base.deepEquivalent(), - extent.deepEquivalent(), - base.affinity(), isDirectional); + return createVisibleSelection(base.deepEquivalent(), extent.deepEquivalent(), + base.affinity(), isDirectional); } VisibleSelectionInFlatTree createVisibleSelection( @@ -183,8 +193,10 @@ bool isDirectional) { DCHECK(!needsLayoutTreeUpdate(range.startPosition())); DCHECK(!needsLayoutTreeUpdate(range.endPosition())); - return VisibleSelectionInFlatTree::create( - range.startPosition(), range.endPosition(), affinity, isDirectional); + SelectionInFlatTree::Builder builder; + builder.setBaseAndExtent(range).setAffinity(affinity).setIsDirectional( + isDirectional); + return createVisibleSelection(builder.build()); } template <typename Strategy> @@ -246,10 +258,10 @@ // needs to be audited. see http://crbug.com/590369 for more details. node->document().updateStyleAndLayoutIgnorePendingStylesheets(); - return VisibleSelectionTemplate::create( - PositionTemplate<Strategy>::firstPositionInNode(node), - PositionTemplate<Strategy>::lastPositionInNode(node), SelDefaultAffinity, - false); + typename SelectionTemplate<Strategy>::Builder builder; + builder.collapse(PositionTemplate<Strategy>::firstPositionInNode(node)) + .extend(PositionTemplate<Strategy>::lastPositionInNode(node)); + return VisibleSelectionTemplate::create(builder.build()); } template <typename Strategy>
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelection.h b/third_party/WebKit/Source/core/editing/VisibleSelection.h index 4c68c5a3..68e7010 100644 --- a/third_party/WebKit/Source/core/editing/VisibleSelection.h +++ b/third_party/WebKit/Source/core/editing/VisibleSelection.h
@@ -29,6 +29,7 @@ #include "core/CoreExport.h" #include "core/editing/EditingStrategy.h" #include "core/editing/EphemeralRange.h" +#include "core/editing/SelectionTemplate.h" #include "core/editing/SelectionType.h" #include "core/editing/TextAffinity.h" #include "core/editing/TextGranularity.h" @@ -60,12 +61,7 @@ // Note: |create()| should be used only by |createVisibleSelection| and // |selectionFromContentsOfNode|. - // TODO(xiaochengh): Use enum class instead of boolean parameter. - static VisibleSelectionTemplate create( - const PositionTemplate<Strategy>& base, - const PositionTemplate<Strategy>& extent, - TextAffinity, - bool isDirectional); + static VisibleSelectionTemplate create(const SelectionTemplate<Strategy>&); static VisibleSelectionTemplate selectionFromContentsOfNode(Node*); @@ -74,6 +70,9 @@ void setAffinity(TextAffinity affinity) { m_affinity = affinity; } TextAffinity affinity() const { return m_affinity; } + // TODO(yosin): To make |VisibleSelection| as immutable object, we should + // get rid of |setBase()| and |setExtent()| by replacing them with + // |createVisibleSelection()|. void setBase(const PositionTemplate<Strategy>&); void setBase(const VisiblePositionTemplate<Strategy>&); void setExtent(const PositionTemplate<Strategy>&); @@ -161,10 +160,7 @@ private: friend class SelectionAdjuster; - VisibleSelectionTemplate(const PositionTemplate<Strategy>& base, - const PositionTemplate<Strategy>& extent, - TextAffinity, - bool isDirectional); + VisibleSelectionTemplate(const SelectionTemplate<Strategy>&); void validate(TextGranularity = CharacterGranularity); @@ -214,7 +210,9 @@ using VisibleSelectionInFlatTree = VisibleSelectionTemplate<EditingInFlatTreeStrategy>; -// TODO(xiaochengh): Introduce builder class to get rid of these overloads. +// TODO(yosin): We should get rid of |createVisibleSelection()| overloads +// except for taking |SelectionInDOMTree| and |SelectionInFlatTree|. +CORE_EXPORT VisibleSelection createVisibleSelection(const SelectionInDOMTree&); CORE_EXPORT VisibleSelection createVisibleSelection(const Position&, TextAffinity, bool isDirectional = false); @@ -236,6 +234,8 @@ bool isDirectional = false); CORE_EXPORT VisibleSelectionInFlatTree +createVisibleSelection(const SelectionInFlatTree&); +CORE_EXPORT VisibleSelectionInFlatTree createVisibleSelection(const PositionInFlatTree&, TextAffinity, bool isDirectional = false);
diff --git a/third_party/WebKit/Source/core/fetch/FontResource.cpp b/third_party/WebKit/Source/core/fetch/FontResource.cpp index a5314e8..2de0a24 100644 --- a/third_party/WebKit/Source/core/fetch/FontResource.cpp +++ b/third_party/WebKit/Source/core/fetch/FontResource.cpp
@@ -83,7 +83,7 @@ FontResource::FontResource(const ResourceRequest& resourceRequest, const ResourceLoaderOptions& options) : Resource(resourceRequest, Font, options), - m_loadLimitState(UnderLimit), + m_loadLimitState(LoadNotStarted), m_corsFailed(false), m_fontLoadShortLimitTimer(this, &FontResource::fontLoadShortLimitCallback), @@ -105,15 +105,14 @@ void FontResource::setRevalidatingRequest(const ResourceRequest& request) { // Reload will use the same object, and needs to reset |m_loadLimitState| // before any didAddClient() is called again. - m_loadLimitState = UnderLimit; + m_loadLimitState = LoadNotStarted; Resource::setRevalidatingRequest(request); } -void FontResource::startLoadLimitTimersIfNeeded() { - DCHECK(!stillNeedsLoad()); - if (isLoaded() || m_fontLoadLongLimitTimer.isActive()) - return; - DCHECK_EQ(m_loadLimitState, UnderLimit); +void FontResource::startLoadLimitTimers() { + DCHECK(isLoading()); + DCHECK_EQ(m_loadLimitState, LoadNotStarted); + m_loadLimitState = UnderLimit; m_fontLoadShortLimitTimer.startOneShot(fontLoadWaitShortLimitSec, BLINK_FROM_HERE); m_fontLoadLongLimitTimer.startOneShot(fontLoadWaitLongLimitSec,
diff --git a/third_party/WebKit/Source/core/fetch/FontResource.h b/third_party/WebKit/Source/core/fetch/FontResource.h index 97ea91f2e..e83ab31 100644 --- a/third_party/WebKit/Source/core/fetch/FontResource.h +++ b/third_party/WebKit/Source/core/fetch/FontResource.h
@@ -54,7 +54,7 @@ void setRevalidatingRequest(const ResourceRequest&) override; void allClientsAndObserversRemoved() override; - void startLoadLimitTimersIfNeeded(); + void startLoadLimitTimers(); void setCORSFailed() override { m_corsFailed = true; } bool isCORSFailed() const { return m_corsFailed; } @@ -84,7 +84,12 @@ void fontLoadShortLimitCallback(TimerBase*); void fontLoadLongLimitCallback(TimerBase*); - enum LoadLimitState { UnderLimit, ShortLimitExceeded, LongLimitExceeded }; + enum LoadLimitState { + LoadNotStarted, + UnderLimit, + ShortLimitExceeded, + LongLimitExceeded + }; std::unique_ptr<FontCustomPlatformData> m_fontData; String m_otsParsingMessage;
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp index 099ed908..2ac47d8 100644 --- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -699,6 +699,30 @@ String encodingMimeType = toEncodingMimeType(mimeType, EncodeReasonToDataURL); + Optional<ScopedUsHistogramTimer> timer; + if (encodingMimeType == "image/png") { + DEFINE_THREAD_SAFE_STATIC_LOCAL( + CustomCountHistogram, scopedUsCounterPNG, + new CustomCountHistogram("Blink.Canvas.ToDataURL.PNG", 0, 10000000, + 50)); + timer.emplace(scopedUsCounterPNG); + } else if (encodingMimeType == "image/jpeg") { + DEFINE_THREAD_SAFE_STATIC_LOCAL( + CustomCountHistogram, scopedUsCounterJPEG, + new CustomCountHistogram("Blink.Canvas.ToDataURL.JPEG", 0, 10000000, + 50)); + timer.emplace(scopedUsCounterJPEG); + } else if (encodingMimeType == "image/webp") { + DEFINE_THREAD_SAFE_STATIC_LOCAL( + CustomCountHistogram, scopedUsCounterWEBP, + new CustomCountHistogram("Blink.Canvas.ToDataURL.WEBP", 0, 10000000, + 50)); + timer.emplace(scopedUsCounterWEBP); + } else { + // Currently we only support three encoding types. + NOTREACHED(); + } + ImageData* imageData = toImageData(sourceBuffer, SnapshotReasonToDataURL); if (!imageData) // allocation failure @@ -722,61 +746,6 @@ exceptionState.throwSecurityError("Tainted canvases may not be exported."); return String(); } - Optional<ScopedUsHistogramTimer> timer; - String lowercaseMimeType = mimeType.lower(); - if (mimeType.isNull()) - lowercaseMimeType = DefaultMimeType; - if (lowercaseMimeType == "image/png") { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, scopedUsCounterPNG, - new CustomCountHistogram("Blink.Canvas.ToDataURL.PNG", 0, 10000000, - 50)); - timer.emplace(scopedUsCounterPNG); - } else if (lowercaseMimeType == "image/jpeg") { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, scopedUsCounterJPEG, - new CustomCountHistogram("Blink.Canvas.ToDataURL.JPEG", 0, 10000000, - 50)); - timer.emplace(scopedUsCounterJPEG); - } else if (lowercaseMimeType == "image/webp") { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, scopedUsCounterWEBP, - new CustomCountHistogram("Blink.Canvas.ToDataURL.WEBP", 0, 10000000, - 50)); - timer.emplace(scopedUsCounterWEBP); - } else if (lowercaseMimeType == "image/gif") { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, scopedUsCounterGIF, - new CustomCountHistogram("Blink.Canvas.ToDataURL.GIF", 0, 10000000, - 50)); - timer.emplace(scopedUsCounterGIF); - } else if (lowercaseMimeType == "image/bmp" || - lowercaseMimeType == "image/x-windows-bmp") { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, scopedUsCounterBMP, - new CustomCountHistogram("Blink.Canvas.ToDataURL.BMP", 0, 10000000, - 50)); - timer.emplace(scopedUsCounterBMP); - } else if (lowercaseMimeType == "image/x-icon") { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, scopedUsCounterICON, - new CustomCountHistogram("Blink.Canvas.ToDataURL.ICON", 0, 10000000, - 50)); - timer.emplace(scopedUsCounterICON); - } else if (lowercaseMimeType == "image/tiff" || - lowercaseMimeType == "image/x-tiff") { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, scopedUsCounterTIFF, - new CustomCountHistogram("Blink.Canvas.ToDataURL.TIFF", 0, 10000000, - 50)); - timer.emplace(scopedUsCounterTIFF); - } else { - DEFINE_THREAD_SAFE_STATIC_LOCAL( - CustomCountHistogram, scopedUsCounterUnknown, - new CustomCountHistogram("Blink.Canvas.ToDataURL.Unknown", 0, 10000000, - 50)); - timer.emplace(scopedUsCounterUnknown); - } double quality = UndefinedQualityValue; if (!qualityArgument.isEmpty()) {
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp index 7b9109c7..79583d0 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
@@ -161,9 +161,7 @@ const CharacterType* end, int& value) { // Step 3 - // We do not do this step and do not have a local sign - // variable since due to a bug in charactersToIntStrict - // we have to add the sign to the digits string. + bool isNegative = false; // Step 4 while (position < end) { @@ -178,9 +176,8 @@ ASSERT(position < end); // Step 6 - StringBuilder digits; if (*position == '-') { - digits.append('-'); + isNegative = true; ++position; } else if (*position == '+') ++position; @@ -193,19 +190,22 @@ return false; // Step 8 - while (position < end) { - if (!isASCIIDigit(*position)) - break; - digits.append(*position++); - } + static const int intMax = std::numeric_limits<int>::max(); + const int base = 10; + const int maxMultiplier = intMax / base; + unsigned temp = 0; + do { + int digitValue = *position - '0'; + if (temp > maxMultiplier || + (temp == maxMultiplier && digitValue > (intMax % base) + isNegative)) + return false; + temp = temp * base + digitValue; + ++position; + } while (position < end && isASCIIDigit(*position)); // Step 9 - bool ok; - if (digits.is8Bit()) - value = charactersToIntStrict(digits.characters8(), digits.length(), &ok); - else - value = charactersToIntStrict(digits.characters16(), digits.length(), &ok); - return ok; + value = isNegative ? (0 - temp) : temp; + return true; } // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h b/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h index f10637e8..61f96ff 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h +++ b/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
@@ -58,7 +58,7 @@ double fallbackValue = std::numeric_limits<double>::quiet_NaN()); // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers -bool parseHTMLInteger(const String&, int&); +CORE_EXPORT bool parseHTMLInteger(const String&, int&); // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-non-negative-integers CORE_EXPORT bool parseHTMLNonNegativeInteger(const String&, unsigned&);
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserIdiomsTest.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserIdiomsTest.cpp index d9b4ade7..556058f 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLParserIdiomsTest.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLParserIdiomsTest.cpp
@@ -10,6 +10,26 @@ namespace { +TEST(HTMLParserIdiomsTest, ParseHTMLInteger) { + int value = 0; + + EXPECT_TRUE(parseHTMLInteger("2147483646", value)); + EXPECT_EQ(2147483646, value); + EXPECT_TRUE(parseHTMLInteger("2147483647", value)); + EXPECT_EQ(2147483647, value); + value = 12345; + EXPECT_FALSE(parseHTMLInteger("2147483648", value)); + EXPECT_EQ(12345, value); + + EXPECT_TRUE(parseHTMLInteger("-2147483647", value)); + EXPECT_EQ(-2147483647, value); + EXPECT_TRUE(parseHTMLInteger("-2147483648", value)); + EXPECT_EQ(0 - 2147483648, value); + value = 12345; + EXPECT_FALSE(parseHTMLInteger("-2147483649", value)); + EXPECT_EQ(12345, value); +} + TEST(HTMLParserIdiomsTest, ParseHTMLNonNegativeInteger) { unsigned value = 0;
diff --git a/third_party/WebKit/Source/core/html/track/TextTrack.cpp b/third_party/WebKit/Source/core/html/track/TextTrack.cpp index 392d67f8..70caa74 100644 --- a/third_party/WebKit/Source/core/html/track/TextTrack.cpp +++ b/third_party/WebKit/Source/core/html/track/TextTrack.cpp
@@ -33,7 +33,6 @@ #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/ExceptionStatePlaceholder.h" -#include "bindings/core/v8/ScriptWrappableVisitor.h" #include "core/dom/ExceptionCode.h" #include "core/html/HTMLMediaElement.h" #include "core/html/track/CueTimeline.h" @@ -94,6 +93,7 @@ TextTrackType type) : TrackBase(WebMediaPlayer::TextTrack, kind, label, language, id), m_cues(nullptr), + m_activeCues(this, nullptr), m_regions(nullptr), m_trackList(nullptr), m_mode(disabledKeyword()), @@ -209,7 +209,6 @@ if (!m_activeCues) { m_activeCues = TextTrackCueList::create(); - ScriptWrappableVisitor::writeBarrier(this, m_activeCues); } m_cues->collectActiveCues(*m_activeCues);
diff --git a/third_party/WebKit/Source/core/html/track/TextTrack.h b/third_party/WebKit/Source/core/html/track/TextTrack.h index 45dbbef..68359273 100644 --- a/third_party/WebKit/Source/core/html/track/TextTrack.h +++ b/third_party/WebKit/Source/core/html/track/TextTrack.h
@@ -27,6 +27,7 @@ #ifndef TextTrack_h #define TextTrack_h +#include "bindings/core/v8/ScriptWrappableVisitor.h" #include "core/CoreExport.h" #include "core/events/EventTarget.h" #include "core/html/track/TrackBase.h" @@ -148,7 +149,7 @@ TextTrackCueList* ensureTextTrackCueList(); Member<TextTrackCueList> m_cues; - Member<TextTrackCueList> m_activeCues; + TraceWrapperMember<TextTrackCueList> m_activeCues; VTTRegionList* ensureVTTRegionList(); Member<VTTRegionList> m_regions;
diff --git a/third_party/WebKit/Source/core/html/track/TextTrackList.cpp b/third_party/WebKit/Source/core/html/track/TextTrackList.cpp index 4991551..a5aa142 100644 --- a/third_party/WebKit/Source/core/html/track/TextTrackList.cpp +++ b/third_party/WebKit/Source/core/html/track/TextTrackList.cpp
@@ -140,7 +140,7 @@ } void TextTrackList::invalidateTrackIndexesAfterTrack(TextTrack* track) { - HeapVector<Member<TextTrack>>* tracks = nullptr; + HeapVector<TraceWrapperMember<TextTrack>>* tracks = nullptr; if (track->trackType() == TextTrack::TrackElement) { tracks = &m_elementTracks; @@ -168,17 +168,16 @@ void TextTrackList::append(TextTrack* track) { if (track->trackType() == TextTrack::AddTrack) { - m_addTrackTracks.append(track); + m_addTrackTracks.append(TraceWrapperMember<TextTrack>(this, track)); } else if (track->trackType() == TextTrack::TrackElement) { // Insert tracks added for <track> element in tree order. size_t index = static_cast<LoadableTextTrack*>(track)->trackElementIndex(); - m_elementTracks.insert(index, track); + m_elementTracks.insert(index, TraceWrapperMember<TextTrack>(this, track)); } else if (track->trackType() == TextTrack::InBand) { - m_inbandTracks.append(track); + m_inbandTracks.append(TraceWrapperMember<TextTrack>(this, track)); } else { NOTREACHED(); } - ScriptWrappableVisitor::writeBarrier(this, track); invalidateTrackIndexesAfterTrack(track); @@ -189,7 +188,7 @@ } void TextTrackList::remove(TextTrack* track) { - HeapVector<Member<TextTrack>>* tracks = nullptr; + HeapVector<TraceWrapperMember<TextTrack>>* tracks = nullptr; if (track->trackType() == TextTrack::TrackElement) { tracks = &m_elementTracks; @@ -223,7 +222,7 @@ } bool TextTrackList::contains(TextTrack* track) const { - const HeapVector<Member<TextTrack>>* tracks = nullptr; + const HeapVector<TraceWrapperMember<TextTrack>>* tracks = nullptr; if (track->trackType() == TextTrack::TrackElement) tracks = &m_elementTracks;
diff --git a/third_party/WebKit/Source/core/html/track/TextTrackList.h b/third_party/WebKit/Source/core/html/track/TextTrackList.h index 0f639d7..e893856 100644 --- a/third_party/WebKit/Source/core/html/track/TextTrackList.h +++ b/third_party/WebKit/Source/core/html/track/TextTrackList.h
@@ -91,9 +91,9 @@ Member<GenericEventQueue> m_asyncEventQueue; - HeapVector<Member<TextTrack>> m_addTrackTracks; - HeapVector<Member<TextTrack>> m_elementTracks; - HeapVector<Member<TextTrack>> m_inbandTracks; + HeapVector<TraceWrapperMember<TextTrack>> m_addTrackTracks; + HeapVector<TraceWrapperMember<TextTrack>> m_elementTracks; + HeapVector<TraceWrapperMember<TextTrack>> m_inbandTracks; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/html/track/TrackListBase.h b/third_party/WebKit/Source/core/html/track/TrackListBase.h index ff785543..482a4e8 100644 --- a/third_party/WebKit/Source/core/html/track/TrackListBase.h +++ b/third_party/WebKit/Source/core/html/track/TrackListBase.h
@@ -50,8 +50,7 @@ void add(T* track) { track->setMediaElement(m_mediaElement); - m_tracks.append(track); - ScriptWrappableVisitor::writeBarrier(this, track); + m_tracks.append(TraceWrapperMember<T>(this, track)); scheduleEvent(TrackEvent::create(EventTypeNames::addtrack, track)); } @@ -100,7 +99,7 @@ m_mediaElement->scheduleEvent(event); } - HeapVector<Member<T>> m_tracks; + HeapVector<TraceWrapperMember<T>> m_tracks; Member<HTMLMediaElement> m_mediaElement; };
diff --git a/third_party/WebKit/Source/core/input/PointerEventManager.cpp b/third_party/WebKit/Source/core/input/PointerEventManager.cpp index 21ce995..5dae542 100644 --- a/third_party/WebKit/Source/core/input/PointerEventManager.cpp +++ b/third_party/WebKit/Source/core/input/PointerEventManager.cpp
@@ -168,6 +168,13 @@ UseCounter::count(m_frame->document(), UseCounter::PointerEventDispatchPointerDown); + std::unique_ptr<UserGestureIndicator> gestureIndicator; + if (eventType == EventTypeNames::pointerup && + pointerEvent->pointerType() == "touch") { + gestureIndicator = + wrapUnique(new UserGestureIndicator(UserGestureToken::create())); + } + DispatchEventResult dispatchResult = target->dispatchEvent(pointerEvent); return EventHandlingUtil::toWebInputEventResult(dispatchResult); }
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp index 54d1faa..becf36a 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -518,6 +518,8 @@ void InspectorDOMAgent::getDocument( ErrorString* errorString, + const Maybe<int>& depth, + const Maybe<bool>& traverseFrames, std::unique_ptr<protocol::DOM::Node>* root) { // Backward compatibility. Mark agent as enabled when it requests document. if (!enabled()) @@ -530,7 +532,13 @@ discardFrontendBindings(); - *root = buildObjectForNode(m_document.get(), 2, m_documentNodeToIdMap.get()); + int sanitizedDepth = depth.fromMaybe(2); + if (sanitizedDepth == -1) + sanitizedDepth = INT_MAX; + + *root = buildObjectForNode(m_document.get(), sanitizedDepth, + traverseFrames.fromMaybe(false), + m_documentNodeToIdMap.get()); } void InspectorDOMAgent::getLayoutTreeNodes( @@ -604,7 +612,9 @@ } } -void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth) { +void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, + int depth, + bool traverseFrames) { Node* node = nodeForId(nodeId); if (!node || (!node->isElementNode() && !node->isDocumentNode() && !node->isDocumentFragment())) @@ -621,14 +631,14 @@ for (node = innerFirstChild(node); node; node = innerNextSibling(node)) { int childNodeId = nodeMap->get(node); ASSERT(childNodeId); - pushChildNodesToFrontend(childNodeId, depth); + pushChildNodesToFrontend(childNodeId, depth, traverseFrames); } return; } std::unique_ptr<protocol::Array<protocol::DOM::Node>> children = - buildArrayForContainerChildren(node, depth, nodeMap); + buildArrayForContainerChildren(node, depth, traverseFrames, nodeMap); frontend()->setChildNodes(nodeId, std::move(children)); } @@ -685,9 +695,11 @@ (*classNames)->addItem(className); } -void InspectorDOMAgent::requestChildNodes(ErrorString* errorString, - int nodeId, - const Maybe<int>& depth) { +void InspectorDOMAgent::requestChildNodes( + ErrorString* errorString, + int nodeId, + const Maybe<int>& depth, + const Maybe<bool>& maybeTaverseFrames) { int sanitizedDepth = depth.fromMaybe(1); if (sanitizedDepth == 0 || sanitizedDepth < -1) { *errorString = @@ -697,7 +709,8 @@ if (sanitizedDepth == -1) sanitizedDepth = INT_MAX; - pushChildNodesToFrontend(nodeId, sanitizedDepth); + pushChildNodesToFrontend(nodeId, sanitizedDepth, + maybeTaverseFrames.fromMaybe(false)); } void InspectorDOMAgent::querySelector(ErrorString* errorString, @@ -797,7 +810,7 @@ m_danglingNodeToIdMaps.append(newMap); std::unique_ptr<protocol::Array<protocol::DOM::Node>> children = protocol::Array<protocol::DOM::Node>::create(); - children->addItem(buildObjectForNode(node, 0, danglingMap)); + children->addItem(buildObjectForNode(node, 0, false, danglingMap)); frontend()->setChildNodes(0, std::move(children)); return pushNodePathToFrontend(nodeToPush, danglingMap); @@ -1646,6 +1659,7 @@ std::unique_ptr<protocol::DOM::Node> InspectorDOMAgent::buildObjectForNode( Node* node, int depth, + bool traverseFrames, NodeToIdMap* nodesMap) { int id = bind(node, nodesMap); String localName; @@ -1690,8 +1704,10 @@ ? toLocalFrame(frameOwner->contentFrame()) : nullptr) value->setFrameId(IdentifiersFactory::frameId(frame)); - if (Document* doc = frameOwner->contentDocument()) - value->setContentDocument(buildObjectForNode(doc, 0, nodesMap)); + if (Document* doc = frameOwner->contentDocument()) { + value->setContentDocument(buildObjectForNode( + doc, traverseFrames ? depth : 0, traverseFrames, nodesMap)); + } } if (node->parentNode() && node->parentNode()->isDocumentNode()) { @@ -1705,8 +1721,10 @@ std::unique_ptr<protocol::Array<protocol::DOM::Node>> shadowRoots = protocol::Array<protocol::DOM::Node>::create(); for (ShadowRoot* root = &shadow->youngestShadowRoot(); root; - root = root->olderShadowRoot()) - shadowRoots->addItem(buildObjectForNode(root, 0, nodesMap)); + root = root->olderShadowRoot()) { + shadowRoots->addItem( + buildObjectForNode(root, 0, traverseFrames, nodesMap)); + } value->setShadowRoots(std::move(shadowRoots)); forcePushChildren = true; } @@ -1714,15 +1732,17 @@ if (isHTMLLinkElement(*element)) { HTMLLinkElement& linkElement = toHTMLLinkElement(*element); if (linkElement.isImport() && linkElement.import() && - innerParentNode(linkElement.import()) == linkElement) - value->setImportedDocument( - buildObjectForNode(linkElement.import(), 0, nodesMap)); + innerParentNode(linkElement.import()) == linkElement) { + value->setImportedDocument(buildObjectForNode( + linkElement.import(), 0, traverseFrames, nodesMap)); + } forcePushChildren = true; } if (isHTMLTemplateElement(*element)) { - value->setTemplateContent(buildObjectForNode( - toHTMLTemplateElement(*element).content(), 0, nodesMap)); + value->setTemplateContent( + buildObjectForNode(toHTMLTemplateElement(*element).content(), 0, + traverseFrames, nodesMap)); forcePushChildren = true; } @@ -1777,7 +1797,7 @@ if (forcePushChildren && !depth) depth = 1; std::unique_ptr<protocol::Array<protocol::DOM::Node>> children = - buildArrayForContainerChildren(node, depth, nodesMap); + buildArrayForContainerChildren(node, depth, traverseFrames, nodesMap); if (children->length() > 0 || depth) // Push children along with shadow in any case. value->setChildren(std::move(children)); @@ -1803,6 +1823,7 @@ std::unique_ptr<protocol::Array<protocol::DOM::Node>> InspectorDOMAgent::buildArrayForContainerChildren(Node* container, int depth, + bool traverseFrames, NodeToIdMap* nodesMap) { std::unique_ptr<protocol::Array<protocol::DOM::Node>> children = protocol::Array<protocol::DOM::Node>::create(); @@ -1812,7 +1833,8 @@ Node* firstChild = container->firstChild(); if (firstChild && firstChild->getNodeType() == Node::kTextNode && !firstChild->nextSibling()) { - children->addItem(buildObjectForNode(firstChild, 0, nodesMap)); + children->addItem( + buildObjectForNode(firstChild, 0, traverseFrames, nodesMap)); m_childrenRequested.add(bind(container, nodesMap)); } return children; @@ -1823,7 +1845,8 @@ m_childrenRequested.add(bind(container, nodesMap)); while (child) { - children->addItem(buildObjectForNode(child, depth, nodesMap)); + children->addItem( + buildObjectForNode(child, depth, traverseFrames, nodesMap)); child = innerNextSibling(child); } return children; @@ -1838,12 +1861,14 @@ std::unique_ptr<protocol::Array<protocol::DOM::Node>> pseudoElements = protocol::Array<protocol::DOM::Node>::create(); - if (element->pseudoElement(PseudoIdBefore)) + if (element->pseudoElement(PseudoIdBefore)) { pseudoElements->addItem(buildObjectForNode( - element->pseudoElement(PseudoIdBefore), 0, nodesMap)); - if (element->pseudoElement(PseudoIdAfter)) - pseudoElements->addItem( - buildObjectForNode(element->pseudoElement(PseudoIdAfter), 0, nodesMap)); + element->pseudoElement(PseudoIdBefore), 0, false, nodesMap)); + } + if (element->pseudoElement(PseudoIdAfter)) { + pseudoElements->addItem(buildObjectForNode( + element->pseudoElement(PseudoIdAfter), 0, false, nodesMap)); + } return pseudoElements; } @@ -1960,7 +1985,7 @@ unbind(frameOwner, m_documentNodeToIdMap.get()); std::unique_ptr<protocol::DOM::Node> value = - buildObjectForNode(frameOwner, 0, m_documentNodeToIdMap.get()); + buildObjectForNode(frameOwner, 0, false, m_documentNodeToIdMap.get()); Node* previousSibling = innerPreviousSibling(frameOwner); int prevId = previousSibling ? m_documentNodeToIdMap->get(previousSibling) : 0; @@ -2002,7 +2027,7 @@ Node* prevSibling = innerPreviousSibling(node); int prevId = prevSibling ? m_documentNodeToIdMap->get(prevSibling) : 0; std::unique_ptr<protocol::DOM::Node> value = - buildObjectForNode(node, 0, m_documentNodeToIdMap.get()); + buildObjectForNode(node, 0, false, m_documentNodeToIdMap.get()); frontend()->childNodeInserted(parentId, prevId, std::move(value)); } } @@ -2121,7 +2146,7 @@ pushChildNodesToFrontend(hostId, 1); frontend()->shadowRootPushed( - hostId, buildObjectForNode(root, 0, m_documentNodeToIdMap.get())); + hostId, buildObjectForNode(root, 0, false, m_documentNodeToIdMap.get())); } void InspectorDOMAgent::willPopShadowRoot(Element* host, ShadowRoot* root) { @@ -2186,7 +2211,7 @@ pushChildNodesToFrontend(parentId, 1); frontend()->pseudoElementAdded( parentId, - buildObjectForNode(pseudoElement, 0, m_documentNodeToIdMap.get())); + buildObjectForNode(pseudoElement, 0, false, m_documentNodeToIdMap.get())); } void InspectorDOMAgent::pseudoElementDestroyed(PseudoElement* pseudoElement) { @@ -2351,7 +2376,7 @@ ErrorString* errorString) { if (!m_documentNodeToIdMap->contains(m_document)) { std::unique_ptr<protocol::DOM::Node> root; - getDocument(errorString, &root); + getDocument(errorString, Maybe<int>(), Maybe<bool>(), &root); return errorString->isEmpty(); } return true;
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h index 32d10c0..3376c2e 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
@@ -121,6 +121,8 @@ void enable(ErrorString*) override; void disable(ErrorString*) override; void getDocument(ErrorString*, + const Maybe<int>& depth, + const Maybe<bool>& traverseFrames, std::unique_ptr<protocol::DOM::Node>* root) override; void getLayoutTreeNodes( ErrorString*, @@ -132,7 +134,8 @@ std::unique_ptr<protocol::Array<String>>* classNames) override; void requestChildNodes(ErrorString*, int nodeId, - const Maybe<int>& depth) override; + const Maybe<int>& depth, + const Maybe<bool>& traverseFrames) override; void querySelector(ErrorString*, int nodeId, const String& selector, @@ -322,18 +325,22 @@ Element* assertEditableElement(ErrorString*, int nodeId); int pushNodePathToFrontend(Node*, NodeToIdMap* nodeMap); - void pushChildNodesToFrontend(int nodeId, int depth = 1); + void pushChildNodesToFrontend(int nodeId, + int depth = 1, + bool traverseFrames = false); void invalidateFrameOwnerElement(LocalFrame*); std::unique_ptr<protocol::DOM::Node> buildObjectForNode(Node*, int depth, + bool traverseFrames, NodeToIdMap*); std::unique_ptr<protocol::Array<String>> buildArrayForElementAttributes( Element*); std::unique_ptr<protocol::Array<protocol::DOM::Node>> buildArrayForContainerChildren(Node* container, int depth, + bool traverseFrames, NodeToIdMap* nodesMap); std::unique_ptr<protocol::Array<protocol::DOM::Node>> buildArrayForPseudoElements(Element*, NodeToIdMap* nodesMap);
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json index a469ff8..e8f88d9b 100644 --- a/third_party/WebKit/Source/core/inspector/browser_protocol.json +++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -2183,10 +2183,14 @@ }, { "name": "getDocument", + "parameters": [ + { "name": "depth", "type": "integer", "optional": true, "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0.", "experimental": true }, + { "name": "traverseFrames", "type": "boolean", "optional": true, "description": "Whether or not iframes should be traversed when returning the subtree (default is false).", "experimental": true } + ], "returns": [ { "name": "root", "$ref": "Node", "description": "Resulting node." } ], - "description": "Returns the root DOM node to the caller." + "description": "Returns the root DOM node (and optionally the subtree) to the caller." }, { "name": "getLayoutTreeNodes", @@ -2211,7 +2215,8 @@ "name": "requestChildNodes", "parameters": [ { "name": "nodeId", "$ref": "NodeId", "description": "Id of the node to get children for." }, - { "name": "depth", "type": "integer", "optional": true, "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0.", "experimental": true } + { "name": "depth", "type": "integer", "optional": true, "description": "The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0.", "experimental": true }, + { "name": "traverseFrames", "type": "boolean", "optional": true, "description": "Whether or not iframes should be traversed when returning the sub-tree (default is false).", "experimental": true } ], "description": "Requests that children of the node with given id are returned to the caller in form of <code>setChildNodes</code> events where not only immediate children are retrieved, but all children down to the specified depth." },
diff --git a/third_party/WebKit/Source/core/testing/DeathAwareScriptWrappable.h b/third_party/WebKit/Source/core/testing/DeathAwareScriptWrappable.h index 3b965d2..386ff84 100644 --- a/third_party/WebKit/Source/core/testing/DeathAwareScriptWrappable.h +++ b/third_party/WebKit/Source/core/testing/DeathAwareScriptWrappable.h
@@ -37,19 +37,51 @@ s_instance = instance; } - DEFINE_INLINE_VIRTUAL_TRACE() { visitor->trace(m_dependency); } - - DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() { - visitor->traceWrappers(m_dependency); + DEFINE_INLINE_VIRTUAL_TRACE() { + visitor->trace(m_rawDependency); + visitor->trace(m_wrappedDependency); + visitor->trace(m_wrappedVectorDependency); + visitor->trace(m_wrappedHashMapDependency); } - void setDependency(DeathAwareScriptWrappable* dependency) { + DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() { + visitor->traceWrappers(m_rawDependency); + visitor->traceWrappers(m_wrappedDependency); + for (auto dep : m_wrappedVectorDependency) { + visitor->traceWrappers(dep); + } + for (auto pair : m_wrappedHashMapDependency) { + visitor->traceWrappers(pair.key); + visitor->traceWrappers(pair.value); + } + } + + void setRawDependency(DeathAwareScriptWrappable* dependency) { ScriptWrappableVisitor::writeBarrier(this, dependency); - m_dependency = dependency; + m_rawDependency = dependency; + } + + void setWrappedDependency(DeathAwareScriptWrappable* dependency) { + m_wrappedDependency = dependency; + } + + void addWrappedVectorDependency(DeathAwareScriptWrappable* dependency) { + m_wrappedVectorDependency.append(Wrapper(this, dependency)); + } + + void addWrappedHashMapDependency(DeathAwareScriptWrappable* key, + DeathAwareScriptWrappable* value) { + m_wrappedHashMapDependency.add(Wrapper(this, key), Wrapper(this, value)); } private: - Member<DeathAwareScriptWrappable> m_dependency; + typedef TraceWrapperMember<DeathAwareScriptWrappable> Wrapper; + DeathAwareScriptWrappable() : m_wrappedDependency(this, nullptr) {} + + Member<DeathAwareScriptWrappable> m_rawDependency; + Wrapper m_wrappedDependency; + HeapVector<Wrapper> m_wrappedVectorDependency; + HeapHashMap<Wrapper, Wrapper> m_wrappedHashMapDependency; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp index c17d001..bddeb4b1 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.cpp
@@ -19,10 +19,13 @@ namespace { const AtomicString& remotePlaybackStateToString(WebRemotePlaybackState state) { + DEFINE_STATIC_LOCAL(const AtomicString, connectingValue, ("connecting")); DEFINE_STATIC_LOCAL(const AtomicString, connectedValue, ("connected")); DEFINE_STATIC_LOCAL(const AtomicString, disconnectedValue, ("disconnected")); switch (state) { + case WebRemotePlaybackState::Connecting: + return connectingValue; case WebRemotePlaybackState::Connected: return connectedValue; case WebRemotePlaybackState::Disconnected: @@ -146,7 +149,17 @@ return; m_state = state; - dispatchEvent(Event::create(EventTypeNames::statechange)); + switch (m_state) { + case WebRemotePlaybackState::Connecting: + dispatchEvent(Event::create(EventTypeNames::connecting)); + break; + case WebRemotePlaybackState::Connected: + dispatchEvent(Event::create(EventTypeNames::connect)); + break; + case WebRemotePlaybackState::Disconnected: + dispatchEvent(Event::create(EventTypeNames::disconnect)); + break; + } } void RemotePlayback::availabilityChanged(bool available) {
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h index cfab31c..a1b3e7db 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.h
@@ -46,7 +46,9 @@ // ScriptWrappable implementation. bool hasPendingActivity() const final; - DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(connecting); + DEFINE_ATTRIBUTE_EVENT_LISTENER(connect); + DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect); DECLARE_VIRTUAL_TRACE();
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.idl b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.idl index f4542ad..65539fb 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.idl +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlayback.idl
@@ -15,7 +15,9 @@ RuntimeEnabled=RemotePlayback ] interface RemotePlayback : EventTarget { readonly attribute RemotePlaybackState state; - attribute EventHandler onstatechange; + attribute EventHandler onconnecting; + attribute EventHandler onconnect; + attribute EventHandler ondisconnect; [CallWith=ScriptState] Promise<RemotePlaybackAvailability> getAvailability(); [CallWith=ScriptState] Promise<void> prompt();
diff --git a/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp b/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp index 87bfdf0..9f83a7e2 100644 --- a/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp +++ b/third_party/WebKit/Source/modules/remoteplayback/RemotePlaybackTest.cpp
@@ -10,6 +10,7 @@ #include "core/html/HTMLVideoElement.h" #include "core/testing/DummyPageHolder.h" #include "platform/testing/UnitTestHelpers.h" +#include "public/platform/modules/remoteplayback/WebRemotePlaybackState.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,11 +31,26 @@ : ScriptFunction(scriptState) {} }; +class MockEventListener : public EventListener { + public: + MockEventListener() : EventListener(CPPEventListenerType) {} + + bool operator==(const EventListener& other) const final { + return this == &other; + } + + MOCK_METHOD2(handleEvent, void(ExecutionContext* executionContext, Event*)); +}; + class RemotePlaybackTest : public ::testing::Test { protected: void cancelPrompt(RemotePlayback* remotePlayback) { remotePlayback->promptCancelled(); } + + void setState(RemotePlayback* remotePlayback, WebRemotePlaybackState state) { + remotePlayback->stateChanged(state); + } }; TEST_F(RemotePlaybackTest, PromptCancelledRejectsWithNotAllowedError) { @@ -56,4 +72,37 @@ cancelPrompt(remotePlayback); } +TEST_F(RemotePlaybackTest, StateChangeEvents) { + V8TestingScope scope; + + auto pageHolder = DummyPageHolder::create(); + + HTMLMediaElement* element = HTMLVideoElement::create(pageHolder->document()); + RemotePlayback* remotePlayback = RemotePlayback::create(*element); + + auto connectingHandler = new ::testing::StrictMock<MockEventListener>(); + auto connectHandler = new ::testing::StrictMock<MockEventListener>(); + auto disconnectHandler = new ::testing::StrictMock<MockEventListener>(); + + remotePlayback->addEventListener(EventTypeNames::connecting, + connectingHandler); + remotePlayback->addEventListener(EventTypeNames::connect, connectHandler); + remotePlayback->addEventListener(EventTypeNames::disconnect, + disconnectHandler); + + EXPECT_CALL(*connectingHandler, handleEvent(::testing::_, ::testing::_)) + .Times(1); + EXPECT_CALL(*connectHandler, handleEvent(::testing::_, ::testing::_)) + .Times(1); + EXPECT_CALL(*disconnectHandler, handleEvent(::testing::_, ::testing::_)) + .Times(1); + + setState(remotePlayback, WebRemotePlaybackState::Connecting); + setState(remotePlayback, WebRemotePlaybackState::Connecting); + setState(remotePlayback, WebRemotePlaybackState::Connected); + setState(remotePlayback, WebRemotePlaybackState::Connected); + setState(remotePlayback, WebRemotePlaybackState::Disconnected); + setState(remotePlayback, WebRemotePlaybackState::Disconnected); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/BUILD.gn b/third_party/WebKit/Source/modules/serviceworkers/BUILD.gn index 6312cd9a..550563d 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/BUILD.gn +++ b/third_party/WebKit/Source/modules/serviceworkers/BUILD.gn
@@ -18,6 +18,8 @@ "ForeignFetchRespondWithObserver.h", "InstallEvent.cpp", "InstallEvent.h", + "NavigationPreloadCallbacks.cpp", + "NavigationPreloadCallbacks.h", "NavigationPreloadManager.cpp", "NavigationPreloadManager.h", "NavigatorServiceWorker.cpp",
diff --git a/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadCallbacks.cpp b/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadCallbacks.cpp new file mode 100644 index 0000000..583bc9e7 --- /dev/null +++ b/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadCallbacks.cpp
@@ -0,0 +1,59 @@ +// 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 "modules/serviceworkers/NavigationPreloadCallbacks.h" + +#include "bindings/core/v8/ScriptPromiseResolver.h" +#include "core/dom/DOMException.h" +#include "modules/serviceworkers/ServiceWorkerError.h" + +namespace blink { + +EnableNavigationPreloadCallbacks::EnableNavigationPreloadCallbacks( + ScriptPromiseResolver* resolver) + : m_resolver(resolver) { + DCHECK(m_resolver); +} + +EnableNavigationPreloadCallbacks::~EnableNavigationPreloadCallbacks() {} + +void EnableNavigationPreloadCallbacks::onSuccess() { + if (!m_resolver->getExecutionContext() || + m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) + return; + m_resolver->resolve(); +} + +void EnableNavigationPreloadCallbacks::onError( + const WebServiceWorkerError& error) { + if (!m_resolver->getExecutionContext() || + m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) + return; + m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error)); +} + +DisableNavigationPreloadCallbacks::DisableNavigationPreloadCallbacks( + ScriptPromiseResolver* resolver) + : m_resolver(resolver) { + DCHECK(m_resolver); +} + +DisableNavigationPreloadCallbacks::~DisableNavigationPreloadCallbacks() {} + +void DisableNavigationPreloadCallbacks::onSuccess() { + if (!m_resolver->getExecutionContext() || + m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) + return; + m_resolver->resolve(); +} + +void DisableNavigationPreloadCallbacks::onError( + const WebServiceWorkerError& error) { + if (!m_resolver->getExecutionContext() || + m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) + return; + m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error)); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadCallbacks.h b/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadCallbacks.h new file mode 100644 index 0000000..497246fd --- /dev/null +++ b/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadCallbacks.h
@@ -0,0 +1,48 @@ +// 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 NavigationPreloadCallbacks_h +#define NavigationPreloadCallbacks_h + +#include "public/platform/modules/serviceworker/WebServiceWorkerRegistration.h" + +namespace blink { + +class ScriptPromiseResolver; +struct WebServiceWorkerError; + +class EnableNavigationPreloadCallbacks final + : public WebServiceWorkerRegistration::WebEnableNavigationPreloadCallbacks { + public: + EnableNavigationPreloadCallbacks(ScriptPromiseResolver*); + ~EnableNavigationPreloadCallbacks() override; + + // WebEnableNavigationPreloadCallbacks interface. + void onSuccess() override; + void onError(const WebServiceWorkerError&) override; + + private: + Persistent<ScriptPromiseResolver> m_resolver; + WTF_MAKE_NONCOPYABLE(EnableNavigationPreloadCallbacks); +}; + +class DisableNavigationPreloadCallbacks final + : public WebServiceWorkerRegistration:: + WebDisableNavigationPreloadCallbacks { + public: + DisableNavigationPreloadCallbacks(ScriptPromiseResolver*); + ~DisableNavigationPreloadCallbacks() override; + + // WebDisableNavigationPreloadCallbacks interface. + void onSuccess() override; + void onError(const WebServiceWorkerError&) override; + + private: + Persistent<ScriptPromiseResolver> m_resolver; + WTF_MAKE_NONCOPYABLE(DisableNavigationPreloadCallbacks); +}; + +} // namespace blink + +#endif // NavigationPreloadCallbacks_h
diff --git a/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadManager.cpp b/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadManager.cpp index d8487b7..1b03b42 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadManager.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadManager.cpp
@@ -4,16 +4,25 @@ #include "modules/serviceworkers/NavigationPreloadManager.h" +#include "modules/serviceworkers/NavigationPreloadCallbacks.h" +#include "modules/serviceworkers/ServiceWorkerRegistration.h" + namespace blink { -ScriptPromise NavigationPreloadManager::enable(ScriptState*) { - NOTIMPLEMENTED(); - return ScriptPromise(); +ScriptPromise NavigationPreloadManager::enable(ScriptState* scriptState) { + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); + ScriptPromise promise = resolver->promise(); + m_registration->webRegistration()->enableNavigationPreload( + new EnableNavigationPreloadCallbacks(resolver)); + return promise; } -ScriptPromise NavigationPreloadManager::disable(ScriptState*) { - NOTIMPLEMENTED(); - return ScriptPromise(); +ScriptPromise NavigationPreloadManager::disable(ScriptState* scriptState) { + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); + ScriptPromise promise = resolver->promise(); + m_registration->webRegistration()->disableNavigationPreload( + new DisableNavigationPreloadCallbacks(resolver)); + return promise; } ScriptPromise NavigationPreloadManager::setHeaderValue(ScriptState*, @@ -27,6 +36,12 @@ return ScriptPromise(); } -NavigationPreloadManager::NavigationPreloadManager() {} +NavigationPreloadManager::NavigationPreloadManager( + ServiceWorkerRegistration* registration) + : m_registration(registration) {} + +DEFINE_TRACE(NavigationPreloadManager) { + visitor->trace(m_registration); +} } // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadManager.h b/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadManager.h index 2c6512f..4f61c47c 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadManager.h +++ b/third_party/WebKit/Source/modules/serviceworkers/NavigationPreloadManager.h
@@ -11,14 +11,17 @@ namespace blink { +class ServiceWorkerRegistration; + class NavigationPreloadManager final : public GarbageCollected<NavigationPreloadManager>, public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - static NavigationPreloadManager* create() { - return new NavigationPreloadManager(); + static NavigationPreloadManager* create( + ServiceWorkerRegistration* registration) { + return new NavigationPreloadManager(registration); } ScriptPromise enable(ScriptState*); @@ -26,10 +29,12 @@ ScriptPromise setHeaderValue(ScriptState*, const String& value); ScriptPromise getState(ScriptState*); - DEFINE_INLINE_TRACE() {} + DECLARE_TRACE(); private: - NavigationPreloadManager(); + explicit NavigationPreloadManager(ServiceWorkerRegistration*); + + Member<ServiceWorkerRegistration> m_registration; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerRegistration.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerRegistration.cpp index 5796077..516e59a 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerRegistration.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerRegistration.cpp
@@ -76,7 +76,7 @@ NavigationPreloadManager* ServiceWorkerRegistration::navigationPreload() { if (!m_navigationPreload) - m_navigationPreload = NavigationPreloadManager::create(); + m_navigationPreload = NavigationPreloadManager::create(this); return m_navigationPreload; }
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index f797e4ff..1fa21047 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -324,6 +324,7 @@ "WebIconSizesParser.cpp", "WebScheduler.cpp", "WebTaskRunner.cpp", + "WebTextInputInfo.cpp", "WebThread.cpp", "WebThreadSupportingGC.cpp", "WebThreadSupportingGC.h",
diff --git a/third_party/WebKit/Source/web/WebTextInputInfo.cpp b/third_party/WebKit/Source/platform/WebTextInputInfo.cpp similarity index 97% rename from third_party/WebKit/Source/web/WebTextInputInfo.cpp rename to third_party/WebKit/Source/platform/WebTextInputInfo.cpp index 79e0e390..4886c74 100644 --- a/third_party/WebKit/Source/web/WebTextInputInfo.cpp +++ b/third_party/WebKit/Source/platform/WebTextInputInfo.cpp
@@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "public/web/WebTextInputInfo.h" +#include "public/platform/WebTextInputInfo.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp index cb2aae1..5c1a7e50 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzFace.cpp
@@ -84,6 +84,21 @@ HarfBuzzFontData() : m_paint(), m_simpleFontData(nullptr), m_rangeSet(nullptr) {} + ~HarfBuzzFontData() { + if (m_simpleFontData) + FontCache::fontCache()->releaseFontData(m_simpleFontData); + } + + void updateSimpleFontData(FontPlatformData* platformData) { + SimpleFontData* simpleFontData = + FontCache::fontCache() + ->fontDataFromFontPlatformData(platformData) + .get(); + if (m_simpleFontData) + FontCache::fontCache()->releaseFontData(m_simpleFontData); + m_simpleFontData = simpleFontData; + } + SkPaint m_paint; SimpleFontData* m_simpleFontData; RefPtr<UnicodeRangeSet> m_rangeSet; @@ -370,10 +385,7 @@ m_platformData->setupPaint(&m_harfBuzzFontData->m_paint); m_harfBuzzFontData->m_paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); m_harfBuzzFontData->m_rangeSet = rangeSet; - m_harfBuzzFontData->m_simpleFontData = - FontCache::fontCache() - ->fontDataFromFontPlatformData(m_platformData) - .get(); + m_harfBuzzFontData->updateSimpleFontData(m_platformData); ASSERT(m_harfBuzzFontData->m_simpleFontData); int scale = SkiaScalarToHarfBuzzPosition(m_platformData->size()); hb_font_set_scale(m_unscaledFont, scale, scale);
diff --git a/third_party/WebKit/Source/platform/heap/HeapAllocator.h b/third_party/WebKit/Source/platform/heap/HeapAllocator.h index d62e793..69ea46bf 100644 --- a/third_party/WebKit/Source/platform/heap/HeapAllocator.h +++ b/third_party/WebKit/Source/platform/heap/HeapAllocator.h
@@ -463,6 +463,16 @@ }; template <typename T> +struct VectorTraits<blink::TraceWrapperMember<T>> + : VectorTraitsBase<blink::TraceWrapperMember<T>> { + STATIC_ONLY(VectorTraits); + static const bool needsDestruction = false; + static const bool canInitializeWithMemset = true; + static const bool canClearUnusedSlotsWithMemset = true; + static const bool canMoveWithMemcpy = true; +}; + +template <typename T> struct VectorTraits<blink::WeakMember<T>> : VectorTraitsBase<blink::WeakMember<T>> { STATIC_ONLY(VectorTraits); @@ -576,6 +586,45 @@ }; template <typename T> +struct HashTraits<blink::TraceWrapperMember<T>> + : SimpleClassHashTraits<blink::TraceWrapperMember<T>> { + STATIC_ONLY(HashTraits); + // FIXME: The distinction between PeekInType and PassInType is there for + // the sake of the reference counting handles. When they are gone the two + // types can be merged into PassInType. + // FIXME: Implement proper const'ness for iterator types. Requires support + // in the marking Visitor. + using PeekInType = T*; + using PassInType = T*; + using IteratorGetType = blink::TraceWrapperMember<T>*; + using IteratorConstGetType = const blink::TraceWrapperMember<T>*; + using IteratorReferenceType = blink::TraceWrapperMember<T>&; + using IteratorConstReferenceType = const blink::TraceWrapperMember<T>&; + static IteratorReferenceType getToReferenceConversion(IteratorGetType x) { + return *x; + } + static IteratorConstReferenceType getToReferenceConstConversion( + IteratorConstGetType x) { + return *x; + } + + using PeekOutType = T*; + + template <typename U> + static void store(const U& value, blink::TraceWrapperMember<T>& storage) { + storage = value; + } + + static PeekOutType peek(const blink::TraceWrapperMember<T>& value) { + return value; + } + + static blink::TraceWrapperMember<T> emptyValue() { + return blink::TraceWrapperMember<T>(nullptr, nullptr); + } +}; + +template <typename T> struct HashTraits<blink::WeakMember<T>> : SimpleClassHashTraits<blink::WeakMember<T>> { STATIC_ONLY(HashTraits);
diff --git a/third_party/WebKit/Source/platform/heap/Member.h b/third_party/WebKit/Source/platform/heap/Member.h index cb9dbd53..aec34ac 100644 --- a/third_party/WebKit/Source/platform/heap/Member.h +++ b/third_party/WebKit/Source/platform/heap/Member.h
@@ -13,6 +13,8 @@ template <typename T> class Persistent; +template <typename T> +class TraceWrapperMember; enum class TracenessMemberConfiguration { Traced, @@ -401,6 +403,12 @@ }; template <typename T> +struct DefaultHash<blink::TraceWrapperMember<T>> { + STATIC_ONLY(DefaultHash); + using Hash = MemberHash<T>; +}; + +template <typename T> struct IsTraceable<blink::Member<T>> { STATIC_ONLY(IsTraceable); static const bool value = true; @@ -418,6 +426,12 @@ static const bool value = true; }; +template <typename T> +struct IsTraceable<blink::TraceWrapperMember<T>> { + STATIC_ONLY(IsTraceable); + static const bool value = true; +}; + } // namespace WTF #endif // Member_h
diff --git a/third_party/WebKit/Source/platform/heap/ThreadingTraits.h b/third_party/WebKit/Source/platform/heap/ThreadingTraits.h index 8aed039f9a..7dfffb55 100644 --- a/third_party/WebKit/Source/platform/heap/ThreadingTraits.h +++ b/third_party/WebKit/Source/platform/heap/ThreadingTraits.h
@@ -18,6 +18,9 @@ namespace blink { +template <typename T> +class TraceWrapperMember; + // ThreadAffinity indicates which threads objects can be used on. We // distinguish between objects that can be used on the main thread // only and objects that can be used on any thread. @@ -80,6 +83,12 @@ }; template <typename T> +struct ThreadingTrait<TraceWrapperMember<T>> { + STATIC_ONLY(ThreadingTrait); + static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity; +}; + +template <typename T> struct ThreadingTrait<WeakMember<T>> { STATIC_ONLY(ThreadingTrait); static const ThreadAffinity Affinity = ThreadingTrait<T>::Affinity;
diff --git a/third_party/WebKit/Source/platform/heap/TraceTraits.h b/third_party/WebKit/Source/platform/heap/TraceTraits.h index e734a7f..a36afa751 100644 --- a/third_party/WebKit/Source/platform/heap/TraceTraits.h +++ b/third_party/WebKit/Source/platform/heap/TraceTraits.h
@@ -346,6 +346,14 @@ }; template <typename T> +class TraceEagerlyTrait<TraceWrapperMember<T>> { + STATIC_ONLY(TraceEagerlyTrait); + + public: + static const bool value = TraceEagerlyTrait<T>::value; +}; + +template <typename T> class TraceEagerlyTrait<WeakMember<T>> { STATIC_ONLY(TraceEagerlyTrait);
diff --git a/third_party/WebKit/Source/platform/heap/Visitor.h b/third_party/WebKit/Source/platform/heap/Visitor.h index eddab64..b9987e2 100644 --- a/third_party/WebKit/Source/platform/heap/Visitor.h +++ b/third_party/WebKit/Source/platform/heap/Visitor.h
@@ -52,6 +52,8 @@ class TraceEagerlyTrait; class ThreadState; class Visitor; +template <typename T> +class TraceWrapperMember; // The TraceMethodDelegate is used to convert a trace method for type T to a // TraceCallback. This allows us to pass a type's trace method as a parameter @@ -158,6 +160,11 @@ mark(t.get()); } + template <typename T> + void trace(const TraceWrapperMember<T>& t) { + trace(*(static_cast<const Member<T>*>(&t))); + } + // Fallback method used only when we need to trace raw pointers of T. // This is the case when a member is a union where we do not support members. template <typename T>
diff --git a/third_party/WebKit/Source/web/BUILD.gn b/third_party/WebKit/Source/web/BUILD.gn index 50336b16..df66130 100644 --- a/third_party/WebKit/Source/web/BUILD.gn +++ b/third_party/WebKit/Source/web/BUILD.gn
@@ -244,7 +244,6 @@ "WebTextCheckingCompletionImpl.cpp", "WebTextCheckingCompletionImpl.h", "WebTextCheckingResult.cpp", - "WebTextInputInfo.cpp", "WebUserGestureIndicator.cpp", "WebUserGestureToken.cpp", "WebUserMediaRequest.cpp",
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp index c522068..cefeb8b 100644 --- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp +++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
@@ -244,7 +244,8 @@ int eventID, const WebString& notificationID, const WebNotificationData& data, - int actionIndex) { + int actionIndex, + const WebString& reply) { WaitUntilObserver* observer = WaitUntilObserver::create( workerGlobalScope(), WaitUntilObserver::NotificationClick, eventID); NotificationEventInit eventInit; @@ -252,6 +253,7 @@ workerGlobalScope(), notificationID, data, true /* showing */)); if (0 <= actionIndex && actionIndex < static_cast<int>(data.actions.size())) eventInit.setAction(data.actions[actionIndex].action); + eventInit.setReply(reply); Event* event = NotificationEvent::create(EventTypeNames::notificationclick, eventInit, observer); workerGlobalScope()->dispatchExtendableEvent(event, observer);
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h index 5ce6d4da..a135654 100644 --- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h +++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.h
@@ -98,7 +98,8 @@ void dispatchNotificationClickEvent(int, const WebString& notificationID, const WebNotificationData&, - int actionIndex) override; + int actionIndex, + const WebString& reply) override; void dispatchNotificationCloseEvent(int, const WebString& notificationID, const WebNotificationData&) override;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index 59f134b..6dcc13d7 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -130,6 +130,7 @@ #include "public/platform/WebImage.h" #include "public/platform/WebLayerTreeView.h" #include "public/platform/WebScheduler.h" +#include "public/platform/WebTextInputInfo.h" #include "public/platform/WebURLRequest.h" #include "public/platform/WebVector.h" #include "public/platform/WebViewScheduler.h" @@ -151,7 +152,6 @@ #include "public/web/WebRange.h" #include "public/web/WebScopedUserGesture.h" #include "public/web/WebSelection.h" -#include "public/web/WebTextInputInfo.h" #include "public/web/WebViewClient.h" #include "public/web/WebWindowFeatures.h" #include "web/CompositionUnderlineVectorBuilder.h"
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/wptserve.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/wptserve.py index a592ebc..861d0b0 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/wptserve.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/servers/wptserve.py
@@ -42,7 +42,10 @@ if self._port_obj.host.filesystem.exists(path_to_ws_handlers): start_cmd += ['--ws_doc_root', path_to_ws_handlers] - self._stdout = self._stderr = self._executive.DEVNULL + # TODO(tkent): Do not suppress console output on Windows until + # crbug.com/623613 is resolved. + if not self._platform.is_win(): + self._stdout = self._stderr = self._executive.DEVNULL # TODO(burnik): We should stop setting the CWD once WPT can be run without it. self._cwd = path_to_wpt_root self._env = {'PYTHONPATH': path_to_thirdparty}
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn index d1d51a63..44d66f9e 100644 --- a/third_party/WebKit/public/BUILD.gn +++ b/third_party/WebKit/public/BUILD.gn
@@ -76,7 +76,7 @@ sources = [ "./platform/WebDisplayMode.h", "./platform/WebInputEvent.h", - "./web/WebTextInputType.h", + "./platform/WebTextInputType.h", ] } @@ -295,6 +295,8 @@ "platform/WebString.h", "platform/WebSuspendableTask.h", "platform/WebTaskRunner.h", + "platform/WebTextInputInfo.h", + "platform/WebTextInputType.h", "platform/WebTextRun.h", "platform/WebThemeEngine.h", "platform/WebThread.h", @@ -553,8 +555,6 @@ "web/WebTextCheckingResult.h", "web/WebTextDecorationType.h", "web/WebTextDirection.h", - "web/WebTextInputInfo.h", - "web/WebTextInputType.h", "web/WebTouchAction.h", "web/WebTreeScopeType.h", "web/WebURLLoaderOptions.h",
diff --git a/third_party/WebKit/public/web/WebTextInputInfo.h b/third_party/WebKit/public/platform/WebTextInputInfo.h similarity index 95% rename from third_party/WebKit/public/web/WebTextInputInfo.h rename to third_party/WebKit/public/platform/WebTextInputInfo.h index ca71b5d..61f8ecc 100644 --- a/third_party/WebKit/public/web/WebTextInputInfo.h +++ b/third_party/WebKit/public/platform/WebTextInputInfo.h
@@ -26,7 +26,8 @@ #ifndef WebTextInputInfo_h #define WebTextInputInfo_h -#include "../platform/WebString.h" +#include "WebCommon.h" +#include "WebString.h" #include "WebTextInputType.h" namespace blink { @@ -56,7 +57,7 @@ // This string is lower-case. WebString inputMode; - BLINK_EXPORT bool equals(const WebTextInputInfo&) const; + BLINK_PLATFORM_EXPORT bool equals(const WebTextInputInfo&) const; WebTextInputInfo() : type(WebTextInputTypeNone),
diff --git a/third_party/WebKit/public/web/WebTextInputType.h b/third_party/WebKit/public/platform/WebTextInputType.h similarity index 100% rename from third_party/WebKit/public/web/WebTextInputType.h rename to third_party/WebKit/public/platform/WebTextInputType.h
diff --git a/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackState.h b/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackState.h index df1cdcc0..5697e35 100644 --- a/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackState.h +++ b/third_party/WebKit/public/platform/modules/remoteplayback/WebRemotePlaybackState.h
@@ -8,7 +8,8 @@ namespace blink { enum class WebRemotePlaybackState { - Connected = 0, + Connecting = 0, + Connected, Disconnected, };
diff --git a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h index ac80115..c7a393d 100644 --- a/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h +++ b/third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h
@@ -26,6 +26,10 @@ WebCallbacks<void, const WebServiceWorkerError&>; using WebServiceWorkerUnregistrationCallbacks = WebCallbacks<bool, const WebServiceWorkerError&>; + using WebEnableNavigationPreloadCallbacks = + WebCallbacks<void, const WebServiceWorkerError&>; + using WebDisableNavigationPreloadCallbacks = + WebCallbacks<void, const WebServiceWorkerError&>; // The handle interface that retains a reference to the implementation of // WebServiceWorkerRegistration in the embedder and is owned by @@ -46,6 +50,9 @@ WebServiceWorkerUpdateCallbacks*) {} virtual void unregister(WebServiceWorkerProvider*, WebServiceWorkerUnregistrationCallbacks*) {} + + virtual void enableNavigationPreload(WebEnableNavigationPreloadCallbacks*) {} + virtual void disableNavigationPreload(WebEnableNavigationPreloadCallbacks*) {} }; } // namespace blink
diff --git a/third_party/WebKit/public/web/WebWidget.h b/third_party/WebKit/public/web/WebWidget.h index 9aaff922..b5b544c 100644 --- a/third_party/WebKit/public/web/WebWidget.h +++ b/third_party/WebKit/public/web/WebWidget.h
@@ -38,11 +38,11 @@ #include "../platform/WebPoint.h" #include "../platform/WebRect.h" #include "../platform/WebSize.h" +#include "../platform/WebTextInputInfo.h" #include "../platform/WebTopControlsState.h" #include "WebCompositionUnderline.h" #include "WebRange.h" #include "WebTextDirection.h" -#include "WebTextInputInfo.h" namespace blink {
diff --git a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h index 4f262ec..e54f7c6 100644 --- a/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h +++ b/third_party/WebKit/public/web/modules/serviceworker/WebServiceWorkerContextProxy.h
@@ -78,7 +78,8 @@ virtual void dispatchNotificationClickEvent(int eventID, const WebString& notificationID, const WebNotificationData&, - int actionIndex) = 0; + int actionIndex, + const WebString& reply) = 0; virtual void dispatchNotificationCloseEvent(int eventID, const WebString& notificationID, const WebNotificationData&) = 0;
diff --git a/third_party/libwebp/README.chromium b/third_party/libwebp/README.chromium index 4c69745..77ac2a9f 100644 --- a/third_party/libwebp/README.chromium +++ b/third_party/libwebp/README.chromium
@@ -22,6 +22,8 @@ * Merged COPYING/PATENTS to LICENSE * Disabled "-frename-registers" flag for ARM64 linux build as clang(3.9.0) build fails with error - unsupported flag. + * Disabled the SSE2 version of VerticalUnfilter due to a crash on android + (crbug.com/654974) Cherry-picks: Revert patch f7fc4bc: dec/webp.c: don't wait for data before reporting w/h Revert patch d1c359e: fix shared object build with -fvisibility=hidden
diff --git a/third_party/libwebp/dsp/filters_sse2.c b/third_party/libwebp/dsp/filters_sse2.c index 67f7799..61bc6b5 100644 --- a/third_party/libwebp/dsp/filters_sse2.c +++ b/third_party/libwebp/dsp/filters_sse2.c
@@ -315,7 +315,9 @@ WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInitSSE2(void) { WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter; - WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter; + // crbug.com/654974 + // WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter; + (void)VerticalUnfilter; WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter; WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter;
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py index 749ee36..5db0f3a1 100755 --- a/tools/gn/bootstrap/bootstrap.py +++ b/tools/gn/bootstrap/bootstrap.py
@@ -498,6 +498,7 @@ 'base/trace_event/process_memory_totals.cc', 'base/trace_event/trace_buffer.cc', 'base/trace_event/trace_config.cc', + 'base/trace_event/trace_event.cc', 'base/trace_event/trace_event_argument.cc', 'base/trace_event/trace_event_impl.cc', 'base/trace_event/trace_event_memory_overhead.cc',
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 0f9e7c8..c347a3d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -5780,6 +5780,9 @@ <histogram name="ChromeGeneratedCustomTab.IntentToFirstCommitNavigationTime" units="ms"> + <obsolete> + Deprecated 10/2016 in favor of .IntentToFirstCommitNavigationTime2.*. + </obsolete> <owner>lizeb@chromium.org</owner> <summary> Time between the intent arrival in a Chrome generated CCT and the first @@ -5788,11 +5791,22 @@ </summary> </histogram> +<histogram name="ChromeGeneratedCustomTab.IntentToFirstCommitNavigationTime2" + units="ms"> + <owner>lizeb@chromium.org</owner> + <summary> + In "Herb" mode shows the time between the intent arrival in a + Chrome generated CCT and the first navigation commit, if the navigation is + successful. Similar in principle to Startup.FirstCommitNavigationTime. + </summary> +</histogram> + <histogram name="ChromeGeneratedCustomTab.IntentToPageLoadedTime" units="ms"> <owner>lizeb@chromium.org</owner> <summary> - Time between the intent arrival in a Chrome generated CCT and the first - "page loaded" event, if the navigation is successful. + In "Herb" mode shows time between the intent arrival in a Chrome + generated CCT and the first "page loaded" event, if the navigation + is successful. </summary> </histogram> @@ -7934,6 +7948,9 @@ </histogram> <histogram name="CustomTabs.IntentToFirstCommitNavigationTime" units="ms"> + <obsolete> + Deprecated 10/2016 in favor of .IntentToFirstCommitNavigationTime2.*. + </obsolete> <owner>lizeb@chromium.org</owner> <summary> Time between the intent arrival in Chrome and the first navigation commit, @@ -7942,11 +7959,21 @@ </summary> </histogram> +<histogram name="CustomTabs.IntentToFirstCommitNavigationTime2" units="ms"> + <owner>lizeb@chromium.org</owner> + <summary> + Time between the intent arrival to a Custom Tab and the first navigation + commit, if the navigation is successful. Similar in principle to + Startup.FirstCommitNavigationTime. Non-"Herb" mode. + </summary> +</histogram> + <histogram name="CustomTabs.IntentToPageLoadedTime" units="ms"> <owner>lizeb@chromium.org</owner> <summary> Time between the intent arrival in Chrome and the first "page - loaded" event, if the navigation is successful. + loaded" event, if the navigation is successful. Non-"Herb" + mode. </summary> </histogram> @@ -14153,7 +14180,7 @@ <owner>tdresser@chromium.org</owner> <owner>caseq@chromium.org</owner> <summary> - Whether the timestapms on input events produced by the windowing system + Whether the timestamps on input events produced by the windowing system appear to be sharing the same time base as TimeTicks, modulo possible roll-over. </summary> @@ -59514,6 +59541,13 @@ </summary> </histogram> +<histogram name="SpecialLocale.PromotionDialog" enum="SpecialLocalePromoAction"> + <owner>ianwen@chromium.org</owner> + <summary> + Records how users interact with the special locale promotion dialog. + </summary> +</histogram> + <histogram name="SpellCheck.SpellingService.Enabled" enum="BooleanEnabled"> <owner>groby@chromium.org</owner> <owner>rlp@chromium.org</owner> @@ -79579,6 +79613,7 @@ <int value="346" label="Enables force sign in for browser."/> <int value="347" label="Always open PDF in external viewer."/> <int value="348" label="Force YouTube Restricted Mode"/> + <int value="349" label="Report information about the status of Android."/> </enum> <enum name="EnterprisePolicyInvalidations" type="int"> @@ -98649,6 +98684,13 @@ <int value="1" label="sent"/> </enum> +<enum name="SpecialLocalePromoAction" type="int"> + <int value="0" label="Use Sogou"/> + <int value="1" label="Keep Google"/> + <int value="2" label="Settings"/> + <int value="3" label="Back key"/> +</enum> + <enum name="SpecialShFileOperationCodes" type="int"> <summary>Legacy error codes still returned by |ShFileOperation()|</summary> <int value="5" label="Access denied (Win32)"/> @@ -103424,13 +103466,33 @@ </histogram_suffixes> <histogram_suffixes name="BlinkCanvasToDataURLTime" separator="."> - <suffix name="BMP"/> - <suffix name="GIF"/> - <suffix name="ICON"/> + <suffix name="BMP"> + <obsolete> + Removed in Oct 2016 + </obsolete> + </suffix> + <suffix name="GIF"> + <obsolete> + Removed in Oct 2016 + </obsolete> + </suffix> + <suffix name="ICON"> + <obsolete> + Removed in Oct 2016 + </obsolete> + </suffix> <suffix name="JPEG"/> <suffix name="PNG"/> - <suffix name="TIFF"/> - <suffix name="Unknown"/> + <suffix name="TIFF"> + <obsolete> + Removed in Oct 2016 + </obsolete> + </suffix> + <suffix name="Unknown"> + <obsolete> + Removed in Oct 2016 + </obsolete> + </suffix> <suffix name="WEBP"/> <affected-histogram name="Blink.Canvas.ToDataURL"/> </histogram_suffixes> @@ -105565,6 +105627,17 @@ <affected-histogram name="PLT.PT_StartToFinish"/> </histogram_suffixes> +<histogram_suffixes name="IntentToFirstCommitZoom" separator="."> + <owner>lizeb@chromium.org</owner> + <owner>pasko@chromium.org</owner> + <suffix name="ZoomedIn" label="Zoomed in view: shorter range, more buckets."/> + <suffix name="ZoomedOut" + label="Zoomed out view: longer time range, less buckets."/> + <affected-histogram + name="ChromeGeneratedCustomTab.IntentToFirstCommitNavigationTime2"/> + <affected-histogram name="CustomTabs.IntentToFirstCommitNavigationTime2"/> +</histogram_suffixes> + <histogram_suffixes name="InterProcessTimeTicksConversionType"> <owner>ppi@chromium.org</owner> <suffix name="BrowserToRenderer"/> @@ -110060,6 +110133,12 @@ <affected-histogram name="ThreadWatcher.UnresponsiveThreads"/> </histogram_suffixes> +<histogram_suffixes name="TimestampTimebaseProcess" separator="."> + <suffix name="Browser"/> + <suffix name="Renderer"/> + <affected-histogram name="Event.TimestampHasValidTimebase"/> +</histogram_suffixes> + <histogram_suffixes name="TotalTimeToHttpsGoogle" separator="."> <suffix name="Quic"> <obsolete>
diff --git a/tools/perf/benchmarks/system_health.py b/tools/perf/benchmarks/system_health.py index c45a9de..4cbd8a9a 100644 --- a/tools/perf/benchmarks/system_health.py +++ b/tools/perf/benchmarks/system_health.py
@@ -88,6 +88,7 @@ https://goo.gl/Jek2NL. """ + options = {'pageset_repeat': 3} def SetExtraBrowserOptions(self, options): options.AppendExtraBrowserArgs([
diff --git a/tools/perf/generate_perf_json.py b/tools/perf/generate_perf_json.py index 076ed8e..97564be 100755 --- a/tools/perf/generate_perf_json.py +++ b/tools/perf/generate_perf_json.py
@@ -235,9 +235,13 @@ 'win-low-end-2-core', 'win', swarming=[ { + 'gpu': '8086:22b1', + 'os': 'Windows-10-10586', 'device_ids': ['build187-b4'] }, { + 'gpu': '1002:9874', + 'os': 'Windows-10-10586', 'device_ids': ['build171-b4', 'build186-b4'] } ]) @@ -395,7 +399,10 @@ # Id is unique within the swarming pool so it is the only needed # identifier for the bot to run the test on swarming_dimensions.append({ - 'id': device_id + 'id': device_id, + 'gpu': dimension['gpu'], + 'os': dimension['os'], + 'pool': 'Chrome-perf', }) test = generate_telemetry_test(
diff --git a/ui/android/java/src/org/chromium/ui/base/Clipboard.java b/ui/android/java/src/org/chromium/ui/base/Clipboard.java index e02b588..4497c60 100644 --- a/ui/android/java/src/org/chromium/ui/base/Clipboard.java +++ b/ui/android/java/src/org/chromium/ui/base/Clipboard.java
@@ -67,14 +67,16 @@ @SuppressWarnings("javadoc") @CalledByNative private String getCoercedText() { - final ClipData clip = mClipboardManager.getPrimaryClip(); - if (clip != null && clip.getItemCount() > 0) { - final CharSequence sequence = clip.getItemAt(0).coerceToText(mContext); - if (sequence != null) { - return sequence.toString(); - } + // getPrimaryClip() has been observed to throw unexpected exceptions for some devices (see + // crbug.com/654802 and b/31501780) + try { + return mClipboardManager.getPrimaryClip() + .getItemAt(0) + .coerceToText(mContext) + .toString(); + } catch (Exception e) { + return null; } - return null; } /** @@ -85,11 +87,13 @@ */ @CalledByNative private String getHTMLText() { - final ClipData clip = mClipboardManager.getPrimaryClip(); - if (clip != null && clip.getItemCount() > 0) { - return clip.getItemAt(0).getHtmlText(); + // getPrimaryClip() has been observed to throw unexpected exceptions for some devices (see + // crbug/654802 and b/31501780) + try { + return mClipboardManager.getPrimaryClip().getItemAt(0).getHtmlText(); + } catch (Exception e) { + return null; } - return null; } /**
diff --git a/ui/aura/window.cc b/ui/aura/window.cc index d920787..2d7a0487 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc
@@ -719,7 +719,7 @@ // changed notification from the layer (this typically happens after animating // hidden). We must notify ourselves. if (layer()->delegate() != this) - OnWindowBoundsChanged(old_bounds); + OnLayerBoundsChanged(old_bounds); } void Window::SetVisible(bool visible) { @@ -1019,17 +1019,6 @@ } } -void Window::OnWindowBoundsChanged(const gfx::Rect& old_bounds) { - bounds_ = layer()->bounds(); - if (layout_manager_) - layout_manager_->OnWindowResized(); - if (delegate_) - delegate_->OnBoundsChanged(old_bounds, bounds()); - FOR_EACH_OBSERVER(WindowObserver, - observers_, - OnWindowBoundsChanged(this, old_bounds, bounds())); -} - bool Window::CleanupGestureState() { bool state_modified = false; state_modified |= ui::GestureRecognizer::Get()->CancelActiveTouches(this); @@ -1054,9 +1043,14 @@ OnDelegatedFrameDamage(this, damage_rect_in_dip)); } -base::Closure Window::PrepareForLayerBoundsChange() { - return base::Bind(&Window::OnWindowBoundsChanged, base::Unretained(this), - bounds()); +void Window::OnLayerBoundsChanged(const gfx::Rect& old_bounds) { + bounds_ = layer()->bounds(); + if (layout_manager_) + layout_manager_->OnWindowResized(); + if (delegate_) + delegate_->OnBoundsChanged(old_bounds, bounds_); + for (auto& observer : observers_) + observer.OnWindowBoundsChanged(this, old_bounds, bounds_); } bool Window::CanAcceptEvent(const ui::Event& event) {
diff --git a/ui/aura/window.h b/ui/aura/window.h index 946904b..f27c2be 100644 --- a/ui/aura/window.h +++ b/ui/aura/window.h
@@ -444,15 +444,10 @@ // |source|. void NotifyAncestorWindowTransformed(Window* source); - // Invoked when the bounds of the window changes. This may be invoked directly - // by us, or from the closure returned by PrepareForLayerBoundsChange() after - // the bounds of the layer has changed. |old_bounds| is the previous bounds. - void OnWindowBoundsChanged(const gfx::Rect& old_bounds); - // Overridden from ui::LayerDelegate: void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; - base::Closure PrepareForLayerBoundsChange() override; + void OnLayerBoundsChanged(const gfx::Rect& old_bounds) override; // Overridden from ui::EventTarget: bool CanAcceptEvent(const ui::Event& event) override;
diff --git a/ui/base/ime/text_input_flags.h b/ui/base/ime/text_input_flags.h index 17fb9fb4..f2d7c49 100644 --- a/ui/base/ime/text_input_flags.h +++ b/ui/base/ime/text_input_flags.h
@@ -8,7 +8,7 @@ namespace ui { // Intentionally keep in sync with blink::WebTextInputFlags defined in: -// third_party/WebKit/public/web/WebTextInputType.h +// third_party/WebKit/public/platform/WebTextInputType.h enum TextInputFlags { TEXT_INPUT_FLAG_NONE = 0, TEXT_INPUT_FLAG_AUTOCOMPLETE_ON = 1 << 0,
diff --git a/ui/base/ime/text_input_type.h b/ui/base/ime/text_input_type.h index 794f5c84..641cb7e 100644 --- a/ui/base/ime/text_input_type.h +++ b/ui/base/ime/text_input_type.h
@@ -8,7 +8,7 @@ namespace ui { // Intentionally keep sync with blink::WebTextInputType defined in: -// third_party/WebKit/public/web/WebTextInputType.h +// third_party/WebKit/public/platform/WebTextInputType.h // // A Java counterpart will be generated for this enum. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.ui.base.ime
diff --git a/ui/compositor/BUILD.gn b/ui/compositor/BUILD.gn index 44a2313..fc2c5a126 100644 --- a/ui/compositor/BUILD.gn +++ b/ui/compositor/BUILD.gn
@@ -45,6 +45,7 @@ "layer_animator.h", "layer_animator_collection.cc", "layer_animator_collection.h", + "layer_delegate.cc", "layer_delegate.h", "layer_observer.h", "layer_owner.cc",
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 67886fc..31c5da6 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc
@@ -896,18 +896,16 @@ return; base::Closure closure; - if (delegate_) - closure = delegate_->PrepareForLayerBoundsChange(); - bool was_move = bounds_.size() == bounds.size(); + const gfx::Rect old_bounds = bounds_; bounds_ = bounds; RecomputeDrawsContentAndUVRect(); RecomputePosition(); - if (!closure.is_null()) - closure.Run(); + if (delegate_) + delegate_->OnLayerBoundsChanged(old_bounds); - if (was_move) { + if (bounds.size() == old_bounds.size()) { // Don't schedule a draw if we're invisible. We'll schedule one // automatically when we get visible. if (IsDrawn())
diff --git a/ui/compositor/layer_delegate.cc b/ui/compositor/layer_delegate.cc new file mode 100644 index 0000000..684bd2e --- /dev/null +++ b/ui/compositor/layer_delegate.cc
@@ -0,0 +1,11 @@ +// 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 "ui/compositor/layer_delegate.h" + +namespace ui { + +void LayerDelegate::OnLayerBoundsChanged(const gfx::Rect& old_bounds) {} + +} // namespace ui
diff --git a/ui/compositor/layer_delegate.h b/ui/compositor/layer_delegate.h index c3c4e39..55bc130 100644 --- a/ui/compositor/layer_delegate.h +++ b/ui/compositor/layer_delegate.h
@@ -5,7 +5,6 @@ #ifndef UI_COMPOSITOR_LAYER_DELEGATE_H_ #define UI_COMPOSITOR_LAYER_DELEGATE_H_ -#include "base/callback_forward.h" #include "ui/compositor/compositor_export.h" namespace gfx { @@ -29,9 +28,8 @@ // Called when the layer's device scale factor has changed. virtual void OnDeviceScaleFactorChanged(float device_scale_factor) = 0; - // Invoked prior to the bounds changing. The returned closured is run after - // the bounds change. - virtual base::Closure PrepareForLayerBoundsChange() = 0; + // Invoked when the bounds have changed. + virtual void OnLayerBoundsChanged(const gfx::Rect& old_bounds); protected: virtual ~LayerDelegate() {}
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index d357c78a..0a58a64 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc
@@ -87,10 +87,6 @@ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - private: SkColor color_; }; @@ -147,10 +143,6 @@ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - private: const SkColor background_color_; const SkColor halo_color_; @@ -339,10 +331,6 @@ device_scale_factor_ = device_scale_factor; } - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - void reset() { color_index_ = 0; device_scale_factor_ = 0.0f; @@ -379,9 +367,6 @@ } void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } bool painted_; const gfx::Rect layer_bounds_; @@ -400,9 +385,6 @@ void OnPaintLayer(const ui::PaintContext& context) override {} void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate); }; @@ -1531,10 +1513,6 @@ void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } - int paint_count_; Layer* layer_; gfx::Rect schedule_paint_rect_;
diff --git a/ui/events/android/motion_event_android.cc b/ui/events/android/motion_event_android.cc index bf1fc53f..f7507bf9 100644 --- a/ui/events/android/motion_event_android.cc +++ b/ui/events/android/motion_event_android.cc
@@ -12,6 +12,7 @@ #include "jni/MotionEvent_jni.h" #include "ui/events/base_event_utils.h" #include "ui/events/event_constants.h" +#include "ui/events/event_utils.h" using base::android::AttachCurrentThread; using namespace JNI_MotionEvent; @@ -94,7 +95,10 @@ } base::TimeTicks FromAndroidTime(int64_t time_ms) { - return base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms); + base::TimeTicks timestamp = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(time_ms); + ValidateEventTimeClock(×tamp); + return timestamp; } float ToValidFloat(float x) {
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc index 81b1d09..01d2544 100644 --- a/ui/events/blink/input_handler_proxy.cc +++ b/ui/events/blink/input_handler_proxy.cc
@@ -405,6 +405,11 @@ input_handler_->MouseMoveAt(gfx::Point(mouse_event.x, mouse_event.y)); return DID_NOT_HANDLE; } + case WebInputEvent::MouseLeave: { + CHECK(input_handler_); + input_handler_->MouseLeave(); + return DID_NOT_HANDLE; + } default: if (WebInputEvent::isKeyboardEventType(event.type)) {
diff --git a/ui/events/blink/input_handler_proxy_unittest.cc b/ui/events/blink/input_handler_proxy_unittest.cc index 769eb99..889270c 100644 --- a/ui/events/blink/input_handler_proxy_unittest.cc +++ b/ui/events/blink/input_handler_proxy_unittest.cc
@@ -151,6 +151,7 @@ void MouseDown() override {} void MouseUp() override {} + void MouseLeave() override {} void MouseMoveAt(const gfx::Point& mouse_position) override {}
diff --git a/ui/events/blink/web_input_event.cc b/ui/events/blink/web_input_event.cc index 705818f1..674f64f 100644 --- a/ui/events/blink/web_input_event.cc +++ b/ui/events/blink/web_input_event.cc
@@ -399,8 +399,14 @@ webkit_event.type = blink::WebInputEvent::MouseUp; webkit_event.clickCount = event.GetClickCount(); break; - case ET_MOUSE_ENTERED: case ET_MOUSE_EXITED: +// TODO(chaopeng) this fix only for chromeos now, should convert ET_MOUSE_EXITED +// to MouseLeave when crbug.com/450631 fixed. +#if defined(OS_CHROMEOS) + webkit_event.type = blink::WebInputEvent::MouseLeave; + break; +#endif + case ET_MOUSE_ENTERED: case ET_MOUSE_MOVED: case ET_MOUSE_DRAGGED: webkit_event.type = blink::WebInputEvent::MouseMove;
diff --git a/ui/events/event_utils.cc b/ui/events/event_utils.cc index 389edcad..dd0da342 100644 --- a/ui/events/event_utils.cc +++ b/ui/events/event_utils.cc
@@ -62,25 +62,20 @@ } void ValidateEventTimeClock(base::TimeTicks* timestamp) { -// Restrict this validation to DCHECK builds except when using X11 which is -// known to provide bogus timestamps that require correction (crbug.com/611950). -#if defined(USE_X11) || DCHECK_IS_ON() if (base::debug::BeingDebugged()) return; base::TimeTicks now = EventTimeForNow(); int64_t delta = (now - *timestamp).InMilliseconds(); - if (delta < 0 || delta > 60 * 1000) { - UMA_HISTOGRAM_BOOLEAN("Event.TimestampHasValidTimebase", false); -#if defined(USE_X11) - *timestamp = now; -#else - NOTREACHED() << "Unexpected event timestamp, now:" << now - << " event timestamp:" << *timestamp; -#endif - } + bool has_valid_timebase = delta >= 0 && delta <= 60 * 1000; + UMA_HISTOGRAM_BOOLEAN("Event.TimestampHasValidTimebase.Browser", + has_valid_timebase); - UMA_HISTOGRAM_BOOLEAN("Event.TimestampHasValidTimebase", true); +#if defined(USE_X11) + // Restrict this correction to X11 which is known to provide bogus timestamps + // that require correction (crbug.com/611950). + if (!has_valid_timebase) + *timestamp = now; #endif }
diff --git a/ui/events/ozone/evdev/event_converter_evdev.cc b/ui/events/ozone/evdev/event_converter_evdev.cc index d0bf95b..42b48ea 100644 --- a/ui/events/ozone/evdev/event_converter_evdev.cc +++ b/ui/events/ozone/evdev/event_converter_evdev.cc
@@ -154,7 +154,10 @@ base::TimeTicks EventConverterEvdev::TimeTicksFromInputEvent( const input_event& event) { - return ui::EventTimeStampFromSeconds(event.time.tv_sec) + + base::TimeTicks timestamp = + ui::EventTimeStampFromSeconds(event.time.tv_sec) + base::TimeDelta::FromMicroseconds(event.time.tv_usec); + ValidateEventTimeClock(×tamp); + return timestamp; } } // namespace ui
diff --git a/ui/gfx/mojo/buffer_types.mojom b/ui/gfx/mojo/buffer_types.mojom index aa5f3be5..8b8de3b8 100644 --- a/ui/gfx/mojo/buffer_types.mojom +++ b/ui/gfx/mojo/buffer_types.mojom
@@ -70,7 +70,7 @@ struct GpuMemoryBufferHandle { GpuMemoryBufferType type; GpuMemoryBufferId id; - handle shared_memory_handle; + handle? shared_memory_handle; uint32 offset; uint32 stride; NativePixmapHandle? native_pixmap_handle;
diff --git a/ui/gfx/mojo/buffer_types_traits.cc b/ui/gfx/mojo/buffer_types_traits.cc index 71cef1b..122d844 100644 --- a/ui/gfx/mojo/buffer_types_traits.cc +++ b/ui/gfx/mojo/buffer_types_traits.cc
@@ -72,6 +72,8 @@ DCHECK(handle.handle.auto_close || handle.handle.fd == -1); platform_file = handle.handle.fd; #endif + if (platform_file == base::kInvalidPlatformFile) + return mojo::ScopedHandle(); return mojo::WrapPlatformFile(platform_file); } @@ -94,20 +96,25 @@ if (!data.ReadType(&out->type) || !data.ReadId(&out->id)) return false; - base::PlatformFile platform_file; - MojoResult unwrap_result = mojo::UnwrapPlatformFile( - data.TakeSharedMemoryHandle(), &platform_file); - if (unwrap_result != MOJO_RESULT_OK) - return false; + mojo::ScopedHandle handle = data.TakeSharedMemoryHandle(); + if (handle.is_valid()) { + base::PlatformFile platform_file; + MojoResult unwrap_result = mojo::UnwrapPlatformFile( + std::move(handle), &platform_file); + if (unwrap_result != MOJO_RESULT_OK) + return false; #if defined(OS_WIN) - out->handle = - base::SharedMemoryHandle(platform_file, base::GetCurrentProcId()); + out->handle = + base::SharedMemoryHandle(platform_file, base::GetCurrentProcId()); #elif defined(OS_MACOSX) || defined(OS_IOS) - // TODO: Add support for mach_port on mac. - out->handle = base::SharedMemoryHandle(); + // TODO: Add support for mach_port on mac. + out->handle = base::SharedMemoryHandle(); #else - out->handle = base::SharedMemoryHandle(platform_file, true); + out->handle = base::SharedMemoryHandle(platform_file, true); #endif + } else { + out->handle = base::SharedMemoryHandle(); + } out->offset = data.offset(); out->stride = data.stride();
diff --git a/ui/gfx/mojo/struct_traits_unittest.cc b/ui/gfx/mojo/struct_traits_unittest.cc index d837cd8..e7cb15f 100644 --- a/ui/gfx/mojo/struct_traits_unittest.cc +++ b/ui/gfx/mojo/struct_traits_unittest.cc
@@ -185,4 +185,11 @@ #endif } +TEST_F(StructTraitsTest, NullGpuMemoryBufferHandle) { + mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); + GpuMemoryBufferHandle output; + proxy->EchoGpuMemoryBufferHandle(GpuMemoryBufferHandle(), &output); + EXPECT_TRUE(output.is_null()); +} + } // namespace gfx
diff --git a/ui/message_center/cocoa/notification_controller.mm b/ui/message_center/cocoa/notification_controller.mm index b14c26c..03ab334 100644 --- a/ui/message_center/cocoa/notification_controller.mm +++ b/ui/message_center/cocoa/notification_controller.mm
@@ -690,6 +690,7 @@ } - (void)settingsClicked:(id)sender { + [NSApp activateIgnoringOtherApps:YES]; messageCenter_->ClickOnSettingsButton([self notificationID]); }
diff --git a/ui/message_center/notification_delegate.cc b/ui/message_center/notification_delegate.cc index 405c703..70675233 100644 --- a/ui/message_center/notification_delegate.cc +++ b/ui/message_center/notification_delegate.cc
@@ -4,6 +4,8 @@ #include "ui/message_center/notification_delegate.h" +#include "base/logging.h" + namespace message_center { // NotificationDelegate: @@ -18,6 +20,11 @@ void NotificationDelegate::ButtonClick(int button_index) {} +void NotificationDelegate::ButtonClickWithReply(int button_index, + const base::string16& reply) { + NOTIMPLEMENTED(); +} + void NotificationDelegate::SettingsClick() {} bool NotificationDelegate::ShouldDisplaySettingsButton() {
diff --git a/ui/message_center/notification_delegate.h b/ui/message_center/notification_delegate.h index 17b4e340..a493c18e 100644 --- a/ui/message_center/notification_delegate.h +++ b/ui/message_center/notification_delegate.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/strings/string16.h" #include "ui/message_center/message_center_export.h" #if defined(TOOLKIT_VIEWS) && !defined(OS_MACOSX) @@ -43,6 +44,12 @@ // To be called when the user clicks a button in a notification. virtual void ButtonClick(int button_index); + // To be called when the user types a reply to a notification. + // TODO(crbug.com/599859) Support this feature in the message center - + // currently it is only supported on Android. + virtual void ButtonClickWithReply(int button_index, + const base::string16& reply); + // To be called when the user clicks the settings button in a notification. virtual void SettingsClick();
diff --git a/ui/views/animation/ink_drop_painted_layer_delegates.cc b/ui/views/animation/ink_drop_painted_layer_delegates.cc index 75609d7..eec57980 100644 --- a/ui/views/animation/ink_drop_painted_layer_delegates.cc +++ b/ui/views/animation/ink_drop_painted_layer_delegates.cc
@@ -39,9 +39,6 @@ void BasePaintedLayerDelegate::OnDeviceScaleFactorChanged( float device_scale_factor) {} -base::Closure BasePaintedLayerDelegate::PrepareForLayerBoundsChange() { - return base::Closure(); -} //////////////////////////////////////////////////////////////////////////////// //
diff --git a/ui/views/animation/ink_drop_painted_layer_delegates.h b/ui/views/animation/ink_drop_painted_layer_delegates.h index c4cab4f3..2103328 100644 --- a/ui/views/animation/ink_drop_painted_layer_delegates.h +++ b/ui/views/animation/ink_drop_painted_layer_delegates.h
@@ -5,7 +5,6 @@ #ifndef UI_VIEWS_ANIMATION_INK_DROP_PAINTED_LAYER_DELEGATES_H_ #define UI_VIEWS_ANIMATION_INK_DROP_PAINTED_LAYER_DELEGATES_H_ -#include "base/callback.h" #include "base/macros.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/compositor/layer_delegate.h" @@ -33,7 +32,6 @@ // ui::LayerDelegate: void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; protected: explicit BasePaintedLayerDelegate(SkColor color);
diff --git a/ui/views/bubble/tray_bubble_view.cc b/ui/views/bubble/tray_bubble_view.cc index 059458a0..fb21a45 100644 --- a/ui/views/bubble/tray_bubble_view.cc +++ b/ui/views/bubble/tray_bubble_view.cc
@@ -187,7 +187,6 @@ void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; private: ui::Layer layer_; @@ -221,10 +220,6 @@ // Redrawing will take care of scale factor change. } -base::Closure TrayBubbleContentMask::PrepareForLayerBoundsChange() { - return base::Closure(); -} - // Custom layout for the bubble-view. Does the default box-layout if there is // enough height. Otherwise, makes sure the bottom rows are visible. class BottomAlignedBoxLayout : public BoxLayout {
diff --git a/ui/views/cocoa/bridged_native_widget.h b/ui/views/cocoa/bridged_native_widget.h index d1e2d08a..0bb5fd9 100644 --- a/ui/views/cocoa/bridged_native_widget.h +++ b/ui/views/cocoa/bridged_native_widget.h
@@ -256,7 +256,6 @@ void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; // Overridden from ui::AcceleratedWidgetMac: NSView* AcceleratedWidgetGetNSView() const override;
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm index 2dc4afd..8e47513 100644 --- a/ui/views/cocoa/bridged_native_widget.mm +++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -1108,10 +1108,6 @@ device_scale_factor); } -base::Closure BridgedNativeWidget::PrepareForLayerBoundsChange() { - return base::Closure(); -} - //////////////////////////////////////////////////////////////////////////////// // BridgedNativeWidget, AcceleratedWidgetMac:
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc index 1e9de95..56415db 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -20,6 +20,7 @@ #include "ui/views/controls/label.h" #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/layout/fill_layout.h" #include "ui/views/layout/layout_manager.h" #include "ui/views/widget/widget.h" @@ -56,6 +57,7 @@ void OnStateChanged() override; // Overridden from View: + gfx::Size GetPreferredSize() const override; void OnPaintBorder(gfx::Canvas* canvas) override; private: @@ -68,18 +70,19 @@ // Internal class name. static const char kViewClassName[]; - explicit TabStrip(TabbedPane* tabbed_pane); + TabStrip(); ~TabStrip() override; // Overridden from View: - gfx::Size GetPreferredSize() const override; - void Layout() override; const char* GetClassName() const override; - void OnPaint(gfx::Canvas* canvas) override; + void OnPaintBorder(gfx::Canvas* canvas) override; + + Tab* GetSelectedTab() const; + Tab* GetTabAtDeltaFromSelected(int delta) const; + Tab* GetTabAtIndex(int index) const; + int GetSelectedTabIndex() const; private: - TabbedPane* tabbed_pane_; - DISALLOW_COPY_AND_ASSIGN(TabStrip); }; @@ -87,13 +90,11 @@ // class uses a BoxLayout to position tabs. class MdTabStrip : public TabStrip { public: - explicit MdTabStrip(TabbedPane* tabbed_pane); + MdTabStrip(); ~MdTabStrip() override; // Overridden from View: - gfx::Size GetPreferredSize() const override; - void Layout() override; - void OnPaint(gfx::Canvas* canvas) override; + void OnPaintBorder(gfx::Canvas* canvas) override; private: DISALLOW_COPY_AND_ASSIGN(MdTabStrip); @@ -115,6 +116,13 @@ // Calculate this now while the font list is guaranteed to be bold. preferred_title_size_ = title_->GetPreferredSize(); + const int kTabVerticalPadding = 5; + const int kTabHorizontalPadding = 10; + + SetBorder(Border::CreateEmptyBorder( + gfx::Insets(kTabVerticalPadding, kTabHorizontalPadding))); + SetLayoutManager(new FillLayout); + SetState(TAB_INACTIVE); AddChildView(title_); } @@ -187,20 +195,10 @@ gfx::Size Tab::GetPreferredSize() const { gfx::Size size(preferred_title_size_); - size.Enlarge(21, 9); - const int kTabMinWidth = 54; - if (size.width() < kTabMinWidth) - size.set_width(kTabMinWidth); + size.Enlarge(GetInsets().width(), GetInsets().height()); return size; } -void Tab::Layout() { - gfx::Rect bounds = GetLocalBounds(); - bounds.Inset(0, 1, 0, 0); - bounds.ClampToCenteredSize(preferred_title_size_); - title_->SetBoundsRect(bounds); -} - const char* Tab::GetClassName() const { return kViewClassName; } @@ -213,10 +211,6 @@ SchedulePaint(); } -bool Tab::ContainerHasFocus() { - return tabbed_pane_->HasFocus(); -} - void Tab::OnFocus() { OnStateChanged(); // When the tab gains focus, send an accessibility event indicating that the @@ -302,49 +296,38 @@ base_color); } +gfx::Size MdTab::GetPreferredSize() const { + return gfx::Size(Tab::GetPreferredSize().width(), kHarmonyTabStripTabHeight); +} + // static const char TabStrip::kViewClassName[] = "TabStrip"; -TabStrip::TabStrip(TabbedPane* tabbed_pane) : tabbed_pane_(tabbed_pane) {} +TabStrip::TabStrip() { + const int kTabStripLeadingEdgePadding = 9; + BoxLayout* layout = + new BoxLayout(BoxLayout::kHorizontal, kTabStripLeadingEdgePadding, 0, 0); + layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_START); + layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_END); + layout->SetDefaultFlex(0); + SetLayoutManager(layout); +} TabStrip::~TabStrip() {} -gfx::Size TabStrip::GetPreferredSize() const { - gfx::Size size; - for (int i = 0; i < child_count(); ++i) { - const gfx::Size child_size = child_at(i)->GetPreferredSize(); - size.SetSize(size.width() + child_size.width(), - std::max(size.height(), child_size.height())); - } - return size; -} - -void TabStrip::Layout() { - const int kTabOffset = 9; - int x = kTabOffset; // Layout tabs with an offset to the tabstrip border. - for (int i = 0; i < child_count(); ++i) { - gfx::Size ps = child_at(i)->GetPreferredSize(); - child_at(i)->SetBounds(x, 0, ps.width(), ps.height()); - x = child_at(i)->bounds().right(); - } -} - const char* TabStrip::GetClassName() const { return kViewClassName; } -void TabStrip::OnPaint(gfx::Canvas* canvas) { - OnPaintBackground(canvas); - - // Draw the TabStrip border. +void TabStrip::OnPaintBorder(gfx::Canvas* canvas) { SkPaint paint; paint.setColor(kTabBorderColor); paint.setStrokeWidth(kTabBorderThickness); SkScalar line_y = SkIntToScalar(height()) - (kTabBorderThickness / 2); SkScalar line_end = SkIntToScalar(width()); - int selected_tab_index = tabbed_pane_->selected_tab_index(); + int selected_tab_index = GetSelectedTabIndex(); if (selected_tab_index >= 0) { - Tab* selected_tab = tabbed_pane_->GetTabAt(selected_tab_index); + Tab* selected_tab = GetTabAtIndex(selected_tab_index); SkPath path; SkScalar tab_height = SkIntToScalar(selected_tab->height()) - kTabBorderThickness; @@ -368,7 +351,30 @@ } } -MdTabStrip::MdTabStrip(TabbedPane* tabbed_pane) : TabStrip(tabbed_pane) { +Tab* TabStrip::GetTabAtIndex(int index) const { + return static_cast<Tab*>(const_cast<View*>(child_at(index))); +} + +int TabStrip::GetSelectedTabIndex() const { + for (int i = 0; i < child_count(); ++i) + if (GetTabAtIndex(i)->selected()) + return i; + return -1; +} + +Tab* TabStrip::GetSelectedTab() const { + int index = GetSelectedTabIndex(); + return index >= 0 ? GetTabAtIndex(index) : nullptr; +} + +Tab* TabStrip::GetTabAtDeltaFromSelected(int delta) const { + int index = (GetSelectedTabIndex() + delta) % child_count(); + if (index < 0) + index += child_count(); + return GetTabAtIndex(index); +} + +MdTabStrip::MdTabStrip() { BoxLayout* layout = new BoxLayout(BoxLayout::kHorizontal, 0, kHarmonyTabStripVerticalPad, 0); layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER); @@ -379,35 +385,25 @@ MdTabStrip::~MdTabStrip() {} -gfx::Size MdTabStrip::GetPreferredSize() const { - return gfx::Size(width(), - kHarmonyTabStripVerticalPad * 2 + kHarmonyTabStripTabHeight); -} - -// Let this class's LayoutManager handle the layout. -void MdTabStrip::Layout() { - return View::Layout(); -} - -// The tab strip "border" is drawn as part of the tabs, so all this method needs -// to do is paint the background. -void MdTabStrip::OnPaint(gfx::Canvas* canvas) { - OnPaintBackground(canvas); -} +// The tab strip "border" is drawn as part of the tabs. +void MdTabStrip::OnPaintBorder(gfx::Canvas* canvas) {} TabbedPane::TabbedPane() : listener_(NULL), tab_strip_(ui::MaterialDesignController::IsSecondaryUiMaterial() - ? new MdTabStrip(this) - : new TabStrip(this)), - contents_(new View()), - selected_tab_index_(-1) { + ? new MdTabStrip + : new TabStrip), + contents_(new View()) { AddChildView(tab_strip_); AddChildView(contents_); } TabbedPane::~TabbedPane() {} +int TabbedPane::GetSelectedTabIndex() const { + return tab_strip_->GetSelectedTabIndex(); +} + int TabbedPane::GetTabCount() { DCHECK_EQ(tab_strip_->child_count(), contents_->child_count()); return contents_->child_count(); @@ -429,24 +425,18 @@ : new Tab(this, title, contents), index); contents_->AddChildViewAt(contents, index); - // TODO(ellyjones): if index < selected_tab_index(), selected_tab_index() gets - // out of sync with which tab believes it is selected. This class should - // directly ask Tabs whether they are selected. - if (selected_tab_index() < 0) + if (!GetSelectedTab()) SelectTabAt(index); PreferredSizeChanged(); } -void TabbedPane::SelectTabAt(int index) { - DCHECK(index >= 0 && index < GetTabCount()); - if (index == selected_tab_index()) +void TabbedPane::SelectTab(Tab* new_selected_tab) { + Tab* old_selected_tab = tab_strip_->GetSelectedTab(); + if (old_selected_tab == new_selected_tab) return; - Tab* old_selected_tab = GetSelectedTab(); - Tab* new_selected_tab = GetTabAt(index); new_selected_tab->SetSelected(true); - selected_tab_index_ = index; if (old_selected_tab) { if (old_selected_tab->HasFocus()) new_selected_tab->RequestFocus(); @@ -463,13 +453,13 @@ } if (listener()) - listener()->TabSelectedAt(index); + listener()->TabSelectedAt(tab_strip_->GetIndexOf(new_selected_tab)); } -void TabbedPane::SelectTab(Tab* tab) { - const int index = tab_strip_->GetIndexOf(tab); - if (index >= 0) - SelectTabAt(index); +void TabbedPane::SelectTabAt(int index) { + Tab* tab = tab_strip_->GetTabAtIndex(index); + if (tab) + SelectTab(tab); } gfx::Size TabbedPane::GetPreferredSize() const { @@ -480,22 +470,14 @@ return size; } -Tab* TabbedPane::GetTabAt(int index) { - return static_cast<Tab*>(tab_strip_->child_at(index)); -} - Tab* TabbedPane::GetSelectedTab() { - return selected_tab_index() >= 0 ? GetTabAt(selected_tab_index()) : nullptr; + return tab_strip_->GetSelectedTab(); } bool TabbedPane::MoveSelectionBy(int delta) { - const int tab_count = GetTabCount(); - if (tab_count <= 1) + if (contents_->child_count() <= 1) return false; - int next_selected_index = (selected_tab_index() + delta) % tab_count; - if (next_selected_index < 0) - next_selected_index += tab_count; - SelectTabAt(next_selected_index); + SelectTab(tab_strip_->GetTabAtDeltaFromSelected(delta)); return true; }
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h index 44c48bb..af41d969 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.h +++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -30,7 +30,9 @@ TabbedPaneListener* listener() const { return listener_; } void set_listener(TabbedPaneListener* listener) { listener_ = listener; } - int selected_tab_index() const { return selected_tab_index_; } + // Returns the index of the currently selected tab, or -1 if no tab is + // selected. + int GetSelectedTabIndex() const; // Returns the number of tabs. int GetTabCount(); @@ -118,7 +120,6 @@ void OnMouseExited(const ui::MouseEvent& event) override; void OnGestureEvent(ui::GestureEvent* event) override; gfx::Size GetPreferredSize() const override; - void Layout() override; const char* GetClassName() const override; void OnFocus() override; void OnBlur() override; @@ -130,9 +131,6 @@ // Called whenever |tab_state_| changes. virtual void OnStateChanged(); - // Returns whether the containing TabStrip has focus. - bool ContainerHasFocus(); - private: enum TabState { TAB_INACTIVE,
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc index 9b1fb8c..e02a252 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -74,20 +74,20 @@ View* tab = new View(); tabbed_pane->AddTab(ASCIIToUTF16("tab"), tab); EXPECT_EQ(i + 1, tabbed_pane->GetTabCount()); - EXPECT_EQ(0, tabbed_pane->selected_tab_index()); + EXPECT_EQ(0, tabbed_pane->GetSelectedTabIndex()); } // Select each tab. for (int i = 0; i < tabbed_pane->GetTabCount(); ++i) { tabbed_pane->SelectTabAt(i); - EXPECT_EQ(i, tabbed_pane->selected_tab_index()); + EXPECT_EQ(i, tabbed_pane->GetSelectedTabIndex()); } // Add a tab at index 0, it should not be selected automatically. View* tab0 = new View(); tabbed_pane->AddTabAtIndex(0, ASCIIToUTF16("tab0"), tab0); EXPECT_NE(tab0, tabbed_pane->GetSelectedTabContentView()); - EXPECT_NE(0, tabbed_pane->selected_tab_index()); + EXPECT_NE(0, tabbed_pane->GetSelectedTabIndex()); } ui::KeyEvent MakeKeyPressedEvent(ui::KeyboardCode keyboard_code, int flags) { @@ -104,27 +104,27 @@ EXPECT_EQ(i + 1, tabbed_pane->GetTabCount()); } - EXPECT_EQ(0, tabbed_pane->selected_tab_index()); + EXPECT_EQ(0, tabbed_pane->GetSelectedTabIndex()); // Right arrow should select tab 1: tabbed_pane->GetSelectedTab()->OnKeyPressed( MakeKeyPressedEvent(ui::VKEY_RIGHT, 0)); - EXPECT_EQ(1, tabbed_pane->selected_tab_index()); + EXPECT_EQ(1, tabbed_pane->GetSelectedTabIndex()); // Left arrow should select tab 0: tabbed_pane->GetSelectedTab()->OnKeyPressed( MakeKeyPressedEvent(ui::VKEY_LEFT, 0)); - EXPECT_EQ(0, tabbed_pane->selected_tab_index()); + EXPECT_EQ(0, tabbed_pane->GetSelectedTabIndex()); // Left arrow again should wrap to tab 2: tabbed_pane->GetSelectedTab()->OnKeyPressed( MakeKeyPressedEvent(ui::VKEY_LEFT, 0)); - EXPECT_EQ(2, tabbed_pane->selected_tab_index()); + EXPECT_EQ(2, tabbed_pane->GetSelectedTabIndex()); // Right arrow again should wrap to tab 0: tabbed_pane->GetSelectedTab()->OnKeyPressed( MakeKeyPressedEvent(ui::VKEY_RIGHT, 0)); - EXPECT_EQ(0, tabbed_pane->selected_tab_index()); + EXPECT_EQ(0, tabbed_pane->GetSelectedTabIndex()); } } // namespace views
diff --git a/ui/views/examples/tabbed_pane_example.cc b/ui/views/examples/tabbed_pane_example.cc index 087c77bf..524fec6c9 100644 --- a/ui/views/examples/tabbed_pane_example.cc +++ b/ui/views/examples/tabbed_pane_example.cc
@@ -40,6 +40,7 @@ // Create a few tabs with a button first. AddButton("Tab 1"); AddButton("Tab 2"); + AddButton("Tab 3"); // Add control buttons horizontally. const int button_column = 1; @@ -76,7 +77,7 @@ void TabbedPaneExample::PrintStatus() { ExampleBase::PrintStatus("Tab Count:%d, Selected Tab:%d", tabbed_pane_->GetTabCount(), - tabbed_pane_->selected_tab_index()); + tabbed_pane_->GetSelectedTabIndex()); } void TabbedPaneExample::AddButton(const std::string& label) {
diff --git a/ui/views/view.cc b/ui/views/view.cc index ca1913ed..3cb42dc 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -1527,10 +1527,6 @@ // Repainting with new scale factor will paint the content at the right scale. } -base::Closure View::PrepareForLayerBoundsChange() { - return base::Closure(); -} - void View::ReorderLayers() { View* v = this; while (v && !v->layer())
diff --git a/ui/views/view.h b/ui/views/view.h index 05f6da3..572d3a5 100644 --- a/ui/views/view.h +++ b/ui/views/view.h
@@ -1123,7 +1123,6 @@ void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; // Finds the layer that this view paints to (it may belong to an ancestor // view), then reorders the immediate children of that layer to match the
diff --git a/ui/wm/core/image_grid.cc b/ui/wm/core/image_grid.cc index c4be0c3..527d6eb 100644 --- a/ui/wm/core/image_grid.cc +++ b/ui/wm/core/image_grid.cc
@@ -286,10 +286,6 @@ // Redrawing will take care of scale factor change. } -base::Closure ImageGrid::ImagePainter::PrepareForLayerBoundsChange() { - return base::Closure(); -} - void ImageGrid::SetImage(const gfx::Image* image, std::unique_ptr<ui::Layer>* layer_ptr, std::unique_ptr<ImagePainter>* painter_ptr,
diff --git a/ui/wm/core/image_grid.h b/ui/wm/core/image_grid.h index eba2817..d171e9b 100644 --- a/ui/wm/core/image_grid.h +++ b/ui/wm/core/image_grid.h
@@ -140,7 +140,6 @@ void OnPaintLayer(const ui::PaintContext& context) override; void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; void OnDeviceScaleFactorChanged(float device_scale_factor) override; - base::Closure PrepareForLayerBoundsChange() override; private: friend class TestAPI;
diff --git a/ui/wm/core/window_util_unittest.cc b/ui/wm/core/window_util_unittest.cc index 8453e30..5cc2b38 100644 --- a/ui/wm/core/window_util_unittest.cc +++ b/ui/wm/core/window_util_unittest.cc
@@ -28,9 +28,6 @@ void OnPaintLayer(const ui::PaintContext& context) override {} void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} void OnDeviceScaleFactorChanged(float device_scale_factor) override {} - base::Closure PrepareForLayerBoundsChange() override { - return base::Closure(); - } ui::Layer* original_layer() { return original_layer_; }