Merge lp:unity-scopes-api/staging into lp:unity-scopes-api

Proposed by Paweł Stołowski
Status: Merged
Approved by: Marcus Tomlinson
Approved revision: 286
Merged at revision: 330
Proposed branch: lp:unity-scopes-api/staging
Merge into: lp:unity-scopes-api
Diff against target: 2435 lines (+858/-262)
68 files modified
CMakeLists.txt (+2/-11)
CONFIGFILES (+22/-87)
RELEASE_NOTES.md (+8/-0)
STRUCTS (+4/-2)
debian/changelog (+12/-0)
debian/control (+2/-7)
debian/libunity-scopes3.symbols (+7/-0)
doc/tutorial.dox (+20/-17)
include/unity/scopes/AbstractScopeBase.h (+4/-0)
include/unity/scopes/ActivationQueryBase.h (+9/-0)
include/unity/scopes/ActivationResponse.h (+29/-11)
include/unity/scopes/Scope.h (+46/-33)
include/unity/scopes/ScopeBase.h (+18/-0)
include/unity/scopes/internal/ActivationResponseImpl.h (+8/-2)
include/unity/scopes/internal/DfltConfig.h.in (+7/-6)
include/unity/scopes/internal/MWScope.h (+5/-0)
include/unity/scopes/internal/ReplyObject.h (+3/-0)
include/unity/scopes/internal/ResultImpl.h (+1/-0)
include/unity/scopes/internal/ResultReplyObject.h (+0/-1)
include/unity/scopes/internal/ScopeImpl.h (+5/-0)
include/unity/scopes/internal/ScopeObject.h (+6/-0)
include/unity/scopes/internal/ScopeObjectBase.h (+6/-0)
include/unity/scopes/internal/smartscopes/HttpClientNetCpp.h (+2/-2)
include/unity/scopes/internal/smartscopes/SSScopeObject.h (+6/-0)
include/unity/scopes/internal/smartscopes/SmartScope.h (+1/-0)
include/unity/scopes/internal/smartscopes/SmartScopesClient.h (+4/-2)
include/unity/scopes/internal/zmq_middleware/ScopeI.h (+3/-0)
include/unity/scopes/internal/zmq_middleware/ZmqConfig.h (+2/-0)
include/unity/scopes/internal/zmq_middleware/ZmqMiddleware.h (+2/-0)
include/unity/scopes/internal/zmq_middleware/ZmqScope.h (+6/-0)
include/unity/scopes/testing/MockScope.h (+4/-0)
src/scopes/ActivationQueryBase.cpp (+5/-0)
src/scopes/ActivationResponse.cpp (+10/-0)
src/scopes/PreviewWidget.cpp (+24/-0)
src/scopes/ScopeBase.cpp (+7/-0)
src/scopes/internal/ActivationReplyObject.cpp (+1/-1)
src/scopes/internal/ActivationResponseImpl.cpp (+39/-3)
src/scopes/internal/ReplyObject.cpp (+5/-0)
src/scopes/internal/ResultImpl.cpp (+5/-0)
src/scopes/internal/ResultReplyObject.cpp (+1/-2)
src/scopes/internal/ScopeConfig.cpp (+23/-5)
src/scopes/internal/ScopeImpl.cpp (+49/-0)
src/scopes/internal/ScopeObject.cpp (+20/-0)
src/scopes/internal/SettingsDB.cpp (+4/-0)
src/scopes/internal/smartscopes/HttpClientNetCpp.cpp (+11/-11)
src/scopes/internal/smartscopes/SSScopeObject.cpp (+14/-0)
src/scopes/internal/smartscopes/SmartScope.cpp (+9/-12)
src/scopes/internal/smartscopes/SmartScopesClient.cpp (+53/-24)
src/scopes/internal/zmq_middleware/ScopeI.cpp (+30/-0)
src/scopes/internal/zmq_middleware/ZmqConfig.cpp (+13/-0)
src/scopes/internal/zmq_middleware/ZmqMiddleware.cpp (+6/-0)
src/scopes/internal/zmq_middleware/ZmqScope.cpp (+44/-3)
src/scopes/internal/zmq_middleware/capnproto/Scope.capnp (+8/-0)
test/gtest/scopes/Activation/Activation_test.cpp (+44/-0)
test/gtest/scopes/Activation/TestScope.h (+31/-0)
test/gtest/scopes/ActivationResponse/ActivationResponse_test.cpp (+47/-6)
test/gtest/scopes/ActivationResponse/CMakeLists.txt (+5/-0)
test/gtest/scopes/ActivationResponse/Registry.ini.in (+6/-0)
test/gtest/scopes/ActivationResponse/Runtime.ini.in (+6/-0)
test/gtest/scopes/ActivationResponse/Zmq.ini.in (+2/-0)
test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp (+4/-0)
test/gtest/scopes/internal/ScopeConfig/CMakeLists.txt (+6/-0)
test/gtest/scopes/internal/ScopeConfig/ScopeConfig_test.cpp (+44/-0)
test/gtest/scopes/internal/ScopeConfig/empty_author.ini.in (+4/-0)
test/gtest/scopes/internal/ScopeConfig/empty_description.ini.in (+4/-0)
test/gtest/scopes/internal/ScopeConfig/empty_display_name.ini.in (+4/-0)
test/gtest/scopes/internal/smartscopes/smartscopesproxy/smartscopesproxy_test.cpp (+7/-14)
test/gtest/scopes/internal/zmq_middleware/ZmqMiddleware/ZmqMiddleware_test.cpp (+9/-0)
To merge this branch: bzr merge lp:unity-scopes-api/staging
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Unity Team Pending
Review via email: mp+261480@code.launchpad.net

Commit message

Implementation of activate_result_action call. Updated doc for scope.ini file in tutorial and CONFIGFILES. Fixes: https://bugs.launchpad.net/bugs/1452681, and https://bugs.launchpad.net/bugs/1412367

Description of the change

Devel into trunk.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-04-15 15:23:45 +0000
3+++ CMakeLists.txt 2015-06-09 10:03:04 +0000
4@@ -70,7 +70,7 @@
5 pkg_check_modules(LIBACCOUNTS libaccounts-glib REQUIRED)
6 pkg_check_modules(LIBSIGNON libsignon-glib REQUIRED)
7 pkg_check_modules(ZMQLIB libzmq REQUIRED)
8-pkg_check_modules(NET_CPP net-cpp REQUIRED)
9+pkg_check_modules(NET_CPP net-cpp>=1.2.0 REQUIRED)
10
11 find_library(ZMQPPLIB zmqpp)
12 if(NOT ZMQPPLIB)
13@@ -154,15 +154,6 @@
14 ${OTHER_INCLUDE_DIRS}
15 )
16
17-# We require g++ 4.9, to avoid ABI breakage with earlier version.
18-# Note that this must match what is specifed in debian/control.
19-set(cxx_version_required 4.9)
20-if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
21- if (NOT CMAKE_CXX_COMPILER_VERSION MATCHES "^${cxx_version_required}")
22- message(FATAL_ERROR "g++ version must be ${cxx_version_required}, found ${CMAKE_CXX_COMPILER_VERSION}!")
23- endif()
24-endif()
25-
26 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wno-variadic-macros -Wextra -fPIC")
27
28 # By default, all symbols are visible in the library. We strip out things we don't
29@@ -227,7 +218,7 @@
30 # API version
31 set(UNITY_SCOPES_MAJOR 0)
32 set(UNITY_SCOPES_MINOR 6)
33-set(UNITY_SCOPES_MICRO 17)
34+set(UNITY_SCOPES_MICRO 18)
35 set(UNITY_SCOPES_SOVERSION 3)
36
37 # Version for testing, with all symbols visible
38
39=== modified file 'CONFIGFILES'
40--- CONFIGFILES 2015-02-04 07:08:27 +0000
41+++ CONFIGFILES 2015-06-09 10:03:04 +0000
42@@ -248,6 +248,16 @@
43
44 The default value is 5000 milliseconds.
45
46+- ChildScopes.Timeout
47+
48+ The timeout to be used when invoking either child_scopes() or set_child_scopes()
49+ on a scope. These methods require more time to execute than other scope methods
50+ as they read from and write to disk.
51+
52+ Only values in the range 10 to 15000 milliseconds are accepted.
53+
54+ The default value is 2000 milliseconds.
55+
56
57 Registry.ini
58 ------------
59@@ -338,6 +348,9 @@
60 <scope_id>.ini
61 --------------
62
63+NOTE: Only undocumented and deprecated keys are listed here.
64+ See tutorial.dox for the "official" list of keys.
65+
66 The recognized groups in this file are:
67
68 - ScopeConfig
69@@ -345,7 +358,7 @@
70
71 The following keys are recognized in the ScopeConfig group:
72
73-- Override
74+- Override (undocumented)
75
76 Determines whether an OEM scope is allowed to override a Canonical scope. This key is used only by Canonical
77 scopes. If true, the Canonical scope can be replaced by an OEM scope with the same ID. The default value
78@@ -353,44 +366,11 @@
79
80 For OEM scopes and click scopes, the setting of this key is ignored.
81
82-- DisplayName
83-
84- The display name of a scope (mandatory, localizable).
85-
86-- Description
87-
88- The description of a scope (mandatory, localizable).
89-
90-- Author
91-
92- The author of the scope (mandatory).
93-
94-- Version
95-
96- A integer describing the scope version. The setting is optional, but we strongly
97- recommend to set it. If the behavior of your scope changes in any way that is
98- visible to the query source (such having added or removed a result attribute),
99- you should increment the version number. This allows an aggregating scope to
100- adjust its behavior according to which version of your scope is installed.
101- If not set, the default value is 0. You can set the value to any integer >= 1.
102-
103-- Art
104-
105- Artwork to be shown for the scope. The default value is the empty string.
106-
107-- Icon
108-
109- The icon to be shown for the scope. The default value is the empty string.
110-
111-- SearchHint
112-
113- A search hint for on-screen display (localizable). The default value is the empty string.
114-
115-- HotKey
116+- HotKey (undocumented, currently unused)
117
118 The hot key for the scope. The default value is the empty string.
119
120-- ChildScopes
121+- ChildScopes (deprecated)
122
123 The list of ids of scopes aggregated by this scope (if any). The values in this list
124 must be separated by semicolons. This list is translated to the names of
125@@ -399,60 +379,15 @@
126 Note: make sure there are no trailing spaces following
127 the ids, as they will be preserved.
128
129-- Invisible
130+- Invisible (undocumented)
131
132 Whether the scope is hidden in the UI. The default value is false.
133
134-- ScopeRunner
135-
136- A custom scoperunner command-line to be executed when the scope is invoked.
137- The following placeholders can be used to substitute config paths where required:
138-
139- - %R - absolute path to the run time .ini config file
140- - %S - absolute path to the scope's .ini config file
141-
142- E.g. "ScopeRunner = /usr/bin/gdb --ex run --args /usr/lib/x86_64-linux-gnu/unity-scopes/scoperunner %R %S"
143-
144- If not set, the default scoperunner is used.
145-
146-- IdleTimeout
147-
148- The amount of time (in seconds) a running scope can be inactive before it will automatically shut down.
149- If not set, a default value of 40 is used.
150-
151-- ResultsTtlType
152-
153- If set, the results for this scope will be set to expire, and be refreshed. Valid values are:
154-
155- - None
156-
157- - Small - in the order of a minute
158-
159- - Medium - in the order of a few minutes
160-
161- - Large - in the order of an hour
162-
163-- LocationDataNeeded
164-
165- Whether the scope wants to have location data delivered to it. Note that this does not mean that the scope
166- will actually receive location data at run time. (The user may deny access, or may only provide approximate
167- location data.)
168-
169- If not set, the default value is false.
170-
171-- Keywords
172-
173- A list of keywords this scope falls under (if any). The values in this list must be separated by semicolons.
174-
175- E.g. "Keywords = music;video"
176-
177- Note: make sure there are no trailing spaces following the keywords, as they will be preserved.
178-
179-- IsAggregator
180-
181- Whether the scope is an aggregator. The default value is false.
182-
183+- DebugMode (undocumented)
184+
185+ Disables a bunch of timeouts when debugging a scope with the SDK.
186+ Default value is false.
187
188 The following keys are recognized in the Appearance group:
189
190-- TODO: document this
191+- see tutorial.dox
192
193=== modified file 'RELEASE_NOTES.md'
194--- RELEASE_NOTES.md 2015-04-15 15:23:45 +0000
195+++ RELEASE_NOTES.md 2015-06-09 10:03:04 +0000
196@@ -1,6 +1,14 @@
197 Release notes
198 =============
199
200+Changes in version 0.6.18
201+=========================
202+ - Allow child_scopes() and set_child_scopes() methods more time to
203+ execute as they read from and write to disk.
204+ - Added ChildScopes.Timeout configuration parameter to Zmq.ini
205+ - Added API for activation of in-card result actions - see
206+ ScopeBase::activate_result_action() and ActivationResponse::Status::UpdateResult.
207+
208 Changes in version 0.6.17
209 =========================
210 - Added is_account_login_result() method to Result class.
211
212=== modified file 'STRUCTS'
213--- STRUCTS 2015-02-11 17:09:45 +0000
214+++ STRUCTS 2015-06-09 10:03:04 +0000
215@@ -156,8 +156,10 @@
216
217 ActivationResponse (returned by serialize())
218 ============================================
219- 'status' : int (corresponds to ActivationResponse::Status enum)
220- 'scope_data' : variant
221+ 'status' : int (corresponds to ActivationResponse::Status enum)
222+ 'scope_data' : variant
223+ 'query' : variant (optional)
224+ 'updated_result' : variant (optional)
225
226 QueryMetadata (returned by serialize())
227 =======================================
228
229=== modified file 'debian/changelog'
230--- debian/changelog 2015-05-26 09:06:53 +0000
231+++ debian/changelog 2015-06-09 10:03:04 +0000
232@@ -1,3 +1,15 @@
233+unity-scopes-api (0.6.18-0ubuntu1) UNRELEASED; urgency=medium
234+
235+ [ Marcus Tomlinson ]
236+ * Allow child_scopes() and set_child_scopes() methods more time to
237+ execute as they read from and write to disk.
238+ * Added ChildScopes.Timeout configuration parameter to Zmq.ini
239+
240+ [ Pawel Stolowski ]
241+ * Added API for activation of in-card result actions.
242+
243+ -- Pawel Stolowski <pawel.stolowski@canonical.com> Mon, 01 Jun 2015 10:14:41 +0000
244+
245 unity-scopes-api (0.6.17+15.10.20150526-0ubuntu1) wily; urgency=medium
246
247 [ CI Train Bot ]
248
249=== modified file 'debian/control'
250--- debian/control 2015-02-05 14:57:01 +0000
251+++ debian/control 2015-06-09 10:03:04 +0000
252@@ -7,12 +7,7 @@
253 dbus-test-runner,
254 debhelper (>= 9),
255 doxygen,
256-# We rely on C++11 features, and to prevent from ABI breaks
257-# in libstdc++ causing us issues, we explicitly select a G++
258-# version. To allow cross-compiling to work, we also must
259-# append :native to g++-4.9 so we don't try to run armhf g++
260-# on an x86 CPU for example, when cross-compiling.
261- g++-4.9:native,
262+ g++,
263 google-mock,
264 graphviz,
265 libaccounts-glib-dev,
266@@ -25,7 +20,7 @@
267 libdbustest1-dev,
268 libjsoncpp-dev,
269 liblttng-ust-dev,
270- libnet-cpp-dev,
271+ libnet-cpp-dev (>= 1.2.0),
272 libprocess-cpp-dev (>= 1.0.1),
273 libsignon-glib-dev,
274 libunity-api-dev (>= 7.80.7~),
275
276=== modified file 'debian/libunity-scopes3.symbols'
277--- debian/libunity-scopes3.symbols 2015-05-26 09:06:53 +0000
278+++ debian/libunity-scopes3.symbols 2015-06-09 10:03:04 +0000
279@@ -120,6 +120,7 @@
280 (c++)"unity::scopes::ActivationQueryBase::activate()@Base" 0.4.0+14.04.20140312.1
281 (c++)"unity::scopes::ActivationQueryBase::~ActivationQueryBase()@Base" 0.4.0+14.04.20140312.1
282 (c++)"unity::scopes::ActivationQueryBase::ActivationQueryBase(unity::scopes::Result const&, unity::scopes::ActionMetadata const&)@Base" 0.5.0+14.10.20140619
283+ (c++)"unity::scopes::ActivationQueryBase::ActivationQueryBase(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
284 (c++)"unity::scopes::ActivationQueryBase::ActivationQueryBase(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.5.0+14.10.20140619
285 (c++)"unity::scopes::ActivationQueryBase::cancelled()@Base" 0.4.0+14.04.20140312.1
286 (c++)"unity::scopes::ActivationQueryBase::fwd() const@Base" 0.5.0+14.10.20140619
287@@ -131,6 +132,7 @@
288 (c++)"unity::scopes::ActivationResponse::ActivationResponse(unity::scopes::ActivationResponse::Status)@Base" 0.4.0+14.04.20140312.1
289 (c++)"unity::scopes::ActivationResponse::ActivationResponse(unity::scopes::CannedQuery const&)@Base" 0.4.0+14.04.20140312.1
290 (c++)"unity::scopes::ActivationResponse::ActivationResponse(unity::scopes::internal::ActivationResponseImpl*)@Base" 0.4.0+14.04.20140312.1
291+ (c++)"unity::scopes::ActivationResponse::ActivationResponse(unity::scopes::Result const&)@Base" 0replaceme
292 (c++)"unity::scopes::ActivationResponse::operator=(unity::scopes::ActivationResponse&&)@Base" 0.4.0+14.04.20140312.1
293 (c++)"unity::scopes::ActivationResponse::operator=(unity::scopes::ActivationResponse const&)@Base" 0.4.0+14.04.20140312.1
294 (c++)"unity::scopes::ActivationResponse::query() const@Base" 0.4.0+14.04.20140312.1
295@@ -138,6 +140,7 @@
296 (c++)"unity::scopes::ActivationResponse::serialize() const@Base" 0.4.0+14.04.20140312.1
297 (c++)"unity::scopes::ActivationResponse::set_scope_data(unity::scopes::Variant const&)@Base" 0.4.0+14.04.20140312.1
298 (c++)"unity::scopes::ActivationResponse::status() const@Base" 0.4.0+14.04.20140312.1
299+ (c++)"unity::scopes::ActivationResponse::updated_result() const@Base" 0replaceme
300 (c++)"unity::scopes::CannedQuery::~CannedQuery()@Base" 0.4.0+14.04.20140312.1
301 (c++)"unity::scopes::CannedQuery::CannedQuery(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
302 (c++)"unity::scopes::CannedQuery::CannedQuery(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
303@@ -507,6 +510,7 @@
304 (c++)"unity::scopes::internal::ScopeConfig::scope_runner() const@Base" 0.4.2+14.04.20140404.2
305 (c++)"unity::scopes::internal::ScopeConfig::search_hint() const@Base" 0.4.0+14.04.20140312.1
306 (c++)"unity::scopes::internal::ScopeConfig::version() const@Base" 0.6.9+15.04.20141129
307+ (c++)"unity::scopes::internal::ScopeImpl::activate_result_action(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<unity::scopes::ActivationListenerBase> const&)@Base" 0replaceme
308 (c++)"unity::scopes::internal::ScopeImpl::activate(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::shared_ptr<unity::scopes::ActivationListenerBase> const&)@Base" 0.4.0+14.04.20140312.1
309 (c++)"unity::scopes::internal::ScopeImpl::child_scopes()@Base" 0.6.15+15.04.20150407
310 (c++)"unity::scopes::internal::ScopeImpl::create(std::shared_ptr<unity::scopes::internal::MWScope> const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.6.11+15.04.20150119
311@@ -577,6 +581,7 @@
312 (c++)"unity::scopes::internal::ScopeMetadataImpl::settings_definitions() const@Base" 0.5.2+14.10.20140709.2
313 (c++)"unity::scopes::internal::ScopeMetadataImpl::set_version(int)@Base" 0.6.9+15.04.20141129
314 (c++)"unity::scopes::internal::ScopeMetadataImpl::version() const@Base" 0.6.9+15.04.20141129
315+ (c++)"unity::scopes::internal::ScopeObject::activate_result_action(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<unity::scopes::internal::MWReply> const&, unity::scopes::internal::InvokeInfo const&)@Base" 0replaceme
316 (c++)"unity::scopes::internal::ScopeObject::activate(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::shared_ptr<unity::scopes::internal::MWReply> const&, unity::scopes::internal::InvokeInfo const&)@Base" 0.4.0+14.04.20140312.1
317 (c++)"unity::scopes::internal::ScopeObject::child_scopes() const@Base" 0.6.15+15.04.20150407
318 (c++)"unity::scopes::internal::ScopeObject::debug_mode() const@Base" 0.6.2+rtm+rtm+rtm+14.09.20140818
319@@ -607,6 +612,7 @@
320 (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::~SSRegistryObject()@Base" 0.4.0+14.04.20140312.1
321 (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::SSRegistryObject(std::shared_ptr<unity::scopes::internal::MiddlewareBase>, unity::scopes::internal::smartscopes::SSConfig const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)@Base" 0.4.4+14.10.20140508
322 (c++)"unity::scopes::internal::smartscopes::SSRegistryObject::SSSettingsDef::~SSSettingsDef()@Base" 0.5.2+14.10.20140709.2
323+ (c++)"unity::scopes::internal::smartscopes::SSScopeObject::activate_result_action(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::shared_ptr<unity::scopes::internal::MWReply> const&, unity::scopes::internal::InvokeInfo const&)@Base" 0replaceme
324 (c++)"unity::scopes::internal::smartscopes::SSScopeObject::activate(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::shared_ptr<unity::scopes::internal::MWReply> const&, unity::scopes::internal::InvokeInfo const&)@Base" 0.4.0+14.04.20140312.1
325 (c++)"unity::scopes::internal::smartscopes::SSScopeObject::child_scopes() const@Base" 0.6.15+15.04.20150407
326 (c++)"unity::scopes::internal::smartscopes::SSScopeObject::debug_mode() const@Base" 0.6.2+rtm+rtm+rtm+14.09.20140818
327@@ -812,6 +818,7 @@
328 (c++)"unity::scopes::Runtime::~Runtime()@Base" 0.4.0+14.04.20140312.1
329 (c++)"unity::scopes::Runtime::Runtime(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0.4.0+14.04.20140312.1
330 (c++)"unity::scopes::Runtime::string_to_proxy(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const@Base" 0.4.0+14.04.20140312.1
331+ (c++)"unity::scopes::ScopeBase::activate_result_action(unity::scopes::Result const&, unity::scopes::ActionMetadata const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 0replaceme
332 (c++)"unity::scopes::ScopeBase::activate(unity::scopes::Result const&, unity::scopes::ActionMetadata const&)@Base" 0.4.0+14.04.20140312.1
333 (c++)"unity::scopes::ScopeBase::app_directory() const@Base" 0.6.9+15.04.20141129
334 (c++)"unity::scopes::ScopeBase::cache_directory() const@Base" 0.6.0+14.10.20140804.1
335
336=== modified file 'doc/tutorial.dox'
337--- doc/tutorial.dox 2015-04-22 13:19:12 +0000
338+++ doc/tutorial.dox 2015-06-09 10:03:04 +0000
339@@ -181,7 +181,7 @@
340 The scopes run time calls \link unity::scopes::ScopeBase::stop() stop()\endlink to inform your scope
341 that it should shut down. You can use this method to perform any one-time clean-up.
342
343-Prior to sending any queries, the scopes run time calls \link unity::scopes::ScopeBase::run() run()\endlink if your `stop()` method
344+Prior to sending any queries, the scopes run time calls \link unity::scopes::ScopeBase::run() run()\endlink if your `start()` method
345 completed successfully (did not throw an exception). The `run()` method
346 is called by a separate thread that you can use for your own purposes, for example, to run an event loop.
347 The scopes run time has no further interest in this thread, but you must ensure that, if you do not return
348@@ -191,7 +191,7 @@
349
350 \paragraph handlingsearch Handling search
351
352-The unity::scopes::ScopeBase::search() method is called once for each query. Its purpose is to instantiante
353+The unity::scopes::ScopeBase::search() method is called once for each query. Its purpose is to instantiate
354 and return a new C++ instance that encapsulates the query, that is, `search()` is a factory method.
355 (Do not start execution of the query as part of `search()`; the query object has a separate method for this.)
356
357@@ -295,7 +295,7 @@
358 `run()` to execute the query.
359
360 The \link unity::scopes::SearchReplyProxy SearchReplyProxy\endlink that is passed to `run()` is an invocation
361-handle that allows you push results for the query back towards the client. (`SearchReplyProxy` is a `shared_ptr`
362+handle that allows you to push results for the query back towards the client. (`SearchReplyProxy` is a `shared_ptr`
363 to a \link unity::scopes::SearchReply SearchReply\endlink object.)
364
365 Two important methods of `SerchReply` are \link unity::scopes::SearchReply::register_category register_category()\endlink
366@@ -1240,8 +1240,8 @@
367 SearchHint = hint text displayed to user when viewing scope
368 HotKey =
369 ResultsTtlType = None, Small, Medium, or Large
370- ChildScopes =
371 Keywords =
372+ IsAggregator = true or false
373 IdleTimeout = idle timeout in seconds
374 LocationDataNeeded = true or false
375 ScopeRunner = path_to_scope_runner args... %R %S
376@@ -1274,10 +1274,24 @@
377 your scope is installed.
378 If not set, the default value is 0. You can set the value to any integer >= 1.
379
380+The `SearchHint` key provides text that may be shown by the UI, such as "Enter a city name".
381+
382+The `Keywords` key is optional, but we recommend that you use it. Keywords are used by aggregators
383+to collect results from scopes of similar type (E.g. The Music scope will aggregate scopes with the
384+keyword "music", and so on). The value of `Keywords` should specify a list of keywords your scope
385+falls under. This value must be a semicolon separated list (E.g. `Keywords = music;video`).
386+
387+The `IsAggregator` key must be set to `true` for aggregating scopes. The default value is `false`.
388+
389 The `IdleTimeout` key controls how long a scope can remain idle before it is told to stop by the registry (or
390 killed if it does not stop within 4 seconds). The default idle timeout is 40 seconds, meaning that a
391 scope will be told to stop if no query was sent to it for that amount of time.
392
393+`ResultTtl` determines how long results should be cached by the UI before they are considered "stale"
394+and should be refreshed. `None` indicates that results remain valid indefinitely; `Small` indicates
395+results are valid for around a minute; `Medium` indicates that results are valid for a few minutes;
396+`Large` indicates that results remain valid for around an hour.
397+
398 `LocationDataNeeded` should be set to `true` if the scope requires location data. In that case, the
399 \link unity::scopes::SearchMetadata SearchMetadata\endlink provides access to
400 \link unity::scopes::Location Location\endlink information
401@@ -1293,8 +1307,8 @@
402 The `%R` expands to the path to the `Runtime.ini` config file, and `%S` expands to the scope's `.ini` file.
403
404 The `Appearance` group and all keys within it are optional and can be used to customize the look of the scope.
405-Some of the `Appearance` keys (such as `PageHeader.Background`) require background scheme uris.
406-Valid uris for these keys include:
407+Some of the `Appearance` keys (such as `PageHeader.Background`) require background scheme URIs.
408+Valid URIs for these keys include:
409
410 <ul>
411 <li>color:///\#aarrggbb</li>
412@@ -1304,17 +1318,6 @@
413 <li>http://remote-server.com/path/to/image</li>
414 </ul>
415
416-The value of `ChildScopes` key is to be used by aggregator scopes. It must be a semicolon separated list of scope identifiers that
417-might be aggregated by this scope, for example:
418-
419-`ChildScopes = com.foo.bar;com.foo.bar2`
420-
421-This list of scopes is translated to the names of children scopes when in the scopes overview page of the Unity Dash.
422-
423-The `Keywords` key is optional, but we recommend that you use it. Keywords are used by aggregators to collect results from scopes of
424-similar type (E.g. The Music scope will aggregate scopes with the keyword "music", and so on). The value of `Keywords` should specify a
425-list of keywords your scope falls under. Like `ChildScopes`, this value must be a semicolon separated list (E.g. `Keywords = music;video`).
426-
427 \note Please refer to the <a href="https://developer.ubuntu.com/en/scopes/tutorials/scope-keywords/">Scope Keywords</a>
428 tutorial document for more detail on using keywords in your scope.
429
430
431=== modified file 'include/unity/scopes/AbstractScopeBase.h'
432--- include/unity/scopes/AbstractScopeBase.h 2015-03-25 05:52:25 +0000
433+++ include/unity/scopes/AbstractScopeBase.h 2015-06-09 10:03:04 +0000
434@@ -62,6 +62,10 @@
435 virtual ChildScopeList find_child_scopes() const = 0;
436 virtual ChildScopeList child_scopes() const = 0;
437
438+ virtual ActivationQueryBase::UPtr activate_result_action(Result const& result,
439+ ActionMetadata const& metadata,
440+ std::string const& action_id) = 0;
441+
442 protected:
443 AbstractScopeBase();
444 /// @endcond
445
446=== modified file 'include/unity/scopes/ActivationQueryBase.h'
447--- include/unity/scopes/ActivationQueryBase.h 2014-11-03 05:31:30 +0000
448+++ include/unity/scopes/ActivationQueryBase.h 2015-06-09 10:03:04 +0000
449@@ -70,6 +70,15 @@
450 ActivationQueryBase(Result const& result, ActionMetadata const& metadata, std::string const& widget_id, std::string const& action_id);
451
452 /**
453+ \brief Create ActivationQueryBase.
454+
455+ \param update_result The result received by ScopeBase::activate_result_action().
456+ \param metadata The metadata received by ScopeBase::activate_result_action().
457+ \param action_id The action identifier received by ScopeBase::activate_result_action().
458+ */
459+ ActivationQueryBase(Result const& update_result, ActionMetadata const& metadata, std::string const& action_id);
460+
461+ /**
462 \brief Called when the originator of the activation request cancelled it.
463 */
464 virtual void cancelled() override;
465
466=== modified file 'include/unity/scopes/ActivationResponse.h'
467--- include/unity/scopes/ActivationResponse.h 2014-11-03 05:31:30 +0000
468+++ include/unity/scopes/ActivationResponse.h 2015-06-09 10:03:04 +0000
469@@ -20,6 +20,7 @@
470
471 #include <unity/scopes/Variant.h>
472 #include <unity/scopes/CannedQuery.h>
473+#include <unity/scopes/Result.h>
474 #include <memory>
475
476 namespace unity
477@@ -41,23 +42,25 @@
478 {
479 public:
480 /**
481- \brief Status of a unity::scopes::ScopeBase::activate or unity::scopes::ScopeBase::perform_action request.
482+ \brief Status of a unity::scopes::ScopeBase::activate, unity::scopes::ScopeBase::perform_action,
483+ or unity::scopes::ScopeBase::activate_result_action request.
484 */
485 enum Status
486 {
487- NotHandled, /**< Activation of this result wasn't handled by the scope */
488- ShowDash, /**< Activation of this result was handled, show the Dash */
489- HideDash, /**< Activation of this result was handled, hide the Dash */
490- ShowPreview, /**< Preview should be requested for this result */
491- PerformQuery /**< Perform new search. This state is implied if creating ActivationResponse with CannedQuery object and is invalid otherwise */
492+ NotHandled, /**< Activation of this result wasn't handled by the scope */
493+ ShowDash, /**< Activation of this result was handled, show the Dash */
494+ HideDash, /**< Activation of this result was handled, hide the Dash */
495+ ShowPreview, /**< Preview should be requested for this result */
496+ PerformQuery, /**< Perform new search. This state is implied if creating ActivationResponse with CannedQuery object and is invalid otherwise */
497+ UpdateResult, /**< Update the result. This state is implied if creating ActivationResponse with Result object and is invalid otherwise */
498 };
499
500 /**
501 \brief Creates ActivationResponse with given status.
502 \param status The activation status.
503- \throws unity::InvalidArgumentException if status is Status::PerformQuery. To
504- create an ActivationResponse of that type, use the ActivationResponse(CannedQuery const&)
505- constructor.
506+ \throws unity::InvalidArgumentException if status is Status::PerformQuery or Status::Update.
507+ To create an ActivationResponse for one of these types, use the ActivationResponse(CannedQuery const&)
508+ or ActivationResponse(Result const&) constructors.
509 */
510 ActivationResponse(Status status);
511
512@@ -67,6 +70,13 @@
513 */
514 ActivationResponse(CannedQuery const& query);
515
516+ /**
517+ \brief Creates an ActivationResponse with status Status::UpdateResult and an updated result that
518+ replaces the original result of the action.
519+ \param updated_result The updated result to replace the original result of the action.
520+ */
521+ ActivationResponse(Result const& updated_result);
522+
523 /**@name Copy and assignment
524 Copy and assignment operators (move and non-move versions) have the usual value semantics.
525 */
526@@ -88,13 +98,13 @@
527 \brief Attach arbitrary data to this response.
528
529 The attached data is sent back to the scope if the status of this response is Status::ShowPreview.
530- \param data arbitrary value attached to response
531+ \param data An arbitrary value attached to the response.
532 */
533 void set_scope_data(Variant const& data);
534
535 /**
536 \brief Get data attached to this response object.
537- \return The data attached to response.
538+ \return The data attached to the response.
539 */
540 Variant scope_data() const;
541
542@@ -106,6 +116,14 @@
543 */
544 CannedQuery query() const;
545
546+ /**
547+ \brief The updated result if status is Status::UpdateResult.
548+
549+ \throws unity::LogicException if the status of this ActivationResponse is anything other than Status::UpdateResult.
550+ \return The result to be displayed instead of the original result.
551+ */
552+ Result updated_result() const;
553+
554 /// @cond
555 VariantMap serialize() const;
556
557
558=== modified file 'include/unity/scopes/Scope.h'
559--- include/unity/scopes/Scope.h 2015-04-09 15:59:17 +0000
560+++ include/unity/scopes/Scope.h 2015-06-09 10:03:04 +0000
561@@ -54,10 +54,10 @@
562 Results for the query may begin to arrive only after search() completes (but may
563 also arrive while search() is still running).
564
565- \param query_string search string
566- \param metadata additional data to pass to scope
567- \param reply The callback object to receive replies
568- \return A proxy that permits cancellation of this request
569+ \param query_string The search string.
570+ \param metadata Additional data to pass to the scope.
571+ \param reply The callback object to receive replies.
572+ \return A proxy that permits cancellation of this request.
573 */
574 virtual QueryCtrlProxy search(std::string const& query_string,
575 SearchMetadata const& metadata,
576@@ -68,11 +68,11 @@
577
578 This method has same synopsis as previous method, but it takes additional unity::scopes::FilterState argument.
579
580- \param query_string search string
581- \param filter_state state of filters
582- \param metadata additional data to pass to scope
583- \param reply The callback object to receive replies
584- \return A proxy that permits cancellation of this request
585+ \param query_string The search string.
586+ \param filter_state The state of filters.
587+ \param metadata Additional data to pass to the scope.
588+ \param reply The callback object to receive replies.
589+ \return A proxy that permits cancellation of this request.
590 */
591 virtual QueryCtrlProxy search(std::string const& query_string,
592 FilterState const& filter_state,
593@@ -84,12 +84,12 @@
594
595 This method has same synopsis as previous method, but it takes additional department identifier argument.
596
597- \param query_string search string
598- \param department_id identifier of a department to search
599- \param filter_state state of filters
600- \param metadata additional data to pass to scope
601- \param reply The callback object to receive replies
602- \return query handler
603+ \param query_string The search string.
604+ \param department_id The identifier of a department to search.
605+ \param filter_state The state of filters.
606+ \param metadata Additional data to pass to the scope.
607+ \param reply The callback object to receive replies.
608+ \return A proxy that permits cancellation of this request.
609 */
610 virtual QueryCtrlProxy search(std::string const& query_string,
611 std::string const& department_id,
612@@ -99,10 +99,10 @@
613
614 /**
615 \brief Initiates activation of a search result.
616- \param result activated result
617- \param metadata additional data to pass to scope
618+ \param result The result that was activated.
619+ \param metadata Additional data to pass to the scope.
620 \param reply The callback object to receive replies
621- \return A proxy that permits cancellation of this request
622+ \return A proxy that permits cancellation of this request.
623 */
624 virtual QueryCtrlProxy activate(Result const& result,
625 ActionMetadata const& metadata,
626@@ -110,12 +110,12 @@
627
628 /**
629 \brief Initiates activation of a preview action.
630- \param result Result that was previewed.
631- \param metadata additional data to pass to scope
632- \param widget_id identifier of 'actions' widget of activated action
633- \param action_id identifier of an action to activate
634+ \param result The result that was previewed.
635+ \param metadata Additional data to pass to the scope.
636+ \param widget_id The identifier of the 'actions' widget of the activated action.
637+ \param action_id The identifier of an action to activate.
638 \param reply The callback object to receive replies
639- \return A proxy that permits cancellation of this request
640+ \return A proxy that permits cancellation of this request.
641 */
642 virtual QueryCtrlProxy perform_action(Result const& result,
643 ActionMetadata const& metadata,
644@@ -125,10 +125,10 @@
645
646 /**
647 \brief Initiates preview request.
648- \param result Result to be previewed
649- \param metadata additional data to pass to scope
650- \param reply The callback object to receive replies
651- \return A proxy that permits cancellation of this request
652+ \param result The result to be previewed.
653+ \param metadata Additional data to pass to the scope.
654+ \param reply The callback object to receive replies.
655+ \return A proxy that permits cancellation of this request.
656 */
657 virtual QueryCtrlProxy preview(Result const& result,
658 ActionMetadata const& metadata,
659@@ -161,13 +161,13 @@
660
661 This method has same synopsis as previous search method, but it takes additional user_data argument.
662
663- \param query_string search string
664- \param department_id identifier of a department to search
665- \param filter_state state of filters
666- \param user_data arbitrary data
667- \param metadata additional data to pass to scope
668+ \param query_string The search string.
669+ \param department_id The identifier of a department to search.
670+ \param filter_state The state of filters.
671+ \param user_data Arbitrary data.
672+ \param metadata Additional data to pass to the scope.
673 \param reply The callback object to receive replies
674- \return query handler
675+ \return A proxy that permits cancellation of this request.
676 */
677 virtual QueryCtrlProxy search(std::string const& query_string,
678 std::string const& department_id,
679@@ -176,6 +176,19 @@
680 SearchMetadata const& metadata,
681 SearchListenerBase::SPtr const& reply) = 0;
682
683+ /**
684+ \brief Initiates activation of a result (in-card) action.
685+ \param result The result that was was activated.
686+ \param metadata Additional data to pass to the scope.
687+ \param action_id The identifier of the action.
688+ \param reply The callback object to receive replies
689+ \return A proxy that permits cancellation of this request.
690+ */
691+ virtual QueryCtrlProxy activate_result_action(Result const& result,
692+ ActionMetadata const& metadata,
693+ std::string const& action_id,
694+ ActivationListenerBase::SPtr const& reply) = 0;
695+
696 protected:
697 /// @cond
698 Scope();
699
700=== modified file 'include/unity/scopes/ScopeBase.h'
701--- include/unity/scopes/ScopeBase.h 2015-04-09 15:59:17 +0000
702+++ include/unity/scopes/ScopeBase.h 2015-06-09 10:03:04 +0000
703@@ -357,6 +357,24 @@
704 */
705 virtual ChildScopeList child_scopes() const final;
706
707+ /**
708+ \brief Invoked when a scope is requested to handle a result in-card action.
709+
710+ This method must return an instance that is derived from `ActivationQueryBase`. The implementation
711+ of this method must return in a timely manner, that is, it should perform only minimal
712+ initialization that is guaranteed to complete quickly. The call to activate_result_action() is made
713+ by an arbitrary thread.
714+ The default implementation returns an instance of ActivationQueryBase that responds with
715+ ActivationResponse::Status::NotHandled.
716+ \param result The result whose action was activated.
717+ \param metadata Additional data sent by the client.
718+ \param action_id The identifier of the action that was activated.
719+ \return The activation instance.
720+ */
721+ virtual ActivationQueryBase::UPtr activate_result_action(Result const& result,
722+ ActionMetadata const& metadata,
723+ std::string const& action_id);
724+
725 protected:
726 /// @cond
727 ScopeBase();
728
729=== modified file 'include/unity/scopes/internal/ActivationResponseImpl.h'
730--- include/unity/scopes/internal/ActivationResponseImpl.h 2014-11-03 05:31:30 +0000
731+++ include/unity/scopes/internal/ActivationResponseImpl.h 2015-06-09 10:03:04 +0000
732@@ -20,6 +20,7 @@
733
734 #include <unity/scopes/ActivationResponse.h>
735 #include <unity/scopes/CannedQuery.h>
736+#include <unity/scopes/Result.h>
737
738 namespace unity
739 {
740@@ -30,12 +31,15 @@
741 namespace internal
742 {
743
744+class RuntimeImpl;
745+
746 class ActivationResponseImpl final
747 {
748 public:
749 ActivationResponseImpl(ActivationResponse::Status status);
750 ActivationResponseImpl(CannedQuery const& query);
751- ActivationResponseImpl(VariantMap const& var);
752+ ActivationResponseImpl(Result const& result);
753+ ActivationResponseImpl(VariantMap const& var, RuntimeImpl const* runtime);
754 ~ActivationResponseImpl() = default;
755
756 ActivationResponseImpl(ActivationResponseImpl const& other) = default;
757@@ -47,15 +51,17 @@
758 void set_scope_data(Variant const& hints);
759 Variant scope_data() const;
760 CannedQuery query() const;
761+ Result updated_result() const;
762
763 VariantMap serialize() const;
764
765- static ActivationResponse create(VariantMap const& var);
766+ static ActivationResponse create(VariantMap const& var, RuntimeImpl const *runtime);
767
768 private:
769 ActivationResponse::Status status_;
770 CannedQuery::SPtr query_;
771 Variant scope_data_;
772+ Result::SPtr updated_result_;
773 };
774
775 } // namespace internal
776
777=== modified file 'include/unity/scopes/internal/DfltConfig.h.in'
778--- include/unity/scopes/internal/DfltConfig.h.in 2015-03-02 03:59:01 +0000
779+++ include/unity/scopes/internal/DfltConfig.h.in 2015-06-09 10:03:04 +0000
780@@ -46,12 +46,13 @@
781
782 static constexpr char const* DFLT_SS_SCOPE_IDENTITY = "SmartScope";
783
784-static constexpr int DFLT_REAP_EXPIRY = 45; // seconds
785-static constexpr int DFLT_REAP_INTERVAL = 10; // seconds
786-static constexpr int DFLT_PROCESS_TIMEOUT = 4000; // milliseconds
787-static constexpr int DFLT_ZMQ_TWOWAY_TIMEOUT = 500; // milliseconds
788-static constexpr int DFLT_ZMQ_LOCATE_TIMEOUT = 5000; // milliseconds
789-static constexpr int DFLT_ZMQ_REGISTRY_TIMEOUT = 5000; // milliseconds
790+static constexpr int DFLT_REAP_EXPIRY = 45; // seconds
791+static constexpr int DFLT_REAP_INTERVAL = 10; // seconds
792+static constexpr int DFLT_PROCESS_TIMEOUT = 4000; // milliseconds
793+static constexpr int DFLT_ZMQ_TWOWAY_TIMEOUT = 500; // milliseconds
794+static constexpr int DFLT_ZMQ_LOCATE_TIMEOUT = 5000; // milliseconds
795+static constexpr int DFLT_ZMQ_REGISTRY_TIMEOUT = 5000; // milliseconds
796+static constexpr int DFLT_ZMQ_CHILDSCOPES_TIMEOUT = 2000; // milliseconds
797
798 static constexpr char const* DFLT_HOME_CACHE_SUBDIR = ".local/share/unity-scopes";
799 static constexpr char const* DFLT_HOME_APP_SUBDIR = ".local/share";
800
801=== modified file 'include/unity/scopes/internal/MWScope.h'
802--- include/unity/scopes/internal/MWScope.h 2015-03-25 05:52:25 +0000
803+++ include/unity/scopes/internal/MWScope.h 2015-06-09 10:03:04 +0000
804@@ -64,6 +64,11 @@
805
806 virtual bool debug_mode() = 0;
807
808+ virtual QueryCtrlProxy activate_result_action(VariantMap const& result,
809+ VariantMap const& hints,
810+ std::string const& action_id,
811+ MWReplyProxy const& reply) = 0;
812+
813 protected:
814 MWScope(MiddlewareBase* mw_base);
815 };
816
817=== modified file 'include/unity/scopes/internal/ReplyObject.h'
818--- include/unity/scopes/internal/ReplyObject.h 2015-02-04 05:45:25 +0000
819+++ include/unity/scopes/internal/ReplyObject.h 2015-06-09 10:03:04 +0000
820@@ -60,6 +60,9 @@
821 void finished(CompletionDetails const& details) noexcept override;
822 void info(OperationInfo const& op_info) noexcept override;
823
824+protected:
825+ RuntimeImpl const* runtime() const;
826+
827 private:
828 RuntimeImpl const* runtime_;
829 ListenerBase::SPtr listener_base_;
830
831=== modified file 'include/unity/scopes/internal/ResultImpl.h'
832--- include/unity/scopes/internal/ResultImpl.h 2014-11-03 05:31:30 +0000
833+++ include/unity/scopes/internal/ResultImpl.h 2015-06-09 10:03:04 +0000
834@@ -84,6 +84,7 @@
835 // a public static method, so there's access to the private constructor
836 // without the need to define too many classes as friends
837 static Result create_result(VariantMap const&);
838+ static Result create_result(ResultImpl *impl);
839
840 protected:
841 virtual void serialize_internal(VariantMap& var) const;
842
843=== modified file 'include/unity/scopes/internal/ResultReplyObject.h'
844--- include/unity/scopes/internal/ResultReplyObject.h 2014-11-03 05:31:30 +0000
845+++ include/unity/scopes/internal/ResultReplyObject.h 2015-06-09 10:03:04 +0000
846@@ -45,7 +45,6 @@
847 private:
848 SearchListenerBase::SPtr const receiver_;
849 std::shared_ptr<CategoryRegistry> cat_registry_;
850- RuntimeImpl const* runtime_;
851 std::atomic_int cardinality_;
852 std::atomic_int num_pushes_;
853 };
854
855=== modified file 'include/unity/scopes/internal/ScopeImpl.h'
856--- include/unity/scopes/internal/ScopeImpl.h 2015-04-09 15:59:17 +0000
857+++ include/unity/scopes/internal/ScopeImpl.h 2015-06-09 10:03:04 +0000
858@@ -100,6 +100,11 @@
859 ActionMetadata const& hints,
860 PreviewListenerBase::SPtr const& reply) override;
861
862+ virtual QueryCtrlProxy activate_result_action(Result const& result,
863+ ActionMetadata const& metadata,
864+ std::string const& action_id,
865+ ActivationListenerBase::SPtr const& reply);
866+
867 virtual ChildScopeList child_scopes() override;
868 virtual bool set_child_scopes(ChildScopeList const& child_scopes) override;
869
870
871=== modified file 'include/unity/scopes/internal/ScopeObject.h'
872--- include/unity/scopes/internal/ScopeObject.h 2015-03-25 05:52:25 +0000
873+++ include/unity/scopes/internal/ScopeObject.h 2015-06-09 10:03:04 +0000
874@@ -82,6 +82,12 @@
875
876 virtual bool debug_mode() const override;
877
878+ virtual MWQueryCtrlProxy activate_result_action(Result const& result,
879+ ActionMetadata const& hints,
880+ std::string const& action_id,
881+ MWReplyProxy const &reply,
882+ InvokeInfo const& info) override;
883+
884 private:
885 MWQueryCtrlProxy query(MWReplyProxy const& reply, MiddlewareBase* mw_base,
886 std::string const& method,
887
888=== modified file 'include/unity/scopes/internal/ScopeObjectBase.h'
889--- include/unity/scopes/internal/ScopeObjectBase.h 2015-03-25 05:52:25 +0000
890+++ include/unity/scopes/internal/ScopeObjectBase.h 2015-06-09 10:03:04 +0000
891@@ -73,6 +73,12 @@
892 virtual bool set_child_scopes(ChildScopeList const& child_scopes) = 0;
893
894 virtual bool debug_mode() const = 0;
895+
896+ virtual MWQueryCtrlProxy activate_result_action(Result const& result,
897+ ActionMetadata const& hints,
898+ std::string const& action_id,
899+ MWReplyProxy const& reply,
900+ InvokeInfo const& info) = 0;
901 };
902
903 } // namespace internal
904
905=== modified file 'include/unity/scopes/internal/smartscopes/HttpClientNetCpp.h'
906--- include/unity/scopes/internal/smartscopes/HttpClientNetCpp.h 2015-01-16 06:13:57 +0000
907+++ include/unity/scopes/internal/smartscopes/HttpClientNetCpp.h 2015-06-09 10:03:04 +0000
908@@ -30,7 +30,7 @@
909 {
910 namespace http
911 {
912-class Client;
913+class StreamingClient;
914 }
915 }
916 }
917@@ -63,7 +63,7 @@
918 void cancel_get(unsigned int session_id) override;
919
920 unsigned int no_reply_timeout;
921- std::shared_ptr<core::net::http::Client> client;
922+ std::shared_ptr<core::net::http::StreamingClient> client;
923 std::thread worker;
924 };
925
926
927=== modified file 'include/unity/scopes/internal/smartscopes/SSScopeObject.h'
928--- include/unity/scopes/internal/smartscopes/SSScopeObject.h 2015-03-25 05:52:25 +0000
929+++ include/unity/scopes/internal/smartscopes/SSScopeObject.h 2015-06-09 10:03:04 +0000
930@@ -79,6 +79,12 @@
931
932 bool debug_mode() const override;
933
934+ MWQueryCtrlProxy activate_result_action(Result const& result,
935+ ActionMetadata const& hints,
936+ std::string const& action_id,
937+ MWReplyProxy const& reply,
938+ InvokeInfo const& info) override;
939+
940 private:
941 MWQueryCtrlProxy query(InvokeInfo const& info,
942 MWReplyProxy const& reply,
943
944=== modified file 'include/unity/scopes/internal/smartscopes/SmartScope.h'
945--- include/unity/scopes/internal/smartscopes/SmartScope.h 2014-11-18 07:04:04 +0000
946+++ include/unity/scopes/internal/smartscopes/SmartScope.h 2015-06-09 10:03:04 +0000
947@@ -92,6 +92,7 @@
948 QueryBase::UPtr preview(std::string const& scope_id, Result const& result, ActionMetadata const& hints);
949 ActivationQueryBase::UPtr activate(std::string const&, Result const& result, ActionMetadata const& metadata);
950 ActivationQueryBase::UPtr perform_action(std::string const& scope_id, Result const& result, ActionMetadata const& metadata, std::string const& widget_id, std::string const& action_id);
951+ ActivationQueryBase::UPtr activate_result_action(std::string const& scope_id, Result const& result, ActionMetadata const& metadata, std::string const& action_id);
952
953 private:
954 SSRegistryObject::SPtr reg_;
955
956=== modified file 'include/unity/scopes/internal/smartscopes/SmartScopesClient.h'
957--- include/unity/scopes/internal/smartscopes/SmartScopesClient.h 2015-01-28 09:03:59 +0000
958+++ include/unity/scopes/internal/smartscopes/SmartScopesClient.h 2015-06-09 10:03:04 +0000
959@@ -215,8 +215,10 @@
960 std::shared_ptr<DepartmentInfo> parse_departments(JsonNodeInterface::SPtr node);
961 Filters parse_filters(JsonNodeInterface::SPtr node);
962 FilterState parse_filter_state(JsonNodeInterface::SPtr node);
963- void parse_line(std::string const& json, SearchReplyHandler const& handler);
964- void parse_line(std::string const& json, PreviewReplyHandler const& handler);
965+
966+ std::string handle_chunk(const std::string& chunk, std::function<void(const std::string&)> line_handler);
967+ void handle_line(std::string const& json, SearchReplyHandler const& handler);
968+ void handle_line(std::string const& json, PreviewReplyHandler const& handler);
969
970 std::vector<std::string> extract_json_stream(std::string const& json_stream);
971
972
973=== modified file 'include/unity/scopes/internal/zmq_middleware/ScopeI.h'
974--- include/unity/scopes/internal/zmq_middleware/ScopeI.h 2015-03-25 05:52:25 +0000
975+++ include/unity/scopes/internal/zmq_middleware/ScopeI.h 2015-06-09 10:03:04 +0000
976@@ -53,6 +53,9 @@
977 virtual void preview_(Current const& current,
978 capnp::AnyPointer::Reader& in_params,
979 capnproto::Response::Builder& r);
980+ virtual void activate_result_action_(Current const& current,
981+ capnp::AnyPointer::Reader& in_params,
982+ capnproto::Response::Builder& r);
983 virtual void child_scopes_(Current const& current,
984 capnp::AnyPointer::Reader& in_params,
985 capnproto::Response::Builder& r);
986
987=== modified file 'include/unity/scopes/internal/zmq_middleware/ZmqConfig.h'
988--- include/unity/scopes/internal/zmq_middleware/ZmqConfig.h 2014-11-03 05:31:30 +0000
989+++ include/unity/scopes/internal/zmq_middleware/ZmqConfig.h 2015-06-09 10:03:04 +0000
990@@ -39,6 +39,7 @@
991 int twoway_timeout() const;
992 int locate_timeout() const;
993 int registry_timeout() const;
994+ int child_scopes_timeout() const;
995 std::string registry_endpoint_dir() const;
996 std::string ss_registry_endpoint_dir() const;
997
998@@ -47,6 +48,7 @@
999 int twoway_timeout_;
1000 int locate_timeout_;
1001 int registry_timeout_;
1002+ int child_scopes_timeout_;
1003 std::string registry_endpoint_dir_;
1004 std::string ss_registry_endpoint_dir_;
1005 };
1006
1007=== modified file 'include/unity/scopes/internal/zmq_middleware/ZmqMiddleware.h'
1008--- include/unity/scopes/internal/zmq_middleware/ZmqMiddleware.h 2014-12-04 03:33:59 +0000
1009+++ include/unity/scopes/internal/zmq_middleware/ZmqMiddleware.h 2015-06-09 10:03:04 +0000
1010@@ -94,6 +94,7 @@
1011 ThreadPool* twoway_pool();
1012 int64_t locate_timeout() const noexcept;
1013 int64_t registry_timeout() const noexcept;
1014+ int64_t child_scopes_timeout() const noexcept;
1015
1016 private:
1017 ObjectProxy make_typed_proxy(std::string const& endpoint,
1018@@ -138,6 +139,7 @@
1019 int64_t twoway_timeout_; // Default timeout for twoway invocations
1020 int64_t locate_timeout_; // Timeout for registry locate()
1021 int64_t registry_timeout_; // Timeout for registry operations other than locate()
1022+ int64_t child_scopes_timeout_; // Timeout for child_scopes() and set_child_scopes() methods
1023
1024 std::string public_endpoint_dir_;
1025 std::string private_endpoint_dir_;
1026
1027=== modified file 'include/unity/scopes/internal/zmq_middleware/ZmqScope.h'
1028--- include/unity/scopes/internal/zmq_middleware/ZmqScope.h 2015-03-25 05:52:25 +0000
1029+++ include/unity/scopes/internal/zmq_middleware/ZmqScope.h 2015-06-09 10:03:04 +0000
1030@@ -68,8 +68,14 @@
1031
1032 virtual bool debug_mode() override;
1033
1034+ virtual QueryCtrlProxy activate_result_action(VariantMap const& result,
1035+ VariantMap const& hints,
1036+ std::string const& action_id,
1037+ MWReplyProxy const& reply) override;
1038+
1039 private:
1040 ZmqObjectProxy::TwowayOutParams invoke_scope_(capnp::MessageBuilder& in_params);
1041+ ZmqObjectProxy::TwowayOutParams invoke_scope_(capnp::MessageBuilder& in_params, int64_t timeout);
1042 std::mutex debug_mode_mutex_;
1043 std::unique_ptr<bool> debug_mode_;
1044 };
1045
1046=== modified file 'include/unity/scopes/testing/MockScope.h'
1047--- include/unity/scopes/testing/MockScope.h 2015-04-09 15:59:17 +0000
1048+++ include/unity/scopes/testing/MockScope.h 2015-06-09 10:03:04 +0000
1049@@ -76,6 +76,10 @@
1050 SearchListenerBase::SPtr const&));
1051
1052 MOCK_METHOD1(set_child_scopes, bool(ChildScopeList const&));
1053+ MOCK_METHOD4(activate_result_action, QueryCtrlProxy(unity::scopes::Result const&,
1054+ ActionMetadata const&,
1055+ std::string const&,
1056+ ActivationListenerBase::SPtr const&));
1057 };
1058
1059 /// @endcond
1060
1061=== modified file 'src/scopes/ActivationQueryBase.cpp'
1062--- src/scopes/ActivationQueryBase.cpp 2014-06-18 10:06:47 +0000
1063+++ src/scopes/ActivationQueryBase.cpp 2015-06-09 10:03:04 +0000
1064@@ -37,6 +37,11 @@
1065 {
1066 }
1067
1068+ActivationQueryBase::ActivationQueryBase(Result const& update_result, ActionMetadata const& metadata, std::string const& action_id) :
1069+ QueryBase(new internal::ActivationQueryBaseImpl(update_result, metadata, "", action_id))
1070+{
1071+}
1072+
1073 ActivationQueryBase::~ActivationQueryBase()
1074 {
1075 }
1076
1077=== modified file 'src/scopes/ActivationResponse.cpp'
1078--- src/scopes/ActivationResponse.cpp 2014-02-27 16:58:50 +0000
1079+++ src/scopes/ActivationResponse.cpp 2015-06-09 10:03:04 +0000
1080@@ -36,6 +36,11 @@
1081 {
1082 }
1083
1084+ActivationResponse::ActivationResponse(Result const& updated_result)
1085+ : p(new internal::ActivationResponseImpl(updated_result))
1086+{
1087+}
1088+
1089 /// @cond
1090 ActivationResponse::ActivationResponse(internal::ActivationResponseImpl* pimpl)
1091 : p(pimpl)
1092@@ -88,6 +93,11 @@
1093 return p->query();
1094 }
1095
1096+Result ActivationResponse::updated_result() const
1097+{
1098+ return p->updated_result();
1099+}
1100+
1101 } // namespace scopes
1102
1103 } // namespace unity
1104
1105=== modified file 'src/scopes/PreviewWidget.cpp'
1106--- src/scopes/PreviewWidget.cpp 2015-02-24 10:45:11 +0000
1107+++ src/scopes/PreviewWidget.cpp 2015-06-09 10:03:04 +0000
1108@@ -90,6 +90,7 @@
1109 \arg \c progress
1110 \arg \c text
1111 \arg \c rating-input
1112+\arg \c rating-edit
1113 \arg \c reviews
1114 \arg \c expandable
1115
1116@@ -319,6 +320,29 @@
1117 }
1118 \endcode
1119
1120+\subsection rating-edit rating-edit widget
1121+
1122+The rating-edit widget allows users to edit an existing review and rating. When used in a preview, the widget displays an existing
1123+review and a small "pen" icon; user can update the review and/or rating after tapping the "pen" icon.
1124+
1125+This widget supports all the attributes of rating-input widget, plus three
1126+extra attributes (\c "review", \c "rating", \c "author") to pre-fill the widget with data of an existing review.
1127+
1128+List of attributes:
1129+
1130+\arg \c rating-label String for the star-based rating (default: "Rate this")
1131+\arg \c review-label String for the review input (default: "Add a review")
1132+\arg \c submit-label String for the confirmation button (default: "Send")
1133+\arg \c rating-icon-empty URI for an empty rating icon
1134+\arg \c rating-icon-full URI for a full rating icon
1135+\arg \c visible String specifying which of the two widgets are visible (\c "rating", \c "review" or default:\c "both")
1136+\arg \c required String specifying which of the two widgets are required to be filled in (\c "rating", \c "review" or default:\c "both")
1137+\arg \c author String for the name of the reviewer (optional)
1138+\arg \c review String for the text of existing review (optional)
1139+\arg \c rating Number for the rating value (optional)
1140+
1141+Note: The rating-edit widget may not be supported by older versions of unity8 shell.
1142+
1143 \subsection reviews reviews widget
1144
1145 The reviews widget is used to display previously-rated content.
1146
1147=== modified file 'src/scopes/ScopeBase.cpp'
1148--- src/scopes/ScopeBase.cpp 2015-03-25 05:52:25 +0000
1149+++ src/scopes/ScopeBase.cpp 2015-06-09 10:03:04 +0000
1150@@ -65,6 +65,13 @@
1151 return ActivationQueryBase::UPtr(new ActivationQueryBase(result, metadata, widget_id, action_id)); // default impl returns NotHandled
1152 }
1153
1154+ActivationQueryBase::UPtr ScopeBase::activate_result_action(Result const& result,
1155+ ActionMetadata const& metadata,
1156+ std::string const& action_id)
1157+{
1158+ return ActivationQueryBase::UPtr(new ActivationQueryBase(result, metadata, action_id)); // default impl returns NotHandled
1159+}
1160+
1161 void ScopeBase::runtime_version(int& v_major, int& v_minor, int& v_micro) noexcept
1162 {
1163 v_major = unity::scopes::major_version();
1164
1165=== modified file 'src/scopes/internal/ActivationReplyObject.cpp'
1166--- src/scopes/internal/ActivationReplyObject.cpp 2014-08-12 09:04:49 +0000
1167+++ src/scopes/internal/ActivationReplyObject.cpp 2015-06-09 10:03:04 +0000
1168@@ -40,7 +40,7 @@
1169
1170 bool ActivationReplyObject::process_data(VariantMap const& data)
1171 {
1172- ActivationResponse resp = ActivationResponseImpl::create(data);
1173+ ActivationResponse resp = ActivationResponseImpl::create(data, runtime());
1174 receiver_->activated(resp);
1175 return false;
1176 }
1177
1178=== modified file 'src/scopes/internal/ActivationResponseImpl.cpp'
1179--- src/scopes/internal/ActivationResponseImpl.cpp 2014-02-27 16:58:50 +0000
1180+++ src/scopes/internal/ActivationResponseImpl.cpp 2015-06-09 10:03:04 +0000
1181@@ -19,6 +19,7 @@
1182 #include <unity/scopes/internal/ActivationResponseImpl.h>
1183 #include <unity/UnityExceptions.h>
1184 #include <unity/scopes/internal/CannedQueryImpl.h>
1185+#include <unity/scopes/internal/ResultImpl.h>
1186 #include <cassert>
1187
1188 namespace unity
1189@@ -37,6 +38,10 @@
1190 {
1191 throw unity::InvalidArgumentException("ActivationResponse(): Status::PerformQuery allowed only with CannedQuery object");
1192 }
1193+ if (status == ActivationResponse::Status::UpdateResult)
1194+ {
1195+ throw unity::InvalidArgumentException("ActivationResponse(): Status::UpdateResult allowed only with Result object");
1196+ }
1197 }
1198
1199 ActivationResponseImpl::ActivationResponseImpl(CannedQuery const& query)
1200@@ -45,7 +50,13 @@
1201 {
1202 }
1203
1204-ActivationResponseImpl::ActivationResponseImpl(VariantMap const& var)
1205+ActivationResponseImpl::ActivationResponseImpl(Result const& updated_result)
1206+ : status_(ActivationResponse::Status::UpdateResult),
1207+ updated_result_(std::make_shared<Result>(updated_result))
1208+{
1209+}
1210+
1211+ActivationResponseImpl::ActivationResponseImpl(VariantMap const& var, RuntimeImpl const* runtime)
1212 {
1213 auto it = var.find("scope_data");
1214 if (it == var.end())
1215@@ -70,6 +81,17 @@
1216 }
1217 query_ = std::make_shared<CannedQuery>(CannedQueryImpl::create(it->second.get_dict()));
1218 }
1219+ else if (status_ == ActivationResponse::Status::UpdateResult)
1220+ {
1221+ it = var.find("updated_result");
1222+ if (it == var.end())
1223+ {
1224+ throw LogicException("ActivationResponseImpl(): Invalid data, missing 'updated_result'");
1225+ }
1226+ auto impl = new ResultImpl(it->second.get_dict());
1227+ impl->set_runtime(runtime);
1228+ updated_result_ = std::make_shared<Result>(ResultImpl::create_result(impl));
1229+ }
1230 }
1231
1232 ActivationResponse::Status ActivationResponseImpl::status() const
1233@@ -97,6 +119,16 @@
1234 throw LogicException("ActivationResponse::query(): query is only available for status of Status::PerformQuery");
1235 }
1236
1237+Result ActivationResponseImpl::updated_result() const
1238+{
1239+ if (updated_result_)
1240+ {
1241+ assert(status_ == ActivationResponse::Status::UpdateResult);
1242+ return *updated_result_;
1243+ }
1244+ throw LogicException("ActivationResponse::updated_result(): updated result is only available for status of Status::UpdateResult");
1245+}
1246+
1247 VariantMap ActivationResponseImpl::serialize() const
1248 {
1249 VariantMap vm;
1250@@ -106,12 +138,16 @@
1251 {
1252 vm["query"] = query_->serialize();
1253 }
1254+ if (updated_result_)
1255+ {
1256+ vm["updated_result"] = updated_result_->serialize();
1257+ }
1258 return vm;
1259 }
1260
1261-ActivationResponse ActivationResponseImpl::create(VariantMap const& var)
1262+ActivationResponse ActivationResponseImpl::create(VariantMap const& var, RuntimeImpl const* runtime)
1263 {
1264- return ActivationResponse(new ActivationResponseImpl(var));
1265+ return ActivationResponse(new ActivationResponseImpl(var, runtime));
1266 }
1267
1268 } // namespace internal
1269
1270=== modified file 'src/scopes/internal/ReplyObject.cpp'
1271--- src/scopes/internal/ReplyObject.cpp 2015-02-04 05:45:25 +0000
1272+++ src/scopes/internal/ReplyObject.cpp 2015-06-09 10:03:04 +0000
1273@@ -232,6 +232,11 @@
1274 return origin_proxy_;
1275 }
1276
1277+RuntimeImpl const* ReplyObject::runtime() const
1278+{
1279+ return runtime_;
1280+}
1281+
1282 } // namespace internal
1283
1284 } // namespace scopes
1285
1286=== modified file 'src/scopes/internal/ResultImpl.cpp'
1287--- src/scopes/internal/ResultImpl.cpp 2014-05-15 22:42:47 +0000
1288+++ src/scopes/internal/ResultImpl.cpp 2015-06-09 10:03:04 +0000
1289@@ -479,6 +479,11 @@
1290 return Result(variant_map);
1291 }
1292
1293+Result ResultImpl::create_result(ResultImpl *impl)
1294+{
1295+ return Result(impl);
1296+}
1297+
1298 } // namespace internal
1299
1300 } // namespace scopes
1301
1302=== modified file 'src/scopes/internal/ResultReplyObject.cpp'
1303--- src/scopes/internal/ResultReplyObject.cpp 2015-01-09 03:16:51 +0000
1304+++ src/scopes/internal/ResultReplyObject.cpp 2015-06-09 10:03:04 +0000
1305@@ -49,7 +49,6 @@
1306 ReplyObject(std::static_pointer_cast<ListenerBase>(receiver), runtime, scope_id, dont_reap),
1307 receiver_(receiver),
1308 cat_registry_(new CategoryRegistry()),
1309- runtime_(runtime),
1310 cardinality_(cardinality),
1311 num_pushes_(0)
1312 {
1313@@ -113,7 +112,7 @@
1314 auto result_var = it->second.get_dict();
1315 auto impl = std::unique_ptr<internal::CategorisedResultImpl>(new internal::CategorisedResultImpl(*cat_registry_, result_var));
1316
1317- impl->set_runtime(runtime_);
1318+ impl->set_runtime(runtime());
1319 // set result origin
1320 if (impl->origin().empty())
1321 {
1322
1323=== modified file 'src/scopes/internal/ScopeConfig.cpp'
1324--- src/scopes/internal/ScopeConfig.cpp 2015-01-28 05:31:24 +0000
1325+++ src/scopes/internal/ScopeConfig.cpp 2015-06-09 10:03:04 +0000
1326@@ -23,6 +23,8 @@
1327 #include <unity/UnityExceptions.h>
1328 #include <unity/scopes/internal/Utils.h>
1329
1330+#include <boost/algorithm/string/trim.hpp>
1331+
1332 #include <algorithm>
1333 #include <sstream>
1334 #include <string>
1335@@ -48,14 +50,14 @@
1336 const string art_key = "Art";
1337 const string icon_key = "Icon";
1338 const string search_hint_key = "SearchHint";
1339- const string hot_key_key = "HotKey";
1340- const string invisible_key = "Invisible";
1341+ const string hot_key_key = "HotKey"; // Undocumented, currently unused
1342+ const string invisible_key = "Invisible"; // Deliberately undocumented
1343 const string location_data_needed_key = "LocationDataNeeded";
1344 const string scoperunner_key = "ScopeRunner";
1345 const string idle_timeout_key = "IdleTimeout";
1346 const string results_ttl_key = "ResultsTtlType";
1347- const string debug_mode_key = "DebugMode";
1348- const string child_scope_ids_key = "ChildScopes";
1349+ const string debug_mode_key = "DebugMode"; // Deliberately undocumented
1350+ const string child_scope_ids_key = "ChildScopes"; // Deprecated
1351 const string version_key = "Version";
1352 const string keywords_key = "Keywords";
1353 const string is_aggregator_key = "IsAggregator";
1354@@ -87,8 +89,25 @@
1355 }
1356
1357 display_name_ = parser()->get_locale_string(scope_config_group, scope_name_key);
1358+ boost::trim(display_name_);
1359+ if (display_name_.empty())
1360+ {
1361+ throw_ex(scope_name_key + " cannot be empty or whitespace only");
1362+ }
1363+
1364 description_ = parser()->get_locale_string(scope_config_group, description_key);
1365+ boost::trim(description_);
1366+ if (description_.empty())
1367+ {
1368+ throw_ex(description_key + " cannot be empty or whitespace only");
1369+ }
1370+
1371 author_ = parser()->get_string(scope_config_group, author_key);
1372+ boost::trim(author_);
1373+ if (author_.empty())
1374+ {
1375+ throw_ex(author_key + " cannot be empty or whitespace only");
1376+ }
1377
1378 // For optional values, we store them in a unique_ptr so we can distinguish the "not set at all" case
1379 // from the "explicitly set to empty string" case. parser()->get_string throws LogicException if
1380@@ -162,7 +181,6 @@
1381 ": value must be >= 0 and <= " + std::to_string(max_idle_timeout));
1382 }
1383
1384-
1385 results_ttl_type_ = ScopeMetadata::ResultsTtlType::None;
1386 try
1387 {
1388
1389=== modified file 'src/scopes/internal/ScopeImpl.cpp'
1390--- src/scopes/internal/ScopeImpl.cpp 2015-05-26 08:23:16 +0000
1391+++ src/scopes/internal/ScopeImpl.cpp 2015-06-09 10:03:04 +0000
1392@@ -338,6 +338,55 @@
1393 return ctrl;
1394 }
1395
1396+QueryCtrlProxy ScopeImpl::activate_result_action(Result const& result,
1397+ ActionMetadata const& metadata,
1398+ std::string const& action_id,
1399+ ActivationListenerBase::SPtr const& reply)
1400+{
1401+ if (reply == nullptr)
1402+ {
1403+ throw unity::InvalidArgumentException("Scope::activate_result_action(): invalid ActivationListenerBase (nullptr)");
1404+ }
1405+
1406+ ReplyObject::SPtr ro(make_shared<ActivationReplyObject>(reply, runtime_, to_string(), fwd()->debug_mode()));
1407+ MWReplyProxy rp = fwd()->mw_base()->add_reply_object(ro);
1408+
1409+ shared_ptr<QueryCtrlImpl> ctrl = make_shared<QueryCtrlImpl>(nullptr, rp);
1410+
1411+ auto impl = dynamic_pointer_cast<ScopeImpl>(shared_from_this());
1412+
1413+ auto send_activate_action = [impl, result, metadata, action_id, rp, ro, ctrl]() -> void
1414+ {
1415+ try
1416+ {
1417+ auto real_ctrl = dynamic_pointer_cast<QueryCtrlImpl>(impl->fwd()->activate_result_action(
1418+ result.p->activation_target(),
1419+ metadata.serialize(),
1420+ action_id,
1421+ rp));
1422+ assert(real_ctrl);
1423+
1424+ auto new_proxy = dynamic_pointer_cast<MWQueryCtrl>(real_ctrl->proxy());
1425+ assert(new_proxy);
1426+ ctrl->set_proxy(new_proxy);
1427+ }
1428+ catch (std::exception const& e)
1429+ {
1430+ try
1431+ {
1432+ ro->finished(CompletionDetails(CompletionDetails::Error, e.what()));
1433+ }
1434+ catch (...)
1435+ {
1436+ }
1437+ }
1438+ };
1439+
1440+ auto future = runtime_->async_pool()->submit(send_activate_action);
1441+ runtime_->future_queue()->push(move(future));
1442+ return ctrl;
1443+}
1444+
1445 ChildScopeList ScopeImpl::child_scopes()
1446 {
1447 return fwd()->child_scopes();
1448
1449=== modified file 'src/scopes/internal/ScopeObject.cpp'
1450--- src/scopes/internal/ScopeObject.cpp 2015-05-26 08:23:16 +0000
1451+++ src/scopes/internal/ScopeObject.cpp 2015-06-09 10:03:04 +0000
1452@@ -239,6 +239,26 @@
1453 );
1454 }
1455
1456+MWQueryCtrlProxy ScopeObject::activate_result_action(Result const& result,
1457+ ActionMetadata const& hints,
1458+ std::string const& action_id,
1459+ MWReplyProxy const &reply,
1460+ InvokeInfo const& info)
1461+{
1462+ return query(reply,
1463+ info.mw,
1464+ "activate_result_action",
1465+ [&result, &hints, &action_id, this]() -> QueryBase::SPtr {
1466+ return this->scope_base_->activate_result_action(result, hints, action_id);
1467+ },
1468+ [&reply, this](QueryBase::SPtr query_base, MWQueryCtrlProxy ctrl_proxy) -> QueryObjectBase::SPtr {
1469+ auto activation_base = dynamic_pointer_cast<ActivationQueryBase>(query_base);
1470+ assert(activation_base);
1471+ return make_shared<ActivationQueryObject>(activation_base, reply, ctrl_proxy);
1472+ }
1473+ );
1474+}
1475+
1476 MWQueryCtrlProxy ScopeObject::preview(Result const& result,
1477 ActionMetadata const& hints,
1478 MWReplyProxy const& reply,
1479
1480=== modified file 'src/scopes/internal/SettingsDB.cpp'
1481--- src/scopes/internal/SettingsDB.cpp 2015-03-02 03:59:01 +0000
1482+++ src/scopes/internal/SettingsDB.cpp 2015-06-09 10:03:04 +0000
1483@@ -348,6 +348,10 @@
1484
1485 if (thread_state_ == Idle)
1486 {
1487+ if (thread_.joinable()) {
1488+ thread_.join();
1489+ }
1490+
1491 thread_state_ = Running;
1492 thread_ = thread(&SettingsDB::watch_thread, this);
1493 }
1494
1495=== modified file 'src/scopes/internal/smartscopes/HttpClientNetCpp.cpp'
1496--- src/scopes/internal/smartscopes/HttpClientNetCpp.cpp 2015-01-19 09:15:06 +0000
1497+++ src/scopes/internal/smartscopes/HttpClientNetCpp.cpp 2015-06-09 10:03:04 +0000
1498@@ -20,8 +20,8 @@
1499
1500 #include <unity/UnityExceptions.h>
1501
1502-#include <core/net/http/client.h>
1503-#include <core/net/http/request.h>
1504+#include <core/net/http/streaming_client.h>
1505+#include <core/net/http/streaming_request.h>
1506 #include <core/net/http/response.h>
1507 #include <core/net/http/status.h>
1508
1509@@ -102,7 +102,7 @@
1510
1511 HttpClientNetCpp::HttpClientNetCpp(unsigned int no_reply_timeout)
1512 : no_reply_timeout{no_reply_timeout},
1513- client{http::make_client()},
1514+ client{http::make_streaming_client()},
1515 worker([this]() { client->run(); })
1516 {
1517 }
1518@@ -129,7 +129,7 @@
1519 }
1520 http_config.header = http_header;
1521
1522- auto request = client->get(http_config);
1523+ auto request = client->streaming_get(http_config);
1524 request->set_timeout(std::chrono::milliseconds{no_reply_timeout});
1525
1526 auto promise = std::make_shared<std::promise<void>>();
1527@@ -157,12 +157,8 @@
1528 }
1529 else
1530 {
1531- std::istringstream in(response.body);
1532- std::string line;
1533- while (std::getline(in, line))
1534- {
1535- line_data(line);
1536- }
1537+ // call line_data with empty string to signal end of chunked data
1538+ line_data("");
1539 promise->set_value();
1540 }
1541 })
1542@@ -170,7 +166,11 @@
1543 {
1544 unity::ResourceException re(e.what());
1545 promise->set_exception(std::make_exception_ptr(re));
1546- }));
1547+ }),
1548+ [line_data](const std::string& const_data)
1549+ {
1550+ line_data(const_data);
1551+ });
1552
1553 return std::make_shared<HttpResponseHandle>(
1554 shared_from_this(),
1555
1556=== modified file 'src/scopes/internal/smartscopes/SSScopeObject.cpp'
1557--- src/scopes/internal/smartscopes/SSScopeObject.cpp 2015-03-25 05:52:25 +0000
1558+++ src/scopes/internal/smartscopes/SSScopeObject.cpp 2015-06-09 10:03:04 +0000
1559@@ -109,6 +109,20 @@
1560 { qo_->add_query(SSQuery::Activation, query_base, reply); });
1561 }
1562
1563+MWQueryCtrlProxy SSScopeObject::activate_result_action(Result const& result,
1564+ ActionMetadata const& hints,
1565+ std::string const& action_id,
1566+ MWReplyProxy const& reply,
1567+ InvokeInfo const& info)
1568+{
1569+ return query(info,
1570+ reply,
1571+ [&result, &hints, &info, &action_id, this ]()->QueryBase::SPtr
1572+ { return this->smartscope_->activate_result_action(info.id, result, hints, action_id); },
1573+ [&reply, &info, this](QueryBase::SPtr query_base)
1574+ { qo_->add_query(SSQuery::Activation, query_base, reply); });
1575+}
1576+
1577 MWQueryCtrlProxy SSScopeObject::preview(Result const& result,
1578 ActionMetadata const& hints,
1579 MWReplyProxy const& reply,
1580
1581=== modified file 'src/scopes/internal/smartscopes/SmartScope.cpp'
1582--- src/scopes/internal/smartscopes/SmartScope.cpp 2015-01-09 03:16:51 +0000
1583+++ src/scopes/internal/smartscopes/SmartScope.cpp 2015-06-09 10:03:04 +0000
1584@@ -50,18 +50,6 @@
1585
1586 void SmartQuery::run(SearchReplyProxy const& reply)
1587 {
1588- static const std::string no_net_hint("no-internet");
1589- if (hints_.contains_hint(no_net_hint))
1590- {
1591- auto var = hints_[no_net_hint];
1592- if (var.which() == Variant::Type::Bool && var.get_bool())
1593- {
1594- BOOST_LOG_SEV(ss_client_->logger(), Logger::Info)
1595- << "SmartQuery(): networking disabled for remote scope " << scope_id_ << ", skipping";
1596- return;
1597- }
1598- }
1599-
1600 struct FiltersHandler
1601 {
1602 FiltersHandler(SearchReplyProxy reply, std::string const& scope_id):
1603@@ -373,3 +361,12 @@
1604 << "SmartScope: created activation for \"" << scope_id << "\": \"" << result.uri() << "\"";
1605 return activation;
1606 }
1607+
1608+ActivationQueryBase::UPtr SmartScope::activate_result_action(std::string const& scope_id, Result const& result, ActionMetadata const& metadata, std::string const& action_id)
1609+{
1610+ // NOTE: there is no endpoint for it really, SmartActivation is a no-op (not-handled)
1611+ ActivationQueryBase::UPtr activation(new SmartActivation(result, metadata, "", action_id));
1612+ BOOST_LOG_SEV(ss_client_->logger(), Logger::Info)
1613+ << "SmartScope: created result action activation for \"" << scope_id << "\": \"" << result.uri() << "\", action_id=" << action_id;
1614+ return activation;
1615+}
1616
1617=== modified file 'src/scopes/internal/smartscopes/SmartScopesClient.cpp'
1618--- src/scopes/internal/smartscopes/SmartScopesClient.cpp 2015-04-10 03:55:25 +0000
1619+++ src/scopes/internal/smartscopes/SmartScopesClient.cpp 2015-06-09 10:03:04 +0000
1620@@ -472,18 +472,17 @@
1621 headers.push_back(std::make_pair("User-Agent", user_agent_hdr));
1622 }
1623
1624- auto reponse_mutex = std::make_shared<std::mutex>();
1625- query_results_[search_id] = http_client_->get(search_uri.str(), [this, handler, reponse_mutex](std::string const& line_data)
1626+ auto tmp_data = std::make_shared<std::string>();
1627+ query_results_[search_id] = http_client_->get(search_uri.str(), [this, tmp_data, handler](std::string const& chunk)
1628 {
1629- std::lock_guard<std::mutex> lock(*reponse_mutex);
1630- try
1631- {
1632- parse_line(line_data, handler);
1633- }
1634- catch (std::exception const &e)
1635- {
1636- BOOST_LOG_SEV(logger_, Logger::Error) << "SmartScopesClient.search(): Failed to parse: " << e.what();
1637- }
1638+ // prepend any leftover data from the previous handle_chunk call
1639+ std::string data = *tmp_data + (chunk.empty() ? "\n" : chunk);
1640+
1641+ // store the leftover data from the handle_chunk call into tmp_data
1642+ *tmp_data = handle_chunk(data, [this, handler](const std::string& line)
1643+ {
1644+ handle_line(line, handler);
1645+ });
1646 }, headers);
1647
1648 return SearchHandle::UPtr(new SearchHandle(search_id, shared_from_this()));
1649@@ -540,24 +539,54 @@
1650
1651 BOOST_LOG_SEV(logger_, Logger::Info) << "SmartScopesClient.preview(): GET " << preview_uri.str();
1652
1653- auto reponse_mutex = std::make_shared<std::mutex>();
1654- query_results_[preview_id] = http_client_->get(preview_uri.str(), [this, handler, reponse_mutex](std::string const& line_data)
1655+ auto tmp_data = std::make_shared<std::string>();
1656+ query_results_[preview_id] = http_client_->get(preview_uri.str(), [this, tmp_data, handler](std::string const& chunk)
1657 {
1658- std::lock_guard<std::mutex> lock(*reponse_mutex);
1659- try
1660- {
1661- parse_line(line_data, handler);
1662- }
1663- catch (std::exception const &e)
1664- {
1665- BOOST_LOG_SEV(logger_, Logger::Error) << "SmartScopesClient.preview(): Failed to parse: " << e.what();
1666- }
1667+ // prepend any leftover data from the previous handle_chunk call
1668+ std::string data = *tmp_data + (chunk.empty() ? "\n" : chunk);
1669+
1670+ // store the leftover data from the handle_chunk call into tmp_data
1671+ *tmp_data = handle_chunk(data, [this, handler](const std::string& line)
1672+ {
1673+ handle_line(line, handler);
1674+ });
1675 }, headers);
1676
1677 return PreviewHandle::UPtr(new PreviewHandle(preview_id, shared_from_this()));
1678 }
1679
1680-void SmartScopesClient::parse_line(std::string const& json, PreviewReplyHandler const& handler)
1681+std::string SmartScopesClient::handle_chunk(const std::string& chunk, std::function<void(const std::string&)> line_handler)
1682+{
1683+ // According to the docs, we expect:
1684+ // The response will have Content-Type
1685+ // application/json, it will be a chunked response, in practice a series of
1686+ // “\r\n” delimited lines, each containing one JSON object, with the
1687+ // possible forms, matching what currently can be pushed into a reply in the
1688+ // new scopes API
1689+ static constexpr const char separator{'\n'};
1690+
1691+ // read data line-by-line calling line_handler() for each
1692+ auto newline_pos = 0;
1693+ auto endline_pos = chunk.find(separator);
1694+ while (endline_pos != std::string::npos)
1695+ {
1696+ try
1697+ {
1698+ line_handler(chunk.substr(newline_pos, endline_pos - newline_pos));
1699+ }
1700+ catch (std::exception const &e)
1701+ {
1702+ BOOST_LOG_SEV(logger_, Logger::Error) << "SmartScopesClient.handle_chunk(): Failed to parse line: " << e.what();
1703+ }
1704+ newline_pos = endline_pos + 1;
1705+ endline_pos = chunk.find(separator, newline_pos);
1706+ }
1707+
1708+ // return the leftover data
1709+ return chunk.substr(newline_pos, chunk.size() - newline_pos);
1710+}
1711+
1712+void SmartScopesClient::handle_line(std::string const& json, PreviewReplyHandler const& handler)
1713 {
1714 JsonNodeInterface::SPtr root_node;
1715 JsonNodeInterface::SPtr child_node;
1716@@ -605,7 +634,7 @@
1717 }
1718 }
1719
1720-void SmartScopesClient::parse_line(std::string const& json, SearchReplyHandler const& handler)
1721+void SmartScopesClient::handle_line(std::string const& json, SearchReplyHandler const& handler)
1722 {
1723 JsonNodeInterface::SPtr root_node;
1724 JsonNodeInterface::SPtr child_node;
1725
1726=== modified file 'src/scopes/internal/zmq_middleware/ScopeI.cpp'
1727--- src/scopes/internal/zmq_middleware/ScopeI.cpp 2015-04-01 09:00:01 +0000
1728+++ src/scopes/internal/zmq_middleware/ScopeI.cpp 2015-06-09 10:03:04 +0000
1729@@ -76,6 +76,7 @@
1730 { "preview", bind(&ScopeI::preview_, this, ph::_1, ph::_2, ph::_3) },
1731 { "activate", bind(&ScopeI::activate_, this, ph::_1, ph::_2, ph::_3) },
1732 { "perform_action", bind(&ScopeI::perform_action_, this, ph::_1, ph::_2, ph::_3) },
1733+ { "activate_result_action", bind(&ScopeI::activate_result_action_, this, ph::_1, ph::_2, ph::_3) },
1734 { "child_scopes", bind(&ScopeI::child_scopes_, this, ph::_1, ph::_2, ph::_3) },
1735 { "set_child_scopes", bind(&ScopeI::set_child_scopes_, this, ph::_1, ph::_2, ph::_3) },
1736 { "debug_mode", bind(&ScopeI::debug_mode_, this, ph::_1, ph::_2, ph::_3) }
1737@@ -201,6 +202,35 @@
1738 p.setCategory(ctrl_proxy->target_category().c_str());
1739 }
1740
1741+void ScopeI::activate_result_action_(Current const& current,
1742+ capnp::AnyPointer::Reader& in_params,
1743+ capnproto::Response::Builder& r)
1744+{
1745+ auto req = in_params.getAs<capnproto::Scope::ResultActionActivationRequest>();
1746+ auto result = ResultImpl::create_result(to_variant_map(req.getResult()));
1747+ auto metadata = ActionMetadataImpl::create(to_variant_map(req.getHints()));
1748+ auto proxy = req.getReplyProxy();
1749+ auto action_id = req.getActionId().cStr();
1750+ ZmqReplyProxy reply_proxy(new ZmqReply(current.adapter->mw(),
1751+ proxy.getEndpoint().cStr(),
1752+ proxy.getIdentity().cStr(),
1753+ proxy.getCategory().cStr()));
1754+ auto delegate = dynamic_pointer_cast<ScopeObjectBase>(del());
1755+ assert(delegate);
1756+ auto ctrl_proxy = dynamic_pointer_cast<ZmqQueryCtrl>(delegate->activate_result_action(result,
1757+ metadata,
1758+ action_id,
1759+ reply_proxy,
1760+ to_info(current)));
1761+ assert(ctrl_proxy);
1762+ r.setStatus(capnproto::ResponseStatus::SUCCESS);
1763+ auto search_response = r.initPayload().getAs<capnproto::Scope::CreateQueryResponse>();
1764+ auto p = search_response.initReturnValue();
1765+ p.setEndpoint(ctrl_proxy->endpoint().c_str());
1766+ p.setIdentity(ctrl_proxy->identity().c_str());
1767+ p.setCategory(ctrl_proxy->target_category().c_str());
1768+}
1769+
1770 void ScopeI::child_scopes_(Current const&,
1771 capnp::AnyPointer::Reader&,
1772 capnproto::Response::Builder& r)
1773
1774=== modified file 'src/scopes/internal/zmq_middleware/ZmqConfig.cpp'
1775--- src/scopes/internal/zmq_middleware/ZmqConfig.cpp 2014-08-04 06:31:27 +0000
1776+++ src/scopes/internal/zmq_middleware/ZmqConfig.cpp 2015-06-09 10:03:04 +0000
1777@@ -42,6 +42,7 @@
1778 const string twoway_timeout_key = "Default.Twoway.Timeout";
1779 const string locate_timeout_key = "Locate.Timeout";
1780 const string registry_timeout_key = "Registry.Timeout";
1781+ const string child_scopes_timeout_key = "ChildScopes.Timeout";
1782 const string registry_endpoint_dir_key = "Registry.EndpointDir";
1783 const string ss_registry_endpoint_dir_key = "Smartscopes.Registry.EndpointDir";
1784 }
1785@@ -90,6 +91,12 @@
1786 throw_ex("Illegal value (" + to_string(locate_timeout_) + ") for " + locate_timeout_key + ": value must be 10-15000");
1787 }
1788
1789+ child_scopes_timeout_ = get_optional_int(zmq_config_group, child_scopes_timeout_key, DFLT_ZMQ_CHILDSCOPES_TIMEOUT);
1790+ if (child_scopes_timeout_ < 10 || child_scopes_timeout_ > 15000)
1791+ {
1792+ throw_ex("Illegal value (" + to_string(child_scopes_timeout_) + ") for " + child_scopes_timeout_key + ": value must be 10-15000");
1793+ }
1794+
1795 registry_endpoint_dir_ = get_optional_string(zmq_config_group, registry_endpoint_dir_key);
1796 ss_registry_endpoint_dir_ = get_optional_string(zmq_config_group, ss_registry_endpoint_dir_key);
1797
1798@@ -100,6 +107,7 @@
1799 twoway_timeout_key,
1800 locate_timeout_key,
1801 registry_timeout_key,
1802+ child_scopes_timeout_key,
1803 registry_endpoint_dir_key,
1804 ss_registry_endpoint_dir_key
1805 }
1806@@ -132,6 +140,11 @@
1807 return registry_timeout_;
1808 }
1809
1810+int ZmqConfig::child_scopes_timeout() const
1811+{
1812+ return child_scopes_timeout_;
1813+}
1814+
1815 string ZmqConfig::registry_endpoint_dir() const
1816 {
1817 return registry_endpoint_dir_;
1818
1819=== modified file 'src/scopes/internal/zmq_middleware/ZmqMiddleware.cpp'
1820--- src/scopes/internal/zmq_middleware/ZmqMiddleware.cpp 2015-01-23 05:00:02 +0000
1821+++ src/scopes/internal/zmq_middleware/ZmqMiddleware.cpp 2015-06-09 10:03:04 +0000
1822@@ -107,6 +107,7 @@
1823 twoway_timeout_ = config.twoway_timeout();
1824 locate_timeout_ = config.locate_timeout();
1825 registry_timeout_ = config.registry_timeout();
1826+ child_scopes_timeout_ = config.child_scopes_timeout();
1827 public_endpoint_dir_ = config.endpoint_dir();
1828 private_endpoint_dir_ = public_endpoint_dir_ + "/priv";
1829 registry_endpoint_dir_ = public_endpoint_dir_;
1830@@ -814,6 +815,11 @@
1831 return registry_timeout_;
1832 }
1833
1834+int64_t ZmqMiddleware::child_scopes_timeout() const noexcept
1835+{
1836+ return child_scopes_timeout_;
1837+}
1838+
1839 ObjectProxy ZmqMiddleware::make_typed_proxy(string const& endpoint,
1840 string const& identity,
1841 string const& category,
1842
1843=== modified file 'src/scopes/internal/zmq_middleware/ZmqScope.cpp'
1844--- src/scopes/internal/zmq_middleware/ZmqScope.cpp 2015-04-01 09:28:20 +0000
1845+++ src/scopes/internal/zmq_middleware/ZmqScope.cpp 2015-06-09 10:03:04 +0000
1846@@ -178,6 +178,40 @@
1847 return make_shared<QueryCtrlImpl>(p, reply_proxy);
1848 }
1849
1850+QueryCtrlProxy ZmqScope::activate_result_action(VariantMap const& result,
1851+ VariantMap const& hints,
1852+ std::string const& action_id,
1853+ MWReplyProxy const& reply)
1854+{
1855+ capnp::MallocMessageBuilder request_builder;
1856+ auto reply_proxy = dynamic_pointer_cast<ZmqReply>(reply);
1857+ {
1858+ auto request = make_request_(request_builder, "activate_result_action");
1859+ auto in_params = request.initInParams().getAs<capnproto::Scope::ResultActionActivationRequest>();
1860+ auto res = in_params.initResult();
1861+ to_value_dict(result, res);
1862+ auto h = in_params.initHints();
1863+ to_value_dict(hints, h);
1864+ in_params.setActionId(action_id);
1865+ auto p = in_params.initReplyProxy();
1866+ p.setEndpoint(reply_proxy->endpoint().c_str());
1867+ p.setIdentity(reply_proxy->identity().c_str());
1868+ }
1869+
1870+ auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder); });
1871+
1872+ auto out_params = future.get();
1873+ auto response = out_params.reader->getRoot<capnproto::Response>();
1874+ throw_if_runtime_exception(response);
1875+
1876+ auto proxy = response.getPayload().getAs<capnproto::Scope::CreateQueryResponse>().getReturnValue();
1877+ ZmqQueryCtrlProxy p(new ZmqQueryCtrl(mw_base(),
1878+ proxy.getEndpoint().cStr(),
1879+ proxy.getIdentity().cStr(),
1880+ proxy.getCategory().cStr()));
1881+ return make_shared<QueryCtrlImpl>(p, reply_proxy);
1882+}
1883+
1884 QueryCtrlProxy ZmqScope::preview(VariantMap const& result, VariantMap const& hints, MWReplyProxy const& reply)
1885 {
1886 capnp::MallocMessageBuilder request_builder;
1887@@ -213,7 +247,8 @@
1888 capnp::MallocMessageBuilder request_builder;
1889 make_request_(request_builder, "child_scopes");
1890
1891- auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder); });
1892+ int64_t timeout = mw_base()->child_scopes_timeout();
1893+ auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder, timeout); });
1894
1895 auto out_params = future.get();
1896 auto response = out_params.reader->getRoot<capnproto::Response>();
1897@@ -270,7 +305,8 @@
1898 }
1899 }
1900
1901- auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder); });
1902+ int64_t timeout = mw_base()->child_scopes_timeout();
1903+ auto future = mw_base()->twoway_pool()->submit([&] { return this->invoke_scope_(request_builder, timeout); });
1904 auto out_params = future.get();
1905 auto r = out_params.reader->getRoot<capnproto::Response>();
1906 throw_if_runtime_exception(r);
1907@@ -303,13 +339,18 @@
1908
1909 ZmqObjectProxy::TwowayOutParams ZmqScope::invoke_scope_(capnp::MessageBuilder& in_params)
1910 {
1911+ return invoke_scope_(in_params, timeout());
1912+}
1913+
1914+ZmqObjectProxy::TwowayOutParams ZmqScope::invoke_scope_(capnp::MessageBuilder& in_params, int64_t timeout)
1915+{
1916 // Check if this scope has requested debug mode, if so, disable two-way timeout and set
1917 // locate timeout to 15s.
1918 if (debug_mode())
1919 {
1920 return this->invoke_twoway_(in_params, -1, 15000);
1921 }
1922- return this->invoke_twoway_(in_params);
1923+ return this->invoke_twoway_(in_params, timeout);
1924 }
1925
1926 } // namespace zmq_middleware
1927
1928=== modified file 'src/scopes/internal/zmq_middleware/capnproto/Scope.capnp'
1929--- src/scopes/internal/zmq_middleware/capnproto/Scope.capnp 2015-04-01 09:00:01 +0000
1930+++ src/scopes/internal/zmq_middleware/capnproto/Scope.capnp 2015-06-09 10:03:04 +0000
1931@@ -59,6 +59,14 @@
1932 replyProxy @4 : Proxy.Proxy;
1933 }
1934
1935+struct ResultActionActivationRequest
1936+{
1937+ result @0 : ValueDict.ValueDict;
1938+ hints @1 : ValueDict.ValueDict;
1939+ actionId @2 : Text;
1940+ replyProxy @3 : Proxy.Proxy;
1941+}
1942+
1943 struct PreviewRequest
1944 {
1945 result @0 : ValueDict.ValueDict;
1946
1947=== modified file 'test/gtest/scopes/Activation/Activation_test.cpp'
1948--- test/gtest/scopes/Activation/Activation_test.cpp 2015-01-09 03:16:51 +0000
1949+++ test/gtest/scopes/Activation/Activation_test.cpp 2015-06-09 10:03:04 +0000
1950@@ -604,6 +604,50 @@
1951 EXPECT_EQ("widget1action1", response->scope_data().get_dict()["activated action"].get_string());
1952 EXPECT_EQ("maiden", response->scope_data().get_dict()["received_hints"].get_dict()["iron"].get_string());
1953 EXPECT_EQ("uri", response->scope_data().get_dict()["activated_uri"].get_string());
1954+ }
1955+}
1956+
1957+TEST(Activation, result_action)
1958+{
1959+ auto reg_rt = run_test_registry();
1960+
1961+ auto scope_rt = Runtime::create_scope_runtime("TestScope", TEST_DIR "/Runtime.ini");
1962+ RaiiScopeThread<TestScope> scope_thread(move(scope_rt));
1963+
1964+ // parent: connect to scope and run a query
1965+ auto rt = internal::RuntimeImpl::create("", TEST_DIR "/Runtime.ini");
1966+ auto mw = rt->factory()->create("TestScope", "Zmq", TEST_DIR "/Zmq.ini");
1967+ mw->start();
1968+ auto proxy = mw->create_scope_proxy("TestScope");
1969+ auto scope = internal::ScopeImpl::create(proxy, "TestScope");
1970+
1971+ VariantMap hints;
1972+ auto receiver = std::make_shared<SearchReceiver>();
1973+ auto ctrl = scope->search("test", SearchMetadata("pl", "phone"), receiver);
1974+ receiver->wait_until_finished();
1975+
1976+ auto result = receiver->result;
1977+ ASSERT_TRUE(result != nullptr);
1978+
1979+ auto target = result->target_scope_proxy();
1980+ EXPECT_TRUE(target != nullptr);
1981+
1982+ // activate result action
1983+ {
1984+ auto act_receiver = std::make_shared<ActivationReceiver>();
1985+ ActionMetadata meta("en", "phone");
1986+ hints["iron"] = "maiden";
1987+ meta.set_scope_data(Variant(hints));
1988+ ctrl = target->activate_result_action(*result, meta, "action1", act_receiver);
1989+ act_receiver->wait_until_finished();
1990+
1991+ auto response = act_receiver->response;
1992+ EXPECT_TRUE(response != nullptr);
1993+ EXPECT_EQ(ActivationResponse::Status::UpdateResult, response->status());
1994+ EXPECT_EQ("uri", response->updated_result().uri());
1995+ ASSERT_NO_THROW(response->updated_result().target_scope_proxy());
1996+ EXPECT_EQ("action1", response->scope_data().get_dict()["activated result action"].get_string());
1997+ EXPECT_EQ("maiden", response->scope_data().get_dict()["received_hints"].get_dict()["iron"].get_string());
1998 }
1999 }
2000
2001
2002=== modified file 'test/gtest/scopes/Activation/TestScope.h'
2003--- test/gtest/scopes/Activation/TestScope.h 2014-11-03 05:31:30 +0000
2004+++ test/gtest/scopes/Activation/TestScope.h 2015-06-09 10:03:04 +0000
2005@@ -94,6 +94,32 @@
2006 Variant recv_hints_;
2007 };
2008
2009+class TestInCardActivation : public ActivationQueryBase
2010+{
2011+public:
2012+ TestInCardActivation(Result const& result, ActionMetadata const& metadata, std::string const& action_id,
2013+ std::string const& hint, std::string const& hint_val)
2014+ : ActivationQueryBase(result, metadata, action_id),
2015+ hint_key_(hint),
2016+ hint_val_(hint_val)
2017+ {
2018+ }
2019+
2020+ virtual ActivationResponse activate() override
2021+ {
2022+ ActivationResponse resp(result());
2023+ VariantMap var;
2024+ var[hint_key_] = hint_val_;
2025+ var["received_hints"] = action_metadata().scope_data(); // send received hints back for testing
2026+ resp.set_scope_data(Variant(var));
2027+ return resp;
2028+ }
2029+
2030+private:
2031+ std::string hint_key_;
2032+ std::string hint_val_;
2033+};
2034+
2035 class TestScope : public ScopeBase
2036 {
2037 public:
2038@@ -122,6 +148,11 @@
2039 {
2040 return ActivationQueryBase::UPtr(new TestActivation(result, hints, widget_id, action_id, "activated action", widget_id + action_id, result.uri(), hints.scope_data()));
2041 }
2042+
2043+ virtual ActivationQueryBase::UPtr activate_result_action(Result const& result, ActionMetadata const& hints, std::string const& action_id) override
2044+ {
2045+ return ActivationQueryBase::UPtr(new TestInCardActivation(result, hints, action_id, "activated result action", action_id));
2046+ }
2047 };
2048
2049 } // namespace scopes
2050
2051=== modified file 'test/gtest/scopes/ActivationResponse/ActivationResponse_test.cpp'
2052--- test/gtest/scopes/ActivationResponse/ActivationResponse_test.cpp 2014-02-27 16:58:50 +0000
2053+++ test/gtest/scopes/ActivationResponse/ActivationResponse_test.cpp 2015-06-09 10:03:04 +0000
2054@@ -19,6 +19,8 @@
2055 #include <unity/scopes/ActivationResponse.h>
2056 #include <unity/scopes/CannedQuery.h>
2057 #include <unity/scopes/internal/ActivationResponseImpl.h>
2058+#include <unity/scopes/internal/ResultImpl.h>
2059+#include <unity/scopes/internal/RuntimeImpl.h>
2060 #include <unity/UnityExceptions.h>
2061 #include <gtest/gtest.h>
2062
2063@@ -53,6 +55,19 @@
2064 ActivationResponse resp(query);
2065 EXPECT_EQ(ActivationResponse::Status::PerformQuery, resp.status());
2066 }
2067+ {
2068+ VariantMap vm;
2069+ VariantMap attrs;
2070+ attrs["uri"] = "foo";
2071+ vm["internal"] = Variant(VariantMap());
2072+ vm["attrs"] = Variant(attrs);
2073+ auto const res = ResultImpl::create_result(vm);
2074+
2075+ ActivationResponse resp(res);
2076+ EXPECT_EQ(ActivationResponse::Status::UpdateResult, resp.status());
2077+ EXPECT_EQ(res.uri(), resp.updated_result().uri());
2078+ }
2079+
2080
2081 // Search only allowed with CannedQuery
2082 {
2083@@ -63,6 +78,16 @@
2084 }
2085 catch (unity::InvalidArgumentException const&) {}
2086 }
2087+
2088+ // UpdateResult only allowed with Result
2089+ {
2090+ try
2091+ {
2092+ ActivationResponse resp(ActivationResponse::Status::UpdateResult);
2093+ FAIL();
2094+ }
2095+ catch (unity::InvalidArgumentException const&) {}
2096+ }
2097 }
2098
2099 TEST(ActivationResponse, serialize)
2100@@ -85,16 +110,32 @@
2101 EXPECT_EQ(ActivationResponse::Status::PerformQuery, static_cast<ActivationResponse::Status>(var["status"].get_int()));
2102 EXPECT_EQ("scope-foo", var["query"].get_dict()["scope"].get_string());
2103 }
2104+ {
2105+ VariantMap vm;
2106+ VariantMap attrs;
2107+ attrs["uri"] = Variant("foo");
2108+ vm["internal"] = Variant(VariantMap());
2109+ vm["attrs"] = Variant(attrs);
2110+ auto const res = ResultImpl::create_result(vm);
2111+
2112+ ActivationResponse resp(res);
2113+ auto var = resp.serialize();
2114+ EXPECT_EQ(ActivationResponse::Status::UpdateResult, static_cast<ActivationResponse::Status>(var["status"].get_int()));
2115+ EXPECT_EQ("foo", var["updated_result"].get_dict()["attrs"].get_dict()["uri"].get_string());
2116+ }
2117 }
2118
2119 TEST(ActivationResponse, deserialize)
2120 {
2121+ // just to make ResultImpl::set_runtime() happy, runtime must not be null.
2122+ auto runtime = internal::RuntimeImpl::create("fooscope", TEST_DIR "/Runtime.ini");
2123+
2124 // invalid variant
2125 {
2126 VariantMap var;
2127 try
2128 {
2129- internal::ActivationResponseImpl res(var);
2130+ internal::ActivationResponseImpl res(var, runtime.get());
2131 FAIL();
2132 }
2133 catch (unity::LogicException const &e)
2134@@ -108,7 +149,7 @@
2135 var["scope_data"] = VariantMap();
2136 try
2137 {
2138- internal::ActivationResponseImpl::create(var);
2139+ internal::ActivationResponseImpl::create(var, runtime.get());
2140 FAIL();
2141 }
2142 catch (unity::LogicException const &e)
2143@@ -125,7 +166,7 @@
2144 var["status"] = static_cast<int>(ActivationResponse::Status::PerformQuery);
2145 try
2146 {
2147- internal::ActivationResponseImpl res(var);
2148+ internal::ActivationResponseImpl res(var, runtime.get());
2149 FAIL();
2150 }
2151 catch (unity::LogicException const &e) {}
2152@@ -140,7 +181,7 @@
2153 var["status"] = static_cast<int>(ActivationResponse::Status::HideDash);
2154 try
2155 {
2156- internal::ActivationResponseImpl res(var);
2157+ internal::ActivationResponseImpl res(var, runtime.get());
2158 EXPECT_EQ("bar", res.scope_data().get_dict()["foo"].get_string());
2159 EXPECT_EQ(ActivationResponse::Status::HideDash, res.status());
2160 }
2161@@ -159,7 +200,7 @@
2162 var["query"] = query.serialize();
2163 try
2164 {
2165- internal::ActivationResponseImpl res(var);
2166+ internal::ActivationResponseImpl res(var, runtime.get());
2167 EXPECT_EQ(ActivationResponse::Status::PerformQuery, res.status());
2168 EXPECT_EQ("scope-foo", res.query().scope_id());
2169 }
2170@@ -176,7 +217,7 @@
2171 var["status"] = static_cast<int>(ActivationResponse::Status::HideDash);
2172 try
2173 {
2174- internal::ActivationResponseImpl res(var);
2175+ internal::ActivationResponseImpl res(var, runtime.get());
2176 EXPECT_EQ("foobar", res.scope_data().get_string());
2177 EXPECT_EQ(ActivationResponse::Status::HideDash, res.status());
2178 }
2179
2180=== modified file 'test/gtest/scopes/ActivationResponse/CMakeLists.txt'
2181--- test/gtest/scopes/ActivationResponse/CMakeLists.txt 2014-01-15 11:29:22 +0000
2182+++ test/gtest/scopes/ActivationResponse/CMakeLists.txt 2015-06-09 10:03:04 +0000
2183@@ -1,4 +1,9 @@
2184 add_executable(ActivationResponse_test ActivationResponse_test.cpp)
2185+add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}")
2186 target_link_libraries(ActivationResponse_test ${TESTLIBS})
2187
2188+configure_file(Registry.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Registry.ini)
2189+configure_file(Runtime.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Runtime.ini)
2190+configure_file(Zmq.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Zmq.ini)
2191+
2192 add_test(ActivationResponse ActivationResponse_test)
2193
2194=== added file 'test/gtest/scopes/ActivationResponse/Registry.ini.in'
2195--- test/gtest/scopes/ActivationResponse/Registry.ini.in 1970-01-01 00:00:00 +0000
2196+++ test/gtest/scopes/ActivationResponse/Registry.ini.in 2015-06-09 10:03:04 +0000
2197@@ -0,0 +1,6 @@
2198+[Registry]
2199+Middleware = Zmq
2200+Zmq.ConfigFile = @CMAKE_CURRENT_BINARY_DIR@/Zmq.ini
2201+Scope.InstallDir = /unused
2202+Click.InstallDir = /unused
2203+Scoperunner.Path = /unused
2204
2205=== added file 'test/gtest/scopes/ActivationResponse/Runtime.ini.in'
2206--- test/gtest/scopes/ActivationResponse/Runtime.ini.in 1970-01-01 00:00:00 +0000
2207+++ test/gtest/scopes/ActivationResponse/Runtime.ini.in 2015-06-09 10:03:04 +0000
2208@@ -0,0 +1,6 @@
2209+[Runtime]
2210+Registry.Identity = TestRegistry
2211+Registry.ConfigFile = @CMAKE_CURRENT_BINARY_DIR@/Registry.ini
2212+Default.Middleware = Zmq
2213+Zmq.ConfigFile = @CMAKE_CURRENT_BINARY_DIR@/Zmq.ini
2214+LogDir=
2215
2216=== added file 'test/gtest/scopes/ActivationResponse/Zmq.ini.in'
2217--- test/gtest/scopes/ActivationResponse/Zmq.ini.in 1970-01-01 00:00:00 +0000
2218+++ test/gtest/scopes/ActivationResponse/Zmq.ini.in 2015-06-09 10:03:04 +0000
2219@@ -0,0 +1,2 @@
2220+[Zmq]
2221+EndpointDir = /tmp
2222
2223=== modified file 'test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp'
2224--- test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp 2015-04-09 15:59:17 +0000
2225+++ test/gtest/scopes/internal/RegistryObject/RegistryObject_test.cpp 2015-06-09 10:03:04 +0000
2226@@ -101,6 +101,10 @@
2227 SearchMetadata const&,
2228 SearchListenerBase::SPtr const&));
2229 MOCK_METHOD1(set_child_scopes, bool(ChildScopeList const&));
2230+ MOCK_METHOD4(activate_result_action, QueryCtrlProxy(unity::scopes::Result const&,
2231+ ActionMetadata const&,
2232+ std::string const&,
2233+ ActivationListenerBase::SPtr const&));
2234 };
2235
2236
2237
2238=== modified file 'test/gtest/scopes/internal/ScopeConfig/CMakeLists.txt'
2239--- test/gtest/scopes/internal/ScopeConfig/CMakeLists.txt 2014-12-03 06:53:40 +0000
2240+++ test/gtest/scopes/internal/ScopeConfig/CMakeLists.txt 2015-06-09 10:03:04 +0000
2241@@ -11,6 +11,9 @@
2242 configure_file(bad_keywords.ini.in bad_keywords.ini copyonly)
2243 configure_file(empty_keywords.ini.in empty_keywords.ini copyonly)
2244 configure_file(single_keyword.ini.in single_keyword.ini copyonly)
2245+configure_file(empty_display_name.ini.in empty_display_name.ini copyonly)
2246+configure_file(empty_description.ini.in empty_description.ini copyonly)
2247+configure_file(empty_author.ini.in empty_author.ini copyonly)
2248
2249 add_definitions(-DCOMPLETE_CONFIG="${CMAKE_CURRENT_BINARY_DIR}/complete_config.ini")
2250 add_definitions(-DMANDATORY_CONFIG="${CMAKE_CURRENT_BINARY_DIR}/mandatory_config.ini")
2251@@ -25,6 +28,9 @@
2252 add_definitions(-DBAD_KEYWORDS="${CMAKE_CURRENT_BINARY_DIR}/bad_keywords.ini")
2253 add_definitions(-DEMPTY_KEYWORDS="${CMAKE_CURRENT_BINARY_DIR}/empty_keywords.ini")
2254 add_definitions(-DSINGLE_KEYWORD="${CMAKE_CURRENT_BINARY_DIR}/single_keyword.ini")
2255+add_definitions(-DEMPTY_DISPLAY_NAME="${CMAKE_CURRENT_BINARY_DIR}/empty_display_name.ini")
2256+add_definitions(-DEMPTY_DESCRIPTION="${CMAKE_CURRENT_BINARY_DIR}/empty_description.ini")
2257+add_definitions(-DEMPTY_AUTHOR="${CMAKE_CURRENT_BINARY_DIR}/empty_author.ini")
2258
2259 add_executable(ScopeConfig_test ScopeConfig_test.cpp)
2260 target_link_libraries(ScopeConfig_test ${TESTLIBS})
2261
2262=== modified file 'test/gtest/scopes/internal/ScopeConfig/ScopeConfig_test.cpp'
2263--- test/gtest/scopes/internal/ScopeConfig/ScopeConfig_test.cpp 2015-01-27 12:46:11 +0000
2264+++ test/gtest/scopes/internal/ScopeConfig/ScopeConfig_test.cpp 2015-06-09 10:03:04 +0000
2265@@ -125,6 +125,7 @@
2266 try
2267 {
2268 ScopeConfig cfg(BAD_CHILD_IDS);
2269+ FAIL();
2270 }
2271 catch(ConfigException const& e)
2272 {
2273@@ -193,6 +194,7 @@
2274 try
2275 {
2276 ScopeConfig cfg(BAD_KEYWORDS);
2277+ FAIL();
2278 }
2279 catch(ConfigException const& e)
2280 {
2281@@ -213,6 +215,48 @@
2282 EXPECT_EQ(cfg.keywords().size(), 1);
2283 }
2284
2285+TEST(ScopeConfig, empty_display_name)
2286+{
2287+ try
2288+ {
2289+ ScopeConfig cfg(EMPTY_DISPLAY_NAME);
2290+ FAIL();
2291+ }
2292+ catch(ConfigException const& e)
2293+ {
2294+ boost::regex r("unity::scopes::ConfigException: \".*\": DisplayName cannot be empty or whitespace only");
2295+ EXPECT_TRUE(boost::regex_match(e.what(), r));
2296+ }
2297+}
2298+
2299+TEST(ScopeConfig, empty_description)
2300+{
2301+ try
2302+ {
2303+ ScopeConfig cfg(EMPTY_DESCRIPTION);
2304+ FAIL();
2305+ }
2306+ catch(ConfigException const& e)
2307+ {
2308+ boost::regex r("unity::scopes::ConfigException: \".*\": Description cannot be empty or whitespace only");
2309+ EXPECT_TRUE(boost::regex_match(e.what(), r));
2310+ }
2311+}
2312+
2313+TEST(ScopeConfig, empty_author)
2314+{
2315+ try
2316+ {
2317+ ScopeConfig cfg(EMPTY_AUTHOR);
2318+ FAIL();
2319+ }
2320+ catch(ConfigException const& e)
2321+ {
2322+ boost::regex r("unity::scopes::ConfigException: \".*\": Author cannot be empty or whitespace only");
2323+ EXPECT_TRUE(boost::regex_match(e.what(), r));
2324+ }
2325+}
2326+
2327 class ScopeConfigWithIntl: public ::testing::Test
2328 {
2329 public:
2330
2331=== added file 'test/gtest/scopes/internal/ScopeConfig/empty_author.ini.in'
2332--- test/gtest/scopes/internal/ScopeConfig/empty_author.ini.in 1970-01-01 00:00:00 +0000
2333+++ test/gtest/scopes/internal/ScopeConfig/empty_author.ini.in 2015-06-09 10:03:04 +0000
2334@@ -0,0 +1,4 @@
2335+[ScopeConfig]
2336+DisplayName = Scope name
2337+Description = Scope description
2338+Author =
2339
2340=== added file 'test/gtest/scopes/internal/ScopeConfig/empty_description.ini.in'
2341--- test/gtest/scopes/internal/ScopeConfig/empty_description.ini.in 1970-01-01 00:00:00 +0000
2342+++ test/gtest/scopes/internal/ScopeConfig/empty_description.ini.in 2015-06-09 10:03:04 +0000
2343@@ -0,0 +1,4 @@
2344+[ScopeConfig]
2345+DisplayName = Scope name
2346+Description = \s
2347+Author = Canonical
2348
2349=== added file 'test/gtest/scopes/internal/ScopeConfig/empty_display_name.ini.in'
2350--- test/gtest/scopes/internal/ScopeConfig/empty_display_name.ini.in 1970-01-01 00:00:00 +0000
2351+++ test/gtest/scopes/internal/ScopeConfig/empty_display_name.ini.in 2015-06-09 10:03:04 +0000
2352@@ -0,0 +1,4 @@
2353+[ScopeConfig]
2354+DisplayName =
2355+Description = Scope description
2356+Author = Canonical
2357
2358=== modified file 'test/gtest/scopes/internal/smartscopes/smartscopesproxy/smartscopesproxy_test.cpp'
2359--- test/gtest/scopes/internal/smartscopes/smartscopesproxy/smartscopesproxy_test.cpp 2015-01-28 09:03:59 +0000
2360+++ test/gtest/scopes/internal/smartscopes/smartscopesproxy/smartscopesproxy_test.cpp 2015-06-09 10:03:04 +0000
2361@@ -53,8 +53,7 @@
2362 , ss_config_("")
2363 {
2364 // set the LANGUAGE env var
2365- std::string locale_env = "LANGUAGE=test_TEST";
2366- ::putenv(const_cast<char*>(locale_env.c_str()));
2367+ ::setenv("LANGUAGE", "test_TEST", 1);
2368
2369 // Instantiate runtime
2370 rt_ = RuntimeImpl::create(reg_id_, SS_RUNTIME_PATH);
2371@@ -191,38 +190,32 @@
2372 TEST_F(smartscopesproxytest, ss_registry_locale)
2373 {
2374 // set an invalid LANGUAGE env var (should return 0 scopes)
2375- std::string locale_env = "LANGUAGE=test_FAIL";
2376- ::putenv(const_cast<char*>(locale_env.c_str()));
2377+ ::setenv("LANGUAGE", "test_FAIL", 1);
2378 reset_reg();
2379 EXPECT_EQ(0, reg_->list().size());
2380
2381 // set an empty LANGUAGE env var (should return 2 scopes)
2382- locale_env = "LANGUAGE=";
2383- ::putenv(const_cast<char*>(locale_env.c_str()));
2384+ ::setenv("LANGUAGE", "", 1);
2385 reset_reg();
2386 EXPECT_EQ(4u, reg_->list().size());
2387
2388 // set a valid LANGUAGE env var (should return 2 scopes)
2389- locale_env = "LANGUAGE=test_TEST";
2390- ::putenv(const_cast<char*>(locale_env.c_str()));
2391+ ::setenv("LANGUAGE", "test_TEST", 1);
2392 reset_reg();
2393 EXPECT_EQ(4u, reg_->list().size());
2394
2395 // set a colon only LANGUAGE env var (should return 2 scopes)
2396- locale_env = "LANGUAGE=:";
2397- ::putenv(const_cast<char*>(locale_env.c_str()));
2398+ ::setenv("LANGUAGE", ":", 1);
2399 reset_reg();
2400 EXPECT_EQ(4u, reg_->list().size());
2401
2402 // set a colon seperated LANGUAGE env var (first valid - should return 2 scopes)
2403- locale_env = "LANGUAGE=test_TEST:test_FAIL";
2404- ::putenv(const_cast<char*>(locale_env.c_str()));
2405+ ::setenv("LANGUAGE", "test_TEST:test_FAIL", 1);
2406 reset_reg();
2407 EXPECT_EQ(4u, reg_->list().size());
2408
2409 // set a colon seperated LANGUAGE env var (first invalid - should return 0 scopes)
2410- locale_env = "LANGUAGE=test_FAIL:test_TEST";
2411- ::putenv(const_cast<char*>(locale_env.c_str()));
2412+ ::setenv("LANGUAGE", "test_FAIL:test_TEST", 1);
2413 reset_reg();
2414 EXPECT_EQ(0, reg_->list().size());
2415 }
2416
2417=== modified file 'test/gtest/scopes/internal/zmq_middleware/ZmqMiddleware/ZmqMiddleware_test.cpp'
2418--- test/gtest/scopes/internal/zmq_middleware/ZmqMiddleware/ZmqMiddleware_test.cpp 2015-03-25 05:52:25 +0000
2419+++ test/gtest/scopes/internal/zmq_middleware/ZmqMiddleware/ZmqMiddleware_test.cpp 2015-06-09 10:03:04 +0000
2420@@ -446,6 +446,15 @@
2421 return nullptr;
2422 }
2423
2424+ virtual MWQueryCtrlProxy activate_result_action(Result const&,
2425+ ActionMetadata const&,
2426+ std::string const&,
2427+ MWReplyProxy const&,
2428+ InvokeInfo const&) override
2429+ {
2430+ return nullptr;
2431+ }
2432+
2433 virtual MWQueryCtrlProxy preview(Result const&,
2434 ActionMetadata const&,
2435 MWReplyProxy const&,

Subscribers

People subscribed via source and target branches

to all changes: