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

Unified Diff: chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc

Issue 2833173002: mash: Support ShelfModel access in Chrome. (Closed)
Patch Set: Cleanup; Fix an Arc test by use CLC, not Ash's ShelfModel. Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
index a7582988caa445814a8962bd32c5fb25cdd45d15..0c729a9fcb1205bc179d8ace94be77aad9b93460 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
#include "ash/multi_profile_uma.h"
+#include "ash/public/cpp/remote_shelf_item_delegate.h"
#include "ash/public/cpp/shelf_item.h"
#include "ash/public/interfaces/constants.mojom.h"
#include "ash/resources/grit/ash_resources.h"
@@ -183,7 +184,10 @@ ChromeLauncherController* ChromeLauncherController::instance_ = nullptr;
ChromeLauncherController::ChromeLauncherController(Profile* profile,
ash::ShelfModel* model)
- : model_(model), observer_binding_(this), weak_ptr_factory_(this) {
+ : model_(model),
+ observer_binding_(this),
+ shelf_model_observer_binding_(this),
+ weak_ptr_factory_(this) {
DCHECK(!instance_);
instance_ = this;
@@ -280,6 +284,17 @@ void ChromeLauncherController::Init() {
ash::mojom::ShelfObserverAssociatedPtrInfo ptr_info;
observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
shelf_controller_->AddObserver(std::move(ptr_info));
+ if (ash_util::IsRunningInMash()) {
+ // Mash synchronizes two ShelfModel instances, owned by Ash and Chrome.
+ // Delay binding Chrome's observer of Ash for now, to avoid handling Ash's
+ // shelf model changes before the initial states have been synchronized.
+ ash::mojom::ShelfModelObserverPtr observer_ptr;
+ shelf_model_observer_request_ = mojo::MakeRequest(&observer_ptr);
+ shelf_controller_->LinkShelfModels(
+ std::move(observer_ptr),
+ base::Bind(&ChromeLauncherController::LinkShelfModels,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
}
CreateBrowserShortcutLauncherItem();
@@ -1237,6 +1252,31 @@ void ChromeLauncherController::ReleaseProfile() {
PrefServiceSyncableFromProfile(profile())->RemoveObserver(this);
}
+void ChromeLauncherController::LinkShelfModels(
+ ash::mojom::ShelfModelObserverPtr observer,
+ const std::vector<ash::ShelfItem>& items) {
+ // Prepend Ash's shelf model items to the local (Chrome) shelf model.
+ DCHECK(!applying_remote_shelf_model_changes_) << "Unexpected model change";
+ base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, true);
+ for (size_t i = 0; i < items.size(); ++i)
+ model_->AddAt(i, items[i]);
+
+ // Notify Ash of all the other existing local (Chrome) items and delegates.
+ for (int32_t i = items.size(); i < model_->item_count(); ++i) {
+ const ash::ShelfItem& item = model_->items()[i];
+ observer->OnShelfItemAdded(i, item);
+ ash::ShelfItemDelegate* delegate = model_->GetShelfItemDelegate(item.id);
+ observer->OnShelfItemDelegateChanged(
+ item.id, delegate ? delegate->CreateInterfacePtrAndBind()
+ : ash::mojom::ShelfItemDelegatePtr());
+ }
+
+ // Delay binding Chrome's observer of Ash until now, to avoid handling Ash's
+ // shelf model changes before the initial states have been synchronized.
+ shelf_model_observer_binding_.Bind(std::move(shelf_model_observer_request_));
+ shelf_model_observers_.AddPtr(std::move(observer));
+}
+
///////////////////////////////////////////////////////////////////////////////
// ash::mojom::ShelfObserver:
@@ -1273,11 +1313,74 @@ void ChromeLauncherController::OnAutoHideBehaviorChanged(
}
///////////////////////////////////////////////////////////////////////////////
+// ash::mojom::ShelfModelObserver:
+
+void ChromeLauncherController::OnShelfItemAdded(int32_t index,
+ const ash::ShelfItem& item) {
+ DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
+ 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 ChromeLauncherController::OnShelfItemRemoved(int32_t index,
+ const ash::ShelfItem& item) {
+ DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
+ 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 ChromeLauncherController::OnShelfItemMoved(int32_t start_index,
+ int32_t target_index) {
+ DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
+ 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 ChromeLauncherController::OnShelfItemChanged(int32_t index,
+ const ash::ShelfItem& item) {
+ DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
+ 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 ChromeLauncherController::OnShelfItemDelegateChanged(
+ const ash::ShelfID& id,
+ ash::mojom::ShelfItemDelegatePtr delegate) {
+ DCHECK(ash_util::IsRunningInMash()) << "Unexpected model synchronization";
+ 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<ash::RemoteShelfItemDelegate>(
+ id, std::move(delegate)));
+ else
+ model_->SetShelfItemDelegate(id, nullptr);
+}
+
+///////////////////////////////////////////////////////////////////////////////
// ash::ShelfModelObserver:
void ChromeLauncherController::ShelfItemAdded(int index) {
- // Update the pin position preference as needed.
ash::ShelfItem item = model_->items()[index];
+ if (!applying_remote_shelf_model_changes_) {
+ shelf_model_observers_.ForAllPtrs(
+ [index, item](ash::mojom::ShelfModelObserver* observer) {
+ observer->OnShelfItemAdded(index, item);
+ });
+ }
+
+ // Update the pin position preference as needed.
if (ItemTypeIsPinned(item) && should_sync_pin_changes_)
SyncPinPosition(item.id);
@@ -1305,12 +1408,17 @@ void ChromeLauncherController::ShelfItemAdded(int index) {
needs_update = true;
item.status = status;
}
- if (needs_update)
+ if (needs_update) {
+ // Ensure these changes are reported back to Ash.
+ base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, false);
model_->Set(index, item);
+ }
}
// Construct a ShelfItemDelegate for the item if one does not yet exist.
if (!model_->GetShelfItemDelegate(item.id)) {
+ // Ensure these changes are reported back to Ash.
+ base::AutoReset<bool> reset(&applying_remote_shelf_model_changes_, false);
model_->SetShelfItemDelegate(
item.id, AppShortcutLauncherItemController::Create(item.id));
}
@@ -1319,6 +1427,13 @@ void ChromeLauncherController::ShelfItemAdded(int index) {
void ChromeLauncherController::ShelfItemRemoved(
int index,
const ash::ShelfItem& old_item) {
+ if (!applying_remote_shelf_model_changes_) {
+ shelf_model_observers_.ForAllPtrs(
+ [index, old_item](ash::mojom::ShelfModelObserver* observer) {
+ observer->OnShelfItemRemoved(index, old_item);
+ });
+ }
+
// Remove the pin position from preferences as needed.
if (ItemTypeIsPinned(old_item) && should_sync_pin_changes_)
RemovePinPosition(profile(), old_item.id);
@@ -1330,6 +1445,13 @@ void ChromeLauncherController::ShelfItemRemoved(
void ChromeLauncherController::ShelfItemMoved(int start_index,
int target_index) {
+ if (!applying_remote_shelf_model_changes_) {
+ shelf_model_observers_.ForAllPtrs(
+ [start_index, target_index](ash::mojom::ShelfModelObserver* observer) {
+ observer->OnShelfItemMoved(start_index, target_index);
+ });
+ }
+
// Update the pin position preference as needed.
const ash::ShelfItem& item = model_->items()[target_index];
DCHECK_NE(ash::TYPE_APP_LIST, item.type);
@@ -1340,6 +1462,14 @@ void ChromeLauncherController::ShelfItemMoved(int start_index,
void ChromeLauncherController::ShelfItemChanged(
int index,
const ash::ShelfItem& old_item) {
+ if (!applying_remote_shelf_model_changes_) {
+ const ash::ShelfItem& item = model_->items()[index];
+ shelf_model_observers_.ForAllPtrs(
+ [index, item](ash::mojom::ShelfModelObserver* observer) {
+ observer->OnShelfItemChanged(index, item);
+ });
+ }
+
if (!should_sync_pin_changes_)
return;
@@ -1351,6 +1481,20 @@ void ChromeLauncherController::ShelfItemChanged(
RemovePinPosition(profile(), old_item.id);
}
+void ChromeLauncherController::ShelfItemDelegateChanged(
+ const ash::ShelfID& id,
+ ash::ShelfItemDelegate* delegate) {
+ if (applying_remote_shelf_model_changes_)
+ return;
+
+ shelf_model_observers_.ForAllPtrs(
+ [id, delegate](ash::mojom::ShelfModelObserver* observer) {
+ observer->OnShelfItemDelegateChanged(
+ id, delegate ? delegate->CreateInterfacePtrAndBind()
+ : ash::mojom::ShelfItemDelegatePtr());
+ });
+}
+
///////////////////////////////////////////////////////////////////////////////
// ash::WindowTreeHostManager::Observer:

Powered by Google App Engine
This is Rietveld 408576698