| 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 1ebd198c9bfc31cc9f9732f1d1ff3b80ccbb9c97..cf5eba22eddb979373773f3571bd7d02d19a4671 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
|
| @@ -87,12 +87,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;
|
| @@ -100,13 +100,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) {
|
| @@ -133,8 +172,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_;
|
| @@ -203,23 +240,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_;
|
| @@ -227,10 +250,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);
|
| };
|
|
|
| @@ -277,19 +296,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.
|
| @@ -339,26 +355,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() {
|
| @@ -385,38 +405,38 @@ 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());
|
| - ash::SetShelfIDForWindow(app_window->shelf_id(), window);
|
| + DCHECK(!info->app_window());
|
| + info->set_app_window(base::MakeUnique<AppWindow>(task_id, widget, this));
|
| + RegisterApp(info);
|
| + DCHECK(info->app_window()->controller());
|
| + ash::SetShelfIDForWindow(info->app_window()->shelf_id(), window);
|
| 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;
|
|
|
| @@ -439,10 +459,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;
|
| @@ -456,21 +477,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);
|
| @@ -480,7 +496,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) {
|
| @@ -489,27 +505,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
|
| @@ -525,17 +538,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);
|
| }
|
| }
|
|
|
| @@ -547,9 +562,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;
|
| @@ -563,8 +582,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() {
|
| @@ -597,7 +619,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);
|
| @@ -620,15 +642,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);
|
| @@ -637,12 +661,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;
|
| @@ -653,6 +681,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(
|
| @@ -661,13 +690,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;
|
| @@ -676,9 +707,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));
|
|
|