Index: ash/shelf/shelf_controller.cc |
diff --git a/ash/shelf/shelf_controller.cc b/ash/shelf/shelf_controller.cc |
index f361975082dfa728a26c41495a20441aa04ea979..0898480b34d45d830aea34ef754f18fea093cdef 100644 |
--- a/ash/shelf/shelf_controller.cc |
+++ b/ash/shelf/shelf_controller.cc |
@@ -4,13 +4,15 @@ |
#include "ash/shelf/shelf_controller.h" |
-#include "ash/public/interfaces/shelf.mojom.h" |
+#include "ash/public/cpp/config.h" |
+#include "ash/public/cpp/remote_shelf_item_delegate.h" |
#include "ash/root_window_controller.h" |
#include "ash/session/session_controller.h" |
#include "ash/shelf/app_list_shelf_item_delegate.h" |
#include "ash/shelf/shelf.h" |
#include "ash/shell.h" |
#include "ash/wm_window.h" |
+#include "base/auto_reset.h" |
#include "base/strings/utf_string_conversions.h" |
#include "ui/base/models/simple_menu_model.h" |
#include "ui/display/display.h" |
@@ -30,12 +32,15 @@ Shelf* GetShelfForDisplay(int64_t display_id) { |
} // namespace |
-ShelfController::ShelfController() { |
+ShelfController::ShelfController() : shelf_model_observer_binding_(this) { |
// Create the app list item in the shelf. |
AppListShelfItemDelegate::CreateAppListItemAndDelegate(&model_); |
+ model_.AddObserver(this); |
} |
-ShelfController::~ShelfController() {} |
+ShelfController::~ShelfController() { |
+ model_.RemoveObserver(this); |
+} |
void ShelfController::BindRequest(mojom::ShelfControllerRequest request) { |
bindings_.AddBinding(this, std::move(request)); |
@@ -73,6 +78,22 @@ void ShelfController::AddObserver( |
observers_.AddPtr(std::move(observer_ptr)); |
} |
+void ShelfController::LinkShelfModels(mojom::ShelfModelObserverPtr observer, |
+ LinkShelfModelsCallback callback) { |
+ // Notify Ash of all the existing local (Chrome) items and delegates. |
+ std::move(callback).Run( |
+ shelf_model_observer_binding_.CreateInterfacePtrAndBind(), |
+ model_.items()); |
+ for (const ShelfItem& item : model_.items()) { |
+ ShelfItemDelegate* delegate = model_.GetShelfItemDelegate(item.id); |
+ mojom::ShelfItemDelegatePtr delegate_ptr; |
+ if (delegate) |
+ delegate_ptr = delegate->CreateInterfacePtrAndBind(); |
+ observer->OnShelfItemDelegateChanged(item.id, std::move(delegate_ptr)); |
+ } |
+ model_observers_.AddPtr(std::move(observer)); |
+} |
+ |
void ShelfController::SetAlignment(ShelfAlignment alignment, |
int64_t display_id) { |
Shelf* shelf = GetShelfForDisplay(display_id); |
@@ -93,19 +114,108 @@ void ShelfController::SetAutoHideBehavior(ShelfAutoHideBehavior auto_hide, |
shelf->SetAutoHideBehavior(auto_hide); |
} |
-void ShelfController::PinItem( |
- const ShelfItem& item, |
- mojom::ShelfItemDelegateAssociatedPtrInfo delegate) { |
- NOTIMPLEMENTED(); |
+void ShelfController::OnShelfItemAdded(int32_t index, const ShelfItem& item) { |
+ DCHECK_EQ(Shell::GetAshConfig(), Config::MASH) << "Unexpected model sync"; |
+ DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change"; |
+ DCHECK_GE(model_.item_count(), index) << "Models out of sync"; |
+ base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true); |
+ model_.AddAt(index, item); |
+} |
+ |
+void ShelfController::OnShelfItemRemoved(int32_t index, const ShelfItem& item) { |
+ DCHECK_EQ(Shell::GetAshConfig(), Config::MASH) << "Unexpected model sync"; |
+ DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change"; |
+ DCHECK_GT(model_.item_count(), index) << "Models out of sync"; |
+ DCHECK_EQ(model_.items()[index].id, item.id) << "Models out of sync"; |
+ base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true); |
+ model_.RemoveItemAt(index); |
+} |
+ |
+void ShelfController::OnShelfItemMoved(int32_t start_index, |
+ int32_t target_index) { |
+ DCHECK_EQ(Shell::GetAshConfig(), Config::MASH) << "Unexpected model sync"; |
+ DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change"; |
+ DCHECK_GT(model_.item_count(), start_index) << "Models out of sync"; |
+ DCHECK_GT(model_.item_count(), target_index) << "Models out of sync"; |
+ base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true); |
+ model_.Move(start_index, target_index); |
} |
-void ShelfController::UnpinItem(const std::string& app_id) { |
- NOTIMPLEMENTED(); |
+void ShelfController::OnShelfItemChanged(int32_t index, const ShelfItem& item) { |
+ DCHECK_EQ(Shell::GetAshConfig(), Config::MASH) << "Unexpected model sync"; |
+ DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change"; |
+ DCHECK_GT(model_.item_count(), index) << "Models out of sync"; |
+ DCHECK_EQ(model_.items()[index].id, item.id) << "Models out of sync"; |
+ base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true); |
+ model_.Set(index, item); |
} |
-void ShelfController::SetItemImage(const std::string& app_id, |
- const SkBitmap& image) { |
- NOTIMPLEMENTED(); |
+void ShelfController::OnShelfItemDelegateChanged( |
+ const ShelfID& id, |
+ mojom::ShelfItemDelegatePtr delegate) { |
+ DCHECK_EQ(Shell::GetAshConfig(), Config::MASH) << "Unexpected model sync"; |
+ DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change"; |
+ base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true); |
+ if (delegate.is_bound()) |
+ model_.SetShelfItemDelegate( |
+ id, base::MakeUnique<RemoteShelfItemDelegate>(id, std::move(delegate))); |
+ else |
+ model_.SetShelfItemDelegate(id, nullptr); |
+} |
+ |
+void ShelfController::ShelfItemAdded(int index) { |
+ if (applying_remote_shelf_model_changes_) |
+ return; |
+ |
+ const ShelfItem& item = model_.items()[index]; |
+ model_observers_.ForAllPtrs( |
+ [index, item](mojom::ShelfModelObserver* observer) { |
+ observer->OnShelfItemAdded(index, item); |
+ }); |
+} |
+ |
+void ShelfController::ShelfItemRemoved(int index, const ShelfItem& old_item) { |
+ if (applying_remote_shelf_model_changes_) |
+ return; |
+ |
+ model_observers_.ForAllPtrs( |
+ [index, old_item](mojom::ShelfModelObserver* observer) { |
+ observer->OnShelfItemRemoved(index, old_item); |
+ }); |
+} |
+ |
+void ShelfController::ShelfItemMoved(int start_index, int target_index) { |
+ if (applying_remote_shelf_model_changes_) |
+ return; |
+ |
+ model_observers_.ForAllPtrs( |
+ [start_index, target_index](mojom::ShelfModelObserver* observer) { |
+ observer->OnShelfItemMoved(start_index, target_index); |
+ }); |
+} |
+ |
+void ShelfController::ShelfItemChanged(int index, const ShelfItem& old_item) { |
+ if (applying_remote_shelf_model_changes_) |
+ return; |
+ |
+ const ShelfItem& item = model_.items()[index]; |
+ model_observers_.ForAllPtrs( |
+ [index, item](mojom::ShelfModelObserver* observer) { |
+ observer->OnShelfItemChanged(index, item); |
+ }); |
+} |
+ |
+void ShelfController::ShelfItemDelegateChanged(const ShelfID& id, |
+ ShelfItemDelegate* delegate) { |
+ if (applying_remote_shelf_model_changes_) |
+ return; |
+ |
+ model_observers_.ForAllPtrs( |
+ [id, delegate](mojom::ShelfModelObserver* observer) { |
+ observer->OnShelfItemDelegateChanged( |
+ id, delegate ? delegate->CreateInterfacePtrAndBind() |
+ : mojom::ShelfItemDelegatePtr()); |
+ }); |
} |
} // namespace ash |