Import Cobalt 22.lts.1.303143
diff --git a/src/cobalt/browser/application.cc b/src/cobalt/browser/application.cc
index ba3c984..6f0d01a 100644
--- a/src/cobalt/browser/application.cc
+++ b/src/cobalt/browser/application.cc
@@ -591,6 +591,9 @@
ssize_t Application::available_memory_ = 0;
int64 Application::lifetime_in_ms_ = 0;
+Application::AppStatus Application::app_status_ =
+ Application::kUninitializedAppStatus;
+
Application::Application(const base::Closure& quit_closure, bool should_preload,
SbTimeMonotonic timestamp)
: message_loop_(base::MessageLoop::current()),
@@ -857,6 +860,8 @@
timestamp);
UpdateUserAgent();
+ app_status_ = (should_preload ? kConcealedAppStatus : kRunningAppStatus);
+
// Register event callbacks.
window_size_change_event_callback_ = base::Bind(
&Application::OnWindowSizeChangedEvent, base::Unretained(this));
@@ -1004,6 +1009,8 @@
base::DateTimeConfigurationChangedEvent::TypeId(),
on_date_time_configuration_changed_event_callback_);
#endif
+
+ app_status_ = kShutDownAppStatus;
}
void Application::Start(SbTimeMonotonic timestamp) {
@@ -1027,6 +1034,7 @@
}
quit_closure_.Run();
+ app_status_ = kQuitAppStatus;
}
void Application::HandleStarboardEvent(const SbEvent* starboard_event) {
diff --git a/src/cobalt/browser/application.h b/src/cobalt/browser/application.h
index 1fa07da..52e2a94 100644
--- a/src/cobalt/browser/application.h
+++ b/src/cobalt/browser/application.h
@@ -203,6 +203,8 @@
static ssize_t available_memory_;
static int64 lifetime_in_ms_;
+ static AppStatus app_status_;
+
CValStats c_val_stats_;
base::RepeatingTimer stats_update_timer_;
diff --git a/src/cobalt/browser/browser_bindings_gen.gyp b/src/cobalt/browser/browser_bindings_gen.gyp
index 9941d47..f9540eb 100644
--- a/src/cobalt/browser/browser_bindings_gen.gyp
+++ b/src/cobalt/browser/browser_bindings_gen.gyp
@@ -135,8 +135,6 @@
'../dom/performance.idl',
'../dom/performance_entry.idl',
'../dom/performance_lifecycle_timing.idl',
- '../dom/performance_mark.idl',
- '../dom/performance_measure.idl',
'../dom/performance_observer.idl',
'../dom/performance_observer_entry_list.idl',
'../dom/performance_resource_timing.idl',
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index 912bb2b..9dfa8f2 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-303120
\ No newline at end of file
+303143
\ No newline at end of file
diff --git a/src/cobalt/dom/dom.gyp b/src/cobalt/dom/dom.gyp
index 4039e2c..7cb5cb8 100644
--- a/src/cobalt/dom/dom.gyp
+++ b/src/cobalt/dom/dom.gyp
@@ -264,10 +264,6 @@
'performance_entry_list_impl.h',
'performance_lifecycle_timing.cc',
'performance_lifecycle_timing.h',
- 'performance_mark.cc',
- 'performance_mark.h',
- 'performance_measure.cc',
- 'performance_measure.h',
'performance_observer.cc',
'performance_observer.h',
'performance_observer_entry_list.cc',
diff --git a/src/cobalt/dom/performance.cc b/src/cobalt/dom/performance.cc
index a90c2e8..f7f79b9 100644
--- a/src/cobalt/dom/performance.cc
+++ b/src/cobalt/dom/performance.cc
@@ -14,61 +14,26 @@
#include "cobalt/dom/performance.h"
-#include <string>
-
-#include "base/time/time.h"
#include "base/time/default_clock.h"
+#include "base/time/time.h"
#include "cobalt/browser/stack_size_constants.h"
-#include "cobalt/dom/dom_exception.h"
#include "cobalt/dom/memory_info.h"
#include "cobalt/dom/performance_entry.h"
-#include "cobalt/dom/performance_mark.h"
-#include "cobalt/dom/performance_measure.h"
namespace cobalt {
namespace dom {
namespace {
-base::TimeDelta GetUnixAtZeroMonotonic(const base::Clock* clock,
+ base::TimeDelta GetUnixAtZeroMonotonic(const base::Clock* clock,
const base::TickClock* tick_clock) {
base::TimeDelta unix_time_now = clock->Now() - base::Time::UnixEpoch();
base::TimeDelta time_since_origin = tick_clock->NowTicks().since_origin();
return unix_time_now - time_since_origin;
}
-bool IsNamePerformanceTimingAttribute(const std::string& name) {
- return name == "navigationStart";
}
-DOMHighResTimeStamp ConvertNameToTimestamp(
- const std::string& name, script::ExceptionState* exception_state) {
- // The algorithm of ConvertNameToTimestamp() follows these steps:
- // https://www.w3.org/TR/user-timing/#convert-a-name-to-a-timestamp
- // 1. If the global object is not a Window object, throw a SyntaxError.
- // 2. If name is navigationStart, return 0.
- if (name == "navigationStart") {
- return 0.0;
- }
-
- // 3. Let startTime be the value of navigationStart in the PerformanceTiming
- // interface.
- // 4. Let endTime be the value of name in the PerformanceTiming interface.
- // 5. If endTime is 0, throw an InvalidAccessError.
- // 6. Return result of subtracting startTime from endTime.
-
- // Note that we only support navigationStart in the PerformanceTiming
- // interface. We return 0.0 instead of the result of subtracting
- // startTime from endTime.
- dom::DOMException::Raise(dom::DOMException::kSyntaxErr,
- "Cannot convert a name that is not a public "
- "attribute of PerformanceTiming to a timestamp",
- exception_state);
- return 0.0;
-}
-
-} //namespace
-
Performance::Performance(script::EnvironmentSettings* settings,
const scoped_refptr<base::BasicClock>& clock)
: EventTarget(settings),
@@ -141,163 +106,6 @@
Performance::kPerformanceTimerMinResolutionInMicroseconds);
}
-void Performance::Mark(const std::string& mark_name,
- script::ExceptionState* exception_state) {
- // The algorithm for mark() follows these steps:
- // https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#mark-method
- // 1. If the global object is a Window object and markName uses the same name
- // as a read only attribute in the PerformanceTiming interface, throw a
- // SyntaxError.
- if (IsNamePerformanceTimingAttribute(mark_name)) {
- dom::DOMException::Raise(
- dom::DOMException::kSyntaxErr,
- "Cannot create a mark with the same name as a read-only attribute in "
- "the PerformanceTiming interface",
- exception_state);
- }
-
- // 2. Create a new PerformanceMark object (entry).
- // 3. Set entry's name attribute to markName.
- // 4. Set entry's entryType attribute to DOMString "mark".
- // 5. Set entry's startTime attribute to the value that would be returned by
- // the Performance object's now() method.
- // 6. Set entry's duration attribute to 0.
- scoped_refptr<PerformanceMark> entry =
- base::MakeRefCounted<PerformanceMark>(mark_name, Now());
-
- // 7. Queue entry.
- QueuePerformanceEntry(entry);
-
- // 8. Add entry to the performance entry buffer.
- performance_entry_buffer_.push_back(entry);
-
- // 9. Return undefined
-}
-
-void Performance::ClearMarks(const std::string& mark_name) {
- // The algorithm for clearMarks follows these steps:
- // https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#clearmarks-method
- // 1. If markName is omitted, remove all PerformanceMark objects from the
- // performance entry buffer.
- // 2. Otherwise, remove all PerformanceMark objects listed in the performance
- // entry buffer whose name matches markName.
- PerformanceEntryList retained_performance_entry_buffer;
- for (const auto& entry : performance_entry_buffer_) {
- bool should_remove_entry =
- PerformanceEntry::ToEntryTypeEnum(entry->entry_type()) ==
- PerformanceEntry::kMark &&
- (mark_name.empty() || entry->name() == mark_name);
- if (!should_remove_entry) {
- retained_performance_entry_buffer.push_back(entry);
- }
- }
- performance_entry_buffer_.swap(retained_performance_entry_buffer);
-
- // 3. Return undefined.
-}
-
-void Performance::Measure(const std::string& measure_name,
- const std::string& start_mark,
- const std::string& end_mark,
- script::ExceptionState* exception_state) {
- // The algorithm for measure() follows these steps:
- // https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#measure-method
- // 1. Let end time be 0.
- DOMHighResTimeStamp end_time = 0.0;
-
- // 2. If endMark is omitted, let end time be the value that would be returned
- // by the Performance object's now() method.
- if (end_mark.empty()) {
- end_time = Now();
- } else if (IsNamePerformanceTimingAttribute(end_mark)) {
- // 2.1. Otherwise, if endMark has the same name as a read only attribute in
- // the PerformanceTiming interface, let end time be the value returned by
- // running the convert a name to a timestamp algorithm with name set to the
- // value of endMark.
- end_time = ConvertNameToTimestamp(end_mark, exception_state);
- } else {
- // 2.2. Otherwise let end time be the value of the startTime attribute from
- // the most recent occurrence of a PerformanceMark object in the performance
- // entry buffer whose name matches the value of endMark. If no matching
- // entry is found, throw a SyntaxError.
- PerformanceEntryList list = GetEntriesByName(end_mark, "mark");
- if (list.empty()) {
- dom::DOMException::Raise(
- dom::DOMException::kSyntaxErr,
- "Cannot create measure; no mark found with name: " + end_mark + ".",
- exception_state);
- return;
- }
- end_time = list.at(list.size() - 1)->start_time();
- }
-
- DOMHighResTimeStamp start_time;
- // 3. If startMark is omitted, let start time be 0.
- if (start_mark.empty()) {
- start_time = 0.0;
- } else if (IsNamePerformanceTimingAttribute(start_mark)) {
- // 3.1. If startMark has the same name as a read only attribute in the
- // PerformanceTiming interface, let start time be the value returned by
- // running the convert a name to a timestamp algorithm with name set to
- // startMark.
- start_time = ConvertNameToTimestamp(start_mark, exception_state);
- } else {
- // 3.2. Otherwise let start time be the value of the startTime attribute
- // from the most recent occurrence of a PerformanceMark object in the
- // performance entry buffer whose name matches the value of startMark. If no
- // matching entry is found, throw a SyntaxError.
- PerformanceEntryList list = GetEntriesByName(start_mark, "mark");
- if (list.empty()) {
- dom::DOMException::Raise(
- dom::DOMException::kSyntaxErr,
- "Cannot create measure; no mark found with name: " + start_mark + ".",
- exception_state);
- return;
- }
- start_time = list.at(list.size() - 1)->start_time();
- }
-
- // 4. Create a new PerformanceMeasure object (entry).
- // 5. Set entry's name attribute to measureName.
- // 6. Set entry's entryType attribute to DOMString "measure".
- // 7. Set entry's startTime attribute to start time.
- // 8. Set entry's duration attribute to the duration from start time to end
- // time. The resulting duration value MAY be negative.
- scoped_refptr<PerformanceMeasure> entry =
- base::MakeRefCounted<PerformanceMeasure>(measure_name, start_time,
- end_time);
-
- // 9. Queue entry.
- QueuePerformanceEntry(entry);
-
- // 10. Add entry to the performance entry buffer.
- performance_entry_buffer_.push_back(entry);
-
- // 11. Return undefined.
-}
-
-void Performance::ClearMeasures(const std::string& measure_name) {
- // The algorithm for clearMeasures follows these steps:
- // https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#clearmeasures-method
- // 1. If measureName is omitted, remove all PerformanceMeasure objects in the
- // performance entry buffer.
- // 2. Otherwise remove all PerformanceMeasure objects listed in the
- // performance entry buffer whose name matches measureName.
- PerformanceEntryList performance_entry_buffer;
- for (const auto& entry : performance_entry_buffer_) {
- bool shouldRemoveEntry =
- PerformanceEntry::ToEntryTypeEnum(entry->entry_type()) ==
- PerformanceEntry::kMeasure &&
- (measure_name.empty() || entry->name() == measure_name);
- if (!shouldRemoveEntry) {
- performance_entry_buffer.push_back(entry);
- }
- }
- performance_entry_buffer_.swap(performance_entry_buffer);
-
- // 3. Return undefined.
-}
-
void Performance::UnregisterPerformanceObserver(
const scoped_refptr<PerformanceObserver>& old_observer) {
auto iter = registered_performance_observers_.begin();
@@ -315,7 +123,8 @@
const PerformanceObserverInit& options) {
std::list<PerformanceObserverInit> options_list;
options_list.push_back(options);
- registered_performance_observers_.emplace_back(observer, options_list);
+ registered_performance_observers_.emplace_back(observer,
+ options_list);
}
void Performance::ReplaceRegisteredPerformanceObserverOptionsList(
@@ -391,8 +200,7 @@
resource_timing_buffer_current_size_ = 0;
}
-void Performance::SetResourceTimingBufferSize(
- unsigned long max_size) { // NOLINT(runtime/int)
+void Performance::SetResourceTimingBufferSize(unsigned long max_size) {
// The method runs the following steps:
// https://www.w3.org/TR/2021/WD-resource-timing-2-20210414/#dom-performance-setresourcetimingbuffersize
// 1. Set resource timing buffer size limit to the maxSize parameter.
@@ -453,7 +261,7 @@
while (!resource_timing_secondary_buffer_.empty()) {
// 1.1 Let number of excess entries before be resource timing secondary
// buffer current size.
- unsigned long excess_entries_before = // NOLINT(runtime/int)
+ unsigned long excess_entries_before =
resource_timing_secondary_buffer_current_size_;
// 1.2 If can add resource timing entry returns false, then fire an event
// named resourcetimingbufferfull at the Performance object.
@@ -464,7 +272,7 @@
CopySecondaryBuffer();
// 1.4 Let number of excess entries after be resource timing secondary
// buffer current size.
- unsigned long excess_entries_after = // NOLINT(runtime/int)
+ unsigned long excess_entries_after =
resource_timing_secondary_buffer_current_size_;
// 1.5 If number of excess entries before is lower than or equals number of
// excess entries after, then remove all entries from resource timing
diff --git a/src/cobalt/dom/performance.h b/src/cobalt/dom/performance.h
index 753123d..38c5600 100644
--- a/src/cobalt/dom/performance.h
+++ b/src/cobalt/dom/performance.h
@@ -21,8 +21,6 @@
#include <string>
#include "base/time/default_tick_clock.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_checker.h"
#include "cobalt/base/application_state.h"
#include "cobalt/base/clock.h"
#include "cobalt/dom/event_target.h"
@@ -35,7 +33,7 @@
#include "cobalt/dom/performance_resource_timing.h"
#include "cobalt/dom/performance_timing.h"
#include "cobalt/script/environment_settings.h"
-#include "cobalt/script/exception_state.h"
+
#include "net/base/load_timing_info.h"
namespace cobalt {
@@ -52,11 +50,9 @@
// order to mitigate potential Spectre-related attacks. This is following
// Mozilla's lead as described here:
// https://www.mozilla.org/en-US/security/advisories/mfsa2018-01/
- // NOLINT(runtime/int)
static constexpr int64_t kPerformanceTimerMinResolutionInMicroseconds = 20;
// https://www.w3.org/TR/2021/WD-resource-timing-2-20210414/#sec-extensions-performance-interface
- static constexpr unsigned long // NOLINT(runtime/int)
- kMaxResourceTimingBufferSize = 250;
+ static constexpr unsigned long kMaxResourceTimingBufferSize = 250;
Performance(script::EnvironmentSettings* settings,
const scoped_refptr<base::BasicClock>& clock);
@@ -81,22 +77,10 @@
PerformanceEntryList GetEntriesByName(const std::string& name,
const base::StringPiece& type);
- // Web API: User Timing extensions to Performance
- // https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#extensions-performance-interface
- void Mark(const std::string& mark_name,
- script::ExceptionState* exception_state);
- void ClearMarks(const std::string& mark_name);
- void Measure(const std::string& measure_name, const std::string& start_mark,
- const std::string& end_mark,
- script::ExceptionState* exception_state);
- void ClearMeasures(const std::string& measure_name);
-
// Web API: Performance Resource Timing extensions to Performance.
// https://w3c.github.io/resource-timing/#sec-extensions-performance-interface
void ClearResourceTimings();
- // NOLINT(runtime/int)
- void SetResourceTimingBufferSize(
- unsigned long max_size); // NOLINT(runtime/int)
+ void SetResourceTimingBufferSize(unsigned long max_size);
bool CanAddResourceTimingEntry();
void CopySecondaryBuffer();
void set_onresourcetimingbufferfull(
@@ -173,8 +157,7 @@
unsigned long resource_timing_buffer_size_limit_;
unsigned long resource_timing_buffer_current_size_;
bool resource_timing_buffer_full_event_pending_flag_;
- unsigned long
- resource_timing_secondary_buffer_current_size_;
+ unsigned long resource_timing_secondary_buffer_current_size_;
std::deque<scoped_refptr<PerformanceResourceTiming>>
resource_timing_secondary_buffer_;
diff --git a/src/cobalt/dom/performance.idl b/src/cobalt/dom/performance.idl
index 91d2e8e..fd42dd3 100644
--- a/src/cobalt/dom/performance.idl
+++ b/src/cobalt/dom/performance.idl
@@ -25,14 +25,4 @@
void clearResourceTimings ();
void setResourceTimingBufferSize (unsigned long maxSize);
attribute EventHandler onresourcetimingbufferfull;
-
- // Web API: User Timing extensions to Performance
- // https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#extensions-performance-interface
- [RaisesException] void mark(DOMString name);
- [RaisesException] void measure(
- DOMString measureName,
- optional DOMString startMark = "",
- optional DOMString endMark = "");
- void clearMarks(optional DOMString name = "");
- void clearMeasures(optional DOMString measureName = "");
};
diff --git a/src/cobalt/dom/performance_entry.h b/src/cobalt/dom/performance_entry.h
index 7617b36..5643bb1 100644
--- a/src/cobalt/dom/performance_entry.h
+++ b/src/cobalt/dom/performance_entry.h
@@ -29,20 +29,19 @@
// https://w3c.github.io/performance-timeline/#the-performanceentry-interface
class PerformanceEntry : public script::Wrappable {
public:
- PerformanceEntry(const std::string& name, DOMHighResTimeStamp start_time,
+ PerformanceEntry(const std::string& name,
+ DOMHighResTimeStamp start_time,
DOMHighResTimeStamp finish_time);
enum EntryType : PerformanceEntryType {
kResource = 0,
kNavigation = 1,
kLifecycle = 2,
- kMark = 3,
- kMeasure = 4,
- kInvalid = 5,
+ kInvalid = 3,
};
- static constexpr const char* kEntryTypeString[] = {
- "resource", "navigation", "lifecycle", "mark", "measure", "invalid"};
+ static constexpr const char* kEntryTypeString[] =
+ {"resource", "navigation", "lifecycle", "invalid"};
std::string name() const { return name_; }
DOMHighResTimeStamp start_time() const;
@@ -55,9 +54,8 @@
static PerformanceEntry::EntryType ToEntryTypeEnum(
const std::string& entry_type);
- static bool StartTimeCompareLessThan(
- const scoped_refptr<PerformanceEntry>& a,
- const scoped_refptr<PerformanceEntry>& b);
+ static bool StartTimeCompareLessThan(const scoped_refptr<PerformanceEntry>& a,
+ const scoped_refptr<PerformanceEntry>& b);
DEFINE_WRAPPABLE_TYPE(PerformanceEntry);
diff --git a/src/cobalt/dom/performance_mark.cc b/src/cobalt/dom/performance_mark.cc
deleted file mode 100644
index 0efdf5b..0000000
--- a/src/cobalt/dom/performance_mark.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2021 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/dom/performance_mark.h"
-
-#include "cobalt/dom/performance.h"
-#include "cobalt/dom/performance_entry.h"
-
-namespace cobalt {
-namespace dom {
-
-PerformanceMark::PerformanceMark(const std::string& name,
- DOMHighResTimeStamp start_time)
- : PerformanceEntry(name, start_time, start_time) {}
-
-} // namespace dom
-} // namespace cobalt
diff --git a/src/cobalt/dom/performance_mark.h b/src/cobalt/dom/performance_mark.h
deleted file mode 100644
index 7d477b6..0000000
--- a/src/cobalt/dom/performance_mark.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2021 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_DOM_PERFORMANCE_MARK_H_
-#define COBALT_DOM_PERFORMANCE_MARK_H_
-
-#include <string>
-
-#include "cobalt/dom/performance_entry.h"
-#include "cobalt/dom/performance_high_resolution_time.h"
-#include "cobalt/script/wrappable.h"
-#include "net/base/load_timing_info.h"
-
-namespace cobalt {
-namespace dom {
-class Performance;
-
-// Implements the PerformanceMart interface.
-// https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#performancemark
-class PerformanceMark : public PerformanceEntry {
- public:
- PerformanceMark(const std::string& name, DOMHighResTimeStamp start_time);
-
- std::string entry_type() const override { return "mark"; }
- PerformanceEntryType EntryTypeEnum() const override {
- return PerformanceEntry::kMark;
- }
-
- DEFINE_WRAPPABLE_TYPE(PerformanceMark);
-};
-} // namespace dom
-} // namespace cobalt
-
-#endif // COBALT_DOM_PERFORMANCE_MARK_H_
diff --git a/src/cobalt/dom/performance_mark.idl b/src/cobalt/dom/performance_mark.idl
deleted file mode 100644
index 834479b..0000000
--- a/src/cobalt/dom/performance_mark.idl
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2021 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-[Exposed=Window]
-interface PerformanceMark : PerformanceEntry {};
diff --git a/src/cobalt/dom/performance_measure.cc b/src/cobalt/dom/performance_measure.cc
deleted file mode 100644
index 1a7edfb..0000000
--- a/src/cobalt/dom/performance_measure.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2021 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/dom/performance_measure.h"
-
-#include "cobalt/dom/performance.h"
-#include "cobalt/dom/performance_entry.h"
-
-namespace cobalt {
-namespace dom {
-
-PerformanceMeasure::PerformanceMeasure(const std::string& name,
- DOMHighResTimeStamp start_time,
- DOMHighResTimeStamp end_time)
- : PerformanceEntry(name, start_time, end_time) {}
-
-} // namespace dom
-} // namespace cobalt
diff --git a/src/cobalt/dom/performance_measure.h b/src/cobalt/dom/performance_measure.h
deleted file mode 100644
index 41107c3..0000000
--- a/src/cobalt/dom/performance_measure.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2021 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_DOM_PERFORMANCE_MEASURE_H_
-#define COBALT_DOM_PERFORMANCE_MEASURE_H_
-
-#include <string>
-
-#include "cobalt/dom/performance_entry.h"
-#include "cobalt/dom/performance_high_resolution_time.h"
-#include "cobalt/script/wrappable.h"
-#include "net/base/load_timing_info.h"
-
-namespace cobalt {
-namespace dom {
-class Performance;
-
-// Implements the PerformanceMeasure interface.
-// https://www.w3.org/TR/2019/REC-user-timing-2-20190226/#performancemeasure
-class PerformanceMeasure : public PerformanceEntry {
- public:
- PerformanceMeasure(const std::string& name, DOMHighResTimeStamp start_time,
- DOMHighResTimeStamp end_time);
-
- std::string entry_type() const override { return "measure"; }
- PerformanceEntryType EntryTypeEnum() const override {
- return PerformanceEntry::kMeasure;
- }
-
- DEFINE_WRAPPABLE_TYPE(PerformanceMeasure);
-};
-} // namespace dom
-} // namespace cobalt
-
-#endif // COBALT_DOM_PERFORMANCE_MEASURE_H_
diff --git a/src/cobalt/dom/performance_measure.idl b/src/cobalt/dom/performance_measure.idl
deleted file mode 100644
index b6cb447..0000000
--- a/src/cobalt/dom/performance_measure.idl
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2021 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-[Exposed=Window]
-interface PerformanceMeasure : PerformanceEntry {};
diff --git a/src/cobalt/dom/performance_timing.h b/src/cobalt/dom/performance_timing.h
index 184d92d..a31efb6 100644
--- a/src/cobalt/dom/performance_timing.h
+++ b/src/cobalt/dom/performance_timing.h
@@ -15,9 +15,10 @@
#ifndef COBALT_DOM_PERFORMANCE_TIMING_H_
#define COBALT_DOM_PERFORMANCE_TIMING_H_
+#include "cobalt/script/wrappable.h"
+
#include "base/time/time.h"
#include "cobalt/base/clock.h"
-#include "cobalt/script/wrappable.h"
namespace cobalt {
namespace dom {
@@ -25,8 +26,6 @@
// Implements the PerformanceTiming IDL interface, as described here:
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html#sec-navigation-timing-interface
class PerformanceTiming : public script::Wrappable {
- // If any new public fields are added here, handling logic must be added to
- // Performance::Mark and Performance::Measure.
public:
explicit PerformanceTiming(const scoped_refptr<base::BasicClock>& clock,
base::TimeTicks time_origin);
diff --git a/src/cobalt/media/base/playback_statistics.cc b/src/cobalt/media/base/playback_statistics.cc
index 2c797c8..c35a451 100644
--- a/src/cobalt/media/base/playback_statistics.cc
+++ b/src/cobalt/media/base/playback_statistics.cc
@@ -14,7 +14,6 @@
#include "cobalt/media/base/playback_statistics.h"
-#include "base/strings/stringprintf.h"
#include "starboard/atomic.h"
#include "starboard/common/string.h"
@@ -74,56 +73,11 @@
}
}
-} // namespace
+std::string ToString(const base::Optional<base::TimeDelta>& t) {
+ return (t) ? starboard::FormatString("%" PRId64, t->InMicroseconds()) : "n/a";
+}
-PlaybackStatistics::PlaybackStatistics(const std::string& pipeline_identifier)
- : seek_time_(base::StringPrintf("Media.Pipeline.%s.SeekTime",
- pipeline_identifier.c_str()),
- base::TimeDelta(), "The seek-to time of the media pipeline."),
- first_written_audio_timestamp_(
- base::StringPrintf("Media.Pipeline.%s.FirstWrittenAudioTimestamp",
- pipeline_identifier.c_str()),
- base::TimeDelta(),
- "The timestamp of the first written audio buffer in the media "
- "pipeline."),
- first_written_video_timestamp_(
- base::StringPrintf("Media.Pipeline.%s.FirstWrittenVideoTimestamp",
- pipeline_identifier.c_str()),
- base::TimeDelta(),
- "The timestamp of the first written audio buffer in the media "
- "pipeline."),
- last_written_audio_timestamp_(
- base::StringPrintf("Media.Pipeline.%s.LastWrittenAudioTimestamp",
- pipeline_identifier.c_str()),
- base::TimeDelta(),
- "The timestamp of the last written audio buffer in the media "
- "pipeline."),
- last_written_video_timestamp_(
- base::StringPrintf("Media.Pipeline.%s.LastWrittenVideoTimestamp",
- pipeline_identifier.c_str()),
- base::TimeDelta(),
- "The timestamp of the last written video buffer in the media "
- "pipeline."),
- video_width_(base::StringPrintf("Media.Pipeline.%s.VideoWidth",
- pipeline_identifier.c_str()),
- 0, "The frame width of the video."),
- video_height_(base::StringPrintf("Media.Pipeline.%s.VideoHeight",
- pipeline_identifier.c_str()),
- 0, "The frame height of the video."),
- is_audio_eos_written_(
- base::StringPrintf("Media.Pipeline.%s.IsAudioEOSWritten",
- pipeline_identifier.c_str()),
- false, "Indicator of if the audio eos is written."),
- is_video_eos_written_(
- base::StringPrintf("Media.Pipeline.%s.IsVideoEOSWritten",
- pipeline_identifier.c_str()),
- false, "Indicator of if the video eos is written."),
- pipeline_status_(base::StringPrintf("Media.Pipeline.%s.PipelineStatus",
- pipeline_identifier.c_str()),
- PIPELINE_OK, "The status of the media pipeline."),
- error_message_(base::StringPrintf("Media.Pipeline.%s.ErrorMessage",
- pipeline_identifier.c_str()),
- "", "The error message of the media pipeline error.") {}
+} // namespace
PlaybackStatistics::~PlaybackStatistics() {
SbAtomicNoBarrier_Increment(&s_active_instances, -1);
@@ -151,11 +105,10 @@
}
}
- video_width_ = video_config.natural_size().width();
- video_height_ = video_config.natural_size().height();
-
- const auto width = static_cast<SbAtomic32>(video_width_);
- const auto height = static_cast<SbAtomic32>(video_height_);
+ const auto width =
+ static_cast<SbAtomic32>(video_config.natural_size().width());
+ const auto height =
+ static_cast<SbAtomic32>(video_config.natural_size().height());
UpdateMinValue(width, &s_min_video_width);
UpdateMaxValue(width, &s_max_video_width);
@@ -173,38 +126,22 @@
void PlaybackStatistics::OnSeek(const base::TimeDelta& seek_time) {
seek_time_ = seek_time;
- is_first_audio_buffer_written_ = false;
- is_first_video_buffer_written_ = false;
+ first_written_audio_timestamp_.reset();
+ first_written_video_timestamp_.reset();
}
-void PlaybackStatistics::OnAudioAU(const scoped_refptr<DecoderBuffer>& buffer) {
- if (buffer->end_of_stream()) {
- is_audio_eos_written_ = true;
- return;
- }
- last_written_audio_timestamp_ = buffer->timestamp();
- if (!is_first_audio_buffer_written_) {
- is_first_audio_buffer_written_ = true;
- first_written_audio_timestamp_ = buffer->timestamp();
+void PlaybackStatistics::OnAudioAU(const base::TimeDelta& timestamp) {
+ last_written_audio_timestamp_ = timestamp;
+ if (!first_written_audio_timestamp_) {
+ first_written_audio_timestamp_.emplace(timestamp);
}
}
-void PlaybackStatistics::OnVideoAU(const scoped_refptr<DecoderBuffer>& buffer) {
- if (buffer->end_of_stream()) {
- is_video_eos_written_ = true;
- return;
+void PlaybackStatistics::OnVideoAU(const base::TimeDelta& timestamp) {
+ last_written_video_timestamp_ = timestamp;
+ if (!first_written_video_timestamp_) {
+ first_written_video_timestamp_.emplace(timestamp);
}
- last_written_video_timestamp_ = buffer->timestamp();
- if (!is_first_video_buffer_written_) {
- is_first_video_buffer_written_ = true;
- first_written_video_timestamp_ = buffer->timestamp();
- }
-}
-
-void PlaybackStatistics::OnError(PipelineStatus status,
- const std::string& error_message) {
- pipeline_status_ = status;
- error_message_ = error_message;
}
std::string PlaybackStatistics::GetStatistics(
@@ -214,14 +151,18 @@
" active_players (max): %d (%d), av1: ~%d, h264: ~%d, hevc: ~%d,"
" vp9: ~%d, min_width: %d, min_height: %d, max_width: %d, max_height: %d,"
" last_working_codec: %s,"
- " seek_time: %s,"
+ " seek_time: %" PRId64
+ ","
" first_audio_time: %s,"
" first_video_time: %s,"
- " last_audio_time: %s,"
- " last_video_time: %s",
+ " last_audio_time: %" PRId64
+ ","
+ " last_video_time: %" PRId64,
GetCodecName(current_video_config.codec()).c_str(),
- (current_video_config.is_encrypted() ? "Y" : "N"), video_width_.value(),
- video_height_.value(), SbAtomicNoBarrier_Load(&s_active_instances),
+ (current_video_config.is_encrypted() ? "Y" : "N"),
+ static_cast<int>(current_video_config.natural_size().width()),
+ static_cast<int>(current_video_config.natural_size().height()),
+ SbAtomicNoBarrier_Load(&s_active_instances),
SbAtomicNoBarrier_Load(&s_max_active_instances),
RoundValues(SbAtomicNoBarrier_Load(&s_av1_played)),
RoundValues(SbAtomicNoBarrier_Load(&s_h264_played)),
@@ -234,19 +175,11 @@
GetCodecName(static_cast<VideoCodec>(
SbAtomicNoBarrier_Load(&s_last_working_codec)))
.c_str(),
- ValToString(seek_time_).c_str(),
- is_first_audio_buffer_written_
- ? ValToString(last_written_audio_timestamp_).c_str()
- : "n/a",
- is_first_video_buffer_written_
- ? ValToString(first_written_audio_timestamp_).c_str()
- : "n/a",
- is_first_audio_buffer_written_
- ? ValToString(last_written_audio_timestamp_).c_str()
- : "n/a",
- is_first_video_buffer_written_
- ? ValToString(last_written_video_timestamp_).c_str()
- : "n/a");
+ seek_time_.InMicroseconds(),
+ ToString(first_written_audio_timestamp_).c_str(),
+ ToString(first_written_audio_timestamp_).c_str(),
+ last_written_audio_timestamp_.InMicroseconds(),
+ last_written_video_timestamp_.InMicroseconds());
}
} // namespace media
diff --git a/src/cobalt/media/base/playback_statistics.h b/src/cobalt/media/base/playback_statistics.h
index 78808b3..9cbb562 100644
--- a/src/cobalt/media/base/playback_statistics.h
+++ b/src/cobalt/media/base/playback_statistics.h
@@ -19,9 +19,6 @@
#include "base/optional.h"
#include "base/time/time.h"
-#include "cobalt/base/c_val.h"
-#include "cobalt/media/base/decoder_buffer.h"
-#include "cobalt/media/base/pipeline_status.h"
#include "cobalt/media/base/video_decoder_config.h"
namespace cobalt {
@@ -29,34 +26,24 @@
class PlaybackStatistics {
public:
- explicit PlaybackStatistics(const std::string& pipeline_identifier);
~PlaybackStatistics();
void UpdateVideoConfig(const VideoDecoderConfig& video_config);
void OnPresenting(const VideoDecoderConfig& video_config);
void OnSeek(const base::TimeDelta& seek_time);
- void OnAudioAU(const scoped_refptr<DecoderBuffer>& buffer);
- void OnVideoAU(const scoped_refptr<DecoderBuffer>& buffer);
- void OnError(PipelineStatus status, const std::string& error_message);
+ void OnAudioAU(const base::TimeDelta& timestamp);
+ void OnVideoAU(const base::TimeDelta& timestamp);
std::string GetStatistics(
const VideoDecoderConfig& current_video_config) const;
private:
- base::CVal<base::TimeDelta> seek_time_;
- base::CVal<base::TimeDelta> first_written_audio_timestamp_;
- base::CVal<base::TimeDelta> first_written_video_timestamp_;
- base::CVal<base::TimeDelta> last_written_audio_timestamp_;
- base::CVal<base::TimeDelta> last_written_video_timestamp_;
- base::CVal<int> video_width_;
- base::CVal<int> video_height_;
- base::CVal<bool> is_audio_eos_written_;
- base::CVal<bool> is_video_eos_written_;
- base::CVal<PipelineStatus> pipeline_status_;
- base::CVal<std::string> error_message_;
+ base::TimeDelta seek_time_;
+ base::Optional<base::TimeDelta> first_written_audio_timestamp_;
+ base::Optional<base::TimeDelta> first_written_video_timestamp_;
+ base::TimeDelta last_written_audio_timestamp_;
+ base::TimeDelta last_written_video_timestamp_;
bool is_initial_config_ = true;
- bool is_first_audio_buffer_written_ = false;
- bool is_first_video_buffer_written_ = false;
};
} // namespace media
diff --git a/src/cobalt/media/base/sbplayer_pipeline.cc b/src/cobalt/media/base/sbplayer_pipeline.cc
index aefa84b..2429ac4 100644
--- a/src/cobalt/media/base/sbplayer_pipeline.cc
+++ b/src/cobalt/media/base/sbplayer_pipeline.cc
@@ -21,13 +21,11 @@
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/optional.h"
-#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/task_runner.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
-#include "cobalt/base/c_val.h"
#include "cobalt/math/size.h"
#include "cobalt/media/base/audio_decoder_config.h"
#include "cobalt/media/base/bind_to_current_loop.h"
@@ -191,10 +189,6 @@
// Retrieve the statistics as a string and append to message.
std::string AppendStatisticsString(const std::string& message) const;
- // An identifier string for the pipeline, used in CVal to identify multiple
- // pipelines.
- const std::string pipeline_identifier_;
-
// Message loop used to execute pipeline tasks. It is thread-safe.
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
@@ -225,12 +219,12 @@
// Current volume level (from 0.0f to 1.0f). This value is set immediately
// via SetVolume() and a task is dispatched on the message loop to notify the
// filters.
- base::CVal<float> volume_;
+ float volume_ = 1.f;
// Current playback rate (>= 0.0f). This value is set immediately via
// SetPlaybackRate() and a task is dispatched on the message loop to notify
// the filters.
- base::CVal<float> playback_rate_;
+ float playback_rate_ = 0.f;
// The saved audio and video demuxer streams. Note that it is safe to store
// raw pointers of the demuxer streams, as the Demuxer guarantees that its
@@ -265,7 +259,7 @@
bool audio_read_in_progress_ = false;
bool audio_read_delayed_ = false;
bool video_read_in_progress_ = false;
- base::CVal<TimeDelta> duration_;
+ TimeDelta duration_;
#if SB_HAS(PLAYER_WITH_URL)
TimeDelta start_date_;
@@ -282,14 +276,12 @@
// Temporary callback used for Start() and Seek().
SeekCB seek_cb_;
- TimeDelta seek_time_;
+ base::TimeDelta seek_time_;
std::unique_ptr<StarboardPlayer> player_;
bool is_initial_preroll_ = true;
- base::CVal<bool> started_;
- base::CVal<bool> suspended_;
- base::CVal<bool> stopped_;
- base::CVal<bool> ended_;
- base::CVal<SbPlayerState> player_state_;
+ bool suspended_ = false;
+ bool stopped_ = false;
+ bool ended_ = false;
VideoFrameProvider* video_frame_provider_;
@@ -307,11 +299,11 @@
// Timestamp for the last written audio.
SbTime timestamp_of_last_written_audio_ = 0;
// Last media time reported by GetMediaTime().
- base::CVal<SbTime> last_media_time_;
+ SbTime last_media_time_ = 0;
// Time when we last checked the media time.
SbTime last_time_media_time_retrieved_ = 0;
// The maximum video playback capabilities required for the playback.
- base::CVal<std::string> max_video_capabilities_;
+ std::string max_video_capabilities_;
PlaybackStatistics playback_statistics_;
@@ -325,51 +317,14 @@
get_decode_target_graphics_context_provider_func,
bool allow_resume_after_suspend, MediaLog* media_log,
VideoFrameProvider* video_frame_provider)
- : pipeline_identifier_(base::StringPrintf("%p", this)),
- task_runner_(task_runner),
+ : task_runner_(task_runner),
allow_resume_after_suspend_(allow_resume_after_suspend),
window_(window),
get_decode_target_graphics_context_provider_func_(
get_decode_target_graphics_context_provider_func),
natural_size_(0, 0),
- volume_(base::StringPrintf("Media.Pipeline.%s.Volume",
- pipeline_identifier_.c_str()),
- 1.0f, "Volume of the media pipeline."),
- playback_rate_(base::StringPrintf("Media.Pipeline.%s.PlaybackRate",
- pipeline_identifier_.c_str()),
- 0.0f, "Playback rate of the media pipeline."),
- duration_(base::StringPrintf("Media.Pipeline.%s.Duration",
- pipeline_identifier_.c_str()),
- base::TimeDelta(), "Playback duration of the media pipeline."),
set_bounds_helper_(new SbPlayerSetBoundsHelper),
- started_(base::StringPrintf("Media.Pipeline.%s.Started",
- pipeline_identifier_.c_str()),
- false, "Whether the media pipeline has started."),
- suspended_(base::StringPrintf("Media.Pipeline.%s.Suspended",
- pipeline_identifier_.c_str()),
- false,
- "Whether the media pipeline has been suspended. The "
- "pipeline is usually suspended after the app enters "
- "background mode."),
- stopped_(base::StringPrintf("Media.Pipeline.%s.Stopped",
- pipeline_identifier_.c_str()),
- false, "Whether the media pipeline has stopped."),
- ended_(base::StringPrintf("Media.Pipeline.%s.Ended",
- pipeline_identifier_.c_str()),
- false, "Whether the media pipeline has ended."),
- player_state_(base::StringPrintf("Media.Pipeline.%s.PlayerState",
- pipeline_identifier_.c_str()),
- kSbPlayerStateInitialized,
- "The underlying SbPlayer state of the media pipeline."),
- video_frame_provider_(video_frame_provider),
- last_media_time_(base::StringPrintf("Media.Pipeline.%s.LastMediaTime",
- pipeline_identifier_.c_str()),
- 0, "Last media time reported by the underlying player."),
- max_video_capabilities_(
- base::StringPrintf("Media.Pipeline.%s.MaxVideoCapabilities",
- pipeline_identifier_.c_str()),
- "", "The max video capabilities required for the media pipeline."),
- playback_statistics_(pipeline_identifier_) {
+ video_frame_provider_(video_frame_provider) {
SbMediaSetAudioWriteDuration(kAudioLimit);
}
@@ -818,8 +773,6 @@
BindToCurrentLoop(base::Bind(
&SbPlayerPipeline::OnDemuxerInitialized, this)),
kEnableTextTracks);
-
- started_ = true;
}
void SbPlayerPipeline::SetVolumeTask(float volume) {
@@ -1160,13 +1113,15 @@
if (type == DemuxerStream::AUDIO) {
audio_read_in_progress_ = false;
- playback_statistics_.OnAudioAU(buffer);
if (!buffer->end_of_stream()) {
+ playback_statistics_.OnAudioAU(buffer->timestamp());
timestamp_of_last_written_audio_ = buffer->timestamp().ToSbTime();
}
} else {
video_read_in_progress_ = false;
- playback_statistics_.OnVideoAU(buffer);
+ if (!buffer->end_of_stream()) {
+ playback_statistics_.OnVideoAU(buffer->timestamp());
+ }
}
player_->WriteBuffer(type, buffer);
@@ -1210,7 +1165,7 @@
timestamp_of_last_written_audio_ - last_media_time_;
if (time_ahead_of_playback > (kAudioLimit + kMediaTimeCheckInterval)) {
SbTime delay_time = (time_ahead_of_playback - kAudioLimit) /
- std::max(playback_rate_.value(), 1.0f);
+ std::max(playback_rate_, 1.0f);
task_runner_->PostDelayedTask(
FROM_HERE, base::Bind(&SbPlayerPipeline::DelayedNeedData, this),
base::TimeDelta::FromMicroseconds(delay_time));
@@ -1241,7 +1196,6 @@
if (!player_) {
return;
}
- player_state_ = state;
switch (state) {
case kSbPlayerStateInitialized:
NOTREACHED();
@@ -1379,11 +1333,6 @@
void SbPlayerPipeline::CallErrorCB(PipelineStatus status,
const std::string& error_message) {
DCHECK_NE(status, PIPELINE_OK);
- // Only to record the first error.
- if (error_cb_.is_null()) {
- return;
- }
- playback_statistics_.OnError(status, error_message);
ResetAndRunIfNotNull(&error_cb_, status,
AppendStatisticsString(error_message));
}
diff --git a/src/cobalt/media_integration_tests/__init__.py b/src/cobalt/media_integration_tests/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/src/cobalt/media_integration_tests/__init__.py
+++ /dev/null
diff --git a/src/cobalt/media_integration_tests/_env.py b/src/cobalt/media_integration_tests/_env.py
deleted file mode 100644
index a9d83bf..0000000
--- a/src/cobalt/media_integration_tests/_env.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Ask the parent directory to load the project environment."""
-
-from imp import load_source
-from os import path
-import sys
-
-_ENV = path.abspath(path.join(path.dirname(__file__), path.pardir, '_env.py'))
-if not path.exists(_ENV):
- print '%s: Can\'t find repo root.\nMissing parent: %s' % (__file__, _ENV)
- sys.exit(1)
-load_source('', _ENV)
diff --git a/src/cobalt/media_integration_tests/endurance/__init__.py b/src/cobalt/media_integration_tests/endurance/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/src/cobalt/media_integration_tests/endurance/__init__.py
+++ /dev/null
diff --git a/src/cobalt/media_integration_tests/endurance/_env.py b/src/cobalt/media_integration_tests/endurance/_env.py
deleted file mode 100644
index a9d83bf..0000000
--- a/src/cobalt/media_integration_tests/endurance/_env.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Ask the parent directory to load the project environment."""
-
-from imp import load_source
-from os import path
-import sys
-
-_ENV = path.abspath(path.join(path.dirname(__file__), path.pardir, '_env.py'))
-if not path.exists(_ENV):
- print '%s: Can\'t find repo root.\nMissing parent: %s' % (__file__, _ENV)
- sys.exit(1)
-load_source('', _ENV)
diff --git a/src/cobalt/media_integration_tests/functionality/__init__.py b/src/cobalt/media_integration_tests/functionality/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/src/cobalt/media_integration_tests/functionality/__init__.py
+++ /dev/null
diff --git a/src/cobalt/media_integration_tests/functionality/_env.py b/src/cobalt/media_integration_tests/functionality/_env.py
deleted file mode 100644
index a9d83bf..0000000
--- a/src/cobalt/media_integration_tests/functionality/_env.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Ask the parent directory to load the project environment."""
-
-from imp import load_source
-from os import path
-import sys
-
-_ENV = path.abspath(path.join(path.dirname(__file__), path.pardir, '_env.py'))
-if not path.exists(_ENV):
- print '%s: Can\'t find repo root.\nMissing parent: %s' % (__file__, _ENV)
- sys.exit(1)
-load_source('', _ENV)
diff --git a/src/cobalt/media_integration_tests/functionality/suspend_resume.py b/src/cobalt/media_integration_tests/functionality/suspend_resume.py
deleted file mode 100644
index e51215b..0000000
--- a/src/cobalt/media_integration_tests/functionality/suspend_resume.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-""" Tests of suspend and resume during playing."""
-
-import time
-import unittest
-
-import _env # pylint: disable=unused-import
-from cobalt.media_integration_tests.test_app import Features
-from cobalt.media_integration_tests.test_case import TestCase
-
-
-class SuspendResumeTest(TestCase):
- """
- Test cases for suspend and resume.
- """
-
- def run_test_with_url(self, url):
- app = self.CreateCobaltApp(url)
- with app:
- # Wait until the playback starts.
- app.WaitUntilPlayerStart()
- app.WaitUntilAdsEnd()
- # Let the playback play for 2 seconds.
- app.WaitUntilMediaTimeReached(app.CurrentMediaTime() + 2)
- # Suspend the app and wait the app enters background.
- app.Suspend()
- app.WaitUntilReachState(
- lambda _app: not _app.ApplicationState().is_visible)
- # Wait for 1 second before resume.
- time.sleep(1)
- # Resume the app and let it play for a few time.
- app.Resume()
- app.WaitUntilPlayerStart()
- app.WaitUntilAdsEnd()
- # Let the playback play for 2 seconds.
- app.WaitUntilMediaTimeReached(app.CurrentMediaTime() + 2)
-
- @unittest.skipIf(not TestCase.IsFeatureSupported(Features.SUSPEND_AND_RESUME),
- 'Suspend and resume is not supported on this platform.')
- def test_playback_h264(self):
- self.run_test_with_url('https://www.youtube.com/tv#/watch?v=RACW52qnJMI')
-
- @unittest.skipIf(not TestCase.IsFeatureSupported(Features.SUSPEND_AND_RESUME),
- 'Suspend and resume is not supported on this platform.')
- def test_encrypted_playback(self):
- self.run_test_with_url('https://www.youtube.com/tv#/watch?v=Vx5lkGS4w30')
-
- @unittest.skipIf(not TestCase.IsFeatureSupported(Features.SUSPEND_AND_RESUME),
- 'Suspend and resume is not supported on this platform.')
- def test_live_stream(self):
- self.run_test_with_url('https://www.youtube.com/tv#/watch?v=KI1XlTQrsa0')
-
- # Test for vp9 playback if supported.
- @unittest.skipIf(not TestCase.IsFeatureSupported(Features.SUSPEND_AND_RESUME),
- 'Suspend and resume is not supported on this platform.')
- def test_playback_vp9(self):
- self.run_test_with_url('https://www.youtube.com/tv#/watch?v=1La4QzGeaaQ')
-
- # Test for av1 playback if supported.
- @unittest.skipIf(not TestCase.IsFeatureSupported(Features.SUSPEND_AND_RESUME),
- 'Suspend and resume is not supported on this platform.')
- def test_playback_av1(self):
- self.run_test_with_url('https://www.youtube.com/tv#/watch?v=iXvy8ZeCs5M')
-
- # Test for vertical playback
- @unittest.skipIf(not TestCase.IsFeatureSupported(Features.SUSPEND_AND_RESUME),
- 'Suspend and resume is not supported on this platform.')
- def test_vertical_playback(self):
- self.run_test_with_url('https://www.youtube.com/tv#/watch?v=jNQXAC9IVRw')
diff --git a/src/cobalt/media_integration_tests/media_integration_tests_runner.py b/src/cobalt/media_integration_tests/media_integration_tests_runner.py
deleted file mode 100644
index 7db2ab2..0000000
--- a/src/cobalt/media_integration_tests/media_integration_tests_runner.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""The media integration test runner.
-
-Usage:
- To run all tests of a specific type:
- "python media_integration_tests_runner.py
- -p android-arm64 -c devel -w noinstall -log-level info
- --type functionality"
- To run a specific test (suspend_resume):
- python media_integration_tests_runner.py
- -p android-arm64 -c devel -w noinstall -log-level info
- --type functionality --test_name suspend_resume"
-
-"""
-
-import argparse
-import importlib
-import logging
-import pkgutil
-import sys
-import unittest
-
-import _env # pylint: disable=unused-import
-from cobalt.media_integration_tests.test_app import Features
-from cobalt.media_integration_tests.test_case import SetLauncherParams, SetSupportedFeatures
-from starboard.tools import abstract_launcher
-from starboard.tools import command_line
-from starboard.tools import log_level
-
-# Location of test files.
-_TESTS_PATH = {
- 'functionality': 'cobalt.media_integration_tests.functionality',
- 'endurance': 'cobalt.media_integration_tests.endurance',
- 'performance': 'cobalt.media_integration_tests.performance'
-}
-
-
-def GetSupportedFeatures(launcher_params):
- launcher = abstract_launcher.LauncherFactory(
- launcher_params.platform,
- 'cobalt',
- launcher_params.config,
- device_id=launcher_params.device_id,
- target_params=None,
- output_file=None,
- out_directory=launcher_params.out_directory,
- loader_platform=launcher_params.loader_platform,
- loader_config=launcher_params.loader_config,
- loader_out_directory=launcher_params.loader_out_directory)
- return {
- Features.SUSPEND_AND_RESUME: launcher.SupportsSystemSuspendResume(),
- Features.SEND_KEYS: True,
- }
-
-
-def GetTestPackagePath(test_type):
- if _TESTS_PATH.has_key(test_type):
- return _TESTS_PATH[test_type]
- return None
-
-
-def GetAllTestNamesInPackage(package_path):
- test_names = []
- loader = pkgutil.get_loader(package_path)
- for sub_module in pkgutil.walk_packages([loader.filename]):
- _, sub_module_name, _ = sub_module
- # Filter '_env' and '__init__'.
- if sub_module_name[0] == '_':
- continue
- if not sub_module_name in test_names:
- test_names.append(sub_module_name)
- return test_names
-
-
-def LoadAllTests(package_path, all_test_names):
- test_suite = unittest.TestSuite()
- for test_name in all_test_names:
- module = importlib.import_module(package_path + '.' + test_name)
- test_suite.addTest(unittest.TestLoader().loadTestsFromModule(module))
- return test_suite
-
-
-def main():
- # TODO: Support filters.
- parser = argparse.ArgumentParser()
- parser.add_argument(
- '--type',
- required=True,
- type=str,
- help=('Type of the tests to run. It must be functionality, endurance or'
- ' performance.'))
- parser.add_argument(
- '--test_name',
- default=None,
- type=str,
- help=('Name of test to run. If not specified, it will run all tests in'
- 'the directory.'))
- args, _ = parser.parse_known_args()
-
- package_path = GetTestPackagePath(args.type)
- if package_path is None:
- logging.error('{%s} is not a valid test type.', args.type)
- return 2
-
- all_test_names = GetAllTestNamesInPackage(package_path)
- specified_test_name = args.test_name
- if specified_test_name is not None:
- if not specified_test_name in all_test_names:
- logging.error('{%s} is not a valid test name.', specified_test_name)
- return 2
- else:
- all_test_names = [specified_test_name]
-
- log_level.InitializeLogging(args)
- launcher_params = command_line.CreateLauncherParams()
- supported_features = GetSupportedFeatures(launcher_params)
-
- # Update global variables in test case.
- SetLauncherParams(launcher_params)
- SetSupportedFeatures(supported_features)
-
- unittest.installHandler()
-
- test_suite = LoadAllTests(package_path, all_test_names)
-
- return not unittest.TextTestRunner(
- verbosity=0, stream=sys.stdout).run(test_suite).wasSuccessful()
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/src/cobalt/media_integration_tests/performance/__init__.py b/src/cobalt/media_integration_tests/performance/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/src/cobalt/media_integration_tests/performance/__init__.py
+++ /dev/null
diff --git a/src/cobalt/media_integration_tests/performance/_env.py b/src/cobalt/media_integration_tests/performance/_env.py
deleted file mode 100644
index a9d83bf..0000000
--- a/src/cobalt/media_integration_tests/performance/_env.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Ask the parent directory to load the project environment."""
-
-from imp import load_source
-from os import path
-import sys
-
-_ENV = path.abspath(path.join(path.dirname(__file__), path.pardir, '_env.py'))
-if not path.exists(_ENV):
- print '%s: Can\'t find repo root.\nMissing parent: %s' % (__file__, _ENV)
- sys.exit(1)
-load_source('', _ENV)
diff --git a/src/cobalt/media_integration_tests/test_app.py b/src/cobalt/media_integration_tests/test_app.py
deleted file mode 100644
index d0f62dd..0000000
--- a/src/cobalt/media_integration_tests/test_app.py
+++ /dev/null
@@ -1,744 +0,0 @@
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""A module to support fundamental communications with Cobalt application."""
-
-import enum
-import json
-import logging
-import threading
-import time
-
-import _env # pylint: disable=unused-import
-from cobalt.tools.automated_testing import cobalt_runner
-from cobalt.tools.automated_testing import webdriver_utils
-
-webdriver_keys = webdriver_utils.import_selenium_module('webdriver.common.keys')
-
-PERIODIC_QUERIES_INTERVAL_SECONDS = 0.1
-THREAD_EXIT_TIMEOUT_SECONDS = 10
-WAIT_INTERVAL_SECONDS = 0.5
-WAIT_UNTIL_REACH_STATE_DEFAULT_TIMEOUT_SECONDS = 30
-WAIT_UNTIL_ADS_END_DEFAULT_TIMEOUT_SECONDS = 120
-WAIT_UNTIL_MEDIA_TIME_REACHED_DEFAULT_TIMEOUT_SECONDS = 30
-
-
-def GetValueFromQueryResult(query_result, key, default):
- if query_result is None:
- return default
-
- if not isinstance(query_result, dict):
- return default
-
- if not query_result.has_key(key):
- return default
-
- value = query_result[key]
- default_value_type = type(default)
- value_type = type(value)
-
- if value is None:
- return default
-
- if value_type == default_value_type:
- return value
-
- if value_type in (int, float) and default_value_type in (int, float):
- return value
-
- # CVal returns unicode, so we need to decode them before using.
- if default_value_type in (bool, int, float):
- if value_type in (str, unicode):
- try:
- # Try to parse numbers and booleans.
- parsed_value = json.loads(value)
- except ValueError:
- raise RuntimeError('Failed to parse query result.')
-
- return parsed_value
-
- elif default_value_type is str:
- if value_type == unicode:
- return value.encode('utf-8')
-
- raise NotImplementedError('Convertion from (%s) to (%s) is not suppoted.' %
- (value_type, default_value_type))
-
-
-class AdditionalKeys():
- """
- Set of special keys codes for media control, corresponding to cobalt
- webdriver AdditionalSpecialKey.
- """
- MEDIA_NEXT_TRACK = u'\uf000'
- MEDIA_PREV_TRACK = u'\uf001'
- MEDIA_STOP = u'\uf002'
- MEDIA_PLAYPAUSE = u'\uf003'
-
-
-class Features(enum.Enum):
- """Set of platform features."""
- SUSPEND_AND_RESUME = 1
- SEND_KEYS = 2
-
-
-class ApplicationState():
- """Set of platform features."""
-
- def __init__(self, query_result=None):
- if not query_result is None and not isinstance(query_result, dict):
- raise NotImplementedError
-
- self.is_visible = GetValueFromQueryResult(query_result, 'is_visible', False)
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- raise NotImplementedError
- return self.is_visible == other.is_visible
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- @staticmethod
- def QueryJsCode():
- return """
- return {
- is_visible: document.visibilityState === "visible",
- }
- """
-
-
-class ApplicationStateHandler():
- """The handler of applicatoin state."""
-
- def __init__(self, app):
- self.app = app
- self.state_change_handlers = []
- self.app_state = ApplicationState()
-
- self.app.RegisterPeriodicQuery('Application',
- ApplicationState.QueryJsCode(),
- self._ApplicatinStateQueryHandler)
-
- def AddAppStateChangeHandler(self, handler):
- self.state_change_handlers.append(handler)
-
- def RemoveAppStateChangeHandler(self, handler):
- self.state_change_handlers.remove(handler)
-
- def _NotifyHandlersOnStateChanged(self):
- for handler in self.state_change_handlers:
- handler(self, self.app, self.app_state)
-
- def _ApplicatinStateQueryHandler(self, app, query_name, query_result):
- del app, query_name # Unused here.
- # Note that the callback is invoked on a different thread.
- new_state = ApplicationState(query_result)
- if self.app_state != new_state:
- self.app_state = new_state
- self._NotifyHandlersOnStateChanged()
-
-
-class PipelinePlayerState(enum.IntEnum):
- """Set of pipeline states, equals to SbPlayerState."""
- INITIALIZED = 0 # kSbPlayerStateInitialized
- PREROLLING = 1 # kSbPlayerStatePrerolling
- PRESENTING = 2 # kSbPlayerStatePresenting
- ENDOFSTREAM = 3 # kSbPlayerStateEndOfStream
- DESTROYED = 4 # kSbPlayerStateDestroyed
-
-
-class PipelineState():
- """
- The states of SbPlayerPipeline. We update the states periodically via
- webdriver and logs. Note that the duration and timestamps are in
- milliseconds.
- """
-
- def __init__(self, query_result=None):
- # If there's no player existing, the query return unicode code "null".
- if (not query_result is None and not query_result == u'null' and
- not isinstance(query_result, dict)):
- raise NotImplementedError
-
- self.identifier = GetValueFromQueryResult(query_result, 'identifier', '')
- self.is_started = GetValueFromQueryResult(query_result, 'is_started', False)
- self.is_suspended = GetValueFromQueryResult(query_result, 'is_suspended',
- False)
- self.is_stopped = GetValueFromQueryResult(query_result, 'is_stopped', False)
- self.is_ended = GetValueFromQueryResult(query_result, 'is_ended', False)
- self.player_state = PipelinePlayerState(
- GetValueFromQueryResult(query_result, 'player_state', 0))
- self.volume = GetValueFromQueryResult(query_result, 'volume', 1.0)
- self.playback_rate = GetValueFromQueryResult(query_result, 'playback_rate',
- 1.0)
- self.duration = GetValueFromQueryResult(query_result, 'duration', 0)
- self.last_media_time = GetValueFromQueryResult(query_result,
- 'last_media_time', 0)
- self.max_video_capabilities = GetValueFromQueryResult(
- query_result, 'max_video_capabilities', '')
- self.seek_time = GetValueFromQueryResult(query_result, 'seek_time', 0)
- self.first_written_audio_timestamp = GetValueFromQueryResult(
- query_result, 'first_written_audio_timestamp', 0)
- self.first_written_video_timestamp = GetValueFromQueryResult(
- query_result, 'first_written_video_timestamp', 0)
- self.last_written_audio_timestamp = GetValueFromQueryResult(
- query_result, 'last_written_audio_timestamp', 0)
- self.last_written_video_timestamp = GetValueFromQueryResult(
- query_result, 'last_written_video_timestamp', 0)
- self.video_width = GetValueFromQueryResult(query_result, 'video_width', 0)
- self.video_height = GetValueFromQueryResult(query_result, 'video_height', 0)
- self.is_audio_eos_written = GetValueFromQueryResult(query_result,
- 'is_audio_eos_written',
- False)
- self.is_video_eos_written = GetValueFromQueryResult(query_result,
- 'is_video_eos_written',
- False)
- # If |pipeline_status| is not 0, it indicates there's an error
- # in the pipeline.
- self.pipeline_status = GetValueFromQueryResult(query_result,
- 'pipeline_status', 0)
- self.error_message = GetValueFromQueryResult(query_result, 'error_message',
- '')
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- raise NotImplementedError
- return (self.identifier == other.identifier and
- self.is_started == other.is_started and
- self.is_suspended == other.identifier and
- self.is_stopped == other.identifier and
- self.is_ended == other.is_ended and
- self.player_state == other.player_state and
- self.volume == other.volume and
- self.playback_rate == other.playback_rate and
- self.duration == other.duration and
- self.last_media_time == other.last_media_time and
- self.max_video_capabilities == other.max_video_capabilities and
- self.seek_time == other.seek_time and
- self.first_written_audio_timestamp
- == other.first_written_audio_timestamp and
- self.first_written_video_timestamp
- == other.first_written_video_timestamp and
- self.last_written_audio_timestamp
- == other.last_written_audio_timestamp and
- self.last_written_video_timestamp
- == other.last_written_video_timestamp and
- self.video_width == other.video_width and
- self.video_height == other.video_height and
- self.is_audio_eos_written == other.is_audio_eos_written and
- self.is_video_eos_written == other.is_video_eos_written and
- self.pipeline_status == other.pipeline_status and
- self.error_message == other.error_message)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- @staticmethod
- def QueryJsCode():
- return """
- const primary_pipeline_keys = h5vcc.cVal.keys().filter(key =>
- key.startsWith("Media.Pipeline.") &&
- key.endsWith("MaxVideoCapabilities") &&
- h5vcc.cVal.getValue(key).length === 0)
- if (primary_pipeline_keys.length == 0) {
- return "null"
- }
- const key_prefix = primary_pipeline_keys[0].slice(0, -".MaxVideoCapabilities".length)
- return {
- identifier: key_prefix.slice("Media.Pipeline.".length),
- is_started: h5vcc.cVal.getValue(key_prefix + '.Started'),
- is_suspended: h5vcc.cVal.getValue(key_prefix + '.Suspended'),
- is_stopped: h5vcc.cVal.getValue(key_prefix + '.Stopped'),
- is_ended: h5vcc.cVal.getValue(key_prefix + '.Ended'),
- player_state: h5vcc.cVal.getValue(key_prefix + '.PlayerState'),
- volume: h5vcc.cVal.getValue(key_prefix + '.Volume'),
- playback_rate: h5vcc.cVal.getValue(key_prefix + '.PlaybackRate'),
- duration: h5vcc.cVal.getValue(key_prefix + '.Duration'),
- last_media_time: h5vcc.cVal.getValue(key_prefix + '.LastMediaTime'),
- max_video_capabilities: h5vcc.cVal.getValue(key_prefix + '.MaxVideoCapabilities'),
- seek_time: h5vcc.cVal.getValue(key_prefix + '.SeekTime'),
- first_written_audio_timestamp:
- h5vcc.cVal.getValue(key_prefix + '.FirstWrittenAudioTimestamp'),
- first_written_video_timestamp:
- h5vcc.cVal.getValue(key_prefix + '.FirstWrittenVideoTimestamp'),
- last_written_audio_timestamp:
- h5vcc.cVal.getValue(key_prefix + '.LastWrittenAudioTimestamp'),
- last_written_video_timestamp:
- h5vcc.cVal.getValue(key_prefix + '.LastWrittenVideoTimestamp'),
- video_width: h5vcc.cVal.getValue(key_prefix + '.VideoWidth'),
- video_height: h5vcc.cVal.getValue(key_prefix + '.VideoHeight'),
- is_audio_eos_written: h5vcc.cVal.getValue(key_prefix + '.IsAudioEOSWritten'),
- is_video_eos_written: h5vcc.cVal.getValue(key_prefix + '.IsVideoEOSWritten'),
- pipeline_status: h5vcc.cVal.getValue(key_prefix + '.PipelineStatus'),
- error_message: h5vcc.cVal.getValue(key_prefix + '.ErrorMessage'),
- }
- """
-
- def IsPlaying(self):
- return (len(self.identifier) > 0 and self.is_started and
- not self.is_ended and not self.is_suspended and not self.is_stopped)
-
-
-class MediaSessionPlaybackState(enum.Enum):
- """Set of media session playback states."""
- NONE = 0
- PAUSED = 1
- PLAYING = 2
-
- # Aliases to convert string to the enum.
- none = 0
- paused = 1
- playing = 2
-
-
-class MediaSessionState():
- """
- The info we get from HTML MediaSession. We update the states periodically
- via webdriver.
- """
-
- def __init__(self, query_result=None):
- if not query_result is None and not isinstance(query_result, dict):
- raise NotImplementedError
-
- metadata = None
- if isinstance(query_result, dict) and query_result.has_key('metadata'):
- metadata = query_result['metadata']
-
- self.title = GetValueFromQueryResult(metadata, 'title', '')
- self.artist = GetValueFromQueryResult(metadata, 'artist', '')
- self.album = GetValueFromQueryResult(metadata, 'album', '')
- self.playback_state = MediaSessionPlaybackState[GetValueFromQueryResult(
- query_result, 'playbackState', 'none')]
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- raise NotImplementedError
- return (self.title == other.title and self.artist == other.artist and
- self.album == other.album and
- self.playback_state == other.playback_state)
-
- def __ne__(self, other):
- if self.__eq__(other):
- return False
- return True
-
- @staticmethod
- def QueryJsCode():
- return """
- return {
- metadata: navigator.mediaSession.metadata,
- playbackState: navigator.mediaSession.playbackState,
- }
- """
-
-
-class VideoElementState():
- """
- The info we get from HTML video element. We update the states periodically
- via webdriver.
- """
-
- def __init__(self, query_result=None):
- # If there's no player existing, the query return unicode code "null".
- if (not query_result is None and not query_result == u'null' and
- not isinstance(query_result, dict)):
- raise NotImplementedError
-
- self.has_player = isinstance(query_result, dict)
- self.current_time = GetValueFromQueryResult(query_result, 'current_time',
- 0.0)
- self.duration = GetValueFromQueryResult(query_result, 'duration', 0.0)
- self.paused = GetValueFromQueryResult(query_result, 'paused', False)
- self.playback_rate = GetValueFromQueryResult(query_result, 'playback_rate',
- 0.0)
- self.volume = GetValueFromQueryResult(query_result, 'volume', 0.0)
- self.dropped_video_frames = GetValueFromQueryResult(query_result,
- 'dropped_video_frames',
- 0)
- self.total_video_frames = GetValueFromQueryResult(query_result,
- 'total_video_frames', 0)
-
- def __eq__(self, other):
- if not isinstance(other, self.__class__):
- raise NotImplementedError
- return (self.has_player == other.has_player and
- self.current_time == other.current_time and
- self.duration == other.duration and self.paused == other.paused and
- self.playback_rate == other.playback_rate and
- self.volume == other.volume and
- self.dropped_video_frames == other.dropped_video_frames and
- self.total_video_frames == other.total_video_frames)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- @staticmethod
- def QueryJsCode():
- # Looking for a full screen video tag and return that as the primary player.
- return """
- const players = document.querySelectorAll("video");
- if (players && players.length > 0) {
- for (let i = 0; i < players.length; i++) {
- const player = players[i]
- const rect = player.getBoundingClientRect()
- if (rect.width === window.innerWidth ||
- rect.height === window.innerHeight) {
- const quality = player.getVideoPlaybackQuality();
- return {
- current_time: player.currentTime,
- duration: player.duration,
- paused: player.paused,
- playback_rate: player.playbackRate,
- volume: player.volume,
- dropped_video_frames: quality.droppedVideoFrames,
- total_video_frames: quality.totalVideoFrames,
- }
- }
- }
- }
- return "null"
- """
-
-
-class PlayerStateHandler():
- """The handler of player state."""
-
- def __init__(self, app):
- self.app = app
- self.state_change_handlers = []
- self.player_state = type('', (), {})()
- self.player_state.pipeline_state = PipelineState()
- self.player_state.media_session_state = MediaSessionState()
- self.player_state.video_element_state = VideoElementState()
-
- self.app.RegisterPeriodicQuery('MediaPipeline', PipelineState.QueryJsCode(),
- self._PipelineStateQueryHandler)
- self.app.RegisterPeriodicQuery('MediaSession',
- MediaSessionState.QueryJsCode(),
- self._MediaSessionStateQueryHandler)
- self.app.RegisterPeriodicQuery('VideoElement',
- VideoElementState.QueryJsCode(),
- self._VideoElementStateQueryHandler)
-
- def AddPlayerStateChangeHandler(self, handler):
- self.state_change_handlers.append(handler)
-
- def RemovePlayerStateChangeHandler(self, handler):
- self.state_change_handlers.remove(handler)
-
- def IsPlayerPlaying(self):
- return self.player_state.pipeline_state.IsPlaying()
-
- def _NotifyHandlersOnStateChanged(self):
- for handler in self.state_change_handlers:
- handler(self, self.player_state)
-
- def _PipelineStateQueryHandler(self, app, query_name, query_result):
- # Note that the callback is invoked on a different thread.
- del app, query_name # Unused here.
- new_state = PipelineState(query_result)
- if self.player_state.pipeline_state != new_state:
- self.player_state.pipeline_state = new_state
- self._NotifyHandlersOnStateChanged()
-
- def _MediaSessionStateQueryHandler(self, app, query_name, query_result):
- # Note that the callback is invoked on a different thread.
- del app, query_name # Unused here.
- new_state = MediaSessionState(query_result)
- if self.player_state.media_session_state != new_state:
- self.player_state.media_session_state = new_state
- self._NotifyHandlersOnStateChanged()
-
- def _VideoElementStateQueryHandler(self, app, query_name, query_result):
- # Note that the callback is invoked on a different thread.
- del app, query_name # Unused here.
- new_state = VideoElementState(query_result)
- if self.player_state.video_element_state != new_state:
- self.player_state.video_element_state = new_state
- self._NotifyHandlersOnStateChanged()
-
-
-class AdsState(enum.IntEnum):
- """Set of ads states. The numeric values are used in ads state query."""
- NONE = 0
- PLAYING = 1
- PLAYING_AND_SKIPPABLE = 2
-
-
-class TestApp():
- """
- A class encapsulating fundamental functions to control and query data
- from Cobalt application.
- """
-
- def __init__(self,
- launcher_params,
- url,
- supported_features,
- log_file=None,
- target_params=None,
- success_message=None):
- self.supported_features = supported_features
- self.runner = cobalt_runner.CobaltRunner(
- launcher_params=launcher_params,
- url=url,
- log_handler=self._OnNewLogLine,
- log_file=log_file,
- target_params=target_params,
- success_message=success_message)
- self.log_handlers = []
- self.is_queries_changed = False
- self.periodic_queries = {}
- self.periodic_queries_lock = threading.Lock()
- self.should_exit = threading.Event()
- self.periodic_query_thread = threading.Thread(
- target=self._RunPeriodicQueries)
-
- self.app_state_handler = ApplicationStateHandler(self)
- self.player_state_handler = PlayerStateHandler(self)
-
- def __enter__(self):
- try:
- self.runner.__enter__()
- except Exception:
- # Potentially from thread.interrupt_main(). No need to start
- # query thread.
- return self
-
- self.periodic_query_thread.start()
- return self
-
- def __exit__(self, *args):
- self.should_exit.set()
- self.periodic_query_thread.join(THREAD_EXIT_TIMEOUT_SECONDS)
- return self.runner.__exit__(*args)
-
- def _OnNewLogLine(self, line):
- # Note that the function is called on cobalt runner reader thread.
- # pass
- self._NotifyHandlersOnNewLogLine(line)
-
- def _NotifyHandlersOnNewLogLine(self, line):
- for handler in self.log_handlers:
- handler(self, line)
-
- def ApplicationState(self):
- return self.app_state_handler.app_state
-
- def PlayerState(self):
- return self.player_state_handler.player_state
-
- def CurrentMediaTime(self):
- # Convert timestamp from millisecond to second.
- return float(self.PlayerState().pipeline_state.last_media_time) / 1000000.0
-
- def Suspend(self):
- if not self.supported_features[Features.SUSPEND_AND_RESUME]:
- raise RuntimeError('Suspend is not supported.')
- if not self.runner.launcher_is_running:
- raise RuntimeError('Runner is not running.')
- self.runner.SendSystemSuspend()
-
- def Resume(self):
- if not self.supported_features[Features.SUSPEND_AND_RESUME]:
- raise RuntimeError('Resume is not supported.')
- if not self.runner.launcher_is_running:
- raise RuntimeError('Runner is not running.')
- self.runner.SendSystemResume()
-
- def SendKeys(self, keys):
- if not self.supported_features[Features.SEND_KEYS]:
- raise RuntimeError('SendKeys is not supported.')
- if not self.runner.launcher_is_running:
- raise RuntimeError('Runner is not running.')
- self.runner.SendKeys(keys)
-
- # The handler will receive parameters (TestApp, String).
- def AddLogHandler(self, handler):
- self.log_handlers.append(handler)
-
- def RemoveLogHandler(self, handler):
- self.log_handlers.remove(handler)
-
- # The handler will receive parameters (TestApp, ApplicationState).
- def AddAppStateChangeHandler(self, handler):
- self.app_state_handler.AddAppStateChangeHandler(handler)
-
- def RemoveAppStateChangeHandler(self, handler):
- self.app_state_handler.RemoveAppStateChangeHandler(handler)
-
- # The handler will receive parameters (TestApp, PlayerState).
- def AddPlayerStateChangeHandler(self, handler):
- self.player_state_handler.AddPlayerStateChangeHandler(handler)
-
- def RemovePlayerStateChangeHandler(self, handler):
- self.player_state_handler.RemoveAppStateChangeHandler(handler)
-
- # The handler will receive parameters (TestApp, String, Dictionary).
- def RegisterPeriodicQuery(self, query_name, query_js_code, result_handler):
- if not isinstance(query_name, str):
- raise RuntimeError('Query name must be a string.')
- if self.periodic_queries.get(query_name):
- raise RuntimeError('Duplicate query name is not allowed.')
- # TODO: Validate js code.
- with self.periodic_queries_lock:
- self.is_queries_changed = True
- self.periodic_queries[query_name] = (query_js_code, result_handler)
-
- def UnregisterPeriodicQuery(self, query_name):
- if not isinstance(query_name, str):
- raise RuntimeError('Query name must be a string.')
- with self.periodic_queries_lock:
- self.is_queries_changed = True
- self.periodic_queries.pop(query_name)
-
- def _RunPeriodicQueries(self):
- while True:
- if self.should_exit.is_set():
- break
- # Wait until webdriver client attached to Cobalt.
- if self.runner.test_script_started.is_set():
- with self.periodic_queries_lock:
- local_is_queries_changed = self.is_queries_changed
- local_periodic_queries = self.periodic_queries
- self.is_queries_changed = False
- # Skip if there's no registered query.
- if len(local_periodic_queries) == 0:
- continue
- # Generate javascript code and execute it.
- js_code = self._GeneratePeriodicQueryJsCode(local_is_queries_changed,
- local_periodic_queries)
- try:
- result = self.runner.webdriver.execute_script(js_code)
- except Exception as e:
- raise RuntimeError('Periodic queries failed with error (%s)' %
- (str(e)))
-
- for query_name in local_periodic_queries.keys():
- if not result.get(query_name):
- raise RuntimeError(
- 'There\'s something wrong in the queries result.')
- local_periodic_queries[query_name][1](self, query_name,
- result[query_name])
-
- time.sleep(PERIODIC_QUERIES_INTERVAL_SECONDS)
-
- _PERIODIC_QUERIES_JS_CODE = """
- var ret = {}
- for(var key in _media_integration_testing_queries) {
- ret[key] = _media_integration_testing_queries[key]()
- }
- return ret
- """
-
- def _GeneratePeriodicQueryJsCode(self, is_queries_changed, periodic_queries):
- js_code = ''
- # Update registered queries at host side.
- if is_queries_changed:
- js_code += '_media_integration_testing_queries = {'
- for query_name in periodic_queries:
- js_code += query_name + ': function() {'
- js_code += periodic_queries[query_name][0]
- js_code += '},'
- js_code += '}'
- # Run queries and collect results.
- js_code += self._PERIODIC_QUERIES_JS_CODE
- return js_code
-
- # The first input of |state_lambda| is an instance of TestApp.
- def WaitUntilReachState(self, state_lambda, timeout=WAIT_UNTIL_REACH_STATE_DEFAULT_TIMEOUT_SECONDS):
- start_time = time.time()
- while not state_lambda(self) and time.time() - start_time < timeout:
- time.sleep(WAIT_INTERVAL_SECONDS)
- execute_interval = time.time() - start_time
- if execute_interval > timeout:
- raise RuntimeError('WaitUntilReachState timed out after (%f) seconds.' %
- (execute_interval))
-
- def WaitUntilPlayerStart(self,
- timeout=WAIT_UNTIL_REACH_STATE_DEFAULT_TIMEOUT_SECONDS
- ):
- self.WaitUntilReachState(
- lambda _app: _app.player_state_handler.IsPlayerPlaying(), timeout)
-
- # TODO: Need to verify if it works without corp network.
- # TODO: Needs to recognize and skip survery.
- """
- The return values of the query, exact mapping of AdsState defined earlier
- in this file.
- """
- _GET_ADS_STATE_QUERY_JS_CODE = """
- if( document.getElementsByTagName("YTLR-AD-PREVIEW-RENDERER").length > 0 ) {
- return 1
- }
- else if( document.getElementsByTagName("YTLR-SKIP-BUTTON-RENDERER").length > 0 ) {
- return 2
- }
- return 0
- """
-
- def GetAdsState(self):
- if not self.runner.test_script_started.is_set():
- raise RuntimeError('Webdriver is not ready yet')
- try:
- result = self.runner.webdriver.execute_script(
- self._GET_ADS_STATE_QUERY_JS_CODE)
- except Exception as e:
- raise RuntimeError('Ads query failed with error (%s)' % (str(e)))
- return AdsState(result)
-
- def WaitUntilAdsEnd(self, timeout=WAIT_UNTIL_ADS_END_DEFAULT_TIMEOUT_SECONDS):
- start_time = time.time()
- # There may be multiple ads and we need to wait all of them finished.
- while time.time() - start_time < timeout:
- # Wait until the content starts, otherwise the ads state may not be right.
- self.WaitUntilReachState(lambda _app: _app.CurrentMediaTime() > 0,
- timeout)
- ads_state = self.GetAdsState()
- if ads_state == AdsState.NONE:
- break
- while ads_state != AdsState.NONE and time.time() - start_time < timeout:
- ads_state = self.GetAdsState()
- if ads_state == AdsState.PLAYING_AND_SKIPPABLE:
- self.SendKeys(webdriver_keys.Keys.ENTER)
- logging.info('Send enter key event to skip the ad.')
- time.sleep(WAIT_INTERVAL_SECONDS)
-
- execute_interval = time.time() - start_time
- if execute_interval > timeout:
- raise RuntimeError(
- 'WaitUntilReachState timed out after (%f) seconds, ads_state: (%d).' %
- (execute_interval, ads_state))
-
- def WaitUntilMediaTimeReached(
- self,
- media_time,
- timeout=WAIT_UNTIL_MEDIA_TIME_REACHED_DEFAULT_TIMEOUT_SECONDS):
- start_media_time = self.CurrentMediaTime()
- if start_media_time > media_time:
- return
-
- # Wait until playback starts, otherwise playback rate could be 0.
- self.WaitUntilReachState(
- lambda _app: _app.CurrentMediaTime() > start_media_time, timeout)
-
- playback_rate = self.PlayerState().pipeline_state.playback_rate
- if playback_rate == 0:
- raise NotImplementedError
-
- adjusted_timeout = (media_time -
- self.CurrentMediaTime()) / playback_rate + timeout
- self.WaitUntilReachState(lambda _app: _app.CurrentMediaTime() > media_time,
- adjusted_timeout)
diff --git a/src/cobalt/media_integration_tests/test_case.py b/src/cobalt/media_integration_tests/test_case.py
deleted file mode 100644
index 09e2ec2..0000000
--- a/src/cobalt/media_integration_tests/test_case.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2021 The Cobalt Authors. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""The module of base media integration test case."""
-
-import logging
-import unittest
-
-import _env # pylint: disable=unused-import
-from cobalt.media_integration_tests.test_app import TestApp
-
-# Global variables
-_launcher_params = None
-_supported_features = None
-
-
-def SetLauncherParams(launcher_params):
- global _launcher_params
- _launcher_params = launcher_params
-
-
-def SetSupportedFeatures(supported_features):
- global _supported_features
- _supported_features = supported_features
-
-
-class TestCase(unittest.TestCase):
- """The base class for media integration test cases."""
-
- def __init__(self, *args, **kwargs):
- super(TestCase, self).__init__(*args, **kwargs)
- self.launcher_params = _launcher_params
- self.supported_features = _supported_features
-
- def setUp(self):
- logging.info('Running %s', str(self.id()))
-
- def tearDown(self):
- logging.info('Done %s', str(self.id()))
-
- def CreateCobaltApp(self, url):
- app = TestApp(
- launcher_params=self.launcher_params,
- supported_features=self.supported_features,
- url=url)
- return app
-
- @staticmethod
- def IsFeatureSupported(feature):
- global _supported_features
- return _supported_features[feature]
diff --git a/src/cobalt/tools/automated_testing/cobalt_runner.py b/src/cobalt/tools/automated_testing/cobalt_runner.py
index 1c26ae3..d1c878b 100644
--- a/src/cobalt/tools/automated_testing/cobalt_runner.py
+++ b/src/cobalt/tools/automated_testing/cobalt_runner.py
@@ -85,8 +85,7 @@
url,
log_file=None,
target_params=None,
- success_message=None,
- log_handler=None):
+ success_message=None):
"""CobaltRunner constructor.
Args:
@@ -113,8 +112,6 @@
'webdriver')
self.launcher_params = launcher_params
- self.log_handler = log_handler
-
if log_file:
self.log_file = open(log_file)
logging.basicConfig(stream=self.log_file, level=logging.INFO)
@@ -155,14 +152,6 @@
"""Sends a system signal to put Cobalt into stopped state."""
self.launcher.SendStop()
- def SendSystemSuspend(self):
- """Ask the system to suspend Cobalt."""
- self.launcher.SendSystemSuspend()
-
- def SendSystemResume(self):
- """Ask the system to resume Cobalt."""
- self.launcher.SendSystemResume()
-
def SendDeepLink(self, link):
"""Sends a deep link to Cobalt."""
return self.launcher.SendDeepLink(link)
@@ -186,21 +175,17 @@
while True:
line = self.launcher_read_pipe.readline()
if line:
- if self.log_handler is not None:
- self.log_handler(line)
self.log_file.write(line)
# Calling flush() to ensure the logs are delivered timely.
self.log_file.flush()
else:
break
- if not self.windowdriver_created.set() and \
- RE_WINDOWDRIVER_CREATED.search(line):
+ if RE_WINDOWDRIVER_CREATED.search(line):
self.windowdriver_created.set()
continue
- if not self.webmodule_loaded.set() and \
- RE_WEBMODULE_LOADED.search(line):
+ if RE_WEBMODULE_LOADED.search(line):
self.webmodule_loaded.set()
continue
diff --git a/src/cobalt/updater/configurator.cc b/src/cobalt/updater/configurator.cc
index b14e2d1..b8df78b 100644
--- a/src/cobalt/updater/configurator.cc
+++ b/src/cobalt/updater/configurator.cc
@@ -207,8 +207,7 @@
std::vector<uint8_t> Configurator::GetRunActionKeyHash() const { return {}; }
std::string Configurator::GetAppGuid() const {
- // Omaha console app id for trunk
- return "{A9557415-DDCD-4948-8113-C643EFCF710C}";
+ return "{6D4E53F3-CC64-4CB8-B6BD-AB0B8F300E1C}";
}
std::unique_ptr<update_client::ProtocolHandlerFactory>
diff --git a/src/cobalt/version.h b/src/cobalt/version.h
index 85eae78..94b0f68 100644
--- a/src/cobalt/version.h
+++ b/src/cobalt/version.h
@@ -35,6 +35,6 @@
// release is cut.
//.
-#define COBALT_VERSION "22.master.0"
+#define COBALT_VERSION "22.lts.1"
#endif // COBALT_VERSION_H_
diff --git a/src/cobalt/webdriver/keyboard.cc b/src/cobalt/webdriver/keyboard.cc
index b65672a..285dc9e 100644
--- a/src/cobalt/webdriver/keyboard.cc
+++ b/src/cobalt/webdriver/keyboard.cc
@@ -162,28 +162,6 @@
dom::keycode::kLwin, // kSpecialKey_Meta
};
-// Besides of selenium defined special keys, we need additional special keys
-// for media control. The following utf-8 code could be provided as "keys"
-// sent to WebDriver, and should be mapped to the corresponding keyboard code.
-enum AdditionalSpecialKey {
- kFirstAdditionalSpecialKey = 0xF000,
- kSpecialKey_MediaNextTrack = kFirstAdditionalSpecialKey,
- kSpecialKey_MediaPrevTrack,
- kSpecialKey_MediaStop,
- kSpecialKey_MediaPlayPause,
- kLastAdditionalSpecialKey = kSpecialKey_MediaPlayPause,
-};
-
-// Mapping from an additional special keycode to virtual keycode. Subtract
-// kFirstAdditionalSpecialKey from the integer value of the WebDriver keycode
-// and index into this table.
-const int32 additional_special_keycode_mapping[] = {
- dom::keycode::kMediaNextTrack, // kSpecialKey_MediaNextTrack,
- dom::keycode::kMediaPrevTrack, // kSpecialKey_MediaPrevTrack,
- dom::keycode::kMediaStop, // kSpecialKey_MediaStop,
- dom::keycode::kMediaPlayPause, // kSpecialKey_MediaPlayPause,
-};
-
// Check that the mapping is the expected size.
const int kLargestMappingIndex = kLastSpecialKey - kFirstSpecialKey;
COMPILE_ASSERT(arraysize(special_keycode_mapping) == kLargestMappingIndex + 1,
@@ -271,11 +249,6 @@
return webdriver_key >= kFirstSpecialKey && webdriver_key < kLastSpecialKey;
}
-bool IsAdditionalSpecialKey(int webdriver_key) {
- return webdriver_key >= kFirstAdditionalSpecialKey &&
- webdriver_key <= kLastAdditionalSpecialKey;
-}
-
bool IsModifierKey(int webdriver_key) {
return webdriver_key == kSpecialKey_Alt ||
webdriver_key == kSpecialKey_Shift ||
@@ -321,15 +294,6 @@
return KeyboardEvent::kDomKeyLocationStandard;
}
-// Returns the keycode that corresponds to this additional special key.
-int32 GetAdditionalSpecialKeycode(int32 webdriver_key) {
- DCHECK(IsAdditionalSpecialKey(webdriver_key));
- int index = webdriver_key - kFirstAdditionalSpecialKey;
- DCHECK_GE(index, 0);
- DCHECK_LT(index, arraysize(additional_special_keycode_mapping));
- return additional_special_keycode_mapping[index];
-}
-
class KeyTranslator {
public:
explicit KeyTranslator(Keyboard::KeyboardEventVector* event_vector)
@@ -363,14 +327,6 @@
KeyLocationCode location = GetSpecialKeyLocation(webdriver_key);
AddKeyDownEvent(key_code, char_code, location);
AddKeyUpEvent(key_code, char_code, location);
- } else if (IsAdditionalSpecialKey(webdriver_key)) {
- // Else if it's an additional special key, translate to key_code and
- // send key events.
- int32 key_code = GetAdditionalSpecialKeycode(webdriver_key);
- int32 char_code = 0;
- KeyLocationCode location = KeyboardEvent::kDomKeyLocationStandard;
- AddKeyDownEvent(key_code, char_code, location);
- AddKeyUpEvent(key_code, char_code, location);
} else {
DCHECK_GE(webdriver_key, 0);
DCHECK_LT(webdriver_key, std::numeric_limits<char>::max());
diff --git a/src/cobalt/webdriver/window_driver.cc b/src/cobalt/webdriver/window_driver.cc
index 6a33518..1cb4432 100644
--- a/src/cobalt/webdriver/window_driver.cc
+++ b/src/cobalt/webdriver/window_driver.cc
@@ -479,6 +479,9 @@
script_executor_ = base::AsWeakPtr(script_executor.get());
}
+ DLOG(INFO) << "Executing: " << script.function_body();
+ DLOG(INFO) << "Arguments: " << script.argument_array();
+
auto gc_prevented_params =
ScriptExecutorParams::Create(global_environment, script.function_body(),
script.argument_array(), async_timeout);
diff --git a/src/cobalt/websocket/web_socket_impl.cc b/src/cobalt/websocket/web_socket_impl.cc
index 39b54d2..e577c68 100644
--- a/src/cobalt/websocket/web_socket_impl.cc
+++ b/src/cobalt/websocket/web_socket_impl.cc
@@ -275,7 +275,6 @@
SendQueueMessage message = send_queue_.front();
size_t current_message_length = message.length - sent_size_of_top_message_;
bool final = false;
- bool continuation = sent_size_of_top_message_ > 0 ? true : false;
if (current_quota_ < static_cast<int64_t>(current_message_length)) {
// quota is not enough to send the top message.
scoped_refptr<net::IOBuffer> new_io_buffer(
@@ -295,10 +294,7 @@
current_quota_ -= current_message_length;
}
auto channel_state = websocket_channel_->SendFrame(
- final,
- continuation ? net::WebSocketFrameHeader::kOpCodeContinuation
- : message.op_code,
- message.io_buffer, current_message_length);
+ final, message.op_code, message.io_buffer, current_message_length);
if (channel_state == net::WebSocketChannel::CHANNEL_DELETED) {
websocket_channel_.reset();
}
diff --git a/src/cobalt/websocket/web_socket_impl_test.cc b/src/cobalt/websocket/web_socket_impl_test.cc
index 802ab70..8db8285 100644
--- a/src/cobalt/websocket/web_socket_impl_test.cc
+++ b/src/cobalt/websocket/web_socket_impl_test.cc
@@ -172,19 +172,12 @@
EXPECT_CALL(*mock_channel_,
MockSendFrame(false, net::WebSocketFrameHeader::kOpCodeText, _,
kDefaultSendQuotaHighWaterMark))
- .Times(1)
+ .Times(2)
.WillRepeatedly(Return(net::WebSocketChannel::CHANNEL_ALIVE));
EXPECT_CALL(
*mock_channel_,
- MockSendFrame(false, net::WebSocketFrameHeader::kOpCodeContinuation, _,
- kDefaultSendQuotaHighWaterMark))
- .Times(1)
- .WillRepeatedly(Return(net::WebSocketChannel::CHANNEL_ALIVE));
-
- EXPECT_CALL(*mock_channel_,
- MockSendFrame(
- true, net::WebSocketFrameHeader::kOpCodeContinuation, _, 1))
+ MockSendFrame(true, net::WebSocketFrameHeader::kOpCodeText, _, 1))
.Times(1)
.WillOnce(Return(net::WebSocketChannel::CHANNEL_ALIVE));
}
@@ -211,7 +204,7 @@
.WillOnce(Return(net::WebSocketChannel::CHANNEL_ALIVE));
EXPECT_CALL(
*mock_channel_,
- MockSendFrame(true, net::WebSocketFrameHeader::kOpCodeContinuation, _, 1))
+ MockSendFrame(true, net::WebSocketFrameHeader::kOpCodeBinary, _, 1))
.Times(1)
.WillOnce(Return(net::WebSocketChannel::CHANNEL_ALIVE));
EXPECT_CALL(*mock_channel_,
@@ -220,7 +213,7 @@
.Times(1)
.WillOnce(Return(net::WebSocketChannel::CHANNEL_ALIVE));
EXPECT_CALL(*mock_channel_,
- MockSendFrame(true, net::WebSocketFrameHeader::kOpCodeContinuation, _,
+ MockSendFrame(true, net::WebSocketFrameHeader::kOpCodeText, _,
kTooMuch - (k512KB - 1)))
.Times(1)
.WillOnce(Return(net::WebSocketChannel::CHANNEL_ALIVE));
diff --git a/src/docker-compose.yml b/src/docker-compose.yml
index 743a169..7cb3f94 100644
--- a/src/docker-compose.yml
+++ b/src/docker-compose.yml
@@ -167,19 +167,6 @@
USE_CCACHE: ${USE_CCACHE:-1}
NINJA_STATUS: ${NINJA_STATUS}
- linux-x64x11-sbversion12-evergreen:
- <<: *build-common-definitions
- build:
- context: ./docker/linux
- dockerfile: linux-x64x11/Dockerfile
- args:
- - FROM_IMAGE=cobalt-build-evergreen
- image: cobalt-build-linux-x64x11-evergreen
- environment:
- <<: *shared-build-env
- PLATFORM: linux-x64x11-sbversion-12
- CONFIG: ${CONFIG:-debug}
-
# Define common build container for Android
build-android:
<<: *build-common-definitions
diff --git a/src/docker/linux/raspi/Dockerfile b/src/docker/linux/raspi/Dockerfile
index e4f7f01..5483068 100644
--- a/src/docker/linux/raspi/Dockerfile
+++ b/src/docker/linux/raspi/Dockerfile
@@ -20,14 +20,10 @@
# Required by the gyp build system.
ENV RASPI_HOME=${raspi_home}
-# libxml2 and binutils* needed for evergreen
RUN apt update -qqy \
&& apt install -qqy --no-install-recommends \
g++-multilib \
bzip2 \
- libxml2 \
- binutils-aarch64-linux-gnu \
- binutils-arm-linux-gnueabi \
&& apt-get clean autoclean \
&& apt-get autoremove -y --purge \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
diff --git a/src/starboard/CHANGELOG.md b/src/starboard/CHANGELOG.md
index 450d514..51a66bd 100644
--- a/src/starboard/CHANGELOG.md
+++ b/src/starboard/CHANGELOG.md
@@ -117,6 +117,7 @@
* `SbStringFindString`
* `SbStringGetLength`
* `SbStringGetLengthWide`
+* `SbStringFindCharacter`
* `SbStringParseDouble`
* `SbStringParseSignedInteger`
* `SbStringParseUInt64`
diff --git a/src/starboard/android/shared/video_render_algorithm.cc b/src/starboard/android/shared/video_render_algorithm.cc
index 74ed628..1b9fcc4 100644
--- a/src/starboard/android/shared/video_render_algorithm.cc
+++ b/src/starboard/android/shared/video_render_algorithm.cc
@@ -73,23 +73,6 @@
video_decoder_->SetPlaybackRate(playback_rate);
}
- if (is_audio_eos_played) {
- // If the audio stream has reached end of stream before the video stream,
- // we should end the video stream immediately by only keeping one frame in
- // the backlog.
- bool popped = false;
- while (frames->size() > 1) {
- frames->pop_front();
- popped = true;
- }
- if (popped) {
- // Let the loop process the end of stream frame, if there is one.
- continue;
- } else {
- break;
- }
- }
-
jlong early_us = frames->front()->timestamp() - playback_time;
auto system_time_ns = GetSystemNanoTime();
diff --git a/src/starboard/android/x86/gyp_configuration.py b/src/starboard/android/x86/gyp_configuration.py
index 9af8e0c..2caad96 100644
--- a/src/starboard/android/x86/gyp_configuration.py
+++ b/src/starboard/android/x86/gyp_configuration.py
@@ -43,20 +43,13 @@
'SbMicrophoneOpenTest.*',
'SbMicrophoneReadTest.*',
'SbPlayerWriteSampleTests/SbPlayerWriteSampleTest.*',
+ 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest'
+ '.SunnyDaySourceForDestination/*',
'SbMediaSetAudioWriteDurationTests/SbMediaSetAudioWriteDurationTest'
'.WriteContinuedLimitedInput/*',
],
'player_filter_tests': [
- 'AudioDecoderTests/*',
'VideoDecoderTests/*',
-
- 'PlayerComponentsTests/PlayerComponentsTest.*/2',
- 'PlayerComponentsTests/PlayerComponentsTest.*/4',
- 'PlayerComponentsTests/PlayerComponentsTest.*/9',
- 'PlayerComponentsTests/PlayerComponentsTest.*/11',
- 'PlayerComponentsTests/PlayerComponentsTest.*/16',
- 'PlayerComponentsTests/PlayerComponentsTest.*/17',
- 'PlayerComponentsTests/PlayerComponentsTest.*/20',
- 'PlayerComponentsTests/PlayerComponentsTest.*/21',
+ 'AudioDecoderTests/*',
],
}
diff --git a/src/starboard/build/config/base_configuration.gni b/src/starboard/build/config/base_configuration.gni
index 8a80d04..3b798ea 100644
--- a/src/starboard/build/config/base_configuration.gni
+++ b/src/starboard/build/config/base_configuration.gni
@@ -21,7 +21,7 @@
# The Starboard API version of the current build configuration. The default
# value is meant to be overridden by a Starboard ABI file.
- sb_api_version = 14
+ sb_api_version = 13
# Enabling this variable enables pedantic levels of warnings for the current
# toolchain.
diff --git a/src/starboard/linux/shared/gyp_configuration.py b/src/starboard/linux/shared/gyp_configuration.py
index e8a7a9f..b8f0949 100644
--- a/src/starboard/linux/shared/gyp_configuration.py
+++ b/src/starboard/linux/shared/gyp_configuration.py
@@ -121,10 +121,3 @@
'VideoDecoderTests/VideoDecoderTest.*Invalid*',
],
}
- # Conditionally disables tests that require ipv6
- if os.getenv('IPV6_NOT_AVAILABLE', False):
- __FILTERED_TESTS['nplb'] = [
- 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDayDestination/1',
- 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceForDestination/1',
- 'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceNotLoopback/1',
- ]
diff --git a/src/starboard/raspi/shared/gyp_configuration.py b/src/starboard/raspi/shared/gyp_configuration.py
index 158f126..9644b4c 100644
--- a/src/starboard/raspi/shared/gyp_configuration.py
+++ b/src/starboard/raspi/shared/gyp_configuration.py
@@ -172,7 +172,36 @@
'VideoDecoderTests/VideoDecoderTest.EndOfStreamWithoutAnyInput/0',
'VideoDecoderTests/VideoDecoderTest.MultipleResets/0',
# Filter failed tests.
- 'PlayerComponentsTests/PlayerComponentsTest.*',
+ 'PlayerComponentsTests/PlayerComponentsTest.Preroll/0',
+ 'PlayerComponentsTests/PlayerComponentsTest.Preroll/1',
+ 'PlayerComponentsTests/PlayerComponentsTest.Preroll/2',
+ 'PlayerComponentsTests/PlayerComponentsTest.Preroll/3',
+ 'PlayerComponentsTests/PlayerComponentsTest.Sunnyday/0',
+ 'PlayerComponentsTests/PlayerComponentsTest.Sunnyday/1',
+ 'PlayerComponentsTests/PlayerComponentsTest.Sunnyday/2',
+ 'PlayerComponentsTests/PlayerComponentsTest.Sunnyday/3',
+ 'PlayerComponentsTests/PlayerComponentsTest.Pause/0',
+ 'PlayerComponentsTests/PlayerComponentsTest.Pause/1',
+ 'PlayerComponentsTests/PlayerComponentsTest.Pause/2',
+ 'PlayerComponentsTests/PlayerComponentsTest.Pause/3',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateHalf/0',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateHalf/1',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateHalf/2',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateHalf/3',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateDouble/0',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateDouble/1',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateDouble/2',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateDouble/3',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateDouble/4',
+ 'PlayerComponentsTests/PlayerComponentsTest.PlaybackRateDouble/5',
+ 'PlayerComponentsTests/PlayerComponentsTest.SeekForward/0',
+ 'PlayerComponentsTests/PlayerComponentsTest.SeekForward/1',
+ 'PlayerComponentsTests/PlayerComponentsTest.SeekForward/2',
+ 'PlayerComponentsTests/PlayerComponentsTest.SeekForward/3',
+ 'PlayerComponentsTests/PlayerComponentsTest.SeekBackward/0',
+ 'PlayerComponentsTests/PlayerComponentsTest.SeekBackward/1',
+ 'PlayerComponentsTests/PlayerComponentsTest.SeekBackward/2',
+ 'PlayerComponentsTests/PlayerComponentsTest.SeekBackward/3',
],
}