Index: chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc |
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc |
index eb5a600576234ab8e1fd1e5c0e53093f4203743d..7dc10d3fad62489f1836438b00fde70921942506 100644 |
--- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc |
+++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc |
@@ -88,12 +88,12 @@ blink::WebScreenOrientationLockType BlinkOrientationLockFromMojom( |
} |
int GetWindowTaskId(aura::Window* window) { |
- const std::string window_app_id = exo::ShellSurface::GetApplicationId(window); |
- if (window_app_id.empty()) |
+ const std::string arc_app_id = exo::ShellSurface::GetApplicationId(window); |
+ if (arc_app_id.empty()) |
return -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 task_id; |
@@ -101,13 +101,52 @@ int GetWindowTaskId(aura::Window* window) { |
} // 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 { |
public: |
AppWindow(int task_id, |
- const std::string app_id, |
views::Widget* widget, |
ArcAppWindowLauncherController* owner) |
- : task_id_(task_id), app_id_(app_id), widget_(widget), owner_(owner) {} |
+ : task_id_(task_id), widget_(widget), owner_(owner) {} |
~AppWindow() {} |
void SetController(ArcAppWindowLauncherItemController* controller) { |
@@ -134,8 +173,6 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow { |
ArcAppWindowLauncherItemController* controller() { return controller_; } |
- const std::string& app_id() { return app_id_; } |
- |
// ui::BaseWindow: |
bool IsActive() const override { |
return widget_->IsActive() && owner_->active_task_id_ == task_id_; |
@@ -204,23 +241,9 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow { |
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: |
int task_id_; |
ash::ShelfID shelf_id_ = 0; |
- std::string app_id_; |
FullScreenMode fullscreen_mode_ = FullScreenMode::NOT_DEFINED; |
// Unowned pointers |
views::Widget* const widget_; |
@@ -228,10 +251,6 @@ class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow { |
ArcAppWindowLauncherItemController* controller_ = nullptr; |
// 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); |
}; |
@@ -278,19 +297,16 @@ void ArcAppWindowLauncherController::ActiveUserChanged( |
// Make sure that we created items for all apps, not only which have a |
// window. |
- for (const auto& it : task_id_to_shelf_app_id_) |
- AttachControllerToTask(it.second, it.first); |
+ for (const auto& info : task_id_to_app_window_info_) |
+ AttachControllerToTask(info.second->shelf_app_id(), info.first); |
// Update active status. |
OnTaskSetActive(active_task_id_); |
} else { |
// 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. |
- for (auto& it : task_id_to_app_window_) { |
- AppWindow* app_window = it.second.get(); |
- UnregisterApp(app_window, true); |
- } |
- task_id_to_app_window_.clear(); |
+ for (auto& it : task_id_to_app_window_info_) |
+ UnregisterApp(it.second.get(), true); |
// Some controllers might have no windows attached, for example background |
// task when foreground tasks is in full screen. |
@@ -340,26 +356,30 @@ void ArcAppWindowLauncherController::OnWindowDestroying(aura::Window* window) { |
observed_windows_.erase(it); |
window->RemoveObserver(this); |
- auto it_app_window = |
- std::find_if(task_id_to_app_window_.begin(), task_id_to_app_window_.end(), |
- [window](const TaskIdToAppWindow::value_type& pair) { |
- return pair.second->GetNativeWindow() == window; |
- }); |
- if (it_app_window != task_id_to_app_window_.end()) { |
+ auto info_it = std::find_if( |
+ task_id_to_app_window_info_.begin(), task_id_to_app_window_info_.end(), |
+ [window](TaskIdToAppWindowInfo::value_type& pair) { |
+ return pair.second->app_window() && |
+ pair.second->app_window()->GetNativeWindow() == window; |
+ }); |
+ if (info_it != task_id_to_app_window_info_.end()) { |
// Note, window may be recreated in some cases, so do not close controller |
// on window destroying. Controller will be closed onTaskDestroyed event |
// which is generated when actual task is destroyed. |
- UnregisterApp(it_app_window->second.get(), false); |
- task_id_to_app_window_.erase(it_app_window); |
+ UnregisterApp(info_it->second.get(), false); |
} |
} |
+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::GetAppWindowForTask(int task_id) { |
- TaskIdToAppWindow::iterator it = task_id_to_app_window_.find(task_id); |
- if (it == task_id_to_app_window_.end()) |
- return nullptr; |
- return it->second.get(); |
+ AppWindowInfo* info = GetAppWindowInfoForTask(task_id); |
+ return info ? info->app_window() : nullptr; |
} |
void ArcAppWindowLauncherController::AttachControllerToWindowsIfNeeded() { |
@@ -386,39 +406,39 @@ void ArcAppWindowLauncherController::AttachControllerToWindowIfNeeded( |
return; |
// Create controller if we have task info. |
- TaskIdToShelfAppIdMap::iterator it = task_id_to_shelf_app_id_.find(task_id); |
- if (it == task_id_to_shelf_app_id_.end()) |
+ AppWindowInfo* info = GetAppWindowInfoForTask(task_id); |
+ if (!info) { |
+ VLOG(1) << "Could not find AppWindowInfo for task:" << task_id; |
return; |
- |
- const std::string& app_id = it->second; |
+ } |
views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); |
DCHECK(widget); |
- std::unique_ptr<AppWindow> app_window( |
- new AppWindow(task_id, app_id, widget, this)); |
- RegisterApp(app_window.get()); |
- DCHECK(app_window->controller()); |
+ DCHECK(!info->app_window()); |
+ info->set_app_window(base::MakeUnique<AppWindow>(task_id, widget, this)); |
+ RegisterApp(info); |
+ DCHECK(info->app_window()->controller()); |
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() |
->maximize_mode_controller() |
->IsMaximizeModeWindowManagerEnabled()) { |
- SetOrientationLockForAppWindow(app_window.get()); |
+ SetOrientationLockForAppWindow(info->app_window()); |
} |
- task_id_to_app_window_[task_id] = std::move(app_window); |
} |
void ArcAppWindowLauncherController::OnAppReadyChanged( |
- const std::string& app_id, |
+ const std::string& arc_app_id, |
bool ready) { |
if (!ready) |
- OnAppRemoved(app_id); |
+ OnAppRemoved(arc_app_id); |
} |
-void ArcAppWindowLauncherController::OnAppRemoved(const std::string& app_id) { |
- const std::string shelf_app_id = GetShelfAppIdFromArcAppId(app_id); |
+void ArcAppWindowLauncherController::OnAppRemoved( |
+ 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()) |
return; |
@@ -441,10 +461,11 @@ void ArcAppWindowLauncherController::OnTaskCreated( |
const std::string& package_name, |
const std::string& activity_name) { |
DCHECK(!GetAppWindowForTask(task_id)); |
- const std::string shelf_app_id = GetShelfAppIdFromArcAppId( |
- ArcAppListPrefs::GetAppId(package_name, activity_name)); |
- task_id_to_shelf_app_id_[task_id] = shelf_app_id; |
- |
+ const std::string arc_app_id = |
+ ArcAppListPrefs::GetAppId(package_name, activity_name); |
+ 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. |
if (observed_profile_ != owner()->GetProfile()) |
return; |
@@ -458,21 +479,16 @@ void ArcAppWindowLauncherController::OnTaskCreated( |
} |
void ArcAppWindowLauncherController::OnTaskDestroyed(int task_id) { |
- auto it = task_id_to_app_window_.find(task_id); |
- if (it != task_id_to_app_window_.end()) { |
- AppWindow* app_window = it->second.get(); |
- UnregisterApp(app_window, true); |
- task_id_to_app_window_.erase(it); |
- } |
+ auto it = task_id_to_app_window_info_.find(task_id); |
+ if (it == task_id_to_app_window_info_.end()) |
+ return; |
+ UnregisterApp(it->second.get(), true); |
// Check if we may close controller now, at this point we can safely remove |
// controllers without window. |
- auto it_app_id = task_id_to_shelf_app_id_.find(task_id); |
- if (it_app_id == task_id_to_shelf_app_id_.end()) |
- return; |
+ const std::string& shelf_app_id = it->second->shelf_app_id(); |
- const std::string& app_id = it_app_id->second; |
- AppControllerMap::iterator it_controller = app_controller_map_.find(app_id); |
+ const auto it_controller = app_controller_map_.find(shelf_app_id); |
if (it_controller != app_controller_map_.end()) { |
ArcAppWindowLauncherItemController* controller = it_controller->second; |
controller->RemoveTaskId(task_id); |
@@ -482,7 +498,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) { |
@@ -491,27 +507,24 @@ void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) { |
return; |
} |
- TaskIdToAppWindow::iterator previous_active_app_it = |
- task_id_to_app_window_.find(active_task_id_); |
- if (previous_active_app_it != task_id_to_app_window_.end()) { |
- owner()->SetItemStatus(previous_active_app_it->second->shelf_id(), |
+ AppWindow* previous_app_window = GetAppWindowForTask(active_task_id_); |
+ if (previous_app_window) { |
+ owner()->SetItemStatus(previous_app_window->shelf_id(), |
ash::STATUS_RUNNING); |
- previous_active_app_it->second->SetFullscreenMode( |
- previous_active_app_it->second->widget() && |
- previous_active_app_it->second->widget()->IsFullscreen() |
+ previous_app_window->SetFullscreenMode( |
+ previous_app_window->widget() && |
+ previous_app_window->widget()->IsFullscreen() |
? FullScreenMode::ACTIVE |
: FullScreenMode::NON_ACTIVE); |
} |
active_task_id_ = task_id; |
- TaskIdToAppWindow::iterator new_active_app_it = |
- task_id_to_app_window_.find(active_task_id_); |
- if (new_active_app_it != task_id_to_app_window_.end()) { |
+ AppWindow* current_app_window = GetAppWindowForTask(task_id); |
+ if (current_app_window) { |
owner()->SetItemStatus( |
- new_active_app_it->second->shelf_id(), |
- new_active_app_it->second->widget() && |
- new_active_app_it->second->widget()->IsActive() |
+ current_app_window->shelf_id(), |
+ current_app_window->widget() && current_app_window->IsActive() |
? ash::STATUS_ACTIVE |
: ash::STATUS_RUNNING); |
// TODO(reveman): Figure out how to support fullscreen in interleaved |
@@ -527,17 +540,19 @@ void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) { |
void ArcAppWindowLauncherController::OnTaskOrientationLockRequested( |
int32_t task_id, |
const arc::mojom::OrientationLock orientation_lock) { |
- // Don't save to AppInfo because this is requested in runtime. |
- TaskIdToAppWindow::iterator app_it = task_id_to_app_window_.find(task_id); |
- if (app_it == task_id_to_app_window_.end()) |
+ // Don't save to AppInfo in prefs because this is requested in runtime. |
+ AppWindowInfo* info = GetAppWindowInfoForTask(task_id); |
+ DCHECK(info); |
+ if (!info) |
return; |
- AppWindow* app_window = app_it->second.get(); |
- app_window->set_requested_orientation_lock(orientation_lock); |
+ info->set_requested_orientation_lock(orientation_lock); |
if (ash::WmShell::Get() |
->maximize_mode_controller() |
->IsMaximizeModeWindowManagerEnabled()) { |
- SetOrientationLockForAppWindow(app_window); |
+ AppWindow* app_window = info->app_window(); |
+ if (app_window) |
+ SetOrientationLockForAppWindow(app_window); |
} |
} |
@@ -549,9 +564,13 @@ ArcAppWindowLauncherController::ControllerForWindow(aura::Window* window) { |
return app_window->controller(); |
} |
- for (auto& it : task_id_to_app_window_) { |
- if (it.second->widget() == views::Widget::GetWidgetForNativeWindow(window)) |
- return it.second->controller(); |
+ for (auto& it : task_id_to_app_window_info_) { |
+ AppWindow* app_window = it.second->app_window(); |
+ if (app_window && |
+ app_window->widget() == |
+ views::Widget::GetWidgetForNativeWindow(window)) { |
+ return it.second->app_window()->controller(); |
+ } |
} |
return nullptr; |
@@ -565,8 +584,11 @@ void ArcAppWindowLauncherController::OnWindowActivated( |
} |
void ArcAppWindowLauncherController::OnMaximizeModeStarted() { |
- for (auto& it : task_id_to_app_window_) |
- SetOrientationLockForAppWindow(it.second.get()); |
+ for (auto& it : task_id_to_app_window_info_) { |
+ AppWindow* app_window = it.second->app_window(); |
+ if (app_window) |
+ SetOrientationLockForAppWindow(app_window); |
+ } |
} |
void ArcAppWindowLauncherController::OnMaximizeModeEnded() { |
@@ -599,7 +621,7 @@ ArcAppWindowLauncherItemController* |
ArcAppWindowLauncherController::AttachControllerToTask( |
const std::string& shelf_app_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()) { |
DCHECK_EQ(it->second->app_id(), shelf_app_id); |
it->second->AddTaskId(task_id); |
@@ -622,15 +644,17 @@ ArcAppWindowLauncherController::AttachControllerToTask( |
return controller; |
} |
-void ArcAppWindowLauncherController::RegisterApp(AppWindow* app_window) { |
- const std::string app_id = app_window->app_id(); |
- DCHECK(!app_id.empty()); |
- |
+void ArcAppWindowLauncherController::RegisterApp( |
+ AppWindowInfo* app_window_info) { |
+ 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 = |
- AttachControllerToTask(app_id, app_window->task_id()); |
+ AttachControllerToTask(shelf_app_id, app_window->task_id()); |
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); |
controller->AddWindow(app_window); |
@@ -639,12 +663,16 @@ void ArcAppWindowLauncherController::RegisterApp(AppWindow* app_window) { |
app_window->set_shelf_id(shelf_id); |
} |
-void ArcAppWindowLauncherController::UnregisterApp(AppWindow* app_window, |
- bool close_controller) { |
- const std::string app_id = app_window->app_id(); |
- |
- DCHECK(!app_id.empty()); |
- AppControllerMap::iterator it = app_controller_map_.find(app_id); |
+void ArcAppWindowLauncherController::UnregisterApp( |
+ AppWindowInfo* app_window_info, |
+ bool close_controller) { |
+ AppWindow* app_window = app_window_info->app_window(); |
+ if (!app_window) |
+ 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()); |
ArcAppWindowLauncherItemController* controller = it->second; |
@@ -655,6 +683,7 @@ void ArcAppWindowLauncherController::UnregisterApp(AppWindow* app_window, |
app_controller_map_.erase(it); |
} |
app_window->ResetController(); |
+ app_window_info->set_app_window(nullptr); |
} |
void ArcAppWindowLauncherController::SetOrientationLockForAppWindow( |
@@ -663,13 +692,15 @@ void ArcAppWindowLauncherController::SetOrientationLockForAppWindow( |
ash::WmLookup::Get()->GetWindowForWidget(app_window->widget()); |
if (!window) |
return; |
+ AppWindowInfo* info = GetAppWindowInfoForTask(app_window->task_id()); |
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 { |
ArcAppListPrefs* prefs = ArcAppListPrefs::Get(observed_profile_); |
std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = |
- prefs->GetApp(app_window->app_id()); |
+ prefs->GetApp(info->shelf_app_id()); |
if (!app_info) |
return; |
orientation_lock = app_info->orientation_lock; |
@@ -678,9 +709,8 @@ void ArcAppWindowLauncherController::SetOrientationLockForAppWindow( |
if (orientation_lock == arc::mojom::OrientationLock::CURRENT) { |
// Resolve the orientation when it first resolved. |
orientation_lock = GetCurrentOrientation(); |
- app_window->set_requested_orientation_lock(orientation_lock); |
+ info->set_requested_orientation_lock(orientation_lock); |
} |
- |
ash::Shell* shell = ash::Shell::GetInstance(); |
shell->screen_orientation_controller()->LockOrientationForWindow( |
window, BlinkOrientationLockFromMojom(orientation_lock)); |