OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" | 4 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" |
5 | 5 |
6 #include <string> | 6 #include <string> |
7 | 7 |
8 #include "ash/common/shelf/shelf_delegate.h" | 8 #include "ash/common/shelf/shelf_delegate.h" |
9 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" | 9 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" |
10 #include "ash/common/wm/window_state.h" | 10 #include "ash/common/wm/window_state.h" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 } | 154 } |
155 | 155 |
156 void Show() override { | 156 void Show() override { |
157 // TODO(khmel): support window minimizing. | 157 // TODO(khmel): support window minimizing. |
158 } | 158 } |
159 | 159 |
160 void ShowInactive() override { NOTREACHED(); } | 160 void ShowInactive() override { NOTREACHED(); } |
161 | 161 |
162 void Hide() override { NOTREACHED(); } | 162 void Hide() override { NOTREACHED(); } |
163 | 163 |
164 void Close() override { | 164 void Close() override { arc::CloseTask(task_id_); } |
165 arc::mojom::AppInstance* app_instance = GetAppInstance(); | |
166 if (!app_instance) | |
167 return; | |
168 app_instance->CloseTask(task_id_); | |
169 } | |
170 | 165 |
171 void Activate() override { | 166 void Activate() override { arc::SetTaskActive(task_id_); } |
172 arc::mojom::AppInstance* app_instance = GetAppInstance(); | |
173 if (!app_instance) | |
174 return; | |
175 app_instance->SetTaskActive(task_id_); | |
176 if (widget_) | |
177 widget_->Activate(); | |
178 } | |
179 | 167 |
180 void Deactivate() override { NOTREACHED(); } | 168 void Deactivate() override { NOTREACHED(); } |
181 | 169 |
182 void Maximize() override { NOTREACHED(); } | 170 void Maximize() override { NOTREACHED(); } |
183 | 171 |
184 void Minimize() override { | 172 void Minimize() override { |
185 if (widget_) | 173 if (widget_) |
186 widget_->Minimize(); | 174 widget_->Minimize(); |
187 } | 175 } |
188 | 176 |
(...skipping 17 matching lines...) Expand all Loading... |
206 void set_requested_orientation_lock(arc::mojom::OrientationLock lock) { | 194 void set_requested_orientation_lock(arc::mojom::OrientationLock lock) { |
207 has_requested_orientation_lock_ = true; | 195 has_requested_orientation_lock_ = true; |
208 requested_orientation_lock_ = lock; | 196 requested_orientation_lock_ = lock; |
209 } | 197 } |
210 | 198 |
211 bool has_requested_orientation_lock() const { | 199 bool has_requested_orientation_lock() const { |
212 return has_requested_orientation_lock_; | 200 return has_requested_orientation_lock_; |
213 } | 201 } |
214 | 202 |
215 private: | 203 private: |
216 arc::mojom::AppInstance* GetAppInstance() { | |
217 arc::ArcBridgeService* bridge_service = arc::ArcBridgeService::Get(); | |
218 arc::mojom::AppInstance* app_instance = | |
219 bridge_service ? bridge_service->app()->instance() : nullptr; | |
220 if (!app_instance) { | |
221 VLOG(2) << "Arc Bridge is not available."; | |
222 return nullptr; | |
223 } | |
224 | |
225 if (bridge_service->app()->version() < 3) { | |
226 VLOG(2) << "Arc Bridge has old version for apps." | |
227 << bridge_service->app()->version(); | |
228 return nullptr; | |
229 } | |
230 return app_instance; | |
231 } | |
232 | |
233 int task_id_; | 204 int task_id_; |
234 ash::ShelfID shelf_id_ = 0; | 205 ash::ShelfID shelf_id_ = 0; |
235 std::string app_id_; | 206 std::string app_id_; |
236 FullScreenMode fullscreen_mode_ = FullScreenMode::NOT_DEFINED; | 207 FullScreenMode fullscreen_mode_ = FullScreenMode::NOT_DEFINED; |
237 // Unowned pointers | 208 // Unowned pointers |
238 ArcAppWindowLauncherController* owner_; | 209 ArcAppWindowLauncherController* owner_; |
239 ArcAppWindowLauncherItemController* controller_ = nullptr; | 210 ArcAppWindowLauncherItemController* controller_ = nullptr; |
240 // Unowned pointer, represents host Arc window. | 211 // Unowned pointer, represents host Arc window. |
241 views::Widget* widget_ = nullptr; | 212 views::Widget* widget_ = nullptr; |
242 | 213 |
243 arc::mojom::OrientationLock requested_orientation_lock_ = | 214 arc::mojom::OrientationLock requested_orientation_lock_ = |
244 arc::mojom::OrientationLock::NONE; | 215 arc::mojom::OrientationLock::NONE; |
245 bool has_requested_orientation_lock_ = false; | 216 bool has_requested_orientation_lock_ = false; |
246 | 217 |
247 DISALLOW_COPY_AND_ASSIGN(AppWindow); | 218 DISALLOW_COPY_AND_ASSIGN(AppWindow); |
248 }; | 219 }; |
249 | 220 |
250 struct ArcAppWindowLauncherController::TaskInfo { | |
251 TaskInfo(const std::string& package_name, const std::string& activity_name) | |
252 : package_name(package_name), activity_name(activity_name) {} | |
253 ~TaskInfo() {} | |
254 | |
255 std::string package_name; | |
256 std::string activity_name; | |
257 }; | |
258 | |
259 ArcAppWindowLauncherController::ArcAppWindowLauncherController( | 221 ArcAppWindowLauncherController::ArcAppWindowLauncherController( |
260 ChromeLauncherController* owner, | 222 ChromeLauncherController* owner, |
261 ash::ShelfDelegate* shelf_delegate) | 223 ash::ShelfDelegate* shelf_delegate) |
262 : AppWindowLauncherController(owner), shelf_delegate_(shelf_delegate) { | 224 : AppWindowLauncherController(owner), shelf_delegate_(shelf_delegate) { |
263 if (arc::ArcAuthService::IsAllowedForProfile(owner->GetProfile())) { | 225 if (arc::ArcAuthService::IsAllowedForProfile(owner->GetProfile())) { |
264 observed_profile_ = owner->GetProfile(); | 226 observed_profile_ = owner->GetProfile(); |
265 StartObserving(observed_profile_); | 227 StartObserving(observed_profile_); |
266 } | 228 } |
267 } | 229 } |
268 | 230 |
(...skipping 22 matching lines...) Expand all Loading... |
291 const std::string& user_email) { | 253 const std::string& user_email) { |
292 for (auto& it : task_id_to_app_window_) { | 254 for (auto& it : task_id_to_app_window_) { |
293 AppWindow* app_window = it.second.get(); | 255 AppWindow* app_window = it.second.get(); |
294 if (user_email == | 256 if (user_email == |
295 user_manager::UserManager::Get() | 257 user_manager::UserManager::Get() |
296 ->GetPrimaryUser() | 258 ->GetPrimaryUser() |
297 ->GetAccountId() | 259 ->GetAccountId() |
298 .GetUserEmail()) { | 260 .GetUserEmail()) { |
299 RegisterApp(app_window); | 261 RegisterApp(app_window); |
300 } else { | 262 } else { |
301 UnregisterApp(app_window); | 263 UnregisterApp(app_window, true); |
302 } | 264 } |
303 } | 265 } |
304 } | 266 } |
305 | 267 |
306 void ArcAppWindowLauncherController::AdditionalUserAddedToSession( | 268 void ArcAppWindowLauncherController::AdditionalUserAddedToSession( |
307 Profile* profile) { | 269 Profile* profile) { |
308 DCHECK(!arc::ArcAuthService::IsAllowedForProfile(profile)); | 270 DCHECK(!arc::ArcAuthService::IsAllowedForProfile(profile)); |
309 } | 271 } |
310 | 272 |
311 void ArcAppWindowLauncherController::OnWindowInitialized(aura::Window* window) { | 273 void ArcAppWindowLauncherController::OnWindowInitialized(aura::Window* window) { |
(...skipping 12 matching lines...) Expand all Loading... |
324 MayAttachContollerToWindow(window); | 286 MayAttachContollerToWindow(window); |
325 } | 287 } |
326 | 288 |
327 void ArcAppWindowLauncherController::OnWindowDestroying(aura::Window* window) { | 289 void ArcAppWindowLauncherController::OnWindowDestroying(aura::Window* window) { |
328 auto it = | 290 auto it = |
329 std::find(observed_windows_.begin(), observed_windows_.end(), window); | 291 std::find(observed_windows_.begin(), observed_windows_.end(), window); |
330 DCHECK(it != observed_windows_.end()); | 292 DCHECK(it != observed_windows_.end()); |
331 observed_windows_.erase(it); | 293 observed_windows_.erase(it); |
332 window->RemoveObserver(this); | 294 window->RemoveObserver(this); |
333 | 295 |
334 for (auto& it : task_id_to_app_window_) { | 296 auto it_app_window = |
335 if (it.second->GetNativeWindow() == window) { | 297 std::find_if(task_id_to_app_window_.begin(), task_id_to_app_window_.end(), |
336 OnTaskDestroyed(it.second->task_id()); | 298 [window](const TaskIdToAppWindow::value_type& pair) { |
337 break; | 299 return pair.second->GetNativeWindow() == window; |
338 } | 300 }); |
| 301 if (it_app_window != task_id_to_app_window_.end()) { |
| 302 // Note, window may be recreated in some cases, so do not close controller |
| 303 // on window destroying. Controller will be closed onTaskDestroyed event |
| 304 // which is generated when actual task is destroyed. |
| 305 UnregisterApp(it_app_window->second.get(), false); |
| 306 task_id_to_app_window_.erase(it_app_window); |
339 } | 307 } |
340 } | 308 } |
341 | 309 |
342 ArcAppWindowLauncherController::AppWindow* | 310 ArcAppWindowLauncherController::AppWindow* |
343 ArcAppWindowLauncherController::GetAppWindowForTask(int task_id) { | 311 ArcAppWindowLauncherController::GetAppWindowForTask(int task_id) { |
344 TaskIdToAppWindow::iterator it = task_id_to_app_window_.find(task_id); | 312 TaskIdToAppWindow::iterator it = task_id_to_app_window_.find(task_id); |
345 if (it == task_id_to_app_window_.end()) | 313 if (it == task_id_to_app_window_.end()) |
346 return nullptr; | 314 return nullptr; |
347 return it->second.get(); | 315 return it->second.get(); |
348 } | 316 } |
(...skipping 17 matching lines...) Expand all Loading... |
366 if (!observing_shell_) { | 334 if (!observing_shell_) { |
367 observing_shell_ = true; | 335 observing_shell_ = true; |
368 ash::WmShell::Get()->AddShellObserver(this); | 336 ash::WmShell::Get()->AddShellObserver(this); |
369 } | 337 } |
370 | 338 |
371 // Check if we have controller for this task. | 339 // Check if we have controller for this task. |
372 if (GetAppWindowForTask(task_id)) | 340 if (GetAppWindowForTask(task_id)) |
373 return; | 341 return; |
374 | 342 |
375 // Create controller if we have task info. | 343 // Create controller if we have task info. |
376 TaskIdToTaskInfoMap::iterator it = task_id_to_task_info_.find(task_id); | 344 TaskIdToShelfAppIdMap::iterator it = task_id_to_shelf_app_id_.find(task_id); |
377 if (it == task_id_to_task_info_.end()) | 345 if (it == task_id_to_shelf_app_id_.end()) |
378 return; | 346 return; |
379 | 347 |
380 const TaskInfo& task_info = *it->second; | 348 const std::string& app_id = it->second; |
381 const std::string app_id = | |
382 GetShelfAppIdFromArcAppId(ArcAppListPrefs::GetAppId( | |
383 task_info.package_name, task_info.activity_name)); | |
384 | 349 |
385 std::unique_ptr<AppWindow> app_window(new AppWindow(task_id, app_id, this)); | 350 std::unique_ptr<AppWindow> app_window(new AppWindow(task_id, app_id, this)); |
386 app_window->set_widget(views::Widget::GetWidgetForNativeWindow(window)); | 351 app_window->set_widget(views::Widget::GetWidgetForNativeWindow(window)); |
387 RegisterApp(app_window.get()); | 352 RegisterApp(app_window.get()); |
388 DCHECK(app_window->controller()); | 353 DCHECK(app_window->controller()); |
389 ash::SetShelfIDForWindow(app_window->shelf_id(), window); | 354 ash::SetShelfIDForWindow(app_window->shelf_id(), window); |
390 chrome::MultiUserWindowManager::GetInstance()->SetWindowOwner( | 355 chrome::MultiUserWindowManager::GetInstance()->SetWindowOwner( |
391 window, | 356 window, |
392 user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId()); | 357 user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId()); |
393 if (ash::WmShell::Get() | 358 if (ash::WmShell::Get() |
394 ->maximize_mode_controller() | 359 ->maximize_mode_controller() |
395 ->IsMaximizeModeWindowManagerEnabled()) { | 360 ->IsMaximizeModeWindowManagerEnabled()) { |
396 SetOrientationLockForAppWindow(app_window.get()); | 361 SetOrientationLockForAppWindow(app_window.get()); |
397 } | 362 } |
398 task_id_to_app_window_[task_id] = std::move(app_window); | 363 task_id_to_app_window_[task_id] = std::move(app_window); |
399 | |
400 // TaskInfo is no longer needed. Discard it. | |
401 task_id_to_task_info_.erase(task_id); | |
402 } | 364 } |
403 | 365 |
404 void ArcAppWindowLauncherController::OnAppReadyChanged( | 366 void ArcAppWindowLauncherController::OnAppReadyChanged( |
405 const std::string& app_id, | 367 const std::string& app_id, |
406 bool ready) { | 368 bool ready) { |
407 if (!ready) | 369 if (!ready) |
408 OnAppRemoved(app_id); | 370 OnAppRemoved(app_id); |
409 } | 371 } |
410 | 372 |
411 void ArcAppWindowLauncherController::OnAppRemoved(const std::string& app_id) { | 373 void ArcAppWindowLauncherController::OnAppRemoved(const std::string& app_id) { |
(...skipping 15 matching lines...) Expand all Loading... |
427 OnTaskDestroyed(task_id); | 389 OnTaskDestroyed(task_id); |
428 | 390 |
429 DCHECK(app_controller_map_.find(shelf_app_id) == app_controller_map_.end()); | 391 DCHECK(app_controller_map_.find(shelf_app_id) == app_controller_map_.end()); |
430 } | 392 } |
431 | 393 |
432 void ArcAppWindowLauncherController::OnTaskCreated( | 394 void ArcAppWindowLauncherController::OnTaskCreated( |
433 int task_id, | 395 int task_id, |
434 const std::string& package_name, | 396 const std::string& package_name, |
435 const std::string& activity_name) { | 397 const std::string& activity_name) { |
436 DCHECK(!GetAppWindowForTask(task_id)); | 398 DCHECK(!GetAppWindowForTask(task_id)); |
437 std::unique_ptr<TaskInfo> task_info( | 399 task_id_to_shelf_app_id_[task_id] = GetShelfAppIdFromArcAppId( |
438 new TaskInfo(package_name, activity_name)); | 400 ArcAppListPrefs::GetAppId(package_name, activity_name)); |
439 task_id_to_task_info_[task_id] = std::move(task_info); | |
440 | 401 |
441 for (auto* window : observed_windows_) | 402 for (auto* window : observed_windows_) |
442 MayAttachContollerToWindow(window); | 403 MayAttachContollerToWindow(window); |
443 } | 404 } |
444 | 405 |
445 void ArcAppWindowLauncherController::OnTaskDestroyed(int task_id) { | 406 void ArcAppWindowLauncherController::OnTaskDestroyed(int task_id) { |
446 task_id_to_task_info_.erase(task_id); | 407 auto it = task_id_to_app_window_.find(task_id); |
| 408 if (it != task_id_to_app_window_.end()) { |
| 409 AppWindow* app_window = it->second.get(); |
| 410 UnregisterApp(app_window, true); |
| 411 task_id_to_app_window_.erase(it); |
| 412 } |
447 | 413 |
448 TaskIdToAppWindow::iterator it = task_id_to_app_window_.find(task_id); | 414 // Check if we may close controller now, at this point we can safely remove |
449 if (it == task_id_to_app_window_.end()) | 415 // controllers without window. |
| 416 auto it_app_id = task_id_to_shelf_app_id_.find(task_id); |
| 417 if (it_app_id == task_id_to_shelf_app_id_.end()) |
450 return; | 418 return; |
451 | 419 |
452 AppWindow* app_window = it->second.get(); | 420 const std::string& app_id = it_app_id->second; |
453 UnregisterApp(app_window); | 421 AppControllerMap::iterator it_controller = app_controller_map_.find(app_id); |
| 422 if (it_controller != app_controller_map_.end()) { |
| 423 ArcAppWindowLauncherItemController* controller = it_controller->second; |
| 424 controller->RemoveTaskId(task_id); |
| 425 if (!controller->window_count()) { |
| 426 owner()->CloseLauncherItem(controller->shelf_id()); |
| 427 app_controller_map_.erase(it_controller); |
| 428 } |
| 429 } |
454 | 430 |
455 task_id_to_app_window_.erase(it); | 431 task_id_to_shelf_app_id_.erase(it_app_id); |
456 } | 432 } |
457 | 433 |
458 void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) { | 434 void ArcAppWindowLauncherController::OnTaskSetActive(int32_t task_id) { |
459 if (observed_profile_ != owner()->GetProfile()) | 435 if (observed_profile_ != owner()->GetProfile()) |
460 return; | 436 return; |
461 | 437 |
462 TaskIdToAppWindow::iterator previous_active_app_it = | 438 TaskIdToAppWindow::iterator previous_active_app_it = |
463 task_id_to_app_window_.find(active_task_id_); | 439 task_id_to_app_window_.find(active_task_id_); |
464 if (previous_active_app_it != task_id_to_app_window_.end()) { | 440 if (previous_active_app_it != task_id_to_app_window_.end()) { |
465 owner()->SetItemStatus(previous_active_app_it->second->shelf_id(), | 441 owner()->SetItemStatus(previous_active_app_it->second->shelf_id(), |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 if (shelf_id == 0) { | 556 if (shelf_id == 0) { |
581 // Map Play Store shelf icon to Arc Support host, to share one entry. | 557 // Map Play Store shelf icon to Arc Support host, to share one entry. |
582 shelf_id = owner()->CreateAppLauncherItem(controller, app_id, | 558 shelf_id = owner()->CreateAppLauncherItem(controller, app_id, |
583 ash::STATUS_RUNNING); | 559 ash::STATUS_RUNNING); |
584 } else { | 560 } else { |
585 owner()->SetItemController(shelf_id, controller); | 561 owner()->SetItemController(shelf_id, controller); |
586 } | 562 } |
587 app_controller_map_[app_id] = controller; | 563 app_controller_map_[app_id] = controller; |
588 } | 564 } |
589 controller->AddWindow(app_window); | 565 controller->AddWindow(app_window); |
| 566 controller->AddTaskId(app_window->task_id()); |
590 owner()->SetItemStatus(shelf_id, ash::STATUS_RUNNING); | 567 owner()->SetItemStatus(shelf_id, ash::STATUS_RUNNING); |
591 app_window->SetController(controller); | 568 app_window->SetController(controller); |
592 app_window->set_shelf_id(shelf_id); | 569 app_window->set_shelf_id(shelf_id); |
593 } | 570 } |
594 | 571 |
595 void ArcAppWindowLauncherController::UnregisterApp(AppWindow* app_window) { | 572 void ArcAppWindowLauncherController::UnregisterApp(AppWindow* app_window, |
| 573 bool close_controller) { |
596 const std::string app_id = app_window->app_id(); | 574 const std::string app_id = app_window->app_id(); |
597 DCHECK(!app_id.empty()); | 575 DCHECK(!app_id.empty()); |
598 AppControllerMap::iterator it = app_controller_map_.find(app_id); | 576 AppControllerMap::iterator it = app_controller_map_.find(app_id); |
599 DCHECK(it != app_controller_map_.end()); | 577 DCHECK(it != app_controller_map_.end()); |
600 | 578 |
601 ArcAppWindowLauncherItemController* controller = it->second; | 579 ArcAppWindowLauncherItemController* controller = it->second; |
602 controller->RemoveWindow(app_window); | 580 controller->RemoveWindow(app_window); |
603 if (!controller->window_count()) { | 581 if (close_controller && !controller->window_count()) { |
604 ash::ShelfID shelf_id = app_window->shelf_id(); | 582 ash::ShelfID shelf_id = app_window->shelf_id(); |
605 owner()->CloseLauncherItem(shelf_id); | 583 owner()->CloseLauncherItem(shelf_id); |
606 app_controller_map_.erase(it); | 584 app_controller_map_.erase(it); |
607 } | 585 } |
608 app_window->ResetController(); | 586 app_window->ResetController(); |
609 } | 587 } |
610 | 588 |
611 void ArcAppWindowLauncherController::SetOrientationLockForAppWindow( | 589 void ArcAppWindowLauncherController::SetOrientationLockForAppWindow( |
612 AppWindow* app_window) { | 590 AppWindow* app_window) { |
613 ash::WmWindow* window = | 591 ash::WmWindow* window = |
(...skipping 15 matching lines...) Expand all Loading... |
629 if (orientation_lock == arc::mojom::OrientationLock::CURRENT) { | 607 if (orientation_lock == arc::mojom::OrientationLock::CURRENT) { |
630 // Resolve the orientation when it first resolved. | 608 // Resolve the orientation when it first resolved. |
631 orientation_lock = GetCurrentOrientation(); | 609 orientation_lock = GetCurrentOrientation(); |
632 app_window->set_requested_orientation_lock(orientation_lock); | 610 app_window->set_requested_orientation_lock(orientation_lock); |
633 } | 611 } |
634 | 612 |
635 ash::Shell* shell = ash::Shell::GetInstance(); | 613 ash::Shell* shell = ash::Shell::GetInstance(); |
636 shell->screen_orientation_controller()->LockOrientationForWindow( | 614 shell->screen_orientation_controller()->LockOrientationForWindow( |
637 window, BlinkOrientationLockFromMojom(orientation_lock)); | 615 window, BlinkOrientationLockFromMojom(orientation_lock)); |
638 } | 616 } |
OLD | NEW |