This file is indexed.

/usr/share/doc/unity-scopes-api/index.html is in libunity-scopes-doc 0.4.2+14.04.20140408-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.6"/>
<title>Unity Scopes API: Main Page</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
  $(window).load(resizeHeight);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">Unity Scopes API
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.6 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li class="current"><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="namespaces.html"><span>Namespaces</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
      </li>
    </ul>
  </div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('index.html','');});
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Macros</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark">&#160;</span>Pages</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="contents">
<div class="textblock"><h1><a class="anchor" id="overview"></a>
What are scopes</h1>
<h2><a class="anchor" id="intro"></a>
Introduction</h2>
<p>One of Unity’s core features on the desktop is the Dash. The Dash allows users to search for and discover virtually anything from local files and applications, to web content and other online data. The Dash achieves this by interfacing with one or more search plug-ins called “scopes” (e.g. “Apps”, “Music”, “Videos”, or “Amazon”, “Wikipedia”, “Youtube”).</p>
<p>On the phone and tablet, scopes make up the central user interface, as they provide everything a user needs from an operating system. Scopes enable users to locate and launch applications, access local files, play music and videos, search the web, manage their favourite social network, keep up with the latest news, and much more.</p>
<p>Each scope is a dedicated search engine for the category / data source it represents. The data source could be a local database, a web service, or even an aggregation of other scopes (e.g. the “Music” scope aggregates “Local Music” and “Online Music” scopes). A scope is primarily responsible for performing the actual search logic and returning the best possible results for each query it receives.</p>
<p>This document describes how to implement, test and package your own scope using the Unity Scopes C++ API (unity-scopes-api).</p>
<h2><a class="anchor" id="LvsR"></a>
Local vs remote scopes</h2>
<p>Local scopes are scopes that are located and run on the user’s device, while remote scopes (or “Smart Scopes”) are scopes that are located and run remotely on the Ubuntu Smart Scopes Server (or “SSS”). (Note: Although local scopes execute as local processes, they may still query online services in order to retrieve search results). A local scope usually requires local data, and therefore, can only be run locally, while a remote scope can effectively be run both locally and remotely.</p>
<p>When deciding on whether to write a local or remote scope, keep the user’s privacy in mind. For security reasons, a scope should not access the user’s personal data unless absolutely necessary (i.e. The scope requires account information or local data to perform searches). It is only in these situations that a scope should be written to run locally. <b>By default, a scope should be written with the intention of running remotely on the Smart Scopes Server.</b></p>
<p>(For more information on how to deploy your scope to the Smart Scopes Server, or how to implement a native remote scope using the SSS REST API see: <em>link_not_yet_available</em>)</p>
<h1><a class="anchor" id="develop"></a>
Developing scopes</h1>
<h2><a class="anchor" id="starting"></a>
Getting started</h2>
<p>A simple C++ scope template with cmake build system is currently available on Launchpad, to use it install the packages required for scope development:</p>
<pre class="fragment">sudo apt-get install libunity-scopes-dev
</pre><p>Clone the bazaar branch with the scope template and build the scope:</p>
<pre class="fragment">bzr branch lp:~jpakkane/+junk/scopetemplate
cd scopetemplate
mkdir build
cd build
cmake ..
make
</pre><p>Now you're ready to explore and modify the sample code in the src/ directory.</p>
<h2><a class="anchor" id="impl"></a>
Implementing scope</h2>
<p>This short tutorial covers the basic steps and building blocks needed for implementing your own scope with unity-scopes-api, using C++. For complete examples of various scopes see demo/scopes subdirectory of the unity-scopes-api source project.</p>
<p>A typical scope implementation needs to implement interfaces of the following classes from the Scopes API: </p>
<ul>
<li>
<a class="el" href="classunity_1_1scopes_1_1_scope_base.html" title="Base class for a scope implementation. ">unity::scopes::ScopeBase</a> - the main scope class and an entry point for all incoming requests. </li>
<li>
<a class="el" href="classunity_1_1scopes_1_1_search_query_base.html" title="Abstract base class to represent a particular query. ">unity::scopes::SearchQueryBase</a> - the handler of search request. </li>
<li>
<a class="el" href="classunity_1_1scopes_1_1_preview_query_base.html" title="Abstract base class to represent a particular preview. ">unity::scopes::PreviewQueryBase</a> - the handler of preview requests (only if handling previews). </li>
<li>
<a class="el" href="classunity_1_1scopes_1_1_activation_query_base.html" title="Base class for an activation request that is executed inside a scope. ">unity::scopes::ActivationQueryBase</a> - the handler of activation and preview action requests (only if handling previews and activation) </li>
<li>
<a class="el" href="classunity_1_1scopes_1_1_search_listener_base.html" title="Abstract base interface that a scope specializes to receive the results of a query. ">unity::scopes::SearchListenerBase</a> - the handler of search replies (only in aggreagator scopes, to pull results from other scopes) </li>
</ul>
<p>The following sections show them in more detail.</p>
<h3><a class="anchor" id="simplescope"></a>
Case 1: A simple scope which doesn't query other scopes.</h3>
<p>This is the typical case: a scope that connects to a remote or local backend, database etc. and provides results in response to search queries coming from a client (i.e. Unity Dash or another scope).</p>
<h4><a class="anchor" id="scopebase"></a>
Create a scope class that implements ScopeBase inteface.</h4>
<p>There are a few pure virtual methods that need to be implemented; at the very minimum you need to provide a non-empty implementation of <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#add7f4b1811774a63cd474ccab702acdf">start</a> and <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a0e4969ff26dc1d396d74c56d896fd564" title="Called by the scopes run time when a scope needs to instantiate a query. ">unity::scopes::ScopeBase::search()</a> and <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a154b9b4cfc0f40572cfec60dd819396f" title="Invoked when a scope is requested to create a preview for a particular result. ">unity::scopes::ScopeBase::preview()</a> methods.</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>MyScope: <span class="keyword">public</span> <a class="code" href="classunity_1_1scopes_1_1_scope_base.html">unity::scopes::ScopeBase</a></div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">    <span class="keyword">virtual</span> <span class="keywordtype">int</span> <a class="code" href="classunity_1_1scopes_1_1_scope_base.html#add7f4b1811774a63cd474ccab702acdf">start</a>(std::string <span class="keyword">const</span>&amp;, <a class="code" href="namespaceunity_1_1scopes.html#a45babc254d3548863d79ee54f266e84d">unity::scopes::RegistryProxy</a> <span class="keyword">const</span>&amp;) <span class="keyword">override</span>;</div>
<div class="line">    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classunity_1_1scopes_1_1_scope_base.html#ad55d5cb31003751b49783799d4d80c09">stop</a>() <span class="keyword">override</span>;</div>
<div class="line">    <span class="keyword">virtual</span> <span class="keywordtype">void</span> <a class="code" href="classunity_1_1scopes_1_1_scope_base.html#a386e99b98318a70f25db84bbe11c0292">run</a>() <span class="keyword">override</span>;</div>
<div class="line">    <span class="keyword">virtual</span> unity::scopes::SearchQueryBase::UPtr <a class="code" href="classunity_1_1scopes_1_1_scope_base.html#a0e4969ff26dc1d396d74c56d896fd564">search</a>(CannedQuery <span class="keyword">const</span>&amp; query, SearchMetadata <span class="keyword">const</span>&amp; metadata) <span class="keyword">override</span>;</div>
<div class="line">    <span class="keyword">virtual</span> unity::scopes::PreviewQueryBase::UPtr <a class="code" href="classunity_1_1scopes_1_1_scope_base.html#a154b9b4cfc0f40572cfec60dd819396f">preview</a>(<a class="code" href="classunity_1_1scopes_1_1_result.html">unity::scopes::Result</a> <span class="keyword">const</span>&amp; result, <a class="code" href="classunity_1_1scopes_1_1_action_metadata.html">unity::scopes::ActionMetadata</a> <span class="keyword">const</span>&amp; metadata) <span class="keyword">override</span>;</div>
<div class="line">}</div>
</div><!-- fragment --><p>The <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#add7f4b1811774a63cd474ccab702acdf">start</a> method must, at the very least return <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a7ef008b8ec7ae3bdab9a1b5dbc2a0dd0" title="This value must be returned from the start() method. ">unity::scopes::ScopeBase::VERSION</a>, e.g.</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> MyScope::start(<span class="keywordtype">string</span> <span class="keyword">const</span>&amp;, <a class="code" href="namespaceunity_1_1scopes.html#a45babc254d3548863d79ee54f266e84d">unity::scopes::RegistryProxy</a> <span class="keyword">const</span>&amp;)</div>
<div class="line">{</div>
<div class="line">    <span class="keywordflow">return</span> ScopeBase::VERSION;</div>
<div class="line">}</div>
</div><!-- fragment --><p>The <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#ad55d5cb31003751b49783799d4d80c09">stop</a> method should release any resources, such as network connections where applicable. See the documentation of <a class="el" href="classunity_1_1scopes_1_1_scope_base.html">ScopeBase</a> for an explanation of when <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a386e99b98318a70f25db84bbe11c0292">ScopeBase::run</a>; is useful; for typical and simple cases the implementation of run can be an empty function.</p>
<h4><a class="anchor" id="handlingsearch"></a>
Handling search</h4>
<p>The <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a0e4969ff26dc1d396d74c56d896fd564" title="Called by the scopes run time when a scope needs to instantiate a query. ">unity::scopes::ScopeBase::search()</a> method of scope implementation is the entry point of every search - it receives search queries from the Dash or other scopes. This method must return an instance of an object that implements <a class="el" href="classunity_1_1scopes_1_1_search_query_base.html" title="Abstract base class to represent a particular query. ">unity::scopes::SearchQueryBase</a> interface, e.g:</p>
<div class="fragment"><div class="line">SearchQueryBase::UPtr MyScope::search(CannedQuery <span class="keyword">const</span>&amp; query, SearchMetadata <span class="keyword">const</span>&amp; metadata)</div>
<div class="line">{</div>
<div class="line">    SearchQueryBase::UPtr q(<span class="keyword">new</span> MyQuery(query));</div>
<div class="line">    <span class="keywordflow">return</span> q;</div>
<div class="line">}</div>
</div><!-- fragment --><p>The search() method receives two arguments: a <a class="el" href="classunity_1_1scopes_1_1_canned_query.html" title="Parameters of a search query. ">unity::scopes::CannedQuery</a> query object that carries actual query string (among other information) and additional parameters of the search request, stored in <a class="el" href="classunity_1_1scopes_1_1_search_metadata.html" title="Metadata passed with search requests. ">unity::scopes::SearchMetadata</a> - such as locale string, form factor string and cardinality. Cardinality is the maximum number of results expected from the scope (the value of 0 should be treated as if no limit was set). For optimal performance scopes should provide no more results than requested; if they however fail to handle cardinality constraint, any excessive results will be ignored by scopes API.</p>
<h4><a class="anchor" id="querybase"></a>
Create a query class that implements SearchQueryBase interface.</h4>
<p>The central and most important method that needs to be implemented in this interface is <a class="el" href="classunity_1_1scopes_1_1_search_query_base.html#afc4f15b2266838d7da75b05ea37d504b" title="Called by scopes run time to start the query. ">unity::scopes::SearchQueryBase::run()</a>. This is where actual processing of current search query takes place, and this is the spot where you may want to query local or remote data source for results matching the query.</p>
<p>The <a class="el" href="classunity_1_1scopes_1_1_search_query_base.html#afc4f15b2266838d7da75b05ea37d504b" title="Called by scopes run time to start the query. ">unity::scopes::SearchQueryBase::run()</a> method gets passed an instance of SearchReplyProxy, which represents a receiver of query results. Please note that SearchReplyProxy is just a shared pointer for <a class="el" href="classunity_1_1scopes_1_1_search_reply.html">SearchReply</a> object. The two most important methods of SearchReply object that every scope have to use are <a class="el" href="classunity_1_1scopes_1_1_search_reply.html#aaa061806a96f50ff66abc6184135ea66">register_category</a> and <a class="el" href="classunity_1_1scopes_1_1_search_reply.html#a63d6de93152b3a972901c2d406ef5760">push</a>.</p>
<p>The <a class="el" href="classunity_1_1scopes_1_1_search_reply.html#aaa061806a96f50ff66abc6184135ea66">register_category</a> method is a factory method for creating new categories (see <a class="el" href="classunity_1_1scopes_1_1_category.html">unity::scopes::Category</a>). Categories can be created at any point during query processing inside run method, but it's recommended to create them as soon as possible (ideally as soon as they are known to the scope).</p>
<p>When creating a category, one of its parameters is a <a class="el" href="classunity_1_1scopes_1_1_category_renderer.html">unity::scopes::CategoryRenderer</a> instance, which specifies how will a particular category be rendered. See the <a class="el" href="classunity_1_1scopes_1_1_category_renderer.html" title="A category renderer template in JSON format. ">unity::scopes::CategoryRenderer</a> documentation for more on that subject.</p>
<p>The actual search results have to be wrapped inside <a class="el" href="classunity_1_1scopes_1_1_categorised_result.html">CategorisedResult</a> objects and passed to <a class="el" href="classunity_1_1scopes_1_1_search_reply.html#a63d6de93152b3a972901c2d406ef5760">push</a>.</p>
<p>A typical implementation of run may look like this:</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> MyQuery::run(SearchReplyProxy <span class="keyword">const</span>&amp; reply)</div>
<div class="line">{</div>
<div class="line">    <span class="keyword">auto</span> category = reply-&gt;register_category(<span class="stringliteral">&quot;recommended&quot;</span>, <span class="stringliteral">&quot;Recommended&quot;</span>, icon);</div>
<div class="line">    <span class="comment">//... query a local or remote backend</span></div>
<div class="line"></div>
<div class="line">    <span class="keywordflow">for</span> (<span class="keyword">auto</span> res: backend.get_results(search_query)) <span class="comment">// for every result returned by a backend</span></div>
<div class="line">    {</div>
<div class="line">        ...</div>
<div class="line">        CategorisedResult result(category); <span class="comment">// create a result item in &quot;recommended&quot; category</span></div>
<div class="line">        result.set_uri(...);</div>
<div class="line">        result.set_title(...);</div>
<div class="line">        result.set_art(...);</div>
<div class="line">        result.set_dnd_uri(...);</div>
<div class="line">        result[<span class="stringliteral">&quot;my-custom-attribute&quot;</span>] = Variant(...); <span class="comment">// add arbitrary data as needed</span></div>
<div class="line"></div>
<div class="line">        <span class="keywordflow">if</span> (!reply-&gt;push(result)) <span class="comment">// send result to the client</span></div>
<div class="line">        {</div>
<div class="line">            <span class="keywordflow">break</span>; <span class="comment">// false from push() means search was cancelled</span></div>
<div class="line">        }</div>
<div class="line">    }</div>
<div class="line">}</div>
</div><!-- fragment --><h4><a class="anchor" id="handlingpreview"></a>
Handling previews</h4>
<p>Scopes are responsible for handling preview requests for results they created; this needs to be implemented by overriding <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a154b9b4cfc0f40572cfec60dd819396f" title="Invoked when a scope is requested to create a preview for a particular result. ">unity::scopes::ScopeBase::preview()</a> method:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>MyScope: <span class="keyword">public</span> <a class="code" href="classunity_1_1scopes_1_1_scope_base.html">unity::scopes::ScopeBase</a></div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">    ...</div>
<div class="line">    <span class="keyword">virtual</span> unity::scopes::PreviewQueryBase::UPtr <a class="code" href="classunity_1_1scopes_1_1_scope_base.html#a154b9b4cfc0f40572cfec60dd819396f">preview</a>(unitu::scopes::Result <span class="keyword">const</span>&amp; result, <a class="code" href="classunity_1_1scopes_1_1_action_metadata.html">unity::scopes::ActionMetadata</a> <span class="keyword">const</span>&amp; metadata) <span class="keyword">override</span>;</div>
<div class="line">    ...</div>
<div class="line">}</div>
</div><!-- fragment --><p>This method must return an instance derived from <a class="el" href="classunity_1_1scopes_1_1_preview_query_base.html" title="Abstract base class to represent a particular preview. ">unity::scopes::PreviewQueryBase</a>. The implementation of <a class="el" href="classunity_1_1scopes_1_1_preview_query_base.html" title="Abstract base class to represent a particular preview. ">unity::scopes::PreviewQueryBase</a> interface is similar to <a class="el" href="classunity_1_1scopes_1_1_search_query_base.html" title="Abstract base class to represent a particular query. ">unity::scopes::SearchQueryBase</a> in that its central method is <a class="el" href="classunity_1_1scopes_1_1_preview_query_base.html#a81b89daf29cd1ada55286f2a3a871347" title="Called by scopes run time to start the preview. ">unity::scopes::PreviewQueryBase::run()</a>. This method is responsible for gathering preview data (from local or remote sources) and passing it along with the definition of preview look to <a class="el" href="namespaceunity_1_1scopes.html#a7b46ef0e880da4c75314fe60bdd55754" title="Convenience type definition. ">unity::scopes::PreviewReplyProxy</a> (this is a pointer to unity::scopes::PreviewReplyBasel; the run() method receives a pointer to an instance of <a class="el" href="classunity_1_1scopes_1_1_preview_reply.html" title="Allows the results of a preview to be sent to the preview requester. ">unity::scopes::PreviewReply</a>).</p>
<p>A preview consists of one or more preview widgets - these are the basic building blocks for previews, such as a header with a title and subtitle, an image, a gallery with multiple images, a list of audio tracks etc.; see <a class="el" href="classunity_1_1scopes_1_1_preview_widget.html" title="A widget for a preview. ">unity::scopes::PreviewWidget</a> for a detailed documentation and a list of supported widget types. So, the implementation of <a class="el" href="classunity_1_1scopes_1_1_preview_query_base.html#a81b89daf29cd1ada55286f2a3a871347" title="Called by scopes run time to start the preview. ">unity::scopes::PreviewQueryBase::run()</a> needs to create and populate one or more instances of <a class="el" href="classunity_1_1scopes_1_1_preview_widget.html" title="A widget for a preview. ">unity::scopes::PreviewWidget</a> and push them to the client with <a class="el" href="classunity_1_1scopes_1_1_preview_reply.html#a9fc593618b83ec444fb6c9b2b298764a" title="Sends widget definitions to the sender of the preview query. ">unity::scopes::PreviewReply::push()</a>.</p>
<p>Every <a class="el" href="classunity_1_1scopes_1_1_preview_widget.html" title="A widget for a preview. ">unity::scopes::PreviewWidget</a> has a unique identifier, a type name and a set of attributes determined by its type. For example, a widget of "image" type expects two attributes: "source", which should point to an image (an uri) and "zoomable" boolean flag, which determines if the image should be zoomable. Values of such attributes can either be specified directly, or they can reference values present already in the <a class="el" href="classunity_1_1scopes_1_1_result.html" title="The attributes of a result returned by a Scope. ">unity::scopes::Result</a> instance, or pushed spearately during the execution of <a class="el" href="classunity_1_1scopes_1_1_preview_query_base.html#a81b89daf29cd1ada55286f2a3a871347" title="Called by scopes run time to start the preview. ">unity::scopes::PreviewQueryBase::run()</a>.</p>
<p>Attributes can be specified directly with <a class="el" href="classunity_1_1scopes_1_1_preview_widget.html#a42dd64704890d72bcc6ecbd7bccbfcd9" title="Adds an attribute definition and its value. ">unity::scopes::PreviewWidget::add_attribute_value()</a> method, e.g:</p>
<div class="fragment"><div class="line">PreviewWidget image_widget(<span class="stringliteral">&quot;myimage&quot;</span>, <span class="stringliteral">&quot;image&quot;</span>);</div>
<div class="line"></div>
<div class="line">image_widget.add_attribute_value(<span class="stringliteral">&quot;source&quot;</span>, Variant(<span class="stringliteral">&quot;file:///tmp/image.jpg&quot;</span>));</div>
<div class="line">image_widget.add_attribute_value(<span class="stringliteral">&quot;zoomable&quot;</span>, Variant(<span class="keyword">false</span>));</div>
</div><!-- fragment --><p>To reference values from results or arbitrary values pushed separately, use <a class="el" href="classunity_1_1scopes_1_1_preview_widget.html#a8bb890267a69dd6bb5ca70b663c75e74" title="Adds an attribute definition using a component mapping. ">unity::scopes::PreviewWidget::add_attribute_mapping()</a> method:</p>
<div class="fragment"><div class="line">PreviewWidget image_widget(<span class="stringliteral">&quot;myimage&quot;</span>, <span class="stringliteral">&quot;image&quot;</span>);</div>
<div class="line">image_widget.add_attribute_mapping(<span class="stringliteral">&quot;source&quot;</span>, <span class="stringliteral">&quot;art&quot;</span>); <span class="comment">// use &#39;art&#39; attribute from the result</span></div>
<div class="line">image_widget.add_attribute_mapping(<span class="stringliteral">&quot;zoomable&quot;</span>, <span class="stringliteral">&quot;myzoomable&quot;</span>); <span class="comment">// &#39;myzoomable&#39; not specified, but pushed below</span></div>
<div class="line">reply-&gt;push(<span class="stringliteral">&quot;myzoomable&quot;</span>, Variant(<span class="keyword">true</span>));</div>
</div><!-- fragment --><p>To push preview widgets to the client, use <a class="el" href="classunity_1_1scopes_1_1_preview_reply.html#a9fc593618b83ec444fb6c9b2b298764a" title="Sends widget definitions to the sender of the preview query. ">unity::scopes::PreviewReply::push()</a>:</p>
<div class="fragment"><div class="line">PreviewWidget image_widget(<span class="stringliteral">&quot;myimage&quot;</span>, <span class="stringliteral">&quot;image&quot;</span>);</div>
<div class="line">PreviewWidget header_widget(<span class="stringliteral">&quot;myheader&quot;</span>, <span class="stringliteral">&quot;header&quot;</span>);</div>
<div class="line"><span class="comment">// fill in widget attributes</span></div>
<div class="line">...</div>
<div class="line">PreviewWidgetList widgets { image_widget, header_widget };</div>
<div class="line">reply-&gt;push(widgets);</div>
</div><!-- fragment --><h4><a class="anchor" id="previewactions"></a>
Preview actions</h4>
<p>Previews can have actions (i.e. buttons) that user can activate - they are supported by <a class="el" href="classunity_1_1scopes_1_1_preview_widget.html" title="A widget for a preview. ">unity::scopes::PreviewWidget</a> of "actions" type. This type of widget takes one or more action button definitions, where every button is constituted by an unique identifier, a label and an optional icon. For example, a widget with two buttons: "Open" and "Download" can be defined as follows (using <a class="el" href="classunity_1_1scopes_1_1_variant_builder.html" title="Helper class for creating and populating Variant containers. ">unity::scopes::VariantBuilder</a> helper class):</p>
<div class="fragment"><div class="line">PreviewWidget buttons(<span class="stringliteral">&quot;mybuttons&quot;</span>, <span class="stringliteral">&quot;actions&quot;</span>);</div>
<div class="line"></div>
<div class="line">VariantBuilder builder;</div>
<div class="line">builder.add_tuple({</div>
<div class="line">    {<span class="stringliteral">&quot;id&quot;</span>, Variant(<span class="stringliteral">&quot;open&quot;</span>)},</div>
<div class="line">    {<span class="stringliteral">&quot;label&quot;</span>, Variant(<span class="stringliteral">&quot;Open&quot;</span>)}</div>
<div class="line">});</div>
<div class="line">builder.add_tuple({</div>
<div class="line">    {<span class="stringliteral">&quot;id&quot;</span>, Variant(<span class="stringliteral">&quot;download&quot;</span>)},</div>
<div class="line">    {<span class="stringliteral">&quot;label&quot;</span>, Variant(<span class="stringliteral">&quot;Download&quot;</span>)}</div>
<div class="line">});</div>
<div class="line"></div>
<div class="line">buttons.add_attribute_value(<span class="stringliteral">&quot;actions&quot;</span>, builder.end());</div>
</div><!-- fragment --><p>To handle activation of preview actions, scope needs to implement the following method of <a class="el" href="classunity_1_1scopes_1_1_scope_base.html" title="Base class for a scope implementation. ">unity::scopes::ScopeBase</a>:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>MyScope: <span class="keyword">public</span> <a class="code" href="classunity_1_1scopes_1_1_scope_base.html">unity::scopes::ScopeBase</a></div>
<div class="line">{</div>
<div class="line">    <span class="keyword">virtual</span> ActivationQueryBase::UPtr <a class="code" href="classunity_1_1scopes_1_1_scope_base.html#a2f4d476fa790349c9a7de52be3232d11">perform_action</a>(Result <span class="keyword">const</span>&amp; result, ActionMetadata <span class="keyword">const</span>&amp; metadata, std::string <span class="keyword">const</span>&amp; widget_id, std::string <span class="keyword">const</span>&amp; action_id) <span class="keyword">override</span></div>
<div class="line">    ...</div>
<div class="line">}</div>
</div><!-- fragment --><p>This method receives a widget identifier and action identifier that was activated. This method needs to return an instance derived from <a class="el" href="classunity_1_1scopes_1_1_activation_query_base.html" title="Base class for an activation request that is executed inside a scope. ">unity::scopes::ActivationQueryBase</a>. The derived class needs to reimplement <a class="el" href="classunity_1_1scopes_1_1_activation_query_base.html#a61ed49d8bc56e677ff2eb1f30e6a6b6b" title="Return response to the activation request. ">unity::scopes::ActivationQueryBase::activate()</a> method and put any activation logic in there. This method needs to respond with an instance of <a class="el" href="classunity_1_1scopes_1_1_activation_response.html" title="Response to a result activation. ">unity::scopes::ActivationResponse</a>, which informs the shell about status of activation and the expected behaviour of the UI. For example, activate() may request a new search query to be executed as follows:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>MyActivation : <span class="keyword">public</span> <a class="code" href="classunity_1_1scopes_1_1_activation_query_base.html">unity::scopes::ActivationQueryBase</a></div>
<div class="line">{</div>
<div class="line">    <span class="keyword">virtual</span> <a class="code" href="classunity_1_1scopes_1_1_activation_response.html">unity::scopes::ActivationResponse</a> <a class="code" href="classunity_1_1scopes_1_1_activation_query_base.html#a61ed49d8bc56e677ff2eb1f30e6a6b6b">activate</a>()<span class="keyword"> override</span></div>
<div class="line"><span class="keyword">    </span>{</div>
<div class="line">        ...</div>
<div class="line">        <span class="keywordflow">if</span> (action_id == <span class="stringliteral">&quot;search-grooveshark&quot;</span>)</div>
<div class="line">        {</div>
<div class="line">            CannedQuery query(<span class="stringliteral">&quot;com.canonical.scopes.grooveshark&quot;</span>);</div>
<div class="line">            query.set_query_string(<span class="stringliteral">&quot;metal&quot;</span>);</div>
<div class="line">            <span class="keywordflow">return</span> <a class="code" href="classunity_1_1scopes_1_1_activation_response.html">unity::scopes::ActivationResponse</a>(query);</div>
<div class="line">        }</div>
<div class="line">        ...</div>
<div class="line">    }</div>
<div class="line">}</div>
</div><!-- fragment --><h4><a class="anchor" id="handlingactivation"></a>
Handling result activation</h4>
<p>In many cases search results can be activated (i.e. when user taps or clicks them) directly by the shell - as long as a desktop schema (such as "http://") of result's uri has a handler in the system. If this is the case, then there is nothing to do in terms of activation handling in the scope code. If however a scope relies on a schema handler that's not present in the system, the offending result will be ignored by Unity shell and nothing will happen on activation.</p>
<p>In cases where scope wants to intercept and handle activation request (e.g. when no handler for specifc type of uri exists, or to do some extra work on activation), it has to reimplement <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a49a0b9ada0eeb4c71e6a2181c3d8c9e7" title="Called by the scopes run time when a scope needs to respond to a result activation request...">unity::scopes::ScopeBase::activate()</a> method:</p>
<div class="fragment"><div class="line"><span class="keyword">class </span>MyScope : <span class="keyword">public</span> ScopeBase</div>
<div class="line">{</div>
<div class="line">    <span class="keyword">virtual</span> ActivationQueryBase::UPtr activate(Result <span class="keyword">const</span>&amp; result, ActionMetadata <span class="keyword">const</span>&amp; metadata) <span class="keyword">override</span>;</div>
<div class="line">    ...</div>
<div class="line">}</div>
</div><!-- fragment --><p>and also call Result::set_intercept_activation() for all results that should trigger <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a49a0b9ada0eeb4c71e6a2181c3d8c9e7" title="Called by the scopes run time when a scope needs to respond to a result activation request...">unity::scopes::ScopeBase::activate()</a> on activation. The implementation of <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a49a0b9ada0eeb4c71e6a2181c3d8c9e7" title="Called by the scopes run time when a scope needs to respond to a result activation request...">unity::scopes::ScopeBase::activate()</a> should follow the same guidelines as <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a2f4d476fa790349c9a7de52be3232d11" title="Invoked when a scope is requested to handle a preview action. ">unity::scopes::ScopeBase::perform_action()</a>, the only difference with result activation being the lack of widget or action identifiers, as those are specific to preview widgets.</p>
<h4><a class="anchor" id="export"></a>
Exporting the scope</h4>
<p>The scope needs to be compiled into a .so shared library and to be succesfully loaded at runtime it must provide two C functions to create and destroy it - a typical code snippet to do this looks as follows:</p>
<div class="fragment"><div class="line"><span class="keyword">extern</span> <span class="stringliteral">&quot;C&quot;</span> {</div>
<div class="line">    EXPORT <a class="code" href="classunity_1_1scopes_1_1_scope_base.html">unity::scopes::ScopeBase</a>* <a class="code" href="_scope_base_8h.html#a21674629dcda399390c80d469fcb1d6d">UNITY_SCOPE_CREATE_FUNCTION</a>()</div>
<div class="line">    {</div>
<div class="line">        <span class="keywordflow">return</span> <span class="keyword">new</span> MyScope();</div>
<div class="line">    }</div>
<div class="line"></div>
<div class="line">    EXPORT <span class="keywordtype">void</span> <a class="code" href="_scope_base_8h.html#ac01d346e43462c07535811fd24c468f7">UNITY_SCOPE_DESTROY_FUNCTION</a>(<a class="code" href="classunity_1_1scopes_1_1_scope_base.html">unity::scopes::ScopeBase</a>* scope_base)</div>
<div class="line">    {</div>
<div class="line">        <span class="keyword">delete</span> scope_base;</div>
<div class="line">    }</div>
<div class="line">}</div>
</div><!-- fragment --><h3><a class="anchor" id="aggscope"></a>
Case 2: A simple aggregator scope.</h3>
<p>Aggregator scope is not much different from regular scopes, except for its data sources can include any other scope(s). The main difference is in the implementation of run method of <a class="el" href="classunity_1_1scopes_1_1_search_query_base.html" title="Abstract base class to represent a particular query. ">unity::scopes::SearchQueryBase</a> and in the new class that has to implement <a class="el" href="classunity_1_1scopes_1_1_search_listener_base.html">SearchListenerBase</a> interface, which receives result from other scope(s).</p>
<h4><a class="anchor" id="subquery"></a>
Query another scopes via SearchQueryBase::subsearch()</h4>
<p>To send search query to another scope, use one of the <code>subsearch()</code> overloads of <a class="el" href="classunity_1_1scopes_1_1_search_query_base.html" title="Abstract base class to represent a particular query. ">unity::scopes::SearchQueryBase</a> inside your implementation of <a class="el" href="classunity_1_1scopes_1_1_search_query_base.html" title="Abstract base class to represent a particular query. ">unity::scopes::SearchQueryBase</a>. This method requires - among search query string - an instance of <a class="el" href="namespaceunity_1_1scopes.html#a94db15da410f8419e4da711db842aaae">ScopeProxy</a> that points to the target scope and an instance of class that implements <a class="el" href="classunity_1_1scopes_1_1_search_listener_base.html">SearchListenerBase</a> interface. ScopeProxy can be obtained from <a class="el" href="namespaceunity_1_1scopes.html#a45babc254d3548863d79ee54f266e84d" title="Convenience type definition. ">unity::scopes::RegistryProxy</a> and the right place to do this is in the implementation of <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#add7f4b1811774a63cd474ccab702acdf">start()</a> method of <a class="el" href="classunity_1_1scopes_1_1_scope_base.html">ScopeBase</a> interface.</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> MyScope::start(std::string <span class="keyword">const</span>&amp;, <a class="code" href="namespaceunity_1_1scopes.html#a45babc254d3548863d79ee54f266e84d">unity::scopes::RegistryProxy</a> <span class="keyword">const</span>&amp; registry)</div>
<div class="line">{</div>
<div class="line">    <span class="keywordflow">try</span></div>
<div class="line">    {</div>
<div class="line">        <span class="keyword">auto</span> meta = registry-&gt;get_metadata(<span class="stringliteral">&quot;scope-A&quot;</span>);</div>
<div class="line">        scope_to_query_ = meta.proxy(); <span class="comment">// store the proxy for passing it further in search </span></div>
<div class="line">    }</div>
<div class="line">    <span class="keywordflow">catch</span> (NotFoundException <span class="keyword">const</span>&amp; e)</div>
<div class="line">    {</div>
<div class="line">        ...</div>
<div class="line">    }</div>
<div class="line">    <span class="keywordflow">return</span> VERSION;</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line">unity::scopes::QueryBase::UPtr MyScope::search(CannedQuery <span class="keyword">const</span>&amp; query, <a class="code" href="classunity_1_1scopes_1_1_search_metadata.html">unity::scopes::SearchMetadata</a> <span class="keyword">const</span>&amp;)</div>
<div class="line">{</div>
<div class="line">    SearchQueryBase::UPtr q(<span class="keyword">new</span> MyQuery(query, scope_to_query_));</div>
<div class="line">    <span class="keywordflow">return</span> q;</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line">...</div>
<div class="line"></div>
<div class="line">void MyQuery::run(<a class="code" href="namespaceunity_1_1scopes.html#a9cd604d9b842ac3b2b8636c2165dec1f">unity::scopes::SearchReplyProxy</a> <span class="keyword">const</span>&amp; upstream_reply) </div>
<div class="line">{</div>
<div class="line">    <span class="keyword">auto</span> category = reply-&gt;register_category(<span class="stringliteral">&quot;recommended&quot;</span>, <span class="stringliteral">&quot;Recommended&quot;</span>, icon, <span class="stringliteral">&quot;&quot;</span>);</div>
<div class="line">    SearchListenerBase::SPtr reply(<span class="keyword">new</span> MyReceiver(upstream_reply, category));</div>
<div class="line">    subsearch(scope_to_query_, query_, reply);</div>
<div class="line">    ...</div>
<div class="line">}</div>
</div><!-- fragment --><h4><a class="anchor" id="receiver"></a>
Create a class that implements SearchListenerBase interface</h4>
<p>The <a class="el" href="classunity_1_1scopes_1_1_search_listener_base.html">SearchListenerBase</a> is an abstract class to receive the results of a query sent to a scope. Its virtual push methods let the implementation receive <a class="el" href="classunity_1_1scopes_1_1_search_listener_base.html#af3f2815ec080baffefd9099273b81a5e">result items and categories</a> returned by that query. A simple implementation of an aggregator scope may just register all categories it receives and push all received results upstream to the query originator, e.g.</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> push(Category::SCPtr category)</div>
<div class="line">{</div>
<div class="line">    upstream_-&gt;register_category(category);</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="keywordtype">void</span> MyReceiver::push(CategorisedResult result)</div>
<div class="line">{</div>
<div class="line">    upstream_-&gt;push(std::move(result));</div>
<div class="line">}</div>
</div><!-- fragment --><p>A more sophisticated aggregator scope can rearrange results it receives into a different set of categories, alter or enrich the results before pushing them upstream etc.</p>
<h4><a class="anchor" id="aggactiv"></a>
Activation and previews of results processed by aggregator scopes</h4>
<p>If an aggregator scope just forwards results it receives from other scopes, possibly only changing their category assignment, then there is nothing to do in terms of handling previews, preview actions and result activation: preview and perform_action requests will trigger respective methods of <a class="el" href="classunity_1_1scopes_1_1_scope_base.html" title="Base class for a scope implementation. ">unity::scopes::ScopeBase</a> for the scope that created results. Result activation will trigger <a class="el" href="classunity_1_1scopes_1_1_scope_base.html#a49a0b9ada0eeb4c71e6a2181c3d8c9e7" title="Called by the scopes run time when a scope needs to respond to a result activation request...">unity::scopes::ScopeBase::activate()</a> method for the scope that produced the result as long as it set interception flag for it. In other words, when aggreagor scope just forwards results (and makes only minor adjustements to them, such as category assignment), it is not involved in preview or activation handling at all.</p>
<p>If, however, aggregator scope changes attributes of results (or creates completely new results that "replace" received results), then some extra care needs to be taken: </p>
<ul>
<li>
<p class="startli">if original scope should still handle preview (and activation) requests, then <b>aggregator has to store a copy of original result</b> in the modified (or brand new) result. This can be done with <a class="el" href="classunity_1_1scopes_1_1_result.html#a744776333a9748ba41dace7c6943ca4d" title="Stores a Result inside this Result instance. ">unity::scopes::Result::store</a> method. Preview request for such result will automatically trigger a scope that created the most inner stored result, and that scope will receive the stored result. It will also do the same for activation as long as the original scope set interception flag on that result.</p>
<dl class="section note"><dt>Note</dt><dd>Making substantial changes to received results and failing to store original results with them may result in unexpected behavior: a scope will suddenly receive a modified version of it and depending on the level of changes, it may or may not be able to correctly handle it.</dd></dl>
</li>
<li>
if aggregator scope creates a completly new result that replaces original one, but doesn't store a copy of the original result, it is expected to handle preview (and potentially activation requests - if interception activation flag is set) - this is no different than for normal scopes, see <a class="el" href="index.html#handlingpreview">Handling previews</a> and <a class="el" href="index.html#handlingactivation">Handling result activation</a> . </li>
</ul>
<p>Consider the following example of implementation of <a class="el" href="classunity_1_1scopes_1_1_search_listener_base.html" title="Abstract base interface that a scope specializes to receive the results of a query. ">unity::scopes::SearchListenerBase</a> interface that modifies results and stores their copies, so that original scope can handle previews and activation for them:</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> MyReceiver::push(CategorisedResult original_result)</div>
<div class="line">{</div>
<div class="line">    CategorisedResult result(agg_category); <span class="comment">// agg_category is a category that aggregates all results from other scopes</span></div>
<div class="line">    result.set_uri(original_result.uri());</div>
<div class="line">    result.set_title(original_result.title() + <span class="stringliteral">&quot;(aggregated)&quot;</span>);</div>
<div class="line">    result.set_art(original_result.art());</div>
<div class="line">    result.store(original_result);</div>
<div class="line"></div>
<div class="line">    upstream_-&gt;push(std::move(result));</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="scopetesting"></a>
Testing</h2>
<p>Unity Scopes API provides testing helpers based on well-known and established testing frameworks: <a href="https://code.google.com/p/googletest/">googletest</a> and <a href="https://code.google.com/p/googlemock/">googlemock</a>. Please see respective documentation of those projects for general information about how to use Google C++ Testing Framework.</p>
<p>All the helper classes provided by Scopes API are located in unity::scopes::testing namespace. The most important ones are: </p>
<ul>
<li>
unity::scopes::testing::TypedScopeFixture - template class that takes your scope class name as a template argument and creates a test fixture that can be used in tests. </li>
<li>
unity::scopes::testing::MockSearchReply - a mock of <a class="el" href="classunity_1_1scopes_1_1_search_reply.html" title="Allows the results of a search query to be sent to the query source. ">unity::scopes::SearchReply</a> that makes it possible to intercept responses to search request sent from the scope to a client, making it easy to test if your scope returns all expected data. </li>
<li>
unity::scopes::testing::MockPreviewReply - a mock of <a class="el" href="classunity_1_1scopes_1_1_preview_reply.html" title="Allows the results of a preview to be sent to the preview requester. ">unity::scopes::PreviewReply</a> that makes is possible to intercept and test responses to preview request sent from the scope to a client. </li>
<li>
<a class="el" href="classunity_1_1scopes_1_1testing_1_1_result.html" title="A simple class implementation of unity::scopes::Result that provides a default constructor. ">unity::scopes::testing::Result</a> - a simple class defined on top of <a class="el" href="classunity_1_1scopes_1_1_result.html" title="The attributes of a result returned by a Scope. ">unity::scopes::Result</a> that provides a default constructor, making it possible to create dummy results (with no attributes) for testing purposes. </li>
<li>
unity::scopes::testing::category - a simple class defined on top of <a class="el" href="classunity_1_1scopes_1_1_category.html" title="A set of related results returned by a scope and displayed within a single pane in the Unity dash...">unity::scopes::Category</a> that makes it possible to create dummy categories (which would otherwise require an instance of <a class="el" href="classunity_1_1scopes_1_1_search_reply.html" title="Allows the results of a search query to be sent to the query source. ">unity::scopes::SearchReply</a> and a call to <a class="el" href="classunity_1_1scopes_1_1_search_reply.html#aaa061806a96f50ff66abc6184135ea66" title="Register an existing category instance and send it to the source of the query. ">unity::scopes::SearchReply::register_category()</a>). </li>
</ul>
<p>With the above classes a test case that checks if MyScope calls appropriate methods of <a class="el" href="classunity_1_1scopes_1_1_search_reply.html" title="Allows the results of a search query to be sent to the query source. ">unity::scopes::SearchReply</a> may look like this (note that it just checks if proper methods get called and uses _ matchers that match any values; put actual values in there for stricts checks): </p>
<div class="fragment"><div class="line"><span class="keyword">typedef</span> unity::scopes::testing::TypedScopeFixture&lt;MyScope&gt; TestScopeFixutre;</div>
<div class="line"><span class="keyword">using namespace </span>::testing;</div>
<div class="line"></div>
<div class="line">TEST_F(TestScopeFixutre, search_results)</div>
<div class="line">{</div>
<div class="line">    <span class="keyword">const</span> <a class="code" href="classunity_1_1scopes_1_1_category_renderer.html">unity::scopes::CategoryRenderer</a> renderer;</div>
<div class="line"></div>
<div class="line">    NiceMock&lt;unity::scopes::testing::MockSearchReply&gt; reply;</div>
<div class="line">    EXPECT_CALL(reply, register_departments(_, _)).Times(1);</div>
<div class="line">    EXPECT_CALL(reply, register_category(_, _, _, _))</div>
<div class="line">            .Times(1)</div>
<div class="line">            .WillOnce(</div>
<div class="line">                Return(</div>
<div class="line">                    unity::scopes::Category::SCPtr(<span class="keyword">new</span> <a class="code" href="classunity_1_1scopes_1_1testing_1_1_category.html">unity::scopes::testing::Category</a>(<span class="stringliteral">&quot;id&quot;</span>, <span class="stringliteral">&quot;title&quot;</span>, <span class="stringliteral">&quot;icon&quot;</span>, renderer))</div>
<div class="line">                )</div>
<div class="line">            );</div>
<div class="line">    EXPECT_CALL(reply, register_annotation(_))</div>
<div class="line">            .Times(1)</div>
<div class="line">            .WillOnce(Return(<span class="keyword">true</span>));</div>
<div class="line">    EXPECT_CALL(reply, push(_))</div>
<div class="line">            .Times(1)</div>
<div class="line">            .WillOnce(Return(<span class="keyword">true</span>));</div>
<div class="line"></div>
<div class="line">    <a class="code" href="namespaceunity_1_1scopes.html#a9cd604d9b842ac3b2b8636c2165dec1f">unity::scopes::SearchReplyProxy</a> reply_proxy(&amp;reply, [](unity::scopes::SearchReplyBase*) {}); <span class="comment">// note: this is a std::shared_ptr with empty deleter</span></div>
<div class="line"></div>
<div class="line">    <a class="code" href="classunity_1_1scopes_1_1_canned_query.html">unity::scopes::CannedQuery</a> query(scope_id, <span class="stringliteral">&quot;&quot;</span>, <span class="stringliteral">&quot;&quot;</span>);</div>
<div class="line">    <a class="code" href="classunity_1_1scopes_1_1_search_metadata.html">unity::scopes::SearchMetadata</a> meta_data(<span class="stringliteral">&quot;en_EN&quot;</span>, <span class="stringliteral">&quot;phone&quot;</span>);</div>
<div class="line"></div>
<div class="line">    <span class="keyword">auto</span> search_query = scope-&gt;search(query, meta_data);</div>
<div class="line">    ASSERT_NE(<span class="keyword">nullptr</span>, search_query);</div>
<div class="line">    search_query-&gt;run(reply_proxy);</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="deployment"></a>
Deployment</h2>
<p>Installing a scope is as simple as running <code>make install</code> when using the scope template. You might need to restart the global scope registry when a new scope is installed by running:</p>
<pre class="fragment">restart scope-registry
</pre><p>The scope will be installed under one of the "scopes directories" scanned by the scope registry. Currently these default to:</p>
<ul>
<li>
/usr/lib/${arch}/unity-scopes </li>
<li>
<p class="startli">/custom/lib/${arch}/unity-scopes</p>
<p class="endli"></p>
</li>
</ul>
<p>Individual scopes are installed into a subdirectory matching the scope's name. At a minimum, the directory structure should contain the following: </p>
<pre class="fragment">-+- ${scopesdir}
 `-+- scopename
   |--- scopename.ini
   `--- libscopename.so
</pre><p>That is, a scope metadata file and a shared library containing the scope code. The scope author is free to ship additional data in this directory (e.g. icons and screenshots).</p>
<p>The scope metadata file uses the standard ini file format, with the following keys: </p>
<pre class="fragment">[ScopeConfig]
DisplayName = human readable name of scope
Description = description of scope
Author = Author
Icon = path to icon representing the scope
Art = path to screenshot of the scope
SearchHint = hint text displayed to user when viewing scope
HotKey =
</pre><p>In addition to allowing the registry to make the scope available, this information controls how the scope appears in the "Scopes" scope.</p>
<h2><a class="anchor" id="scopetool"></a>
Previewing scope</h2>
<p>To help with the development of a scope and to be able to see how will the dash render the dynamically-specified categories (see <a class="el" href="classunity_1_1scopes_1_1_category_renderer.html" title="A category renderer template in JSON format. ">unity::scopes::CategoryRenderer</a>), a specialized tool to preview a scope is provided - the "Unity Scope Tool".</p>
<p>You can install it from the Ubuntu archive using: </p>
<pre class="fragment">sudo apt-get install unity-scope-tool
</pre><p>After installation, you can run the scope-tool with a parameter specifying path to your scope configuration file (for example <code>unity-scope-tool ~/dev/myscope/build/myscope.ini</code>). If a binary for your scope can be found in the same directory (ie there's <code>~/dev/myscope/build/libmyscope.so</code>), the scope-tool will display surfacing and search results provided by your scope, and allow you to perform searches, invoke previews and actions within previews.</p>
<p>Note that the scope-tool is using the same rendering mechanism as Unity itself, and therefore what you see in the scope-tool is what you get in Unity. It can also be used to fine-tune the category definitions, as it allows you to manipulate the definitions on the fly, and once you're happy with the result you can just copy the JSON definition back into your scope (see <a class="el" href="classunity_1_1scopes_1_1_category_renderer.html#a046414ae2092968686ee4ee00629054a" title="Creates a CategoryRenderer from a JSON string. ">unity::scopes::CategoryRenderer::CategoryRenderer()</a>).</p>
<p>The scope-tool supports a few command line arguments: </p>
<ul>
<li>by default (without any arguments) it will communicate with all scopes installed on the system and available on the smart scopes server. </li>
<li>When a path to a scope configuration file is provided, only that scope is initialized, but you can either pass multiple configuration files or the <code>--include-system-scopes</code> / <code>--include-server-scopes</code> option to allow development of aggregating scopes. </li>
</ul>
</div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Tue Apr 8 2014 14:04:48 for Unity Scopes API by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.6 </li>
  </ul>
</div>
</body>
</html>