Commit c9eb2964 authored by Ivan Sandrk's avatar Ivan Sandrk Committed by Commit Bot

Support removing windows from locked fullscreen state

Continuation of work from crrev.com/c/723422. Previous CL enabled creation of a
locked fullscreen window, and updating a window to locked fullscreen, but it
didn't support removing locked fullscreen from a window.

Design doc @ go/locked-fullscreen-mode

Bug: chromium:755696
Change-Id: Ie9cd6c5944620d260c1f42d327af47b9ac569465
Reviewed-on: https://chromium-review.googlesource.com/769029
Commit-Queue: Ivan Šandrk <isandrk@chromium.org>
Reviewed-by: default avatarIstiaque Ahmed <lazyboy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517090}
parent 961944ce
...@@ -254,18 +254,28 @@ bool IsValidStateForWindowsCreateFunction( ...@@ -254,18 +254,28 @@ bool IsValidStateForWindowsCreateFunction(
return true; return true;
} }
bool HasLockedFullscreenPermissionIfNeeded(const Extension* extension,
windows::WindowState state) {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
if (state == windows::WINDOW_STATE_LOCKED_FULLSCREEN && bool IsWindowTrustedPinned(ui::BaseWindow* base_window) {
!extension->permissions_data()->HasAPIPermission( aura::Window* window = base_window->GetNativeWindow();
APIPermission::kLockWindowFullscreenPrivate)) { ash::mojom::WindowPinType type = window->GetProperty(ash::kWindowPinTypeKey);
return false; return type == ash::mojom::WindowPinType::TRUSTED_PINNED;
}
#endif
return true;
} }
void SetWindowTrustedPinned(ui::BaseWindow* base_window, bool trusted_pinned) {
aura::Window* window = base_window->GetNativeWindow();
// TRUSTED_PINNED is used here because that one locks the window fullscreen
// without allowing the user to exit (as opposed to regular PINNED).
window->SetProperty(ash::kWindowPinTypeKey,
trusted_pinned ? ash::mojom::WindowPinType::TRUSTED_PINNED
: ash::mojom::WindowPinType::NONE);
}
bool ExtensionHasLockedFullscreenPermission(const Extension* extension) {
return extension->permissions_data()->HasAPIPermission(
APIPermission::kLockWindowFullscreenPrivate);
}
#endif // defined(OS_CHROMEOS)
} // namespace } // namespace
void ZoomModeToZoomSettings(ZoomController::ZoomMode zoom_mode, void ZoomModeToZoomSettings(ZoomController::ZoomMode zoom_mode,
...@@ -580,11 +590,13 @@ ExtensionFunction::ResponseAction WindowsCreateFunction::Run() { ...@@ -580,11 +590,13 @@ ExtensionFunction::ResponseAction WindowsCreateFunction::Run() {
} }
create_params.initial_show_state = ui::SHOW_STATE_NORMAL; create_params.initial_show_state = ui::SHOW_STATE_NORMAL;
if (create_data && create_data->state) { if (create_data && create_data->state) {
if (!HasLockedFullscreenPermissionIfNeeded(extension(), #if defined(OS_CHROMEOS)
create_data->state)) { if (create_data->state == windows::WINDOW_STATE_LOCKED_FULLSCREEN &&
!ExtensionHasLockedFullscreenPermission(extension())) {
return RespondNow( return RespondNow(
Error(keys::kMissingLockWindowFullscreenPrivatePermission)); Error(keys::kMissingLockWindowFullscreenPrivatePermission));
} }
#endif
create_params.initial_show_state = create_params.initial_show_state =
ConvertToWindowShowState(create_data->state); ConvertToWindowShowState(create_data->state);
} }
...@@ -594,11 +606,7 @@ ExtensionFunction::ResponseAction WindowsCreateFunction::Run() { ...@@ -594,11 +606,7 @@ ExtensionFunction::ResponseAction WindowsCreateFunction::Run() {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
if (create_data && if (create_data &&
create_data->state == windows::WINDOW_STATE_LOCKED_FULLSCREEN) { create_data->state == windows::WINDOW_STATE_LOCKED_FULLSCREEN) {
aura::Window* window = new_window->window()->GetNativeWindow(); SetWindowTrustedPinned(new_window->window(), true);
// TRUSTED_PINNED is used here because that one locks the window fullscreen
// without allowing the user to exit (as opposed to regular PINNED).
window->SetProperty(ash::kWindowPinTypeKey,
ash::mojom::WindowPinType::TRUSTED_PINNED);
} }
#endif #endif
...@@ -676,11 +684,30 @@ ExtensionFunction::ResponseAction WindowsUpdateFunction::Run() { ...@@ -676,11 +684,30 @@ ExtensionFunction::ResponseAction WindowsUpdateFunction::Run() {
// state (crbug.com/703733). // state (crbug.com/703733).
ReportRequestedWindowState(params->update_info.state); ReportRequestedWindowState(params->update_info.state);
if (!HasLockedFullscreenPermissionIfNeeded(extension(), #if defined(OS_CHROMEOS)
params->update_info.state)) { const bool is_window_trusted_pinned =
IsWindowTrustedPinned(controller->window());
// Don't allow locked fullscreen operations on a window without the proper
// permission (also don't allow any operations on a locked window if the
// extension doesn't have the permission).
if ((is_window_trusted_pinned ||
params->update_info.state == windows::WINDOW_STATE_LOCKED_FULLSCREEN) &&
!ExtensionHasLockedFullscreenPermission(extension())) {
return RespondNow( return RespondNow(
Error(keys::kMissingLockWindowFullscreenPrivatePermission)); Error(keys::kMissingLockWindowFullscreenPrivatePermission));
} }
// state will be WINDOW_STATE_NONE if the state parameter wasn't passed from
// the JS side, and in that case we don't want to change the locked state.
if (is_window_trusted_pinned &&
params->update_info.state != windows::WINDOW_STATE_LOCKED_FULLSCREEN &&
params->update_info.state != windows::WINDOW_STATE_NONE) {
SetWindowTrustedPinned(controller->window(), false);
} else if (!is_window_trusted_pinned &&
params->update_info.state ==
windows::WINDOW_STATE_LOCKED_FULLSCREEN) {
SetWindowTrustedPinned(controller->window(), true);
}
#endif
ui::WindowShowState show_state = ui::WindowShowState show_state =
ConvertToWindowShowState(params->update_info.state); ConvertToWindowShowState(params->update_info.state);
...@@ -700,15 +727,6 @@ ExtensionFunction::ResponseAction WindowsUpdateFunction::Run() { ...@@ -700,15 +727,6 @@ ExtensionFunction::ResponseAction WindowsUpdateFunction::Run() {
if (controller->window()->IsMinimized() || if (controller->window()->IsMinimized() ||
controller->window()->IsMaximized()) controller->window()->IsMaximized())
controller->window()->Restore(); controller->window()->Restore();
#if defined(OS_CHROMEOS)
if (params->update_info.state ==
windows::WINDOW_STATE_LOCKED_FULLSCREEN) {
aura::Window* window = controller->window()->GetNativeWindow();
window->SetProperty(ash::kWindowPinTypeKey,
ash::mojom::WindowPinType::TRUSTED_PINNED);
break;
}
#endif
controller->SetFullscreenMode(true, extension()->url()); controller->SetFullscreenMode(true, extension()->url());
break; break;
case ui::SHOW_STATE_NORMAL: case ui::SHOW_STATE_NORMAL:
...@@ -791,11 +809,8 @@ ExtensionFunction::ResponseAction WindowsRemoveFunction::Run() { ...@@ -791,11 +809,8 @@ ExtensionFunction::ResponseAction WindowsRemoveFunction::Run() {
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
aura::Window* window = controller->window()->GetNativeWindow(); if (IsWindowTrustedPinned(controller->window()) &&
ash::mojom::WindowPinType type = window->GetProperty(ash::kWindowPinTypeKey); !ExtensionHasLockedFullscreenPermission(extension())) {
if (type == ash::mojom::WindowPinType::TRUSTED_PINNED &&
!extension()->permissions_data()->HasAPIPermission(
APIPermission::kLockWindowFullscreenPrivate)) {
return RespondNow( return RespondNow(
Error(keys::kMissingLockWindowFullscreenPrivatePermission)); Error(keys::kMissingLockWindowFullscreenPrivatePermission));
} }
......
...@@ -387,7 +387,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ...@@ -387,7 +387,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest,
namespace { namespace {
ash::mojom::WindowPinType GetCurrentWindowPinType() { aura::Window* GetCurrentWindow() {
extensions::WindowController* controller = nullptr; extensions::WindowController* controller = nullptr;
for (auto* iter : for (auto* iter :
extensions::WindowControllerList::GetInstance()->windows()) { extensions::WindowControllerList::GetInstance()->windows()) {
...@@ -397,11 +397,19 @@ ash::mojom::WindowPinType GetCurrentWindowPinType() { ...@@ -397,11 +397,19 @@ ash::mojom::WindowPinType GetCurrentWindowPinType() {
} }
} }
EXPECT_TRUE(controller); EXPECT_TRUE(controller);
aura::Window* window = controller->window()->GetNativeWindow(); return controller->window()->GetNativeWindow();
ash::mojom::WindowPinType type = window->GetProperty(ash::kWindowPinTypeKey); }
ash::mojom::WindowPinType GetCurrentWindowPinType() {
ash::mojom::WindowPinType type =
GetCurrentWindow()->GetProperty(ash::kWindowPinTypeKey);
return type; return type;
} }
void SetCurrentWindowPinType(ash::mojom::WindowPinType type) {
GetCurrentWindow()->SetProperty(ash::kWindowPinTypeKey, type);
}
} // namespace } // namespace
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, OpenLockedFullscreenWindow) { IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, OpenLockedFullscreenWindow) {
...@@ -425,6 +433,17 @@ IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, UpdateWindowToLockedFullscreen) { ...@@ -425,6 +433,17 @@ IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, UpdateWindowToLockedFullscreen) {
GetCurrentWindowPinType()); GetCurrentWindowPinType());
} }
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, RemoveLockedFullscreenFromWindow) {
SetCurrentWindowPinType(ash::mojom::WindowPinType::TRUSTED_PINNED);
ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
"removeLockedFullscreenFromWindow"))
<< message_;
// Make sure the current window is removed from locked-fullscreen state.
EXPECT_EQ(ash::mojom::WindowPinType::NONE, GetCurrentWindowPinType());
}
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
OpenLockedFullscreenWindowWithoutPermission) { OpenLockedFullscreenWindowWithoutPermission) {
ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission", ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
...@@ -446,7 +465,19 @@ IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, ...@@ -446,7 +465,19 @@ IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
// chrome.windows.update call fails since this extension doesn't have the // chrome.windows.update call fails since this extension doesn't have the
// correct permission and hence the current window has NONE as WindowPinType. // correct permission and hence the current window has NONE as WindowPinType.
EXPECT_EQ(ash::mojom::WindowPinType::NONE, EXPECT_EQ(ash::mojom::WindowPinType::NONE, GetCurrentWindowPinType());
}
IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
RemoveLockedFullscreenFromWindowWithoutPermission) {
SetCurrentWindowPinType(ash::mojom::WindowPinType::TRUSTED_PINNED);
ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
"removeLockedFullscreenFromWindow"))
<< message_;
// The current window is still locked-fullscreen.
EXPECT_EQ(ash::mojom::WindowPinType::TRUSTED_PINNED,
GetCurrentWindowPinType()); GetCurrentWindowPinType());
} }
#endif // defined(OS_CHROMEOS) #endif // defined(OS_CHROMEOS)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm/SnG89efu11DRvktEcYekVYV2rMCSsl2pkEODRls9nfce/TKobKSDosTnDUdoTabGe39SXpTdXIzwdBxSc8PWj0xX3O3IIwJkj2YBorI/Gs1Kxm0r+kHwEtC6mLbAntlZIJhVWEezvUABq64b0IBPF+wjZpQZvAdBAdVDJIRgMXI3EAmUJHNVf7veUlzltguNnoDeKPT1Lb4xK37L049eo/aYrinFSiWoOfpEk4gpVJMpjAMq1iyLYNLZ6MCccIhKee8dpXDCd2pQEToBEM6DPsqZAn2XBmrmaLlDntPV7N4sN9IwXOH1g91hAR0VRKWIgNpA6Fkk3P9OrtN1du6QIDAQAB", "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm/SnG89efu11DRvktEcYekVYV2rMCSsl2pkEODRls9nfce/TKobKSDosTnDUdoTabGe39SXpTdXIzwdBxSc8PWj0xX3O3IIwJkj2YBorI/Gs1Kxm0r+kHwEtC6mLbAntlZIJhVWEezvUABq64b0IBPF+wjZpQZvAdBAdVDJIRgMXI3EAmUJHNVf7veUlzltguNnoDeKPT1Lb4xK37L049eo/aYrinFSiWoOfpEk4gpVJMpjAMq1iyLYNLZ6MCccIhKee8dpXDCd2pQEToBEM6DPsqZAn2XBmrmaLlDntPV7N4sN9IwXOH1g91hAR0VRKWIgNpA6Fkk3P9OrtN1du6QIDAQAB",
"version": "0.1", "version": "0.1",
"manifest_version": 2, "manifest_version": 2,
"description": "Tests the chrome.windows.* with WindowState = locked (with permission).", "description": "Tests the chrome.windows.* with WindowState = locked-fullscreen (with permission).",
"background": { "background": {
"scripts": ["test.js"] "scripts": ["test.js"]
}, },
......
...@@ -23,9 +23,19 @@ updateWindowToLockedFullscreen = function() { ...@@ -23,9 +23,19 @@ updateWindowToLockedFullscreen = function() {
}))}); }))});
}; };
removeLockedFullscreenFromWindow = function() {
chrome.windows.getCurrent(null, function(window) {
chrome.windows.update(window.id, {state: 'fullscreen'},
chrome.test.callbackPass(function(window) {
chrome.test.assertEq('fullscreen', window.state);
}));
});
};
const tests = { const tests = {
openLockedFullscreenWindow: openLockedFullscreenWindow, openLockedFullscreenWindow: openLockedFullscreenWindow,
updateWindowToLockedFullscreen: updateWindowToLockedFullscreen, updateWindowToLockedFullscreen: updateWindowToLockedFullscreen,
removeLockedFullscreenFromWindow: removeLockedFullscreenFromWindow,
}; };
window.onload = function() { window.onload = function() {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm/SnG89efu11DRvktEcYekVYV2rMCSsl2pkEODRls9nfce/TKobKSDosTnDUdoTabGe39SXpTdXIzwdBxSc8PWj0xX3O3IIwJkj2YBorI/Gs1Kxm0r+kHwEtC6mLbAntlZIJhVWEezvUABq64b0IBPF+wjZpQZvAdBAdVDJIRgMXI3EAmUJHNVf7veUlzltguNnoDeKPT1Lb4xK37L049eo/aYrinFSiWoOfpEk4gpVJMpjAMq1iyLYNLZ6MCccIhKee8dpXDCd2pQEToBEM6DPsqZAn2XBmrmaLlDntPV7N4sN9IwXOH1g91hAR0VRKWIgNpA6Fkk3P9OrtN1du6QIDAQAB", "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm/SnG89efu11DRvktEcYekVYV2rMCSsl2pkEODRls9nfce/TKobKSDosTnDUdoTabGe39SXpTdXIzwdBxSc8PWj0xX3O3IIwJkj2YBorI/Gs1Kxm0r+kHwEtC6mLbAntlZIJhVWEezvUABq64b0IBPF+wjZpQZvAdBAdVDJIRgMXI3EAmUJHNVf7veUlzltguNnoDeKPT1Lb4xK37L049eo/aYrinFSiWoOfpEk4gpVJMpjAMq1iyLYNLZ6MCccIhKee8dpXDCd2pQEToBEM6DPsqZAn2XBmrmaLlDntPV7N4sN9IwXOH1g91hAR0VRKWIgNpA6Fkk3P9OrtN1du6QIDAQAB",
"version": "0.1", "version": "0.1",
"manifest_version": 2, "manifest_version": 2,
"description": "Tests the chrome.windows.* with WindowState = locked (without permission).", "description": "Tests the chrome.windows.* with WindowState = locked-fullscreen (without permission).",
"background": { "background": {
"scripts": ["test.js"] "scripts": ["test.js"]
}, },
......
...@@ -17,9 +17,17 @@ updateWindowToLockedFullscreen = function() { ...@@ -17,9 +17,17 @@ updateWindowToLockedFullscreen = function() {
chrome.test.callbackFail(error_msg))}); chrome.test.callbackFail(error_msg))});
}; };
removeLockedFullscreenFromWindow = function() {
chrome.windows.getCurrent(null, function(window) {
chrome.windows.update(window.id, {state: 'fullscreen'},
chrome.test.callbackFail(error_msg));
});
};
const tests = { const tests = {
openLockedFullscreenWindow: openLockedFullscreenWindow, openLockedFullscreenWindow: openLockedFullscreenWindow,
updateWindowToLockedFullscreen: updateWindowToLockedFullscreen, updateWindowToLockedFullscreen: updateWindowToLockedFullscreen,
removeLockedFullscreenFromWindow: removeLockedFullscreenFromWindow,
}; };
window.onload = function() { window.onload = function() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment