Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / mojo / shell / dynamic_service_loader.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/shell/dynamic_service_loader.h"
6
7 #include "base/command_line.h"
8 #include "base/location.h"
9 #include "mojo/shell/context.h"
10 #include "mojo/shell/keep_alive.h"
11 #include "mojo/shell/switches.h"
12
13 namespace mojo {
14 namespace shell {
15
16 namespace {
17
18 std::string MakeSharedLibraryName(const std::string& file_name) {
19 #if defined(OS_WIN)
20   return file_name + ".dll";
21 #elif defined(OS_LINUX)
22   return "lib" + file_name + ".so";
23 #elif defined(OS_MACOSX)
24   return "lib" + file_name + ".dylib";
25 #else
26   NOTREACHED() << "dynamic loading of services not supported";
27   return std::string();
28 #endif
29 }
30
31 }  // namespace
32
33 class DynamicServiceLoader::LoadContext : public mojo::shell::Loader::Delegate {
34  public:
35   LoadContext(DynamicServiceLoader* loader,
36               const GURL& url,
37               ScopedMessagePipeHandle service_handle,
38               scoped_ptr<DynamicServiceRunner> runner)
39       : loader_(loader),
40         url_(url),
41         service_handle_(service_handle.Pass()),
42         runner_(runner.Pass()),
43         keep_alive_(loader->context_) {
44     GURL url_to_load;
45
46     if (url.SchemeIs("mojo")) {
47       std::string origin =
48           CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
49               switches::kOrigin);
50       std::string lib = MakeSharedLibraryName(url.ExtractFileName());
51       url_to_load = GURL(origin + "/" + lib);
52     } else {
53       url_to_load = url;
54     }
55
56     request_ = loader_->context_->loader()->Load(url_to_load, this);
57   }
58
59   virtual ~LoadContext() {
60   }
61
62  private:
63   // |Loader::Delegate| method:
64   virtual void DidCompleteLoad(const GURL& app_url,
65                                const base::FilePath& app_path,
66                                const std::string* mime_type) OVERRIDE {
67     DVLOG(2) << "Completed load of " << app_url << " (" << url_ << ") to "
68              << app_path.value();
69     DCHECK(loader_->context_->task_runners()->ui_runner()->
70                BelongsToCurrentThread());
71
72     runner_->Start(
73         app_path,
74         service_handle_.Pass(),
75         base::Bind(&DynamicServiceLoader::AppCompleted,
76                    base::Unretained(loader_), url_));
77   }
78
79   DynamicServiceLoader* const loader_;
80   const GURL url_;
81   scoped_ptr<mojo::shell::Loader::Job> request_;
82   ScopedMessagePipeHandle service_handle_;
83   scoped_ptr<DynamicServiceRunner> runner_;
84   KeepAlive keep_alive_;
85
86   DISALLOW_COPY_AND_ASSIGN(LoadContext);
87 };
88
89 DynamicServiceLoader::DynamicServiceLoader(
90     Context* context,
91     scoped_ptr<DynamicServiceRunnerFactory> runner_factory)
92     : context_(context),
93       runner_factory_(runner_factory.Pass()) {
94 }
95
96 DynamicServiceLoader::~DynamicServiceLoader() {
97   DCHECK(url_to_load_context_.empty());
98 }
99
100 void DynamicServiceLoader::LoadService(ServiceManager* manager,
101                                        const GURL& url,
102                                        ScopedMessagePipeHandle service_handle) {
103   DCHECK(url_to_load_context_.find(url) == url_to_load_context_.end());
104   url_to_load_context_[url] = new LoadContext(
105       this, url, service_handle.Pass(), runner_factory_->Create(context_));
106 }
107
108 void DynamicServiceLoader::OnServiceError(ServiceManager* manager,
109                                           const GURL& url) {
110 }
111
112 void DynamicServiceLoader::AppCompleted(const GURL& url) {
113   DCHECK(context_->task_runners()->ui_runner()->BelongsToCurrentThread());
114   DVLOG(2) << "App completed (url: " << url << ")";
115
116   LoadContextMap::iterator it = url_to_load_context_.find(url);
117   DCHECK(it != url_to_load_context_.end()) << url;
118
119   LoadContext* doomed = it->second;
120   url_to_load_context_.erase(it);
121
122   delete doomed;
123 }
124
125 }  // namespace shell
126 }  // namespace mojo