[Author: zork]
[google-gears.git] / gears / localserver / npapi / managed_resource_store_np.cc
blob2d16a33e079b5fd9caad18df684bffa77d5e7dac
1 // Copyright 2005, Google Inc.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
5 //
6 // 1. Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright notice,
9 // this list of conditions and the following disclaimer in the documentation
10 // and/or other materials provided with the distribution.
11 // 3. Neither the name of Google Inc. nor the names of its contributors may be
12 // used to endorse or promote products derived from this software without
13 // specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "gears/localserver/npapi/managed_resource_store_np.h"
28 #include "gears/base/common/module_wrapper.h"
29 #include "gears/base/common/url_utils.h"
30 #include "gears/localserver/common/update_task.h"
32 DECLARE_GEARS_WRAPPER(GearsManagedResourceStore);
34 // static
35 template<>
36 void Dispatcher<GearsManagedResourceStore>::Init() {
37 RegisterProperty("name", &GearsManagedResourceStore::GetName, NULL);
38 RegisterProperty("requiredCookie",
39 &GearsManagedResourceStore::GetRequiredCookie, NULL);
40 RegisterProperty("enabled", &GearsManagedResourceStore::GetEnabled,
41 &GearsManagedResourceStore::SetEnabled);
42 RegisterProperty("manifestUrl", &GearsManagedResourceStore::GetManifestUrl,
43 &GearsManagedResourceStore::SetManifestUrl);
44 RegisterProperty("lastUpdateCheckTime",
45 &GearsManagedResourceStore::GetLastUpdateCheckTime, NULL);
46 RegisterProperty("updateStatus",
47 &GearsManagedResourceStore::GetUpdateStatus, NULL);
48 RegisterProperty("lastErrorMessage",
49 &GearsManagedResourceStore::GetLastErrorMessage, NULL);
50 RegisterProperty("currentVersion",
51 &GearsManagedResourceStore::GetCurrentVersion, NULL);
52 RegisterProperty("onerror", &GearsManagedResourceStore::GetOnerror,
53 &GearsManagedResourceStore::SetOnerror);
54 RegisterProperty("onprogress", &GearsManagedResourceStore::GetOnprogress,
55 &GearsManagedResourceStore::SetOnprogress);
56 RegisterProperty("oncomplete", &GearsManagedResourceStore::GetOncomplete,
57 &GearsManagedResourceStore::SetOncomplete);
58 RegisterMethod("checkForUpdate",
59 &GearsManagedResourceStore::CheckForUpdate);
62 GearsManagedResourceStore::~GearsManagedResourceStore() {
63 MessageService::GetInstance()->RemoveObserver(this,
64 observer_topic_.c_str());
67 //------------------------------------------------------------------------------
68 // GetName
69 //------------------------------------------------------------------------------
70 void GearsManagedResourceStore::GetName(JsCallContext *context) {
71 std::string16 name(store_.GetName());
72 context->SetReturnValue(JSPARAM_STRING16, &name);
75 //------------------------------------------------------------------------------
76 // GetRequiredCookie
77 //------------------------------------------------------------------------------
78 void GearsManagedResourceStore::GetRequiredCookie(JsCallContext *context) {
79 std::string16 cookie(store_.GetRequiredCookie());
80 context->SetReturnValue(JSPARAM_STRING16, &cookie);
83 //------------------------------------------------------------------------------
84 // GetEnabled
85 //------------------------------------------------------------------------------
86 void GearsManagedResourceStore::GetEnabled(JsCallContext *context) {
87 bool enabled = store_.IsEnabled();
88 context->SetReturnValue(JSPARAM_BOOL, &enabled);
91 //------------------------------------------------------------------------------
92 // SetEnabled
93 //------------------------------------------------------------------------------
94 void GearsManagedResourceStore::SetEnabled(JsCallContext *context) {
95 bool enabled;
96 JsArgument argv[] = {
97 { JSPARAM_REQUIRED, JSPARAM_BOOL, &enabled },
99 context->GetArguments(ARRAYSIZE(argv), argv);
100 if (context->is_exception_set())
101 return;
103 if (!store_.SetEnabled(enabled)) {
104 context->SetException(STRING16(L"Failed to set the enabled property."));
105 return;
109 //------------------------------------------------------------------------------
110 // GetManifestUrl
111 //------------------------------------------------------------------------------
112 void GearsManagedResourceStore::GetManifestUrl(JsCallContext *context) {
113 std::string16 manifest_url;
114 if (store_.GetManifestUrl(&manifest_url)) {
115 context->SetReturnValue(JSPARAM_STRING16, &manifest_url);
116 } else {
117 context->SetException(STRING16(L"Failed to get manifest url."));
121 //------------------------------------------------------------------------------
122 // SetManifestUrl
123 //------------------------------------------------------------------------------
124 void GearsManagedResourceStore::SetManifestUrl(JsCallContext *context) {
125 std::string16 url;
126 JsArgument argv[] = {
127 { JSPARAM_REQUIRED, JSPARAM_STRING16, &url },
129 context->GetArguments(ARRAYSIZE(argv), argv);
130 if (context->is_exception_set())
131 return;
133 std::string16 full_url;
134 if (!ResolveAndNormalize(EnvPageLocationUrl().c_str(), url.c_str(),
135 &full_url)) {
136 context->SetException(STRING16(L"Failed to resolve url."));
137 return;
140 if (!EnvPageSecurityOrigin().IsSameOriginAsUrl(full_url.c_str())) {
141 context->SetException(STRING16(L"Url is not from the same origin"));
142 return;
145 if (!store_.SetManifestUrl(full_url.c_str())) {
146 context->SetException(STRING16(L"Failed to set manifest url."));
147 return;
151 //------------------------------------------------------------------------------
152 // GetLastUpdateCheckTime
153 //------------------------------------------------------------------------------
154 void GearsManagedResourceStore::GetLastUpdateCheckTime(JsCallContext *context) {
155 WebCacheDB::UpdateStatus status;
156 int64 time64 = 0;
157 if (store_.GetUpdateInfo(&status, &time64, NULL, NULL)) {
158 int time = static_cast<int>(time64 / 1000); // convert to seconds
159 context->SetReturnValue(JSPARAM_INT, &time);
160 } else {
161 context->SetException(STRING16(L"Failed to get update info."));
162 return;
166 //------------------------------------------------------------------------------
167 // GetUpdateStatus
168 //------------------------------------------------------------------------------
169 void GearsManagedResourceStore::GetUpdateStatus(JsCallContext *context) {
170 WebCacheDB::UpdateStatus status = WebCacheDB::UPDATE_OK;
171 int64 time64 = 0;
172 if (store_.GetUpdateInfo(&status, &time64, NULL, NULL)) {
173 context->SetReturnValue(JSPARAM_INT, &status);
174 } else {
175 context->SetException(STRING16(L"Failed to get update info."));
176 return;
180 //------------------------------------------------------------------------------
181 // GetLastErrorMessage
182 //------------------------------------------------------------------------------
183 void GearsManagedResourceStore::GetLastErrorMessage(JsCallContext *context) {
184 WebCacheDB::UpdateStatus status;
185 int64 time64 = 0;
186 std::string16 error_message;
187 if (store_.GetUpdateInfo(&status, &time64, NULL, &error_message)) {
188 context->SetReturnValue(JSPARAM_STRING16, &error_message);
189 } else {
190 context->SetException(STRING16(L"Failed to get last error message."));
191 return;
195 //------------------------------------------------------------------------------
196 // CheckForUpdate
197 //------------------------------------------------------------------------------
198 void GearsManagedResourceStore::CheckForUpdate(JsCallContext *context) {
199 scoped_ptr<UpdateTask> update_task(UpdateTask::CreateUpdateTask());
200 if (!update_task->Init(&store_)) {
201 context->SetException(STRING16(L"Failed to initialize update task."));
202 return;
205 if (!update_task->Start()) {
206 context->SetException(STRING16(L"Failed to start update task."));
207 return;
210 // We wait here so the updateStatus property reflects a running task
211 // upon return
212 update_task->AwaitStartup();
214 update_task.release()->DeleteWhenDone();
217 //------------------------------------------------------------------------------
218 // GetCurrentVersion
219 //------------------------------------------------------------------------------
220 void GearsManagedResourceStore::GetCurrentVersion(JsCallContext *context) {
221 std::string16 version;
222 store_.GetVersionString(WebCacheDB::VERSION_CURRENT, &version);
223 context->SetReturnValue(JSPARAM_STRING16, &version);
226 //------------------------------------------------------------------------------
227 // GetOnerror
228 //------------------------------------------------------------------------------
229 void GearsManagedResourceStore::GetOnerror(JsCallContext *context) {
230 context->SetException(STRING16(L"This property is write only."));
233 //------------------------------------------------------------------------------
234 // SetOnerror
235 //------------------------------------------------------------------------------
236 void GearsManagedResourceStore::SetOnerror(JsCallContext *context) {
237 SetEventHandler(context, &onerror_handler_);
240 //------------------------------------------------------------------------------
241 // GetOnprogress
242 //------------------------------------------------------------------------------
243 void GearsManagedResourceStore::GetOnprogress(JsCallContext *context) {
244 context->SetException(STRING16(L"This property is write only."));
247 //------------------------------------------------------------------------------
248 // SetOnprogress
249 //------------------------------------------------------------------------------
250 void GearsManagedResourceStore::SetOnprogress(JsCallContext *context) {
251 SetEventHandler(context, &onprogress_handler_);
254 //------------------------------------------------------------------------------
255 // GetOncomplete
256 //------------------------------------------------------------------------------
257 void GearsManagedResourceStore::GetOncomplete(JsCallContext *context) {
258 context->SetException(STRING16(L"This property is write only."));
261 //------------------------------------------------------------------------------
262 // SetOncomplete
263 //------------------------------------------------------------------------------
264 void GearsManagedResourceStore::SetOncomplete(JsCallContext *context) {
265 SetEventHandler(context, &oncomplete_handler_);
268 //------------------------------------------------------------------------------
269 // SetEventHandler
270 //------------------------------------------------------------------------------
271 void GearsManagedResourceStore::SetEventHandler(
272 JsCallContext *context, scoped_ptr<JsRootedCallback> *handler) {
273 JsRootedCallback *function = NULL;
274 JsArgument argv[] = {
275 { JSPARAM_REQUIRED, JSPARAM_FUNCTION, &function },
277 context->GetArguments(ARRAYSIZE(argv), argv);
278 scoped_ptr<JsRootedCallback> scoped_function(function);
279 if (context->is_exception_set())
280 return;
282 // Create an event monitor to alert us when the page unloads.
283 if (unload_monitor_ == NULL) {
284 unload_monitor_.reset(new JsEventMonitor(GetJsRunner(), JSEVENT_UNLOAD,
285 this));
287 // Add the callbacks to handle deserializing messages.
288 UpdateTask::RegisterEventClasses();
291 handler->reset(scoped_function.release());
292 if (function) {
293 observer_topic_ = UpdateTask::GetNotificationTopic(&store_);
294 MessageService::GetInstance()->AddObserver(this, observer_topic_.c_str());
298 //------------------------------------------------------------------------------
299 // HandleEvent
300 //------------------------------------------------------------------------------
301 void GearsManagedResourceStore::HandleEvent(JsEventType event_type) {
302 assert(event_type == JSEVENT_UNLOAD);
304 // Drop references, js context is going away.
305 onerror_handler_.reset();
306 onprogress_handler_.reset();
307 oncomplete_handler_.reset();
308 MessageService::GetInstance()->RemoveObserver(this,
309 observer_topic_.c_str());
312 //------------------------------------------------------------------------------
313 // OnNotify
314 //------------------------------------------------------------------------------
315 void GearsManagedResourceStore::OnNotify(MessageService *service,
316 const char16 *topic,
317 const NotificationData *data) {
318 scoped_ptr<JsObject> param;
319 JsRootedCallback *handler = 0;
321 const UpdateTask::Event *event = static_cast<const UpdateTask::Event *>(data);
322 switch(event->event_type()) {
323 case UpdateTask::ERROR_EVENT: {
324 if (!onerror_handler_.get()) return;
325 handler = onerror_handler_.get();
327 param.reset(GetJsRunner()->NewObject(STRING16(L"Error")));
328 if (!param.get()) return;
330 const UpdateTask::ErrorEvent *error_event =
331 static_cast<const UpdateTask::ErrorEvent *>(data);
332 param->SetPropertyString(STRING16(L"message"),
333 error_event->error_message());
335 break;
337 case UpdateTask::PROGRESS_EVENT: {
338 if (!onprogress_handler_.get()) return;
339 handler = onprogress_handler_.get();
341 param.reset(GetJsRunner()->NewObject(NULL));
342 if (!param.get()) return;
344 const UpdateTask::ProgressEvent *progress_event =
345 static_cast<const UpdateTask::ProgressEvent *>(data);
346 param->SetPropertyInt(STRING16(L"filesTotal"),
347 progress_event->files_total());
348 param->SetPropertyInt(STRING16(L"filesComplete"),
349 progress_event->files_complete());
351 break;
353 case UpdateTask::COMPLETION_EVENT: {
354 if (!oncomplete_handler_.get()) return;
355 handler = oncomplete_handler_.get();
357 param.reset(GetJsRunner()->NewObject(NULL));
358 if (!param.get()) return;
360 const UpdateTask::CompletionEvent *completion_event =
361 static_cast<const UpdateTask::CompletionEvent *>(data);
362 param->SetPropertyString(STRING16(L"newVersion"),
363 completion_event->new_version_string());
365 break;
367 default:
368 return;
371 const int argc = 1;
372 JsParamToSend argv[argc] = {
373 { JSPARAM_OBJECT, param.get() }
375 GetJsRunner()->InvokeCallback(handler, argc, argv, NULL);