Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc

Issue 1823923002: arc: Support running Arc app in shelf (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased + few nits Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h"
6
7 #include "ash/shelf/shelf_util.h"
8 #include "ash/wm/window_util.h"
9 #include "base/bind.h"
10 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
11 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_item_controller .h"
12 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
13 #include "components/arc/arc_bridge_service.h"
14 #include "components/exo/shell_surface.h"
15 #include "ui/aura/env.h"
16 #include "ui/base/base_window.h"
17 #include "ui/views/widget/widget.h"
18
19 class ArcAppWindowLauncherController::AppWindow : public ui::BaseWindow {
20 public:
21 AppWindow(int task_id, views::Widget* widget)
22 : task_id_(task_id), widget_(widget) {}
23 ~AppWindow() {}
24
25 void SetController(ArcAppWindowLauncherItemController* controller) {
26 DCHECK(!controller_ && controller);
27 controller_ = controller;
28 }
29
30 int task_id() const { return task_id_; }
31
32 ArcAppWindowLauncherItemController* controller() { return controller_; }
33
34 // ui::BaseWindow:
35 bool IsActive() const override { return widget_->IsActive(); }
36
37 bool IsMaximized() const override { return widget_->IsMaximized(); }
38
39 bool IsMinimized() const override { return widget_->IsMinimized(); }
40
41 bool IsFullscreen() const override { return widget_->IsFullscreen(); }
42
43 gfx::NativeWindow GetNativeWindow() const override {
44 return widget_->GetNativeWindow();
45 }
46
47 gfx::Rect GetRestoredBounds() const override {
48 return widget_->GetRestoredBounds();
49 }
50
51 ui::WindowShowState GetRestoredState() const override {
52 // Stub implementation. See also ChromeNativeAppWindowViews.
53 if (IsMaximized())
54 return ui::SHOW_STATE_MAXIMIZED;
55 if (IsFullscreen())
56 return ui::SHOW_STATE_FULLSCREEN;
57 return ui::SHOW_STATE_NORMAL;
58 }
59
60 gfx::Rect GetBounds() const override {
61 return widget_->GetWindowBoundsInScreen();
62 }
63
64 void Show() override {
65 if (widget_->IsVisible()) {
66 widget_->Activate();
67 return;
68 }
69 widget_->Show();
70 }
71
72 void ShowInactive() override {
73 if (widget_->IsVisible())
74 return;
75
76 widget_->ShowInactive();
77 }
78
79 void Hide() override { widget_->Hide(); }
80
81 void Close() override { widget_->Close(); }
82
83 void Activate() override { widget_->Activate(); }
84
85 void Deactivate() override { widget_->Deactivate(); }
86
87 void Maximize() override { widget_->Maximize(); }
88
89 void Minimize() override { widget_->Minimize(); }
90
91 void Restore() override { widget_->Restore(); }
92
93 void SetBounds(const gfx::Rect& bounds) override {
94 widget_->SetBounds(bounds);
95 }
96
97 void FlashFrame(bool flash) override { widget_->FlashFrame(flash); }
98
99 bool IsAlwaysOnTop() const override { return widget_->IsAlwaysOnTop(); }
100
101 void SetAlwaysOnTop(bool always_on_top) override {
102 widget_->SetAlwaysOnTop(always_on_top);
103 }
104
105 private:
106 int task_id_;
107 // Unowned pointers
108 views::Widget* widget_;
109 ArcAppWindowLauncherItemController* controller_ = nullptr;
110
111 DISALLOW_COPY_AND_ASSIGN(AppWindow);
112 };
113
114 ArcAppWindowLauncherController::ArcAppWindowLauncherController(
115 ChromeLauncherController* owner)
116 : AppWindowLauncherController(owner),
117 observed_windows_(this),
118 weak_ptr_factory_(this) {
119 aura::Env* env = aura::Env::GetInstanceDontCreate();
120 if (env)
121 env->AddObserver(this);
122 }
123
124 ArcAppWindowLauncherController::~ArcAppWindowLauncherController() {
125 aura::Env* env = aura::Env::GetInstanceDontCreate();
126 if (env)
127 env->RemoveObserver(this);
128 }
129
130 void ArcAppWindowLauncherController::OnWindowInitialized(aura::Window* window) {
131 DCHECK(!observed_windows_.IsObserving(window));
132
133 // Root Arc window has type WINDOW_TYPE_NORMAL.
134 if (window->type() != ui::wm::WINDOW_TYPE_NORMAL)
135 return;
136
137 observed_windows_.Add(window);
138 }
139
140 void ArcAppWindowLauncherController::OnWindowPropertyChanged(
141 aura::Window* window,
142 const void* key,
143 intptr_t old) {
144 if (window_to_app_window_.find(window) != window_to_app_window_.end())
145 return;
146
147 const std::string app_id = exo::ShellSurface::GetApplicationId(window);
148 if (app_id.empty())
149 return;
150
151 int task_id = 0;
152 if (sscanf(app_id.c_str(), "org.chromium.arc.%d", &task_id) != 1 || !task_id)
153 return;
154
155 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window);
156 DCHECK(widget);
157 window_to_app_window_[window].reset(new AppWindow(task_id, widget));
158
159 arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get();
160 if (!bridge_service) {
161 NOTREACHED();
162 return;
163 }
164
165 arc::AppInstance* app_instance = bridge_service->app_instance();
166 if (!app_instance) {
167 VLOG(2) << "Request to resolve task when bridge service is not ready.";
168 return;
169 }
170
171 // Resolve information about task.
172 app_instance->GetTaskInfo(
173 task_id, base::Bind(&ArcAppWindowLauncherController::OnGetTaskInfo,
174 weak_ptr_factory_.GetWeakPtr(), task_id));
175 }
176
177 void ArcAppWindowLauncherController::OnWindowDestroying(aura::Window* window) {
178 DCHECK(observed_windows_.IsObserving(window));
179 observed_windows_.Remove(window);
180
181 WindowToAppWindow::iterator it = window_to_app_window_.find(window);
182 if (it == window_to_app_window_.end())
183 return;
184
185 ArcAppWindowLauncherItemController* controller = it->second->controller();
186 if (controller) {
187 const std::string app_id = controller->app_id();
188 controller->RemoveWindowForNativeWindow(window);
189 if (!controller->window_count()) {
190 ash::ShelfID shelf_id = ash::GetShelfIDForWindow(window);
191 DCHECK(shelf_id);
192 owner()->CloseLauncherItem(shelf_id);
193 AppControllerMap::iterator it2 = app_controller_map_.find(app_id);
194 DCHECK(it2 != app_controller_map_.end());
195 app_controller_map_.erase(it2);
196 }
197 }
198 window_to_app_window_.erase(it);
199 }
200
201 ArcAppWindowLauncherController::AppWindow*
202 ArcAppWindowLauncherController::GetAppWindowForTask(int task_id) {
203 for (auto& it : window_to_app_window_) {
204 if (it.second->task_id() == task_id)
205 return it.second.get();
206 }
207 return nullptr;
208 }
209
210 void ArcAppWindowLauncherController::OnGetTaskInfo(int task_id,
211 mojo::String package_name,
212 mojo::String activity_name) {
213 if (package_name.get().empty() || activity_name.get().empty())
214 return;
215
216 AppWindow* app_window = GetAppWindowForTask(task_id);
217 if (!app_window)
218 return;
219
220 DCHECK(app_window && !app_window->controller());
221 ash::ShelfItemStatus status =
222 ash::wm::IsActiveWindow(app_window->GetNativeWindow())
223 ? ash::STATUS_ACTIVE
224 : ash::STATUS_RUNNING;
225
226 const std::string app_id =
227 ArcAppListPrefs::GetAppId(package_name, activity_name);
228
229 ArcAppWindowLauncherItemController* controller;
230 AppControllerMap::iterator it = app_controller_map_.find(app_id);
231 ash::ShelfID shelf_id = 0;
232 if (it != app_controller_map_.end()) {
233 controller = it->second;
234 DCHECK(controller->app_id() == app_id);
235 shelf_id = controller->shelf_id();
236 controller->AddWindow(app_window);
237 } else {
238 controller = new ArcAppWindowLauncherItemController(app_id, owner());
239 controller->AddWindow(app_window);
240 shelf_id = owner()->GetShelfIDForAppID(app_id);
241 if (shelf_id == 0)
242 shelf_id = owner()->CreateAppLauncherItem(controller, app_id, status);
243 else
244 owner()->SetItemController(shelf_id, controller);
245 app_controller_map_[app_id] = controller;
246 }
247 app_window->SetController(controller);
248 owner()->SetItemStatus(shelf_id, status);
249 ash::SetShelfIDForWindow(shelf_id, app_window->GetNativeWindow());
250 }
251
252 AppWindowLauncherItemController*
253 ArcAppWindowLauncherController::ControllerForWindow(aura::Window* window) {
254 WindowToAppWindow::iterator it = window_to_app_window_.find(window);
255 if (it == window_to_app_window_.end())
256 return nullptr;
257 return it->second->controller();
258 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698