Import Cobalt 22.lts.3.306081
diff --git a/src/.codespellignorelines b/src/.codespellignorelines
new file mode 100644
index 0000000..4e787e0
--- /dev/null
+++ b/src/.codespellignorelines
@@ -0,0 +1 @@
+ vp9WhiteList.get("Technicolor").add("STING");
diff --git a/src/.pre-commit-config.yaml b/src/.pre-commit-config.yaml
index 7bc0f93..e78b053 100644
--- a/src/.pre-commit-config.yaml
+++ b/src/.pre-commit-config.yaml
@@ -21,6 +21,7 @@
hooks:
- id: codespell
name: Spell Check
+ args: [-x, .codespellignorelines]
- repo: local
hooks:
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 6900b8c..54b1b89 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -12,10 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# executable("hello_world") {
-# sources = ["hello_world.cc"]
-# }
-
group("gn_all") {
testonly = true
diff --git a/src/cobalt/black_box_tests/black_box_tests.py b/src/cobalt/black_box_tests/black_box_tests.py
index 271b2cc..9468917 100644
--- a/src/cobalt/black_box_tests/black_box_tests.py
+++ b/src/cobalt/black_box_tests/black_box_tests.py
@@ -153,7 +153,8 @@
proxy_port=None,
test_name=None,
wpt_http_port=None,
- device_ips=None):
+ device_ips=None,
+ device_id=None):
# Setup global variables used by test cases.
global _launcher_params
_launcher_params = command_line.CreateLauncherParams()
@@ -167,9 +168,17 @@
wpt_http_port = str(self.GetUnusedPort([server_binding_address]))
global _wpt_http_port
_wpt_http_port = wpt_http_port
+ # TODO: Remove generation of --dev_servers_listen_ip once executable will
+ # be able to bind correctly with incomplete support of IPv6
+ if device_id and IsValidIpAddress(device_id):
+ _launcher_params.target_params.append(
+ '--dev_servers_listen_ip={}'.format(device_id))
+ elif IsValidIpAddress(server_binding_address):
+ _launcher_params.target_params.append(
+ '--dev_servers_listen_ip={}'.format(server_binding_address))
_launcher_params.target_params.append(
- '--web-platform-test-server=http://web-platform.test:%s' %
- wpt_http_port)
+ '--web-platform-test-server=http://web-platform.test:{}'.format(
+ wpt_http_port))
# Port used to create the proxy server. If not specified, a random free
# port is used.
@@ -258,6 +267,29 @@
sock[1].close()
+def IsValidIpAddress(address):
+ """Checks if address is valid IP address."""
+ return IsValidIpv4Address(address) or IsValidIpv6Address(address)
+
+
+def IsValidIpv4Address(address):
+ """Checks if address is valid IPv4 address."""
+ try:
+ socket.inet_pton(socket.AF_INET, address)
+ return True
+ except socket.error: # not a valid address
+ return False
+
+
+def IsValidIpv6Address(address):
+ """Checks if address is valid IPv6 address."""
+ try:
+ socket.inet_pton(socket.AF_INET6, address)
+ return True
+ except socket.error: # not a valid address
+ return False
+
+
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbose', required=False, action='store_true')
@@ -289,10 +321,15 @@
'server. If not specified, a random free port is'
'used.'))
parser.add_argument(
+ '--device_id',
+ default=None,
+ help=('ID of test device to connect. If specified, it will be passed '
+ 'as --dev_servers_listen_ip param on the test device.'))
+ parser.add_argument(
'--device_ips',
default=None,
nargs='*',
- help=('IPs of test devices that will be allowed to connect. If not'
+ help=('IPs of test devices that will be allowed to connect. If not '
'specified, all IPs will be allowed to connect.'))
args, _ = parser.parse_known_args()
@@ -300,7 +337,8 @@
test_object = BlackBoxTests(args.server_binding_address, args.proxy_address,
args.proxy_port, args.test_name,
- args.wpt_http_port, args.device_ips)
+ args.wpt_http_port, args.device_ips,
+ args.device_id)
sys.exit(test_object.Run())
diff --git a/src/cobalt/browser/application.cc b/src/cobalt/browser/application.cc
index 05e4364..303a70b 100644
--- a/src/cobalt/browser/application.cc
+++ b/src/cobalt/browser/application.cc
@@ -839,7 +839,21 @@
#if SB_IS(EVERGREEN)
if (SbSystemGetExtension(kCobaltExtensionInstallationManagerName) &&
!command_line->HasSwitch(switches::kDisableUpdaterModule)) {
- updater_module_.reset(new updater::UpdaterModule(network_module_.get()));
+ uint64_t update_check_delay_sec =
+ cobalt::updater::kDefaultUpdateCheckDelaySeconds;
+ if (command_line->HasSwitch(browser::switches::kUpdateCheckDelaySeconds)) {
+ std::string seconds_value = command_line->GetSwitchValueASCII(
+ browser::switches::kUpdateCheckDelaySeconds);
+ if (!base::StringToUint64(seconds_value, &update_check_delay_sec)) {
+ LOG(WARNING) << "Invalid delay specified for the update check: "
+ << seconds_value << ". Using default value: "
+ << cobalt::updater::kDefaultUpdateCheckDelaySeconds;
+ update_check_delay_sec =
+ cobalt::updater::kDefaultUpdateCheckDelaySeconds;
+ }
+ }
+ updater_module_.reset(new updater::UpdaterModule(network_module_.get(),
+ update_check_delay_sec));
}
#endif
browser_module_.reset(new BrowserModule(
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index 44fc15e..ea42569 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -409,6 +409,15 @@
#endif // ENABLE_DEBUGGER
}
}
+
+ if (command_line->HasSwitch(switches::kDisableMediaEncryptionSchemes)) {
+ std::string encryption_schemes = command_line->GetSwitchValueASCII(
+ switches::kDisableMediaEncryptionSchemes);
+ if (!encryption_schemes.empty()) {
+ can_play_type_handler_->SetDisabledMediaEncryptionSchemes(
+ encryption_schemes);
+ }
+ }
#endif // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
if (application_state_ == base::kApplicationStateStarted ||
diff --git a/src/cobalt/browser/switches.cc b/src/cobalt/browser/switches.cc
index 4241402..01ff75d 100644
--- a/src/cobalt/browser/switches.cc
+++ b/src/cobalt/browser/switches.cc
@@ -71,6 +71,15 @@
"example, setting the value to \"avc;hvc\" will disable any h264 and h265 "
"playbacks.";
+const char kDisableMediaEncryptionSchemes[] =
+ "disable_media_encryption_schemes";
+const char kDisableMediaEncryptionSchemesHelp[] =
+ "Disables the semicolon-separated list of encryption schemes that will be "
+ "treated as unsupported for encrypted media playback. Used for debugging "
+ "and testing purposes. For example, setting the value to \"cenc;cbcs\" "
+ "will disable any cenc and cbcs DRM playbacks. Accepted values: \"cenc\", "
+ "\"cbcs\", \"cbcs-1-9\".";
+
const char kDisableRasterizerCaching[] = "disable_rasterizer_caching";
const char kDisableRasterizerCachingHelp[] =
"Disables caching of rasterized render tree nodes; caching improves "
@@ -410,6 +419,11 @@
"the URL used to launch Cobalt, then the value of "
"'fallback_splash_screen_url' will be used.";
+const char kUpdateCheckDelaySeconds[] = "update_check_delay_seconds";
+const char kUpdateCheckDelaySecondsHelp[] =
+ "Number of seconds to delay the first Cobalt Evergreen check for updates."
+ "The default value is 60 seconds.";
+
const char kVersion[] = "version";
const char kVersionHelp[] = "Prints the current version of Cobalt";
@@ -437,6 +451,7 @@
{kDisableImageAnimations, kDisableImageAnimationsHelp},
{kForceDeterministicRendering, kForceDeterministicRenderingHelp},
{kDisableMediaCodecs, kDisableMediaCodecsHelp},
+ {kDisableMediaEncryptionSchemes, kDisableMediaEncryptionSchemesHelp},
{kDisableRasterizerCaching, kDisableRasterizerCachingHelp},
{kDisableSignIn, kDisableSignInHelp},
{kDisableSplashScreenOnReloads, kDisableSplashScreenOnReloadsHelp},
@@ -493,6 +508,7 @@
{kSoftwareSurfaceCacheSizeInBytes,
kSoftwareSurfaceCacheSizeInBytesHelp},
{kFallbackSplashScreenURL, kFallbackSplashScreenURLHelp},
+ {kUpdateCheckDelaySeconds, kUpdateCheckDelaySecondsHelp},
{kVersion, kVersionHelp}, {kViewport, kViewportHelp},
{kVideoPlaybackRateMultiplier, kVideoPlaybackRateMultiplierHelp},
};
diff --git a/src/cobalt/browser/switches.h b/src/cobalt/browser/switches.h
index d07aa1e..fa7f6a4 100644
--- a/src/cobalt/browser/switches.h
+++ b/src/cobalt/browser/switches.h
@@ -41,6 +41,8 @@
extern const char kForceDeterministicRendering[];
extern const char kDisableMediaCodecs[];
extern const char kDisableMediaCodecsHelp[];
+extern const char kDisableMediaEncryptionSchemes[];
+extern const char kDisableMediaEncryptionSchemesHelp[];
extern const char kDisableRasterizerCaching[];
extern const char kDisableSignIn[];
extern const char kDisableSignInHelp[];
@@ -151,6 +153,8 @@
extern const char kFallbackSplashScreenURLHelp[];
extern const char kFallbackSplashScreenTopics[];
extern const char kFallbackSplashScreenTopicsHelp[];
+extern const char kUpdateCheckDelaySeconds[];
+extern const char kUpdateCheckDelaySecondsHelp[];
extern const char kVersion[];
extern const char kVersionHelp[];
extern const char kViewport[];
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index a003887..bd615ed 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-305573
\ No newline at end of file
+306081
\ No newline at end of file
diff --git a/src/cobalt/build/gyp_utils.py b/src/cobalt/build/gyp_utils.py
index fc61343..022cb74 100644
--- a/src/cobalt/build/gyp_utils.py
+++ b/src/cobalt/build/gyp_utils.py
@@ -34,13 +34,11 @@
def CheckRevInfo(key, cwd=None):
- cwd = cwd if cwd else '.'
- git_prefix = ['git', '-C', cwd]
- git_get_remote_args = git_prefix + ['config', '--get', 'remote.origin.url']
- remote = subprocess.check_output(git_get_remote_args).strip()
+ git_get_remote_args = ['git', 'config', '--get', 'remote.origin.url']
+ remote = subprocess.check_output(git_get_remote_args, cwd=cwd).strip()
- git_get_revision_args = git_prefix + ['rev-parse', 'HEAD']
- revision = subprocess.check_output(git_get_revision_args).strip()
+ git_get_revision_args = ['git', 'rev-parse', 'HEAD']
+ revision = subprocess.check_output(git_get_revision_args, cwd=cwd).strip()
return {key: '{}@{}'.format(remote, revision)}
@@ -70,7 +68,11 @@
try:
repos.update(CheckRevInfo(rel_path, cwd=path))
except subprocess.CalledProcessError as e:
- logging.warning('Failed to get revision information for subrepo: %s', e)
+ logging.warning('Failed to get revision information for subrepo %s: %s',
+ rel_path, e)
+ continue
+ except OSError as e:
+ logging.info('%s. Subrepository %s not found.', e, rel_path)
continue
return repos
diff --git a/src/cobalt/doc/deep_links.md b/src/cobalt/doc/deep_links.md
new file mode 100644
index 0000000..69080ca
--- /dev/null
+++ b/src/cobalt/doc/deep_links.md
@@ -0,0 +1,135 @@
+# Cobalt Deep Links
+
+- [Cobalt Deep Links](#cobalt-deep-links)
+ - [Deep Links](#deep-links)
+ - [Web API](#web-api)
+ - [Platform (Starboard) API](#platform-starboard-api)
+ - [Behavior details](#behavior-details)
+## Deep Links
+
+For Cobalt, a deep link is a string that can be sent from the platform to an
+application running in Cobalt. Generally, it can be used as any string value
+signal, but typically deep links are used to specify a view, page, or content
+to be shown by the application. While these strings typically are URI formatted
+values, when deep link strings are received by Cobalt they are forwarded to the
+running application without separate validation or modification.
+
+Applications should interpret received deep links as superseding previous deep
+links. Deep links received by Cobalt in rapid succession are not guaranteed to
+all be delivered to the application. On a busy or slow device, intermediate
+deep links can be dropped before they are delivered to the application.
+
+The startup URL passed to Cobalt determines which application Cobalt will load.
+Web deep links intended as a signal to the application should not be sent to
+Cobalt as a startup URL because that would result in a different application
+being loaded. Since a deep link is a string that may originate from an
+untrusted source on the device, it should not be used directly to determine
+what application Cobalt will load.
+
+Deep links are made visible to applications by Cobalt with a Web API that is
+separate from the Location interface web API. Cobalt will never directly
+navigate as a result of a received deep link, even if the link matches the
+current application location, for example with a query or fragment identifier.
+Applications that wish to navigate as a result of incoming deep links should do
+so explicitly when they are received.
+
+## Web API
+
+The deep link Web API consists of two parts: The
+`h5vcc.runtime.initialDeepLink` property and `h5vcc.runtime.onDeepLink` event
+target.
+
+Applications can read the value of `initialDeepLink`, and/or they can use
+`h5vcc.runtime.onDeepLink.addListener(foo)` to register callback functions to
+be called when deep links are received.
+
+A deep link is considered 'consumed' when it is read from `initialDeepLink`, or
+when it is reported to a callback function registered to `onDeepLink`.
+
+The IDL for this Cobalt specific interface can be found in cobalt/h5vcc, and is
+repeated below.
+
+```
+interface H5vccRuntime {
+ readonly attribute DOMString initialDeepLink;
+ readonly attribute H5vccDeepLinkEventTarget onDeepLink;
+}
+interface H5vccDeepLinkEventTarget {
+ void addListener(H5vccDeepLinkEventCallback callback);
+};
+callback H5vccDeepLinkEventCallback = void(DOMString link);
+interface H5vcc {
+ readonly attribute H5vccRuntime runtime;
+}
+```
+
+## Platform (Starboard) API
+
+Deep links can be passed into Cobalt in two ways:
+ * As the 'Startup Link':
+ * When Cobalt is first started, a deep link can be passed in with the
+ initial event (either `kSbEventTypePreload` or `kSbEventTypeStart`). This
+ can be achieved by calling `Application::SetStartLink` or by using and
+ overload of `Application::Run` that has the 'link_data' parameter to start
+ Cobalt. The value passed in there is then passed into Cobalt via the
+ 'link' member of the SbEventStartData event parameter, constructed in
+ `Application::CreateInitialEvent`.
+ * As a 'Deep Link Event':
+ * At any time while Cobalt is running, it can be sent as the string value
+ passed with a kSbEventTypeLink event. The `Application::Link` method can
+ be called to inject such an event.
+
+On many platforms, the 'Startup Link' value can also be set with the `--link`
+command-line parameter (See `kLinkSwitch` in `Application::Run`).
+
+The `Application` class mentioned above can be found at
+`starboard/shared/starboard/application.cc`.
+
+## Behavior details
+
+Both the 'Startup Link' and 'Deep Link Event' values are treated the same by
+Cobalt: A 'Startup Link' is treated as a 'Deep Link Event' that was received
+immediately at startup. For the application, it is transparent whether a deep
+link was received as a 'Startup Link' or arrived from a 'Deep Link Event'. Deep
+link values of either type are made available as soon as they are known, with
+the same Web API interface.
+
+The most recently received deep link is remembered by Cobalt until it is
+consumed by the application. This includes deep links received by Cobalt while
+the application is still being fetched and loaded, including during page
+redirects or reloads, and after the application is loaded, if it has not
+consumed the deep link.
+
+Deep link values are considered consumed when the application either reads them
+from the `initialDeepLink` attribute or receives them in a callback to an
+`onDeepLink` listener. An application can use either or both reads of
+`initialDeepLink` or `onDeepLink` listeners to consume the most recently
+received deep link value.
+
+Calls to `onDeepLink` listeners are done as soon as deep links are available.
+Specifically, they can be called before `document.onreadystatechange`,
+`document.onload` & `window.onload` event handlers are called. As a result,
+deep link values can be consumed in synchronously loaded JavaScript that
+executes before the `document.onload` event.
+
+Until the first `onDeepLink` listener is added, the `initialDeepLink` property
+will return the most recently received deep link value. When an `onDeepLink`
+listener is added, the `initialDeepLink` value will no longer be updated, even
+when additional deep link events are received subsequently.
+
+An application can decide to never register an `onDeepLink` listener and poll
+the `initialDeepLink` value instead. This will then always return the value of
+the most recently received deep link.
+
+An application can decide to register an `onDeepLink` listener without reading
+the `initialDeepLink` value. Upon registering, the most recently received deep
+link, which may be the 'Startup Link' or from a 'Deep Link Event', will be
+reported to the listener.
+
+If a deep link value is consumed, it will not be made available again if the
+page is navigated (e.g. redirected or reloaded). When a deep link is consumed
+before a page redirect or reload, the deep link will not be repeated later.
+
+If a deep link value is not consumed, it will be made available again if the
+page is navigated (e.g. redirected or reloaded). A deep link will not be lost
+if a page redirect or reload is done without consuming it.
diff --git a/src/cobalt/h5vcc/h5vcc.gyp b/src/cobalt/h5vcc/h5vcc.gyp
index 6486986..ce59392 100644
--- a/src/cobalt/h5vcc/h5vcc.gyp
+++ b/src/cobalt/h5vcc/h5vcc.gyp
@@ -110,6 +110,9 @@
'h5vcc_updater.cc',
'h5vcc_updater.h',
],
+ 'dependencies': [
+ '<(DEPTH)/cobalt/updater/updater.gyp:updater',
+ ],
}],
],
},
diff --git a/src/cobalt/h5vcc/h5vcc_updater.cc b/src/cobalt/h5vcc/h5vcc_updater.cc
index c4d7bbf..97162bb 100644
--- a/src/cobalt/h5vcc/h5vcc_updater.cc
+++ b/src/cobalt/h5vcc/h5vcc_updater.cc
@@ -14,6 +14,10 @@
#include "cobalt/h5vcc/h5vcc_updater.h"
+#if SB_IS(EVERGREEN)
+#include "cobalt/updater/utils.h"
+#endif
+
namespace {
const uint16 kInvalidInstallationIndex = 1000;
@@ -23,6 +27,7 @@
namespace cobalt {
namespace h5vcc {
+#if SB_IS(EVERGREEN)
std::string H5vccUpdater::GetUpdaterChannel() const {
if (!updater_module_) {
return "";
@@ -66,5 +71,10 @@
return index == -1 ? kInvalidInstallationIndex : static_cast<uint16>(index);
}
+std::string H5vccUpdater::GetLibrarySha256(uint16 index) const {
+ return cobalt::updater::GetLibrarySha256(index);
+}
+
+#endif // SB_IS(EVERGREEN)
} // namespace h5vcc
} // namespace cobalt
diff --git a/src/cobalt/h5vcc/h5vcc_updater.h b/src/cobalt/h5vcc/h5vcc_updater.h
index 841b893..8b869ff 100644
--- a/src/cobalt/h5vcc/h5vcc_updater.h
+++ b/src/cobalt/h5vcc/h5vcc_updater.h
@@ -46,6 +46,8 @@
uint16 GetInstallationIndex() const;
+ std::string GetLibrarySha256(uint16 index) const;
+
#else
H5vccUpdater() {}
#endif
diff --git a/src/cobalt/h5vcc/h5vcc_updater.idl b/src/cobalt/h5vcc/h5vcc_updater.idl
index 4a81664..d71d603 100644
--- a/src/cobalt/h5vcc/h5vcc_updater.idl
+++ b/src/cobalt/h5vcc/h5vcc_updater.idl
@@ -24,4 +24,7 @@
void resetInstallations();
unsigned short getInstallationIndex();
+
+ DOMString getLibrarySha256(unsigned short index);
+
};
diff --git a/src/cobalt/media/base/sbplayer_pipeline.cc b/src/cobalt/media/base/sbplayer_pipeline.cc
index 3fa6b43..52e44a4 100644
--- a/src/cobalt/media/base/sbplayer_pipeline.cc
+++ b/src/cobalt/media/base/sbplayer_pipeline.cc
@@ -935,8 +935,8 @@
CallSeekCB(DECODER_ERROR_NOT_SUPPORTED,
"SbPlayerPipeline::CreateUrlPlayer failed to create a valid "
- "StarboardPlayer:" +
- (error_message.empty() ? "" : " Error: " + error_message));
+ "StarboardPlayer: \'" +
+ error_message + "\'");
}
void SbPlayerPipeline::SetDrmSystem(SbDrmSystem drm_system) {
@@ -1037,8 +1037,8 @@
CallSeekCB(DECODER_ERROR_NOT_SUPPORTED,
"SbPlayerPipeline::CreatePlayer failed to create a valid "
- "StarboardPlayer:" +
- (error_message.empty() ? "" : " Error: " + error_message));
+ "StarboardPlayer: \'" +
+ error_message + "\'");
}
void SbPlayerPipeline::OnDemuxerInitialized(PipelineStatus status) {
@@ -1441,15 +1441,18 @@
if (player_) {
player_->Resume(window);
if (!player_->IsValid()) {
+ std::string error_message;
{
base::AutoLock auto_lock(lock_);
+ error_message = player_->GetPlayerCreationErrorMessage();
player_.reset();
}
// TODO: Determine if CallSeekCB() may be used here, as |seek_cb_| may be
// available if the app is suspended before a seek is completed.
CallErrorCB(DECODER_ERROR_NOT_SUPPORTED,
- "SbPlayerPipeline::ResumeTask failed: "
- "player_->IsValid() is false.");
+ "SbPlayerPipeline::ResumeTask failed to create a valid "
+ "StarboardPlayer: \'" +
+ error_message + "\'");
return;
}
}
diff --git a/src/cobalt/media/can_play_type_handler.h b/src/cobalt/media/can_play_type_handler.h
index 00b94f1..5ed65d7 100644
--- a/src/cobalt/media/can_play_type_handler.h
+++ b/src/cobalt/media/can_play_type_handler.h
@@ -30,6 +30,8 @@
virtual SbMediaSupportType CanPlayAdaptive(
const std::string& mime_type, const std::string& key_system) const = 0;
virtual void SetDisabledMediaCodecs(const std::string& codecs) = 0;
+ virtual void SetDisabledMediaEncryptionSchemes(
+ const std::string& disabled_encryption_schemes) = 0;
protected:
CanPlayTypeHandler() {}
diff --git a/src/cobalt/media/decoder_buffer_allocator.cc b/src/cobalt/media/decoder_buffer_allocator.cc
index 7c83911..9515da1 100644
--- a/src/cobalt/media/decoder_buffer_allocator.cc
+++ b/src/cobalt/media/decoder_buffer_allocator.cc
@@ -37,10 +37,6 @@
// be different.
const std::size_t kSmallAllocationThreshold = 512;
-bool IsLargeAllocation(std::size_t size) {
- return size > kSmallAllocationThreshold;
-}
-
} // namespace
DecoderBufferAllocator::DecoderBufferAllocator()
@@ -65,8 +61,9 @@
// set yet. Use 0 (unbounded) until |video_codec_| is updated in
// UpdateVideoConfig().
int max_capacity = 0;
- reuse_allocator_.reset(new ReuseAllocator(
- &fallback_allocator_, initial_capacity_, allocation_unit_, max_capacity));
+ reuse_allocator_.reset(new nb::BidirectionalFitReuseAllocator(
+ &fallback_allocator_, initial_capacity_, kSmallAllocationThreshold,
+ allocation_unit_, max_capacity));
DLOG(INFO) << "Allocated " << initial_capacity_
<< " bytes for media buffer pool as its initial buffer, with max"
<< " capacity set to " << max_capacity;
@@ -109,9 +106,9 @@
max_capacity = SbMediaGetMaxBufferCapacity(
video_codec_, resolution_width_, resolution_height_, bits_per_pixel_);
}
- reuse_allocator_.reset(new ReuseAllocator(&fallback_allocator_,
- initial_capacity_,
- allocation_unit_, max_capacity));
+ reuse_allocator_.reset(new nb::BidirectionalFitReuseAllocator(
+ &fallback_allocator_, initial_capacity_, kSmallAllocationThreshold,
+ allocation_unit_, max_capacity));
DLOG(INFO) << "Allocated " << initial_capacity_
<< " bytes for media buffer pool, with max capacity set to "
<< max_capacity;
@@ -189,48 +186,6 @@
<< reuse_allocator_->GetCapacity();
}
-DecoderBufferAllocator::ReuseAllocator::ReuseAllocator(
- Allocator* fallback_allocator, std::size_t initial_capacity,
- std::size_t allocation_increment, std::size_t max_capacity)
- : BidirectionalFitReuseAllocator(fallback_allocator, initial_capacity,
- kSmallAllocationThreshold,
- allocation_increment, max_capacity) {}
-
-DecoderBufferAllocator::ReuseAllocator::FreeBlockSet::iterator
-DecoderBufferAllocator::ReuseAllocator::FindBestFreeBlock(
- std::size_t size, std::size_t alignment, intptr_t context,
- FreeBlockSet::iterator begin, FreeBlockSet::iterator end,
- bool* allocate_from_front) {
- DCHECK(allocate_from_front);
-
- auto free_block_iter =
- FindFreeBlock(size, alignment, begin, end, allocate_from_front);
- if (free_block_iter != end) {
- return free_block_iter;
- }
-
- *allocate_from_front = size > kSmallAllocationThreshold;
- *allocate_from_front = context == 1;
- if (*allocate_from_front) {
- for (FreeBlockSet::iterator it = begin; it != end; ++it) {
- if (it->CanFulfill(1, alignment)) {
- return it;
- }
- }
-
- return end;
- }
-
- FreeBlockSet::reverse_iterator rbegin(end);
- FreeBlockSet::reverse_iterator rend(begin);
- for (FreeBlockSet::reverse_iterator it = rbegin; it != rend; ++it) {
- if (it->CanFulfill(1, alignment)) {
- return --it.base();
- }
- }
- return end;
-}
-
std::size_t DecoderBufferAllocator::GetAllocatedMemory() const {
if (!using_memory_pool_) {
return sbmemory_bytes_used_.load();
diff --git a/src/cobalt/media/decoder_buffer_allocator.h b/src/cobalt/media/decoder_buffer_allocator.h
index 0504a6e..e78e6af 100644
--- a/src/cobalt/media/decoder_buffer_allocator.h
+++ b/src/cobalt/media/decoder_buffer_allocator.h
@@ -46,17 +46,6 @@
size_t GetMaximumMemoryCapacity() const override;
private:
- class ReuseAllocator : public nb::BidirectionalFitReuseAllocator {
- public:
- ReuseAllocator(Allocator* fallback_allocator, std::size_t initial_capacity,
- std::size_t allocation_increment, std::size_t max_capacity);
-
- FreeBlockSet::iterator FindBestFreeBlock(
- std::size_t size, std::size_t alignment, intptr_t context,
- FreeBlockSet::iterator begin, FreeBlockSet::iterator end,
- bool* allocate_from_front) override;
- };
-
// Update the Allocation record, and return false if allocation exceeds the
// max buffer capacity, or true otherwise.
bool UpdateAllocationRecord() const;
@@ -68,7 +57,7 @@
starboard::Mutex mutex_;
nb::StarboardMemoryAllocator fallback_allocator_;
- std::unique_ptr<ReuseAllocator> reuse_allocator_;
+ std::unique_ptr<nb::BidirectionalFitReuseAllocator> reuse_allocator_;
SbMediaVideoCodec video_codec_ = kSbMediaVideoCodecNone;
int resolution_width_ = -1;
diff --git a/src/cobalt/media/media_module.cc b/src/cobalt/media/media_module.cc
index b70b045..3f6671d 100644
--- a/src/cobalt/media/media_module.cc
+++ b/src/cobalt/media/media_module.cc
@@ -14,6 +14,9 @@
#include "cobalt/media/media_module.h"
+#include <algorithm>
+#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -37,6 +40,57 @@
namespace {
+// TODO: Determine if ExtractCodecs() and ExtractEncryptionScheme() can be
+// combined and simplified.
+static std::vector<std::string> ExtractCodecs(const std::string& mime_type) {
+ std::vector<std::string> codecs;
+ std::vector<std::string> components = base::SplitString(
+ mime_type, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ LOG_IF(WARNING, components.empty())
+ << "argument mime type \"" << mime_type << "\" is not valid.";
+ // The first component is the type/subtype pair. We want to iterate over the
+ // remaining components to search for the codecs.
+ auto iter = components.begin() + 1;
+ for (; iter != components.end(); ++iter) {
+ std::vector<std::string> name_and_value = base::SplitString(
+ *iter, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ if (name_and_value.size() != 2) {
+ LOG(WARNING) << "parameter for mime_type \"" << mime_type
+ << "\" is not valid.";
+ continue;
+ }
+ if (name_and_value[0] == "codecs") {
+ ParseCodecString(name_and_value[1], &codecs, /* strip= */ false);
+ return codecs;
+ }
+ }
+ return codecs;
+}
+
+static std::string ExtractEncryptionScheme(const std::string& key_system) {
+ std::vector<std::string> components = base::SplitString(
+ key_system, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+ auto iter = components.begin();
+ for (; iter != components.end(); ++iter) {
+ std::vector<std::string> name_and_value = base::SplitString(
+ *iter, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ if (name_and_value.size() != 1 && name_and_value.size() != 2) {
+ LOG(WARNING) << "parameter for key_system \"" << key_system
+ << "\" is not valid.";
+ continue;
+ }
+ if (name_and_value[0] == "encryptionscheme") {
+ if (name_and_value.size() < 2) {
+ return "";
+ }
+ base::RemoveChars(name_and_value[1], "\"", &name_and_value[1]);
+ return name_and_value[1];
+ }
+ }
+ return "";
+}
+
class CanPlayTypeHandlerStarboard : public CanPlayTypeHandler {
public:
void SetDisabledMediaCodecs(
@@ -48,6 +102,15 @@
<< "\" from console/command line.";
}
+ void SetDisabledMediaEncryptionSchemes(
+ const std::string& disabled_encryption_schemes) override {
+ disabled_encryption_schemes_ =
+ base::SplitString(disabled_encryption_schemes, ";",
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ LOG(INFO) << "Disabled encryption scheme(s) \""
+ << disabled_encryption_schemes << "\" from command line.";
+ }
+
SbMediaSupportType CanPlayProgressive(
const std::string& mime_type) const override {
// |mime_type| is something like:
@@ -72,31 +135,6 @@
}
private:
- std::vector<std::string> ExtractCodecs(const std::string& mime_type) const {
- std::vector<std::string> codecs;
- std::vector<std::string> components = base::SplitString(
- mime_type, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
- LOG_IF(WARNING, components.empty())
- << "argument mime type \"" << mime_type << "\" is not valid.";
- // The first component is the type/subtype pair. We want to iterate over the
- // remaining components to search for the codecs.
- auto iter = components.begin() + 1;
- for (; iter != components.end(); ++iter) {
- std::vector<std::string> name_and_value = base::SplitString(
- *iter, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
- if (name_and_value.size() != 2) {
- LOG(WARNING) << "parameter for mime_type \"" << mime_type
- << "\" is not valid.";
- continue;
- }
- if (name_and_value[0] == "codecs") {
- ParseCodecString(name_and_value[1], &codecs, /* strip= */ false);
- return codecs;
- }
- }
- return codecs;
- }
-
SbMediaSupportType CanPlayType(const std::string& mime_type,
const std::string& key_system) const {
if (!disabled_media_codecs_.empty()) {
@@ -111,6 +149,17 @@
}
}
}
+
+ if (!disabled_encryption_schemes_.empty()) {
+ std::string encryption_scheme = ExtractEncryptionScheme(key_system);
+ if (std::find(disabled_encryption_schemes_.begin(),
+ disabled_encryption_schemes_.end(),
+ encryption_scheme) != disabled_encryption_schemes_.end()) {
+ LOG(INFO) << "Encryption scheme (" << encryption_scheme
+ << ") is disabled via console/command line.";
+ return kSbMediaSupportTypeNotSupported;
+ }
+ }
SbMediaSupportType type =
SbMediaCanPlayMimeAndKeySystem(mime_type.c_str(), key_system.c_str());
return type;
@@ -118,6 +167,9 @@
// List of disabled media codecs that will be treated as unsupported.
std::vector<std::string> disabled_media_codecs_;
+ // List of disabled DRM encryption schemes that will be treated as
+ // unsupported.
+ std::vector<std::string> disabled_encryption_schemes_;
};
} // namespace
diff --git a/src/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md b/src/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md
index 8fc180c..76eda31 100644
--- a/src/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md
+++ b/src/cobalt/site/docs/codelabs/cobalt_extensions/codelab.md
@@ -108,7 +108,7 @@
because it makes rebasing to future versions of Cobalt more difficult but has
been possible because porters have historically built **both** Cobalt and
Starboard. However, Cobalt is moving toward Evergreen
-(<a href="https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/doc/evergreen/cobalt_evergreen_overview.md">overview</a>),
+(<a href="https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/doc/evergreen/cobalt_evergreen_overview.md">overview</a>),
an architecture that enables automatic Cobalt updates on devices by separating a
Google-built, Cobalt core shared library from the partner-built Starboard layer
and Cobalt loader app. Because Cobalt core code is built by Google, custom
diff --git a/src/cobalt/site/docs/development/setup-android.md b/src/cobalt/site/docs/development/setup-android.md
index f999d81..b2ddb55 100644
--- a/src/cobalt/site/docs/development/setup-android.md
+++ b/src/cobalt/site/docs/development/setup-android.md
@@ -224,9 +224,7 @@
run that on a device, it needs to be packaged into an APK, which is done by the
associated "deploy" target (e.g. nplb_deploy). The Starboard test runner does
all this for you, so just use that to build and run tests. For example, to
-build and run "devel" NPLB on an ARM64 device, from the top 'src' directory
-(if you've unnested the 'src' directory, just run this from your top-level
-directory):
+build and run "devel" NPLB on an ARM64 device, from the top-level directory:
```
starboard/tools/testing/test_runner.py -p android-arm64 -c devel -b -r -t nplb
diff --git a/src/cobalt/site/docs/development/setup-linux.md b/src/cobalt/site/docs/development/setup-linux.md
index 014394d..288711b 100644
--- a/src/cobalt/site/docs/development/setup-linux.md
+++ b/src/cobalt/site/docs/development/setup-linux.md
@@ -57,23 +57,17 @@
### Set up Developer Tools
-Cobalt's developer tools require a different file structure which we are in the
-process of moving to. For now, if you want to use these tools, you must unnest
-the `src/` directory like so:
+1. Enter your new `cobalt` directory:
-```
-$ cd cobalt
-$ mv src/* ./
-$ mv src/.* ./
-```
+ ```
+ $ cd cobalt
+ ```
-Once you do that, you'll be able to follow the following two steps to have C++
-and Python linting and formatting as well as other helpful checks enabled. Keep
-in mind that after doing this, you'll want to run following commands in the
-top-level directory instead of the `src/` subdirectory.
-
-Git will track this as a large change, we recommend that you create a commit
-for it and rebase that commit of our upstream continuously for now.
+<aside class="note">
+<b>Note:</b> Pre-commit is only available on branches later than 22.lts.1+,
+including trunk. The below commands will fail on 22.lts.1+ and earlier branches.
+For earlier branches, run `cd src` and move on to the next section.
+</aside>
1. Create a Python 3 virtual environment for working on Cobalt (feel free to use `virtualenvwrapper` instead):
@@ -87,15 +81,14 @@
```
$ pre-commit install -t post-checkout -t pre-commit -t pre-push --allow-missing-config
- $ git checkout -b <my-branch-name> origin/COBALT
+ $ git checkout -b <my-branch-name> origin/master
```
## Build and Run Cobalt
-1. Build the code by navigating to the `src` directory in your new
- `cobalt` directory and running the following command. You must
- specify a platform when running this command. On Ubuntu Linux, the
- canonical platform is `linux-x64x11`.
+1. Build the code running the following command in the top-level `cobalt`
+ directory. You must specify a platform when running this command. On Ubuntu
+ Linux, the canonical platform is `linux-x64x11`.
You can also use the `-C` command-line flag to specify a `build_type`.
Valid build types are `debug`, `devel`, `qa`, and `gold`. If you
@@ -109,7 +102,7 @@
<aside class="note"><b>Important:</b> You need to rerun gyp_cobalt every
time a change is made to a `.gyp` file.</aside>
-1. Compile the code from the `src/` directory:
+1. Compile the code from the `cobalt/` directory:
```
$ ninja -C out/<platform>_<build_type> <target_name>
@@ -155,7 +148,7 @@
The flags in the following table are frequently used, and the full set
of flags that this command supports are in <code><a
- href="https://cobalt.googlesource.com/cobalt/+/master/src/cobalt/browser/switches.cc">cobalt/browser/switches.cc</a></code>.
+ href="https://cobalt.googlesource.com/cobalt/+/master/cobalt/browser/switches.cc">cobalt/browser/switches.cc</a></code>.
<table class="details responsive">
<tr>
diff --git a/src/cobalt/site/docs/development/setup-raspi.md b/src/cobalt/site/docs/development/setup-raspi.md
index 0e58a7d..48ca4cc 100644
--- a/src/cobalt/site/docs/development/setup-raspi.md
+++ b/src/cobalt/site/docs/development/setup-raspi.md
@@ -106,19 +106,14 @@
## Build, install, and run Cobalt for Raspberry Pi
-<aside class="note">
-<b>Note:</b> If you've unnested the 'src' directory, build and compile the code
-in your top-level checkout of Cobalt instead of the 'src' subdirectory.
-</aside>
-
-1. Build the code by navigating to the src directory in your cobalt directory and run the
- following command :
+1. Build the code by navigating to the `cobalt` directory and run the
+ following command:
```
$ cobalt/build/gyp_cobalt raspi-2
```
-1. Compile the code from the `src/` directory:
+1. Compile the code from the `cobalt/` directory:
```
$ ninja -C out/raspi-2_debug cobalt
diff --git a/src/cobalt/site/docs/gen/starboard/build/doc/gn_migrate_stub_to_platform.md b/src/cobalt/site/docs/gen/starboard/build/doc/gn_migrate_stub_to_platform.md
index f717d32..12c9356 100644
--- a/src/cobalt/site/docs/gen/starboard/build/doc/gn_migrate_stub_to_platform.md
+++ b/src/cobalt/site/docs/gen/starboard/build/doc/gn_migrate_stub_to_platform.md
@@ -17,14 +17,14 @@
Here are the steps to do your migration:
1. [Copy stub files over to your platform and build them](#copy-stub-files-over-to-your-platform-and-build-them).
-2. [Replace stub toolchain with your platform's toolchain](#replace-stub-toolchain-with-your-platforms-toolchain).
-3. [Replace stub configuration with your platform's configuration](#replace-stub-configuration-with-your-platforms-configuration).
-4. [Replace stubbed starboard_platform target sources with your platform's
- sources](#replace-stubbed-starboardplatform-sources-with-your-platforms-sources).
+2. [Replace stub toolchain with toolchain for your platform](#replace-stub-toolchain-with-toolchain-for-your-platform).
+3. [Replace stub configuration with configuration for your platform](#replace-stub-configuration-with-configuration-for-your-platform).
+4. [Replace stubbed starboard_platform sources with sources for your platform](#replace-stubbed-starboard_platform-sources-with-sources-for-your-platform).
-After each step, you should be able to build the starboard_platform target.
-For example, you would build raspi2 starboard_platform target with the following
+After each step, you should be able to build the starboard_platform target. For
+example, you would build raspi2 starboard_platform target with the following
commands:
+
```
$gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel"'
$ninja -C out/raspi-2gn_devel/ starboard
@@ -47,41 +47,43 @@
* starboard/stub/toolchain/BUILD.gn >
starboard/YOUR_PLATFORM/toolchain/BUILD.gn
2. Add your platform path to starboard/build/platforms.gni as referenced
- [here](../migrating_gyp_to_gn.md#adding-your-platform-to-starboard)
+ [here](./migrating_gyp_to_gn.md#adding-your-platform-to-starboard)
3. Resolve any errors which come up for missing/incorrect file paths. Then, you
should be able to build your platform target with the stubbed out files
suggested in the above section.
-### Replace Stub Toolchain with Your Platform's Toolchain
+### Replace Stub Toolchain with Toolchain for Your Platform
-Follow instructions [here](../migrating_gyp_to_gn.md#migrating-a-toolchain) for
+Follow instructions [here](./migrating_gyp_to_gn.md#migrating-a-toolchain) for
migrating the toolchain. Resolve errors and build the starboard_platform target
with the stubbed files.
-### Replace Stub Configuration with Your Platform's Configuration
+### Replace Stub Configuration with Configuration for Your Platform
This involves migrating the compiler flags and build variables as referenced
-[here](../migrating_gyp_to_gn.md#migrating-a-platform).
+[here](./migrating_gyp_to_gn.md#migrating-a-platform).
> **Highly recommended** \
-> It’s good to turn off the `treat_warnings_as_errors flag` until you can compile
-> the starboard_platform target with the platform files.
-> If this flag is not disabled you might run into a lot of
-> warnings turned errors and it might take time to solve all those errors.
-> Meanwhile you won't be in a buildable state which might make it uncertain as to
-> how much progress you are actually making.
-> For disabling the flag you can pass that as an argument to gn.
-> Here's an example for disabling the flag for raspi2:
+> It’s good to turn off the `treat_warnings_as_errors flag` until you can
+> compile the starboard_platform target with the platform files. If this flag is
+> not disabled you might run into a lot of warnings turned errors and it might
+> take time to solve all those errors. Meanwhile you won't be in a buildable
+> state which might make it uncertain as to how much progress you are actually
+> making. For disabling the flag you can pass that as an argument to gn. Here's
+> an example for disabling the flag for raspi2:
+>
> ```
-> $gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel" treat_warnings_as_errors=false'
+> $gn gen out/raspi-2gn_devel
+> --args='target_platform="raspi-2" build_type="devel"
+> treat_warnings_as_errors=false'
> ```
Resolve errors and build the starboard_platform target with the stubbed files.
-### Replace Stubbed starboard_platform Sources with Your Platform's Sources
+### Replace Stubbed starboard_platform Sources with Sources for Your Platform
This involves adding files for the starboard_platform target as suggested
-[here](../migrating_gyp_to_gn.md#migrating-a-platform).
+[here](./migrating_gyp_to_gn.md#migrating-a-platform).
While building any target, follow the recommendation above of building the
target with `treat_warnings_as_errors=false`.
@@ -118,15 +120,16 @@
* Are the compiler flags for this file the same as in GYP ?
> To compare flags for GYP vs GN refer
- > [section](../migrating_gyp_to_gn.md#validating-a-target). To check if
+ > [section](./migrating_gyp_to_gn.md#validating-a-target). To check if
> the variables/flags you are compiling have changed since GYP, refer
- > [page](../migration_changes.md).
+ > [page](./migration_changes.md).
* Have you passed in the default arguments for your platform correctly?
> Default variables such as `target_cpu`, `target_os` and others can be
> overridden by passing arguments to gn while building. Here's an
> example of passing the default argument `target_cpu` for raspi2:
+ >
> ```
> $gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel" target_cpu="arm"'
> ```
diff --git a/src/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md b/src/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md
index 07b4968..3a9c87e 100644
--- a/src/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md
+++ b/src/cobalt/site/docs/gen/starboard/build/doc/migrating_gyp_to_gn.md
@@ -83,7 +83,8 @@
```
You also may need to remove default configs. The default configs are listed in
-[BUILDCONFIG.gn](../config/BUILDCONFIG.gn). You remove a config like so:
+[BUILDCONFIG.gn](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/config/BUILDCONFIG.gn).
+You remove a config like so:
```
static_library("foo") {
@@ -148,8 +149,9 @@
Instead of implicitly searching directories for certain files like GYP did, we
explicitly enumerate our ports and their locations.
-[platforms.gni](../platforms.gni) contains all of this information, and you'll
-need to add your platform to that list following the same format.
+[platforms.gni](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/platforms.gni)
+contains all of this information, and you'll need to add your platform to that
+list following the same format.
### Migrating a Family of Platforms
@@ -175,10 +177,10 @@
You may define a toolchain from scratch following the [reference][gn_toolchain],
or you can use the
-[gcc/clang templates](../../../build/toolchain/gcc_toolchain.gni) provided.
-Almost all of the reference platforms use these templates, so look to those as
-examples for how to use it correctly. Here's the linux-x64x11
-[toolchain/BUILD.gn file](../../linux/x64x11/toolchain/BUILD.gn).
+[gcc/clang templates](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/build/toolchain/gcc_toolchain.gni)
+provided. Almost all of the reference platforms use these templates, so look to
+those as examples for how to use it correctly. Here's the linux-x64x11
+[toolchain/BUILD.gn file](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/linux/x64x11/toolchain/BUILD.gn).
## Checking Your Migration
@@ -203,29 +205,36 @@
```
If this was equivalent to a GYP target, you can compare the ninja compilation
-databases by using [format_ninja.py](../../../tools/format_ninja.py) and a
-comparison tool, i.e. [meld](https://meldmerge.org/). This will allow you to see
-any changes in commands, i.e. with flags or otherwise.
+databases by using
+[format_ninja.py](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/tools/format_ninja.py)
+and a comparison tool, i.e. [meld](https://meldmerge.org/). This will allow you
+to see any changes in commands, i.e. with flags or otherwise.
The following differences for ninja flags between GYP and GN don't cause any
issues:
-1. The name of the intermediate .o, .d files is different in both cases: Here is
- an example while compiling the same source file
- ```
- starboard/common/new.cc
- ```
- GYP generates:
- ```
- obj/starboard/common/common.new.cc.o
- ```
- GN generates:
- ```
- obj/starboard/common/common/new.o
- ```
-2. The `-x` flag for specifying language is not present in GN migration.
- For example GYP specifies `-x c` flag while building c language files for
- certain targets. This flag is not specified while building any GN targets.
+1. The name of the intermediate .o, .d files is different in both cases: Here
+ is an example while compiling the same source file
+
+ ```
+ starboard/common/new.cc
+ ```
+
+ GYP generates:
+
+ ```
+ obj/starboard/common/common.new.cc.o
+ ```
+
+ GN generates:
+
+ ```
+ obj/starboard/common/common/new.o
+ ```
+
+1. The `-x` flag for specifying language is not present in GN migration. For
+ example GYP specifies `-x c` flag while building c language files for
+ certain targets. This flag is not specified while building any GN targets.
### Validating a Platform
@@ -240,7 +249,7 @@
### Step by Step Stub to Your Platform Migration Guide
-This [document](../gn_migrate_stub_to_platform.md) outlines a step by step
+This [document](./gn_migrate_stub_to_platform.md) outlines a step by step
process for converting the stub platform's GN files to GN files that will be
able to be built for your platform.
diff --git a/src/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md b/src/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md
index 38d8477..83f3dfa 100644
--- a/src/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md
+++ b/src/cobalt/site/docs/gen/starboard/build/doc/migration_changes.md
@@ -19,6 +19,7 @@
`has_drm_system_extension` | `is_internal_build` (true/false) | (global)
`has_cdm` | `is_internal_build` (true/false) | (global)
`has_private_system_properties` | `is_internal_build` (true/false) | (global)
+`sb_pedantic_warnings` (0/1) | `has_pedantic_warnings` (true/false) | (global, see "Compiler Options" note)
`sb_deploy_output_dir` | `sb_install_output_dir` | `//starboard/build/config/base_configuration.gni`
`sb_evergreen` (0/1) | `sb_is_evergreen` (true/false) | `//starboard/build/config/base_configuration.gni`
`sb_evergreen_compatible` (0/1) | `sb_is_evergreen_compatible` (true/false) | `//starboard/build/config/base_configuration.gni`
@@ -42,10 +43,8 @@
`optimize_target_for_speed` (1) | `"//starboard/build/config:speed"` | Optimizations
`compiler_flags_*_speed` | `speed_config_path` | Optimizations
`compiler_flags_*_size` | `size_config_path` | Optimizations
-`sb_pedantic_warnings` | `pedantic_warnings_config_path` | Compiler Options
-`sb_pedantic_warnings` | `no_pedantic_warnings_config_path` | Compiler Options
-Notes:
+## Notes:
* *Starboard Implementation:* If your platform defined
`STARBOARD_IMPLENTATION` in its implementation, you would now add the above
@@ -60,13 +59,12 @@
correct ones for `speed_config_path` and `size_config_path` in your
platform's `platform_configuration/configuration.gni` file.
-* *Compiler Options:* Cobalt compiles some targets with stricter settings
- than others, depending on the platform. Before these targets would opt into
- the stricter settings by settings `sb_pedantic_warnings: 1` in their
- `variables` section. Now they will add the appropriate config like so:
- `configs += [ "//starboard/build/config:pedantic_warnings" ]` and remove
- the default: `configs -= [ "//starboard/build/config:no_pedantic_warnings"
- ]`. The additional config that is used to compile these targets is
- specified with the `pedantic_warnings_config_path` and
- `no_pedantic_warnings_config_path` variables in your platform's
- `platform_configuration/configuration.gni` file.
+* *Compiler Options:* Cobalt compiles some targets with stricter,
+ platform-dependent settings than others. Before these targets would opt into
+ the stricter settings by setting `sb_pedantic_warnings: 1` in their
+ `variables` section. Now targets will be compiled with pedantic warnings if
+ the target sets `has_pedantic_warnings=true`. The additional config that is
+ used to compile these targets is specified with the
+ `pedantic_warnings_config_path` and `no_pedantic_warnings_config_path`
+ variables in your platform's `platform_configuration/configuration.gni`
+ file.
diff --git a/src/cobalt/site/docs/gen/starboard/doc/c99.md b/src/cobalt/site/docs/gen/starboard/doc/c99.md
index 3aed66d..2c5f7a5 100644
--- a/src/cobalt/site/docs/gen/starboard/doc/c99.md
+++ b/src/cobalt/site/docs/gen/starboard/doc/c99.md
@@ -35,13 +35,63 @@
* tolower
* toupper
### <math.h>
+* acos
+* acosf
+* asin
+* asinf
+* atan
+* atan2
+* atan2f
+* atanf
+* cbrt
+* cbrtf
+* ceil
+* ceilf
+* cos
+* cosf
+* div
+* erf
+* erff
+* exp
+* expf
+* exp2f
* fabs
* floor
+* floorf
+* fmod
+* fmodf
+* frexp
* isfinite
* isnan
+* labs
+* llround
+* llroundf
+* log
+* log10
+* log10f
+* log2
+* log2f
+* ldexp
+* lrint
+* lrintf
+* modf
+* nearbyint
+* nearbyintf
+* nextafter
+* nextafterf
* pow
+* powf
+* round
+* roundf
+* scalbn
+* sin
+* sinf
* sqrt
* sqrtf
+* tan
+* tanf
+* trunc
+* truncf
### <stdlib.h>
* abs
* atoi
@@ -70,6 +120,9 @@
* strrchr
* strstr
* strspn
+### <tgmath.h>
+* ceill
+* logl
### <wchar.h>
* wcscat
* wcschr
diff --git a/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_overview.md b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_overview.md
index 4e07d8e..8d770ca 100644
--- a/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_overview.md
+++ b/src/cobalt/site/docs/gen/starboard/doc/evergreen/cobalt_evergreen_overview.md
@@ -507,16 +507,17 @@
### Fonts
The system font directory `kSbSystemPathFontDirectory` should be configured to
-point to the `standard` (23MB) or the `limited` (3.1MB) cobalt font packages. An
-easy way to do that is to use the `kSbSystemPathContentDirectory` to contain
-the system font directory and setting the `cobalt_font_package` to `standard` or
-`limited` in your port.
+point to either the system fonts on the device or the Cobalt `standard` (23MB)
+or the Cobalt `limited` (3.1MB) font packages. An easy way to use the Cobalt
+fonts is to set `kSbSystemPathFontDirectory` to point to
+`kSbSystemPathContentDirectory/fonts` and configure `cobalt_font_package` to
+`standard` or `limited` in your port.
Cobalt Evergreen (built by Google), will by default use the `empty` font
package to minimize storage requirements. A separate
`cobalt_font_package` variable is set to `empty` in the Evergreen platform.
-On Raspberry Pi this is:
+On Raspberry Pi the Cobalt fonts are configured the following way:
`empty` set of fonts under:
```
diff --git a/src/cobalt/site/docs/starboard/porting.md b/src/cobalt/site/docs/starboard/porting.md
index aee5b59..c6e635a 100644
--- a/src/cobalt/site/docs/starboard/porting.md
+++ b/src/cobalt/site/docs/starboard/porting.md
@@ -71,9 +71,9 @@
Add the following directories to the source tree for the `<family-name>`
that you selected in step 1:
-* `src/third_party/starboard/<family-name>/`
+* `third_party/starboard/<family-name>/`
-* `src/third_party/starboard/<family-name>/shared/`
+* `third_party/starboard/<family-name>/shared/`
This subdirectory contains code that is shared between architectures
within a product family. For example, if BobBox devices run on many
@@ -82,15 +82,15 @@
Starboard function implementation, BobCo can put that function in the
`shared` directory to make it accessible in every binary variant.
-* `src/third_party/starboard/<family-name>/<binary-variant>/`
+* `third_party/starboard/<family-name>/<binary-variant>/`
You should create one directory for _each_ `<binary-variant>`. So, for
example, BobCo could create the following directories:
- * `src/third_party/starboard/bobbox/shared/`
- * `src/third_party/starboard/bobbox/armeb/`
- * `src/third_party/starboard/bobbox/armel/`
- * `src/third_party/starboard/bobbox/armel/gles/`
+ * `third_party/starboard/bobbox/shared/`
+ * `third_party/starboard/bobbox/armeb/`
+ * `third_party/starboard/bobbox/armel/`
+ * `third_party/starboard/bobbox/armel/gles/`
Again, functions that work for all of the configurations would go in the
`shared` directory. Functions that work for all little-endian devices would go
@@ -110,7 +110,7 @@
* `thread_types_public.h`
We recommend that you copy the files from the Stub reference implementation,
-located at `src/starboard/stub/` to your `binary-variant` directories.
+located at `starboard/stub/` to your `binary-variant` directories.
In this approach, you will essentially start with a clean slate of stub
interfaces that need to be modified to work with your platform.
@@ -122,8 +122,8 @@
command for each `binary-variant` directory:
```sh
-cp -R src/starboard/stub
- src/third_party/starboard/<family-name>/<binary-variant>
+cp -R starboard/stub
+ third_party/starboard/<family-name>/<binary-variant>
```
After copying these files, you should be able to compile Cobalt and link it
@@ -304,20 +304,20 @@
The `starboard_platform.gyp` file points to all of the source files included
in your new Starboard implementation. If you are starting with a copy of the
Stub implementation, then that file will initially include a lot of files
-from the `src/starboard/shared/stub/` directory. Similarly, if you are starting
+from the `starboard/shared/stub/` directory. Similarly, if you are starting
starting with a copy of the Desktop Linux port, then that file will initially
-point to files in the `src/starboard/shared/posix` directory.
+point to files in the `starboard/shared/posix` directory.
The modules are defined so that each one has a set of functions, and each
function is defined in its own file with a consistent naming convention.
For example, the `SbSystemBreakIntoDebugger()` function is defined in the
`system_break_into_debugger.cc` file. The list of files in the
-`src/starboard/shared/stub/` directory represents an authoritative list of
+`starboard/shared/stub/` directory represents an authoritative list of
supported functions.
Function-by-function and module-by-module, you can now replace stub
implementations with either custom implementations or with other ported
-implementations from the `src/starboard/shared/` directory until you have
+implementations from the `starboard/shared/` directory until you have
gone through all of the modules. As you do, update the
`starboard_platform.gyp` file to identify the appropriate source files.
diff --git a/src/cobalt/site/docs/starboard/testing.md b/src/cobalt/site/docs/starboard/testing.md
index fd2f502..16eea52 100644
--- a/src/cobalt/site/docs/starboard/testing.md
+++ b/src/cobalt/site/docs/starboard/testing.md
@@ -21,11 +21,11 @@
## Test Organization
-NPLB tests can be found in the `src/starboard/nplb/` directory and are broken
+NPLB tests can be found in the `starboard/nplb/` directory and are broken
out into files by Starboard module and function:
```
-src/starboard/nplb/<module>_<function>_test.cc
+starboard/nplb/<module>_<function>_test.cc
```
Although each test may incidentally test other functions, there is an attempt
@@ -36,4 +36,4 @@
For example, the `SbSocketSendTo` and `SbSocketReceiveFrom` are tested
together, ensuring that the API is self-consistent on both sides of a
connection. Therefore, only one set of tests exist to cover those use cases,
-in `src/starboard/nplb/socket_receive_from_test.cc`.
+in `starboard/nplb/socket_receive_from_test.cc`.
diff --git a/src/cobalt/updater/configurator.cc b/src/cobalt/updater/configurator.cc
index b8df78b..d26d9a4 100644
--- a/src/cobalt/updater/configurator.cc
+++ b/src/cobalt/updater/configurator.cc
@@ -64,6 +64,7 @@
network_fetcher_factory_(
base::MakeRefCounted<NetworkFetcherFactoryCobalt>(network_module)),
patch_factory_(base::MakeRefCounted<PatcherFactory>()) {
+ LOG(INFO) << "Configurator::Configurator";
const std::string persisted_channel =
persisted_data_->GetUpdaterChannel(GetAppGuid());
if (persisted_channel.empty()) {
@@ -75,7 +76,7 @@
user_agent_string_ = network_module->GetUserAgent();
}
}
-Configurator::~Configurator() = default;
+Configurator::~Configurator() { LOG(INFO) << "Configurator::~Configurator"; }
int Configurator::InitialDelay() const { return 0; }
diff --git a/src/cobalt/updater/network_fetcher.cc b/src/cobalt/updater/network_fetcher.cc
index 1dfbc7c..c70b636 100644
--- a/src/cobalt/updater/network_fetcher.cc
+++ b/src/cobalt/updater/network_fetcher.cc
@@ -52,7 +52,7 @@
}
// Returns the integral value of a header of the server response or -1 if
-// if the header is not available or a conversion error has occured.
+// if the header is not available or a conversion error has occurred.
int64_t GetInt64Header(const net::HttpResponseHeaders* headers,
const char* header_name) {
if (!headers) {
@@ -68,9 +68,13 @@
namespace updater {
NetworkFetcher::NetworkFetcher(const network::NetworkModule* network_module)
- : network_module_(network_module) {}
+ : network_module_(network_module) {
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::NetworkFetcher";
+}
-NetworkFetcher::~NetworkFetcher() {}
+NetworkFetcher::~NetworkFetcher() {
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::~NetworkFetcher";
+}
void NetworkFetcher::PostRequest(
const GURL& url, const std::string& post_data,
@@ -80,8 +84,9 @@
PostRequestCompleteCallback post_request_complete_callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- SB_LOG(INFO) << "PostRequest url = " << url;
- SB_LOG(INFO) << "PostRequest post_data = " << post_data;
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::PostRequest";
+ LOG(INFO) << "PostRequest url = " << url;
+ LOG(INFO) << "PostRequest post_data = " << post_data;
response_started_callback_ = std::move(response_started_callback);
progress_callback_ = std::move(progress_callback);
@@ -111,8 +116,9 @@
DownloadToFileCompleteCallback download_to_file_complete_callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- SB_LOG(INFO) << "DownloadToFile url = " << url;
- SB_LOG(INFO) << "DownloadToFile file_path = " << file_path;
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::DownloadToFile";
+ LOG(INFO) << "DownloadToFile url = " << url;
+ LOG(INFO) << "DownloadToFile file_path = " << file_path;
response_started_callback_ = std::move(response_started_callback);
progress_callback_ = std::move(progress_callback);
@@ -129,15 +135,15 @@
url_fetcher_->Start();
}
-void NetworkFetcher::CancelDownloadToFile() {
+void NetworkFetcher::Cancel() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
- SB_LOG(INFO) << "Canceling DownloadToFile";
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::Cancel";
url_fetcher_.reset();
}
void NetworkFetcher::OnURLFetchResponseStarted(const net::URLFetcher* source) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::OnURLFetchResponseStarted";
std::move(response_started_callback_)
.Run(source->GetURL(), source->GetResponseCode(),
source->GetResponseHeaders()
@@ -147,6 +153,7 @@
void NetworkFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::OnURLFetchComplete";
const net::URLRequestStatus& status = source->GetStatus();
const int response_code = source->GetResponseCode();
if (url_fetcher_type_ == kUrlFetcherTypePostRequest) {
@@ -169,6 +176,7 @@
int64_t current, int64_t total,
int64_t current_network_bytes) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::OnURLFetchDownloadProgress";
progress_callback_.Run(current);
}
@@ -195,6 +203,7 @@
void NetworkFetcher::OnPostRequestComplete(const net::URLFetcher* source,
const int status_error) {
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::OnPostRequestComplete";
std::unique_ptr<std::string> response_body(new std::string);
auto* download_data_writer =
base::polymorphic_downcast<loader::URLFetcherStringWriter*>(
@@ -204,11 +213,10 @@
}
if (response_body->empty()) {
- SB_LOG(ERROR) << "PostRequest got empty response.";
+ LOG(ERROR) << "PostRequest got empty response.";
}
- SB_LOG(INFO) << "OnPostRequestComplete response_body = "
- << *response_body.get();
+ LOG(INFO) << "OnPostRequestComplete response_body = " << *response_body.get();
net::HttpResponseHeaders* response_headers = source->GetResponseHeaders();
std::move(post_request_complete_callback_)
@@ -221,11 +229,12 @@
void NetworkFetcher::OnDownloadToFileComplete(const net::URLFetcher* source,
const int status_error) {
+ LOG(INFO) << "cobalt::updater::NetworkFetcher::OnDownloadToFileComplete";
base::FilePath response_file;
if (!source->GetResponseAsFilePath(true, &response_file)) {
- SB_LOG(ERROR) << "DownloadToFile failed to get response from a file";
+ LOG(ERROR) << "DownloadToFile failed to get response from a file";
}
- SB_LOG(INFO) << "OnDownloadToFileComplete response_file = " << response_file;
+ LOG(INFO) << "OnDownloadToFileComplete response_file = " << response_file;
std::move(download_to_file_complete_callback_)
.Run(response_file, status_error,
@@ -236,8 +245,9 @@
NetworkFetcher::ReturnWrapper NetworkFetcher::HandleError(
const std::string& message) {
+ LOG(ERROR) << "cobalt::updater::NetworkFetcher::HandleError message="
+ << message;
url_fetcher_.reset();
- SB_LOG(ERROR) << message;
return ReturnWrapper();
}
diff --git a/src/cobalt/updater/network_fetcher.h b/src/cobalt/updater/network_fetcher.h
index 17b8909..c32f74d 100644
--- a/src/cobalt/updater/network_fetcher.h
+++ b/src/cobalt/updater/network_fetcher.h
@@ -69,7 +69,7 @@
ProgressCallback progress_callback,
DownloadToFileCompleteCallback
download_to_file_complete_callback) override;
- void CancelDownloadToFile() override;
+ void Cancel() override;
// net::URLFetcherDelegate interface.
void OnURLFetchResponseStarted(const net::URLFetcher* source) override;
diff --git a/src/cobalt/updater/prefs.cc b/src/cobalt/updater/prefs.cc
index 5745632..3e195bb 100644
--- a/src/cobalt/updater/prefs.cc
+++ b/src/cobalt/updater/prefs.cc
@@ -1,6 +1,16 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Copyright 2019 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/updater/prefs.h"
@@ -27,17 +37,17 @@
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_api) {
- SB_LOG(ERROR) << "Failed to get installation manager api.";
+ LOG(ERROR) << "Failed to get installation manager api.";
return nullptr;
}
char app_key[IM_EXT_MAX_APP_KEY_LENGTH];
if (installation_api->GetAppKey(app_key, IM_EXT_MAX_APP_KEY_LENGTH) ==
IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Failed to get app key.";
+ LOG(ERROR) << "Failed to get app key.";
return nullptr;
}
- SB_LOG(INFO) << "Updater: prefs app_key=" << app_key;
+ LOG(INFO) << "Updater: prefs app_key=" << app_key;
PrefServiceFactory pref_service_factory;
std::string file_name = "prefs_";
file_name += app_key;
diff --git a/src/cobalt/updater/unzipper.cc b/src/cobalt/updater/unzipper.cc
index 876eea6..1855b3a 100644
--- a/src/cobalt/updater/unzipper.cc
+++ b/src/cobalt/updater/unzipper.cc
@@ -1,6 +1,16 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+// Copyright 2019 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/updater/unzipper.h"
@@ -25,10 +35,10 @@
std::move(callback).Run(zip::Unzip(zip_path, output_path));
SbTimeMonotonic time_unzip_took =
SbTimeGetMonotonicNow() - time_before_unzip;
- SB_LOG(INFO) << "Unzip file path = " << zip_path;
- SB_LOG(INFO) << "output_path = " << output_path;
- SB_LOG(INFO) << "Unzip took " << time_unzip_took / kSbTimeMillisecond
- << " milliseconds.";
+ LOG(INFO) << "Unzip file path = " << zip_path;
+ LOG(INFO) << "output_path = " << output_path;
+ LOG(INFO) << "Unzip took " << time_unzip_took / kSbTimeMillisecond
+ << " milliseconds.";
}
};
diff --git a/src/cobalt/updater/updater.cc b/src/cobalt/updater/updater.cc
index 8f77701..9d8da63 100644
--- a/src/cobalt/updater/updater.cc
+++ b/src/cobalt/updater/updater.cc
@@ -94,7 +94,8 @@
network::NetworkModule::Options network_options;
network_module.reset(new network::NetworkModule(network_options));
- updater_module.reset(new updater::UpdaterModule(network_module.get()));
+ updater_module.reset(new updater::UpdaterModule(
+ network_module.get(), kDefaultUpdateCheckDelaySeconds));
return 0;
}
diff --git a/src/cobalt/updater/updater_module.cc b/src/cobalt/updater/updater_module.cc
index 3941cb6..2cf09b5 100644
--- a/src/cobalt/updater/updater_module.cc
+++ b/src/cobalt/updater/updater_module.cc
@@ -26,10 +26,12 @@
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
+#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
#include "base/task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
+#include "cobalt/browser/switches.h"
#include "cobalt/extension/installation_manager.h"
#include "cobalt/updater/crash_client.h"
#include "cobalt/updater/crash_reporter.h"
@@ -81,7 +83,10 @@
namespace cobalt {
namespace updater {
+const uint64_t kDefaultUpdateCheckDelaySeconds = 60;
+
void Observer::OnEvent(Events event, const std::string& id) {
+ LOG(INFO) << "Observer::OnEvent id=" << id;
std::string status;
if (update_client_->GetCrxUpdateState(id, &crx_update_item_)) {
auto status_iterator =
@@ -112,35 +117,51 @@
status = "No status available";
}
updater_configurator_->SetUpdaterStatus(status);
- SB_LOG(INFO) << "Updater status is " << status;
+ LOG(INFO) << "Updater status is " << status;
}
-UpdaterModule::UpdaterModule(network::NetworkModule* network_module)
- : updater_thread_("updater"), network_module_(network_module) {
- updater_thread_.StartWithOptions(
+UpdaterModule::UpdaterModule(network::NetworkModule* network_module,
+ uint64_t update_check_delay_sec)
+ : network_module_(network_module),
+ update_check_delay_sec_(update_check_delay_sec) {
+ LOG(INFO) << "UpdaterModule::UpdaterModule";
+ updater_thread_.reset(new base::Thread("Updater"));
+ updater_thread_->StartWithOptions(
base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
DETACH_FROM_THREAD(thread_checker_);
// Initialize the underlying update client.
is_updater_running_ = true;
- updater_thread_.task_runner()->PostTask(
+ updater_thread_->task_runner()->PostTask(
FROM_HERE,
base::Bind(&UpdaterModule::Initialize, base::Unretained(this)));
+
+ // Mark the current installation as successful.
+ updater_thread_->task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&UpdaterModule::MarkSuccessful, base::Unretained(this)));
}
UpdaterModule::~UpdaterModule() {
+ LOG(INFO) << "UpdaterModule::~UpdaterModule";
if (is_updater_running_) {
is_updater_running_ = false;
- updater_thread_.task_runner()->PostBlockingTask(
+ updater_thread_->task_runner()->PostBlockingTask(
FROM_HERE,
base::Bind(&UpdaterModule::Finalize, base::Unretained(this)));
}
+
+ // Upon destruction the thread will allow all queued tasks to complete before
+ // the thread is terminated. The thread is destroyed before returning from
+ // this destructor to prevent one of the thread's tasks from accessing member
+ // fields after they are destroyed.
+ updater_thread_.reset();
}
void UpdaterModule::Suspend() {
if (is_updater_running_) {
is_updater_running_ = false;
- updater_thread_.task_runner()->PostBlockingTask(
+ updater_thread_->task_runner()->PostBlockingTask(
FROM_HERE,
base::Bind(&UpdaterModule::Finalize, base::Unretained(this)));
}
@@ -149,7 +170,7 @@
void UpdaterModule::Resume() {
if (!is_updater_running_) {
is_updater_running_ = true;
- updater_thread_.task_runner()->PostTask(
+ updater_thread_->task_runner()->PostTask(
FROM_HERE,
base::Bind(&UpdaterModule::Initialize, base::Unretained(this)));
}
@@ -165,13 +186,17 @@
update_client_->AddObserver(updater_observer_.get());
// Schedule the first update check.
- updater_thread_.task_runner()->PostDelayedTask(
+
+ LOG(INFO) << "Scheduling UpdateCheck with delay " << update_check_delay_sec_
+ << " seconds";
+ updater_thread_->task_runner()->PostDelayedTask(
FROM_HERE, base::Bind(&UpdaterModule::Update, base::Unretained(this)),
- base::TimeDelta::FromMinutes(1));
+ base::TimeDelta::FromSeconds(update_check_delay_sec_));
}
void UpdaterModule::Finalize() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ LOG(INFO) << "UpdaterModule::Finalize begin";
update_client_->RemoveObserver(updater_observer_.get());
updater_observer_.reset();
update_client_->Stop();
@@ -186,27 +211,28 @@
}
updater_configurator_ = nullptr;
+ LOG(INFO) << "UpdaterModule::Finalize end";
}
void UpdaterModule::MarkSuccessful() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ LOG(INFO) << "UpdaterModule::MarkSuccessful";
auto installation_manager =
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_manager) {
- SB_LOG(ERROR) << "Updater failed to get installation manager extension.";
+ LOG(ERROR) << "Updater failed to get installation manager extension.";
return;
}
int index = installation_manager->GetCurrentInstallationIndex();
if (index == IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Updater failed to get current installation index.";
+ LOG(ERROR) << "Updater failed to get current installation index.";
return;
}
if (installation_manager->MarkInstallationSuccessful(index) !=
IM_EXT_SUCCESS) {
- SB_LOG(ERROR)
- << "Updater failed to mark the current installation successful";
+ LOG(ERROR) << "Updater failed to mark the current installation successful";
}
}
@@ -221,7 +247,7 @@
const base::Version manifest_version(GetCurrentEvergreenVersion());
if (!manifest_version.IsValid()) {
- SB_LOG(ERROR) << "Updater failed to get the current update version.";
+ LOG(ERROR) << "Updater failed to get the current update version.";
return;
}
@@ -250,11 +276,6 @@
},
base::Bind(base::DoNothing::Repeatedly())));
- // Mark the current installation as successful.
- updater_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&UpdaterModule::MarkSuccessful, base::Unretained(this)));
-
IncrementUpdateCheckCount();
int kNextUpdateCheckHours = 0;
@@ -267,7 +288,7 @@
// hours.
kNextUpdateCheckHours = 24;
}
- updater_thread_.task_runner()->PostDelayedTask(
+ updater_thread_->task_runner()->PostDelayedTask(
FROM_HERE, base::Bind(&UpdaterModule::Update, base::Unretained(this)),
base::TimeDelta::FromHours(kNextUpdateCheckHours));
}
@@ -280,26 +301,41 @@
}
std::string UpdaterModule::GetUpdaterChannel() const {
+ LOG(INFO) << "UpdaterModule::GetUpdaterChannel";
auto config = updater_configurator_;
- if (!config) return "";
+ if (!config) {
+ LOG(ERROR) << "UpdaterModule::GetUpdaterChannel: missing config";
+ return "";
+ }
- return config->GetChannel();
+ std::string channel = config->GetChannel();
+ LOG(INFO) << "UpdaterModule::GetUpdaterChannel channel=" << channel;
+ return channel;
}
void UpdaterModule::SetUpdaterChannel(const std::string& updater_channel) {
+ LOG(INFO) << "UpdaterModule::SetUpdaterChannel updater_channel="
+ << updater_channel;
auto config = updater_configurator_;
if (config) config->SetChannel(updater_channel);
}
std::string UpdaterModule::GetUpdaterStatus() const {
+ LOG(INFO) << "UpdaterModule::GetUpdaterStatus";
auto config = updater_configurator_;
- if (!config) return "";
+ if (!config) {
+ LOG(ERROR) << "UpdaterModule::GetUpdaterStatus: missing configuration";
+ return "";
+ }
- return config->GetUpdaterStatus();
+ std::string updater_status = config->GetUpdaterStatus();
+ LOG(INFO) << "UpdaterModule::GetUpdaterStatus updater_status="
+ << updater_status;
+ return updater_status;
}
void UpdaterModule::RunUpdateCheck() {
- updater_thread_.task_runner()->PostTask(
+ updater_thread_->task_runner()->PostTask(
FROM_HERE, base::Bind(&UpdaterModule::Update, base::Unretained(this)));
}
@@ -308,21 +344,21 @@
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_manager) {
- SB_LOG(ERROR) << "Updater failed to get installation manager extension.";
+ LOG(ERROR) << "Updater failed to get installation manager extension.";
return;
}
if (installation_manager->Reset() == IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Updater failed to reset installations.";
+ LOG(ERROR) << "Updater failed to reset installations.";
return;
}
base::FilePath product_data_dir;
if (!GetProductDirectoryPath(&product_data_dir)) {
- SB_LOG(ERROR) << "Updater failed to get product directory path.";
+ LOG(ERROR) << "Updater failed to get product directory path.";
return;
}
if (!starboard::SbFileDeleteRecursive(product_data_dir.value().c_str(),
true)) {
- SB_LOG(ERROR) << "Updater failed to clean the product directory.";
+ LOG(ERROR) << "Updater failed to clean the product directory.";
return;
}
}
@@ -332,12 +368,12 @@
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_manager) {
- SB_LOG(ERROR) << "Updater failed to get installation manager extension.";
+ LOG(ERROR) << "Updater failed to get installation manager extension.";
return -1;
}
int index = installation_manager->GetCurrentInstallationIndex();
if (index == IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Updater failed to get current installation index.";
+ LOG(ERROR) << "Updater failed to get current installation index.";
return -1;
}
return index;
diff --git a/src/cobalt/updater/updater_module.h b/src/cobalt/updater/updater_module.h
index fa4abc0..353215e 100644
--- a/src/cobalt/updater/updater_module.h
+++ b/src/cobalt/updater/updater_module.h
@@ -53,8 +53,9 @@
};
// Mapping a component state to an updater status.
-const std::map<ComponentState, UpdaterStatus> component_to_updater_status_map =
- {
+// clang-format off
+const std::map<ComponentState, UpdaterStatus> component_to_updater_status_map = {
+ // clang-format on
{ComponentState::kNew, UpdaterStatus::kNewUpdate},
{ComponentState::kChecking, UpdaterStatus::kChecking},
{ComponentState::kCanUpdate, UpdaterStatus::kUpdateAvailable},
@@ -88,6 +89,9 @@
{UpdaterStatus::kRun, "Transitioning..."},
};
+// Default number of seconds to delay the first update check.
+extern const uint64_t kDefaultUpdateCheckDelaySeconds;
+
// An interface that observes the updater. It provides notifications when the
// updater changes status.
class Observer : public update_client::UpdateClient::Observer {
@@ -101,7 +105,7 @@
SbSystemGetExtension(kCobaltExtensionUpdaterNotificationName));
if (updater_notification_ext &&
strcmp(updater_notification_ext->name,
- kCobaltExtensionUpdaterNotificationName) == 0 &&
+ kCobaltExtensionUpdaterNotificationName) == 0 &&
updater_notification_ext->version >= 1) {
updater_notification_ext_ = updater_notification_ext;
} else {
@@ -127,7 +131,8 @@
// checks run according to a schedule defined by the Cobalt application.
class UpdaterModule {
public:
- explicit UpdaterModule(network::NetworkModule* network_module);
+ explicit UpdaterModule(network::NetworkModule* network_module,
+ uint64_t update_check_delay_sec);
~UpdaterModule();
void Suspend();
@@ -147,13 +152,14 @@
int GetInstallationIndex() const;
private:
- base::Thread updater_thread_;
+ std::unique_ptr<base::Thread> updater_thread_;
scoped_refptr<update_client::UpdateClient> update_client_;
std::unique_ptr<Observer> updater_observer_;
network::NetworkModule* network_module_;
scoped_refptr<Configurator> updater_configurator_;
int update_check_count_ = 0;
bool is_updater_running_;
+ uint64_t update_check_delay_sec_ = kDefaultUpdateCheckDelaySeconds;
THREAD_CHECKER(thread_checker_);
diff --git a/src/cobalt/updater/utils.cc b/src/cobalt/updater/utils.cc
index 5baad0a..decc274 100644
--- a/src/cobalt/updater/utils.cc
+++ b/src/cobalt/updater/utils.cc
@@ -4,6 +4,7 @@
#include "cobalt/updater/utils.h"
+#include <memory>
#include <vector>
#include "base/base_paths.h"
@@ -11,10 +12,13 @@
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
+#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "cobalt/extension/installation_manager.h"
#include "components/update_client/utils.h"
+#include "crypto/secure_hash.h"
+#include "crypto/sha2.h"
#include "starboard/configuration_constants.h"
#include "starboard/string.h"
#include "starboard/system.h"
@@ -61,8 +65,8 @@
#if SB_API_VERSION >= 12
if (!SbSystemGetPath(kSbSystemPathStorageDirectory, storage_dir.data(),
kSbFileMaxPath)) {
- SB_LOG(ERROR) << "GetProductDirectoryPath: Failed to get "
- "kSbSystemPathStorageDirectory";
+ LOG(ERROR) << "GetProductDirectoryPath: Failed to get "
+ "kSbSystemPathStorageDirectory";
return false;
}
#else
@@ -97,7 +101,7 @@
std::vector<char> system_path_content_dir(kSbFileMaxPath);
if (!SbSystemGetPath(kSbSystemPathContentDirectory,
system_path_content_dir.data(), kSbFileMaxPath)) {
- SB_LOG(ERROR) << "Failed to get system path content directory";
+ LOG(ERROR) << "Failed to get system path content directory";
return "";
}
// Get the parent directory of the system_path_content_dir, and read the
@@ -108,8 +112,8 @@
.DirName());
if (!version.IsValid()) {
- SB_LOG(ERROR) << "Failed to get the Evergreen version. Defaulting to "
- << kDefaultManifestVersion << ".";
+ LOG(ERROR) << "Failed to get the Evergreen version. Defaulting to "
+ << kDefaultManifestVersion << ".";
return std::string(kDefaultManifestVersion);
}
return version.GetString();
@@ -120,23 +124,23 @@
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_manager) {
- SB_LOG(ERROR) << "Failed to get installation manager extension, getting "
- "the Evergreen version of the loaded installation.";
+ LOG(ERROR) << "Failed to get installation manager extension, getting "
+ "the Evergreen version of the loaded installation.";
return GetLoadedInstallationEvergreenVersion();
}
// Get the update version from the manifest file under the current
// installation path.
int index = installation_manager->GetCurrentInstallationIndex();
if (index == IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Failed to get current installation index, getting the "
- "Evergreen version of the currently loaded installation.";
+ LOG(ERROR) << "Failed to get current installation index, getting the "
+ "Evergreen version of the currently loaded installation.";
return GetLoadedInstallationEvergreenVersion();
}
std::vector<char> installation_path(kSbFileMaxPath);
if (installation_manager->GetInstallationPath(
index, installation_path.data(), kSbFileMaxPath) == IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Failed to get installation path, getting the Evergreen "
- "version of the currently loaded installation.";
+ LOG(ERROR) << "Failed to get installation path, getting the Evergreen "
+ "version of the currently loaded installation.";
return GetLoadedInstallationEvergreenVersion();
}
@@ -144,12 +148,81 @@
std::string(installation_path.begin(), installation_path.end())));
if (!version.IsValid()) {
- SB_LOG(ERROR) << "Failed to get the Evergreen version. Defaulting to "
- << kDefaultManifestVersion << ".";
+ LOG(ERROR) << "Failed to get the Evergreen version. Defaulting to "
+ << kDefaultManifestVersion << ".";
return std::string(kDefaultManifestVersion);
}
return version.GetString();
}
+std::string GetLibrarySha256(int index) {
+ base::FilePath filepath;
+ auto installation_manager =
+ static_cast<const CobaltExtensionInstallationManagerApi*>(
+ SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
+ if (!installation_manager && index == 0) {
+ // Evergreen Lite
+ std::vector<char> system_path_content_dir(kSbFileMaxPath);
+ if (!SbSystemGetPath(kSbSystemPathContentDirectory,
+ system_path_content_dir.data(), kSbFileMaxPath)) {
+ SB_LOG(ERROR)
+ << "GetLibrarySha256: Failed to get system path content directory";
+ return "";
+ }
+
+ filepath = base::FilePath(std::string(system_path_content_dir.begin(),
+ system_path_content_dir.end()))
+ .DirName();
+ } else if (!installation_manager && index != 0) {
+ SB_LOG(ERROR) << "GetLibrarySha256: Evergreen lite supports only slot 0";
+ return "";
+ } else {
+ // Evergreen Full
+ std::vector<char> installation_path(kSbFileMaxPath);
+ if (installation_manager->GetInstallationPath(
+ index, installation_path.data(), kSbFileMaxPath) == IM_EXT_ERROR) {
+ SB_LOG(ERROR) << "GetLibrarySha256: Failed to get installation path";
+ return "";
+ }
+
+ filepath = base::FilePath(installation_path.data());
+ }
+
+ filepath = filepath.AppendASCII("lib").AppendASCII("libcobalt.so");
+ base::File source_file(filepath,
+ base::File::FLAG_OPEN | base::File::FLAG_READ);
+ if (!source_file.IsValid()) {
+ SB_LOG(ERROR) << "GetLibrarySha256(): Unable to open source file: "
+ << filepath.value();
+ return "";
+ }
+
+ const size_t kBufferSize = 32768;
+ std::vector<char> buffer(kBufferSize);
+ uint8_t actual_hash[crypto::kSHA256Length] = {0};
+ std::unique_ptr<crypto::SecureHash> hasher(
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+
+ while (true) {
+ int bytes_read = source_file.ReadAtCurrentPos(&buffer[0], buffer.size());
+ if (bytes_read < 0) {
+ SB_LOG(ERROR) << "GetLibrarySha256(): error reading from: "
+ << filepath.value();
+
+ return "";
+ }
+
+ if (bytes_read == 0) {
+ break;
+ }
+
+ hasher->Update(&buffer[0], bytes_read);
+ }
+
+ hasher->Finish(actual_hash, sizeof(actual_hash));
+
+ return base::HexEncode(actual_hash, sizeof(actual_hash));
+}
+
} // namespace updater
} // namespace cobalt
diff --git a/src/cobalt/updater/utils.h b/src/cobalt/updater/utils.h
index 5efa2db..a0b5008 100644
--- a/src/cobalt/updater/utils.h
+++ b/src/cobalt/updater/utils.h
@@ -29,6 +29,10 @@
// Read the Evergreen version of the installation dir.
base::Version ReadEvergreenVersion(base::FilePath installation_dir);
+// Returns the hash of the libcobalt.so binary for the installation
+// at slot |index|.
+std::string GetLibrarySha256(int index);
+
} // namespace updater
} // namespace cobalt
diff --git a/src/cobalt/version.h b/src/cobalt/version.h
index b338e71..67c2448 100644
--- a/src/cobalt/version.h
+++ b/src/cobalt/version.h
@@ -35,6 +35,6 @@
// release is cut.
//.
-#define COBALT_VERSION "22.lts.2"
+#define COBALT_VERSION "22.lts.3"
#endif // COBALT_VERSION_H_
diff --git a/src/components/prefs/pref_service.cc b/src/components/prefs/pref_service.cc
index 624a78f..a59c614 100644
--- a/src/components/prefs/pref_service.cc
+++ b/src/components/prefs/pref_service.cc
@@ -97,6 +97,9 @@
user_pref_store_(std::move(user_prefs)),
read_error_callback_(std::move(read_error_callback)),
pref_registry_(std::move(pref_registry)) {
+#if defined(STARBOARD)
+ LOG(INFO) << "PrefService::PrefService";
+#endif
pref_notifier_->SetPrefService(this);
DCHECK(pref_registry_);
@@ -106,6 +109,9 @@
}
PrefService::~PrefService() {
+#if defined(STARBOARD)
+ LOG(INFO) << "PrefService::~PrefService";
+#endif
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// TODO(crbug.com/942491, 946668, 945772) The following code collects
diff --git a/src/components/update_client/cobalt_slot_management.cc b/src/components/update_client/cobalt_slot_management.cc
index cc8856e..0c601d7 100644
--- a/src/components/update_client/cobalt_slot_management.cc
+++ b/src/components/update_client/cobalt_slot_management.cc
@@ -14,6 +14,8 @@
#include "components/update_client/cobalt_slot_management.h"
+#include <vector>
+
#include "base/values.h"
#include "cobalt/updater/utils.h"
#include "components/update_client/utils.h"
@@ -29,9 +31,9 @@
std::string bad_app_key_file_path =
starboard::loader_app::GetBadAppKeyFilePath(installation_path, app_key);
SB_DCHECK(!bad_app_key_file_path.empty());
- SB_LOG(INFO) << "bad_app_key_file_path: " << bad_app_key_file_path;
- SB_LOG(INFO) << "bad_app_key_file_path SbFileExists: "
- << SbFileExists(bad_app_key_file_path.c_str());
+ LOG(INFO) << "bad_app_key_file_path: " << bad_app_key_file_path;
+ LOG(INFO) << "bad_app_key_file_path SbFileExists: "
+ << SbFileExists(bad_app_key_file_path.c_str());
return !bad_app_key_file_path.empty() &&
SbFileExists(bad_app_key_file_path.c_str());
}
@@ -41,21 +43,21 @@
bool CobaltSlotManagement::Init(
const CobaltExtensionInstallationManagerApi* installation_api) {
- SB_LOG(INFO) << "CobaltSlotManagement::Init";
+ LOG(INFO) << "CobaltSlotManagement::Init";
installation_api_ = installation_api;
// Make sure the index is reset
installation_index_ = IM_EXT_INVALID_INDEX;
if (!installation_api_) {
- SB_LOG(ERROR) << "Failed to get installation manager";
+ LOG(ERROR) << "Failed to get installation manager";
return false;
}
char app_key[IM_EXT_MAX_APP_KEY_LENGTH];
if (installation_api_->GetAppKey(app_key, IM_EXT_MAX_APP_KEY_LENGTH) ==
IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Failed to get app key.";
+ LOG(ERROR) << "Failed to get app key.";
return false;
}
app_key_ = app_key;
@@ -64,10 +66,10 @@
bool CobaltSlotManagement::SelectSlot(base::FilePath* dir) {
SB_DCHECK(installation_api_);
- SB_LOG(INFO) << "CobaltSlotManagement::SelectSlot";
+ LOG(INFO) << "CobaltSlotManagement::SelectSlot";
int max_slots = installation_api_->GetMaxNumberInstallations();
if (max_slots == IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Failed to get max number of slots";
+ LOG(ERROR) << "Failed to get max number of slots";
return false;
}
@@ -78,14 +80,14 @@
// Iterate over all writeable slots - index >= 1.
for (int i = 1; i < max_slots; i++) {
- SB_LOG(INFO) << "CobaltSlotManagement::SelectSlot iterating slot=" << i;
+ LOG(INFO) << "CobaltSlotManagement::SelectSlot iterating slot=" << i;
std::vector<char> installation_path(kSbFileMaxPath);
if (installation_api_->GetInstallationPath(i, installation_path.data(),
installation_path.size()) ==
IM_EXT_ERROR) {
- SB_LOG(ERROR) << "CobaltSlotManagement::SelectSlot: Failed to get "
- "installation path for slot="
- << i;
+ LOG(ERROR) << "CobaltSlotManagement::SelectSlot: Failed to get "
+ "installation path for slot="
+ << i;
continue;
}
@@ -103,31 +105,29 @@
base::Version version =
cobalt::updater::ReadEvergreenVersion(installation_dir);
if (!version.IsValid()) {
- SB_LOG(INFO)
- << "CobaltSlotManagement::SelectSlot installed version invalid";
+ LOG(INFO) << "CobaltSlotManagement::SelectSlot installed version invalid";
if (!DrainFileDraining(installation_dir.value().c_str(), "")) {
- SB_LOG(INFO) << "CobaltSlotManagement::SelectSlot not draining";
+ LOG(INFO) << "CobaltSlotManagement::SelectSlot not draining";
// Found empty slot.
slot_candidate = i;
slot_candidate_path = installation_dir;
break;
} else {
// There is active draining from another updater so bail out.
- SB_LOG(ERROR) << "CobaltSlotManagement::SelectSlot bailing out";
+ LOG(ERROR) << "CobaltSlotManagement::SelectSlot bailing out";
return false;
}
} else if ((!slot_candidate_version.IsValid() ||
slot_candidate_version > version)) {
if (!DrainFileDraining(installation_dir.value().c_str(), "")) {
// Found a slot with older version that's not draining.
- SB_LOG(INFO) << "CobaltSlotManagement::SelectSlot slot candidate: "
- << i;
+ LOG(INFO) << "CobaltSlotManagement::SelectSlot slot candidate: " << i;
slot_candidate_version = version;
slot_candidate = i;
slot_candidate_path = installation_dir;
} else {
// There is active draining from another updater so bail out.
- SB_LOG(ERROR) << "CobaltSlotManagement::SelectSlot bailing out";
+ LOG(ERROR) << "CobaltSlotManagement::SelectSlot bailing out";
return false;
}
}
@@ -138,7 +138,7 @@
if (installation_index_ == -1 ||
!DrainFileTryDrain(dir->value().c_str(), app_key_.c_str())) {
- SB_LOG(ERROR)
+ LOG(ERROR)
<< "CobaltSlotManagement::SelectSlot unable to find a slot, candidate="
<< installation_index_;
return false;
@@ -148,19 +148,19 @@
bool CobaltSlotManagement::ConfirmSlot(const base::FilePath& dir) {
SB_DCHECK(installation_api_);
- SB_LOG(INFO) << "CobaltSlotManagement::ConfirmSlot ";
+ LOG(INFO) << "CobaltSlotManagement::ConfirmSlot ";
if (!DrainFileRankAndCheck(dir.value().c_str(), app_key_.c_str())) {
- SB_LOG(INFO) << "CobaltSlotManagement::ConfirmSlot: failed to lock slot ";
+ LOG(INFO) << "CobaltSlotManagement::ConfirmSlot: failed to lock slot ";
return false;
}
// TODO: Double check the installed_version.
// Use the installation slot
- SB_LOG(INFO) << "Resetting the slot: " << installation_index_;
+ LOG(INFO) << "Resetting the slot: " << installation_index_;
if (installation_api_->ResetInstallation(installation_index_) ==
IM_EXT_ERROR) {
- SB_LOG(INFO) << "CobaltSlotManagement::ConfirmSlot: failed to reset slot ";
+ LOG(INFO) << "CobaltSlotManagement::ConfirmSlot: failed to reset slot ";
return false;
}
@@ -189,13 +189,13 @@
starboard::loader_app::GetGoodAppKeyFilePath(dir, app_key);
SB_CHECK(!good_app_key_file_path.empty());
if (!starboard::loader_app::CreateAppKeyFile(good_app_key_file_path)) {
- SB_LOG(WARNING) << "Failed to create good app key file";
+ LOG(WARNING) << "Failed to create good app key file";
}
DrainFileRemove(dir.c_str(), app_key.c_str());
int ret =
installation_api->RequestRollForwardToInstallation(installation_index);
if (ret == IM_EXT_ERROR) {
- SB_LOG(ERROR) << "Failed to request roll forward.";
+ LOG(ERROR) << "Failed to request roll forward.";
return false;
}
return true;
@@ -210,13 +210,13 @@
char app_key[IM_EXT_MAX_APP_KEY_LENGTH];
if (installation_api->GetAppKey(app_key, IM_EXT_MAX_APP_KEY_LENGTH) ==
IM_EXT_ERROR) {
- SB_LOG(ERROR) << "CobaltQuickUpdate: Failed to get app key.";
+ LOG(ERROR) << "CobaltQuickUpdate: Failed to get app key.";
return true;
}
int max_slots = installation_api->GetMaxNumberInstallations();
if (max_slots == IM_EXT_ERROR) {
- SB_LOG(ERROR) << "CobaltQuickUpdate: Failed to get max number of slots.";
+ LOG(ERROR) << "CobaltQuickUpdate: Failed to get max number of slots.";
return true;
}
@@ -227,14 +227,14 @@
// Iterate over all writeable slots - index >= 1.
for (int i = 1; i < max_slots; i++) {
- SB_LOG(INFO) << "CobaltQuickInstallation: iterating slot=" << i;
+ LOG(INFO) << "CobaltQuickInstallation: iterating slot=" << i;
// Get the path to new installation.
std::vector<char> installation_path(kSbFileMaxPath);
if (installation_api->GetInstallationPath(i, installation_path.data(),
installation_path.size()) ==
IM_EXT_ERROR) {
- SB_LOG(ERROR) << "CobaltQuickInstallation: Failed to get "
- << "installation path for slot=" << i;
+ LOG(ERROR) << "CobaltQuickInstallation: Failed to get "
+ << "installation path for slot=" << i;
continue;
}
@@ -248,7 +248,7 @@
cobalt::updater::ReadEvergreenVersion(installation_dir);
if (!installed_version.IsValid()) {
- SB_LOG(WARNING) << "CobaltQuickInstallation: invalid version ";
+ LOG(WARNING) << "CobaltQuickInstallation: invalid version ";
continue;
} else if (slot_candidate_version < installed_version &&
current_version < installed_version &&
@@ -260,7 +260,7 @@
// draining, and no bad file of current app exists, and a good file
// exists. The final candidate is the newest version of the valid
// candidates.
- SB_LOG(INFO) << "CobaltQuickInstallation: slot candidate: " << i;
+ LOG(INFO) << "CobaltQuickInstallation: slot candidate: " << i;
slot_candidate_version = installed_version;
slot_candidate = i;
}
@@ -269,11 +269,11 @@
if (slot_candidate != -1) {
if (installation_api->RequestRollForwardToInstallation(slot_candidate) !=
IM_EXT_ERROR) {
- SB_LOG(INFO) << "CobaltQuickInstallation: quick update succeeded.";
+ LOG(INFO) << "CobaltQuickInstallation: quick update succeeded.";
return true;
}
}
- SB_LOG(WARNING) << "CobaltQuickInstallation: quick update failed.";
+ LOG(WARNING) << "CobaltQuickInstallation: quick update failed.";
return false;
}
diff --git a/src/components/update_client/cobalt_slot_management_test.cc b/src/components/update_client/cobalt_slot_management_test.cc
index f12f060..55256de 100644
--- a/src/components/update_client/cobalt_slot_management_test.cc
+++ b/src/components/update_client/cobalt_slot_management_test.cc
@@ -149,7 +149,7 @@
base::FilePath dir;
cobalt_slot_management.SelectSlot(&dir);
ASSERT_TRUE(DrainFileDraining(dir.value().c_str(), kTestAppKey1));
- SB_LOG(INFO) << "dir=" << dir;
+ LOG(INFO) << "dir=" << dir;
ASSERT_TRUE(base::EndsWith(dir.value(), "installation_2",
base::CompareCase::SENSITIVE));
@@ -169,7 +169,7 @@
ASSERT_TRUE(cobalt_slot_management.Init(api_));
base::FilePath dir;
ASSERT_TRUE(cobalt_slot_management.SelectSlot(&dir));
- SB_LOG(INFO) << "dir=" << dir;
+ LOG(INFO) << "dir=" << dir;
ASSERT_TRUE(base::EndsWith(dir.value(), "installation_1",
base::CompareCase::SENSITIVE));
diff --git a/src/components/update_client/component.cc b/src/components/update_client/component.cc
index 421dc40..d9158fc 100644
--- a/src/components/update_client/component.cc
+++ b/src/components/update_client/component.cc
@@ -15,6 +15,9 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
+#if defined(STARBOARD)
+#include "base/threading/thread_id_name_manager.h"
+#endif
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "components/update_client/action_runner.h"
@@ -81,6 +84,10 @@
InstallOnBlockingTaskRunnerCompleteCallback callback,
const base::FilePath& unpack_path,
const CrxInstaller::Result& result) {
+#if defined(STARBOARD)
+ LOG(INFO) << "InstallComplete thread_name="
+ << base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
+#endif
base::PostTaskWithTraits(
FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()},
base::BindOnce(
@@ -88,7 +95,10 @@
InstallOnBlockingTaskRunnerCompleteCallback callback,
const base::FilePath& unpack_path,
const CrxInstaller::Result& result) {
-
+#if defined(STARBOARD)
+ LOG(INFO) << "Closure kicked off from InstallComplete thread_name="
+ << base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
+#endif
// For Cobalt, don't delete the unpack_path, which is not a temp directory.
// Cobalt uses a dedicated installation slot obtained from the Installation
// Manager.
@@ -117,6 +127,11 @@
InstallOnBlockingTaskRunnerCompleteCallback callback) {
DCHECK(base::DirectoryExists(unpack_path));
+#if defined(STARBOARD)
+ LOG(INFO) << "InstallOnBlockingTaskRunner thread_name="
+ << base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
+#endif
+
#if !defined(STARBOARD)
// Acquire the ownership of the |unpack_path|.
base::ScopedTempDir unpack_path_owner;
@@ -141,11 +156,11 @@
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_api) {
- SB_LOG(ERROR) << "Failed to get installation manager api.";
+ LOG(ERROR) << "Failed to get installation manager api.";
// TODO: add correct error code.
install_error = InstallError::GENERIC_ERROR;
} else if (installation_index == IM_EXT_INVALID_INDEX) {
- SB_LOG(ERROR) << "Installation index is invalid.";
+ LOG(ERROR) << "Installation index is invalid.";
// TODO: add correct error code.
install_error = InstallError::GENERIC_ERROR;
} else {
@@ -187,8 +202,9 @@
scoped_refptr<CrxInstaller> installer,
InstallOnBlockingTaskRunnerCompleteCallback callback,
const ComponentUnpacker::Result& result) {
-
#if defined(STARBOARD)
+ LOG(INFO) << "UnpackCompleteOnBlockingTaskRunner thread_name="
+ << base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
base::DeleteFile(crx_path, false);
#else
update_client::DeleteFileAndEmptyParentDirectory(crx_path);
@@ -245,6 +261,10 @@
scoped_refptr<Patcher> patcher_,
crx_file::VerifierFormat crx_format,
InstallOnBlockingTaskRunnerCompleteCallback callback) {
+#if defined(STARBOARD)
+ LOG(INFO) << "StartInstallOnBlockingTaskRunner thread_name="
+ << base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
+#endif
auto unpacker = base::MakeRefCounted<ComponentUnpacker>(
pk_hash, crx_path, installer, std::move(unzipper_), std::move(patcher_),
crx_format);
@@ -274,9 +294,17 @@
Component::Component(const UpdateContext& update_context, const std::string& id)
: id_(id),
state_(std::make_unique<StateNew>(this)),
- update_context_(update_context) {}
+ update_context_(update_context) {
+#if defined(STARBOARD)
+ LOG(INFO) << "Component::Component";
+#endif
+}
-Component::~Component() {}
+Component::~Component() {
+#if defined(STARBOARD)
+ LOG(INFO) << "Component::~Component";
+#endif
+}
scoped_refptr<Configurator> Component::config() const {
return update_context_.config;
@@ -293,7 +321,9 @@
void Component::Handle(CallbackHandleComplete callback_handle_complete) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(state_);
-
+#if defined(STARBOARD)
+ LOG(INFO) << "Component::Handle";
+#endif
callback_handle_complete_ = std::move(callback_handle_complete);
state_->Handle(
@@ -309,6 +339,10 @@
void Component::ChangeState(std::unique_ptr<State> next_state) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "Component::ChangeState next_state="
+ << ((next_state)? next_state->state_name(): "nullptr");
+#endif
previous_state_ = state();
if (next_state)
@@ -533,6 +567,9 @@
void Component::State::Handle(CallbackNextState callback_next_state) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "Component::State::Handle";
+#endif
callback_next_state_ = std::move(callback_next_state);
@@ -542,7 +579,7 @@
#if defined(STARBOARD)
void Component::State::Cancel() {
DCHECK(thread_checker_.CalledOnValidThread());
- // Further work may be needed to ensure cancelation during any state results
+ // Further work may be needed to ensure cancellation during any state results
// in a clear result and no memory leaks.
}
#endif
@@ -550,6 +587,10 @@
void Component::State::TransitionState(std::unique_ptr<State> next_state) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(next_state);
+#if defined(STARBOARD)
+ LOG(INFO) << "Component::State::TransitionState next_state="
+ << ((next_state)? next_state->state_name(): "nullptr");
+#endif
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -628,7 +669,7 @@
base::Unretained(metadata), component.id_,
config->GetChannel()));
} else {
- SB_LOG(WARNING) << "Failed to get the persisted data store to write the "
+ LOG(WARNING) << "Failed to get the persisted data store to write the "
"updater channel.";
}
#endif
@@ -972,6 +1013,10 @@
}
void Component::StateUpdating::DoHandle() {
+#if defined(STARBOARD)
+ LOG(INFO) << "Component::StateUpdating::DoHandle() thread_name="
+ << base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
+#endif
DCHECK(thread_checker_.CalledOnValidThread());
const auto& component = Component::State::component();
diff --git a/src/components/update_client/component.h b/src/components/update_client/component.h
index f6cc035..83b8a35 100644
--- a/src/components/update_client/component.h
+++ b/src/components/update_client/component.h
@@ -169,6 +169,41 @@
ComponentState state() const { return state_; }
+#if defined(STARBOARD)
+ std::string state_name() {
+ switch (state_) {
+ case ComponentState::kNew:
+ return "New";
+ case ComponentState::kChecking:
+ return "Checking";
+ case ComponentState::kCanUpdate:
+ return "CanUpdate";
+ case ComponentState::kDownloadingDiff:
+ return "DownloadingDiff";
+ case ComponentState::kDownloading:
+ return "Downloaded";
+ case ComponentState::kUpdatingDiff:
+ return "UpdatingDiff";
+ case ComponentState::kUpdating:
+ return "Updating";
+ case ComponentState::kUpdated:
+ return "Updated";
+ case ComponentState::kUpToDate:
+ return "UpToDate";
+ case ComponentState::kUpdateError:
+ return "UpdateError";
+ case ComponentState::kUninstalled:
+ return "Uninstalled";
+ case ComponentState::kRun:
+ return "Run";
+ case ComponentState::kLastStatus:
+ return "LastStatus";
+ default:
+ return "Unknown";
+ }
+ }
+#endif
+
protected:
// Initiates the transition to the new state.
void TransitionState(std::unique_ptr<State> new_state);
diff --git a/src/components/update_client/component_unpacker.cc b/src/components/update_client/component_unpacker.cc
index 15dbf50..f76cb6a 100644
--- a/src/components/update_client/component_unpacker.cc
+++ b/src/components/update_client/component_unpacker.cc
@@ -72,7 +72,7 @@
result != crx_file::VerifierResult::OK_DELTA) {
error_ = UnpackerError::kInvalidFile;
extended_error_ = static_cast<int>(result);
- SB_LOG(INFO) << "Verification failed. Verifier error = " << extended_error_;
+ LOG(INFO) << "Verification failed. Verifier error = " << extended_error_;
return false;
}
is_delta_ = result == crx_file::VerifierResult::OK_DELTA;
diff --git a/src/components/update_client/crx_downloader.cc b/src/components/update_client/crx_downloader.cc
index 8f2bffa..fb18952 100644
--- a/src/components/update_client/crx_downloader.cc
+++ b/src/components/update_client/crx_downloader.cc
@@ -12,6 +12,9 @@
#include "base/logging.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
+#if defined(STARBOARD)
+#include "base/threading/thread_id_name_manager.h"
+#endif
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#if defined(OS_WIN)
@@ -60,9 +63,17 @@
CrxDownloader::CrxDownloader(std::unique_ptr<CrxDownloader> successor)
: main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- successor_(std::move(successor)) {}
+ successor_(std::move(successor)) {
+#if defined(STARBOARD)
+ LOG(INFO) << "CrxDownloader::CrxDownloader";
+#endif
+}
-CrxDownloader::~CrxDownloader() {}
+CrxDownloader::~CrxDownloader() {
+#if defined(STARBOARD)
+ LOG(INFO) << "CrxDownloader::~CrxDownloader";
+#endif
+}
void CrxDownloader::set_progress_callback(
const ProgressCallback& progress_callback) {
@@ -87,6 +98,9 @@
void CrxDownloader::StartDownloadFromUrl(const GURL& url,
const std::string& expected_hash,
DownloadCallback download_callback) {
+#if defined(STARBOARD)
+ LOG(INFO) << "CrxDownloader::StartDownloadFromUrl: url=" << url;
+#endif
std::vector<GURL> urls;
urls.push_back(url);
StartDownload(urls, expected_hash, std::move(download_callback));
@@ -122,6 +136,7 @@
#if defined(STARBOARD)
void CrxDownloader::CancelDownload() {
+ LOG(INFO) << "CrxDownloader::CancelDownload";
DoCancelDownload();
}
#endif
@@ -131,7 +146,9 @@
const Result& result,
const DownloadMetrics& download_metrics) {
DCHECK(thread_checker_.CalledOnValidThread());
-
+#if defined(STARBOARD)
+ LOG(INFO) << "CrxDownloader::OnDownloadComplete";
+#endif
if (!result.error)
base::PostTaskWithTraits(
FROM_HERE, kTaskTraits,
@@ -161,7 +178,10 @@
DCHECK_EQ(0, result.error);
DCHECK_EQ(0, download_metrics.error);
DCHECK(is_handled);
-
+#if defined(STARBOARD)
+ LOG(INFO) << "CrxDownloader::VerifyResponse thread_name="
+ << base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
+#endif
if (VerifyFileHash256(result.response, expected_hash_)) {
download_metrics_.push_back(download_metrics);
main_task_runner()->PostTask(
@@ -196,6 +216,10 @@
DCHECK(result.response.empty());
DCHECK_NE(0, download_metrics.error);
+#if defined(STARBOARD)
+ LOG(INFO) << "CrxDownloader::HandleDownloadError";
+#endif
+
download_metrics_.push_back(download_metrics);
#if defined(STARBOARD)
diff --git a/src/components/update_client/crx_downloader_unittest.cc b/src/components/update_client/crx_downloader_unittest.cc
index e0cb5f9..1ff4634 100644
--- a/src/components/update_client/crx_downloader_unittest.cc
+++ b/src/components/update_client/crx_downloader_unittest.cc
@@ -22,6 +22,7 @@
#include "components/update_client/utils.h"
#include "net/base/net_errors.h"
#if defined(STARBOARD)
+#include "components/update_client/test_configurator.h"
#include "net/url_request/test_url_request_interceptor.h"
#include "net/url_request/url_request_test_util.h"
#else
@@ -72,17 +73,20 @@
void DownloadProgress(int crx_context);
+#if !defined(STARBOARD)
int GetInterceptorCount() { return interceptor_count_; }
void AddResponse(const GURL& url,
const base::FilePath& file_path,
int net_error);
-
+#endif
protected:
std::unique_ptr<CrxDownloader> crx_downloader_;
-
+#if defined(STARBOARD)
+ std::unique_ptr<GetInterceptor> get_interceptor_;
+#else
network::TestURLLoaderFactory test_url_loader_factory_;
-
+#endif
CrxDownloader::DownloadCallback callback_;
CrxDownloader::ProgressCallback progress_callback_;
@@ -94,16 +98,22 @@
// These members are updated by DownloadProgress.
int num_progress_calls_;
+#if !defined(STARBOARD)
// Accumulates the number of loads triggered.
int interceptor_count_ = 0;
+#endif
// A magic value for the context to be used in the tests.
static const int kExpectedContext = 0xaabb;
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
+#if defined(STARBOARD)
+ scoped_refptr<net::TestURLRequestContextGetter> context_;
+#else
scoped_refptr<network::SharedURLLoaderFactory>
test_shared_url_loader_factory_;
+#endif
base::OnceClosure quit_closure_;
};
@@ -121,18 +131,40 @@
num_progress_calls_(0),
scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::IO),
+#if defined(STARBOARD)
+ context_(base::MakeRefCounted<net::TestURLRequestContextGetter>(
+ base::ThreadTaskRunnerHandle::Get())) {
+}
+
+CrxDownloaderTest::~CrxDownloaderTest() {
+ context_ = nullptr;
+
+ // The GetInterceptor requires the message loop to run to destruct correctly.
+ get_interceptor_.reset();
+ RunThreadsUntilIdle();
+}
+#else
test_shared_url_loader_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- &test_url_loader_factory_)) {}
+ &test_url_loader_factory_)) {
+}
CrxDownloaderTest::~CrxDownloaderTest() {}
-
+#endif
void CrxDownloaderTest::SetUp() {
num_download_complete_calls_ = 0;
download_complete_result_ = CrxDownloader::Result();
num_progress_calls_ = 0;
- // Do not use the background downloader in these tests.
+// Do not use the background downloader in these tests.
+#if defined(STARBOARD)
+ auto config = base::MakeRefCounted<TestConfigurator>();
+ crx_downloader_ = CrxDownloader::Create(false, config);
+ crx_downloader_->set_progress_callback(progress_callback_);
+
+ get_interceptor_ = std::make_unique<GetInterceptor>(
+ base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get());
+#else
crx_downloader_ = CrxDownloader::Create(
false, base::MakeRefCounted<NetworkFetcherChromiumFactory>(
test_shared_url_loader_factory_));
@@ -140,6 +172,7 @@
test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
[&](const network::ResourceRequest& request) { interceptor_count_++; }));
+#endif
}
void CrxDownloaderTest::TearDown() {
@@ -162,7 +195,7 @@
void CrxDownloaderTest::DownloadProgress(int crx_context) {
++num_progress_calls_;
}
-
+#if !defined(STARBOARD)
void CrxDownloaderTest::AddResponse(const GURL& url,
const base::FilePath& file_path,
int net_error) {
@@ -182,7 +215,7 @@
url, network::ResourceResponseHead(), std::string(),
network::URLLoaderCompletionStatus(net_error));
}
-
+#endif
void CrxDownloaderTest::RunThreads() {
base::RunLoop runloop;
quit_closure_ = runloop.QuitClosure();
@@ -236,14 +269,19 @@
GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+ get_interceptor_->SetResponse(expected_crx_url, test_file);
+#else
AddResponse(expected_crx_url, test_file, net::OK);
-
+#endif
crx_downloader_->StartDownloadFromUrl(
expected_crx_url, std::string(hash_jebg), std::move(callback_));
RunThreads();
-
+#if defined(STARBOARD)
+ EXPECT_EQ(1, get_interceptor_->GetHitCount());
+#else
EXPECT_EQ(1, GetInterceptorCount());
-
+#endif
EXPECT_EQ(1, num_download_complete_calls_);
EXPECT_EQ(kExpectedContext, crx_context_);
EXPECT_EQ(0, download_complete_result_.error);
@@ -262,17 +300,22 @@
GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+ get_interceptor_->SetResponse(expected_crx_url, test_file);
+#else
AddResponse(expected_crx_url, test_file, net::OK);
-
+#endif
crx_downloader_->StartDownloadFromUrl(
expected_crx_url,
std::string(
"813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9"),
std::move(callback_));
RunThreads();
-
+#if defined(STARBOARD)
+ EXPECT_EQ(1, get_interceptor_->GetHitCount());
+#else
EXPECT_EQ(1, GetInterceptorCount());
-
+#endif
EXPECT_EQ(1, num_download_complete_calls_);
EXPECT_EQ(kExpectedContext, crx_context_);
EXPECT_EQ(static_cast<int>(CrxDownloaderError::BAD_HASH),
@@ -289,8 +332,11 @@
GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+ get_interceptor_->SetResponse(expected_crx_url, test_file);
+#else
AddResponse(expected_crx_url, test_file, net::OK);
-
+#endif
std::vector<GURL> urls;
urls.push_back(expected_crx_url);
urls.push_back(expected_crx_url);
@@ -299,8 +345,11 @@
std::move(callback_));
RunThreads();
+#if defined(STARBOARD)
+ EXPECT_EQ(1, get_interceptor_->GetHitCount());
+#else
EXPECT_EQ(1, GetInterceptorCount());
-
+#endif
EXPECT_EQ(1, num_download_complete_calls_);
EXPECT_EQ(kExpectedContext, crx_context_);
EXPECT_EQ(0, download_complete_result_.error);
@@ -320,9 +369,14 @@
GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc.crx");
const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+ get_interceptor_->SetResponse(expected_crx_url, test_file);
+ get_interceptor_->SetResponse(no_file_url,
+ base::FilePath(FILE_PATH_LITERAL("no-file")));
+#else
AddResponse(expected_crx_url, test_file, net::OK);
AddResponse(no_file_url, base::FilePath(), net::ERR_FILE_NOT_FOUND);
-
+#endif
std::vector<GURL> urls;
urls.push_back(no_file_url);
urls.push_back(expected_crx_url);
@@ -331,8 +385,11 @@
std::move(callback_));
RunThreads();
+#if defined(STARBOARD)
+ EXPECT_EQ(2, get_interceptor_->GetHitCount());
+#else
EXPECT_EQ(2, GetInterceptorCount());
-
+#endif
EXPECT_EQ(1, num_download_complete_calls_);
EXPECT_EQ(kExpectedContext, crx_context_);
EXPECT_EQ(0, download_complete_result_.error);
@@ -365,8 +422,14 @@
GURL("http://localhost/download/ihfokbkgjpifnbbojhneepfflplebdkc.crx");
const base::FilePath test_file(MakeTestFilePath(kTestFileName));
+#if defined(STARBOARD)
+ get_interceptor_->SetResponse(expected_crx_url, test_file);
+ get_interceptor_->SetResponse(no_file_url,
+ base::FilePath(FILE_PATH_LITERAL("no-file")));
+#else
AddResponse(expected_crx_url, test_file, net::OK);
AddResponse(no_file_url, base::FilePath(), net::ERR_FILE_NOT_FOUND);
+#endif
std::vector<GURL> urls;
urls.push_back(expected_crx_url);
@@ -376,8 +439,11 @@
std::move(callback_));
RunThreads();
+#if defined(STARBOARD)
+ EXPECT_EQ(1, get_interceptor_->GetHitCount());
+#else
EXPECT_EQ(1, GetInterceptorCount());
-
+#endif
EXPECT_EQ(1, num_download_complete_calls_);
EXPECT_EQ(kExpectedContext, crx_context_);
EXPECT_EQ(0, download_complete_result_.error);
@@ -396,7 +462,12 @@
const GURL expected_crx_url =
GURL("http://localhost/download/jebgalgnebhfojomionfpkfelancnnkf.crx");
+#if defined(STARBOARD)
+ get_interceptor_->SetResponse(expected_crx_url,
+ base::FilePath(FILE_PATH_LITERAL("no-file")));
+#else
AddResponse(expected_crx_url, base::FilePath(), net::ERR_FILE_NOT_FOUND);
+#endif
std::vector<GURL> urls;
urls.push_back(expected_crx_url);
@@ -406,8 +477,11 @@
std::move(callback_));
RunThreads();
+#if defined(STARBOARD)
+ EXPECT_EQ(2, get_interceptor_->GetHitCount());
+#else
EXPECT_EQ(2, GetInterceptorCount());
-
+#endif
EXPECT_EQ(1, num_download_complete_calls_);
EXPECT_EQ(kExpectedContext, crx_context_);
EXPECT_NE(0, download_complete_result_.error);
diff --git a/src/components/update_client/net/network_impl_cobalt.cc b/src/components/update_client/net/network_impl_cobalt.cc
index 02acd0f..feada05 100644
--- a/src/components/update_client/net/network_impl_cobalt.cc
+++ b/src/components/update_client/net/network_impl_cobalt.cc
@@ -53,7 +53,7 @@
}
// Returns the integral value of a header of the server response or -1 if
-// if the header is not available or a conversion error has occured.
+// if the header is not available or a conversion error has occurred.
int64_t GetInt64Header(const net::HttpResponseHeaders* headers,
const char* header_name) {
if (!headers) {
@@ -82,8 +82,8 @@
PostRequestCompleteCallback post_request_complete_callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- SB_LOG(INFO) << "PostRequest url = " << url;
- SB_LOG(INFO) << "PostRequest post_data = " << post_data;
+ LOG(INFO) << "PostRequest url = " << url;
+ LOG(INFO) << "PostRequest post_data = " << post_data;
response_started_callback_ = std::move(response_started_callback);
progress_callback_ = std::move(progress_callback);
@@ -114,8 +114,8 @@
DownloadToFileCompleteCallback download_to_file_complete_callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- SB_LOG(INFO) << "DownloadToFile url = " << url;
- SB_LOG(INFO) << "DownloadToFile file_path = " << file_path;
+ LOG(INFO) << "DownloadToFile url = " << url;
+ LOG(INFO) << "DownloadToFile file_path = " << file_path;
response_started_callback_ = std::move(response_started_callback);
progress_callback_ = std::move(progress_callback);
@@ -132,6 +132,13 @@
url_fetcher_->Start();
}
+void NetworkFetcherCobaltImpl::Cancel() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ LOG(INFO) << "Cancel";
+ url_fetcher_.reset();
+}
+
void NetworkFetcherCobaltImpl::OnURLFetchResponseStarted(
const net::URLFetcher* source) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
@@ -206,11 +213,10 @@
}
if (response_body->empty()) {
- SB_LOG(ERROR) << "PostRequest got empty response.";
+ LOG(ERROR) << "PostRequest got empty response.";
}
- SB_LOG(INFO) << "OnPostRequestComplete response_body = "
- << *response_body.get();
+ LOG(INFO) << "OnPostRequestComplete response_body = " << *response_body.get();
net::HttpResponseHeaders* response_headers = source->GetResponseHeaders();
std::move(post_request_complete_callback_)
@@ -226,9 +232,9 @@
const int status_error) {
base::FilePath response_file;
if (!source->GetResponseAsFilePath(true, &response_file)) {
- SB_LOG(ERROR) << "DownloadToFile failed to get response from a file";
+ LOG(ERROR) << "DownloadToFile failed to get response from a file";
}
- SB_LOG(INFO) << "OnDownloadToFileComplete response_file = " << response_file;
+ LOG(INFO) << "OnDownloadToFileComplete response_file = " << response_file;
std::move(download_to_file_complete_callback_)
.Run(response_file, status_error,
@@ -240,7 +246,7 @@
NetworkFetcherCobaltImpl::ReturnWrapper NetworkFetcherCobaltImpl::HandleError(
const std::string& message) {
url_fetcher_.reset();
- SB_LOG(ERROR) << message;
+ LOG(ERROR) << message;
return ReturnWrapper();
}
diff --git a/src/components/update_client/net/network_impl_cobalt.h b/src/components/update_client/net/network_impl_cobalt.h
index c30f3ad..742e8ea 100644
--- a/src/components/update_client/net/network_impl_cobalt.h
+++ b/src/components/update_client/net/network_impl_cobalt.h
@@ -71,6 +71,7 @@
ProgressCallback progress_callback,
DownloadToFileCompleteCallback
download_to_file_complete_callback) override;
+ void Cancel() override;
// net::URLFetcherDelegate interface.
void OnURLFetchResponseStarted(const net::URLFetcher* source) override;
diff --git a/src/components/update_client/network.h b/src/components/update_client/network.h
index dec108f..cf884b5 100644
--- a/src/components/update_client/network.h
+++ b/src/components/update_client/network.h
@@ -64,7 +64,7 @@
ProgressCallback progress_callback,
DownloadToFileCompleteCallback download_to_file_complete_callback) = 0;
#if defined(STARBOARD)
- virtual void CancelDownloadToFile() = 0;
+ virtual void Cancel() = 0;
#endif
protected:
diff --git a/src/components/update_client/ping_manager.cc b/src/components/update_client/ping_manager.cc
index 3c2a60c..25c2c25 100644
--- a/src/components/update_client/ping_manager.cc
+++ b/src/components/update_client/ping_manager.cc
@@ -32,6 +32,12 @@
const int kErrorNoEvents = -1;
const int kErrorNoUrl = -2;
+// When building for STARBOARD add the PingSender to the update_client namespace
+// as we keep a reference to it in PingManager.
+#if defined(STARBOARD)
+}
+#endif
+
// An instance of this class can send only one ping.
class PingSender : public base::RefCountedThreadSafe<PingSender> {
public:
@@ -39,6 +45,10 @@
explicit PingSender(scoped_refptr<Configurator> config);
void SendPing(const Component& component, Callback callback);
+#if defined(STARBOARD)
+ void Cancel();
+#endif
+
protected:
virtual ~PingSender();
@@ -66,6 +76,10 @@
void PingSender::SendPing(const Component& component, Callback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+#if defined(STARBOARD)
+ LOG(INFO) << "PingSender::SendPing";
+#endif
+
if (component.events().empty()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), kErrorNoEvents, ""));
@@ -103,27 +117,62 @@
false, base::BindOnce(&PingSender::SendPingComplete, this));
}
+#if defined(STARBOARD)
+void PingSender::Cancel() {
+ LOG(INFO) << "PingSender::Cancel";
+ if (request_sender_.get()) {
+ request_sender_->Cancel();
+ }
+}
+#endif
+
void PingSender::SendPingComplete(int error,
const std::string& response,
int retry_after_sec) {
+ LOG(INFO) << "PingSender::SendPingComplete";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
std::move(callback_).Run(error, response);
}
+#if !defined(STARBOARD)
} // namespace
+#endif
PingManager::PingManager(scoped_refptr<Configurator> config)
- : config_(config) {}
+ : config_(config) {
+#if defined(STARBOARD)
+ LOG(INFO) << "PingManager::PingManager";
+#endif
+}
+
+#if defined(STARBOARD)
+void PingManager::Cancel() {
+ LOG(INFO) << "PingManager::Cancel";
+ if (ping_sender_.get()) {
+ ping_sender_->Cancel();
+ }
+}
+#endif
PingManager::~PingManager() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+#if defined(STARBOARD)
+ LOG(INFO) << "PingManager::~PingManager";
+#endif
}
void PingManager::SendPing(const Component& component, Callback callback) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+#if defined(STARBOARD)
+ LOG(INFO) << "PingManager::SendPing";
+
+ ping_sender_ = base::MakeRefCounted<PingSender>(config_);
+ ping_sender_->SendPing(component, std::move(callback));
+#else
auto ping_sender = base::MakeRefCounted<PingSender>(config_);
ping_sender->SendPing(component, std::move(callback));
+#endif
}
} // namespace update_client
diff --git a/src/components/update_client/ping_manager.h b/src/components/update_client/ping_manager.h
index 24040e6..d049788 100644
--- a/src/components/update_client/ping_manager.h
+++ b/src/components/update_client/ping_manager.h
@@ -17,6 +17,10 @@
class Configurator;
class Component;
+#if defined(STARBOARD)
+class PingSender;
+#endif
+
class PingManager : public base::RefCountedThreadSafe<PingManager> {
public:
// |error| is 0 if the ping was sent successfully, otherwise |error| contains
@@ -31,6 +35,9 @@
// be discarded if it has not been sent for any reason.
virtual void SendPing(const Component& component, Callback callback);
+#if defined(STARBOARD)
+ virtual void Cancel();
+#endif
protected:
virtual ~PingManager();
@@ -40,6 +47,10 @@
THREAD_CHECKER(thread_checker_);
const scoped_refptr<Configurator> config_;
+#if defined(STARBOARD)
+ scoped_refptr<PingSender> ping_sender_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(PingManager);
};
diff --git a/src/components/update_client/request_sender.cc b/src/components/update_client/request_sender.cc
index a68df98..2f3d878 100644
--- a/src/components/update_client/request_sender.cc
+++ b/src/components/update_client/request_sender.cc
@@ -45,6 +45,9 @@
bool use_signing,
RequestSenderCallback request_sender_callback) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "RequestSender::Send";
+#endif
urls_ = urls;
request_extra_headers_ = request_extra_headers;
@@ -101,10 +104,22 @@
base::Unretained(this), url));
}
+#if defined(STARBOARD)
+void RequestSender::Cancel() {
+ LOG(INFO) << "RequestSender::Cancel";
+ if (network_fetcher_.get()) {
+ network_fetcher_->Cancel();
+ }
+}
+#endif
+
void RequestSender::SendInternalComplete(int error,
const std::string& response_body,
const std::string& response_etag,
int retry_after_sec) {
+#if defined(STARBOARD)
+ LOG(INFO) << "RequestSender::SendInternalComplete";
+#endif
if (!error) {
if (!use_signing_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -152,6 +167,9 @@
const std::string& header_etag,
int64_t xheader_retry_after_sec) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "RequestSender::OnNetworkFetcherComplete";
+#endif
VLOG(1) << "request completed from url: " << original_url.spec();
diff --git a/src/components/update_client/request_sender.h b/src/components/update_client/request_sender.h
index 7b9e21b..1936047 100644
--- a/src/components/update_client/request_sender.h
+++ b/src/components/update_client/request_sender.h
@@ -58,6 +58,10 @@
bool use_signing,
RequestSenderCallback request_sender_callback);
+#if defined(STARBOARD)
+ void Cancel();
+#endif
+
private:
// Combines the |url| and |query_params| parameters.
static GURL BuildUpdateUrl(const GURL& url, const std::string& query_params);
diff --git a/src/components/update_client/task_update.cc b/src/components/update_client/task_update.cc
index 0129e4c..b4894b7 100644
--- a/src/components/update_client/task_update.cc
+++ b/src/components/update_client/task_update.cc
@@ -22,14 +22,28 @@
is_foreground_(is_foreground),
ids_(ids),
crx_data_callback_(std::move(crx_data_callback)),
- callback_(std::move(callback)) {}
+ callback_(std::move(callback))
+#if defined(STARBOARD)
+ , is_completed_(false)
+#endif
+{
+#if defined(STARBOARD)
+ LOG(INFO) << "TaskUpdate::TaskUpdate";
+#endif
+}
TaskUpdate::~TaskUpdate() {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "TaskUpdate::~TaskUpdate";
+#endif
}
void TaskUpdate::Run() {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "TaskUpdate::Run begin";
+#endif
if (ids_.empty()) {
TaskComplete(Error::INVALID_ARGUMENT);
@@ -40,16 +54,19 @@
update_engine_->Update(is_foreground_, ids_, std::move(crx_data_callback_),
base::BindOnce(&TaskUpdate::TaskComplete, this),
cancelation_closure_);
+ LOG(INFO) << "TaskUpdate::Run end";
#else
update_engine_->Update(is_foreground_, ids_, std::move(crx_data_callback_),
base::BindOnce(&TaskUpdate::TaskComplete, this));
#endif
+
}
void TaskUpdate::Cancel() {
DCHECK(thread_checker_.CalledOnValidThread());
#if defined(STARBOARD)
+ LOG(INFO) << "TaskUpdate::Cancel";
if (cancelation_closure_) { // The engine's picked up the task.
std::move(cancelation_closure_).Run();
}
@@ -64,6 +81,18 @@
void TaskUpdate::TaskComplete(Error error) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "TaskUpdate::TaskComplete";
+
+ // The callback is defined as OnceCallback and should not
+ // be called multiple times.
+ if(is_completed_) {
+ LOG(INFO) << "TaskUpdate::TaskComplete already called";
+ return;
+ }
+
+ is_completed_ = true;
+#endif
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback_),
diff --git a/src/components/update_client/task_update.h b/src/components/update_client/task_update.h
index 74c0a6a..2697c35 100644
--- a/src/components/update_client/task_update.h
+++ b/src/components/update_client/task_update.h
@@ -59,6 +59,7 @@
Callback callback_;
#if defined(STARBOARD)
base::OnceClosure cancelation_closure_;
+ bool is_completed_;
#endif
DISALLOW_COPY_AND_ASSIGN(TaskUpdate);
diff --git a/src/components/update_client/test_configurator.h b/src/components/update_client/test_configurator.h
index c3fbda1..6a9e5eb 100644
--- a/src/components/update_client/test_configurator.h
+++ b/src/components/update_client/test_configurator.h
@@ -85,7 +85,7 @@
public:
TestConfigurator();
- // Overrrides for Configurator.
+ // Overrides for Configurator.
int InitialDelay() const override;
int NextCheckDelay() const override;
int OnDemandDelay() const override;
@@ -127,8 +127,14 @@
void SetAppGuid(const std::string& app_guid);
#if defined(STARBOARD)
+ // TODO: add unit tests for updater channels and status
void SetChannel(const std::string& channel) override {}
void CompareAndSwapChannelChanged(int old_value, int new_value) override {}
+ std::string GetUpdaterStatus() const override { return ""; }
+ void SetUpdaterStatus(const std::string& status) override {}
+
+ std::string GetPreviousUpdaterStatus() const override { return ""; }
+ void SetPreviousUpdaterStatus(const std::string& status) override {}
#else
network::TestURLLoaderFactory* test_url_loader_factory() {
return &test_url_loader_factory_;
diff --git a/src/components/update_client/update_checker.cc b/src/components/update_client/update_checker.cc
index 1e7eed4..4951abf 100644
--- a/src/components/update_client/update_checker.cc
+++ b/src/components/update_client/update_checker.cc
@@ -20,6 +20,9 @@
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/threading/thread_checker.h"
+#if defined(STARBOARD)
+#include "base/threading/thread_id_name_manager.h"
+#endif
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#if defined(STARBOARD)
@@ -98,6 +101,9 @@
const IdToComponentPtrMap& components,
const base::flat_map<std::string, std::string>& additional_attributes,
bool enabled_component_updates);
+#if defined(STARBOARD)
+ void Cancel();
+#endif
void OnRequestSenderComplete(int error,
const std::string& response,
int retry_after_sec);
@@ -121,10 +127,17 @@
UpdateCheckerImpl::UpdateCheckerImpl(scoped_refptr<Configurator> config,
PersistedData* metadata)
- : config_(config), metadata_(metadata) {}
+ : config_(config), metadata_(metadata) {
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateCheckerImpl::UpdateCheckerImpl";
+#endif
+}
UpdateCheckerImpl::~UpdateCheckerImpl() {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateCheckerImpl::~UpdateCheckerImpl";
+#endif
}
void UpdateCheckerImpl::CheckForUpdates(
@@ -135,6 +148,9 @@
bool enabled_component_updates,
UpdateCheckCallback update_check_callback) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateCheckerImpl::CheckForUpdates";
+#endif
ids_checked_ = ids_checked;
update_check_callback_ = std::move(update_check_callback);
@@ -150,6 +166,11 @@
// This function runs on the blocking pool task runner.
void UpdateCheckerImpl::ReadUpdaterStateAttributes() {
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateCheckerImpl::ReadUpdaterStateAttributes current_thread="
+ << base::ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
+#endif
+
#if defined(OS_WIN)
// On Windows, the Chrome and the updater install modes are matched by design.
updater_state_attributes_ =
@@ -168,6 +189,9 @@
const base::flat_map<std::string, std::string>& additional_attributes,
bool enabled_component_updates) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateCheckerImpl::CheckForUpdatesHelper";
+#endif
auto urls(config_->UpdateUrl());
if (IsEncryptionRequired(components))
@@ -219,7 +243,7 @@
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_api) {
- SB_LOG(ERROR) << "Failed to get installation manager extension.";
+ LOG(ERROR) << "Failed to get installation manager extension.";
return;
}
@@ -274,6 +298,15 @@
#endif
}
+#if defined(STARBOARD)
+void UpdateCheckerImpl::Cancel() {
+ LOG(INFO) << "UpdateCheckerImpl::Cancel";
+ if (request_sender_.get()) {
+ request_sender_->Cancel();
+ }
+}
+#endif
+
void UpdateCheckerImpl::OnRequestSenderComplete(int error,
const std::string& response,
int retry_after_sec) {
diff --git a/src/components/update_client/update_checker.h b/src/components/update_client/update_checker.h
index 9a53357..78eb968 100644
--- a/src/components/update_client/update_checker.h
+++ b/src/components/update_client/update_checker.h
@@ -51,6 +51,10 @@
bool enabled_component_updates,
UpdateCheckCallback update_check_callback) = 0;
+#if defined(STARBOARD)
+ virtual void Cancel() = 0;
+#endif
+
static std::unique_ptr<UpdateChecker> Create(
scoped_refptr<Configurator> config,
PersistedData* persistent);
diff --git a/src/components/update_client/update_checker_unittest.cc b/src/components/update_client/update_checker_unittest.cc
index de84eb9..7905805 100644
--- a/src/components/update_client/update_checker_unittest.cc
+++ b/src/components/update_client/update_checker_unittest.cc
@@ -369,7 +369,7 @@
EXPECT_EQ(GURL("http://localhost/download/"), result.crx_urls.front());
EXPECT_STREQ("this", result.action_run.c_str());
- // Check the DDOS protection header values.
+// Check the DDOS protection header values.
#if defined(STARBOARD)
const auto extra_request_headers = post_interceptor_->GetRequests()[0].second;
#else
@@ -740,8 +740,12 @@
if (is_foreground_) {
{
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -758,8 +762,12 @@
EXPECT_FALSE(app.FindKey("installedby"));
}
{
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -783,8 +791,12 @@
DCHECK(!is_foreground_);
{
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -800,8 +812,12 @@
EXPECT_FALSE(app.FindKey("installsource"));
}
{
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -832,8 +848,12 @@
auto crx_component = component->crx_component();
{
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -853,8 +873,12 @@
{
crx_component->disabled_reasons = {};
component->set_crx_component(*crx_component);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -874,8 +898,12 @@
{
crx_component->disabled_reasons = {0};
component->set_crx_component(*crx_component);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -896,8 +924,12 @@
{
crx_component->disabled_reasons = {1};
component->set_crx_component(*crx_component);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -919,8 +951,12 @@
{
crx_component->disabled_reasons = {4, 8, 16};
component->set_crx_component(*crx_component);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -944,8 +980,12 @@
{
crx_component->disabled_reasons = {0, 4, 8, 16};
component->set_crx_component(*crx_component);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -987,8 +1027,12 @@
// Expects the group policy to be ignored and the update check to not
// include the "updatedisabled" attribute.
EXPECT_FALSE(crx_component->supports_group_policy_enable_component_updates);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -1013,8 +1057,12 @@
// Expects the update check to include the "updatedisabled" attribute.
crx_component->supports_group_policy_enable_component_updates = true;
component->set_crx_component(*crx_component);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -1039,8 +1087,12 @@
// Expects the update check to not include the "updatedisabled" attribute.
crx_component->supports_group_policy_enable_component_updates = false;
component->set_crx_component(*crx_component);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -1065,8 +1117,12 @@
// Expects the update check to not include the "updatedisabled" attribute.
crx_component->supports_group_policy_enable_component_updates = true;
component->set_crx_component(*crx_component);
+#if defined(STARBOARD)
+ auto post_interceptor = post_interceptor_;
+#else
auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
config_->test_url_loader_factory());
+#endif
EXPECT_TRUE(post_interceptor->ExpectRequest(
std::make_unique<PartialMatch>("updatecheck"),
test_file("updatecheck_reply_1.json")));
@@ -1221,7 +1277,7 @@
}
// The update response contains a status |error-unknownApplication| for the
-// app. The response is succesfully parsed and a result is extracted to
+// app. The response is successfully parsed and a result is extracted to
// indicate this status.
TEST_P(UpdateCheckerTest, ParseErrorAppStatusErrorUnknownApplication) {
EXPECT_TRUE(post_interceptor_->ExpectRequest(
diff --git a/src/components/update_client/update_client.cc b/src/components/update_client/update_client.cc
index 6ce65bf..0ba76cd 100644
--- a/src/components/update_client/update_client.cc
+++ b/src/components/update_client/update_client.cc
@@ -78,6 +78,10 @@
DCHECK(task_queue_.empty());
DCHECK(tasks_.empty());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateClientImpl::~UpdateClientImpl: task_queue_.size=" << task_queue_.size() << " tasks.size=" << tasks_.size();
+#endif
+
config_ = nullptr;
}
@@ -135,6 +139,10 @@
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(task);
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateClientImpl::OnTaskComplete";
+#endif
+
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), error));
diff --git a/src/components/update_client/update_client.gyp b/src/components/update_client/update_client.gyp
index 3b9edd7..6a15ed0 100644
--- a/src/components/update_client/update_client.gyp
+++ b/src/components/update_client/update_client.gyp
@@ -148,18 +148,19 @@
'sources': [
'component_unpacker_unittest.cc',
# TODO: enable the tests commented out
- # 'crx_downloader_unittest.cc',
+ 'crx_downloader_unittest.cc',
'persisted_data_unittest.cc',
'ping_manager_unittest.cc',
'protocol_parser_json_unittest.cc',
# 'protocol_serializer_json_unittest.cc',
'protocol_serializer_unittest.cc',
'request_sender_unittest.cc',
- # 'update_checker_unittest.cc',
+ 'update_checker_unittest.cc',
# 'update_client_unittest.cc',
'update_query_params_unittest.cc',
'updater_state_unittest.cc',
'utils_unittest.cc',
+ '<(DEPTH)/cobalt/updater/utils.cc',
],
'dependencies': [
'update_client',
diff --git a/src/components/update_client/update_engine.cc b/src/components/update_client/update_engine.cc
index 29c260b..9e39a0f 100644
--- a/src/components/update_client/update_engine.cc
+++ b/src/components/update_client/update_engine.cc
@@ -51,7 +51,11 @@
}
}
-UpdateContext::~UpdateContext() {}
+UpdateContext::~UpdateContext() {
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateContext::~UpdateContext";
+#endif
+}
UpdateEngine::UpdateEngine(
scoped_refptr<Configurator> config,
@@ -66,10 +70,17 @@
metadata_(
std::make_unique<PersistedData>(config->GetPrefService(),
config->GetActivityDataService())),
- notify_observers_callback_(notify_observers_callback) {}
+ notify_observers_callback_(notify_observers_callback) {
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::UpdateEngine";
+#endif
+}
UpdateEngine::~UpdateEngine() {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::~UpdateEngine";
+#endif
}
#if !defined(STARBOARD)
@@ -87,6 +98,10 @@
#endif
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::Update";
+#endif
+
if (ids.empty()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
@@ -169,6 +184,10 @@
DCHECK_EQ(1u, update_context->components.count(id));
DCHECK(update_context->components.at(id));
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::ComponentCheckingForUpdatesStart";
+#endif
+
// Handle |kChecking| state.
auto& component = *update_context->components.at(id);
component.Handle(
@@ -190,6 +209,10 @@
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(update_context);
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::DoUpdateCheck";
+#endif
+
update_context->update_checker =
update_checker_factory_(config_, metadata_.get());
@@ -211,6 +234,10 @@
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(update_context);
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::UpdateCheckResultsAvailable";
+#endif
+
update_context->retry_after_sec = retry_after_sec;
// Only positive values for throttle_sec are effective. 0 means that no
@@ -283,6 +310,10 @@
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(update_context);
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::ComponentCheckingForUpdatesComplete";
+#endif
+
++update_context->num_components_checked;
if (update_context->num_components_checked <
update_context->components_to_check_for_updates.size()) {
@@ -299,6 +330,10 @@
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(update_context);
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::UpdateCheckComplete";
+#endif
+
for (const auto& id : update_context->components_to_check_for_updates)
update_context->component_queue.push(id);
@@ -312,6 +347,10 @@
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(update_context);
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::HandleComponent";
+#endif
+
auto& queue = update_context->component_queue;
if (queue.empty()) {
@@ -354,6 +393,10 @@
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(update_context);
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::HandleComponentComplete";
+#endif
+
auto& queue = update_context->component_queue;
DCHECK(!queue.empty());
@@ -380,6 +423,10 @@
void UpdateEngine::UpdateComplete(scoped_refptr<UpdateContext> update_context,
Error error) {
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::UpdateComplete";
+#endif
+
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(update_context);
@@ -393,6 +440,9 @@
bool UpdateEngine::GetUpdateState(const std::string& id,
CrxUpdateItem* update_item) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::GetUpdateState";
+#endif
for (const auto& context : update_contexts_) {
const auto& components = context.second->components;
const auto it = components.find(id);
@@ -406,6 +456,9 @@
bool UpdateEngine::IsThrottled(bool is_foreground) const {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::IsThrottled";
+#endif
if (is_foreground || throttle_updates_until_.is_null())
return false;
@@ -421,7 +474,16 @@
#if defined(STARBOARD)
void UpdateEngine::Cancel(const std::string& update_context_session_id,
const std::vector<std::string>& crx_component_ids) {
+ LOG(INFO) << "UpdateEngine::Cancel";
+
+ if (ping_manager_.get()) {
+ ping_manager_->Cancel();
+ }
+
const auto& context = update_contexts_.at(update_context_session_id);
+ if (context->update_checker.get()) {
+ context->update_checker->Cancel();
+ }
for (const auto& crx_component_id : crx_component_ids) {
auto& component = context->components.at(crx_component_id);
component->Cancel();
@@ -435,6 +497,10 @@
Callback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
+#if defined(STARBOARD)
+ LOG(INFO) << "UpdateEngine::SendUninstallPing";
+#endif
+
const auto update_context = base::MakeRefCounted<UpdateContext>(
config_, false, std::vector<std::string>{id},
UpdateClient::CrxDataCallback(), UpdateEngine::NotifyObserversCallback(),
diff --git a/src/components/update_client/update_engine.h b/src/components/update_client/update_engine.h
index 4384fa8..1cd0ac9 100644
--- a/src/components/update_client/update_engine.h
+++ b/src/components/update_client/update_engine.h
@@ -109,7 +109,8 @@
#if defined(STARBOARD)
// Cancels updates currently handled by the engine for each component
// identified by one of |crx_component_ids| for the update context identified
- // by the |update_context_session_id|.
+ // by the |update_context_session_id|. Also cancels the |UpdateChecker| for
+ // the component and the |PingManager|.
void Cancel(const std::string& update_context_session_id,
const std::vector<std::string>& crx_component_ids);
#endif
diff --git a/src/components/update_client/url_fetcher_downloader.cc b/src/components/update_client/url_fetcher_downloader.cc
index 078c275..b5c13cc 100644
--- a/src/components/update_client/url_fetcher_downloader.cc
+++ b/src/components/update_client/url_fetcher_downloader.cc
@@ -71,7 +71,9 @@
scoped_refptr<Configurator> config)
: CrxDownloader(std::move(successor)),
config_(config),
- network_fetcher_factory_(config->GetNetworkFetcherFactory()) {}
+ network_fetcher_factory_(config->GetNetworkFetcherFactory()) {
+ LOG(INFO) << "UrlFetcherDownloader::UrlFetcherDownloader";
+}
#else
UrlFetcherDownloader::UrlFetcherDownloader(
std::unique_ptr<CrxDownloader> successor,
@@ -82,11 +84,14 @@
UrlFetcherDownloader::~UrlFetcherDownloader() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+#if defined(STARBOARD)
+ LOG(INFO) << "UrlFetcherDownloader::UrlFetcherDownloader";
+#endif
}
#if defined(STARBOARD)
void UrlFetcherDownloader::ConfirmSlot(const GURL& url) {
- SB_LOG(INFO) << "UrlFetcherDownloader::ConfirmSlot: url=" << url;
+ LOG(INFO) << "UrlFetcherDownloader::ConfirmSlot: url=" << url;
if (!cobalt_slot_management_.ConfirmSlot(download_dir_)) {
ReportDownloadFailure(url, CrxDownloaderError::SLOT_UNAVAILABLE);
return;
@@ -98,7 +103,7 @@
}
void UrlFetcherDownloader::SelectSlot(const GURL& url) {
- SB_LOG(INFO) << "UrlFetcherDownloader::SelectSlot: url=" << url;
+ LOG(INFO) << "UrlFetcherDownloader::SelectSlot: url=" << url;
if (!cobalt_slot_management_.SelectSlot(&download_dir_)) {
ReportDownloadFailure(url, CrxDownloaderError::SLOT_UNAVAILABLE);
return;
@@ -119,11 +124,13 @@
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
#if defined(STARBOARD)
+ LOG(INFO) << "UrlFetcherDownloader::DoStartDownload";
+
const CobaltExtensionInstallationManagerApi* installation_api =
static_cast<const CobaltExtensionInstallationManagerApi*>(
SbSystemGetExtension(kCobaltExtensionInstallationManagerName));
if (!installation_api) {
- SB_LOG(ERROR) << "Failed to get installation manager";
+ LOG(ERROR) << "Failed to get installation manager";
ReportDownloadFailure(url);
return;
}
@@ -146,8 +153,11 @@
#if defined(STARBOARD)
void UrlFetcherDownloader::DoCancelDownload() {
+ LOG(INFO) << "UrlFetcherDownloader::DoCancelDownload";
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- network_fetcher_->CancelDownloadToFile();
+ if (network_fetcher_.get()) {
+ network_fetcher_->Cancel();
+ }
}
#endif
@@ -158,6 +168,7 @@
#if defined(STARBOARD)
void UrlFetcherDownloader::ReportDownloadFailure(const GURL& url) {
+ LOG(INFO) << "UrlFetcherDownloader::ReportDownloadFailure";
ReportDownloadFailure(url, CrxDownloaderError::GENERIC_ERROR);
}
@@ -195,13 +206,13 @@
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
#if defined(STARBOARD)
- SB_LOG(INFO) << "UrlFetcherDownloader::StartURLFetch: url" << url
+ LOG(INFO) << "UrlFetcherDownloader::StartURLFetch: url" << url
<< " download_dir=" << download_dir_;
#endif
if (download_dir_.empty()) {
#if defined(STARBOARD)
- SB_LOG(ERROR) << "UrlFetcherDownloader::StartURLFetch: failed with empty "
+ LOG(ERROR) << "UrlFetcherDownloader::StartURLFetch: failed with empty "
"download_dir";
#endif
ReportDownloadFailure(url);
@@ -227,6 +238,10 @@
int64_t content_size) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+#if defined(STARBOARD)
+ LOG(INFO) << "UrlFetcherDownloader::OnNetworkFetcherComplete";
+#endif
+
const base::TimeTicks download_end_time(base::TimeTicks::Now());
const base::TimeDelta download_time =
download_end_time >= download_start_time_
@@ -299,6 +314,10 @@
int64_t content_length) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+#if defined(STARBOARD)
+ LOG(INFO) << "UrlFetcherDownloader::OnResponseStarted";
+#endif
+
VLOG(1) << "url fetcher response started for: " << final_url.spec();
final_url_ = final_url;
diff --git a/src/docker-compose.yml b/src/docker-compose.yml
index 2401d96..b3ef1ce 100644
--- a/src/docker-compose.yml
+++ b/src/docker-compose.yml
@@ -165,7 +165,6 @@
PLATFORM: linux-x64x11-clang-3-9
CONFIG: ${CONFIG:-debug}
USE_CCACHE: ${USE_CCACHE:-1}
- NINJA_STATUS: ${NINJA_STATUS}
# Define common build container for Android
build-android:
diff --git a/src/docker/linux/base/build/Dockerfile b/src/docker/linux/base/build/Dockerfile
index 0de107d..85cc781 100644
--- a/src/docker/linux/base/build/Dockerfile
+++ b/src/docker/linux/base/build/Dockerfile
@@ -59,7 +59,7 @@
# === Configure common env vars
ENV OUTDIR=out \
- NINJA_STATUS="[%f/%t %c/sec] " \
+ NINJA_STATUS="[%e sec | %f/%t %u remaining | %c/sec | j%r] " \
NINJA_PARALLEL=4 \
IS_CI=0 \
CCACHE_DIR=/root/ccache \
diff --git a/src/docker/linux/raspi/gn/Dockerfile b/src/docker/linux/raspi/gn/Dockerfile
index 3339455..bb56179 100644
--- a/src/docker/linux/raspi/gn/Dockerfile
+++ b/src/docker/linux/raspi/gn/Dockerfile
@@ -14,5 +14,5 @@
FROM cobalt-build-raspi
-CMD gn gen ${OUTDIR}/${PLATFORM}_${CONFIG} --args="target_platform=\"${PLATFORM}\" build_type=\"${CONFIG}\" target_cpu=\"arm\" is_clang=false can_build_evergreen_loader_apps=false " && \
+CMD gn gen ${OUTDIR}/${PLATFORM}_${CONFIG} --args="target_platform=\"${PLATFORM}\" build_type=\"${CONFIG}\" target_cpu=\"arm\" is_clang=false" && \
ninja -j ${NINJA_PARALLEL} -C ${OUTDIR}/${PLATFORM}_${CONFIG}
diff --git a/src/nb/reuse_allocator_base.cc b/src/nb/reuse_allocator_base.cc
index 14f280d..b057413 100644
--- a/src/nb/reuse_allocator_base.cc
+++ b/src/nb/reuse_allocator_base.cc
@@ -1,18 +1,16 @@
-/*
- * Copyright 2014 Google Inc. 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.
- */
+// Copyright 2014 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 "nb/reuse_allocator_base.h"
@@ -49,7 +47,7 @@
}
bool ReuseAllocatorBase::MemoryBlock::CanFulfill(std::size_t request_size,
- std::size_t alignment) const {
+ std::size_t alignment) const {
const std::size_t extra_bytes_for_alignment =
AlignUp(AsInteger(address_), alignment) - AsInteger(address_);
const std::size_t aligned_size = request_size + extra_bytes_for_alignment;
@@ -233,62 +231,6 @@
return true;
}
-void* ReuseAllocatorBase::AllocateBestBlock(std::size_t alignment,
- intptr_t context,
- std::size_t* size_hint) {
- const std::size_t kMinAlignment = 16;
- std::size_t size =
- AlignUp(std::max(*size_hint, kMinAlignment), kMinAlignment);
- alignment = AlignUp(std::max<std::size_t>(alignment, 1), kMinAlignment);
-
- bool allocate_from_front;
- FreeBlockSet::iterator free_block_iter =
- FindBestFreeBlock(size, alignment, context, free_blocks_.begin(),
- free_blocks_.end(), &allocate_from_front);
-
- if (free_block_iter == free_blocks_.end()) {
- if (CapacityExceeded()) {
- return NULL;
- }
- free_block_iter = ExpandToFit(*size_hint, alignment);
- if (free_block_iter == free_blocks_.end()) {
- return NULL;
- }
- }
-
- MemoryBlock block = *free_block_iter;
- // The block is big enough. We may waste some space due to alignment.
- RemoveFreeBlock(free_block_iter);
-
- MemoryBlock allocated_block;
- void* user_address;
-
- if (block.CanFulfill(size, alignment)) {
- MemoryBlock free_block;
- block.Allocate(size, alignment, allocate_from_front, &allocated_block,
- &free_block);
- if (free_block.size() > 0) {
- SB_DCHECK(free_block.address());
- AddFreeBlock(free_block);
- }
- user_address = AlignUp(allocated_block.address(), alignment);
- } else {
- allocated_block = block;
- user_address = AlignUp(allocated_block.address(), alignment);
- }
- SB_DCHECK(AsInteger(user_address) >= AsInteger(allocated_block.address()));
- uintptr_t offset =
- AsInteger(user_address) - AsInteger(allocated_block.address());
- SB_DCHECK(allocated_block.size() >= offset);
- if (allocated_block.size() - offset < *size_hint) {
- *size_hint = allocated_block.size() - offset;
- }
-
- AddAllocatedBlock(user_address, allocated_block);
-
- return user_address;
-}
-
ReuseAllocatorBase::ReuseAllocatorBase(Allocator* fallback_allocator,
std::size_t initial_capacity,
std::size_t allocation_increment,
@@ -299,7 +241,7 @@
capacity_(0),
total_allocated_(0) {
if (initial_capacity > 0) {
- FreeBlockSet::iterator iter = ExpandToFit(initial_capacity, 1);
+ FreeBlockSet::iterator iter = ExpandToFit(initial_capacity, kMinAlignment);
SB_DCHECK(iter != free_blocks_.end());
}
}
diff --git a/src/nb/reuse_allocator_base.h b/src/nb/reuse_allocator_base.h
index a437373..a285694 100644
--- a/src/nb/reuse_allocator_base.h
+++ b/src/nb/reuse_allocator_base.h
@@ -1,18 +1,16 @@
-/*
- * Copyright 2014 Google Inc. 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.
- */
+// Copyright 2014 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 NB_REUSE_ALLOCATOR_BASE_H_
#define NB_REUSE_ALLOCATOR_BASE_H_
@@ -52,19 +50,6 @@
bool TryFree(void* memory);
- // Try to allocate a memory block for the |*size_hint| passed in. If there is
- // no such block available, the function may return a block whose size is less
- // than |*size_hint| and set |*size_hint| to that size. |context| will be
- // passed to FindBestFreeBlock() as is, which is useful when the user of a
- // sub-class wants to pass extra information along with the allocation request
- // to FindBestFreeBlock(). The function never sets |*size_hint| to a value
- // greater than the value passed in.
- // This allows the caller to allocate multiple smaller blocks to fulfill a
- // large allocation request.
- void* AllocateBestBlock(std::size_t alignment,
- intptr_t context,
- std::size_t* size_hint);
-
std::size_t max_capacity() const { return max_capacity_; }
void IncreaseMaxCapacityIfNecessary(std::size_t max_capacity) {
max_capacity_ = std::max(max_capacity, max_capacity_);
@@ -132,20 +117,6 @@
FreeBlockSet::iterator end,
bool* allocate_from_front) = 0;
- // The inherited class can implement this function to return a block whose
- // size might be smaller than the |size| passed in. AllocateBestBlock() uses
- // this functional internally. The default implementation simply calls
- // FindFreeBlock() and fails if there isn't a block that is large enough for
- // |size| bytes.
- virtual FreeBlockSet::iterator FindBestFreeBlock(std::size_t size,
- std::size_t alignment,
- intptr_t context,
- FreeBlockSet::iterator begin,
- FreeBlockSet::iterator end,
- bool* allocate_from_front) {
- return FindFreeBlock(size, alignment, begin, end, allocate_from_front);
- }
-
private:
// Map from pointers we returned to the user, back to memory blocks.
typedef std::map<void*, MemoryBlock> AllocatedBlockMap;
diff --git a/src/nb/starboard_memory_allocator.h b/src/nb/starboard_memory_allocator.h
index 0f6895c..44d9ed3 100644
--- a/src/nb/starboard_memory_allocator.h
+++ b/src/nb/starboard_memory_allocator.h
@@ -1,22 +1,22 @@
-/*
- * Copyright 2017 Google Inc. 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.
- */
+// Copyright 2017 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 NB_STARBOARD_MEMORY_ALLOCATOR_H_
#define NB_STARBOARD_MEMORY_ALLOCATOR_H_
+#include <algorithm>
+
#include "nb/allocator.h"
#include "starboard/configuration.h"
#include "starboard/memory.h"
@@ -31,7 +31,7 @@
void* Allocate(std::size_t size) override { return Allocate(size, 1); }
void* Allocate(std::size_t size, std::size_t alignment) override {
- return SbMemoryAllocateAligned(alignment, size);
+ return SbMemoryAllocateAligned(std::max(alignment, sizeof(void*)), size);
}
void* AllocateForAlignment(std::size_t* size,
diff --git a/src/net/net.gyp b/src/net/net.gyp
index 5f96584..e791500 100644
--- a/src/net/net.gyp
+++ b/src/net/net.gyp
@@ -2743,6 +2743,8 @@
'test/url_request/url_request_slow_download_job.h',
'url_request/test_url_fetcher_factory.cc',
'url_request/test_url_fetcher_factory.h',
+ 'url_request/test_url_request_interceptor.cc',
+ 'url_request/test_url_request_interceptor.h',
'url_request/url_request_test_job.cc',
'url_request/url_request_test_job.h',
'url_request/url_request_test_util.cc',
@@ -2786,7 +2788,7 @@
'quic/mock_encrypter.h',
'quic/test_task_runner.cc',
'quic/test_task_runner.h',
- # Requres quic_trace third-party library. Not yet supported.
+ # Requires quic_trace third-party library. Not yet supported.
# 'third_party/quic/core/quic_trace_visitor.cc',
# 'third_party/quic/core/quic_trace_visitor.h',
'third_party/quic/platform/api/quic_expect_bug.h',
diff --git a/src/starboard/android/apk/BUILD.gn b/src/starboard/android/apk/BUILD.gn
index e0b3819..cd95c13 100644
--- a/src/starboard/android/apk/BUILD.gn
+++ b/src/starboard/android/apk/BUILD.gn
@@ -16,5 +16,5 @@
script = "//starboard/build/touch.py"
sources = [ "cobalt-gradle.sh" ]
outputs = [ "$root_out_dir/gradle/apk_sources.stamp" ]
- args = outputs
+ args = rebase_path(outputs, root_build_dir)
}
diff --git a/src/starboard/android/apk/app/cobalt-ninja.sh b/src/starboard/android/apk/app/cobalt-ninja.sh
index f1edba2..7cd85ce 100755
--- a/src/starboard/android/apk/app/cobalt-ninja.sh
+++ b/src/starboard/android/apk/app/cobalt-ninja.sh
@@ -16,7 +16,7 @@
# This wrapper allows us to run ninja without any assumptions about the
# environment having been setup correctly to build Cobalt, since that won't
# happen when started from Android Studio. See:
-# https://cobalt.googlesource.com/cobalt/+/master/src/#Building-and-Running-the-Code
+# https://cobalt.googlesource.com/cobalt/+/master/#Building-and-Running-the-Code
# Allow for a developer-specific environment setup from .cobaltrc
local_rc=$(dirname $0)/.cobaltrc
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/MediaPlaybackService.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/MediaPlaybackService.java
index 16518da..1b54143 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/MediaPlaybackService.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/MediaPlaybackService.java
@@ -25,11 +25,13 @@
import android.os.Build;
import android.os.Build.VERSION;
import android.os.IBinder;
+import android.os.RemoteException;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import dev.cobalt.util.Log;
import dev.cobalt.util.UsedByNative;
+/** Implementation of the MediaPlaybackService used for Background mode media playing. */
public class MediaPlaybackService extends Service {
private static final int NOTIFICATION_ID = 193266736; // CL number for uniqueness.
@@ -51,8 +53,8 @@
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Cold start - Starting the service.");
startService();
- // We don't want the system to recreate a service for us.
- return START_NOT_STICKY;
+ // It is better for background media playback service.
+ return START_STICKY;
}
@Override
@@ -74,7 +76,11 @@
public void startService() {
createChannel();
- startForeground(NOTIFICATION_ID, buildNotification());
+ try {
+ startForeground(NOTIFICATION_ID, buildNotification());
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Failed to start Foreground Service", e);
+ }
}
public void stopService() {
@@ -95,12 +101,16 @@
private void createChannel() {
if (Build.VERSION.SDK_INT >= 26) {
- createChannelInternalV26();
+ try {
+ createChannelInternalV26();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to create Notification Channel.", e);
+ }
}
}
@RequiresApi(26)
- private void createChannelInternalV26() {
+ private void createChannelInternalV26() throws RemoteException {
NotificationManager notificationManager =
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel =
@@ -109,11 +119,7 @@
NOTIFICATION_CHANNEL_NAME,
notificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("Channel for showing persistent notification");
- try {
- notificationManager.createNotificationChannel(channel);
- } catch (IllegalArgumentException e) {
- // intentional empty.
- }
+ notificationManager.createNotificationChannel(channel);
}
public void deleteChannel() {
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java
index 68d95ef..408ada0 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java
@@ -31,6 +31,7 @@
import android.net.Network;
import android.net.NetworkCapabilities;
import android.os.Build;
+import android.os.Build.VERSION;
import android.util.Size;
import android.util.SizeF;
import android.view.Display;
@@ -171,6 +172,11 @@
@SuppressWarnings("unused")
@UsedByNative
protected void startMediaPlaybackService() {
+ if (cobaltMediaSession == null || !cobaltMediaSession.isActive()) {
+ Log.w(TAG, "Do not start a MediaPlaybackService when the MediSsession is null or inactive.");
+ return;
+ }
+
Service service = serviceHolder.get();
if (service == null) {
if (appContext == null) {
@@ -179,9 +185,18 @@
}
Log.i(TAG, "Cold start - Instantiating a MediaPlaybackService.");
Intent intent = new Intent(appContext, MediaPlaybackService.class);
- appContext.startService(intent);
+ try {
+ if (VERSION.SDK_INT >= 26) {
+ appContext.startForegroundService(intent);
+ } else {
+ appContext.startService(intent);
+ }
+ } catch (SecurityException e) {
+ Log.e(TAG, "Failed to start MediaPlaybackService with intent.", e);
+ return;
+ }
} else {
- Log.i(TAG, "Warm start - Restarting the service.");
+ Log.i(TAG, "Warm start - Restarting the MediaPlaybackService.");
((MediaPlaybackService) service).startService();
}
}
@@ -191,7 +206,7 @@
protected void stopMediaPlaybackService() {
Service service = serviceHolder.get();
if (service != null) {
- Log.i(TAG, "Stopping the Media playback service.");
+ Log.i(TAG, "Stopping the MediaPlaybackService.");
((MediaPlaybackService) service).stopService();
}
}
@@ -222,6 +237,9 @@
for (CobaltService service : cobaltServices.values()) {
service.beforeSuspend();
}
+ // We need to stop MediaPlaybackService before suspending so that this foreground service
+ // would not prevent releasing activity's memory consumption.
+ stopMediaPlaybackService();
} catch (Throwable e) {
Log.i(TAG, "Caught exception in beforeSuspend: " + e.getMessage());
}
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/CobaltMediaSession.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/CobaltMediaSession.java
index ba0329d..4a95898 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/CobaltMediaSession.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/CobaltMediaSession.java
@@ -123,6 +123,14 @@
setMediaSession();
}
+ public boolean isActive() {
+ if (this.mediaSession == null) {
+ return false;
+ } else {
+ return this.mediaSession.isActive();
+ }
+ }
+
public void setLifecycleCallback(LifecycleCallback lifecycleCallback) {
this.lifecycleCallback = lifecycleCallback;
if (lifecycleCallback != null && this.mediaSession != null) {
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
index 2473e28..e47ce31 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java
@@ -23,6 +23,7 @@
import android.media.AudioFormat;
import android.media.MediaCodec;
import android.media.MediaCodec.CryptoInfo;
+import android.media.MediaCodec.CryptoInfo.Pattern;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecInfo.VideoCapabilities;
import android.media.MediaCrypto;
@@ -30,6 +31,7 @@
import android.os.Build;
import android.os.Bundle;
import android.view.Surface;
+import androidx.annotation.Nullable;
import dev.cobalt.util.Log;
import dev.cobalt.util.UsedByNative;
import java.nio.ByteBuffer;
@@ -523,22 +525,22 @@
public static MediaCodecBridge createAudioMediaCodecBridge(
long nativeMediaCodecBridge,
String mime,
- boolean isSecure,
- boolean requireSoftwareCodec,
int sampleRate,
int channelCount,
- MediaCrypto crypto) {
+ MediaCrypto crypto,
+ @Nullable byte[] configurationData) {
MediaCodec mediaCodec = null;
try {
- String decoderName = MediaCodecUtil.findAudioDecoder(mime, 0, false);
+ String decoderName =
+ MediaCodecUtil.findAudioDecoder(mime, 0, false /* mustSupportTunnelMode */);
if (decoderName.equals("")) {
- Log.e(TAG, String.format("Failed to find decoder: %s, isSecure: %s", mime, isSecure));
+ Log.e(TAG, String.format("Failed to find decoder: %s", mime));
return null;
}
Log.i(TAG, String.format("Creating \"%s\" decoder.", decoderName));
mediaCodec = MediaCodec.createByCodecName(decoderName);
} catch (Exception e) {
- Log.e(TAG, String.format("Failed to create MediaCodec: %s, isSecure: %s", mime, isSecure), e);
+ Log.e(TAG, String.format("Failed to create MediaCodec: %s, ", mime), e);
return null;
}
if (mediaCodec == null) {
@@ -554,7 +556,17 @@
-1);
MediaFormat mediaFormat = createAudioFormat(mime, sampleRate, channelCount);
- setFrameHasADTSHeader(mediaFormat);
+
+ if (mime.contains("opus")) {
+ if (!setOpusConfigurationData(mediaFormat, sampleRate, configurationData)) {
+ bridge.release();
+ return null;
+ }
+ } else {
+ // TODO: Determine if we should explicitly check the mime for AAC audio before calling
+ // setFrameHasADTSHeader(), as more codecs may be supported here in the future.
+ setFrameHasADTSHeader(mediaFormat);
+ }
if (!bridge.configureAudio(mediaFormat, crypto, 0)) {
Log.e(TAG, "Failed to configure audio codec.");
bridge.release();
@@ -574,8 +586,8 @@
public static void createVideoMediaCodecBridge(
long nativeMediaCodecBridge,
String mime,
- boolean isSecure,
- boolean requireSoftwareCodec,
+ boolean mustSupportSecure,
+ boolean mustSupportSoftwareCodec,
int width,
int height,
int fps,
@@ -587,32 +599,52 @@
MediaCodec mediaCodec = null;
outCreateMediaCodecBridgeResult.mMediaCodecBridge = null;
- boolean findHDRDecoder = android.os.Build.VERSION.SDK_INT >= 24 && colorInfo != null;
- boolean findTunneledDecoder = tunnelModeAudioSessionId != -1;
+ boolean mustSupportHdr = android.os.Build.VERSION.SDK_INT >= 24 && colorInfo != null;
+ boolean mustSupportTunneled = tunnelModeAudioSessionId != -1;
// On first pass, try to find a decoder with HDR if the color info is non-null.
MediaCodecUtil.FindVideoDecoderResult findVideoDecoderResult =
MediaCodecUtil.findVideoDecoder(
- mime, isSecure, 0, 0, 0, 0, findHDRDecoder, requireSoftwareCodec, findTunneledDecoder);
- if (findVideoDecoderResult.name.equals("") && findHDRDecoder) {
+ mime,
+ mustSupportSecure,
+ mustSupportHdr,
+ mustSupportSoftwareCodec,
+ mustSupportTunneled,
+ 0,
+ 0,
+ 0,
+ 0);
+ if (findVideoDecoderResult.name.equals("") && mustSupportHdr) {
// On second pass, forget HDR.
findVideoDecoderResult =
MediaCodecUtil.findVideoDecoder(
- mime, isSecure, 0, 0, 0, 0, false, requireSoftwareCodec, findTunneledDecoder);
+ mime,
+ mustSupportSecure,
+ false /* mustSupportHdr */,
+ mustSupportSoftwareCodec,
+ mustSupportTunneled,
+ 0,
+ 0,
+ 0,
+ 0);
}
try {
String decoderName = findVideoDecoderResult.name;
if (decoderName.equals("") || findVideoDecoderResult.videoCapabilities == null) {
- Log.e(TAG, String.format("Failed to find decoder: %s, isSecure: %s", mime, isSecure));
- outCreateMediaCodecBridgeResult.mErrorMessage =
- String.format("Failed to find decoder: %s, isSecure: %s", mime, isSecure);
+ String message =
+ String.format(
+ "Failed to find decoder: %s, mustSupportSecure: %s", mime, mustSupportSecure);
+ Log.e(TAG, message);
+ outCreateMediaCodecBridgeResult.mErrorMessage = message;
return;
}
Log.i(TAG, String.format("Creating \"%s\" decoder.", decoderName));
mediaCodec = MediaCodec.createByCodecName(decoderName);
} catch (Exception e) {
- Log.e(TAG, String.format("Failed to create MediaCodec: %s, isSecure: %s", mime, isSecure), e);
- outCreateMediaCodecBridgeResult.mErrorMessage =
- String.format("Failed to create MediaCodec: %s, isSecure: %s", mime, isSecure);
+ String message =
+ String.format(
+ "Failed to create MediaCodec: %s, mustSupportSecure: %s", mime, mustSupportSecure);
+ Log.e(TAG, message, e);
+ outCreateMediaCodecBridgeResult.mErrorMessage = message;
return;
}
if (mediaCodec == null) {
@@ -648,10 +680,7 @@
if (tunnelModeAudioSessionId != -1) {
mediaFormat.setFeatureEnabled(CodecCapabilities.FEATURE_TunneledPlayback, true);
mediaFormat.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, tunnelModeAudioSessionId);
- Log.d(
- TAG,
- String.format(
- "Enabled tunnel mode playback on audio session %d", tunnelModeAudioSessionId));
+ Log.d(TAG, "Enabled tunnel mode playback on audio session " + tunnelModeAudioSessionId);
}
VideoCapabilities videoCapabilities = findVideoDecoderResult.videoCapabilities;
@@ -907,31 +936,22 @@
int[] numBytesOfEncryptedData,
int numSubSamples,
int cipherMode,
- int patternEncrypt,
- int patternSkip,
+ int blocksToEncrypt,
+ int blocksToSkip,
long presentationTimeUs) {
resetLastPresentationTimeIfNeeded(presentationTimeUs);
try {
- boolean usesCbcs =
- Build.VERSION.SDK_INT >= 24 && cipherMode == MediaCodec.CRYPTO_MODE_AES_CBC;
-
- if (usesCbcs) {
- Log.e(TAG, "Encryption scheme 'cbcs' not supported on this platform.");
- return MEDIA_CODEC_ERROR;
- }
CryptoInfo cryptoInfo = new CryptoInfo();
cryptoInfo.set(
numSubSamples, numBytesOfClearData, numBytesOfEncryptedData, keyId, iv, cipherMode);
- if (patternEncrypt != 0 && patternSkip != 0) {
- if (usesCbcs) {
- // Above platform check ensured that setting the pattern is indeed supported.
- // MediaCodecUtil.setPatternIfSupported(cryptoInfo, patternEncrypt, patternSkip);
- Log.e(TAG, "Only AES_CTR is supported.");
- } else {
- Log.e(TAG, "Pattern encryption only supported for 'cbcs' scheme (CBC mode).");
- return MEDIA_CODEC_ERROR;
- }
+
+ if (Build.VERSION.SDK_INT >= 24 && cipherMode == MediaCodec.CRYPTO_MODE_AES_CBC) {
+ cryptoInfo.setPattern(new Pattern(blocksToEncrypt, blocksToSkip));
+ } else if (blocksToEncrypt != 0 || blocksToSkip != 0) {
+ Log.e(TAG, "Pattern encryption only supported for 'cbcs' scheme (CBC mode).");
+ return MEDIA_CODEC_ERROR;
}
+
mMediaCodec.queueSecureInputBuffer(index, offset, cryptoInfo, presentationTimeUs, 0);
} catch (MediaCodec.CryptoException e) {
int errorCode = e.getErrorCode();
@@ -1065,7 +1085,7 @@
}
// Use some heuristics to set KEY_MAX_INPUT_SIZE (the size of the input buffers).
- // Taken from exoplayer:
+ // Taken from ExoPlayer:
// https://github.com/google/ExoPlayer/blob/8595c65678a181296cdf673eacb93d8135479340/library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java
private void maybeSetMaxInputSize(MediaFormat format) {
if (format.containsKey(android.media.MediaFormat.KEY_MAX_INPUT_SIZE)) {
@@ -1148,6 +1168,46 @@
}
@SuppressWarnings("unused")
+ private static boolean setOpusConfigurationData(
+ MediaFormat format, int sampleRate, @Nullable byte[] configurationData) {
+ final int MIN_OPUS_INITIALIZATION_DATA_BUFFER_SIZE = 19;
+ final long NANOSECONDS_IN_ONE_SECOND = 1000000000L;
+ // 3840 is the default seek pre-roll samples used by ExoPlayer:
+ // https://github.com/google/ExoPlayer/blob/0ba317b1337eaa789f05dd6c5241246478a3d1e5/library/common/src/main/java/com/google/android/exoplayer2/audio/OpusUtil.java#L30.
+ final int DEFAULT_SEEK_PRE_ROLL_SAMPLES = 3840;
+ if (configurationData == null
+ || configurationData.length < MIN_OPUS_INITIALIZATION_DATA_BUFFER_SIZE) {
+ Log.e(
+ TAG,
+ "Failed to configure Opus audio codec. "
+ + (configurationData == null
+ ? "|configurationData| is null."
+ : String.format(
+ "Configuration data size (%d) is less than the required size (%d).",
+ configurationData.length, MIN_OPUS_INITIALIZATION_DATA_BUFFER_SIZE)));
+ return false;
+ }
+ // Both the number of samples to skip from the beginning of the stream and the amount of time
+ // to pre-roll when seeking must be specified when configuring the Opus decoder. Logic adapted
+ // from ExoPlayer:
+ // https://github.com/google/ExoPlayer/blob/0ba317b1337eaa789f05dd6c5241246478a3d1e5/library/common/src/main/java/com/google/android/exoplayer2/audio/OpusUtil.java#L52.
+ int preSkipSamples = ((configurationData[11] & 0xFF) << 8) | (configurationData[10] & 0xFF);
+ long preSkipNanos = (preSkipSamples * NANOSECONDS_IN_ONE_SECOND) / sampleRate;
+ long seekPreRollNanos =
+ (DEFAULT_SEEK_PRE_ROLL_SAMPLES * NANOSECONDS_IN_ONE_SECOND) / sampleRate;
+ setCodecSpecificData(format, 0, configurationData);
+ setCodecSpecificData(
+ format,
+ 1,
+ ByteBuffer.allocate(8).order(ByteOrder.nativeOrder()).putLong(preSkipNanos).array());
+ setCodecSpecificData(
+ format,
+ 2,
+ ByteBuffer.allocate(8).order(ByteOrder.nativeOrder()).putLong(seekPreRollNanos).array());
+ return true;
+ }
+
+ @SuppressWarnings("unused")
@UsedByNative
private static void setFrameHasADTSHeader(MediaFormat format) {
format.setInteger(MediaFormat.KEY_IS_ADTS, 1);
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java
index 68ea364..e2632dd 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java
@@ -36,18 +36,18 @@
/** Utility functions for dealing with MediaCodec related things. */
public class MediaCodecUtil {
- // A low priority black list of codec names that should never be used.
- private static final Set<String> codecBlackList = new HashSet<>();
- // A high priority white list of brands/model that should always attempt to
+ // A low priority deny list of video codec names that should never be used.
+ private static final Set<String> videoCodecDenyList = new HashSet<>();
+ // A high priority allow list of brands/model that should always attempt to
// play vp9.
- private static final Map<String, Set<String>> vp9WhiteList = new HashMap<>();
- // A white list of software codec names that can be used.
- private static final Set<String> softwareCodecWhiteList = new HashSet<>();
+ private static final Map<String, Set<String>> vp9AllowList = new HashMap<>();
+ // An allow list of software codec names that can be used.
+ private static final Set<String> softwareCodecAllowList = new HashSet<>();
// Whether we should report vp9 codecs as supported or not. Will be set
- // based on whether vp9WhiteList contains our brand/model. If this is set
- // to true, then codecBlackList will be ignored.
- private static boolean isVp9WhiteListed;
+ // based on whether vp9AllowList contains our brand/model. If this is set
+ // to true, then videoCodecDenyList will be ignored.
+ private static boolean isVp9AllowListed;
private static final String SECURE_DECODER_SUFFIX = ".secure";
private static final String VP9_MIME_TYPE = "video/x-vnd.on2.vp9";
private static final String AV1_MIME_TYPE = "video/av01";
@@ -71,315 +71,315 @@
static {
if (Build.VERSION.SDK_INT >= 24 && Build.BRAND.equals("google")) {
- codecBlackList.add("OMX.Nvidia.vp9.decode");
+ videoCodecDenyList.add("OMX.Nvidia.vp9.decode");
}
if (Build.VERSION.SDK_INT >= 24 && Build.BRAND.equals("LGE")) {
- codecBlackList.add("OMX.qcom.video.decoder.vp9");
+ videoCodecDenyList.add("OMX.qcom.video.decoder.vp9");
}
if (Build.VERSION.RELEASE.startsWith("6.0.1")) {
- codecBlackList.add("OMX.Exynos.vp9.dec");
- codecBlackList.add("OMX.Intel.VideoDecoder.VP9.hwr");
- codecBlackList.add("OMX.MTK.VIDEO.DECODER.VP9");
- codecBlackList.add("OMX.qcom.video.decoder.vp9");
+ videoCodecDenyList.add("OMX.Exynos.vp9.dec");
+ videoCodecDenyList.add("OMX.Intel.VideoDecoder.VP9.hwr");
+ videoCodecDenyList.add("OMX.MTK.VIDEO.DECODER.VP9");
+ videoCodecDenyList.add("OMX.qcom.video.decoder.vp9");
}
if (Build.VERSION.RELEASE.startsWith("6.0")) {
- codecBlackList.add("OMX.MTK.VIDEO.DECODER.VP9");
- codecBlackList.add("OMX.Nvidia.vp9.decode");
+ videoCodecDenyList.add("OMX.MTK.VIDEO.DECODER.VP9");
+ videoCodecDenyList.add("OMX.Nvidia.vp9.decode");
}
if (Build.VERSION.RELEASE.startsWith("5.1.1")) {
- codecBlackList.add("OMX.allwinner.video.decoder.vp9");
- codecBlackList.add("OMX.Exynos.vp9.dec");
- codecBlackList.add("OMX.Intel.VideoDecoder.VP9.hwr");
- codecBlackList.add("OMX.MTK.VIDEO.DECODER.VP9");
- codecBlackList.add("OMX.qcom.video.decoder.vp9");
+ videoCodecDenyList.add("OMX.allwinner.video.decoder.vp9");
+ videoCodecDenyList.add("OMX.Exynos.vp9.dec");
+ videoCodecDenyList.add("OMX.Intel.VideoDecoder.VP9.hwr");
+ videoCodecDenyList.add("OMX.MTK.VIDEO.DECODER.VP9");
+ videoCodecDenyList.add("OMX.qcom.video.decoder.vp9");
}
if (Build.VERSION.RELEASE.startsWith("5.1")) {
- codecBlackList.add("OMX.Exynos.VP9.Decoder");
- codecBlackList.add("OMX.Intel.VideoDecoder.VP9.hwr");
- codecBlackList.add("OMX.MTK.VIDEO.DECODER.VP9");
+ videoCodecDenyList.add("OMX.Exynos.VP9.Decoder");
+ videoCodecDenyList.add("OMX.Intel.VideoDecoder.VP9.hwr");
+ videoCodecDenyList.add("OMX.MTK.VIDEO.DECODER.VP9");
}
if (Build.VERSION.RELEASE.startsWith("5.0")) {
- codecBlackList.add("OMX.allwinner.video.decoder.vp9");
- codecBlackList.add("OMX.Exynos.vp9.dec");
- codecBlackList.add("OMX.Intel.VideoDecoder.VP9.hwr");
- codecBlackList.add("OMX.MTK.VIDEO.DECODER.VP9");
+ videoCodecDenyList.add("OMX.allwinner.video.decoder.vp9");
+ videoCodecDenyList.add("OMX.Exynos.vp9.dec");
+ videoCodecDenyList.add("OMX.Intel.VideoDecoder.VP9.hwr");
+ videoCodecDenyList.add("OMX.MTK.VIDEO.DECODER.VP9");
}
if (Build.BRAND.equals("google")) {
- codecBlackList.add("OMX.Intel.VideoDecoder.VP9.hybrid");
+ videoCodecDenyList.add("OMX.Intel.VideoDecoder.VP9.hybrid");
}
- // Black list non hardware media codec names if we aren't running on an emulator.
+ // Denylist non hardware media codec names if we aren't running on an emulator.
if (!IsEmulator.isEmulator()) {
- codecBlackList.add("OMX.ffmpeg.vp9.decoder");
- codecBlackList.add("OMX.Intel.sw_vd.vp9");
- codecBlackList.add("OMX.MTK.VIDEO.DECODER.SW.VP9");
+ videoCodecDenyList.add("OMX.ffmpeg.vp9.decoder");
+ videoCodecDenyList.add("OMX.Intel.sw_vd.vp9");
+ videoCodecDenyList.add("OMX.MTK.VIDEO.DECODER.SW.VP9");
}
- // Black list the Google software vp9 decoder both on hardware and on the emulator.
+ // Denylist the Google software vp9 decoder both on hardware and on the emulator.
// On the emulator it fails with the log: "storeMetaDataInBuffers failed w/ err -1010"
- codecBlackList.add("OMX.google.vp9.decoder");
+ videoCodecDenyList.add("OMX.google.vp9.decoder");
- vp9WhiteList.put("Amazon", new HashSet<String>());
- vp9WhiteList.put("Amlogic", new HashSet<String>());
- vp9WhiteList.put("Arcadyan", new HashSet<String>());
- vp9WhiteList.put("arcelik", new HashSet<String>());
- vp9WhiteList.put("BNO", new HashSet<String>());
- vp9WhiteList.put("BROADCOM", new HashSet<String>());
- vp9WhiteList.put("broadcom", new HashSet<String>());
- vp9WhiteList.put("Foxconn", new HashSet<String>());
- vp9WhiteList.put("Freebox", new HashSet<String>());
- vp9WhiteList.put("Funai", new HashSet<String>());
- vp9WhiteList.put("gfiber", new HashSet<String>());
- vp9WhiteList.put("Google", new HashSet<String>());
- vp9WhiteList.put("google", new HashSet<String>());
- vp9WhiteList.put("Hisense", new HashSet<String>());
- vp9WhiteList.put("HUAWEI", new HashSet<String>());
- vp9WhiteList.put("KaonMedia", new HashSet<String>());
- vp9WhiteList.put("LeTV", new HashSet<String>());
- vp9WhiteList.put("LGE", new HashSet<String>());
- vp9WhiteList.put("MediaTek", new HashSet<String>());
- vp9WhiteList.put("MStar", new HashSet<String>());
- vp9WhiteList.put("MTK", new HashSet<String>());
- vp9WhiteList.put("NVIDIA", new HashSet<String>());
- vp9WhiteList.put("PHILIPS", new HashSet<String>());
- vp9WhiteList.put("Philips", new HashSet<String>());
- vp9WhiteList.put("PIXELA CORPORATION", new HashSet<String>());
- vp9WhiteList.put("RCA", new HashSet<String>());
- vp9WhiteList.put("Sagemcom", new HashSet<String>());
- vp9WhiteList.put("samsung", new HashSet<String>());
- vp9WhiteList.put("SHARP", new HashSet<String>());
- vp9WhiteList.put("Skyworth", new HashSet<String>());
- vp9WhiteList.put("Sony", new HashSet<String>());
- vp9WhiteList.put("STMicroelectronics", new HashSet<String>());
- vp9WhiteList.put("SumitomoElectricIndustries", new HashSet<String>());
- vp9WhiteList.put("TCL", new HashSet<String>());
- vp9WhiteList.put("Technicolor", new HashSet<String>());
- vp9WhiteList.put("Vestel", new HashSet<String>());
- vp9WhiteList.put("wnc", new HashSet<String>());
- vp9WhiteList.put("Xiaomi", new HashSet<String>());
- vp9WhiteList.put("ZTE TV", new HashSet<String>());
+ vp9AllowList.put("Amazon", new HashSet<String>());
+ vp9AllowList.put("Amlogic", new HashSet<String>());
+ vp9AllowList.put("Arcadyan", new HashSet<String>());
+ vp9AllowList.put("arcelik", new HashSet<String>());
+ vp9AllowList.put("BNO", new HashSet<String>());
+ vp9AllowList.put("BROADCOM", new HashSet<String>());
+ vp9AllowList.put("broadcom", new HashSet<String>());
+ vp9AllowList.put("Foxconn", new HashSet<String>());
+ vp9AllowList.put("Freebox", new HashSet<String>());
+ vp9AllowList.put("Funai", new HashSet<String>());
+ vp9AllowList.put("gfiber", new HashSet<String>());
+ vp9AllowList.put("Google", new HashSet<String>());
+ vp9AllowList.put("google", new HashSet<String>());
+ vp9AllowList.put("Hisense", new HashSet<String>());
+ vp9AllowList.put("HUAWEI", new HashSet<String>());
+ vp9AllowList.put("KaonMedia", new HashSet<String>());
+ vp9AllowList.put("LeTV", new HashSet<String>());
+ vp9AllowList.put("LGE", new HashSet<String>());
+ vp9AllowList.put("MediaTek", new HashSet<String>());
+ vp9AllowList.put("MStar", new HashSet<String>());
+ vp9AllowList.put("MTK", new HashSet<String>());
+ vp9AllowList.put("NVIDIA", new HashSet<String>());
+ vp9AllowList.put("PHILIPS", new HashSet<String>());
+ vp9AllowList.put("Philips", new HashSet<String>());
+ vp9AllowList.put("PIXELA CORPORATION", new HashSet<String>());
+ vp9AllowList.put("RCA", new HashSet<String>());
+ vp9AllowList.put("Sagemcom", new HashSet<String>());
+ vp9AllowList.put("samsung", new HashSet<String>());
+ vp9AllowList.put("SHARP", new HashSet<String>());
+ vp9AllowList.put("Skyworth", new HashSet<String>());
+ vp9AllowList.put("Sony", new HashSet<String>());
+ vp9AllowList.put("STMicroelectronics", new HashSet<String>());
+ vp9AllowList.put("SumitomoElectricIndustries", new HashSet<String>());
+ vp9AllowList.put("TCL", new HashSet<String>());
+ vp9AllowList.put("Technicolor", new HashSet<String>());
+ vp9AllowList.put("Vestel", new HashSet<String>());
+ vp9AllowList.put("wnc", new HashSet<String>());
+ vp9AllowList.put("Xiaomi", new HashSet<String>());
+ vp9AllowList.put("ZTE TV", new HashSet<String>());
- vp9WhiteList.get("Amazon").add("AFTS");
- vp9WhiteList.get("Amlogic").add("p212");
- vp9WhiteList.get("Arcadyan").add("Bouygtel4K");
- vp9WhiteList.get("Arcadyan").add("HMB2213PW22TS");
- vp9WhiteList.get("Arcadyan").add("IPSetTopBox");
- vp9WhiteList.get("arcelik").add("arcelik_uhd_powermax_at");
- vp9WhiteList.get("BNO").add("QM153E");
- vp9WhiteList.get("broadcom").add("avko");
- vp9WhiteList.get("broadcom").add("banff");
- vp9WhiteList.get("BROADCOM").add("BCM7XXX_TEST_SETTOP");
- vp9WhiteList.get("broadcom").add("cypress");
- vp9WhiteList.get("broadcom").add("dawson");
- vp9WhiteList.get("broadcom").add("elfin");
- vp9WhiteList.get("Foxconn").add("ba101");
- vp9WhiteList.get("Foxconn").add("bd201");
- vp9WhiteList.get("Freebox").add("Freebox Player Mini v2");
- vp9WhiteList.get("Funai").add("PHILIPS 4K TV");
- vp9WhiteList.get("gfiber").add("GFHD254");
- vp9WhiteList.get("google").add("avko");
- vp9WhiteList.get("google").add("marlin");
- vp9WhiteList.get("Google").add("Pixel XL");
- vp9WhiteList.get("Google").add("Pixel");
- vp9WhiteList.get("google").add("sailfish");
- vp9WhiteList.get("google").add("sprint");
- vp9WhiteList.get("Hisense").add("HAT4KDTV");
- vp9WhiteList.get("HUAWEI").add("X21");
- vp9WhiteList.get("KaonMedia").add("IC1110");
- vp9WhiteList.get("KaonMedia").add("IC1130");
- vp9WhiteList.get("KaonMedia").add("MCM4000");
- vp9WhiteList.get("KaonMedia").add("PRDMK100T");
- vp9WhiteList.get("KaonMedia").add("SFCSTB2LITE");
- vp9WhiteList.get("LeTV").add("uMax85");
- vp9WhiteList.get("LeTV").add("X4-43Pro");
- vp9WhiteList.get("LeTV").add("X4-55");
- vp9WhiteList.get("LeTV").add("X4-65");
- vp9WhiteList.get("LGE").add("S60CLI");
- vp9WhiteList.get("LGE").add("S60UPA");
- vp9WhiteList.get("LGE").add("S60UPI");
- vp9WhiteList.get("LGE").add("S70CDS");
- vp9WhiteList.get("LGE").add("S70PCI");
- vp9WhiteList.get("LGE").add("SH960C-DS");
- vp9WhiteList.get("LGE").add("SH960C-LN");
- vp9WhiteList.get("LGE").add("SH960S-AT");
- vp9WhiteList.get("MediaTek").add("Archer");
- vp9WhiteList.get("MediaTek").add("augie");
- vp9WhiteList.get("MediaTek").add("kane");
- vp9WhiteList.get("MStar").add("Denali");
- vp9WhiteList.get("MStar").add("Rainier");
- vp9WhiteList.get("MTK").add("Generic Android on sharp_2k15_us_android");
- vp9WhiteList.get("NVIDIA").add("SHIELD Android TV");
- vp9WhiteList.get("NVIDIA").add("SHIELD Console");
- vp9WhiteList.get("NVIDIA").add("SHIELD Portable");
- vp9WhiteList.get("PHILIPS").add("QM151E");
- vp9WhiteList.get("PHILIPS").add("QM161E");
- vp9WhiteList.get("PHILIPS").add("QM163E");
- vp9WhiteList.get("Philips").add("TPM171E");
- vp9WhiteList.get("PIXELA CORPORATION").add("POE-MP4000");
- vp9WhiteList.get("RCA").add("XLDRCAV1");
- vp9WhiteList.get("Sagemcom").add("DNA Android TV");
- vp9WhiteList.get("Sagemcom").add("GigaTV");
- vp9WhiteList.get("Sagemcom").add("M387_QL");
- vp9WhiteList.get("Sagemcom").add("Sagemcom Android STB");
- vp9WhiteList.get("Sagemcom").add("Sagemcom ATV Demo");
- vp9WhiteList.get("Sagemcom").add("Telecable ATV");
- vp9WhiteList.get("samsung").add("c71kw200");
- vp9WhiteList.get("samsung").add("GX-CJ680CL");
- vp9WhiteList.get("samsung").add("SAMSUNG-SM-G890A");
- vp9WhiteList.get("samsung").add("SAMSUNG-SM-G920A");
- vp9WhiteList.get("samsung").add("SAMSUNG-SM-G920AZ");
- vp9WhiteList.get("samsung").add("SAMSUNG-SM-G925A");
- vp9WhiteList.get("samsung").add("SAMSUNG-SM-G928A");
- vp9WhiteList.get("samsung").add("SM-G9200");
- vp9WhiteList.get("samsung").add("SM-G9208");
- vp9WhiteList.get("samsung").add("SM-G9209");
- vp9WhiteList.get("samsung").add("SM-G920A");
- vp9WhiteList.get("samsung").add("SM-G920D");
- vp9WhiteList.get("samsung").add("SM-G920F");
- vp9WhiteList.get("samsung").add("SM-G920FD");
- vp9WhiteList.get("samsung").add("SM-G920FQ");
- vp9WhiteList.get("samsung").add("SM-G920I");
- vp9WhiteList.get("samsung").add("SM-G920K");
- vp9WhiteList.get("samsung").add("SM-G920L");
- vp9WhiteList.get("samsung").add("SM-G920P");
- vp9WhiteList.get("samsung").add("SM-G920R4");
- vp9WhiteList.get("samsung").add("SM-G920R6");
- vp9WhiteList.get("samsung").add("SM-G920R7");
- vp9WhiteList.get("samsung").add("SM-G920S");
- vp9WhiteList.get("samsung").add("SM-G920T");
- vp9WhiteList.get("samsung").add("SM-G920T1");
- vp9WhiteList.get("samsung").add("SM-G920V");
- vp9WhiteList.get("samsung").add("SM-G920W8");
- vp9WhiteList.get("samsung").add("SM-G9250");
- vp9WhiteList.get("samsung").add("SM-G925A");
- vp9WhiteList.get("samsung").add("SM-G925D");
- vp9WhiteList.get("samsung").add("SM-G925F");
- vp9WhiteList.get("samsung").add("SM-G925FQ");
- vp9WhiteList.get("samsung").add("SM-G925I");
- vp9WhiteList.get("samsung").add("SM-G925J");
- vp9WhiteList.get("samsung").add("SM-G925K");
- vp9WhiteList.get("samsung").add("SM-G925L");
- vp9WhiteList.get("samsung").add("SM-G925P");
- vp9WhiteList.get("samsung").add("SM-G925R4");
- vp9WhiteList.get("samsung").add("SM-G925R6");
- vp9WhiteList.get("samsung").add("SM-G925R7");
- vp9WhiteList.get("samsung").add("SM-G925S");
- vp9WhiteList.get("samsung").add("SM-G925T");
- vp9WhiteList.get("samsung").add("SM-G925V");
- vp9WhiteList.get("samsung").add("SM-G925W8");
- vp9WhiteList.get("samsung").add("SM-G925Z");
- vp9WhiteList.get("samsung").add("SM-G9280");
- vp9WhiteList.get("samsung").add("SM-G9287");
- vp9WhiteList.get("samsung").add("SM-G9287C");
- vp9WhiteList.get("samsung").add("SM-G928A");
- vp9WhiteList.get("samsung").add("SM-G928C");
- vp9WhiteList.get("samsung").add("SM-G928F");
- vp9WhiteList.get("samsung").add("SM-G928G");
- vp9WhiteList.get("samsung").add("SM-G928I");
- vp9WhiteList.get("samsung").add("SM-G928K");
- vp9WhiteList.get("samsung").add("SM-G928L");
- vp9WhiteList.get("samsung").add("SM-G928N0");
- vp9WhiteList.get("samsung").add("SM-G928P");
- vp9WhiteList.get("samsung").add("SM-G928S");
- vp9WhiteList.get("samsung").add("SM-G928T");
- vp9WhiteList.get("samsung").add("SM-G928V");
- vp9WhiteList.get("samsung").add("SM-G928W8");
- vp9WhiteList.get("samsung").add("SM-G928X");
- vp9WhiteList.get("samsung").add("SM-G9300");
- vp9WhiteList.get("samsung").add("SM-G9308");
- vp9WhiteList.get("samsung").add("SM-G930A");
- vp9WhiteList.get("samsung").add("SM-G930AZ");
- vp9WhiteList.get("samsung").add("SM-G930F");
- vp9WhiteList.get("samsung").add("SM-G930FD");
- vp9WhiteList.get("samsung").add("SM-G930K");
- vp9WhiteList.get("samsung").add("SM-G930L");
- vp9WhiteList.get("samsung").add("SM-G930P");
- vp9WhiteList.get("samsung").add("SM-G930R4");
- vp9WhiteList.get("samsung").add("SM-G930R6");
- vp9WhiteList.get("samsung").add("SM-G930R7");
- vp9WhiteList.get("samsung").add("SM-G930S");
- vp9WhiteList.get("samsung").add("SM-G930T");
- vp9WhiteList.get("samsung").add("SM-G930T1");
- vp9WhiteList.get("samsung").add("SM-G930U");
- vp9WhiteList.get("samsung").add("SM-G930V");
- vp9WhiteList.get("samsung").add("SM-G930VL");
- vp9WhiteList.get("samsung").add("SM-G930W8");
- vp9WhiteList.get("samsung").add("SM-G9350");
- vp9WhiteList.get("samsung").add("SM-G935A");
- vp9WhiteList.get("samsung").add("SM-G935D");
- vp9WhiteList.get("samsung").add("SM-G935F");
- vp9WhiteList.get("samsung").add("SM-G935FD");
- vp9WhiteList.get("samsung").add("SM-G935J");
- vp9WhiteList.get("samsung").add("SM-G935K");
- vp9WhiteList.get("samsung").add("SM-G935L");
- vp9WhiteList.get("samsung").add("SM-G935P");
- vp9WhiteList.get("samsung").add("SM-G935R4");
- vp9WhiteList.get("samsung").add("SM-G935S");
- vp9WhiteList.get("samsung").add("SM-G935T");
- vp9WhiteList.get("samsung").add("SM-G935U");
- vp9WhiteList.get("samsung").add("SM-G935V");
- vp9WhiteList.get("samsung").add("SM-G935W8");
- vp9WhiteList.get("samsung").add("SM-N9200");
- vp9WhiteList.get("samsung").add("SM-N9208");
- vp9WhiteList.get("samsung").add("SM-N920A");
- vp9WhiteList.get("samsung").add("SM-N920C");
- vp9WhiteList.get("samsung").add("SM-N920F");
- vp9WhiteList.get("samsung").add("SM-N920G");
- vp9WhiteList.get("samsung").add("SM-N920I");
- vp9WhiteList.get("samsung").add("SM-N920K");
- vp9WhiteList.get("samsung").add("SM-N920L");
- vp9WhiteList.get("samsung").add("SM-N920R4");
- vp9WhiteList.get("samsung").add("SM-N920R6");
- vp9WhiteList.get("samsung").add("SM-N920R7");
- vp9WhiteList.get("samsung").add("SM-N920S");
- vp9WhiteList.get("samsung").add("SM-N920T");
- vp9WhiteList.get("samsung").add("SM-N920TP");
- vp9WhiteList.get("samsung").add("SM-N920V");
- vp9WhiteList.get("samsung").add("SM-N920W8");
- vp9WhiteList.get("samsung").add("SM-N920X");
- vp9WhiteList.get("SHARP").add("AN-NP40");
- vp9WhiteList.get("SHARP").add("AQUOS-4KTVJ17");
- vp9WhiteList.get("SHARP").add("AQUOS-4KTVT17");
- vp9WhiteList.get("SHARP").add("AQUOS-4KTVX17");
- vp9WhiteList.get("SHARP").add("LC-U35T");
- vp9WhiteList.get("SHARP").add("LC-UE630X");
- vp9WhiteList.get("SHARP").add("LC-Ux30US");
- vp9WhiteList.get("SHARP").add("LC-XU35T");
- vp9WhiteList.get("SHARP").add("LC-XU930X_830X");
- vp9WhiteList.get("Skyworth").add("globe");
- vp9WhiteList.get("Sony").add("Amai VP9");
- vp9WhiteList.get("Sony").add("BRAVIA 4K 2015");
- vp9WhiteList.get("Sony").add("BRAVIA 4K GB");
- vp9WhiteList.get("STMicroelectronics").add("sti4k");
- vp9WhiteList.get("SumitomoElectricIndustries").add("C02AS");
- vp9WhiteList.get("SumitomoElectricIndustries").add("ST4173");
- vp9WhiteList.get("SumitomoElectricIndustries").add("test_STW2000");
- vp9WhiteList.get("TCL").add("Percee TV");
- vp9WhiteList.get("Technicolor").add("AirTV Player");
- vp9WhiteList.get("Technicolor").add("Bouygtel4K");
- vp9WhiteList.get("Technicolor").add("CM-7600");
- vp9WhiteList.get("Technicolor").add("cooper");
- vp9WhiteList.get("Technicolor").add("Foxtel Now box");
- vp9WhiteList.get("Technicolor").add("pearl");
- vp9WhiteList.get("Technicolor").add("Sapphire");
- vp9WhiteList.get("Technicolor").add("Shortcut");
- vp9WhiteList.get("Technicolor").add("skipper");
- vp9WhiteList.get("Technicolor").add("STING");
- vp9WhiteList.get("Technicolor").add("TIM_BOX");
- vp9WhiteList.get("Technicolor").add("uzx8020chm");
- vp9WhiteList.get("Vestel").add("S7252");
- vp9WhiteList.get("Vestel").add("SmartTV");
- vp9WhiteList.get("wnc").add("c71kw400");
- vp9WhiteList.get("Xiaomi").add("MIBOX3");
- vp9WhiteList.get("ZTE TV").add("AV-ATB100");
- vp9WhiteList.get("ZTE TV").add("B860H");
+ vp9AllowList.get("Amazon").add("AFTS");
+ vp9AllowList.get("Amlogic").add("p212");
+ vp9AllowList.get("Arcadyan").add("Bouygtel4K");
+ vp9AllowList.get("Arcadyan").add("HMB2213PW22TS");
+ vp9AllowList.get("Arcadyan").add("IPSetTopBox");
+ vp9AllowList.get("arcelik").add("arcelik_uhd_powermax_at");
+ vp9AllowList.get("BNO").add("QM153E");
+ vp9AllowList.get("broadcom").add("avko");
+ vp9AllowList.get("broadcom").add("banff");
+ vp9AllowList.get("BROADCOM").add("BCM7XXX_TEST_SETTOP");
+ vp9AllowList.get("broadcom").add("cypress");
+ vp9AllowList.get("broadcom").add("dawson");
+ vp9AllowList.get("broadcom").add("elfin");
+ vp9AllowList.get("Foxconn").add("ba101");
+ vp9AllowList.get("Foxconn").add("bd201");
+ vp9AllowList.get("Freebox").add("Freebox Player Mini v2");
+ vp9AllowList.get("Funai").add("PHILIPS 4K TV");
+ vp9AllowList.get("gfiber").add("GFHD254");
+ vp9AllowList.get("google").add("avko");
+ vp9AllowList.get("google").add("marlin");
+ vp9AllowList.get("Google").add("Pixel XL");
+ vp9AllowList.get("Google").add("Pixel");
+ vp9AllowList.get("google").add("sailfish");
+ vp9AllowList.get("google").add("sprint");
+ vp9AllowList.get("Hisense").add("HAT4KDTV");
+ vp9AllowList.get("HUAWEI").add("X21");
+ vp9AllowList.get("KaonMedia").add("IC1110");
+ vp9AllowList.get("KaonMedia").add("IC1130");
+ vp9AllowList.get("KaonMedia").add("MCM4000");
+ vp9AllowList.get("KaonMedia").add("PRDMK100T");
+ vp9AllowList.get("KaonMedia").add("SFCSTB2LITE");
+ vp9AllowList.get("LeTV").add("uMax85");
+ vp9AllowList.get("LeTV").add("X4-43Pro");
+ vp9AllowList.get("LeTV").add("X4-55");
+ vp9AllowList.get("LeTV").add("X4-65");
+ vp9AllowList.get("LGE").add("S60CLI");
+ vp9AllowList.get("LGE").add("S60UPA");
+ vp9AllowList.get("LGE").add("S60UPI");
+ vp9AllowList.get("LGE").add("S70CDS");
+ vp9AllowList.get("LGE").add("S70PCI");
+ vp9AllowList.get("LGE").add("SH960C-DS");
+ vp9AllowList.get("LGE").add("SH960C-LN");
+ vp9AllowList.get("LGE").add("SH960S-AT");
+ vp9AllowList.get("MediaTek").add("Archer");
+ vp9AllowList.get("MediaTek").add("augie");
+ vp9AllowList.get("MediaTek").add("kane");
+ vp9AllowList.get("MStar").add("Denali");
+ vp9AllowList.get("MStar").add("Rainier");
+ vp9AllowList.get("MTK").add("Generic Android on sharp_2k15_us_android");
+ vp9AllowList.get("NVIDIA").add("SHIELD Android TV");
+ vp9AllowList.get("NVIDIA").add("SHIELD Console");
+ vp9AllowList.get("NVIDIA").add("SHIELD Portable");
+ vp9AllowList.get("PHILIPS").add("QM151E");
+ vp9AllowList.get("PHILIPS").add("QM161E");
+ vp9AllowList.get("PHILIPS").add("QM163E");
+ vp9AllowList.get("Philips").add("TPM171E");
+ vp9AllowList.get("PIXELA CORPORATION").add("POE-MP4000");
+ vp9AllowList.get("RCA").add("XLDRCAV1");
+ vp9AllowList.get("Sagemcom").add("DNA Android TV");
+ vp9AllowList.get("Sagemcom").add("GigaTV");
+ vp9AllowList.get("Sagemcom").add("M387_QL");
+ vp9AllowList.get("Sagemcom").add("Sagemcom Android STB");
+ vp9AllowList.get("Sagemcom").add("Sagemcom ATV Demo");
+ vp9AllowList.get("Sagemcom").add("Telecable ATV");
+ vp9AllowList.get("samsung").add("c71kw200");
+ vp9AllowList.get("samsung").add("GX-CJ680CL");
+ vp9AllowList.get("samsung").add("SAMSUNG-SM-G890A");
+ vp9AllowList.get("samsung").add("SAMSUNG-SM-G920A");
+ vp9AllowList.get("samsung").add("SAMSUNG-SM-G920AZ");
+ vp9AllowList.get("samsung").add("SAMSUNG-SM-G925A");
+ vp9AllowList.get("samsung").add("SAMSUNG-SM-G928A");
+ vp9AllowList.get("samsung").add("SM-G9200");
+ vp9AllowList.get("samsung").add("SM-G9208");
+ vp9AllowList.get("samsung").add("SM-G9209");
+ vp9AllowList.get("samsung").add("SM-G920A");
+ vp9AllowList.get("samsung").add("SM-G920D");
+ vp9AllowList.get("samsung").add("SM-G920F");
+ vp9AllowList.get("samsung").add("SM-G920FD");
+ vp9AllowList.get("samsung").add("SM-G920FQ");
+ vp9AllowList.get("samsung").add("SM-G920I");
+ vp9AllowList.get("samsung").add("SM-G920K");
+ vp9AllowList.get("samsung").add("SM-G920L");
+ vp9AllowList.get("samsung").add("SM-G920P");
+ vp9AllowList.get("samsung").add("SM-G920R4");
+ vp9AllowList.get("samsung").add("SM-G920R6");
+ vp9AllowList.get("samsung").add("SM-G920R7");
+ vp9AllowList.get("samsung").add("SM-G920S");
+ vp9AllowList.get("samsung").add("SM-G920T");
+ vp9AllowList.get("samsung").add("SM-G920T1");
+ vp9AllowList.get("samsung").add("SM-G920V");
+ vp9AllowList.get("samsung").add("SM-G920W8");
+ vp9AllowList.get("samsung").add("SM-G9250");
+ vp9AllowList.get("samsung").add("SM-G925A");
+ vp9AllowList.get("samsung").add("SM-G925D");
+ vp9AllowList.get("samsung").add("SM-G925F");
+ vp9AllowList.get("samsung").add("SM-G925FQ");
+ vp9AllowList.get("samsung").add("SM-G925I");
+ vp9AllowList.get("samsung").add("SM-G925J");
+ vp9AllowList.get("samsung").add("SM-G925K");
+ vp9AllowList.get("samsung").add("SM-G925L");
+ vp9AllowList.get("samsung").add("SM-G925P");
+ vp9AllowList.get("samsung").add("SM-G925R4");
+ vp9AllowList.get("samsung").add("SM-G925R6");
+ vp9AllowList.get("samsung").add("SM-G925R7");
+ vp9AllowList.get("samsung").add("SM-G925S");
+ vp9AllowList.get("samsung").add("SM-G925T");
+ vp9AllowList.get("samsung").add("SM-G925V");
+ vp9AllowList.get("samsung").add("SM-G925W8");
+ vp9AllowList.get("samsung").add("SM-G925Z");
+ vp9AllowList.get("samsung").add("SM-G9280");
+ vp9AllowList.get("samsung").add("SM-G9287");
+ vp9AllowList.get("samsung").add("SM-G9287C");
+ vp9AllowList.get("samsung").add("SM-G928A");
+ vp9AllowList.get("samsung").add("SM-G928C");
+ vp9AllowList.get("samsung").add("SM-G928F");
+ vp9AllowList.get("samsung").add("SM-G928G");
+ vp9AllowList.get("samsung").add("SM-G928I");
+ vp9AllowList.get("samsung").add("SM-G928K");
+ vp9AllowList.get("samsung").add("SM-G928L");
+ vp9AllowList.get("samsung").add("SM-G928N0");
+ vp9AllowList.get("samsung").add("SM-G928P");
+ vp9AllowList.get("samsung").add("SM-G928S");
+ vp9AllowList.get("samsung").add("SM-G928T");
+ vp9AllowList.get("samsung").add("SM-G928V");
+ vp9AllowList.get("samsung").add("SM-G928W8");
+ vp9AllowList.get("samsung").add("SM-G928X");
+ vp9AllowList.get("samsung").add("SM-G9300");
+ vp9AllowList.get("samsung").add("SM-G9308");
+ vp9AllowList.get("samsung").add("SM-G930A");
+ vp9AllowList.get("samsung").add("SM-G930AZ");
+ vp9AllowList.get("samsung").add("SM-G930F");
+ vp9AllowList.get("samsung").add("SM-G930FD");
+ vp9AllowList.get("samsung").add("SM-G930K");
+ vp9AllowList.get("samsung").add("SM-G930L");
+ vp9AllowList.get("samsung").add("SM-G930P");
+ vp9AllowList.get("samsung").add("SM-G930R4");
+ vp9AllowList.get("samsung").add("SM-G930R6");
+ vp9AllowList.get("samsung").add("SM-G930R7");
+ vp9AllowList.get("samsung").add("SM-G930S");
+ vp9AllowList.get("samsung").add("SM-G930T");
+ vp9AllowList.get("samsung").add("SM-G930T1");
+ vp9AllowList.get("samsung").add("SM-G930U");
+ vp9AllowList.get("samsung").add("SM-G930V");
+ vp9AllowList.get("samsung").add("SM-G930VL");
+ vp9AllowList.get("samsung").add("SM-G930W8");
+ vp9AllowList.get("samsung").add("SM-G9350");
+ vp9AllowList.get("samsung").add("SM-G935A");
+ vp9AllowList.get("samsung").add("SM-G935D");
+ vp9AllowList.get("samsung").add("SM-G935F");
+ vp9AllowList.get("samsung").add("SM-G935FD");
+ vp9AllowList.get("samsung").add("SM-G935J");
+ vp9AllowList.get("samsung").add("SM-G935K");
+ vp9AllowList.get("samsung").add("SM-G935L");
+ vp9AllowList.get("samsung").add("SM-G935P");
+ vp9AllowList.get("samsung").add("SM-G935R4");
+ vp9AllowList.get("samsung").add("SM-G935S");
+ vp9AllowList.get("samsung").add("SM-G935T");
+ vp9AllowList.get("samsung").add("SM-G935U");
+ vp9AllowList.get("samsung").add("SM-G935V");
+ vp9AllowList.get("samsung").add("SM-G935W8");
+ vp9AllowList.get("samsung").add("SM-N9200");
+ vp9AllowList.get("samsung").add("SM-N9208");
+ vp9AllowList.get("samsung").add("SM-N920A");
+ vp9AllowList.get("samsung").add("SM-N920C");
+ vp9AllowList.get("samsung").add("SM-N920F");
+ vp9AllowList.get("samsung").add("SM-N920G");
+ vp9AllowList.get("samsung").add("SM-N920I");
+ vp9AllowList.get("samsung").add("SM-N920K");
+ vp9AllowList.get("samsung").add("SM-N920L");
+ vp9AllowList.get("samsung").add("SM-N920R4");
+ vp9AllowList.get("samsung").add("SM-N920R6");
+ vp9AllowList.get("samsung").add("SM-N920R7");
+ vp9AllowList.get("samsung").add("SM-N920S");
+ vp9AllowList.get("samsung").add("SM-N920T");
+ vp9AllowList.get("samsung").add("SM-N920TP");
+ vp9AllowList.get("samsung").add("SM-N920V");
+ vp9AllowList.get("samsung").add("SM-N920W8");
+ vp9AllowList.get("samsung").add("SM-N920X");
+ vp9AllowList.get("SHARP").add("AN-NP40");
+ vp9AllowList.get("SHARP").add("AQUOS-4KTVJ17");
+ vp9AllowList.get("SHARP").add("AQUOS-4KTVT17");
+ vp9AllowList.get("SHARP").add("AQUOS-4KTVX17");
+ vp9AllowList.get("SHARP").add("LC-U35T");
+ vp9AllowList.get("SHARP").add("LC-UE630X");
+ vp9AllowList.get("SHARP").add("LC-Ux30US");
+ vp9AllowList.get("SHARP").add("LC-XU35T");
+ vp9AllowList.get("SHARP").add("LC-XU930X_830X");
+ vp9AllowList.get("Skyworth").add("globe");
+ vp9AllowList.get("Sony").add("Amai VP9");
+ vp9AllowList.get("Sony").add("BRAVIA 4K 2015");
+ vp9AllowList.get("Sony").add("BRAVIA 4K GB");
+ vp9AllowList.get("STMicroelectronics").add("sti4k");
+ vp9AllowList.get("SumitomoElectricIndustries").add("C02AS");
+ vp9AllowList.get("SumitomoElectricIndustries").add("ST4173");
+ vp9AllowList.get("SumitomoElectricIndustries").add("test_STW2000");
+ vp9AllowList.get("TCL").add("Percee TV");
+ vp9AllowList.get("Technicolor").add("AirTV Player");
+ vp9AllowList.get("Technicolor").add("Bouygtel4K");
+ vp9AllowList.get("Technicolor").add("CM-7600");
+ vp9AllowList.get("Technicolor").add("cooper");
+ vp9AllowList.get("Technicolor").add("Foxtel Now box");
+ vp9AllowList.get("Technicolor").add("pearl");
+ vp9AllowList.get("Technicolor").add("Sapphire");
+ vp9AllowList.get("Technicolor").add("Shortcut");
+ vp9AllowList.get("Technicolor").add("skipper");
+ vp9AllowList.get("Technicolor").add("STING");
+ vp9AllowList.get("Technicolor").add("TIM_BOX");
+ vp9AllowList.get("Technicolor").add("uzx8020chm");
+ vp9AllowList.get("Vestel").add("S7252");
+ vp9AllowList.get("Vestel").add("SmartTV");
+ vp9AllowList.get("wnc").add("c71kw400");
+ vp9AllowList.get("Xiaomi").add("MIBOX3");
+ vp9AllowList.get("ZTE TV").add("AV-ATB100");
+ vp9AllowList.get("ZTE TV").add("B860H");
- isVp9WhiteListed =
- vp9WhiteList.containsKey(Build.BRAND)
- && vp9WhiteList.get(Build.BRAND).contains(Build.MODEL);
+ isVp9AllowListed =
+ vp9AllowList.containsKey(Build.BRAND)
+ && vp9AllowList.get(Build.BRAND).contains(Build.MODEL);
- softwareCodecWhiteList.add("OMX.google.h264.decoder");
+ softwareCodecAllowList.add("OMX.google.h264.decoder");
}
private MediaCodecUtil() {}
@@ -394,24 +394,24 @@
@UsedByNative
public static boolean hasVideoDecoderFor(
String mimeType,
- boolean secure,
+ boolean mustSupportSecure,
+ boolean mustSupportHdr,
+ boolean mustSupportTunnelMode,
int frameWidth,
int frameHeight,
int bitrate,
- int fps,
- boolean mustSupportHdr,
- boolean mustSupportTunnelMode) {
+ int fps) {
FindVideoDecoderResult findVideoDecoderResult =
findVideoDecoder(
mimeType,
- secure,
+ mustSupportSecure,
+ mustSupportHdr,
+ false /* mustSupportSoftwareCodec */,
+ mustSupportTunnelMode,
frameWidth,
frameHeight,
bitrate,
- fps,
- mustSupportHdr,
- false,
- mustSupportTunnelMode);
+ fps);
return !findVideoDecoderResult.name.equals("")
&& (!mustSupportHdr || isHdrCapableVideoDecoder(mimeType, findVideoDecoderResult));
}
@@ -446,7 +446,7 @@
}
FindVideoDecoderResult findVideoDecoderResult =
- findVideoDecoder(mimeType, false, 0, 0, 0, 0, true, false, false);
+ findVideoDecoder(mimeType, false, true, false, false, 0, 0, 0, 0);
return isHdrCapableVideoDecoder(mimeType, findVideoDecoderResult);
}
@@ -483,38 +483,38 @@
*/
public static FindVideoDecoderResult findVideoDecoder(
String mimeType,
- boolean secure,
+ boolean mustSupportSecure,
+ boolean mustSupportHdr,
+ boolean mustSupportSoftwareCodec,
+ boolean mustSupportTunnelMode,
int frameWidth,
int frameHeight,
int bitrate,
- int fps,
- boolean hdr, // TODO: Move all boolean feature parameters after |secure|
- boolean requireSoftwareCodec,
- boolean requireTunneledPlayback) {
+ int fps) {
Log.v(
TAG,
String.format(
"Searching for video decoder with parameters mimeType: %s, secure: %b, frameWidth: %d,"
- + " frameHeight: %d, bitrate: %d, fps: %d, hdr: %b, requireSoftwareCodec: %b,"
- + " requireTunneledPlayback: %b",
+ + " frameHeight: %d, bitrate: %d, fps: %d, mustSupportHdr: %b,"
+ + " mustSupportSoftwareCodec: %b, mustSupportTunnelMode: %b",
mimeType,
- secure,
+ mustSupportSecure,
frameWidth,
frameHeight,
bitrate,
fps,
- hdr,
- requireSoftwareCodec,
- requireTunneledPlayback));
+ mustSupportHdr,
+ mustSupportSoftwareCodec,
+ mustSupportTunnelMode));
Log.v(
TAG,
String.format(
- "brand: %s, model: %s, version: %s, API level: %d, isVp9WhiteListed: %b",
+ "brand: %s, model: %s, version: %s, API level: %d, isVp9AllowListed: %b",
Build.BRAND,
Build.MODEL,
Build.VERSION.RELEASE,
Build.VERSION.SDK_INT,
- isVp9WhiteListed));
+ isVp9AllowListed));
// Note: MediaCodecList is sorted by the framework such that the best decoders come first.
for (MediaCodecInfo info : new MediaCodecList(MediaCodecList.ALL_CODECS).getCodecInfos()) {
@@ -526,12 +526,12 @@
continue;
}
String name = info.getName();
- if (requireSoftwareCodec && !softwareCodecWhiteList.contains(name)) {
+ if (mustSupportSoftwareCodec && !softwareCodecAllowList.contains(name)) {
Log.v(TAG, String.format("Rejecting %s, reason: require software codec", name));
continue;
}
- if (!isVp9WhiteListed && codecBlackList.contains(name)) {
- Log.v(TAG, String.format("Rejecting %s, reason: codec is black listed", name));
+ if (!isVp9AllowListed && videoCodecDenyList.contains(name)) {
+ Log.v(TAG, String.format("Rejecting %s, reason: codec is on deny list", name));
continue;
}
// MediaCodecList is supposed to feed us names of decoders that do NOT end in ".secure". We
@@ -541,60 +541,55 @@
// decoders that end in ".secure". Empirically, FEATURE_SecurePlayback has still been
// correct when this happens.
if (name.endsWith(SECURE_DECODER_SUFFIX)) {
- // If we want a secure decoder, then make sure the version without ".secure" isn't
- // blacklisted.
- String nameWithoutSecureSuffix =
- name.substring(0, name.length() - SECURE_DECODER_SUFFIX.length());
- if (secure && !isVp9WhiteListed && codecBlackList.contains(nameWithoutSecureSuffix)) {
- Log.v(
- TAG,
- String.format("Rejecting %s, reason: offpsec blacklisted secure decoder", name));
+ // If we don't want a secure decoder, then don't bother messing around with this thing.
+ if (!mustSupportSecure) {
+ String format = "Rejecting %s, reason: want !secure decoder and ends with .secure";
+ Log.v(TAG, String.format(format, name));
continue;
}
- // If we don't want a secure decoder, then don't bother messing around with this thing.
- if (!secure) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: want !secure decoder and ends with .secure", name));
+ // If we want a secure decoder, then make sure the version without ".secure" isn't
+ // denylisted.
+ String nameWithoutSecureSuffix =
+ name.substring(0, name.length() - SECURE_DECODER_SUFFIX.length());
+ if (!isVp9AllowListed && videoCodecDenyList.contains(nameWithoutSecureSuffix)) {
+ String format = "Rejecting %s, reason: offpsec denylisted secure decoder";
+ Log.v(TAG, String.format(format, name));
continue;
}
}
CodecCapabilities codecCapabilities = info.getCapabilitiesForType(supportedType);
- if (secure
- && !codecCapabilities.isFeatureSupported(
- MediaCodecInfo.CodecCapabilities.FEATURE_SecurePlayback)) {
- Log.v(
- TAG,
+ boolean requiresSecurePlayback =
+ codecCapabilities.isFeatureRequired(
+ MediaCodecInfo.CodecCapabilities.FEATURE_SecurePlayback);
+ boolean supportsSecurePlayback =
+ codecCapabilities.isFeatureSupported(
+ MediaCodecInfo.CodecCapabilities.FEATURE_SecurePlayback);
+ if (mustSupportSecure && !supportsSecurePlayback
+ || !mustSupportSecure && requiresSecurePlayback) {
+ String message =
String.format(
- "Rejecting %s, reason: want secure decoder and !FEATURE_SecurePlayback", name));
+ "Rejecting %s, reason: secure decoder requested: %b, "
+ + "codec FEATURE_SecurePlayback supported: %b, required: %b",
+ name, mustSupportSecure, supportsSecurePlayback, requiresSecurePlayback);
+ Log.v(TAG, message);
continue;
}
- if (!requireTunneledPlayback
- && codecCapabilities.isFeatureRequired(
- MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback)) {
- Log.v(
- TAG,
- String.format("Rejecting %s, reason: codec requires FEATURE_TunneledPlayback", name));
- continue;
- }
- if (!secure
- && codecCapabilities.isFeatureRequired(
- MediaCodecInfo.CodecCapabilities.FEATURE_SecurePlayback)) {
- Log.v(
- TAG,
- String.format("Rejecting %s, reason: code requires FEATURE_SecurePlayback", name));
- continue;
- }
- if (requireTunneledPlayback
- && !codecCapabilities.isFeatureSupported(
- MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback)) {
- Log.v(
- TAG,
+
+ boolean requiresTunneledPlayback =
+ codecCapabilities.isFeatureRequired(
+ MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback);
+ boolean supportsTunneledPlayback =
+ codecCapabilities.isFeatureSupported(
+ MediaCodecInfo.CodecCapabilities.FEATURE_TunneledPlayback);
+ if (mustSupportTunnelMode && !supportsTunneledPlayback
+ || !mustSupportTunnelMode && requiresTunneledPlayback) {
+ String message =
String.format(
- "Rejecting %s, reason: want tunneled playback and !FEATURE_TunneledPlayback",
- name));
+ "Rejecting %s, reason: tunneled playback requested: %b, "
+ + "codec FEATURE_TunneledPlayback supported: %b, required: %b",
+ name, mustSupportTunnelMode, supportsTunneledPlayback, requiresTunneledPlayback);
+ Log.v(TAG, message);
continue;
}
@@ -608,6 +603,8 @@
}
VideoCapabilities videoCapabilities = codecCapabilities.getVideoCapabilities();
+ Range<Integer> supportedWidths = videoCapabilities.getSupportedWidths();
+ Range<Integer> supportedHeights = videoCapabilities.getSupportedHeights();
// Enable the improved support check based on more specific APIs, like isSizeSupported() or
// areSizeAndRateSupported(), for 8k content. These APIs are theoretically more accurate,
@@ -616,102 +613,81 @@
if (enableImprovedCheck) {
if (frameWidth != 0 && frameHeight != 0) {
if (!videoCapabilities.isSizeSupported(frameWidth, frameHeight)) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: width %s is not compatible with height %d",
- name, frameWidth, frameHeight));
+ String format = "Rejecting %s, reason: width %s is not compatible with height %d";
+ Log.v(TAG, String.format(format, name, frameWidth, frameHeight));
continue;
}
} else if (frameWidth != 0) {
- if (!videoCapabilities.getSupportedWidths().contains(frameWidth)) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: supported widths %s does not contain %d",
- name, videoCapabilities.getSupportedWidths().toString(), frameWidth));
+ if (!supportedWidths.contains(frameWidth)) {
+ String format = "Rejecting %s, reason: supported widths %s does not contain %d";
+ Log.v(TAG, String.format(format, name, supportedWidths.toString(), frameWidth));
continue;
}
} else if (frameHeight != 0) {
- if (!videoCapabilities.getSupportedHeights().contains(frameHeight)) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: supported heights %s does not contain %d",
- name, videoCapabilities.getSupportedHeights().toString(), frameHeight));
+ if (!supportedHeights.contains(frameHeight)) {
+ String format = "Rejecting %s, reason: supported heights %s does not contain %d";
+ Log.v(TAG, String.format(format, name, supportedHeights.toString(), frameHeight));
continue;
}
}
} else {
- if (frameWidth != 0 && !videoCapabilities.getSupportedWidths().contains(frameWidth)) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: supported widths %s does not contain %d",
- name, videoCapabilities.getSupportedWidths().toString(), frameWidth));
+ if (frameWidth != 0 && !supportedWidths.contains(frameWidth)) {
+ String format = "Rejecting %s, reason: supported widths %s does not contain %d";
+ Log.v(TAG, String.format(format, name, supportedWidths.toString(), frameWidth));
continue;
}
- if (frameHeight != 0 && !videoCapabilities.getSupportedHeights().contains(frameHeight)) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: supported heights %s does not contain %d",
- name, videoCapabilities.getSupportedHeights().toString(), frameHeight));
+ if (frameHeight != 0 && !supportedHeights.contains(frameHeight)) {
+ String format = "Rejecting %s, reason: supported heights %s does not contain %d";
+ Log.v(TAG, String.format(format, name, supportedHeights.toString(), frameHeight));
continue;
}
}
- if (bitrate != 0 && !videoCapabilities.getBitrateRange().contains(bitrate)) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: bitrate range %s does not contain %d",
- name, videoCapabilities.getBitrateRange().toString(), bitrate));
+
+ Range<Integer> bitrates = videoCapabilities.getBitrateRange();
+ if (bitrate != 0 && !bitrates.contains(bitrate)) {
+ String format = "Rejecting %s, reason: bitrate range %s does not contain %d";
+ Log.v(TAG, String.format(format, name, bitrates.toString(), bitrate));
continue;
}
+
+ Range<Integer> supportedFrameRates = videoCapabilities.getSupportedFrameRates();
if (enableImprovedCheck) {
if (fps != 0) {
if (frameHeight != 0 && frameWidth != 0) {
if (!videoCapabilities.areSizeAndRateSupported(frameWidth, frameHeight, fps)) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: supported frame rates %s does not contain %d",
- name,
- videoCapabilities
- .getSupportedFrameRatesFor(frameWidth, frameHeight)
- .toString(),
- fps));
+ String format =
+ "Rejecting %s, reason: supported frame rates %s does not contain %d";
+ Log.v(TAG, String.format(format, name, supportedFrameRates.toString(), fps));
continue;
}
} else {
// At least one of frameHeight or frameWidth is 0
- if (!videoCapabilities.getSupportedFrameRates().contains(fps)) {
- Log.v(
- TAG,
- String.format(
- "Rejecting %s, reason: supported frame rates %s does not contain %d",
- name, videoCapabilities.getSupportedFrameRates().toString(), fps));
+ if (!supportedFrameRates.contains(fps)) {
+ String format =
+ "Rejecting %s, reason: supported frame rates %s does not contain %d";
+ Log.v(TAG, String.format(format, name, supportedFrameRates.toString(), fps));
continue;
}
}
}
} else {
- if (fps != 0 && !videoCapabilities.getSupportedFrameRates().contains(fps)) {
+ if (fps != 0 && !supportedFrameRates.contains(fps)) {
Log.v(
TAG,
String.format(
"Rejecting %s, reason: supported frame rates %s does not contain %d",
- name, videoCapabilities.getSupportedFrameRates().toString(), fps));
+ name, supportedFrameRates.toString(), fps));
continue;
}
}
+
String resultName =
- (secure && !name.endsWith(SECURE_DECODER_SUFFIX))
+ (mustSupportSecure && !name.endsWith(SECURE_DECODER_SUFFIX))
? (name + SECURE_DECODER_SUFFIX)
: name;
FindVideoDecoderResult findVideoDecoderResult =
new FindVideoDecoderResult(resultName, videoCapabilities, codecCapabilities);
- if (hdr && !isHdrCapableVideoDecoder(mimeType, findVideoDecoderResult)) {
+ if (mustSupportHdr && !isHdrCapableVideoDecoder(mimeType, findVideoDecoderResult)) {
Log.v(TAG, String.format("Rejecting %s, reason: codec does not support HDR", name));
continue;
}
@@ -727,7 +703,7 @@
* "" otherwise.
*/
public static String findAudioDecoder(
- String mimeType, int bitrate, boolean requireTunneledPlayback) {
+ String mimeType, int bitrate, boolean mustSupportTunnelMode) {
// Note: MediaCodecList is sorted by the framework such that the best decoders come first.
for (MediaCodecInfo info : new MediaCodecList(MediaCodecList.ALL_CODECS).getCodecInfos()) {
if (info.isEncoder()) {
@@ -745,12 +721,12 @@
if (!bitrateRange.contains(bitrate)) {
continue;
}
- if (requireTunneledPlayback
+ if (mustSupportTunnelMode
&& !codecCapabilities.isFeatureSupported(CodecCapabilities.FEATURE_TunneledPlayback)) {
continue;
}
// TODO: Determine if we can safely check if an audio codec requires the tunneled playback
- // feature. i.e., reject when |requireTunneledPlayback| == false
+ // feature. i.e., reject when |mustSupportTunnelMode| == false
// and codecCapabilities.isFeatureRequired(CodecCapabilities.FEATURE_TunneledPlayback) ==
// true.
return name;
@@ -874,7 +850,7 @@
"name: %s (%s, %s): ",
name,
supportedType,
- codecBlackList.contains(name) ? "blacklisted" : "not blacklisted");
+ videoCodecDenyList.contains(name) ? "denylisted" : "not denylisted");
CodecCapabilities codecCapabilities = info.getCapabilitiesForType(supportedType);
VideoCapabilities videoCapabilities = codecCapabilities.getVideoCapabilities();
String resultName =
diff --git a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java
index b3b8300..abb56c8 100644
--- a/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java
+++ b/src/starboard/android/apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java
@@ -162,7 +162,11 @@
* @return true if the container and the crypto scheme is supported, or false otherwise.
*/
@UsedByNative
- static boolean isWidevineCryptoSchemeSupported() {
+ static boolean isWidevineCryptoSchemeSupported(boolean usesCbcs) {
+ if (Build.VERSION.SDK_INT < 24 && usesCbcs) {
+ Log.e(TAG, "Encryption scheme 'cbcs' is not supported on this platform.");
+ return false;
+ }
return MediaDrm.isCryptoSchemeSupported(WIDEVINE_UUID);
}
@@ -173,9 +177,13 @@
* @return true if the container and the crypto scheme is supported, or false otherwise.
*/
@UsedByNative
- static boolean isWidevineCryptoSchemeSupported(String containerMimeType) {
+ static boolean isWidevineCryptoSchemeSupported(String containerMimeType, boolean usesCbcs) {
if (containerMimeType.isEmpty()) {
- return isWidevineCryptoSchemeSupported();
+ return isWidevineCryptoSchemeSupported(usesCbcs);
+ }
+ if (Build.VERSION.SDK_INT < 24 && usesCbcs) {
+ Log.e(TAG, "Encryption scheme 'cbcs' is not supported on this platform.");
+ return false;
}
return MediaDrm.isCryptoSchemeSupported(WIDEVINE_UUID, containerMimeType);
}
diff --git a/src/starboard/android/shared/android_main.cc b/src/starboard/android/shared/android_main.cc
index a44497e..0c04c79 100644
--- a/src/starboard/android/shared/android_main.cc
+++ b/src/starboard/android/shared/android_main.cc
@@ -115,12 +115,20 @@
void OnResume(ANativeActivity* activity) {
if (g_app_running) {
+ // Stop the MediaPlaybackService if activity state transits from background
+ // to foreground. Note that the MediaPlaybackService may already have
+ // been stopped before Cobalt's lifecycle state transits from Concealed
+ // to Frozen.
+ ApplicationAndroid::Get()->StopMediaPlaybackService();
ApplicationAndroid::Get()->SendAndroidCommand(AndroidCommand::kResume);
}
}
void OnPause(ANativeActivity* activity) {
if (g_app_running) {
+ // Start the MediaPlaybackService before activity state transits from
+ // foreground to background.
+ ApplicationAndroid::Get()->StartMediaPlaybackService();
ApplicationAndroid::Get()->SendAndroidCommand(AndroidCommand::kPause);
}
}
@@ -133,9 +141,9 @@
void OnWindowFocusChanged(ANativeActivity* activity, int focused) {
if (g_app_running) {
- ApplicationAndroid::Get()->SendAndroidCommand(focused
- ? AndroidCommand::kWindowFocusGained
- : AndroidCommand::kWindowFocusLost);
+ ApplicationAndroid::Get()->SendAndroidCommand(
+ focused ? AndroidCommand::kWindowFocusGained
+ : AndroidCommand::kWindowFocusLost);
}
}
@@ -168,15 +176,16 @@
}
extern "C" SB_EXPORT_PLATFORM void ANativeActivity_onCreate(
- ANativeActivity *activity, void *savedState, size_t savedStateSize) {
-
+ ANativeActivity* activity,
+ void* savedState,
+ size_t savedStateSize) {
// Start the Starboard thread the first time an Activity is created.
if (!SbThreadIsValid(g_starboard_thread)) {
Semaphore semaphore;
- g_starboard_thread = SbThreadCreate(
- 0, kSbThreadPriorityNormal, kSbThreadNoAffinity, false,
- "StarboardMain", &ThreadEntryPoint, &semaphore);
+ g_starboard_thread =
+ SbThreadCreate(0, kSbThreadPriorityNormal, kSbThreadNoAffinity, false,
+ "StarboardMain", &ThreadEntryPoint, &semaphore);
// Wait for the ApplicationAndroid to be created.
semaphore.Take();
@@ -194,8 +203,8 @@
activity->instance = ApplicationAndroid::Get();
}
-extern "C" SB_EXPORT_PLATFORM
-jboolean Java_dev_cobalt_coat_StarboardBridge_nativeIsReleaseBuild() {
+extern "C" SB_EXPORT_PLATFORM jboolean
+Java_dev_cobalt_coat_StarboardBridge_nativeIsReleaseBuild() {
#if defined(COBALT_BUILD_TYPE_GOLD)
return true;
#else
@@ -203,9 +212,10 @@
#endif
}
-extern "C" SB_EXPORT_PLATFORM
-void Java_dev_cobalt_coat_StarboardBridge_nativeInitialize(
- JniEnvExt* env, jobject starboard_bridge) {
+extern "C" SB_EXPORT_PLATFORM void
+Java_dev_cobalt_coat_StarboardBridge_nativeInitialize(
+ JniEnvExt* env,
+ jobject starboard_bridge) {
JniEnvExt::Initialize(env, starboard_bridge);
}
diff --git a/src/starboard/android/shared/application_android.cc b/src/starboard/android/shared/application_android.cc
index 45a57af..f2986e7 100644
--- a/src/starboard/android/shared/application_android.cc
+++ b/src/starboard/android/shared/application_android.cc
@@ -250,10 +250,6 @@
// Now that we have the window, signal that the Android UI thread can
// continue, before we start or resume the Starboard app.
android_command_condition_.Signal();
- // Media playback service is tied to UI window being created/destroyed
- // (rather than to the Activity lifecycle), the service should be
- // stopped before native window being created.
- StopMediaPlaybackService();
}
if (state() == kStateUnstarted) {
// This is the initial launch, so we have to start Cobalt now that we
@@ -291,10 +287,6 @@
// Now that we've suspended the Starboard app, and let go of the window,
// signal that the Android UI thread can continue.
android_command_condition_.Signal();
- // Media playback service is tied to UI window being created/destroyed
- // (rather than to the Activity lifecycle). The service should be
- // started after window being destroyed.
- StartMediaPlaybackService();
}
break;
diff --git a/src/starboard/android/shared/application_android.h b/src/starboard/android/shared/application_android.h
index 6e5a458..a1c92a6 100644
--- a/src/starboard/android/shared/application_android.h
+++ b/src/starboard/android/shared/application_android.h
@@ -96,6 +96,10 @@
void SendDateTimeConfigurationChangedEvent();
+ // Methods to start/stop Media playback service.
+ void StartMediaPlaybackService();
+ void StopMediaPlaybackService();
+
protected:
// --- Application overrides ---
void Initialize() override;
@@ -139,10 +143,6 @@
void ProcessAndroidCommand();
void ProcessAndroidInput();
void ProcessKeyboardInject();
-
- // Methods to start/stop Media playback service.
- void StartMediaPlaybackService();
- void StopMediaPlaybackService();
};
} // namespace shared
diff --git a/src/starboard/android/shared/install_target.gni b/src/starboard/android/shared/install_target.gni
index 1442c9f..dbfe29c 100644
--- a/src/starboard/android/shared/install_target.gni
+++ b/src/starboard/android/shared/install_target.gni
@@ -28,6 +28,7 @@
]
target_output = "$root_out_dir/lib${installable_target_name}.so"
+ gradle_content_dir = "$sb_install_output_dir/$content_dir"
gradle_files_dir = "$root_out_dir/gradle/$installable_target_name"
if (is_gold) {
gradle_build_type = "release"
@@ -42,30 +43,12 @@
outputs = [ "$root_out_dir/${installable_target_name}.apk" ]
- cobalt_project_dir =
- string_join("/",
- [
- root_build_dir,
- rebase_path("//starboard/android/apk", root_build_dir),
- ])
- cobalt_deploy_apk = string_join("/",
- [
- root_build_dir,
- rebase_path(outputs[0], root_build_dir),
- ])
- cobalt_content_dir =
- string_join("/",
- [
- root_build_dir,
- rebase_path("$sb_install_output_dir/$content_dir",
- root_build_dir),
- ])
- cobalt_gradle_dir =
- string_join("/",
- [
- root_build_dir,
- rebase_path(gradle_files_dir, root_build_dir),
- ])
+ cobalt_project_dir = rebase_path("//starboard/android/apk")
+ cobalt_deploy_apk = rebase_path(outputs[0])
+ cobalt_content_dir = rebase_path(gradle_content_dir)
+ cobalt_gradle_dir = rebase_path(gradle_files_dir)
+ cobalt_product_dir = rebase_path(root_out_dir)
+ cobalt_library_dir = rebase_path(root_out_dir)
script = "//starboard/build/run_bash.py"
bash_script =
@@ -75,7 +58,7 @@
"--sdk",
android_sdk_path,
"--cache",
- cobalt_gradle_dir,
+ rebase_path(root_build_dir),
"--project-dir",
cobalt_project_dir,
"-P",
@@ -87,9 +70,9 @@
"-P",
"cobaltGradleDir=$cobalt_gradle_dir",
"-P",
- "cobaltProductDir=$root_out_dir",
+ "cobaltProductDir=$cobalt_product_dir",
"-P",
- "cobaltLibraryDir=$root_out_dir",
+ "cobaltLibraryDir=$cobalt_library_dir",
"-P",
"cobaltTarget=$installable_target_name",
"-P",
diff --git a/src/starboard/android/shared/media_codec_bridge.cc b/src/starboard/android/shared/media_codec_bridge.cc
index 3b5427d..57acdad 100644
--- a/src/starboard/android/shared/media_codec_bridge.cc
+++ b/src/starboard/android/shared/media_codec_bridge.cc
@@ -166,16 +166,24 @@
return scoped_ptr<MediaCodecBridge>(NULL);
}
JniEnvExt* env = JniEnvExt::Get();
+ ScopedLocalJavaRef<jbyteArray> configuration_data;
+ if (audio_codec == kSbMediaAudioCodecOpus &&
+ audio_sample_info.audio_specific_config_size != 0) {
+ configuration_data.Reset(env->NewByteArrayFromRaw(
+ static_cast<const jbyte*>(audio_sample_info.audio_specific_config),
+ audio_sample_info.audio_specific_config_size));
+ }
ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
scoped_ptr<MediaCodecBridge> native_media_codec_bridge(
new MediaCodecBridge(handler));
jobject j_media_codec_bridge = env->CallStaticObjectMethodOrAbort(
"dev/cobalt/media/MediaCodecBridge", "createAudioMediaCodecBridge",
- "(JLjava/lang/String;ZZIILandroid/media/MediaCrypto;)Ldev/cobalt/media/"
+ "(JLjava/lang/String;IILandroid/media/MediaCrypto;[B)Ldev/cobalt/media/"
"MediaCodecBridge;",
reinterpret_cast<jlong>(native_media_codec_bridge.get()), j_mime.Get(),
- !!j_media_crypto, false, audio_sample_info.samples_per_second,
- audio_sample_info.number_of_channels, j_media_crypto);
+ audio_sample_info.samples_per_second,
+ audio_sample_info.number_of_channels, j_media_crypto,
+ configuration_data.Get());
if (!j_media_codec_bridge) {
return scoped_ptr<MediaCodecBridge>(NULL);
@@ -338,11 +346,20 @@
ScopedLocalJavaRef<jintArray> j_encrypted_bytes(
env->NewIntArrayFromRaw(encrypted_bytes.get(), subsample_count));
+ jint cipher_mode = CRYPTO_MODE_AES_CTR;
+ jint blocks_to_encrypt = 0;
+ jint blocks_to_skip = 0;
+ if (drm_sample_info.encryption_scheme == kSbDrmEncryptionSchemeAesCbc) {
+ cipher_mode = CRYPTO_MODE_AES_CBC;
+ blocks_to_encrypt = drm_sample_info.encryption_pattern.crypt_byte_block;
+ blocks_to_skip = drm_sample_info.encryption_pattern.skip_byte_block;
+ }
+
return env->CallIntMethodOrAbort(
j_media_codec_bridge_, "queueSecureInputBuffer", "(II[B[B[I[IIIIIJ)I",
index, offset, j_iv.Get(), j_key_id.Get(), j_clear_bytes.Get(),
- j_encrypted_bytes.Get(), subsample_count, CRYPTO_MODE_AES_CTR, 0, 0,
- presentation_time_microseconds);
+ j_encrypted_bytes.Get(), subsample_count, cipher_mode, blocks_to_encrypt,
+ blocks_to_skip, presentation_time_microseconds);
}
jobject MediaCodecBridge::GetOutputBuffer(jint index) {
diff --git a/src/starboard/android/shared/media_common.h b/src/starboard/android/shared/media_common.h
index 5a8d57c..aa17a47 100644
--- a/src/starboard/android/shared/media_common.h
+++ b/src/starboard/android/shared/media_common.h
@@ -60,6 +60,9 @@
if (audio_codec == kSbMediaAudioCodecAac) {
return "audio/mp4a-latm";
}
+ if (audio_codec == kSbMediaAudioCodecOpus) {
+ return "audio/opus";
+ }
return nullptr;
}
diff --git a/src/starboard/android/shared/media_decoder.cc b/src/starboard/android/shared/media_decoder.cc
index 69293d1..d6c7f71 100644
--- a/src/starboard/android/shared/media_decoder.cc
+++ b/src/starboard/android/shared/media_decoder.cc
@@ -90,7 +90,12 @@
SB_LOG(ERROR) << "Failed to create audio media codec bridge.";
return;
}
- if (audio_sample_info.audio_specific_config_size > 0) {
+ // When |audio_codec| == kSbMediaAudioCodecOpus, we instead send the audio
+ // specific configuration when we create the MediaCodec object.
+ // TODO: Determine if we should send the audio specific configuration here
+ // only when |audio_codec| == kSbMediaAudioCodecAac.
+ if (audio_codec != kSbMediaAudioCodecOpus &&
+ audio_sample_info.audio_specific_config_size > 0) {
// |audio_sample_info.audio_specific_config| is guaranteed to be outlived
// the decoder as it is stored in |FilterBasedPlayerWorkerHandler|.
pending_tasks_.push_back(Event(
diff --git a/src/starboard/android/shared/media_get_initial_buffer_capacity.cc b/src/starboard/android/shared/media_get_initial_buffer_capacity.cc
index 1634373..6002db7 100644
--- a/src/starboard/android/shared/media_get_initial_buffer_capacity.cc
+++ b/src/starboard/android/shared/media_get_initial_buffer_capacity.cc
@@ -15,5 +15,5 @@
#include "starboard/media.h"
int SbMediaGetInitialBufferCapacity() {
- return 80 * 1024 * 1024;
+ return 4 * 1024 * 1024;
}
diff --git a/src/starboard/android/shared/media_is_audio_supported.cc b/src/starboard/android/shared/media_is_audio_supported.cc
index a9c63f6..419de2a 100644
--- a/src/starboard/android/shared/media_is_audio_supported.cc
+++ b/src/starboard/android/shared/media_is_audio_supported.cc
@@ -34,11 +34,6 @@
return false;
}
- // Android now uses libopus based opus decoder.
- if (audio_codec == kSbMediaAudioCodecOpus) {
- return true;
- }
-
bool is_passthrough = false;
const char* mime =
SupportedAudioCodecToMimeType(audio_codec, &is_passthrough);
@@ -72,6 +67,12 @@
return false;
}
+ // Android uses a libopus based opus decoder for clear content, or a platform
+ // opus decoder for encrypted content, if available.
+ if (audio_codec == kSbMediaAudioCodecOpus) {
+ return true;
+ }
+
JniEnvExt* env = JniEnvExt::Get();
ScopedLocalJavaRef<jstring> j_mime(env->NewStringStandardUTFOrAbort(mime));
auto media_codec_supported =
diff --git a/src/starboard/android/shared/media_is_supported.cc b/src/starboard/android/shared/media_is_supported.cc
index bd1f79e..f6cfe75 100644
--- a/src/starboard/android/shared/media_is_supported.cc
+++ b/src/starboard/android/shared/media_is_supported.cc
@@ -12,11 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <string>
+
#include "starboard/shared/starboard/media/media_support_internal.h"
#include "starboard/android/shared/jni_env_ext.h"
#include "starboard/android/shared/media_common.h"
#include "starboard/media.h"
+#include "starboard/shared/starboard/media/mime_type.h"
#include "starboard/string.h"
bool SbMediaIsSupported(SbMediaVideoCodec video_codec,
@@ -24,24 +27,35 @@
const char* key_system) {
using starboard::android::shared::IsWidevineL1;
using starboard::android::shared::JniEnvExt;
+ using starboard::shared::starboard::media::MimeType;
- if (strchr(key_system, ';')) {
- // TODO: Remove this check and enable key system with attributes support.
+ // It is possible that the |key_system| comes with extra attributes, like
+ // `com.widevine.alpha; encryptionscheme="cenc"`. We prepend "key_system/"
+ // to it, so it can be parsed by MimeType.
+ MimeType mime_type(std::string("key_system/") + key_system);
+ mime_type.RegisterStringParameter("encryptionscheme", "cenc|cbcs|cbcs-1-9");
+ if (!mime_type.is_valid()) {
return false;
}
- // We support all codecs except Opus in L1. Use allow list to avoid
- // accidentally introducing the support of a codec brought in in future.
+ // Use allow list to avoid accidentally introducing the support of a codec
+ // brought in the future.
if (audio_codec != kSbMediaAudioCodecNone &&
audio_codec != kSbMediaAudioCodecAac &&
+ audio_codec != kSbMediaAudioCodecOpus &&
audio_codec != kSbMediaAudioCodecAc3 &&
audio_codec != kSbMediaAudioCodecEac3) {
return false;
}
- if (!IsWidevineL1(key_system)) {
+ const char* key_system_type = mime_type.subtype().c_str();
+ if (!IsWidevineL1(key_system_type)) {
return false;
}
+ std::string encryption_scheme =
+ mime_type.GetParamStringValue("encryptionscheme", "");
+ bool uses_cbcs =
+ encryption_scheme == "cbcs" || encryption_scheme == "cbcs-1-9";
return JniEnvExt::Get()->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaDrmBridge",
- "isWidevineCryptoSchemeSupported", "()Z") == JNI_TRUE;
+ "isWidevineCryptoSchemeSupported", "(Z)Z", uses_cbcs) == JNI_TRUE;
}
diff --git a/src/starboard/android/shared/media_is_video_supported.cc b/src/starboard/android/shared/media_is_video_supported.cc
index 09895ed..d4e8a48 100644
--- a/src/starboard/android/shared/media_is_video_supported.cc
+++ b/src/starboard/android/shared/media_is_video_supported.cc
@@ -130,8 +130,8 @@
const bool require_secure_playback = must_support_tunnel_mode;
return env->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaCodecUtil", "hasVideoDecoderFor",
- "(Ljava/lang/String;ZIIIIZZ)Z", j_mime.Get(),
- require_secure_playback, frame_width, frame_height,
- static_cast<jint>(bitrate), fps, must_support_hdr,
- must_support_tunnel_mode) == JNI_TRUE;
+ "(Ljava/lang/String;ZZZIIII)Z", j_mime.Get(),
+ require_secure_playback, must_support_hdr,
+ must_support_tunnel_mode, frame_width, frame_height,
+ static_cast<jint>(bitrate), fps) == JNI_TRUE;
}
diff --git a/src/starboard/android/shared/platform_configuration/BUILD.gn b/src/starboard/android/shared/platform_configuration/BUILD.gn
index 75b13be..f2f9739 100644
--- a/src/starboard/android/shared/platform_configuration/BUILD.gn
+++ b/src/starboard/android/shared/platform_configuration/BUILD.gn
@@ -31,20 +31,13 @@
cflags += [ "-O2" ]
}
if (is_debug) {
- cflags += [
- "-frtti",
- "-O0",
- ]
+ cflags += [ "-O0" ]
+ configs += [ "//build/config/compiler:rtti" ]
} else if (is_devel) {
- cflags += [
- "-frtti",
- "-O2",
- ]
+ cflags += [ "-O2" ]
+ configs += [ "//build/config/compiler:rtti" ]
} else {
- cflags += [
- "-fno-rtti",
- "-gline-tables-only",
- ]
+ cflags += [ "-gline-tables-only" ]
}
libs = [
@@ -96,7 +89,6 @@
# Other flags
"-fsigned-char",
"-fno-limit-debug-info",
- "-fno-exceptions",
"-fcolor-diagnostics",
"-fno-strict-aliasing", # See http://crbug.com/32204
diff --git a/src/starboard/android/shared/player_components_factory.h b/src/starboard/android/shared/player_components_factory.h
index 037e757..a4041e2 100644
--- a/src/starboard/android/shared/player_components_factory.h
+++ b/src/starboard/android/shared/player_components_factory.h
@@ -54,6 +54,10 @@
// mode on all playbacks.
constexpr bool kForceTunnelMode = false;
+// By default, the platform Opus decoder is only enabled for encrypted playback.
+// Set the following variable to true to force it for clear playback.
+constexpr bool kForcePlatformOpusDecoder = false;
+
// On some platforms tunnel mode is only supported in the secure pipeline. Set
// the following variable to true to force creating a secure pipeline in tunnel
// mode, even for clear content.
@@ -350,15 +354,19 @@
auto decoder_creator = [](const SbMediaAudioSampleInfo& audio_sample_info,
SbDrmSystem drm_system) {
- if (audio_sample_info.codec == kSbMediaAudioCodecAac) {
- scoped_ptr<AudioDecoder> audio_decoder_impl(new AudioDecoder(
- audio_sample_info.codec, audio_sample_info, drm_system));
+ bool use_libopus_decoder =
+ audio_sample_info.codec == kSbMediaAudioCodecOpus &&
+ !SbDrmSystemIsValid(drm_system) && !kForcePlatformOpusDecoder;
+ if (use_libopus_decoder) {
+ scoped_ptr<OpusAudioDecoder> audio_decoder_impl(
+ new OpusAudioDecoder(audio_sample_info));
if (audio_decoder_impl->is_valid()) {
return audio_decoder_impl.PassAs<AudioDecoderBase>();
}
- } else if (audio_sample_info.codec == kSbMediaAudioCodecOpus) {
- scoped_ptr<OpusAudioDecoder> audio_decoder_impl(
- new OpusAudioDecoder(audio_sample_info));
+ } else if (audio_sample_info.codec == kSbMediaAudioCodecAac ||
+ audio_sample_info.codec == kSbMediaAudioCodecOpus) {
+ scoped_ptr<AudioDecoder> audio_decoder_impl(new AudioDecoder(
+ audio_sample_info.codec, audio_sample_info, drm_system));
if (audio_decoder_impl->is_valid()) {
return audio_decoder_impl.PassAs<AudioDecoderBase>();
}
@@ -526,8 +534,8 @@
bool is_encrypted = !!j_media_crypto;
if (env->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaCodecUtil", "hasVideoDecoderFor",
- "(Ljava/lang/String;ZIIIIZZ)Z", j_mime.Get(), is_encrypted, 0, 0, 0,
- 0, false, true) == JNI_TRUE) {
+ "(Ljava/lang/String;ZZZIIII)Z", j_mime.Get(), is_encrypted, false,
+ true, 0, 0, 0, 0) == JNI_TRUE) {
return true;
}
@@ -536,8 +544,8 @@
auto support_tunnel_mode_under_secure_pipeline =
env->CallStaticBooleanMethodOrAbort(
"dev/cobalt/media/MediaCodecUtil", "hasVideoDecoderFor",
- "(Ljava/lang/String;ZIIIIZZ)Z", j_mime.Get(), kIsEncrypted, 0, 0,
- 0, 0, false, true) == JNI_TRUE;
+ "(Ljava/lang/String;ZZZIIII)Z", j_mime.Get(), kIsEncrypted, false,
+ true, 0, 0, 0, 0) == JNI_TRUE;
if (support_tunnel_mode_under_secure_pipeline) {
*force_secure_pipeline_under_tunnel_mode = true;
return true;
diff --git a/src/starboard/android/shared/player_create.cc b/src/starboard/android/shared/player_create.cc
index e9e1041..a79fa48 100644
--- a/src/starboard/android/shared/player_create.cc
+++ b/src/starboard/android/shared/player_create.cc
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <string>
+
#include "starboard/player.h"
#include "starboard/android/shared/video_decoder.h"
@@ -92,21 +94,21 @@
if (!sample_deallocate_func) {
SB_LOG(ERROR) << "|sample_deallocate_func| cannot be null.";
player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
- "|sample_deallocate_func| cannot be null.");
+ "|sample_deallocate_func| cannot be null");
return kSbPlayerInvalid;
}
if (!decoder_status_func) {
SB_LOG(ERROR) << "|decoder_status_func| cannot be null.";
player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
- "|decoder_status_func| cannot be null.");
+ "|decoder_status_func| cannot be null");
return kSbPlayerInvalid;
}
if (!player_status_func) {
SB_LOG(ERROR) << "|player_status_func| cannot be null.";
player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
- "|player_status_func| cannot be null.");
+ "|player_status_func| cannot be null");
return kSbPlayerInvalid;
}
diff --git a/src/starboard/build/config/BUILDCONFIG.gn b/src/starboard/build/config/BUILDCONFIG.gn
index b3356ca..52910cb 100644
--- a/src/starboard/build/config/BUILDCONFIG.gn
+++ b/src/starboard/build/config/BUILDCONFIG.gn
@@ -26,9 +26,6 @@
cobalt_fastbuild = getenv("IS_CI") == 1
is_internal_build = false
-
- # TODO: Remove this flag when the affected targets can be built.
- can_build_evergreen_loader_apps = true
}
is_debug = build_type == "debug"
@@ -104,39 +101,89 @@
default_compiler_configs = [
"//build/config/compiler:default_include_dirs",
"//build/config/compiler:no_exceptions",
- "//$starboard_path/platform_configuration",
+ "//build/config/compiler:thin_archive",
"//starboard/build/config:base",
"//starboard/build/config:host",
"//starboard/build/config:size",
"//starboard/build/config:target",
- "//starboard/build/config:no_pedantic_warnings",
]
if (is_starboard) {
default_compiler_configs += [ "//starboard/build/config:starboard" ]
}
+if (is_qa || is_gold) {
+ default_compiler_configs += [ "//build/config/compiler:no_rtti" ]
+}
+
set_defaults("static_library") {
configs = default_compiler_configs + static_library_configs
+ has_pedantic_warnings = false
}
set_defaults("source_set") {
configs = default_compiler_configs + source_set_configs
+ has_pedantic_warnings = false
}
set_defaults("loadable_module") {
configs = default_compiler_configs + loadable_module_configs
+ has_pedantic_warnings = false
}
set_defaults("executable") {
configs = default_compiler_configs + executable_configs
+ has_pedantic_warnings = false
}
set_defaults("shared_library") {
configs = default_compiler_configs + shared_library_configs
+ has_pedantic_warnings = false
+}
+
+# We make sure to change the pedantic_warnings configs in a particular order to
+# ensure -Wno-foo compiler flags (usually set in no_pedantic_warnings and some
+# of the platform_configuration) come after -Wfoo flags (including -Wall and
+# -Wextra which are set in pedantic_warnings). It is only certain the the "foo"
+# error will be ignored if -Wfoo precedes -Wno-foo in the compilation line.
+template("target_with_platform_configs") {
+ target(invoker.target_type, target_name) {
+ forward_variables_from(invoker, "*", [ "target_type" ])
+
+ if (has_pedantic_warnings) {
+ configs += [ "//starboard/build/config:pedantic_warnings" ]
+ }
+ configs += [ "//$starboard_path/platform_configuration" ]
+ if (!has_pedantic_warnings) {
+ configs += [ "//starboard/build/config:no_pedantic_warnings" ]
+ }
+ }
+}
+
+# Ensure the platform_configuration config is the last one included.
+template("static_library") {
+ target_with_platform_configs(target_name) {
+ target_type = "static_library"
+ forward_variables_from(invoker, "*")
+ }
+}
+
+template("source_set") {
+ target_with_platform_configs(target_name) {
+ target_type = "source_set"
+ forward_variables_from(invoker, "*")
+ }
+}
+
+template("loadable_module") {
+ target_with_platform_configs(target_name) {
+ target_type = "loadable_module"
+ forward_variables_from(invoker, "*")
+ }
}
# Set up the method of generating the install targets as defined by the
# platform.
import("$install_target_path")
template("executable") {
- executable(target_name) {
+ target_with_platform_configs(target_name) {
+ target_type = "executable"
forward_variables_from(invoker, "*", [ "install_target" ])
}
@@ -155,7 +202,8 @@
}
template("shared_library") {
- shared_library(target_name) {
+ target_with_platform_configs(target_name) {
+ target_type = "shared_library"
forward_variables_from(invoker, "*", [ "install_target" ])
}
diff --git a/src/starboard/build/config/components.gni b/src/starboard/build/config/components.gni
index d983e19..7aef3d1 100644
--- a/src/starboard/build/config/components.gni
+++ b/src/starboard/build/config/components.gni
@@ -50,6 +50,16 @@
target(_component_mode, target_name) {
forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
+
+ if (is_starboard) {
+ if (_component_mode == "source_set") {
+ configs += source_set_configs
+ } else if (_component_mode == "static_library") {
+ configs += static_library_configs
+ } else if (_component_mode == "shared_library") {
+ configs += shared_library_configs
+ }
+ }
}
}
diff --git a/src/starboard/build/doc/gn_migrate_stub_to_platform.md b/src/starboard/build/doc/gn_migrate_stub_to_platform.md
index 2f16d36..a2468f2 100644
--- a/src/starboard/build/doc/gn_migrate_stub_to_platform.md
+++ b/src/starboard/build/doc/gn_migrate_stub_to_platform.md
@@ -13,14 +13,14 @@
Here are the steps to do your migration:
1. [Copy stub files over to your platform and build them](#copy-stub-files-over-to-your-platform-and-build-them).
-2. [Replace stub toolchain with your platform's toolchain](#replace-stub-toolchain).
-3. [Replace stub configuration with your platform's configuration](#replace-stub-configuration).
-4. [Replace stubbed starboard_platform target sources with your platform's
- sources](#replace-stubbed-starboard).
+2. [Replace stub toolchain with toolchain for your platform](#replace-stub-toolchain-with-toolchain-for-your-platform).
+3. [Replace stub configuration with configuration for your platform](#replace-stub-configuration-with-configuration-for-your-platform).
+4. [Replace stubbed starboard_platform sources with sources for your platform](#replace-stubbed-starboard_platform-sources-with-sources-for-your-platform).
-After each step, you should be able to build the starboard_platform target.
-For example, you would build raspi2 starboard_platform target with the following
+After each step, you should be able to build the starboard_platform target. For
+example, you would build raspi2 starboard_platform target with the following
commands:
+
```
$gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel"'
$ninja -C out/raspi-2gn_devel/ starboard
@@ -48,33 +48,35 @@
should be able to build your platform target with the stubbed out files
suggested in the above section.
-### Replace Stub Toolchain with Your Platform's Toolchain {#replace-stub-toolchain}
+### Replace Stub Toolchain with Toolchain for Your Platform
Follow instructions [here](./migrating_gyp_to_gn.md#migrating-a-toolchain) for
migrating the toolchain. Resolve errors and build the starboard_platform target
with the stubbed files.
-### Replace Stub Configuration with Your Platform's Configuration {#replace-stub-configuration}
+### Replace Stub Configuration with Configuration for Your Platform
This involves migrating the compiler flags and build variables as referenced
[here](./migrating_gyp_to_gn.md#migrating-a-platform).
> **Highly recommended** \
-> It’s good to turn off the `treat_warnings_as_errors flag` until you can compile
-> the starboard_platform target with the platform files.
-> If this flag is not disabled you might run into a lot of
-> warnings turned errors and it might take time to solve all those errors.
-> Meanwhile you won't be in a buildable state which might make it uncertain as to
-> how much progress you are actually making.
-> For disabling the flag you can pass that as an argument to gn.
-> Here's an example for disabling the flag for raspi2:
+> It’s good to turn off the `treat_warnings_as_errors flag` until you can
+> compile the starboard_platform target with the platform files. If this flag is
+> not disabled you might run into a lot of warnings turned errors and it might
+> take time to solve all those errors. Meanwhile you won't be in a buildable
+> state which might make it uncertain as to how much progress you are actually
+> making. For disabling the flag you can pass that as an argument to gn. Here's
+> an example for disabling the flag for raspi2:
+>
> ```
-> $gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel" treat_warnings_as_errors=false'
+> $gn gen out/raspi-2gn_devel
+> --args='target_platform="raspi-2" build_type="devel"
+> treat_warnings_as_errors=false'
> ```
Resolve errors and build the starboard_platform target with the stubbed files.
-### Replace Stubbed starboard_platform Sources with Your Platform's Sources {#replace-stubbed-starboard}
+### Replace Stubbed starboard_platform Sources with Sources for Your Platform
This involves adding files for the starboard_platform target as suggested
[here](./migrating_gyp_to_gn.md#migrating-a-platform).
@@ -123,6 +125,7 @@
> Default variables such as `target_cpu`, `target_os` and others can be
> overridden by passing arguments to gn while building. Here's an
> example of passing the default argument `target_cpu` for raspi2:
+ >
> ```
> $gn gen out/raspi-2gn_devel --args='target_platform="raspi-2" build_type="devel" target_cpu="arm"'
> ```
diff --git a/src/starboard/build/doc/migrating_gyp_to_gn.md b/src/starboard/build/doc/migrating_gyp_to_gn.md
index 5834300..276bc92 100644
--- a/src/starboard/build/doc/migrating_gyp_to_gn.md
+++ b/src/starboard/build/doc/migrating_gyp_to_gn.md
@@ -79,7 +79,7 @@
```
You also may need to remove default configs. The default configs are listed in
-[BUILDCONFIG.gn](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/build/config/BUILDCONFIG.gn).
+[BUILDCONFIG.gn](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/config/BUILDCONFIG.gn).
You remove a config like so:
```
@@ -145,7 +145,7 @@
Instead of implicitly searching directories for certain files like GYP did, we
explicitly enumerate our ports and their locations.
-[platforms.gni](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/build/platforms.gni)
+[platforms.gni](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/platforms.gni)
contains all of this information, and you'll need to add your platform to that
list following the same format.
@@ -173,10 +173,10 @@
You may define a toolchain from scratch following the [reference][gn_toolchain],
or you can use the
-[gcc/clang templates](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/build/toolchain/gcc_toolchain.gni)
+[gcc/clang templates](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/build/toolchain/gcc_toolchain.gni)
provided. Almost all of the reference platforms use these templates, so look to
those as examples for how to use it correctly. Here's the linux-x64x11
-[toolchain/BUILD.gn file](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/starboard/linux/x64x11/toolchain/BUILD.gn).
+[toolchain/BUILD.gn file](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/linux/x64x11/toolchain/BUILD.gn).
## Checking Your Migration
@@ -202,7 +202,7 @@
If this was equivalent to a GYP target, you can compare the ninja compilation
databases by using
-[format_ninja.py](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/src/tools/format_ninja.py)
+[format_ninja.py](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/tools/format_ninja.py)
and a comparison tool, i.e. [meld](https://meldmerge.org/). This will allow you
to see any changes in commands, i.e. with flags or otherwise.
diff --git a/src/starboard/build/doc/migration_changes.md b/src/starboard/build/doc/migration_changes.md
index 433d1a3..650d107 100644
--- a/src/starboard/build/doc/migration_changes.md
+++ b/src/starboard/build/doc/migration_changes.md
@@ -15,6 +15,7 @@
`has_drm_system_extension` | `is_internal_build` (true/false) | (global)
`has_cdm` | `is_internal_build` (true/false) | (global)
`has_private_system_properties` | `is_internal_build` (true/false) | (global)
+`sb_pedantic_warnings` (0/1) | `has_pedantic_warnings` (true/false) | (global, see "Compiler Options" note)
`sb_deploy_output_dir` | `sb_install_output_dir` | `//starboard/build/config/base_configuration.gni`
`sb_evergreen` (0/1) | `sb_is_evergreen` (true/false) | `//starboard/build/config/base_configuration.gni`
`sb_evergreen_compatible` (0/1) | `sb_is_evergreen_compatible` (true/false) | `//starboard/build/config/base_configuration.gni`
@@ -38,10 +39,8 @@
`optimize_target_for_speed` (1) | `"//starboard/build/config:speed"` | Optimizations
`compiler_flags_*_speed` | `speed_config_path` | Optimizations
`compiler_flags_*_size` | `size_config_path` | Optimizations
-`sb_pedantic_warnings` | `pedantic_warnings_config_path` | Compiler Options
-`sb_pedantic_warnings` | `no_pedantic_warnings_config_path` | Compiler Options
-Notes:
+## Notes:
* *Starboard Implementation:* If your platform defined
`STARBOARD_IMPLENTATION` in its implementation, you would now add the above
@@ -56,13 +55,12 @@
correct ones for `speed_config_path` and `size_config_path` in your
platform's `platform_configuration/configuration.gni` file.
-* *Compiler Options:* Cobalt compiles some targets with stricter settings
- than others, depending on the platform. Before these targets would opt into
- the stricter settings by settings `sb_pedantic_warnings: 1` in their
- `variables` section. Now they will add the appropriate config like so:
- `configs += [ "//starboard/build/config:pedantic_warnings" ]` and remove
- the default: `configs -= [ "//starboard/build/config:no_pedantic_warnings"
- ]`. The additional config that is used to compile these targets is
- specified with the `pedantic_warnings_config_path` and
- `no_pedantic_warnings_config_path` variables in your platform's
- `platform_configuration/configuration.gni` file.
+* *Compiler Options:* Cobalt compiles some targets with stricter,
+ platform-dependent settings than others. Before these targets would opt into
+ the stricter settings by setting `sb_pedantic_warnings: 1` in their
+ `variables` section. Now targets will be compiled with pedantic warnings if
+ the target sets `has_pedantic_warnings=true`. The additional config that is
+ used to compile these targets is specified with the
+ `pedantic_warnings_config_path` and `no_pedantic_warnings_config_path`
+ variables in your platform's `platform_configuration/configuration.gni`
+ file.
diff --git a/src/starboard/doc/c99.md b/src/starboard/doc/c99.md
index 0030329..34a2131 100644
--- a/src/starboard/doc/c99.md
+++ b/src/starboard/doc/c99.md
@@ -31,13 +31,63 @@
* tolower
* toupper
### <math.h>
+* acos
+* acosf
+* asin
+* asinf
+* atan
+* atan2
+* atan2f
+* atanf
+* cbrt
+* cbrtf
+* ceil
+* ceilf
+* cos
+* cosf
+* div
+* erf
+* erff
+* exp
+* expf
+* exp2f
* fabs
* floor
+* floorf
+* fmod
+* fmodf
+* frexp
* isfinite
* isnan
+* labs
+* llround
+* llroundf
+* log
+* log10
+* log10f
+* log2
+* log2f
+* ldexp
+* lrint
+* lrintf
+* modf
+* nearbyint
+* nearbyintf
+* nextafter
+* nextafterf
* pow
+* powf
+* round
+* roundf
+* scalbn
+* sin
+* sinf
* sqrt
* sqrtf
+* tan
+* tanf
+* trunc
+* truncf
### <stdlib.h>
* abs
* atoi
@@ -66,6 +116,9 @@
* strrchr
* strstr
* strspn
+### <tgmath.h>
+* ceill
+* logl
### <wchar.h>
* wcscat
* wcschr
diff --git a/src/starboard/elf_loader/BUILD.gn b/src/starboard/elf_loader/BUILD.gn
index eff2b9e..9ce393b 100644
--- a/src/starboard/elf_loader/BUILD.gn
+++ b/src/starboard/elf_loader/BUILD.gn
@@ -97,33 +97,31 @@
]
}
-if (can_build_evergreen_loader_apps) {
- target(final_executable_type, "elf_loader_sys_sandbox") {
- # To properly function the system loader requires the starboard
- # symbols to be exported from the binary.
- # To allow symbols to be exported remove the '-fvisibility=hidden' flag
- # from your compiler_flags.gypi. For Linux this would be:
- # starboard/linux/shared/compiler_flags.gypi
- # Example run:
- # export LD_LIBRARY_PATH=.
- # ./elf_loader_sys_sandbox --evergreen_library=app/cobalt/lib/libcobalt.so --evergreen_content=app/cobalt/content
- sources = [ "sandbox.cc" ]
- configs += [ ":elf_loader_config" ]
+target(final_executable_type, "elf_loader_sys_sandbox") {
+ # To properly function the system loader requires the starboard
+ # symbols to be exported from the binary.
+ # To allow symbols to be exported remove the '-fvisibility=hidden' flag
+ # from your compiler_flags.gypi. For Linux this would be:
+ # starboard/linux/shared/compiler_flags.gypi
+ # Example run:
+ # export LD_LIBRARY_PATH=.
+ # ./elf_loader_sys_sandbox --evergreen_library=app/cobalt/lib/libcobalt.so --evergreen_content=app/cobalt/content
+ sources = [ "sandbox.cc" ]
+ configs += [ ":elf_loader_config" ]
- starboard_syms_path =
- rebase_path("//starboard/starboard.syms", root_build_dir)
- ldflags = [
- "-Wl,--dynamic-list=$starboard_syms_path",
- "-ldl",
- ]
+ starboard_syms_path =
+ rebase_path("//starboard/starboard.syms", root_build_dir)
+ ldflags = [
+ "-Wl,--dynamic-list=$starboard_syms_path",
+ "-ldl",
+ ]
- deps = [
- ":elf_loader_sys",
- ":evergreen_info",
- ":sabi_string",
- "//starboard",
- ]
- }
+ deps = [
+ ":elf_loader_sys",
+ ":evergreen_info",
+ ":sabi_string",
+ "//starboard",
+ ]
}
target(gtest_target_type, "elf_loader_test") {
diff --git a/src/starboard/evergreen/testing/tests/suspend_resume_test.sh b/src/starboard/evergreen/testing/tests/suspend_resume_test.sh
new file mode 100755
index 0000000..35b549f
--- /dev/null
+++ b/src/starboard/evergreen/testing/tests/suspend_resume_test.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+#
+# 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.
+
+# Unset the previous test's name and runner function.
+unset TEST_NAME
+unset TEST_FILE
+unset -f run_test
+
+TEST_NAME="SuspendResume"
+TEST_FILE="test.html"
+
+function verify_log() {
+ declare -a CrashSignals=("SIGABRT" "SIGBUS" "SIGFPE" "SIGILL" "SIGSEGV" "SIGSYS")
+
+ for VAL in ${CrashSignals[@]}; do
+ if grep -Eq "Caught signal: ${VAL}" "${1}"; then
+ log "error" "Crash detected"
+ return 1
+ fi
+ done
+
+ return 0
+}
+
+function run_test() {
+ clear_storage
+
+ LOG="${TEST_NAME}.0.log"
+ start_cobalt "file:///tests/${TEST_FILE}?channel=test" "${LOG}" LOADER --update_check_delay=1
+
+ VAR=1
+
+ for i in {1..20}
+ do
+ log "info" "SuspendResume #${VAR}"
+ sleep ${VAR}
+
+ # suspend
+ kill -s USR1 "${LOADER}"
+ if [[ $? -ne 0 ]]; then
+ log "warning" "Failed to suspend"
+ break
+ fi
+
+ sleep 1
+
+ # resume
+ kill -s CONT "${LOADER}"
+ if [[ $? -ne 0 ]]; then
+ log "warning" "Failed to resume"
+ break
+ fi
+
+ let "VAR=${VAR}+1"
+ done
+
+ return $(verify_log "${LOG_PATH}/${LOG}")
+}
diff --git a/src/starboard/linux/shared/configuration_public.h b/src/starboard/linux/shared/configuration_public.h
index 81fb6b6..98a1ccc 100644
--- a/src/starboard/linux/shared/configuration_public.h
+++ b/src/starboard/linux/shared/configuration_public.h
@@ -271,12 +271,6 @@
#define SB_CAN_MAP_EXECUTABLE_MEMORY 1
#if SB_API_VERSION < 12
-// Whether this platform has and should use an growable heap (e.g. with sbrk())
-// to map physical memory to the virtual address space.
-#define SB_HAS_VIRTUAL_REGIONS 0
-#endif // SB_API_VERSION < 12
-
-#if SB_API_VERSION < 12
// Specifies the alignment for IO Buffers, in bytes. Some low-level network APIs
// may require buffers to have a specific alignment, and this is the place to
// specify that.
@@ -289,7 +283,7 @@
#endif // SB_API_VERSION < 12
#if SB_API_VERSION < 12
-// Determines the threshhold of allocation size that should be done with mmap
+// Determines the threshold of allocation size that should be done with mmap
// (if available), rather than allocated within the core heap.
#define SB_DEFAULT_MMAP_THRESHOLD ((size_t)(256 * 1024U))
#endif // SB_API_VERSION < 12
diff --git a/src/starboard/linux/shared/gyp_configuration.py b/src/starboard/linux/shared/gyp_configuration.py
index 4e4a96c..d33e2e0 100644
--- a/src/starboard/linux/shared/gyp_configuration.py
+++ b/src/starboard/linux/shared/gyp_configuration.py
@@ -121,10 +121,30 @@
'VideoDecoderTests/VideoDecoderTest.*Invalid*',
],
}
+ __FILTERED_TESTS['nplb'] = []
# Conditionally disables tests that require ipv6
- if os.getenv('IPV6_AVAILABLE', 1) == '0':
- __FILTERED_TESTS['nplb'] = [
+ if os.getenv('IPV6_AVAILABLE', '1') == '0':
+ __FILTERED_TESTS['nplb'].extend([
'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDayDestination/1',
'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceForDestination/1',
'SbSocketAddressTypes/SbSocketGetInterfaceAddressTest.SunnyDaySourceNotLoopback/1',
- ]
+ ])
+ # TODO: Re-enable once tests or infra fixed.
+ __FILTERED_TESTS['nplb'].extend([
+ 'SbSocketAddressTypes/SbSocketBindTest.RainyDayBadInterface/1',
+ 'SbSocketAddressTypes/PairSbSocketGetLocalAddressTest.SunnyDayConnected/1',
+ 'SbSocketAddressTypes/PairSbSocketIsConnectedAndIdleTest.SunnyDay/1',
+ 'SbSocketAddressTypes/PairSbSocketIsConnectedTest.SunnyDay/1',
+ 'SbSocketAddressTypes/PairSbSocketReceiveFromTest.SunnyDay/1',
+ 'SbSocketAddressTypes/SbSocketResolveTest.Localhost/1',
+ 'SbSocketAddressTypes/SbSocketResolveTest.SunnyDayFiltered/1',
+ 'SbSocketAddressTypes/PairSbSocketSendToTest.RainyDaySendToClosedSocket/1',
+ 'SbSocketAddressTypes/PairSbSocketSendToTest.RainyDaySendToSocketUntilBlocking/1',
+ 'SbSocketAddressTypes/PairSbSocketSendToTest.RainyDaySendToSocketConnectionReset/1',
+ 'SbSocketAddressTypes/PairSbSocketWaiterWaitTest.SunnyDay/1',
+ 'SbSocketAddressTypes/PairSbSocketWaiterWaitTest.SunnyDayAlreadyReady/1',
+ 'SbSocketAddressTypes/PairSbSocketWaiterWaitTimedTest.SunnyDay/1',
+ 'SbSocketAddressTypes/PairSbSocketWrapperTest.SunnyDay/1',
+ ])
+
+ # pylint: enable=line-too-long
diff --git a/src/starboard/linux/shared/launcher.py b/src/starboard/linux/shared/launcher.py
index 8888d6d..4290703 100644
--- a/src/starboard/linux/shared/launcher.py
+++ b/src/starboard/linux/shared/launcher.py
@@ -50,7 +50,8 @@
if self.device_id:
self.device_ip = self.device_id
else:
- if socket.has_ipv6: # If the device supports IPv6:
+ if os.getenv("IPV6_AVAILABLE", "1") == "1" and socket.has_ipv6:
+ # If the device supports IPv6:
self.device_id = "[::1]" # Use IPv6 loopback address (rfc2732 format).
else:
self.device_id = socket.gethostbyname("localhost") # pylint: disable=W6503
diff --git a/src/starboard/linux/shared/platform_configuration/BUILD.gn b/src/starboard/linux/shared/platform_configuration/BUILD.gn
index 9920863..7d23495 100644
--- a/src/starboard/linux/shared/platform_configuration/BUILD.gn
+++ b/src/starboard/linux/shared/platform_configuration/BUILD.gn
@@ -20,20 +20,11 @@
ldflags = []
if (is_debug) {
- cflags += [
- "-frtti",
- "-O0",
- ]
+ cflags += [ "-O0" ]
} else if (is_devel) {
- cflags += [
- "-frtti",
- "-O2",
- ]
+ cflags += [ "-O2" ]
} else {
- cflags += [
- "-fno-rtti",
- "-gline-tables-only",
- ]
+ cflags += [ "-gline-tables-only" ]
}
if (is_clang) {
@@ -149,11 +140,13 @@
"_GLIBCXX_DEBUG",
"_LIBCPP_DEBUG=1",
]
+ configs = [ "//build/config/compiler:rtti" ]
} else if (is_devel) {
defines += [
"_GLIBCXX_DEBUG",
"_LIBCPP_DEBUG=0",
]
+ configs = [ "//build/config/compiler:rtti" ]
}
}
diff --git a/src/starboard/loader_app/BUILD.gn b/src/starboard/loader_app/BUILD.gn
index cc35c66..481ccc8 100644
--- a/src/starboard/loader_app/BUILD.gn
+++ b/src/starboard/loader_app/BUILD.gn
@@ -42,24 +42,22 @@
}
}
-if (can_build_evergreen_loader_apps) {
- target(final_executable_type, "loader_app_sys") {
- if (target_cpu == "x86" || target_cpu == "x64" || target_cpu == "arm" ||
- target_cpu == "arm64") {
- sources = _common_loader_app_sources
+target(final_executable_type, "loader_app_sys") {
+ if (target_cpu == "x86" || target_cpu == "x64" || target_cpu == "arm" ||
+ target_cpu == "arm64") {
+ sources = _common_loader_app_sources
- starboard_syms_path =
- rebase_path("//starboard/starboard.syms", root_build_dir)
- ldflags = [
- "-Wl,--dynamic-list=$starboard_syms_path",
- "-ldl",
- ]
- deps = [
- ":common_loader_app_dependencies",
- "//cobalt/content/fonts:copy_font_data",
- "//starboard/elf_loader:elf_loader_sys",
- ]
- }
+ starboard_syms_path =
+ rebase_path("//starboard/starboard.syms", root_build_dir)
+ ldflags = [
+ "-Wl,--dynamic-list=$starboard_syms_path",
+ "-ldl",
+ ]
+ deps = [
+ ":common_loader_app_dependencies",
+ "//cobalt/content/fonts:copy_font_data",
+ "//starboard/elf_loader:elf_loader_sys",
+ ]
}
}
diff --git a/src/starboard/nplb/player_create_test.cc b/src/starboard/nplb/player_create_test.cc
index 535d4b9..29d8355 100644
--- a/src/starboard/nplb/player_create_test.cc
+++ b/src/starboard/nplb/player_create_test.cc
@@ -78,9 +78,9 @@
TEST_P(SbPlayerTest, SunnyDay) {
SbMediaAudioSampleInfo audio_sample_info =
CreateAudioSampleInfo(kSbMediaAudioCodecAac);
- SbMediaVideoCodec kVideoCodec = kSbMediaVideoCodecH264;
- if (!IsOutputModeSupported(output_mode_, kVideoCodec)) {
+ if (!IsOutputModeSupported(output_mode_, kSbMediaAudioCodecAac,
+ kSbMediaVideoCodecH264)) {
return;
}
@@ -101,9 +101,9 @@
TEST_P(SbPlayerTest, NullCallbacks) {
SbMediaAudioSampleInfo audio_sample_info =
CreateAudioSampleInfo(kSbMediaAudioCodecAac);
- SbMediaVideoCodec kVideoCodec = kSbMediaVideoCodecH264;
- if (!IsOutputModeSupported(output_mode_, kVideoCodec)) {
+ if (!IsOutputModeSupported(output_mode_, kSbMediaAudioCodecAac,
+ kSbMediaVideoCodecH264)) {
return;
}
@@ -160,14 +160,13 @@
}
TEST_P(SbPlayerTest, Audioless) {
- SbMediaVideoCodec kVideoCodec = kSbMediaVideoCodecH264;
-
- if (!IsOutputModeSupported(output_mode_, kVideoCodec)) {
+ if (!IsOutputModeSupported(output_mode_, kSbMediaAudioCodecNone,
+ kSbMediaVideoCodecH264)) {
return;
}
SbPlayer player = CallSbPlayerCreate(
- fake_graphics_context_provider_.window(), kVideoCodec,
+ fake_graphics_context_provider_.window(), kSbMediaVideoCodecH264,
kSbMediaAudioCodecNone, kSbDrmSystemInvalid, NULL /* audio_sample_info */,
"" /* max_video_capabilities */, DummyDeallocateSampleFunc,
DummyDecoderStatusFunc, DummyStatusFunc, DummyErrorFunc,
@@ -183,16 +182,15 @@
TEST_P(SbPlayerTest, AudioOnly) {
SbMediaAudioSampleInfo audio_sample_info =
CreateAudioSampleInfo(kSbMediaAudioCodecAac);
- SbMediaAudioCodec kAudioCodec = kSbMediaAudioCodecAac;
- SbMediaVideoCodec kVideoCodec = kSbMediaVideoCodecH264;
- if (!IsOutputModeSupported(output_mode_, kVideoCodec)) {
+ if (!IsOutputModeSupported(output_mode_, kSbMediaAudioCodecAac,
+ kSbMediaVideoCodecH264)) {
return;
}
SbPlayer player = CallSbPlayerCreate(
fake_graphics_context_provider_.window(), kSbMediaVideoCodecNone,
- kAudioCodec, kSbDrmSystemInvalid, &audio_sample_info,
+ kSbMediaAudioCodecAac, kSbDrmSystemInvalid, &audio_sample_info,
"" /* max_video_capabilities */, DummyDeallocateSampleFunc,
DummyDecoderStatusFunc, DummyStatusFunc, DummyErrorFunc,
NULL /* context */, output_mode_,
@@ -213,13 +211,10 @@
kSbPlayerOutputModeDecodeToTexture, kSbPlayerOutputModePunchOut};
constexpr SbMediaAudioCodec kAudioCodecs[] = {
- kSbMediaAudioCodecNone,
+ kSbMediaAudioCodecNone,
- kSbMediaAudioCodecAac,
- kSbMediaAudioCodecAc3,
- kSbMediaAudioCodecEac3,
- kSbMediaAudioCodecOpus,
- kSbMediaAudioCodecVorbis,
+ kSbMediaAudioCodecAac, kSbMediaAudioCodecAc3, kSbMediaAudioCodecEac3,
+ kSbMediaAudioCodecOpus, kSbMediaAudioCodecVorbis,
};
// TODO: turn this into a macro.
@@ -238,16 +233,11 @@
}
constexpr SbMediaVideoCodec kVideoCodecs[] = {
- kSbMediaVideoCodecNone,
+ kSbMediaVideoCodecNone,
- kSbMediaVideoCodecH264,
- kSbMediaVideoCodecH265,
- kSbMediaVideoCodecMpeg2,
- kSbMediaVideoCodecTheora,
- kSbMediaVideoCodecVc1,
- kSbMediaVideoCodecAv1,
- kSbMediaVideoCodecVp8,
- kSbMediaVideoCodecVp9,
+ kSbMediaVideoCodecH264, kSbMediaVideoCodecH265, kSbMediaVideoCodecMpeg2,
+ kSbMediaVideoCodecTheora, kSbMediaVideoCodecVc1, kSbMediaVideoCodecAv1,
+ kSbMediaVideoCodecVp8, kSbMediaVideoCodecVp9,
};
// TODO: turn this into a macro.
diff --git a/src/starboard/nplb/player_test_util.cc b/src/starboard/nplb/player_test_util.cc
index e4d6afd..ddcacf1 100644
--- a/src/starboard/nplb/player_test_util.cc
+++ b/src/starboard/nplb/player_test_util.cc
@@ -74,7 +74,8 @@
if (SbMediaCanPlayMimeAndKeySystem(dmp_reader.audio_mime_type().c_str(),
"")) {
for (auto output_mode : kOutputModes) {
- if (IsOutputModeSupported(output_mode, kSbMediaVideoCodecNone)) {
+ if (IsOutputModeSupported(output_mode, dmp_reader.audio_codec(),
+ kSbMediaVideoCodecNone)) {
test_configs.push_back(
std::make_tuple(audio_filename, kEmptyName, output_mode));
}
@@ -90,7 +91,8 @@
continue;
}
for (auto output_mode : kOutputModes) {
- if (IsOutputModeSupported(output_mode, dmp_reader.video_codec())) {
+ if (IsOutputModeSupported(output_mode, kSbMediaAudioCodecNone,
+ dmp_reader.video_codec())) {
test_configs.push_back(
std::make_tuple(kEmptyName, video_filename, output_mode));
}
@@ -173,24 +175,26 @@
#else // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
- return SbPlayerCreate(
- window, video_codec, audio_codec, kSbDrmSystemInvalid, audio_sample_info,
- max_video_capabilities,
- sample_deallocate_func, decoder_status_func, player_status_func,
- player_error_func, context, output_mode, context_provider);
+ return SbPlayerCreate(window, video_codec, audio_codec, kSbDrmSystemInvalid,
+ audio_sample_info, max_video_capabilities,
+ sample_deallocate_func, decoder_status_func,
+ player_status_func, player_error_func, context,
+ output_mode, context_provider);
#endif // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
}
bool IsOutputModeSupported(SbPlayerOutputMode output_mode,
- SbMediaVideoCodec codec) {
+ SbMediaAudioCodec audio_codec,
+ SbMediaVideoCodec video_codec) {
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
SbPlayerCreationParam creation_param =
- CreatePlayerCreationParam(kSbMediaAudioCodecNone, codec);
+ CreatePlayerCreationParam(audio_codec, video_codec);
creation_param.output_mode = output_mode;
return SbPlayerGetPreferredOutputMode(&creation_param) == output_mode;
#else // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
- return SbPlayerOutputModeSupported(output_mode, codec, kSbDrmSystemInvalid);
+ return SbPlayerOutputModeSupported(output_mode, video_codec,
+ kSbDrmSystemInvalid);
#endif // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
}
diff --git a/src/starboard/nplb/player_test_util.h b/src/starboard/nplb/player_test_util.h
index dfb8f11..53503ee 100644
--- a/src/starboard/nplb/player_test_util.h
+++ b/src/starboard/nplb/player_test_util.h
@@ -70,7 +70,8 @@
SbDecodeTargetGraphicsContextProvider* context_provider);
bool IsOutputModeSupported(SbPlayerOutputMode output_mode,
- SbMediaVideoCodec codec);
+ SbMediaAudioCodec audio_codec,
+ SbMediaVideoCodec video_codec);
} // namespace nplb
} // namespace starboard
diff --git a/src/starboard/nplb/player_write_sample_test.cc b/src/starboard/nplb/player_write_sample_test.cc
index 13977ee..0a5d6fd 100644
--- a/src/starboard/nplb/player_write_sample_test.cc
+++ b/src/starboard/nplb/player_write_sample_test.cc
@@ -220,7 +220,9 @@
}
void SbPlayerWriteSampleTest::TearDown() {
- SB_DCHECK(SbPlayerIsValid(player_));
+ if (!SbPlayerIsValid(player_)) {
+ return;
+ }
ASSERT_FALSE(destroy_player_called_);
destroy_player_called_ = true;
diff --git a/src/starboard/raspi/2/skia/toolchain/BUILD.gn b/src/starboard/raspi/2/skia/toolchain/BUILD.gn
index 653ad00..53ae193 100644
--- a/src/starboard/raspi/2/skia/toolchain/BUILD.gn
+++ b/src/starboard/raspi/2/skia/toolchain/BUILD.gn
@@ -25,7 +25,6 @@
ld = cxx
ar = "$gcc_toolchain_ar"
- strip = "$gcc_toolchain_strip"
toolchain_args = {
is_clang = false
diff --git a/src/starboard/raspi/2/toolchain/BUILD.gn b/src/starboard/raspi/2/toolchain/BUILD.gn
index 7e872a6..ffd79f7 100644
--- a/src/starboard/raspi/2/toolchain/BUILD.gn
+++ b/src/starboard/raspi/2/toolchain/BUILD.gn
@@ -26,7 +26,6 @@
# We use whatever 'ar' resolves to in gyp.
ar = "$gcc_toolchain_ar"
- strip = "$gcc_toolchain_strip"
toolchain_args = {
is_clang = false
diff --git a/src/starboard/raspi/shared/BUILD.gn b/src/starboard/raspi/shared/BUILD.gn
index 2cc3d1c..9813050 100644
--- a/src/starboard/raspi/shared/BUILD.gn
+++ b/src/starboard/raspi/shared/BUILD.gn
@@ -20,6 +20,8 @@
static_library("starboard_platform_sources") {
check_includes = false
+ has_pedantic_warnings = true
+
sources = [
"//starboard/linux/shared/atomic_public.h",
"//starboard/linux/shared/configuration_constants.cc",
@@ -386,11 +388,7 @@
]
}
- configs += [
- "//starboard/build/config:pedantic_warnings",
- "//starboard/build/config:starboard_implementation",
- ]
- configs -= [ "//starboard/build/config:no_pedantic_warnings" ]
+ configs += [ "//starboard/build/config:starboard_implementation" ]
public_deps = [
":starboard_base_symbolize",
diff --git a/src/starboard/raspi/shared/platform_configuration/BUILD.gn b/src/starboard/raspi/shared/platform_configuration/BUILD.gn
index fe181d1..988df3e 100644
--- a/src/starboard/raspi/shared/platform_configuration/BUILD.gn
+++ b/src/starboard/raspi/shared/platform_configuration/BUILD.gn
@@ -36,13 +36,10 @@
if (is_debug) {
cflags += [ "-O0" ]
- cflags_cc += [ "-frtti" ]
} else if (is_devel) {
cflags += [ "-O2" ]
- cflags_cc += [ "-frtti" ]
} else {
cflags += [ "-Wno-unused-but-set-variable" ]
- cflags_cc += [ "-fno-rtti" ]
}
ldflags += [
@@ -63,9 +60,6 @@
]
cflags += [
- # Generated by Audio Renderer and Audio Sink implementations.
- "-Wno-reorder",
-
# Generated by code in the raspi/shared/open_max.
"-Wno-sign-compare",
@@ -124,6 +118,9 @@
cflags_cc += [
"-std=gnu++14",
"-Wno-literal-suffix",
+
+ # Generated by Audio Renderer and Audio Sink implementations.
+ "-Wno-reorder",
]
}
@@ -149,6 +146,10 @@
]
configs = [ "//starboard/raspi/shared/platform_configuration:compiler_flags" ]
+
+ if (is_debug || is_devel) {
+ configs += [ "//build/config/compiler:rtti" ]
+ }
}
config("speed") {
diff --git a/src/starboard/raspi/shared/toolchain/raspi_shared_toolchain.gni b/src/starboard/raspi/shared/toolchain/raspi_shared_toolchain.gni
index d773598..1b0b0e4 100644
--- a/src/starboard/raspi/shared/toolchain/raspi_shared_toolchain.gni
+++ b/src/starboard/raspi/shared/toolchain/raspi_shared_toolchain.gni
@@ -23,4 +23,3 @@
gcc_toolchain_ar = "ar"
gcc_toolchain_cc = "$_raspi_toolchain_path/arm-linux-gnueabihf-gcc"
gcc_toolchain_cxx = "$_raspi_toolchain_path/arm-linux-gnueabihf-g++"
-gcc_toolchain_strip = "$_raspi_toolchain_path/arm-linux-gnueabihf-strip"
diff --git a/src/starboard/shared/dlmalloc/page_internal.h b/src/starboard/shared/dlmalloc/page_internal.h
index e72fd75..e26d509 100644
--- a/src/starboard/shared/dlmalloc/page_internal.h
+++ b/src/starboard/shared/dlmalloc/page_internal.h
@@ -27,83 +27,6 @@
extern "C" {
#endif
-// A virtual memory address.
-typedef void* SbPageVirtualMemory;
-
-// Internal Virtual memory API
-//
-// This was designed to provide common wrappers around OS functions relied upon
-// by dlmalloc. However the APIs can also be used for other custom allocators,
-// but, due to platform restrictions, this is not completely generic.
-//
-// When dlmalloc requires memory from the system, it uses two different
-// approaches to get it. It either extends a growing heap, or it uses mmap() to
-// request a bunch of pages from the system.
-//
-// Its default behavior is to place small allocations into a contiguous heap,
-// and allocate large (256K+) blocks with mmap. Separating large blocks from the
-// main heap has advantages for reducing fragmentation.
-//
-// In dlmalloc, extending the heap is called "MORECORE" and, by default on POSIX
-// systems, uses sbrk().
-//
-// Since almost none of our platforms support sbrk(), we implement MORECORE by
-// reserving a large virtual region and giving that to dlmalloc. This region
-// starts off unmapped, i.e. there are no physical pages backing it, so reading
-// or writing from that region is invalid. As dlmalloc requests memory, we
-// allocate physical pages from the OS and map them to the top of the heap,
-// thereby growing the usable heap area. When the heap shrinks, we can unmap
-// those pages and free them back to the OS.
-//
-// mmap(), by contrast, allocates N pages from the OS, and the OS then maps them
-// into some arbitrary virtual address space. There is no guarantee that two
-// consecutive mmap() calls will return a contiguous block.
-//
-// SbMap() is our implementation of mmap(). On platforms such as Linux that
-// actually have mmap(), we call that directly. Otherwise we use
-// platform-specific system allocators.
-//
-// Platforms that support SbMap() must be at least starboard version 12 or
-// enable SB_HAS_MMAP in their configuration_public.h file. dlmalloc is very
-// flexible and if a platform can't implement virtual regions, it will use
-// Map() for all allocations, merging adjacent allocations when it can.
-//
-// If a platform can't use Map(), it will just use MORECORE for everything.
-// Currently we believe a mixture of both provides best behavior, but more
-// testing would be useful.
-//
-// See also dlmalloc_config.h which controls some dlmalloc behavior.
-
-#if SB_API_VERSION < 12 && SB_HAS(VIRTUAL_REGIONS)
-// Reserves a virtual address space |size_bytes| big, without mapping any
-// physical pages to that range, returning a pointer to the beginning of the
-// reserved virtual address range. To get memory that is actually usable and
-// backed by physical memory, a reserved virtual address needs to passed into
-// AllocateAndMap().
-// [Presumably size_bytes should be a multiple of a physical page size? -DG]
-SbPageVirtualMemory SbPageReserveVirtualRegion(size_t size_bytes);
-
-// Releases a virtual address space reserved with ReserveVirtualRegion().
-// [What happens if that address space is wholly or partially mapped? -DG]
-void SbPageReleaseVirtualRegion(SbPageVirtualMemory range_start);
-
-// Allocate |size_bytes| of physical memory and map it to a virtual address
-// range starting at |virtual_address|. |virtual_address| should be a pointer
-// into the range returned by ReserveVirtualRegion().
-int SbPageAllocatePhysicalAndMap(SbPageVirtualMemory virtual_address,
- size_t size_bytes);
-
-// Frees |size_bytes| of physical memory that had been mapped to
-// |virtual_address| and return them to the system. After this,
-// [virtual_address, virtual_address + size_bytes) will not be read/writable.
-int SbPageUnmapAndFreePhysical(SbPageVirtualMemory virtual_address,
- size_t size_bytes);
-
-// How big of a virtual region dlmalloc should allocate.
-size_t SbPageGetVirtualRegionSize();
-#endif // SB_API_VERSION < 12 &&
- // SB_HAS(VIRTUAL_REGIONS)
-
#if SB_API_VERSION >= 12 || SB_HAS(MMAP)
// Allocates |size_bytes| worth of physical memory pages and maps them into an
// available virtual region. On some platforms, |name| appears in the debugger
@@ -157,26 +80,6 @@
// always be a multiple of kSbMemoryPageSize.
size_t SbPageGetMappedBytes();
-// Declaration of the allocator API.
-
-#if defined(ADDRESS_SANITIZER)
-#define SB_ALLOCATOR_PREFIX
-#include <stdlib.h>
-#else
-#define SB_ALLOCATOR_PREFIX dl
-#endif
-
-#define SB_ALLOCATOR_MANGLER_2(prefix, fn) prefix##fn
-#define SB_ALLOCATOR_MANGLER(prefix, fn) SB_ALLOCATOR_MANGLER_2(prefix, fn)
-#define SB_ALLOCATOR(fn) SB_ALLOCATOR_MANGLER(SB_ALLOCATOR_PREFIX, fn)
-
-void SB_ALLOCATOR(_malloc_init)();
-void SB_ALLOCATOR(_malloc_finalize)();
-void* SB_ALLOCATOR(malloc)(size_t size);
-void* SB_ALLOCATOR(memalign)(size_t align, size_t size);
-void* SB_ALLOCATOR(realloc)(void* ptr, size_t size);
-void SB_ALLOCATOR(free)(void* ptr);
-
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/src/starboard/shared/dlmalloc/system_get_used_cpu_memory.cc b/src/starboard/shared/dlmalloc/system_get_used_cpu_memory.cc
deleted file mode 100644
index 2e9a4d3..0000000
--- a/src/starboard/shared/dlmalloc/system_get_used_cpu_memory.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 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 "starboard/memory.h"
-
-#include "starboard/shared/dlmalloc/page_internal.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Returns the number of bytes obtained from the system. The total
-// number of bytes allocated by malloc, realloc etc., is less than this
-// value. Unlike mallinfo, this function returns only a precomputed
-// result, so can be called frequently to monitor memory consumption.
-// Even if locks are otherwise defined, this function does not use them,
-// so results might not be up to date.
-//
-// See http://gee.cs.oswego.edu/pub/misc/malloc.h for more details.
-size_t SB_ALLOCATOR(malloc_footprint)();
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-int64_t SbSystemGetUsedCPUMemory() {
- return static_cast<int64_t>(SB_ALLOCATOR(malloc_footprint)());
-}
diff --git a/src/starboard/shared/libdav1d/dav1d_video_decoder.cc b/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
index 80ce0d5..1f793ac 100644
--- a/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
+++ b/src/starboard/shared/libdav1d/dav1d_video_decoder.cc
@@ -37,21 +37,8 @@
using starboard::player::JobThread;
using starboard::player::filter::CpuVideoFrame;
-int AllocatePicture(Dav1dPicture* picture, void* context) {
- SB_DCHECK(picture);
- SB_DCHECK(context);
-
- VideoDecoder* decoder = static_cast<VideoDecoder*>(context);
- return decoder->AllocatePicture(picture);
-}
-
-void ReleasePicture(Dav1dPicture* picture, void* context) {
- SB_DCHECK(picture);
- SB_DCHECK(context);
-
- VideoDecoder* decoder = static_cast<VideoDecoder*>(context);
- decoder->ReleasePicture(picture);
-}
+constexpr int kMaxDecodedFrameWidth = 3840;
+constexpr int kMaxDecodedFrameHeight = 2160;
void ReleaseInputBuffer(const uint8_t* buf, void* context) {
SB_DCHECK(context);
@@ -154,52 +141,6 @@
frames_ = std::queue<scoped_refptr<CpuVideoFrame>>();
}
-int VideoDecoder::AllocatePicture(Dav1dPicture* picture) const {
- SB_DCHECK(decoder_thread_);
- SB_DCHECK(decoder_thread_->job_queue()->BelongsToCurrentThread());
- SB_DCHECK(picture->data[0] == NULL);
- SB_DCHECK(picture->data[1] == NULL);
- SB_DCHECK(picture->data[2] == NULL);
-
- // dav1d requires that the allocated width and height is a multiple of 128.
- // NOTE: UV resolution is half that of Y resolution.
- int uv_width = (((picture->p.w + 127) / 128) * 128) / 2;
- int uv_height = (((picture->p.h + 127) / 128) * 128) / 2;
- // dav1d requires DAV1D_PICTURE_ALIGNMENT padded to allocated memory areas.
- int uv_size = uv_width * uv_height + DAV1D_PICTURE_ALIGNMENT;
-
- // This guarantees that the Y dimension is double the UV dimension.
- int y_width = uv_width * 2;
- int y_height = uv_height * 2;
- int y_size = y_width * y_height + DAV1D_PICTURE_ALIGNMENT;
-
- picture->stride[0] = y_width;
- picture->stride[1] = uv_width;
-
- void* ptr =
- SbMemoryAllocateAligned(DAV1D_PICTURE_ALIGNMENT, y_size + uv_size * 2);
- if (ptr == NULL) {
- return DAV1D_ERR(ENOMEM);
- }
- picture->data[0] = ptr;
- picture->data[1] = static_cast<uint8_t*>(ptr) + y_size;
- picture->data[2] = static_cast<uint8_t*>(ptr) + y_size + uv_size;
- return 0;
-}
-
-void VideoDecoder::ReleasePicture(Dav1dPicture* picture) const {
- SB_DCHECK(picture->data[0]);
- SB_DCHECK(picture->data[1]);
- SB_DCHECK(picture->data[2]);
- SB_DCHECK(picture->data[0] < picture->data[1]);
- SB_DCHECK(picture->data[1] < picture->data[2]);
-
- SbMemoryDeallocateAligned(picture->data[0]);
- for (int i = 0; i < 3; ++i) {
- picture->data[i] = NULL;
- }
-}
-
void VideoDecoder::UpdateDecodeTarget_Locked(
const scoped_refptr<CpuVideoFrame>& frame) {
SbDecodeTarget decode_target = DecodeTargetCreate(
@@ -229,13 +170,8 @@
// TODO: Verify this setting is optimal.
dav1d_settings.n_threads = 8;
- Dav1dPicAllocator allocator;
- allocator.cookie = this; // dav1d refers to context pointers as "cookie".
- allocator.alloc_picture_callback =
- &::starboard::shared::libdav1d::AllocatePicture;
- allocator.release_picture_callback =
- &::starboard::shared::libdav1d::ReleasePicture;
- dav1d_settings.allocator = allocator;
+ dav1d_settings.frame_size_limit =
+ kMaxDecodedFrameHeight * kMaxDecodedFrameWidth;
int result = dav1d_open(&dav1d_context_, &dav1d_settings);
if (result != kDav1dSuccess) {
diff --git a/src/starboard/shared/libdav1d/dav1d_video_decoder.h b/src/starboard/shared/libdav1d/dav1d_video_decoder.h
index 0cc2c3f..49d590a 100644
--- a/src/starboard/shared/libdav1d/dav1d_video_decoder.h
+++ b/src/starboard/shared/libdav1d/dav1d_video_decoder.h
@@ -54,9 +54,6 @@
void WriteEndOfStream() override;
void Reset() override;
- int AllocatePicture(Dav1dPicture* picture) const;
- void ReleasePicture(Dav1dPicture* picture) const;
-
private:
typedef ::starboard::shared::starboard::player::filter::CpuVideoFrame
CpuVideoFrame;
diff --git a/src/starboard/shared/starboard/player/player_create.cc b/src/starboard/shared/starboard/player/player_create.cc
index 41552de..dd59c65 100644
--- a/src/starboard/shared/starboard/player/player_create.cc
+++ b/src/starboard/shared/starboard/player/player_create.cc
@@ -12,9 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <string>
+
#include "starboard/player.h"
#include "starboard/common/log.h"
+#include "starboard/common/media.h"
+#include "starboard/common/string.h"
#include "starboard/configuration.h"
#include "starboard/decode_target.h"
#include "starboard/shared/media_session/playback_state.h"
@@ -43,8 +47,15 @@
SbPlayerErrorFunc player_error_func,
void* context,
SbDecodeTargetGraphicsContextProvider* provider) {
+ if (!player_error_func) {
+ SB_LOG(ERROR) << "|player_error_func| cannot be null.";
+ return kSbPlayerInvalid;
+ }
+
if (!creation_param) {
SB_LOG(ERROR) << "CreationParam cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "CreationParam cannot be null");
return kSbPlayerInvalid;
}
@@ -62,15 +73,22 @@
if (!audio_mime) {
SB_LOG(ERROR) << "creation_param->audio_sample_info.mime cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "creation_param->video_sample_info.mime cannot be null");
return kSbPlayerInvalid;
}
if (!video_mime) {
SB_LOG(ERROR) << "creation_param->video_sample_info.mime cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "creation_param->video_sample_info.mime cannot be null");
return kSbPlayerInvalid;
}
if (!max_video_capabilities) {
SB_LOG(ERROR) << "creation_param->video_sample_info.max_video_capabilities"
<< " cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "creation_param->video_sample_info.max_video_"
+ "capabilities cannot be null");
return kSbPlayerInvalid;
}
@@ -105,12 +123,33 @@
SbDecodeTargetGraphicsContextProvider* provider) {
#endif // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
+ if (!player_error_func) {
+ SB_LOG(ERROR) << "|player_error_func| cannot be null.";
+ return kSbPlayerInvalid;
+ }
+
if (audio_sample_info) {
SB_DCHECK(audio_sample_info->codec == audio_codec);
}
- if (!sample_deallocate_func || !decoder_status_func || !player_status_func ||
- !player_error_func) {
+ if (!sample_deallocate_func) {
+ SB_LOG(ERROR) << "|sample_deallocate_func| cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "|sample_deallocate_func| cannot be null");
+ return kSbPlayerInvalid;
+ }
+
+ if (!decoder_status_func) {
+ SB_LOG(ERROR) << "|decoder_status_func| cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "|decoder_status_func| cannot be null");
+ return kSbPlayerInvalid;
+ }
+
+ if (!player_status_func) {
+ SB_LOG(ERROR) << "|player_status_func| cannot be null.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "|player_status_func| cannot be null");
return kSbPlayerInvalid;
}
@@ -121,7 +160,13 @@
audio_mime,
#endif // SB_API_VERSION >= 12
kDefaultBitRate)) {
- SB_LOG(ERROR) << "Unsupported audio codec " << audio_codec;
+ SB_LOG(ERROR) << "Unsupported audio codec "
+ << starboard::GetMediaAudioCodecName(audio_codec) << ".";
+ player_error_func(
+ kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ starboard::FormatString("Unsupported audio codec: %s",
+ starboard::GetMediaAudioCodecName(audio_codec))
+ .c_str());
return kSbPlayerInvalid;
}
@@ -145,14 +190,24 @@
kDefaultFrameWidth, kDefaultFrameHeight, kDefaultBitRate,
kDefaultFrameRate,
output_mode == kSbPlayerOutputModeDecodeToTexture)) {
- SB_LOG(ERROR) << "Unsupported video codec " << video_codec;
+ SB_LOG(ERROR) << "Unsupported video codec "
+ << starboard::GetMediaVideoCodecName(video_codec) << ".";
+ player_error_func(
+ kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ starboard::FormatString("Unsupported video codec: %s",
+ starboard::GetMediaVideoCodecName(video_codec))
+ .c_str());
return kSbPlayerInvalid;
}
if (audio_codec != kSbMediaAudioCodecNone && !audio_sample_info) {
SB_LOG(ERROR)
<< "SbPlayerCreate() requires a non-NULL SbMediaAudioSampleInfo "
- << "when |audio_codec| is not kSbMediaAudioCodecNone";
+ << "when |audio_codec| is not kSbMediaAudioCodecNone.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "SbPlayerCreate() requires a non-NULL "
+ "SbMediaAudioSampleInfo when |audio_codec| is not "
+ "kSbMediaAudioCodecNone");
return kSbPlayerInvalid;
}
@@ -160,27 +215,41 @@
video_codec == kSbMediaVideoCodecNone) {
SB_LOG(ERROR) << "SbPlayerCreate() requires at least one audio track or"
<< " one video track.";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ "SbPlayerCreate() requires at least one audio track or "
+ "one video track");
return kSbPlayerInvalid;
}
+ std::string error_message;
if (audio_sample_info &&
audio_sample_info->number_of_channels > SbAudioSinkGetMaxChannels()) {
- SB_LOG(ERROR) << "audio_sample_info->number_of_channels ("
- << audio_sample_info->number_of_channels
- << ") exceeds the maximum"
- << " number of audio channels supported by this platform ("
- << SbAudioSinkGetMaxChannels() << ").";
+ error_message = starboard::FormatString(
+ "Number of audio channels (%d) exceeds the maximum number of audio "
+ "channels supported by this platform (%d)",
+ audio_sample_info->number_of_channels, SbAudioSinkGetMaxChannels());
+ SB_LOG(ERROR) << error_message << ".";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ error_message.c_str());
return kSbPlayerInvalid;
}
#if SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
if (SbPlayerGetPreferredOutputMode(creation_param) != output_mode) {
- SB_LOG(ERROR) << "Unsupported player output mode " << output_mode;
+ error_message = starboard::FormatString("Unsupported player output mode %d",
+ output_mode);
+ SB_LOG(ERROR) << error_message << ".";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ error_message.c_str());
return kSbPlayerInvalid;
}
#else // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
if (!SbPlayerOutputModeSupported(output_mode, video_codec, drm_system)) {
- SB_LOG(ERROR) << "Unsupported player output mode " << output_mode;
+ error_message = starboard::FormatString("Unsupported player output mode %d",
+ output_mode);
+ SB_LOG(ERROR) << error_message << ".";
+ player_error_func(kSbPlayerInvalid, context, kSbPlayerErrorDecode,
+ error_message.c_str());
return kSbPlayerInvalid;
}
#endif // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
diff --git a/src/starboard/stub/platform_configuration/BUILD.gn b/src/starboard/stub/platform_configuration/BUILD.gn
index a5bdb8f..e75f459 100644
--- a/src/starboard/stub/platform_configuration/BUILD.gn
+++ b/src/starboard/stub/platform_configuration/BUILD.gn
@@ -25,18 +25,13 @@
}
if (is_debug) {
- cflags += [
- "-frtti",
- "-O0",
- ]
+ cflags += [ "-O0" ]
+ configs += [ "//build/config/compiler:rtti" ]
} else if (is_devel) {
- cflags += [
- "-frtti",
- "-O2",
- ]
+ cflags += [ "-O2" ]
+ configs += [ "//build/config/compiler:rtti" ]
} else {
cflags += [
- "-fno-rtti",
"-O2",
"-gline-tables-only",
]
diff --git a/src/third_party/angle/src/libANGLE/HandleAllocator.cpp b/src/third_party/angle/src/libANGLE/HandleAllocator.cpp
index 013f1df..f9efef0 100644
--- a/src/third_party/angle/src/libANGLE/HandleAllocator.cpp
+++ b/src/third_party/angle/src/libANGLE/HandleAllocator.cpp
@@ -11,6 +11,7 @@
#include <algorithm>
#include <functional>
+#include <limits>
#include "common/debug.h"
diff --git a/src/third_party/crashpad/client/crashpad_client.h b/src/third_party/crashpad/client/crashpad_client.h
index 6d0c094..b9bfeeb 100644
--- a/src/third_party/crashpad/client/crashpad_client.h
+++ b/src/third_party/crashpad/client/crashpad_client.h
@@ -40,6 +40,7 @@
#if defined(STARBOARD)
#include "starboard/elf_loader/evergreen_info.h"
+#include "third_party/crashpad/snapshot/sanitized/sanitization_information.h" // nogncheck
#include "third_party/crashpad/wrapper/annotations.h"
#endif
@@ -398,6 +399,16 @@
//!
//! \return `true` on success, `false` on failure with a message logged.
static bool SendAnnotationsToHandler(CrashpadAnnotations annotations);
+
+ //! \brief Sends mapping info to the handler
+ //!
+ //! A handler must have already been installed before calling this method.
+ //! \param[in] sanitization_information A SanitizationInformation struct, whose information
+ //! was created on Evergreen startup.
+ //!
+ //! \return `true` on success, `false` on failure with a message logged.
+ static bool SendSanitizationInformationToHandler(SanitizationInformation sanitization_information);
+
#endif
//! \brief Requests that the handler capture a dump even though there hasn't
diff --git a/src/third_party/crashpad/client/crashpad_client_linux.cc b/src/third_party/crashpad/client/crashpad_client_linux.cc
index b1bba00..570be2e 100644
--- a/src/third_party/crashpad/client/crashpad_client_linux.cc
+++ b/src/third_party/crashpad/client/crashpad_client_linux.cc
@@ -137,6 +137,10 @@
}
#if defined(STARBOARD)
+ bool SendSanitizationInformation(SanitizationInformation sanitization_information) {
+ sanitization_information_ = sanitization_information;
+ return true;
+ }
bool SendEvergreenInfo(EvergreenInfo evergreen_info) {
evergreen_info_ = evergreen_info;
return SendEvergreenInfoImpl();
@@ -187,6 +191,9 @@
#if defined(STARBOARD)
const EvergreenInfo& GetEvergreenInfo() { return evergreen_info_; }
const CrashpadAnnotations& GetAnnotations() { return annotations_; }
+ const SanitizationInformation& GetSanitizationInformation() {
+ return sanitization_information_;
+ }
#endif
const ExceptionInformation& GetExceptionInfo() {
@@ -219,6 +226,7 @@
#if defined(STARBOARD)
EvergreenInfo evergreen_info_;
CrashpadAnnotations annotations_;
+ SanitizationInformation sanitization_information_;
#endif
static SignalHandler* handler_;
@@ -376,6 +384,11 @@
ExceptionHandlerProtocol::ClientInformation info = {};
info.exception_information_address =
FromPointerCast<VMAddress>(&GetExceptionInfo());
+#if defined(STARBOARD)
+ info.sanitization_information_address =
+ FromPointerCast<VMAddress>(&GetSanitizationInformation());
+#endif
+
#if defined(OS_CHROMEOS)
info.crash_loop_before_time = crash_loop_before_time_;
#endif
@@ -603,6 +616,16 @@
return SignalHandler::Get()->SendAnnotations(annotations);
}
+
+bool CrashpadClient::SendSanitizationInformationToHandler(
+ SanitizationInformation sanitization_information) {
+ if (!SignalHandler::Get()) {
+ DLOG(ERROR) << "Crashpad isn't enabled";
+ return false;
+ }
+
+ return SignalHandler::Get()->SendSanitizationInformation(sanitization_information);
+}
#endif
// static
diff --git a/src/third_party/crashpad/wrapper/wrapper.cc b/src/third_party/crashpad/wrapper/wrapper.cc
index f482f2f..aa40f75 100644
--- a/src/third_party/crashpad/wrapper/wrapper.cc
+++ b/src/third_party/crashpad/wrapper/wrapper.cc
@@ -27,6 +27,7 @@
#include "starboard/directory.h"
#include "starboard/file.h"
#include "starboard/system.h"
+#include "third_party/crashpad/snapshot/sanitized/sanitization_information.h" // nogncheck
namespace third_party {
namespace crashpad {
@@ -202,6 +203,9 @@
default_arguments,
false,
false);
+
+ ::crashpad::SanitizationInformation sanitization_info = {0, 0, 0, 1};
+ client->SendSanitizationInformationToHandler(sanitization_info);
}
bool AddEvergreenInfoToCrashpad(EvergreenInfo evergreen_info) {
diff --git a/src/third_party/google_benchmark/src/benchmark_register.h b/src/third_party/google_benchmark/src/benchmark_register.h
index 61377d7..204bf1d 100644
--- a/src/third_party/google_benchmark/src/benchmark_register.h
+++ b/src/third_party/google_benchmark/src/benchmark_register.h
@@ -1,6 +1,7 @@
#ifndef BENCHMARK_REGISTER_H
#define BENCHMARK_REGISTER_H
+#include <limits>
#include <vector>
#include "check.h"