summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mojo/examples/embedded_app/embedded_app.cc2
-rw-r--r--mojo/examples/window_manager/window_manager.cc2
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_manager.cc47
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_manager_private.h4
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc8
-rw-r--r--mojo/services/public/cpp/view_manager/tests/DEPS3
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc69
-rw-r--r--mojo/services/public/cpp/view_manager/view_manager.h22
8 files changed, 135 insertions, 22 deletions
diff --git a/mojo/examples/embedded_app/embedded_app.cc b/mojo/examples/embedded_app/embedded_app.cc
index 139e313..73f7f93 100644
--- a/mojo/examples/embedded_app/embedded_app.cc
+++ b/mojo/examples/embedded_app/embedded_app.cc
@@ -19,7 +19,7 @@ class EmbeddedApp : public Application {
private:
// Overridden from Application:
virtual void Initialize() MOJO_OVERRIDE {
- view_manager_ = new view_manager::ViewManager(this);
+ view_manager_ = view_manager::ViewManager::CreateBlocking(this);
view_manager::View* view = view_manager::View::Create(view_manager_);
view_manager_->tree()->SetActiveView(view);
view->SetColor(SK_ColorYELLOW);
diff --git a/mojo/examples/window_manager/window_manager.cc b/mojo/examples/window_manager/window_manager.cc
index 8aa52a3..e3e88ac 100644
--- a/mojo/examples/window_manager/window_manager.cc
+++ b/mojo/examples/window_manager/window_manager.cc
@@ -19,7 +19,7 @@ class WindowManager : public Application {
private:
// Overridden from Application:
virtual void Initialize() MOJO_OVERRIDE {
- view_manager_ = new view_manager::ViewManager(this);
+ view_manager_ = view_manager::ViewManager::CreateBlocking(this);
view_manager::ViewTreeNode* node =
view_manager::ViewTreeNode::Create(view_manager_);
view_manager_->tree()->AddChild(node);
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager.cc b/mojo/services/public/cpp/view_manager/lib/view_manager.cc
index 74fa699..936387f1 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager.cc
@@ -4,23 +4,27 @@
#include "mojo/services/public/cpp/view_manager/view_manager.h"
-#include "base/message_loop/message_loop.h"
+#include "base/bind.h"
+#include "base/run_loop.h"
#include "mojo/public/cpp/application/application.h"
+#include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
#include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
#include "mojo/services/public/cpp/view_manager/view.h"
namespace mojo {
namespace view_manager {
+namespace {
-ViewManager::ViewManager(Application* application)
- : synchronizer_(NULL),
- tree_(NULL) {
- application->AddService<ViewManagerSynchronizer>(this);
- // Block in a nested message loop until the ViewManagerSynchronizer is set up.
- base::MessageLoop::current()->Run();
+void OnViewManagerReady(base::RunLoop* loop, ViewManager* manager) {
+ loop->Quit();
}
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// ViewManager, public:
+
ViewManager::~ViewManager() {
while (!nodes_.empty()) {
IdToNodeMap::iterator it = nodes_.begin();
@@ -38,6 +42,23 @@ ViewManager::~ViewManager() {
}
}
+// static
+ViewManager* ViewManager::CreateBlocking(Application* application) {
+ base::RunLoop init_loop;
+ ViewManager* manager = new ViewManager(
+ application,
+ base::Bind(&OnViewManagerReady, &init_loop));
+ init_loop.Run();
+ return manager;
+}
+
+// static
+void ViewManager::Create(
+ Application* application,
+ const base::Callback<void(ViewManager*)> ready_callback) {
+ new ViewManager(application, ready_callback);
+}
+
ViewTreeNode* ViewManager::GetNodeById(TransportNodeId id) {
IdToNodeMap::const_iterator it = nodes_.find(id);
return it != nodes_.end() ? it->second : NULL;
@@ -52,5 +73,17 @@ void ViewManager::Embed(const String& url, ViewTreeNode* node) {
synchronizer_->Embed(url, node->id());
}
+////////////////////////////////////////////////////////////////////////////////
+// ViewManager, private:
+
+ViewManager::ViewManager(
+ Application* application,
+ const base::Callback<void(ViewManager*)> ready_callback)
+ : ready_callback_(ready_callback),
+ synchronizer_(NULL),
+ tree_(NULL) {
+ application->AddService<ViewManagerSynchronizer>(this);
+}
+
} // namespace view_manager
} // namespace mojo
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_private.h b/mojo/services/public/cpp/view_manager/lib/view_manager_private.h
index a2b2aab..1c091ed 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_private.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_private.h
@@ -19,6 +19,10 @@ class ViewManagerPrivate {
explicit ViewManagerPrivate(ViewManager* manager);
~ViewManagerPrivate();
+ void NotifyReady() {
+ manager_->ready_callback_.Run(manager_);
+ }
+
ViewManagerSynchronizer* synchronizer() {
return manager_->synchronizer_;
}
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
index 7d1d489..258aeae 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
@@ -560,12 +560,10 @@ void ViewManagerSynchronizer::OnViewManagerConnectionEstablished(
connection_id_ = connection_id;
next_server_change_id_ = next_server_change_id;
- ViewManagerPrivate(view_manager()).set_root(
- BuildNodeTree(view_manager(), nodes));
-
+ ViewManagerPrivate private_manager(view_manager());
+ private_manager.set_root(BuildNodeTree(view_manager(), nodes));
Sync();
-
- base::MessageLoop::current()->Quit();
+ private_manager.NotifyReady();
}
void ViewManagerSynchronizer::OnServerChangeIdAdvanced(
diff --git a/mojo/services/public/cpp/view_manager/tests/DEPS b/mojo/services/public/cpp/view_manager/tests/DEPS
new file mode 100644
index 0000000..a024069
--- /dev/null
+++ b/mojo/services/public/cpp/view_manager/tests/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+mojo/service_manager",
+]
diff --git a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
index 90bbb6c..7c70b45 100644
--- a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
+++ b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc
@@ -6,6 +6,8 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "mojo/public/cpp/application/application.h"
+#include "mojo/service_manager/service_manager.h"
#include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
#include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
@@ -20,6 +22,8 @@ namespace mojo {
namespace view_manager {
namespace {
+const char kTestServiceURL[] = "mojo:test_url";
+
base::RunLoop* current_run_loop = NULL;
void DoRunLoop() {
@@ -44,6 +48,33 @@ void WaitForAllChangesToBeAcked(ViewManager* manager) {
ViewManagerPrivate(manager).synchronizer()->ClearChangesAckedCallback();
}
+// Used with IViewManager::Connect(). Creates a TestViewManagerClientConnection,
+// which creates and owns the ViewManagerProxy.
+class ConnectServiceLoader : public ServiceLoader {
+ public:
+ explicit ConnectServiceLoader(base::Callback<void(ViewManager*)> callback)
+ : callback_(callback) {}
+ virtual ~ConnectServiceLoader() {}
+
+ // ServiceLoader:
+ virtual void LoadService(ServiceManager* manager,
+ const GURL& url,
+ ScopedMessagePipeHandle shell_handle) OVERRIDE {
+ scoped_ptr<Application> app(new Application(shell_handle.Pass()));
+ ViewManager::Create(app.get(), callback_);
+ apps_.push_back(app.release());
+ }
+ virtual void OnServiceError(ServiceManager* manager,
+ const GURL& url) OVERRIDE {
+ }
+
+ private:
+ ScopedVector<Application> apps_;
+ base::Callback<void(ViewManager*)> callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConnectServiceLoader);
+};
+
class ActiveViewChangedObserver : public ViewTreeNodeObserver {
public:
explicit ActiveViewChangedObserver(ViewTreeNode* node)
@@ -276,10 +307,45 @@ class ViewManagerTest : public testing::Test {
// Overridden from testing::Test:
virtual void SetUp() OVERRIDE {
test_helper_.Init();
+ ConnectServiceLoader* loader =
+ new ConnectServiceLoader(
+ base::Bind(&ViewManagerTest::OnViewManagerLoaded,
+ base::Unretained(this)));
+ test_helper_.SetLoaderForURL(
+ scoped_ptr<ServiceLoader>(loader),
+ GURL(kTestServiceURL));
+
+ ConnectToService(test_helper_.service_provider(),
+ "mojo:mojo_view_manager",
+ &view_manager_init_);
+ ASSERT_TRUE(ViewManagerInitConnect(view_manager_init_.get(),
+ kTestServiceURL));
+ }
+
+ void ViewManagerInitConnectCallback(bool* result_cache,
+ bool result) {
+ *result_cache = result;
+ }
+
+ bool ViewManagerInitConnect(IViewManagerInit* view_manager_init,
+ const std::string& url) {
+ bool result = false;
+ view_manager_init->Connect(
+ url,
+ base::Bind(&ViewManagerTest::ViewManagerInitConnectCallback,
+ base::Unretained(this), &result));
+ init_loop_.Run();
+ return result;
+ }
+
+ void OnViewManagerLoaded(ViewManager* view_manager) {
+ init_loop_.Quit();
}
base::MessageLoop loop_;
+ base::RunLoop init_loop_;
shell::ShellTestHelper test_helper_;
+ IViewManagerInitPtr view_manager_init_;
ViewManager* view_manager_1_;
ViewManager* view_manager_2_;
int commit_count_;
@@ -336,6 +402,9 @@ class HierarchyChanged_NodeCreatedObserver : public TreeObserverBase {
// TODO(beng): reenable these once converted to new way of connecting.
+TEST_F(ViewManagerTest, SetUp) {
+}
+
TEST_F(ViewManagerTest, DISABLED_HierarchyChanged_NodeCreated) {
HierarchyChanged_NodeCreatedObserver observer(view_manager_2());
ViewTreeNode* node1 = ViewTreeNode::Create(view_manager_1());
diff --git a/mojo/services/public/cpp/view_manager/view_manager.h b/mojo/services/public/cpp/view_manager/view_manager.h
index edfe2c1..34db8e7 100644
--- a/mojo/services/public/cpp/view_manager/view_manager.h
+++ b/mojo/services/public/cpp/view_manager/view_manager.h
@@ -8,6 +8,7 @@
#include <map>
#include "base/basictypes.h"
+#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "mojo/public/cpp/bindings/callback.h"
#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
@@ -27,16 +28,16 @@ class ViewTreeNode;
// TODO: displays
class ViewManager {
public:
- // Blocks on establishing the connection and subsequently receiving a node
- // tree from the service.
- // TODO(beng): blocking is currently achieved by running a nested runloop,
- // which will dispatch all messages on all pipes while blocking.
- // we should instead wait on the client pipe receiving a
- // connection established message.
- // TODO(beng): this method could optionally not block if supplied a callback.
- explicit ViewManager(Application* application);
~ViewManager();
+ // |ready_callback| is run when the ViewManager connection is established
+ // and ready to use.
+ static void Create(
+ Application* application,
+ const base::Callback<void(ViewManager*)> ready_callback);
+ // Blocks until ViewManager is ready to use.
+ static ViewManager* CreateBlocking(Application* application);
+
ViewTreeNode* tree() { return tree_; }
ViewTreeNode* GetNodeById(TransportNodeId id);
@@ -49,6 +50,11 @@ class ViewManager {
typedef std::map<TransportNodeId, ViewTreeNode*> IdToNodeMap;
typedef std::map<TransportViewId, View*> IdToViewMap;
+ ViewManager(Application* application,
+ const base::Callback<void(ViewManager*)> ready_callback);
+
+ base::Callback<void(ViewManager*)> ready_callback_;
+
ViewManagerSynchronizer* synchronizer_;
ViewTreeNode* tree_;