Skip to content

Commit

Permalink
Add support for user on exit strategy.
Browse files Browse the repository at this point in the history
b/385357645
  • Loading branch information
aee-google committed Jan 23, 2025
1 parent 2395442 commit 77e156a
Show file tree
Hide file tree
Showing 7 changed files with 284 additions and 0 deletions.
24 changes: 24 additions & 0 deletions cobalt/configuration/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2025 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.

static_library("configuration") {
sources = [
"configuration.cc",
"configuration.h",
]
deps = [
"//base",
"//starboard:starboard_headers_only",
]
}
54 changes: 54 additions & 0 deletions cobalt/configuration/configuration.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2025 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/configuration/configuration.h"

#include "base/logging.h"
#include "base/memory/singleton.h"
#include "starboard/system.h"

namespace cobalt {
namespace configuration {

// static
Configuration* Configuration::GetInstance() {
return base::Singleton<Configuration,
base::LeakySingletonTraits<Configuration>>::get();
}

Configuration::Configuration() {
configuration_api_ = static_cast<const CobaltExtensionConfigurationApi*>(
SbSystemGetExtension(kCobaltExtensionConfigurationName));
if (configuration_api_) {
// Verify it's the extension needed.
if (strcmp(configuration_api_->name, kCobaltExtensionConfigurationName) !=
0 ||
configuration_api_->version < 1) {
LOG(WARNING) << "Not using supplied cobalt configuration extension: "
<< "'" << configuration_api_->name << "' ("
<< configuration_api_->version << ")";
configuration_api_ = nullptr;
}
}
}

const char* Configuration::CobaltUserOnExitStrategy() {
if (configuration_api_) {
return configuration_api_->CobaltUserOnExitStrategy();
}
return "stop";
}

} // namespace configuration
} // namespace cobalt
53 changes: 53 additions & 0 deletions cobalt/configuration/configuration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2025 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_CONFIGURATION_CONFIGURATION_H_
#define COBALT_CONFIGURATION_CONFIGURATION_H_

#include "starboard/extension/configuration.h"

namespace base {
template <typename T>
struct DefaultSingletonTraits;
}

namespace cobalt {
namespace configuration {

// The Configuration changes certain Cobalt features as specified by the
// platform. This class picks up values set in the
// CobaltConfigurationExtensionApi if it is implemented by the platform and
// will otherwise use default configurations.
class Configuration {
public:
// The Configuration is a singleton initialized on the first call of
// GetInstance(). Calls to this function will return a pointer to the same
// instance as was previously initialized.
static Configuration* GetInstance();

const char* CobaltUserOnExitStrategy();

private:
Configuration();
Configuration(const Configuration&) = delete;
Configuration& operator=(const Configuration&) = delete;

friend struct base::DefaultSingletonTraits<Configuration>;
const CobaltExtensionConfigurationApi* configuration_api_;
};

} // namespace configuration
} // namespace cobalt

#endif // COBALT_CONFIGURATION_CONFIGURATION_H_
4 changes: 4 additions & 0 deletions cobalt/renderer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ source_set("renderer") {
sources = [
"cobalt_content_renderer_client.cc",
"cobalt_content_renderer_client.h",
"cobalt_render_frame_observer.cc",
"cobalt_render_frame_observer.h",
]

deps = [
"//cobalt/configuration",
"//cobalt/media/audio:webaudio",
"//components/cdm/renderer",
"//components/js_injection/renderer:renderer",
Expand All @@ -27,6 +30,7 @@ source_set("renderer") {
"//content/public/common",
"//content/public/renderer",
"//content/test:content_test_mojo_bindings",
"//gin",
"//media/mojo:buildflags",
"//starboard:starboard_headers_only",
"//v8",
Expand Down
3 changes: 3 additions & 0 deletions cobalt/renderer/cobalt_content_renderer_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "cobalt/common/shell_switches.h"
#include "cobalt/renderer/cobalt_render_frame_observer.h"
#include "components/cdm/renderer/external_clear_key_key_system_info.h"
#include "components/network_hints/renderer/web_prescient_networking_impl.h"
#include "components/web_cache/renderer/web_cache_impl.h"
Expand Down Expand Up @@ -107,6 +108,8 @@ void CobaltContentRendererClient::ExposeInterfacesToBrowser(
void CobaltContentRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) {
new js_injection::JsCommunication(render_frame);
CobaltRenderFrameObserver* render_frame_observer =
new CobaltRenderFrameObserver(render_frame);
}

void CobaltContentRendererClient::PrepareErrorPage(
Expand Down
116 changes: 116 additions & 0 deletions cobalt/renderer/cobalt_render_frame_observer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright 2025 The Cobalt Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cobalt/renderer/cobalt_render_frame_observer.h"

#include "cobalt/configuration/configuration.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/renderer/chrome_object_extensions_utils.h"
#include "content/public/renderer/render_frame.h"
#include "gin/converter.h"
#include "starboard/system.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "v8/include/v8.h"

namespace cobalt {

namespace {

enum UserOnExitStrategy {
kUserOnExitStrategyClose,
kUserOnExitStrategyMinimize,
kUserOnExitStrategyNoExit,
};

uint32_t GetUserOnExitStrategy() {
// Convert from the Cobalt gyp setting variable's enum options to the H5VCC
// interface enum options.
std::string exit_strategy_str(
configuration::Configuration::GetInstance()->CobaltUserOnExitStrategy());
if (exit_strategy_str == "stop") {
return static_cast<UserOnExitStrategy>(kUserOnExitStrategyClose);
} else if (exit_strategy_str == "suspend") {
#if SB_IS(EVERGREEN)
// Note: The status string used here must be synced with the
// ComponentState::kUpdated status string defined in updater_module.cc.
if (updater_->GetUpdateStatus() == "Update installed, pending restart") {
return static_cast<UserOnExitStrategy>(kUserOnExitStrategyClose);
}
#endif
return static_cast<UserOnExitStrategy>(kUserOnExitStrategyMinimize);
} else if (exit_strategy_str == "noexit") {
return static_cast<UserOnExitStrategy>(kUserOnExitStrategyNoExit);
} else {
NOTREACHED() << "Unknown exit strategy.";
return static_cast<UserOnExitStrategy>(kUserOnExitStrategyClose);
}
}

void WindowClose(const v8::FunctionCallbackInfo<v8::Value>& info) {
SbSystemRequestStop(0);
}

void WindowMinimize(const v8::FunctionCallbackInfo<v8::Value>& info) {
SbSystemRequestConceal();
}

void InstallCloseAndMinimize(content::RenderFrame* render_frame) {
if (!render_frame) {
return;
}

v8::Isolate* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
render_frame->GetWebFrame()->MainWorldScriptContext();
if (context.IsEmpty()) {
return;
}

v8::Context::Scope context_scope(context);
v8::Local<v8::Object> window = context->Global();
// v8::Local<v8::Object> window =
// content::GetOrCreateObject(isolate, context, "window");
window
->Set(context, gin::StringToSymbol(isolate, "minimize"),
v8::Function::New(context, WindowMinimize).ToLocalChecked())
.Check();
window
->Set(context, gin::StringToSymbol(isolate, "close"),
v8::Function::New(context, WindowClose).ToLocalChecked())
.Check();
v8::Local<v8::Object> h5vcc =
content::GetOrCreateObject(isolate, context, "h5vcc");
v8::Local<v8::Object> h5vcc_system =
content::GetOrCreateObject(isolate, context, h5vcc, "system");
// Set exit strategy to minimize.

h5vcc_system->Set(context, gin::StringToSymbol(isolate, "userOnExitStrategy"),
v8::Integer::New(isolate, GetUserOnExitStrategy()));
}

} // namespace

CobaltRenderFrameObserver::CobaltRenderFrameObserver(
content::RenderFrame* render_frame)
: content::RenderFrameObserver(render_frame) {}

void CobaltRenderFrameObserver::DidCreateScriptContext(
v8::Local<v8::Context> v8_context,
int32_t world_id) {
// Only install on the main world context of the main frame.
if (!render_frame() || !render_frame()->IsMainFrame() ||
world_id != content::ISOLATED_WORLD_ID_GLOBAL) {
return;
}

InstallCloseAndMinimize(render_frame());
}

void CobaltRenderFrameObserver::OnDestruct() {
delete this;
}

} // namespace cobalt
30 changes: 30 additions & 0 deletions cobalt/renderer/cobalt_render_frame_observer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2025 The Cobalt Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COBALT_RENDERER_COBALT_RENDERER_FRAME_OBSERVER_H_
#define COBALT_RENDERER_COBALT_RENDERER_FRAME_OBSERVER_H_

#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
#include "v8/include/v8.h"

namespace cobalt {

class CobaltRenderFrameObserver : public content::RenderFrameObserver {
public:
explicit CobaltRenderFrameObserver(content::RenderFrame* render_frame);

CobaltRenderFrameObserver(const CobaltRenderFrameObserver&) = delete;
CobaltRenderFrameObserver& operator=(const CobaltRenderFrameObserver&) =
delete;

private:
void DidCreateScriptContext(v8::Local<v8::Context> v8_context,
int32_t world_id) override;
void OnDestruct() override;
};

} // namespace cobalt

#endif // COBALT_RENDERER_COBALT_RENDERER_FRAME_OBSERVER_H_

0 comments on commit 77e156a

Please sign in to comment.