Commit fa571e82 authored by Tim Zheng's avatar Tim Zheng Committed by Commit Bot

Multi-user support for Crostini apps.

This CL adds multiple user support for Crostini apps.
Crostini app window is registered to the user who launches it so when
user switch happens, Crostini app window will not leak to other users
in the session.
When user switch occurs, Crostini app windows launched by previous user
will be removed from the Shelf and Crostini app windows launched by the
current user will be added to the Shelf.

BUG=chromium:829159
TEST=Manually tested on an eve device.

Change-Id: I2983d7087ffb87764954c2e8799b29a1ba46feec
Reviewed-on: https://chromium-review.googlesource.com/1031746Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Reviewed-by: default avatarMichael Wasserman <msw@chromium.org>
Commit-Queue: Tim Zheng <timzheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554426}
parent 4f3e0134
...@@ -15,7 +15,9 @@ ...@@ -15,7 +15,9 @@
#include "chrome/browser/ui/ash/launcher/app_window_base.h" #include "chrome/browser/ui/ash/launcher/app_window_base.h"
#include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h" #include "chrome/browser/ui/ash/launcher/app_window_launcher_item_controller.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
#include "components/exo/shell_surface.h" #include "components/exo/shell_surface.h"
#include "components/user_manager/user_manager.h"
#include "ui/aura/client/aura_constants.h" #include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h" #include "ui/aura/env.h"
#include "ui/base/base_window.h" #include "ui/base/base_window.h"
...@@ -39,6 +41,59 @@ CrostiniAppWindowShelfController::~CrostiniAppWindowShelfController() { ...@@ -39,6 +41,59 @@ CrostiniAppWindowShelfController::~CrostiniAppWindowShelfController() {
env->RemoveObserver(this); env->RemoveObserver(this);
} }
void CrostiniAppWindowShelfController::AddToShelf(aura::Window* window,
AppWindowBase* app_window) {
ash::ShelfID shelf_id = app_window->shelf_id();
AppWindowLauncherItemController* item_controller =
owner()->shelf_model()->GetAppWindowLauncherItemController(shelf_id);
if (item_controller == nullptr) {
auto controller =
std::make_unique<AppWindowLauncherItemController>(shelf_id);
item_controller = controller.get();
if (!owner()->GetItem(shelf_id)) {
owner()->CreateAppLauncherItem(std::move(controller),
ash::STATUS_RUNNING);
} else {
owner()->shelf_model()->SetShelfItemDelegate(shelf_id,
std::move(controller));
owner()->SetItemStatus(shelf_id, ash::STATUS_RUNNING);
}
window->SetProperty(ash::kShelfIDKey,
new std::string(shelf_id.Serialize()));
}
item_controller->AddWindow(app_window);
app_window->SetController(item_controller);
}
void CrostiniAppWindowShelfController::RemoveFromShelf(
aura::Window* window,
AppWindowBase* app_window) {
UnregisterAppWindow(app_window);
// Check if we may close controller now, at this point we can safely remove
// controllers without window.
AppWindowLauncherItemController* item_controller =
owner()->shelf_model()->GetAppWindowLauncherItemController(
app_window->shelf_id());
if (item_controller != nullptr && item_controller->window_count() == 0)
owner()->CloseLauncherItem(item_controller->shelf_id());
}
void CrostiniAppWindowShelfController::ActiveUserChanged(
const std::string& user_email) {
for (auto& w : aura_window_to_app_window_) {
if (MultiUserWindowManager::GetInstance()
->GetWindowOwner(w.first)
.GetUserEmail() == user_email) {
AddToShelf(w.first, w.second.get());
} else {
RemoveFromShelf(w.first, w.second.get());
}
}
}
void CrostiniAppWindowShelfController::OnWindowInitialized( void CrostiniAppWindowShelfController::OnWindowInitialized(
aura::Window* window) { aura::Window* window) {
// An Crostini window has type WINDOW_TYPE_NORMAL, a WindowDelegate and // An Crostini window has type WINDOW_TYPE_NORMAL, a WindowDelegate and
...@@ -69,6 +124,7 @@ void CrostiniAppWindowShelfController::OnWindowVisibilityChanged( ...@@ -69,6 +124,7 @@ void CrostiniAppWindowShelfController::OnWindowVisibilityChanged(
exo::ShellSurface::GetApplicationId(window); exo::ShellSurface::GetApplicationId(window);
if (window_app_id == nullptr) if (window_app_id == nullptr)
return; return;
crostini::CrostiniRegistryService* registry_service = crostini::CrostiniRegistryService* registry_service =
crostini::CrostiniRegistryServiceFactory::GetForProfile( crostini::CrostiniRegistryServiceFactory::GetForProfile(
owner()->profile()); owner()->profile());
...@@ -78,6 +134,10 @@ void CrostiniAppWindowShelfController::OnWindowVisibilityChanged( ...@@ -78,6 +134,10 @@ void CrostiniAppWindowShelfController::OnWindowVisibilityChanged(
if (shelf_app_id.empty()) if (shelf_app_id.empty())
return; return;
// Prevent Crostini window from showing up after user switch.
MultiUserWindowManager::GetInstance()->SetWindowOwner(
window,
user_manager::UserManager::Get()->GetActiveUser()->GetAccountId());
RegisterAppWindow(window, shelf_app_id); RegisterAppWindow(window, shelf_app_id);
} }
...@@ -89,27 +149,7 @@ void CrostiniAppWindowShelfController::RegisterAppWindow( ...@@ -89,27 +149,7 @@ void CrostiniAppWindowShelfController::RegisterAppWindow(
aura_window_to_app_window_[window] = aura_window_to_app_window_[window] =
std::make_unique<AppWindowBase>(shelf_id, widget); std::make_unique<AppWindowBase>(shelf_id, widget);
AppWindowBase* app_window = aura_window_to_app_window_[window].get(); AppWindowBase* app_window = aura_window_to_app_window_[window].get();
AddToShelf(window, app_window);
AppWindowLauncherItemController* item_controller =
owner()->shelf_model()->GetAppWindowLauncherItemController(shelf_id);
if (item_controller == nullptr) {
auto controller =
std::make_unique<AppWindowLauncherItemController>(shelf_id);
item_controller = controller.get();
if (!owner()->GetItem(shelf_id)) {
owner()->CreateAppLauncherItem(std::move(controller),
ash::STATUS_RUNNING);
} else {
owner()->shelf_model()->SetShelfItemDelegate(shelf_id,
std::move(controller));
owner()->SetItemStatus(shelf_id, ash::STATUS_RUNNING);
}
window->SetProperty(ash::kShelfIDKey,
new std::string(shelf_id.Serialize()));
}
item_controller->AddWindow(app_window);
app_window->SetController(item_controller);
} }
void CrostiniAppWindowShelfController::OnWindowDestroying( void CrostiniAppWindowShelfController::OnWindowDestroying(
...@@ -123,16 +163,8 @@ void CrostiniAppWindowShelfController::OnWindowDestroying( ...@@ -123,16 +163,8 @@ void CrostiniAppWindowShelfController::OnWindowDestroying(
auto app_window_it = aura_window_to_app_window_.find(window); auto app_window_it = aura_window_to_app_window_.find(window);
if (app_window_it == aura_window_to_app_window_.end()) if (app_window_it == aura_window_to_app_window_.end())
return; return;
UnregisterAppWindow(app_window_it->second.get());
// Check if we may close controller now, at this point we can safely remove
// controllers without window.
AppWindowLauncherItemController* item_controller =
owner()->shelf_model()->GetAppWindowLauncherItemController(
app_window_it->second->shelf_id());
if (item_controller != nullptr && item_controller->window_count() == 0) RemoveFromShelf(window, app_window_it->second.get());
owner()->CloseLauncherItem(item_controller->shelf_id());
aura_window_to_app_window_.erase(app_window_it); aura_window_to_app_window_.erase(app_window_it);
} }
......
...@@ -34,6 +34,9 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController, ...@@ -34,6 +34,9 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController,
explicit CrostiniAppWindowShelfController(ChromeLauncherController* owner); explicit CrostiniAppWindowShelfController(ChromeLauncherController* owner);
~CrostiniAppWindowShelfController() override; ~CrostiniAppWindowShelfController() override;
// AppWindowLauncherController:
void ActiveUserChanged(const std::string& user_email) override;
// aura::EnvObserver: // aura::EnvObserver:
void OnWindowInitialized(aura::Window* window) override; void OnWindowInitialized(aura::Window* window) override;
...@@ -47,6 +50,8 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController, ...@@ -47,6 +50,8 @@ class CrostiniAppWindowShelfController : public AppWindowLauncherController,
void RegisterAppWindow(aura::Window* window, const std::string& shelf_app_id); void RegisterAppWindow(aura::Window* window, const std::string& shelf_app_id);
void UnregisterAppWindow(AppWindowBase* app_window); void UnregisterAppWindow(AppWindowBase* app_window);
void AddToShelf(aura::Window* window, AppWindowBase* app_window);
void RemoveFromShelf(aura::Window* window, AppWindowBase* app_window);
// AppWindowLauncherController: // AppWindowLauncherController:
AppWindowLauncherItemController* ControllerForWindow( AppWindowLauncherItemController* ControllerForWindow(
......
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