Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 | 4 |
| 5 #include "chrome/browser/ui/views/ash/launcher/chrome_launcher_controller.h" | 5 #include "chrome/browser/ui/views/ash/launcher/chrome_launcher_controller.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "ash/launcher/launcher_model.h" | 10 #include "ash/launcher/launcher_model.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 } | 57 } |
| 58 | 58 |
| 59 // ChromeLauncherController ---------------------------------------------------- | 59 // ChromeLauncherController ---------------------------------------------------- |
| 60 | 60 |
| 61 // static | 61 // static |
| 62 ChromeLauncherController* ChromeLauncherController::instance_ = NULL; | 62 ChromeLauncherController* ChromeLauncherController::instance_ = NULL; |
| 63 | 63 |
| 64 ChromeLauncherController::ChromeLauncherController(Profile* profile, | 64 ChromeLauncherController::ChromeLauncherController(Profile* profile, |
| 65 ash::LauncherModel* model) | 65 ash::LauncherModel* model) |
| 66 : model_(model), | 66 : model_(model), |
| 67 profile_(profile) { | 67 profile_(profile), |
| 68 activation_client_(NULL) { | |
| 68 if (!profile_) { | 69 if (!profile_) { |
| 69 // Use the original profile as on chromeos we may get a temporary off the | 70 // Use the original profile as on chromeos we may get a temporary off the |
| 70 // record profile. | 71 // record profile. |
| 71 profile_ = ProfileManager::GetDefaultProfile()->GetOriginalProfile(); | 72 profile_ = ProfileManager::GetDefaultProfile()->GetOriginalProfile(); |
| 72 } | 73 } |
| 73 instance_ = this; | 74 instance_ = this; |
| 74 model_->AddObserver(this); | 75 model_->AddObserver(this); |
| 75 ShellWindowRegistry::Get(profile_)->AddObserver(this); | 76 ShellWindowRegistry::Get(profile_)->AddObserver(this); |
| 76 app_icon_loader_.reset(new LauncherAppIconLoader(profile_, this)); | 77 app_icon_loader_.reset(new LauncherAppIconLoader(profile_, this)); |
| 77 | 78 |
| 78 notification_registrar_.Add(this, | 79 notification_registrar_.Add(this, |
| 79 chrome::NOTIFICATION_EXTENSION_LOADED, | 80 chrome::NOTIFICATION_EXTENSION_LOADED, |
| 80 content::Source<Profile>(profile_)); | 81 content::Source<Profile>(profile_)); |
| 81 notification_registrar_.Add(this, | 82 notification_registrar_.Add(this, |
| 82 chrome::NOTIFICATION_EXTENSION_UNLOADED, | 83 chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 83 content::Source<Profile>(profile_)); | 84 content::Source<Profile>(profile_)); |
| 84 pref_change_registrar_.Init(profile_->GetPrefs()); | 85 pref_change_registrar_.Init(profile_->GetPrefs()); |
| 85 pref_change_registrar_.Add(prefs::kPinnedLauncherApps, this); | 86 pref_change_registrar_.Add(prefs::kPinnedLauncherApps, this); |
| 86 } | 87 } |
| 87 | 88 |
| 88 ChromeLauncherController::~ChromeLauncherController() { | 89 ChromeLauncherController::~ChromeLauncherController() { |
| 89 ShellWindowRegistry::Get(profile_)->RemoveObserver(this); | 90 ShellWindowRegistry::Get(profile_)->RemoveObserver(this); |
| 90 model_->RemoveObserver(this); | 91 model_->RemoveObserver(this); |
| 91 for (IDToItemMap::iterator i = id_to_item_map_.begin(); | 92 for (IDToItemMap::iterator i = id_to_item_map_.begin(); |
| 92 i != id_to_item_map_.end(); ++i) { | 93 i != id_to_item_map_.end(); ++i) { |
| 93 model_->RemoveItemAt(model_->ItemIndexByID(i->first)); | 94 model_->RemoveItemAt(model_->ItemIndexByID(i->first)); |
| 94 } | 95 } |
| 95 if (instance_ == this) | 96 if (instance_ == this) |
| 96 instance_ = NULL; | 97 instance_ = NULL; |
| 98 if (activation_client_) | |
| 99 activation_client_->RemoveObserver(this); | |
| 97 } | 100 } |
|
sky
2012/06/11 17:47:39
Remove observers from any windows in window_to_id_
DaveMoore
2012/06/11 18:13:40
Done.
| |
| 98 | 101 |
| 99 void ChromeLauncherController::Init() { | 102 void ChromeLauncherController::Init() { |
| 100 // TODO(xiyuan): Remove migration code and kUseDefaultPinnedApp after M20. | 103 // TODO(xiyuan): Remove migration code and kUseDefaultPinnedApp after M20. |
| 101 // Migration cases: | 104 // Migration cases: |
| 102 // - Users that unpin all apps: | 105 // - Users that unpin all apps: |
| 103 // - have default pinned apps | 106 // - have default pinned apps |
| 104 // - kUseDefaultPinnedApps set to false | 107 // - kUseDefaultPinnedApps set to false |
| 105 // Migrate them by setting an empty list for kPinnedLauncherApps. | 108 // Migrate them by setting an empty list for kPinnedLauncherApps. |
| 106 // | 109 // |
| 107 // - Users that have customized pinned apps: | 110 // - Users that have customized pinned apps: |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 126 if (ash::Shell::HasInstance()) { | 129 if (ash::Shell::HasInstance()) { |
| 127 std::string behavior_value( | 130 std::string behavior_value( |
| 128 profile_->GetPrefs()->GetString(prefs::kShelfAutoHideBehavior)); | 131 profile_->GetPrefs()->GetString(prefs::kShelfAutoHideBehavior)); |
| 129 ash::ShelfAutoHideBehavior behavior = | 132 ash::ShelfAutoHideBehavior behavior = |
| 130 ash::SHELF_AUTO_HIDE_BEHAVIOR_DEFAULT; | 133 ash::SHELF_AUTO_HIDE_BEHAVIOR_DEFAULT; |
| 131 if (behavior_value == ash::kShelfAutoHideBehaviorNever) | 134 if (behavior_value == ash::kShelfAutoHideBehaviorNever) |
| 132 behavior = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER; | 135 behavior = ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER; |
| 133 else if (behavior_value == ash::kShelfAutoHideBehaviorAlways) | 136 else if (behavior_value == ash::kShelfAutoHideBehaviorAlways) |
| 134 behavior = ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; | 137 behavior = ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; |
| 135 ash::Shell::GetInstance()->SetShelfAutoHideBehavior(behavior); | 138 ash::Shell::GetInstance()->SetShelfAutoHideBehavior(behavior); |
| 139 activation_client_ = | |
| 140 aura::client::GetActivationClient( | |
| 141 ash::Shell::GetInstance()->GetPrimaryRootWindow()); | |
| 142 activation_client_->AddObserver(this); | |
| 136 } | 143 } |
| 137 } | 144 } |
| 138 | 145 |
| 139 ash::LauncherID ChromeLauncherController::CreateTabbedLauncherItem( | 146 ash::LauncherID ChromeLauncherController::CreateTabbedLauncherItem( |
| 140 BrowserLauncherItemController* controller, | 147 BrowserLauncherItemController* controller, |
| 141 IncognitoState is_incognito, | 148 IncognitoState is_incognito, |
| 142 ash::LauncherItemStatus status) { | 149 ash::LauncherItemStatus status) { |
| 143 ash::LauncherID id = model_->next_id(); | 150 ash::LauncherID id = model_->next_id(); |
| 144 DCHECK(id_to_item_map_.find(id) == id_to_item_map_.end()); | 151 DCHECK(id_to_item_map_.find(id) == id_to_item_map_.end()); |
| 145 id_to_item_map_[id].item_type = TYPE_TABBED_BROWSER; | 152 id_to_item_map_[id].item_type = TYPE_TABBED_BROWSER; |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 491 NOTREACHED() << "Unexpected pref change for " << pref_name; | 498 NOTREACHED() << "Unexpected pref change for " << pref_name; |
| 492 } | 499 } |
| 493 break; | 500 break; |
| 494 } | 501 } |
| 495 default: | 502 default: |
| 496 NOTREACHED() << "Unexpected notification type=" << type; | 503 NOTREACHED() << "Unexpected notification type=" << type; |
| 497 } | 504 } |
| 498 } | 505 } |
| 499 | 506 |
| 500 void ChromeLauncherController::OnShellWindowAdded(ShellWindow* shell_window) { | 507 void ChromeLauncherController::OnShellWindowAdded(ShellWindow* shell_window) { |
| 508 aura::Window* window = shell_window->GetNativeWindow(); | |
| 509 ash::LauncherItemStatus status = | |
| 510 ash::wm::IsActiveWindow(window) ? | |
| 511 ash::STATUS_ACTIVE : ash::STATUS_RUNNING; | |
| 512 window->AddObserver(this); | |
| 501 const std::string app_id = shell_window->extension()->id(); | 513 const std::string app_id = shell_window->extension()->id(); |
| 502 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); | 514 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); |
| 503 i != id_to_item_map_.end(); ++i) { | 515 i != id_to_item_map_.end(); ++i) { |
| 504 if (i->second.app_id == app_id) { | 516 if (i->second.app_id == app_id) { |
| 505 SetItemStatus(i->first, ash::STATUS_RUNNING); | 517 window_to_id_map_[window] = i->first; |
| 518 SetItemStatus(i->first, status); | |
| 506 return; | 519 return; |
| 507 } | 520 } |
| 508 } | 521 } |
| 509 CreateAppLauncherItem(NULL, app_id, ash::STATUS_RUNNING); | 522 ash::LauncherID id = CreateAppLauncherItem(NULL, app_id, status); |
| 523 window_to_id_map_[window] = id; | |
| 510 } | 524 } |
| 511 | 525 |
| 512 void ChromeLauncherController::OnShellWindowRemoved(ShellWindow* shell_window) { | 526 void ChromeLauncherController::OnShellWindowRemoved(ShellWindow* shell_window) { |
| 513 const std::string app_id = shell_window->extension()->id(); | 527 // Window removal is handled in OnWindowRemovingFromRootWindow() below. |
| 514 ShellWindowRegistry* registry = ShellWindowRegistry::Get(profile_); | 528 } |
| 515 if (registry->GetShellWindowsForApp(app_id).size() > 0) | |
| 516 return; | |
| 517 | 529 |
| 518 for (IDToItemMap::const_iterator i = id_to_item_map_.begin(); | 530 void ChromeLauncherController::OnWindowActivated(aura::Window* active, |
| 519 i != id_to_item_map_.end(); ++i) { | 531 aura::Window* old_active) { |
| 520 if (i->second.app_id == app_id) { | 532 if (window_to_id_map_.find(old_active) != window_to_id_map_.end()) { |
| 521 int index = model_->ItemIndexByID(i->first); | 533 if (window_to_id_map_.find(active) != window_to_id_map_.end() && |
| 522 DCHECK_GE(index, 0); | 534 window_to_id_map_[old_active] == window_to_id_map_[active]) { |
| 523 ash::LauncherItem item = model_->items()[index]; | 535 // Old and new windows are for the same item. Don't change the status. |
| 524 if (item.type == ash::TYPE_APP_SHORTCUT) | |
| 525 SetItemStatus(i->first, ash::STATUS_CLOSED); | |
| 526 else | |
| 527 LauncherItemClosed(i->first); | |
| 528 return; | 536 return; |
| 529 } | 537 } |
| 538 SetItemStatus(window_to_id_map_[old_active], ash::STATUS_RUNNING); | |
| 530 } | 539 } |
| 540 if (window_to_id_map_.find(active) != window_to_id_map_.end()) | |
| 541 SetItemStatus(window_to_id_map_[active], ash::STATUS_ACTIVE); | |
| 542 } | |
| 543 | |
| 544 void ChromeLauncherController::OnWindowRemovingFromRootWindow( | |
| 545 aura::Window* window) { | |
| 546 ash::LauncherID id = window_to_id_map_[window]; | |
|
sky
2012/06/11 17:47:39
window->RemoveObserver(this) ?
sky
2012/06/11 17:47:39
DCHECK(window_to_id_map_.find(window) != window_to
DaveMoore
2012/06/11 18:13:40
Done.
| |
| 547 window_to_id_map_.erase(window); | |
| 548 | |
| 549 DCHECK(id_to_item_map_.find(id) != id_to_item_map_.end()); | |
| 550 ShellWindowRegistry::ShellWindowSet remaining_windows = | |
| 551 ShellWindowRegistry::Get(profile_)->GetShellWindowsForApp( | |
| 552 id_to_item_map_[id].app_id); | |
| 553 | |
| 554 // We can't count on getting called before or after the ShellWindowRegistry. | |
| 555 if (remaining_windows.size() > 1 || | |
| 556 (remaining_windows.size() == 1 && | |
| 557 (*remaining_windows.begin())->GetNativeWindow() != window)) { | |
| 558 return; | |
| 559 } | |
| 560 | |
| 561 // Close or remove item. | |
| 562 int index = model_->ItemIndexByID(id); | |
| 563 DCHECK_GE(index, 0); | |
| 564 ash::LauncherItem item = model_->items()[index]; | |
| 565 if (item.type == ash::TYPE_APP_SHORTCUT) | |
| 566 SetItemStatus(id, ash::STATUS_CLOSED); | |
| 567 else | |
| 568 LauncherItemClosed(id); | |
| 531 } | 569 } |
| 532 | 570 |
| 533 void ChromeLauncherController::PersistPinnedState() { | 571 void ChromeLauncherController::PersistPinnedState() { |
| 534 // It is a coding error to call PersistPinnedState() if the pinned apps are | 572 // It is a coding error to call PersistPinnedState() if the pinned apps are |
| 535 // not user-editable. The code should check earlier and not perform any | 573 // not user-editable. The code should check earlier and not perform any |
| 536 // modification actions that trigger persisting the state. | 574 // modification actions that trigger persisting the state. |
| 537 if (!CanPin()) { | 575 if (!CanPin()) { |
| 538 NOTREACHED() << "Can't pin but pinned state being updated"; | 576 NOTREACHED() << "Can't pin but pinned state being updated"; |
| 539 return; | 577 return; |
| 540 } | 578 } |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 725 } | 763 } |
| 726 model_->AddAt(index, item); | 764 model_->AddAt(index, item); |
| 727 | 765 |
| 728 if (!controller || controller->type() != | 766 if (!controller || controller->type() != |
| 729 BrowserLauncherItemController::TYPE_EXTENSION_PANEL) { | 767 BrowserLauncherItemController::TYPE_EXTENSION_PANEL) { |
| 730 if (item.status != ash::STATUS_IS_PENDING) | 768 if (item.status != ash::STATUS_IS_PENDING) |
| 731 app_icon_loader_->FetchImage(app_id); | 769 app_icon_loader_->FetchImage(app_id); |
| 732 } | 770 } |
| 733 return id; | 771 return id; |
| 734 } | 772 } |
| OLD | NEW |