Commit f086a6df authored by oshima's avatar oshima Committed by Commit bot

Orientation request may arrive before the window is created.

Instead of adding another map, I introduced AppWindowInfo which stores information about the arc windows w/o actual window.

Technically, we can move more from AppWindow, but we
can revisit it later if we want.

BUG=31836336
TEST=ChromeLauncherControllerOrientationTest.ArcOrientationLockBeforeWindowReady

Review-Url: https://codereview.chromium.org/2384773002
Cr-Commit-Position: refs/heads/master@{#422635}
parent ee53d147
...@@ -89,12 +89,12 @@ blink::WebScreenOrientationLockType BlinkOrientationLockFromMojom( ...@@ -89,12 +89,12 @@ blink::WebScreenOrientationLockType BlinkOrientationLockFromMojom(
} }
int GetWindowTaskId(aura::Window* window) { int GetWindowTaskId(aura::Window* window) {
const std::string window_app_id = exo::ShellSurface::GetApplicationId(window); const std::string arc_app_id = exo::ShellSurface::GetApplicationId(window);
if (window_app_id.empty()) if (arc_app_id.empty())
return -1; return -1;
int task_id = -1; int task_id = -1;
if (sscanf(window_app_id.c_str(), "org.chromium.arc.%d", &task_id) != 1) if (sscanf(arc_app_id.c_str(), "org.chromium.arc.%d", &task_id) != 1)
return -1; return -1;
return task_id; return task_id;
...@@ -102,13 +102,52 @@ int GetWindowTaskId(aura::Window* window) { ...@@ -102,13 +102,52 @@ int GetWindowTaskId(aura::Window* window) {
} // namespace } // namespace
// The information about the arc application window which has to be kept
// even when its AppWindow is not present.
class ArcAppWindowLauncherController::AppWindowInfo {
public:
explicit AppWindowInfo(const std::string& shelf_app_id)
: shelf_app_id_(shelf_app_id) {}
~AppWindowInfo() {}
const std::string& shelf_app_id() const { return shelf_app_id_; }
bool has_requested_orientation_lock() const {
return has_requested_orientation_lock_;
}
void set_requested_orientation_lock(arc::mojom::OrientationLock lock) {
has_requested_orientation_lock_ = true;
requested_orientation_lock_ = lock;
}
arc::mojom::OrientationLock requested_orientation_lock() const {
return requested_orientation_lock_;
}
void set_app_window(std::unique_ptr<AppWindow> window) {
app_window_ = std::move(window);
}
AppWindow* app_window() { return app_window_.get(); }
private:
std::string shelf_app_id_;
bool has_requested_orientation_lock_ = false;
arc::mojom::OrientationLock requested_orientation_lock_ =
arc::mojom::OrientationLock::NONE;
std::unique_ptr<AppWindow> app_window_;
DISALLOW_COPY_AND_ASSIGN(AppWindowInfo);
};
// A ui::BaseWindow for a chromeos launcher to control ARC applications.
class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow { class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow {
public: public:
AppWindow(int task_id, AppWindow(int task_id,
const std::string app_id,
views::Widget* widget, views::Widget* widget,
ArcAppWindowLauncherController* owner) ArcAppWindowLauncherController* owner)
: task_id_(task_id), app_id_(app_id), widget_(widget), owner_(owner) {} : task_id_(task_id), widget_(widget), owner_(owner) {}
~AppWindow() {} ~AppWindow() {}
void SetController(ArcAppWindowLauncherItemController* controller) { void SetController(ArcAppWindowLauncherItemController* controller) {
...@@ -135,8 +174,6 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow { ...@@ -135,8 +174,6 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow {
ArcAppWindowLauncherItemController* controller() { return controller_; } ArcAppWindowLauncherItemController* controller() { return controller_; }
const std::string& app_id() { return app_id_; }
// ui::BaseWindow: // ui::BaseWindow:
bool IsActive() const override { bool IsActive() const override {
return widget_->IsActive() && owner_->active_task_id_ == task_id_; return widget_->IsActive() && owner_->active_task_id_ == task_id_;
...@@ -205,23 +242,9 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow { ...@@ -205,23 +242,9 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow {
void SetAlwaysOnTop(bool always_on_top) override { NOTREACHED(); } void SetAlwaysOnTop(bool always_on_top) override { NOTREACHED(); }
arc::mojom::OrientationLock requested_orientation_lock() const {
return requested_orientation_lock_;
}
void set_requested_orientation_lock(arc::mojom::OrientationLock lock) {
has_requested_orientation_lock_ = true;
requested_orientation_lock_ = lock;
}
bool has_requested_orientation_lock() const {
return has_requested_orientation_lock_;
}
private: private:
int task_id_; int task_id_;
ash::ShelfID shelf_id_ = 0; ash::ShelfID shelf_id_ = 0;
std::string app_id_;
FullScreenMode fullscreen_mode_ = FullScreenMode::NOT_DEFINED; FullScreenMode fullscreen_mode_ = FullScreenMode::NOT_DEFINED;
// Unowned pointers // Unowned pointers
views::Widget* const widget_; views::Widget* const widget_;
...@@ -229,10 +252,6 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow { ...@@ -229,10 +252,6 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow {
ArcAppWindowLauncherItemController* controller_ = nullptr; ArcAppWindowLauncherItemController* controller_ = nullptr;
// Unowned pointer, represents host Arc window. // Unowned pointer, represents host Arc window.
arc::mojom::OrientationLock requested_orientation_lock_ =
arc::mojom::OrientationLock::NONE;
bool has_requested_orientation_lock_ = false;
DISALLOW_COPY_AND_ASSIGN(AppWindow); DISALLOW_COPY_AND_ASSIGN(AppWindow);
}; };
...@@ -279,19 +298,16 @@ void ArcAppWindowLauncherController::ActiveUserChanged( ...@@ -279,19 +298,16 @@ void ArcAppWindowLauncherController::ActiveUserChanged(
// Make sure that we created items for all apps, not only which have a // Make sure that we created items for all apps, not only which have a
// window. // window.
for (const auto& it : task_id_to_shelf_app_id_) for (const auto& info : task_id_to_app_window_info_)
AttachControllerToTask(it.second, it.first); AttachControllerToTask(info.second->shelf_app_id(), info.first);
// Update active status. // Update active status.
OnTaskSetActive(active_task_id_); OnTaskSetActive(active_task_id_);
} else { } else {
// Remove all Arc apps and destroy its controllers. There is no mapping // Remove all Arc apps and destroy its controllers. There is no mapping
// task id to app window because it is not safe when controller is missing. // task id to app window because it is not safe when controller is missing.
for (auto& it : task_id_to_app_window_) { for (auto& it : task_id_to_app_window_info_)
AppWindow* app_window = it.second.get(); UnregisterApp(it.second.get(), true);
UnregisterApp(app_window, true);
}
task_id_to_app_window_.clear();
// Some controllers might have no windows attached, for example background // Some controllers might have no windows attached, for example background
// task when foreground tasks is in full screen. // task when foreground tasks is in full screen.
...@@ -341,26 +357,30 @@ void ArcAppWindowLauncherController::OnWindowDestroying(aura::Window* window) { ...@@ -341,26 +357,30 @@ void ArcAppWindowLauncherController::OnWindowDestroying(aura::Window* window) {
observed_windows_.erase(it); observed_windows_.erase(it);
window->RemoveObserver(this); window->RemoveObserver(this);
auto it_app_window = auto info_it = std::find_if(
std::find_if(task_id_to_app_window_.begin(), task_id_to_app_window_.end(), task_id_to_app_window_info_.begin(), task_id_to_app_window_info_.end(),
[window](const TaskIdToAppWindow::value_type& pair) { [window](TaskIdToAppWindowInfo::value_type& pair) {
return pair.second->GetNativeWindow() == window; return pair.second->app_window() &&
}); pair.second->app_window()->GetNativeWindow() == window;
if (it_app_window != task_id_to_app_window_.end()) { });
if (info_it != task_id_to_app_window_info_.end()) {
// Note, window may be recreated in some cases, so do not close controller // Note, window may be recreated in some cases, so do not close controller
// on window destroying. Controller will be closed onTaskDestroyed event // on window destroying. Controller will be closed onTaskDestroyed event
// which is generated when actual task is destroyed. // which is generated when actual task is destroyed.
UnregisterApp(it_app_window->second.get(), false); UnregisterApp(info_it->second.get(), false);
task_id_to_app_window_.erase(it_app_window);
} }
} }
ArcAppWindowLauncherController::AppWindowInfo*
ArcAppWindowLauncherController::GetAppWindowInfoForTask(int task_id) {
const auto it = task_id_to_app_window_info_.find(task_id);
return it == task_id_to_app_window_info_.end() ? nullptr : it->second.get();
}
ArcAppWindowLauncherController::AppWindow* ArcAppWindowLauncherController::AppWindow*
ArcAppWindowLauncherController::GetAppWindowForTask(int task_id) { ArcAppWindowLauncherController::GetAppWindowForTask(int task_id) {
TaskIdToAppWindow::iterator it = task_id_to_app_window_.find(task_id); AppWindowInfo* info = GetAppWindowInfoForTask(task_id);
if (it == task_id_to_app_window_.end()) return info ? info->app_window() : nullptr;
return nullptr;
return it->second.get();
} }
void ArcAppWindowLauncherController::AttachControllerToWindowsIfNeeded() { void ArcAppWindowLauncherController::AttachControllerToWindowsIfNeeded() {
...@@ -390,39 +410,39 @@ void ArcAppWindowLauncherController::AttachControllerToWindowIfNeeded( ...@@ -390,39 +410,39 @@ void ArcAppWindowLauncherController::AttachControllerToWindowIfNeeded(
static_cast<int>(ash::AppType::ARC_APP)); static_cast<int>(ash::AppType::ARC_APP));
// Create controller if we have task info. // Create controller if we have task info.
TaskIdToShelfAppIdMap::iterator it = task_id_to_shelf_app_id_.find(task_id); AppWindowInfo* info = GetAppWindowInfoForTask(task_id);
if (it == task_id_to_shelf_app_id_.end()) if (!info) {
VLOG(1) << "Could not find AppWindowInfo for task:" << task_id;
return; return;
}
const std::string& app_id = it->second;
views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
DCHECK(widget); DCHECK(widget);
std::unique_ptr<AppWindow> app_window( DCHECK(!info->app_window());
new AppWindow(task_id, app_id, widget, this)); info->set_app_window(base::MakeUnique<AppWindow>(task_id, widget, this));
RegisterApp(app_window.get()); RegisterApp(info);
DCHECK(app_window->controller()); DCHECK(info->app_window()->controller());
ash::WmWindowAura::Get(window)->SetIntProperty( ash::WmWindowAura::Get(window)->SetIntProperty(
ash::WmWindowProperty::SHELF_ID, app_window->shelf_id()); ash::WmWindowProperty::SHELF_ID, info->app_window()->shelf_id());
if (ash::WmShell::Get() if (ash::WmShell::Get()
->maximize_mode_controller() ->maximize_mode_controller()
->IsMaximizeModeWindowManagerEnabled()) { ->IsMaximizeModeWindowManagerEnabled()) {
SetOrientationLockForAppWindow(app_window.get()); SetOrientationLockForAppWindow(info->app_window());
} }
task_id_to_app_window_[task_id] = std::move(app_window);
} }
void ArcAppWindowLauncherController::OnAppReadyChanged( void ArcAppWindowLauncherController::OnAppReadyChanged(
const std::string& app_id, const std::string& arc_app_id,
bool ready) { bool ready) {
if (!ready) if (!ready)
OnAppRemoved(app_id); OnAppRemoved(arc_app_id);
} }
void ArcAppWindowLauncherController::OnAppRemoved(const std::string& app_id) { void ArcAppWindowLauncherController::OnAppRemoved(
const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id); const std::string& arc_app_id) {
const std::string shelf_app_id = GetShelfAppIdFromArcAppId(arc_app_id);
AppControllerMap::const_iterator it = app_controller_map_.find(shelf_app_id); const auto it = app_controller_map_.find(shelf_app_id);
if (it == app_controller_map_.end()) if (it == app_controller_map_.end())
return; return;
...@@ -445,10 +465,11 @@ void ArcAppWindowLauncherController::OnTaskCreated( ...@@ -445,10 +465,11 @@ void ArcAppWindowLauncherController::OnTaskCreated(
const std::string& package_name, const std::string& package_name,
const std::string& activity_name) { const std::string& activity_name) {
DCHECK(!GetAppWindowForTask(task_id)); DCHECK(!GetAppWindowForTask(task_id));
const std::string shelf_app_id = GetShelfAppIdFromArcAppId( const std::string arc_app_id =
ArcAppListPrefs::GetAppId(package_name, activity_name)); ArcAppListPrefs::GetAppId(package_name, activity_name);
task_id_to_shelf_app_id_[task_id] = shelf_app_id; const std::string shelf_app_id = GetShelfAppIdFromArcAppId(arc_app_id);
task_id_to_app_window_info_[task_id] =
base::MakeUnique<AppWindowInfo>(shelf_app_id);
// Don't create shelf icon for non-primary user. // Don't create shelf icon for non-primary user.
if (observed_profile_ != owner()->GetProfile()) if (observed_profile_ != owner()->GetProfile())
return; return;
...@@ -462,21 +483,16 @@ void ArcAppWindowLauncherController::OnTaskCreated( ...@@ -462,21 +483,16 @@ void ArcAppWindowLauncherController::OnTaskCreated(
} }
void ArcAppWindowLauncherController::OnTaskDestroyed(int task_id) { void ArcAppWindowLauncherController::OnTaskDestroyed(int task_id) {
auto it = task_id_to_app_window_.find(task_id); auto it = task_id_to_app_window_info_.find(task_id);
if (it != task_id_to_app_window_.end()) { if (it == task_id_to_app_window_info_.end())
AppWindow* app_window = it->second.get(); return;
UnregisterApp(app_window, true); UnregisterApp(it->second.get(), true);
task_id_to_app_window_.erase(it);
}
// Check if we may close controller now, at this point we can safely remove // Check if we may close controller now, at this point we can safely remove
// controllers without window. // controllers without window.
auto it_app_id = task_id_to_shelf_app_id_.find(task_id); const std::string& shelf_app_id = it->second->shelf_app_id();
if (it_app_id == task_id_to_shelf_app_id_.end())
return;
const std::string& app_id = it_app_id->second; const auto it_controller = app_controller_map_.find(shelf_app_id);
AppControllerMap::iterator it_controller = app_controller_map_.find(app_id);
if (it_controller != app_controller_map_.end()) { if (it_controller != app_controller_map_.end()) {
ArcAppWindowLauncherItemController* controller = it_controller->second; ArcAppWindowLauncherItemController* controller = it_controller->second;
controller->RemoveTaskId(task_id); controller->RemoveTaskId(task_id);
...@@ -486,7 +502,7 @@ void ArcAppWindowLauncherController::OnTaskDestroyed(int task_id) { ...@@ -486,7 +502,7 @@ void ArcAppWindowLauncherController::OnTaskDestroyed(int task_id) {
} }
} }
task_id_to_shelf_app_id_.erase(it_app_id); task_id_to_app_window_info_.erase(it);
} }
void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) { void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) {
...@@ -495,27 +511,24 @@ void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) { ...@@ -495,27 +511,24 @@ void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) {
return; return;
} }
TaskIdToAppWindow::iterator previous_active_app_it = AppWindow* previous_app_window = GetAppWindowForTask(active_task_id_);
task_id_to_app_window_.find(active_task_id_); if (previous_app_window) {
if (previous_active_app_it != task_id_to_app_window_.end()) { owner()->SetItemStatus(previous_app_window->shelf_id(),
owner()->SetItemStatus(previous_active_app_it->second->shelf_id(),
ash::STATUS_RUNNING); ash::STATUS_RUNNING);
previous_active_app_it->second->SetFullscreenMode( previous_app_window->SetFullscreenMode(
previous_active_app_it->second->widget() && previous_app_window->widget() &&
previous_active_app_it->second->widget()->IsFullscreen() previous_app_window->widget()->IsFullscreen()
? FullScreenMode::ACTIVE ? FullScreenMode::ACTIVE
: FullScreenMode::NON_ACTIVE); : FullScreenMode::NON_ACTIVE);
} }
active_task_id_ = task_id; active_task_id_ = task_id;
TaskIdToAppWindow::iterator new_active_app_it = AppWindow* current_app_window = GetAppWindowForTask(task_id);
task_id_to_app_window_.find(active_task_id_); if (current_app_window) {
if (new_active_app_it != task_id_to_app_window_.end()) {
owner()->SetItemStatus( owner()->SetItemStatus(
new_active_app_it->second->shelf_id(), current_app_window->shelf_id(),
new_active_app_it->second->widget() && current_app_window->widget() && current_app_window->IsActive()
new_active_app_it->second->widget()->IsActive()
? ash::STATUS_ACTIVE ? ash::STATUS_ACTIVE
: ash::STATUS_RUNNING); : ash::STATUS_RUNNING);
// TODO(reveman): Figure out how to support fullscreen in interleaved // TODO(reveman): Figure out how to support fullscreen in interleaved
...@@ -531,17 +544,19 @@ void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) { ...@@ -531,17 +544,19 @@ void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) {
void ArcAppWindowLauncherController::OnTaskOrientationLockRequested( void ArcAppWindowLauncherController::OnTaskOrientationLockRequested(
int32_t task_id, int32_t task_id,
const arc::mojom::OrientationLock orientation_lock) { const arc::mojom::OrientationLock orientation_lock) {
// Don't save to AppInfo because this is requested in runtime. // Don't save to AppInfo in prefs because this is requested in runtime.
TaskIdToAppWindow::iterator app_it = task_id_to_app_window_.find(task_id); AppWindowInfo* info = GetAppWindowInfoForTask(task_id);
if (app_it == task_id_to_app_window_.end()) DCHECK(info);
if (!info)
return; return;
AppWindow* app_window = app_it->second.get(); info->set_requested_orientation_lock(orientation_lock);
app_window->set_requested_orientation_lock(orientation_lock);
if (ash::WmShell::Get() if (ash::WmShell::Get()
->maximize_mode_controller() ->maximize_mode_controller()
->IsMaximizeModeWindowManagerEnabled()) { ->IsMaximizeModeWindowManagerEnabled()) {
SetOrientationLockForAppWindow(app_window); AppWindow* app_window = info->app_window();
if (app_window)
SetOrientationLockForAppWindow(app_window);
} }
} }
...@@ -553,9 +568,13 @@ ArcAppWindowLauncherController::ControllerForWindow(aura::Window* window) { ...@@ -553,9 +568,13 @@ ArcAppWindowLauncherController::ControllerForWindow(aura::Window* window) {
return app_window->controller(); return app_window->controller();
} }
for (auto& it : task_id_to_app_window_) { for (auto& it : task_id_to_app_window_info_) {
if (it.second->widget() == views::Widget::GetWidgetForNativeWindow(window)) AppWindow* app_window = it.second->app_window();
return it.second->controller(); if (app_window &&
app_window->widget() ==
views::Widget::GetWidgetForNativeWindow(window)) {
return it.second->app_window()->controller();
}
} }
return nullptr; return nullptr;
...@@ -569,8 +588,11 @@ void ArcAppWindowLauncherController::OnWindowActivated( ...@@ -569,8 +588,11 @@ void ArcAppWindowLauncherController::OnWindowActivated(
} }
void ArcAppWindowLauncherController::OnMaximizeModeStarted() { void ArcAppWindowLauncherController::OnMaximizeModeStarted() {
for (auto& it : task_id_to_app_window_) for (auto& it : task_id_to_app_window_info_) {
SetOrientationLockForAppWindow(it.second.get()); AppWindow* app_window = it.second->app_window();
if (app_window)
SetOrientationLockForAppWindow(app_window);
}
} }
void ArcAppWindowLauncherController::OnMaximizeModeEnded() { void ArcAppWindowLauncherController::OnMaximizeModeEnded() {
...@@ -603,7 +625,7 @@ ArcAppWindowLauncherItemController* ...@@ -603,7 +625,7 @@ ArcAppWindowLauncherItemController*
ArcAppWindowLauncherController::AttachControllerToTask( ArcAppWindowLauncherController::AttachControllerToTask(
const std::string& shelf_app_id, const std::string& shelf_app_id,
int task_id) { int task_id) {
AppControllerMap::const_iterator it = app_controller_map_.find(shelf_app_id); const auto it = app_controller_map_.find(shelf_app_id);
if (it != app_controller_map_.end()) { if (it != app_controller_map_.end()) {
DCHECK_EQ(it->second->app_id(), shelf_app_id); DCHECK_EQ(it->second->app_id(), shelf_app_id);
it->second->AddTaskId(task_id); it->second->AddTaskId(task_id);
...@@ -626,15 +648,17 @@ ArcAppWindowLauncherController::AttachControllerToTask( ...@@ -626,15 +648,17 @@ ArcAppWindowLauncherController::AttachControllerToTask(
return controller; return controller;
} }
void ArcAppWindowLauncherController::RegisterApp(AppWindow* app_window) { void ArcAppWindowLauncherController::RegisterApp(
const std::string app_id = app_window->app_id(); AppWindowInfo* app_window_info) {
DCHECK(!app_id.empty()); const std::string shelf_app_id = app_window_info->shelf_app_id();
DCHECK(!shelf_app_id.empty());
AppWindow* app_window = app_window_info->app_window();
ArcAppWindowLauncherItemController* controller = ArcAppWindowLauncherItemController* controller =
AttachControllerToTask(app_id, app_window->task_id()); AttachControllerToTask(shelf_app_id, app_window->task_id());
DCHECK(controller); DCHECK(controller);
const ash::ShelfID shelf_id = shelf_delegate_->GetShelfIDForAppID(app_id); const ash::ShelfID shelf_id =
shelf_delegate_->GetShelfIDForAppID(shelf_app_id);
DCHECK(shelf_id); DCHECK(shelf_id);
controller->AddWindow(app_window); controller->AddWindow(app_window);
...@@ -643,12 +667,16 @@ void ArcAppWindowLauncherController::RegisterApp(AppWindow* app_window) { ...@@ -643,12 +667,16 @@ void ArcAppWindowLauncherController::RegisterApp(AppWindow* app_window) {
app_window->set_shelf_id(shelf_id); app_window->set_shelf_id(shelf_id);
} }
void ArcAppWindowLauncherController::UnregisterApp(AppWindow* app_window, void ArcAppWindowLauncherController::UnregisterApp(
bool close_controller) { AppWindowInfo* app_window_info,
const std::string app_id = app_window->app_id(); bool close_controller) {
AppWindow* app_window = app_window_info->app_window();
DCHECK(!app_id.empty()); if (!app_window)
AppControllerMap::iterator it = app_controller_map_.find(app_id); return;
const std::string& shelf_app_id = app_window_info->shelf_app_id();
DCHECK(app_window);
DCHECK(!shelf_app_id.empty());
const auto it = app_controller_map_.find(shelf_app_id);
CHECK(it != app_controller_map_.end()); CHECK(it != app_controller_map_.end());
ArcAppWindowLauncherItemController* controller = it->second; ArcAppWindowLauncherItemController* controller = it->second;
...@@ -659,6 +687,7 @@ void ArcAppWindowLauncherController::UnregisterApp(AppWindow* app_window, ...@@ -659,6 +687,7 @@ void ArcAppWindowLauncherController::UnregisterApp(AppWindow* app_window,
app_controller_map_.erase(it); app_controller_map_.erase(it);
} }
app_window->ResetController(); app_window->ResetController();
app_window_info->set_app_window(nullptr);
} }
void ArcAppWindowLauncherController::SetOrientationLockForAppWindow( void ArcAppWindowLauncherController::SetOrientationLockForAppWindow(
...@@ -667,13 +696,15 @@ void ArcAppWindowLauncherController::SetOrientationLockForAppWindow( ...@@ -667,13 +696,15 @@ void ArcAppWindowLauncherController::SetOrientationLockForAppWindow(
ash::WmLookup::Get()->GetWindowForWidget(app_window->widget()); ash::WmLookup::Get()->GetWindowForWidget(app_window->widget());
if (!window) if (!window)
return; return;
AppWindowInfo* info = GetAppWindowInfoForTask(app_window->task_id());
arc::mojom::OrientationLock orientation_lock; arc::mojom::OrientationLock orientation_lock;
if (app_window->has_requested_orientation_lock()) {
orientation_lock = app_window->requested_orientation_lock(); if (info->has_requested_orientation_lock()) {
orientation_lock = info->requested_orientation_lock();
} else { } else {
ArcAppListPrefs* prefs = ArcAppListPrefs::Get(observed_profile_); ArcAppListPrefs* prefs = ArcAppListPrefs::Get(observed_profile_);
std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
prefs->GetApp(app_window->app_id()); prefs->GetApp(info->shelf_app_id());
if (!app_info) if (!app_info)
return; return;
orientation_lock = app_info->orientation_lock; orientation_lock = app_info->orientation_lock;
...@@ -682,9 +713,8 @@ void ArcAppWindowLauncherController::SetOrientationLockForAppWindow( ...@@ -682,9 +713,8 @@ void ArcAppWindowLauncherController::SetOrientationLockForAppWindow(
if (orientation_lock == arc::mojom::OrientationLock::CURRENT) { if (orientation_lock == arc::mojom::OrientationLock::CURRENT) {
// Resolve the orientation when it first resolved. // Resolve the orientation when it first resolved.
orientation_lock = GetCurrentOrientation(); orientation_lock = GetCurrentOrientation();
app_window->set_requested_orientation_lock(orientation_lock); info->set_requested_orientation_lock(orientation_lock);
} }
ash::Shell* shell = ash::Shell::GetInstance(); ash::Shell* shell = ash::Shell::GetInstance();
shell->screen_orientation_controller()->LockOrientationForWindow( shell->screen_orientation_controller()->LockOrientationForWindow(
window, BlinkOrientationLockFromMojom(orientation_lock)); window, BlinkOrientationLockFromMojom(orientation_lock));
......
...@@ -85,18 +85,19 @@ class ArcAppWindowLauncherController : public AppWindowLauncherController, ...@@ -85,18 +85,19 @@ class ArcAppWindowLauncherController : public AppWindowLauncherController,
private: private:
class AppWindow; class AppWindow;
class AppWindowInfo;
using TaskIdToAppWindow = std::map<int, std::unique_ptr<AppWindow>>; using TaskIdToAppWindowInfo = std::map<int, std::unique_ptr<AppWindowInfo>>;
using TaskIdToShelfAppIdMap = std::map<int, std::string>; using ShelfAppIdToAppControllerMap =
using AppControllerMap =
std::map<std::string, ArcAppWindowLauncherItemController*>; std::map<std::string, ArcAppWindowLauncherItemController*>;
void StartObserving(Profile* profile); void StartObserving(Profile* profile);
void StopObserving(Profile* profile); void StopObserving(Profile* profile);
void RegisterApp(AppWindow* app_window); void RegisterApp(AppWindowInfo* app_window_info);
void UnregisterApp(AppWindow* app_window, bool close_controller); void UnregisterApp(AppWindowInfo* app_window_info, bool close_controller);
AppWindowInfo* GetAppWindowInfoForTask(int task_id);
AppWindow* GetAppWindowForTask(int task_id); AppWindow* GetAppWindowForTask(int task_id);
void AttachControllerToWindowIfNeeded(aura::Window* window); void AttachControllerToWindowIfNeeded(aura::Window* window);
...@@ -114,9 +115,8 @@ class ArcAppWindowLauncherController : public AppWindowLauncherController, ...@@ -114,9 +115,8 @@ class ArcAppWindowLauncherController : public AppWindowLauncherController,
// Not owned // Not owned
ash::ShelfDelegate* shelf_delegate_; ash::ShelfDelegate* shelf_delegate_;
int active_task_id_ = -1; int active_task_id_ = -1;
TaskIdToAppWindow task_id_to_app_window_; TaskIdToAppWindowInfo task_id_to_app_window_info_;
TaskIdToShelfAppIdMap task_id_to_shelf_app_id_; ShelfAppIdToAppControllerMap app_controller_map_;
AppControllerMap app_controller_map_;
std::vector<aura::Window*> observed_windows_; std::vector<aura::Window*> observed_windows_;
Profile* observed_profile_ = nullptr; Profile* observed_profile_ = nullptr;
bool observing_shell_ = false; bool observing_shell_ = false;
......
...@@ -3719,6 +3719,57 @@ class ChromeLauncherControllerArcDefaultAppsTest ...@@ -3719,6 +3719,57 @@ class ChromeLauncherControllerArcDefaultAppsTest
} // namespace } // namespace
TEST_F(ChromeLauncherControllerOrientationTest,
ArcOrientationLockBeforeWindowReady) {
ASSERT_TRUE(display::Display::HasInternalDisplay());
extension_service_->AddExtension(arc_support_host_.get());
EnableArc(true);
InitLauncherController();
arc::ArcAuthService::SetShelfDelegateForTesting(launcher_controller_.get());
ash::ScreenOrientationController* controller =
ash::Shell::GetInstance()->screen_orientation_controller();
std::string app_id1("org.chromium.arc.1");
int task_id1 = 1;
arc::mojom::AppInfo appinfo1 =
CreateAppInfo("Test1", "test", "com.example.app", OrientationLock::NONE);
AddArcAppAndShortcut(appinfo1);
NotifyOnTaskCreated(appinfo1, task_id1);
NotifyOnTaskOrientationLockRequested(task_id1, OrientationLock::PORTRAIT);
// Widgets will be deleted by the system.
CreateArcWindow(app_id1);
EXPECT_FALSE(controller->rotation_locked());
EnableTabletMode(true);
EXPECT_TRUE(controller->rotation_locked());
EXPECT_EQ(display::Display::ROTATE_90,
display::Screen::GetScreen()->GetPrimaryDisplay().rotation());
std::string app_id2("org.chromium.arc.2");
int task_id2 = 2;
arc::mojom::AppInfo appinfo2 =
CreateAppInfo("Test2", "test", "com.example.app", OrientationLock::NONE);
// Create in tablet mode.
AddArcAppAndShortcut(appinfo2);
NotifyOnTaskCreated(appinfo2, task_id2);
NotifyOnTaskOrientationLockRequested(task_id2, OrientationLock::LANDSCAPE);
EXPECT_TRUE(controller->rotation_locked());
EXPECT_EQ(display::Display::ROTATE_90,
display::Screen::GetScreen()->GetPrimaryDisplay().rotation());
// The screen will be locked when the window is created.
CreateArcWindow(app_id2);
EXPECT_TRUE(controller->rotation_locked());
EXPECT_EQ(display::Display::ROTATE_0,
display::Screen::GetScreen()->GetPrimaryDisplay().rotation());
}
TEST_F(ChromeLauncherControllerOrientationTest, ArcOrientationLock) { TEST_F(ChromeLauncherControllerOrientationTest, ArcOrientationLock) {
ASSERT_TRUE(display::Display::HasInternalDisplay()); ASSERT_TRUE(display::Display::HasInternalDisplay());
......
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