0

boca: Propagate is_paused status from/to UI.

This config allows teacher to disable tabstrip and block view on
student's device.

Bug: b:405468844
Test: Manually tested
Change-Id: Iaa3a0dde0ca7c191c24c629282f4e8e74f731ef3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6384377
Commit-Queue: April Zhou <aprilzhou@google.com>
Reviewed-by: Benjamin Zielinski <bzielinski@google.com>
Reviewed-by: Elly FJ <ellyjones@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1437876}
This commit is contained in:
April Zhou
2025-03-25 18:08:23 -07:00
committed by Chromium LUCI CQ
parent 8e9a796084
commit afb1f8d465
11 changed files with 58 additions and 17 deletions

@ -61,6 +61,7 @@ std::unique_ptr<::boca::OnTaskConfig> OnTaskConfigMojomToProto(
auto on_task_config = std::make_unique<::boca::OnTaskConfig>();
auto* active_bundle = on_task_config->mutable_active_bundle();
active_bundle->set_locked(config->is_locked);
active_bundle->set_lock_to_app_home(config->is_paused);
for (auto& item : config->tabs) {
auto* content_config = active_bundle->mutable_content_configs()->Add();
@ -126,7 +127,9 @@ mojom::ConfigPtr SessionConfigProtoToMojom(::boca::Session* session) {
tab.locked_navigation_options().navigation_type())));
}
on_task_config = mojom::OnTaskConfig::New(
session_on_task_config.active_bundle().locked(), std::move(tabs));
session_on_task_config.active_bundle().locked(),
session_on_task_config.active_bundle().lock_to_app_home(),
std::move(tabs));
}
mojom::IdentityPtr teacher;
if (session->has_teacher()) {

@ -89,12 +89,13 @@ mojom::OnTaskConfigPtr GetCommonTestLockOnTaskConfig() {
tabs.push_back(mojom::ControlledTab::New(
mojom::TabInfo::New(1, "google", GURL("http://google.com/"),
GURL("http://data/image")),
/*=navigation_type*/ mojom::NavigationType::kOpen));
/*navigation_type=*/mojom::NavigationType::kOpen));
tabs.push_back(mojom::ControlledTab::New(
mojom::TabInfo::New(2, "youtube", GURL("http://youtube.com/"),
GURL("http://data/image")),
/*=navigation_type*/ mojom::NavigationType::kBlock));
return mojom::OnTaskConfig::New(/*=is_locked*/ true, std::move(tabs));
/*navigation_type=*/mojom::NavigationType::kBlock));
return mojom::OnTaskConfig::New(/*is_locked=*/true, /*is_paused=*/true,
std::move(tabs));
}
mojom::OnTaskConfigPtr GetCommonTestUnLockedOnTaskConfig() {
@ -102,14 +103,16 @@ mojom::OnTaskConfigPtr GetCommonTestUnLockedOnTaskConfig() {
tabs.push_back(mojom::ControlledTab::New(
mojom::TabInfo::New(1, "google", GURL("http://google.com/"),
GURL("http://data/image")),
/*=navigation_type*/ mojom::NavigationType::kOpen));
return mojom::OnTaskConfig::New(/*=is_locked*/ false, std::move(tabs));
/*navigation_type=*/mojom::NavigationType::kOpen));
return mojom::OnTaskConfig::New(/*is_locked=*/false, /*is_paused=*/false,
std::move(tabs));
}
::boca::OnTaskConfig GetCommonTestLockOnTaskConfigProto() {
::boca::OnTaskConfig on_task_config;
auto* active_bundle = on_task_config.mutable_active_bundle();
active_bundle->set_locked(true);
active_bundle->set_lock_to_app_home(true);
auto* content = active_bundle->mutable_content_configs()->Add();
content->set_url("http://google.com/");
content->set_favicon_url("http://data/image");
@ -129,6 +132,7 @@ mojom::OnTaskConfigPtr GetCommonTestUnLockedOnTaskConfig() {
::boca::OnTaskConfig on_task_config;
auto* active_bundle = on_task_config.mutable_active_bundle();
active_bundle->set_locked(false);
active_bundle->set_lock_to_app_home(false);
auto* content = active_bundle->mutable_content_configs()->Add();
content->set_url("http://google.com/");
content->set_favicon_url("http://data/image");
@ -165,6 +169,7 @@ mojom::CaptionConfigPtr GetCommonCaptionConfig() {
auto* active_bundle =
session_config.mutable_on_task_config()->mutable_active_bundle();
active_bundle->set_locked(false);
active_bundle->set_lock_to_app_home(false);
auto* content = active_bundle->mutable_content_configs()->Add();
content->set_url("http://default.com/");
content->set_favicon_url("http://data/image");
@ -542,6 +547,8 @@ TEST_F(BocaAppPageHandlerTest, CreateSessionWithFullInput) {
.photo_url());
ASSERT_TRUE(request->on_task_config());
EXPECT_TRUE(request->on_task_config()->active_bundle().locked());
EXPECT_TRUE(
request->on_task_config()->active_bundle().lock_to_app_home());
ASSERT_EQ(2, request->on_task_config()
->active_bundle()
.content_configs()
@ -712,6 +719,7 @@ TEST_F(BocaAppPageHandlerTest, GetSessionWithFullInputTest) {
auto* active_bundle =
session_config.mutable_on_task_config()->mutable_active_bundle();
active_bundle->set_locked(true);
active_bundle->set_lock_to_app_home(true);
auto* content = active_bundle->mutable_content_configs()->Add();
content->set_url("http://google.com/");
content->set_favicon_url("http://data/image");
@ -774,6 +782,7 @@ TEST_F(BocaAppPageHandlerTest, GetSessionWithFullInputTest) {
ASSERT_EQ(1u, result->on_task_config->tabs.size());
ASSERT_TRUE(result->on_task_config->is_locked);
ASSERT_TRUE(result->on_task_config->is_paused);
EXPECT_EQ(mojom::NavigationType::kOpen,
result->on_task_config->tabs[0]->navigation_type);
EXPECT_EQ("http://google.com/",

@ -165,6 +165,8 @@ struct ControlledTab {
struct OnTaskConfig {
// If content will be display on students' device in lock mode.
bool is_locked;
// If the entire screen will be paused.
bool is_paused;
array<ControlledTab> tabs;
};

@ -169,6 +169,7 @@ export declare interface ControlledTab {
*/
export declare interface OnTaskConfig {
isLocked: boolean;
isPaused?: boolean;
tabs: ControlledTab[];
}

@ -72,6 +72,7 @@ export function getSessionConfigMojomToUI(session: Config|
}),
onTaskConfig: {
isLocked: session.onTaskConfig.isLocked,
isPaused: session.onTaskConfig.isPaused,
tabs: session.onTaskConfig.tabs.map((item: ControlledTabMojom) => {
return {
tab: {
@ -180,6 +181,7 @@ export class ClientDelegateFactory {
}),
onTaskConfig: {
isLocked: sessionConfig.onTaskConfig?.isLocked,
isPaused: sessionConfig.onTaskConfig?.isPaused,
tabs:
sessionConfig.onTaskConfig?.tabs.map((item: ControlledTab) => {
return {
@ -226,6 +228,7 @@ export class ClientDelegateFactory {
const result = await pageHandler.updateOnTaskConfig(
{
isLocked: onTaskConfig.isLocked,
isPaused: onTaskConfig.isPaused ? onTaskConfig.isPaused : false,
tabs: onTaskConfig.tabs.map((item: ControlledTab) => {
return {
tab: {

@ -113,6 +113,7 @@ class MockRemoteHandler extends PageHandlerRemote {
sessionStartTime: null,
onTaskConfig: {
isLocked: true,
isPaused: true,
tabs: [
{
tab: {
@ -182,6 +183,7 @@ class MockRemoteHandler extends PageHandlerRemote {
}],
onTaskConfig: {
isLocked: true,
isPaused: true,
tabs: [
{
tab: {
@ -220,6 +222,7 @@ class MockRemoteHandler extends PageHandlerRemote {
assertDeepEquals(
{
isLocked: true,
isPaused: true,
tabs: [
{
tab: {
@ -456,6 +459,7 @@ suite('ClientDelegateTest', function() {
sessionStartTime: undefined,
onTaskConfig: {
isLocked: true,
isPaused: true,
tabs: [
{
tab: {
@ -512,6 +516,7 @@ suite('ClientDelegateTest', function() {
accessCode: 'testCode',
onTaskConfig: {
isLocked: true,
isPaused: true,
tabs: [
{
tab: {
@ -554,7 +559,7 @@ suite('ClientDelegateTest', function() {
sessionStartTime: new Date(1000000),
students: [],
studentsJoinViaCode: [],
onTaskConfig: {isLocked: false, tabs: []},
onTaskConfig: {isLocked: false, isPaused: false, tabs: []},
teacher: {
id: '0',
name: 'teacher',
@ -583,6 +588,7 @@ suite('ClientDelegateTest', function() {
studentsJoinViaCode: [],
onTaskConfig: {
isLocked: false,
isPaused: false,
tabs: [],
},
accessCode: '',
@ -602,6 +608,7 @@ suite('ClientDelegateTest', function() {
const result =
await clientDelegateImpl.getInstance().updateOnTaskConfig({
isLocked: true,
isPaused: true,
tabs: [
{
tab: {

@ -78,6 +78,7 @@ inline constexpr char kFavIcon[] = "faviconUrl";
inline constexpr char kContentConfigs[] = "contentConfigs";
inline constexpr char kActiveBundle[] = "activeBundle";
inline constexpr char kLocked[] = "locked";
inline constexpr char kLockToAppHome[] = "lockToAppHome";
inline constexpr char kLockedNavigationOptions[] = "lockedNavigationOptions";
inline constexpr char kNavigationType[] = "navigationType";
inline constexpr char kSeconds[] = "seconds";

@ -223,15 +223,17 @@ TEST_F(SessionApiRequestsTest, CreateSessionWithFullInputAndSucceed) {
"\"google\",\"url\":\"https://google.com\"},{\"faviconUrl\":\"data:image/"
"123\",\"lockedNavigationOptions\":{\"navigationType\":2},\"title\":"
"\"youtube\",\"url\":\"https://"
"youtube.com\"}],\"locked\":true}}},\"main\":{\"captionsConfig\":{"
"\"captionsEnabled\":true,\"translationsEnabled\":true},\"onTaskConfig\":"
"{\"activeBundle\":{\"contentConfigs\":[{\"faviconUrl\":\"data:image/"
"youtube.com\"}],\"lockToAppHome\":false,\"locked\":true}}},\"main\":{"
"\"captionsConfig\":{\"captionsEnabled\":true,\"translationsEnabled\":"
"true},\"onTaskConfig\":{\"activeBundle\":{\"contentConfigs\":[{"
"\"faviconUrl\":\"data:image/"
"123\",\"lockedNavigationOptions\":{\"navigationType\":1},\"title\":"
"\"google\",\"url\":\"https://google.com\"},{\"faviconUrl\":\"data:image/"
"123\",\"lockedNavigationOptions\":{\"navigationType\":2},\"title\":"
"\"youtube\",\"url\":\"https://"
"youtube.com\"}],\"locked\":true}}}},\"teacher\":{\"email\":\"teacher@"
"gmail.com\",\"fullName\":\"teacher\",\"gaiaId\":\"1\"}}";
"youtube.com\"}],\"lockToAppHome\":false,\"locked\":true}}}},\"teacher\":"
"{\"email\":\"teacher@gmail.com\",\"fullName\":\"teacher\",\"gaiaId\":"
"\"1\"}}";
ASSERT_TRUE(http_request.has_content);
EXPECT_EQ(contentData, http_request.content);
EXPECT_EQ(true, result.has_value());

@ -251,6 +251,8 @@ void ParseSessionConfigProtoFromJson(base::Value::Dict* session_dict,
auto* active_bundle = on_task_config->mutable_active_bundle();
active_bundle->set_locked(
active_bundle_dict->FindBool(kLocked).value_or(false));
active_bundle->set_lock_to_app_home(
active_bundle_dict->FindBool(kLockToAppHome).value_or(false));
auto* content_configs_list =
active_bundle_dict->FindList(kContentConfigs);
if (content_configs_list) {
@ -466,6 +468,8 @@ void ParseOnTaskConfigJsonFromProto(::boca::OnTaskConfig* on_task_config,
if (on_task_config && on_task_config->has_active_bundle()) {
base::Value::Dict bundle;
bundle.Set(kLocked, on_task_config->active_bundle().locked());
bundle.Set(kLockToAppHome,
on_task_config->active_bundle().lock_to_app_home());
base::Value::List content_configs;
for (const auto& content :
on_task_config->active_bundle().content_configs()) {

@ -126,7 +126,8 @@ constexpr char kFullSessionResponse[] = R"(
"url": "https://youtube.com"
}
],
"locked": true
"locked": true,
"lockToAppHome": true
}
}
}
@ -305,6 +306,12 @@ TEST_F(SessionParserTest, TestParseSessionConfigProtoFromJson) {
.active_bundle()
.locked());
EXPECT_TRUE(session_full->student_group_configs()
.at(kMainStudentGroupName)
.on_task_config()
.active_bundle()
.lock_to_app_home());
auto content_config = std::move(session_full->student_group_configs()
.at(kMainStudentGroupName)
.on_task_config()

@ -309,14 +309,16 @@ TEST_F(UpdateSessionTest, UpdateSessionWithUpdateSessionConfigAndSucceed) {
"\"google\",\"url\":\"https://google.com\"},{\"faviconUrl\":\"data:image/"
"123\",\"lockedNavigationOptions\":{\"navigationType\":2},\"title\":"
"\"youtube\",\"url\":\"https://"
"youtube.com\"}],\"locked\":true}}},\"main\":{\"captionsConfig\":{"
"\"captionsEnabled\":true,\"translationsEnabled\":true},\"onTaskConfig\":"
"{\"activeBundle\":{\"contentConfigs\":[{\"faviconUrl\":\"data:image/"
"youtube.com\"}],\"lockToAppHome\":false,\"locked\":true}}},\"main\":{"
"\"captionsConfig\":{\"captionsEnabled\":true,\"translationsEnabled\":"
"true},\"onTaskConfig\":{\"activeBundle\":{\"contentConfigs\":[{"
"\"faviconUrl\":\"data:image/"
"123\",\"lockedNavigationOptions\":{\"navigationType\":1},\"title\":"
"\"google\",\"url\":\"https://google.com\"},{\"faviconUrl\":\"data:image/"
"123\",\"lockedNavigationOptions\":{\"navigationType\":2},\"title\":"
"\"youtube\",\"url\":\"https://"
"youtube.com\"}],\"locked\":true}}}},\"teacher\":{\"gaiaId\":\"1\"}}";
"youtube.com\"}],\"lockToAppHome\":false,\"locked\":true}}}},\"teacher\":"
"{\"gaiaId\":\"1\"}}";
ASSERT_TRUE(http_request.has_content);
EXPECT_EQ(contentData, http_request.content);
EXPECT_TRUE(result.value());