3dedd9633d187dbbe333441befa0ef931e083786
[platform/framework/web/crosswalk.git] / src / xwalk / application / extension / application_widget_extension.cc
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.
4
5 #include "xwalk/application/extension/application_widget_extension.h"
6
7 #include "base/bind.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"
26
27 using content::BrowserThread;
28
29 namespace {
30 const char kCommandKey[] = "cmd";
31 const char kWidgetAttributeKey[] = "widgetKey";
32 const char kPreferencesItemKey[] = "preferencesItemKey";
33 const char kPreferencesItemValue[] = "preferencesItemValue";
34 }
35
36 namespace xwalk {
37 namespace application {
38
39 namespace widget_keys = xwalk::application_widget_keys;
40
41 ApplicationWidgetExtension::ApplicationWidgetExtension(
42     Application* application)
43   : application_(application) {
44   set_name("widget");
45   set_javascript_api(ResourceBundle::GetSharedInstance().GetRawDataResource(
46       IDR_XWALK_APPLICATION_WIDGET_API).as_string());
47 }
48
49 XWalkExtensionInstance* ApplicationWidgetExtension::CreateInstance() {
50   return new AppWidgetExtensionInstance(application_);
51 }
52
53 AppWidgetExtensionInstance::AppWidgetExtensionInstance(
54     Application* application)
55   : application_(application),
56     handler_(this) {
57   DCHECK(application_);
58   base::ThreadRestrictions::SetIOAllowed(true);
59
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));
66 }
67
68 AppWidgetExtensionInstance::~AppWidgetExtensionInstance() {}
69
70 void AppWidgetExtensionInstance::HandleMessage(scoped_ptr<base::Value> msg) {
71   handler_.HandleMessage(msg.Pass());
72 }
73
74 void AppWidgetExtensionInstance::HandleSyncMessage(
75     scoped_ptr<base::Value> msg) {
76   base::DictionaryValue* dict;
77   std::string command;
78   msg->GetAsDictionary(&dict);
79
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("")));
83     return;
84   }
85
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());
99   } else {
100     LOG(ERROR) << command << " ASSERT NOT REACHED.";
101   }
102
103   SendSyncReplyToJS(result.Pass());
104 }
105
106 scoped_ptr<base::StringValue> AppWidgetExtensionInstance::GetWidgetInfo(
107     scoped_ptr<base::Value> msg) {
108   scoped_ptr<base::StringValue> result(new base::StringValue(""));
109   std::string key;
110   std::string value;
111   base::DictionaryValue* dict;
112
113   if (!msg->GetAsDictionary(&dict) ||
114       !dict->GetString(kWidgetAttributeKey, &key)) {
115     LOG(ERROR) << "Fail to get widget attribute key.";
116     return result.Pass();
117   }
118
119   WidgetInfo* info =
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();
126 }
127
128 scoped_ptr<base::FundamentalValue>
129 AppWidgetExtensionInstance::SetPreferencesItem(scoped_ptr<base::Value> msg) {
130   scoped_ptr<base::FundamentalValue> result(
131       new base::FundamentalValue(false));
132   std::string key;
133   std::string value;
134   base::DictionaryValue* dict;
135
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();
141   }
142
143   if (widget_storage_->AddEntry(key, value, false))
144     result.reset(new base::FundamentalValue(true));
145
146   return result.Pass();
147 }
148
149 scoped_ptr<base::FundamentalValue>
150 AppWidgetExtensionInstance::RemovePreferencesItem(scoped_ptr<base::Value> msg) {
151   scoped_ptr<base::FundamentalValue> result(
152       new base::FundamentalValue(false));
153   std::string key;
154   base::DictionaryValue* dict;
155
156   if (!msg->GetAsDictionary(&dict) ||
157       !dict->GetString(kPreferencesItemKey, &key)) {
158     LOG(ERROR) << "Fail to remove preferences item.";
159     return result.Pass();
160   }
161
162   if (widget_storage_->RemoveEntry(key))
163     result.reset(new base::FundamentalValue(true));
164
165   return result.Pass();
166 }
167
168 scoped_ptr<base::FundamentalValue> AppWidgetExtensionInstance::ClearAllItems(
169     scoped_ptr<base::Value> msg) {
170   scoped_ptr<base::FundamentalValue> result(
171       new base::FundamentalValue(false));
172
173   if (widget_storage_->Clear())
174     result.reset(new base::FundamentalValue(true));
175
176   return result.Pass();
177 }
178
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());
183
184   return result.Pass();
185 }
186
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));
191   std::string key;
192   base::DictionaryValue* dict;
193
194   if (!msg->GetAsDictionary(&dict) ||
195       !dict->GetString(kPreferencesItemKey, &key)) {
196     LOG(ERROR) << "Fail to remove preferences item.";
197     return result.Pass();
198   }
199
200   if (widget_storage_->EntryExists(key))
201     result.reset(new base::FundamentalValue(true));
202
203   return result.Pass();
204 }
205
206 }  // namespace application
207 }  // namespace xwalk