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

Side by Side Diff: services/python/content_handler/content_handler_main.cc

Issue 942013003: Python handler: Pass a python object to content handled application. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 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 unified diff | Download patch
« no previous file with comments | « mojo/public/python/src/common.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 <python2.7/Python.h> 5 #include <python2.7/Python.h>
6 #include <dlfcn.h> 6 #include <dlfcn.h>
7 7
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/files/scoped_temp_dir.h" 9 #include "base/files/scoped_temp_dir.h"
10 #include "base/i18n/icu_util.h" 10 #include "base/i18n/icu_util.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
12 #include "mojo/application/application_runner_chromium.h" 13 #include "mojo/application/application_runner_chromium.h"
13 #include "mojo/application/content_handler_factory.h" 14 #include "mojo/application/content_handler_factory.h"
14 #include "mojo/common/common_type_converters.h" 15 #include "mojo/common/common_type_converters.h"
15 #include "mojo/common/data_pipe_utils.h" 16 #include "mojo/common/data_pipe_utils.h"
16 #include "mojo/public/c/system/main.h" 17 #include "mojo/public/c/system/main.h"
17 #include "mojo/public/cpp/application/application_delegate.h" 18 #include "mojo/public/cpp/application/application_delegate.h"
18 #include "mojo/public/cpp/application/application_impl.h" 19 #include "mojo/public/cpp/application/application_impl.h"
19 #include "mojo/public/cpp/application/interface_factory_impl.h" 20 #include "mojo/public/cpp/application/interface_factory_impl.h"
20 #include "mojo/public/python/src/common.h" 21 #include "mojo/public/python/src/common.h"
21 #include "third_party/zlib/google/zip_reader.h" 22 #include "third_party/zlib/google/zip_reader.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 CHECK(reader.OpenFromString(input_data)); 79 CHECK(reader.OpenFromString(input_data));
79 base::FilePath temp_dir_path = temp_dir->path(); 80 base::FilePath temp_dir_path = temp_dir->path();
80 while (reader.HasMore()) { 81 while (reader.HasMore()) {
81 CHECK(reader.OpenCurrentEntryInZip()); 82 CHECK(reader.OpenCurrentEntryInZip());
82 CHECK(reader.ExtractCurrentEntryIntoDirectory(temp_dir_path)); 83 CHECK(reader.ExtractCurrentEntryIntoDirectory(temp_dir_path));
83 CHECK(reader.AdvanceToNextEntry()); 84 CHECK(reader.AdvanceToNextEntry());
84 } 85 }
85 return temp_dir; 86 return temp_dir;
86 } 87 }
87 88
88 bool RunPythonCommand(std::string command, PyObject* globals) { 89 ScopedPyRef RunString(std::string command, PyObject* globals, int mode) {
89 ScopedPyRef result( 90 ScopedPyRef result(PyRun_String(command.c_str(), mode, globals, nullptr));
90 PyRun_String(command.c_str(), Py_file_input, globals, NULL));
91 91
92 if (result == nullptr) { 92 if (!result) {
93 LOG(ERROR) << "Error while running command: '" << command << "'"; 93 LOG(ERROR) << "Error while running command: '" << command << "'";
94 PyErr_Print(); 94 PyErr_Print();
95 return false;
96 } 95 }
97 return true; 96 return result;
97 }
98
99 bool Exec(std::string command, PyObject* globals) {
100 return RunString(command, globals, Py_file_input);
101 }
102
103 ScopedPyRef Eval(std::string command, PyObject* globals) {
104 return RunString(command, globals, Py_eval_input);
98 } 105 }
99 106
100 // Sets up the Python interpreter and loads mojo system modules. This method 107 // Sets up the Python interpreter and loads mojo system modules. This method
101 // returns the global dictionary for the python environment that should be 108 // returns the global dictionary for the python environment that should be
102 // used for subsequent calls. Takes as input the path of the unpacked 109 // used for subsequent calls. Takes as input the path of the unpacked
103 // application files. 110 // application files.
104 PyObject* SetupPythonEnvironment(const std::string& application_path) { 111 PyObject* SetupPythonEnvironment(const std::string& application_path) {
105 // TODO(etiennej): Build python ourselves so we don't have to rely on 112 // TODO(etiennej): Build python ourselves so we don't have to rely on
106 // dynamically loading a system library. 113 // dynamically loading a system library.
107 dlopen("libpython2.7.so", RTLD_LAZY | RTLD_GLOBAL); 114 dlopen("libpython2.7.so", RTLD_LAZY | RTLD_GLOBAL);
108 115
109 PyImport_AppendInittab(kMojoSystemImpl, &initmojo_system_impl); 116 PyImport_AppendInittab(kMojoSystemImpl, &initmojo_system_impl);
110 PyImport_AppendInittab(kMojoSystem, &initmojo_system); 117 PyImport_AppendInittab(kMojoSystem, &initmojo_system);
111 118
112 Py_Initialize(); 119 Py_Initialize();
113 120
114 PyObject *m, *d; 121 PyObject *m, *d;
115 m = PyImport_AddModule("__main__"); 122 m = PyImport_AddModule("__main__");
116 if (m == NULL) 123 if (!m)
117 return NULL; 124 return nullptr;
118 d = PyModule_GetDict(m); 125 d = PyModule_GetDict(m);
119 126
120 // Enable debug information if requested. 127 // Enable debug information if requested.
121 if (debug_) { 128 if (debug_) {
122 std::string enable_logging = 129 std::string enable_logging =
123 "import logging;" 130 "import logging;"
124 "logging.basicConfig();" 131 "logging.basicConfig();"
125 "logging.getLogger().setLevel(logging.DEBUG)"; 132 "logging.getLogger().setLevel(logging.DEBUG)";
126 if (!RunPythonCommand(enable_logging, d)) 133 if (!Exec(enable_logging, d))
127 return NULL; 134 return nullptr;
128 } 135 }
129 136
130 // Inject the application path into the python search path so that imports 137 // Inject the application path into the python search path so that imports
131 // from the application work as expected. 138 // from the application work as expected.
132 std::string search_path_py_command = 139 std::string search_path_py_command =
133 "import sys; sys.path.append('" + application_path + "');"; 140 "import sys; sys.path.append('" + application_path + "');";
134 if (!RunPythonCommand(search_path_py_command, d)) 141 if (!Exec(search_path_py_command, d))
135 return NULL; 142 return nullptr;
136 143
137 return d; 144 return d;
138 } 145 }
139 146
140 // Overridden from ContentHandlerFactory::ManagedDelegate: 147 // Overridden from ContentHandlerFactory::ManagedDelegate:
141 void RunApplication(InterfaceRequest<Application> application_request, 148 void RunApplication(InterfaceRequest<Application> application_request,
142 URLResponsePtr response) override { 149 URLResponsePtr response) override {
143 std::unique_ptr<base::ScopedTempDir> temp_dir = 150 std::unique_ptr<base::ScopedTempDir> temp_dir =
144 ExtractApplication(response.Pass()); 151 ExtractApplication(response.Pass());
145 base::FilePath directory_path = temp_dir->path(); 152 base::FilePath directory_path = temp_dir->path();
146 153
147 PyObject* d = SetupPythonEnvironment(directory_path.value()); 154 PyObject* d = SetupPythonEnvironment(directory_path.value());
148 DCHECK(d); 155 DCHECK(d);
149 156
150 base::FilePath entry_path = directory_path.Append("__mojo__.py"); 157 base::FilePath entry_path = directory_path.Append("__mojo__.py");
151 158
152 FILE* entry_file = base::OpenFile(entry_path, "r"); 159 FILE* entry_file = base::OpenFile(entry_path, "r");
153 DCHECK(entry_file); 160 DCHECK(entry_file);
154 161
155 // Ensure that all created objects are destroyed before calling Py_Finalize. 162 // Ensure that all created objects are destroyed before calling Py_Finalize.
156 { 163 {
157 // Load the __mojo__.py file into the interpreter. MojoMain hasn't run 164 // Load the __mojo__.py file into the interpreter. MojoMain hasn't run
158 // yet. 165 // yet.
159 ScopedPyRef result(PyRun_File(entry_file, entry_path.value().c_str(), 166 ScopedPyRef result(PyRun_File(entry_file, entry_path.value().c_str(),
160 Py_file_input, d, d)); 167 Py_file_input, d, d));
161 if (result == nullptr) { 168 if (!result) {
162 LOG(ERROR) << "Error while loading script"; 169 LOG(ERROR) << "Error while loading script";
163 PyErr_Print(); 170 PyErr_Print();
164 return; 171 return;
165 } 172 }
166 173
167 // Find MojoMain. 174 // Find MojoMain.
168 ScopedPyRef py_function(PyMapping_GetItemString(d, kMojoMain)); 175 ScopedPyRef py_function(PyMapping_GetItemString(d, kMojoMain));
169 176
170 if (py_function == NULL) { 177 if (!py_function) {
171 LOG(ERROR) << "Locals size: " << PyMapping_Size(d); 178 LOG(ERROR) << "Locals size: " << PyMapping_Size(d);
172 LOG(ERROR) << "MojoMain not found"; 179 LOG(ERROR) << "MojoMain not found";
173 PyErr_Print(); 180 PyErr_Print();
174 return; 181 return;
175 } 182 }
176 183
177 if (PyCallable_Check(py_function)) { 184 if (PyCallable_Check(py_function)) {
178 MojoHandle application_request_handle = 185 MojoHandle application_request_handle =
179 application_request.PassMessagePipe().release().value(); 186 application_request.PassMessagePipe().release().value();
180 ScopedPyRef py_input(PyInt_FromLong(application_request_handle)); 187 std::string handle_command = base::StringPrintf(
188 "mojo_system.Handle(%u)", application_request_handle);
189 ScopedPyRef py_input = Eval(handle_command, d);
etiennej 2015/02/24 09:20:54 Why can't you use ScopedPyRef py_input(Eval(handle
qsr 2015/02/24 13:25:16 I can. Done.
190 if (!py_input) {
191 MojoClose(application_request_handle);
192 return;
193 }
181 ScopedPyRef py_arguments(PyTuple_New(1)); 194 ScopedPyRef py_arguments(PyTuple_New(1));
182 // py_input reference is stolen by py_arguments 195 // py_input reference is stolen by py_arguments
183 PyTuple_SetItem(py_arguments, 0, py_input.Release()); 196 PyTuple_SetItem(py_arguments, 0, py_input.Release());
184 // Run MojoMain with application_request_handle as the first and only 197 // Run MojoMain with application_request_handle as the first and only
185 // argument. 198 // argument.
186 ScopedPyRef py_output(PyObject_CallObject(py_function, py_arguments)); 199 ScopedPyRef py_output(PyObject_CallObject(py_function, py_arguments));
187 200
188 if (!py_output) { 201 if (!py_output) {
189 LOG(ERROR) << "Error while executing MojoMain"; 202 LOG(ERROR) << "Error while executing MojoMain";
190 PyErr_Print(); 203 PyErr_Print();
(...skipping 21 matching lines...) Expand all
212 225
213 } // namespace content_handler 226 } // namespace content_handler
214 } // namespace python 227 } // namespace python
215 } // namespace services 228 } // namespace services
216 229
217 MojoResult MojoMain(MojoHandle shell_handle) { 230 MojoResult MojoMain(MojoHandle shell_handle) {
218 mojo::ApplicationRunnerChromium runner( 231 mojo::ApplicationRunnerChromium runner(
219 new services::python::content_handler::PythonContentHandler()); 232 new services::python::content_handler::PythonContentHandler());
220 return runner.Run(shell_handle); 233 return runner.Run(shell_handle);
221 } 234 }
OLDNEW
« no previous file with comments | « mojo/public/python/src/common.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698