1 // Copyright (c) 2014 Intel Corporation. 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.
5 #include "xwalk/application/extension/application_widget_extension.h"
8 #include "base/path_service.h"
9 #include "base/strings/string_util.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "content/public/browser/storage_partition.h"
13 #include "content/public/browser/web_contents.h"
14 #include "ipc/ipc_message.h"
15 #include "grit/xwalk_application_resources.h"
16 #include "ui/base/resource/resource_bundle.h"
17 #include "xwalk/application/browser/application.h"
18 #include "xwalk/application/common/application_data.h"
19 #include "xwalk/application/common/application_manifest_constants.h"
20 #include "xwalk/application/common/manifest_handlers/widget_handler.h"
21 #include "xwalk/application/extension/application_widget_storage.h"
22 #include "xwalk/runtime/browser/runtime.h"
23 #include "xwalk/runtime/browser/runtime_context.h"
24 #include "xwalk/runtime/browser/xwalk_runner.h"
25 #include "xwalk/runtime/common/xwalk_paths.h"
27 using content::BrowserThread;
30 const char kCommandKey[] = "cmd";
31 const char kWidgetAttributeKey[] = "widgetKey";
32 const char kPreferencesItemKey[] = "preferencesItemKey";
33 const char kPreferencesItemValue[] = "preferencesItemValue";
37 namespace application {
39 namespace widget_keys = xwalk::application_widget_keys;
41 ApplicationWidgetExtension::ApplicationWidgetExtension(
42 Application* application)
43 : application_(application) {
45 set_javascript_api(ResourceBundle::GetSharedInstance().GetRawDataResource(
46 IDR_XWALK_APPLICATION_WIDGET_API).as_string());
49 XWalkExtensionInstance* ApplicationWidgetExtension::CreateInstance() {
50 return new AppWidgetExtensionInstance(application_);
53 AppWidgetExtensionInstance::AppWidgetExtensionInstance(
54 Application* application)
55 : application_(application),
58 base::ThreadRestrictions::SetIOAllowed(true);
60 content::RenderProcessHost* rph =
61 content::RenderProcessHost::FromID(application->GetRenderProcessHostID());
62 content::StoragePartition* partition = rph->GetStoragePartition();
63 base::FilePath path = partition->GetPath().Append(
64 FILE_PATH_LITERAL("WidgetStorage"));
65 widget_storage_.reset(new AppWidgetStorage(application_, path));
68 AppWidgetExtensionInstance::~AppWidgetExtensionInstance() {}
70 void AppWidgetExtensionInstance::HandleMessage(scoped_ptr<base::Value> msg) {
71 handler_.HandleMessage(msg.Pass());
74 void AppWidgetExtensionInstance::HandleSyncMessage(
75 scoped_ptr<base::Value> msg) {
76 base::DictionaryValue* dict;
78 msg->GetAsDictionary(&dict);
80 if (!msg->GetAsDictionary(&dict) || !dict->GetString(kCommandKey, &command)) {
81 LOG(ERROR) << "Fail to handle command sync message.";
82 SendSyncReplyToJS(scoped_ptr<base::Value>(new base::StringValue("")));
86 scoped_ptr<base::Value> result(new base::StringValue(""));
87 if (command == "GetWidgetInfo") {
88 result = GetWidgetInfo(msg.Pass());
89 } else if (command == "SetPreferencesItem") {
90 result = SetPreferencesItem(msg.Pass());
91 } else if (command == "RemovePreferencesItem") {
92 result = RemovePreferencesItem(msg.Pass());
93 } else if (command == "ClearAllItems") {
94 result = ClearAllItems(msg.Pass());
95 } else if (command == "GetAllItems") {
96 result = GetAllItems(msg.Pass());
97 } else if (command == "KeyExists") {
98 result = KeyExists(msg.Pass());
100 LOG(ERROR) << command << " ASSERT NOT REACHED.";
103 SendSyncReplyToJS(result.Pass());
106 scoped_ptr<base::StringValue> AppWidgetExtensionInstance::GetWidgetInfo(
107 scoped_ptr<base::Value> msg) {
108 scoped_ptr<base::StringValue> result(new base::StringValue(""));
111 base::DictionaryValue* dict;
113 if (!msg->GetAsDictionary(&dict) ||
114 !dict->GetString(kWidgetAttributeKey, &key)) {
115 LOG(ERROR) << "Fail to get widget attribute key.";
116 return result.Pass();
120 static_cast<WidgetInfo*>(
121 application_->data()->GetManifestData(widget_keys::kWidgetKey));
122 base::DictionaryValue* widget_info = info->GetWidgetInfo();
123 widget_info->GetString(key, &value);
124 result.reset(new base::StringValue(value));
125 return result.Pass();
128 scoped_ptr<base::FundamentalValue>
129 AppWidgetExtensionInstance::SetPreferencesItem(scoped_ptr<base::Value> msg) {
130 scoped_ptr<base::FundamentalValue> result(
131 new base::FundamentalValue(false));
134 base::DictionaryValue* dict;
136 if (!msg->GetAsDictionary(&dict) ||
137 !dict->GetString(kPreferencesItemKey, &key) ||
138 !dict->GetString(kPreferencesItemValue, &value)) {
139 LOG(ERROR) << "Fail to set preferences item.";
140 return result.Pass();
143 if (widget_storage_->AddEntry(key, value, false))
144 result.reset(new base::FundamentalValue(true));
146 return result.Pass();
149 scoped_ptr<base::FundamentalValue>
150 AppWidgetExtensionInstance::RemovePreferencesItem(scoped_ptr<base::Value> msg) {
151 scoped_ptr<base::FundamentalValue> result(
152 new base::FundamentalValue(false));
154 base::DictionaryValue* dict;
156 if (!msg->GetAsDictionary(&dict) ||
157 !dict->GetString(kPreferencesItemKey, &key)) {
158 LOG(ERROR) << "Fail to remove preferences item.";
159 return result.Pass();
162 if (widget_storage_->RemoveEntry(key))
163 result.reset(new base::FundamentalValue(true));
165 return result.Pass();
168 scoped_ptr<base::FundamentalValue> AppWidgetExtensionInstance::ClearAllItems(
169 scoped_ptr<base::Value> msg) {
170 scoped_ptr<base::FundamentalValue> result(
171 new base::FundamentalValue(false));
173 if (widget_storage_->Clear())
174 result.reset(new base::FundamentalValue(true));
176 return result.Pass();
179 scoped_ptr<base::DictionaryValue> AppWidgetExtensionInstance::GetAllItems(
180 scoped_ptr<base::Value> msg) {
181 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
182 widget_storage_->GetAllEntries(result.get());
184 return result.Pass();
187 scoped_ptr<base::FundamentalValue> AppWidgetExtensionInstance::KeyExists(
188 scoped_ptr<base::Value> msg) const {
189 scoped_ptr<base::FundamentalValue> result(
190 new base::FundamentalValue(false));
192 base::DictionaryValue* dict;
194 if (!msg->GetAsDictionary(&dict) ||
195 !dict->GetString(kPreferencesItemKey, &key)) {
196 LOG(ERROR) << "Fail to remove preferences item.";
197 return result.Pass();
200 if (widget_storage_->EntryExists(key))
201 result.reset(new base::FundamentalValue(true));
203 return result.Pass();
206 } // namespace application