2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "common/app_control.h"
20 #include <app_control_internal.h>
21 #include <bundle_internal.h>
26 #include <regex> // NOLINT
30 #include "common/file_utils.h"
31 #include "common/logger.h"
32 #include "common/string_utils.h"
37 static bool BundleAddData(bundle* target, const std::string& key,
38 const std::string& value) {
39 int result = appsvc_add_data(target, key.c_str(), value.c_str());
41 LOGGER(ERROR) << "Failed to add data to appsvc.";
48 static bool BundleAddDataArray(bundle* target, const std::string& key,
49 const std::vector<std::string>& value_array) {
50 int n = value_array.size();
51 std::vector<const char*> v;
52 std::for_each(value_array.begin(), value_array.end(),
53 [&v] (const std::string& str) {
54 v.push_back(static_cast<const char*>(str.c_str()));
57 int result = appsvc_add_data_array(target, key.c_str(),
60 LOGGER(ERROR) << "Failed to add an array of data to appsvc.";
67 static const std::string GetOperationFromScheme(const std::string& scheme) {
68 static std::map<const std::string, const std::string> table = {
69 {"sms", APP_CONTROL_OPERATION_COMPOSE},
70 {"mmsto", APP_CONTROL_OPERATION_COMPOSE},
71 {"mailto", APP_CONTROL_OPERATION_COMPOSE},
72 {"tel", APP_CONTROL_OPERATION_CALL}
74 auto found = table.find(scheme);
75 if (found == table.end()) {
77 return APP_CONTROL_OPERATION_VIEW;
82 static void AppendExtraDatafromUrl(AppControl* request,
83 const std::string& url) {
84 static std::vector<std::pair<std::string, std::string> > patterns = {
85 {".*[?&]body=([^&]+).*", APP_CONTROL_DATA_TEXT},
86 {".*[?&]cc=([^&]+).*", APP_CONTROL_DATA_CC},
87 {".*[?&]bcc=([^&]+).*", APP_CONTROL_DATA_BCC},
88 {".*[?&]subject=([^&]+).*", APP_CONTROL_DATA_SUBJECT},
89 {".*[?&]to=([^&]+).*", APP_CONTROL_DATA_TO},
90 {"sms:([^?&]+).*", APP_CONTROL_DATA_TO},
91 {"mmsto:([^?&]+).*", APP_CONTROL_DATA_TO},
92 {"mailto:([^?&]+).*", APP_CONTROL_DATA_TO}
95 for (auto& param : patterns) {
96 std::regex pattern(param.first, std::regex_constants::icase);
98 if (std::regex_match(url, result, pattern) && result.size() >= 2) {
99 std::string extra_data = result[1].str();
102 utils::UrlDecode(extra_data));
110 AppControl::AppControl(app_control_h app_control)
111 : app_control_bundle_(nullptr),
113 app_control_clone(&app_control_, app_control);
114 app_control_to_bundle(app_control_, &app_control_bundle_);
117 AppControl:: AppControl()
118 : app_control_bundle_(nullptr),
120 app_control_create(&app_control_);
121 app_control_to_bundle(app_control_, &app_control_bundle_);
124 AppControl::~AppControl() {
125 if (app_control_ != NULL) {
126 app_control_destroy(app_control_);
130 std::string AppControl::operation() const {
131 const char* operation = appsvc_get_operation(app_control_bundle_);
133 if (operation != NULL) {
134 return std::string(operation);
136 return std::string();
140 void AppControl::set_operation(const std::string& operation) {
141 appsvc_set_operation(app_control_bundle_, operation.c_str());
144 std::string AppControl::mime() const {
145 const char* mime = appsvc_get_mime(app_control_bundle_);
148 return std::string(mime);
150 return std::string();
154 void AppControl::set_mime(const std::string& mime) {
155 appsvc_set_mime(app_control_bundle_, mime.c_str());
158 std::string AppControl::uri() const {
159 const char* uri = appsvc_get_uri(app_control_bundle_);
162 return std::string(uri);
164 return std::string();
168 void AppControl::set_uri(const std::string& uri) {
169 appsvc_set_uri(app_control_bundle_, uri.c_str());
172 std::string AppControl::category() const {
173 const char* category = appsvc_get_category(app_control_bundle_);
175 if (category != NULL) {
176 return std::string(category);
178 return std::string();
182 void AppControl::set_category(const std::string& category) {
183 appsvc_set_category(app_control_bundle_, category.c_str());
186 std::string AppControl::data(const std::string& key) const {
187 const char* data = appsvc_get_data(app_control_bundle_, key.c_str());
190 return std::string(data);
192 return std::string();
196 std::vector<std::string> AppControl::data_array(const std::string& key) const {
197 int data_array_len = 0;
198 const char** data_array = appsvc_get_data_array(app_control_bundle_,
199 key.c_str(), &data_array_len);
200 std::vector<std::string> data_vector;
201 if (data_array) { // checking whether the 'data_array' is valid
202 if (data_array_len > 0) {
203 for (int i = 0; i < data_array_len; i++) {
204 data_vector.push_back(data_array[i]);
211 std::string AppControl::encoded_bundle() {
212 bundle_raw* encoded_data;
214 bundle_encode(app_control_bundle_, &encoded_data, &len);
215 std::unique_ptr<bundle_raw*, decltype(bundle_free_encoded_rawdata)*>
216 ptr { &encoded_data, bundle_free_encoded_rawdata};
217 return std::string(reinterpret_cast<char*>(encoded_data), len);
220 bool AppControl::IsDataArray(const std::string& key) {
221 return appsvc_data_is_array(app_control_bundle_, key.c_str());
224 bool AppControl::AddData(const std::string& key, const std::string& value) {
225 return BundleAddData(app_control_bundle_, key, value);
230 bool AppControl::AddDataArray(const std::string& key,
231 const std::vector<std::string>& value_array) {
232 return BundleAddDataArray(app_control_bundle_, key, value_array);
236 bool AppControl::Reply(const std::map<std::string,
237 std::vector<std::string>>& data) {
239 if (appsvc_create_result_bundle(app_control_bundle_,
240 &result) != APPSVC_RET_OK) {
241 LOGGER(ERROR) << "Failed to craete result bundle.";
244 auto it = data.begin();
245 for ( ; it != data.end(); ++it) {
246 const std::string& key = it->first;
247 if (it->second.size() == 1) {
248 BundleAddData(result, key, it->second[0]);
250 BundleAddDataArray(result, key, it->second);
254 int ret = appsvc_send_result(result, APPSVC_RES_OK);
257 return ret == APPSVC_RET_OK ? true : false;
260 bool AppControl::LaunchRequest() {
261 return (app_control_send_launch_request(app_control_, NULL, NULL) ==
262 APP_CONTROL_ERROR_NONE);
265 std::unique_ptr<AppControl> AppControl::MakeAppcontrolFromURL(
266 const std::string& url) {
267 std::string smsto_scheme("smsto");
269 std::string request_url(url);
270 std::string scheme = utils::SchemeName(request_url);
271 // smsto: does not supported by platform. change to sms:
272 if (scheme == smsto_scheme) {
273 request_url = "sms" + request_url.substr(smsto_scheme.length());
277 std::unique_ptr<AppControl> request(new AppControl());
278 request->set_uri(request_url);
279 request->set_operation(GetOperationFromScheme(scheme));
280 AppendExtraDatafromUrl(request.get(), request_url);
282 return std::move(request);
285 } // namespace common