summaryrefslogtreecommitdiffstats
path: root/native_client_sdk/doc_generated/devguide/distributing.html
blob: 31041608001b7bdd1e9c771265c1add0a7fd484a (plain)
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
{{+bindTo:partials.standard_nacl_article}}

<section id="distributing-your-application">
<span id="distributing"></span><h1 id="distributing-your-application"><span id="distributing"></span>Distributing Your Application</h1>
<div class="contents local" id="contents" style="display: none">
<ul class="small-gap">
<li><a class="reference internal" href="#portable-native-client" id="id1">Portable Native Client</a></li>
<li><p class="first"><a class="reference internal" href="#non-portable-native-client" id="id2">Non-portable Native Client</a></p>
<ul class="small-gap">
<li><a class="reference internal" href="#packaged-application" id="id3">Packaged application</a></li>
<li><a class="reference internal" href="#extension" id="id4">Extension</a></li>
<li><a class="reference internal" href="#hosted-application" id="id5">Hosted application</a></li>
<li><a class="reference internal" href="#registering-native-client-modules-to-handle-mime-types" id="id6">Registering Native Client modules to handle MIME types</a></li>
</ul>
</li>
</ul>

</div><p>This document describes how to distribute Portable Native Client applications
on the web, and Native Client applications through the
<a class="reference external" href="/webstore">Chrome Web Store</a> (CWS).</p>
<h2 id="portable-native-client">Portable Native Client</h2>
<p>Portable Native Client is enabled by default for web pages, so no separate
distribution step is requred. Making PNaCl a part of your web application is as
simple as embedding a manifest file that points to a <strong>pexe</strong>. See the
<a class="reference internal" href="/native-client/overview.html"><em>technical overview</em></a> for more details.</p>
<img alt="/native-client/images/nacl-in-a-web-app.png" src="/native-client/images/nacl-in-a-web-app.png" />
<p>The only constraint for distributing PNaCl modules with a web application is
abiding by the <a class="reference external" href="http://en.wikipedia.org/wiki/Same_origin_policy">Same-origin policy</a>. The PNaCl manifest and
<strong>pexe</strong> must either be served from the same domain with the HTML, or the <a class="reference external" href="http://en.wikipedia.org/wiki/Cross-origin_resource_sharing">CORS
mechanism</a> should
be used to safely host them on a different domain.</p>
<h2 id="non-portable-native-client">Non-portable Native Client</h2>
<p>NaCl modules are only allowed for applications distributed through the <a class="reference external" href="https://chrome.google.com/webstore/category/apps">Chrome
Web Store (CWS)</a>
The CWS requirement is in place to prevent the proliferation of Native Client
executables (<strong>nexe</strong>s) compiled for specific architecures (e.g., x86-32,
x86-64, or ARM).</p>
<p>In general, the considerations and guidelines for distributing applications
through the Chrome Web Store apply to applications that contain NaCl modules as
well. Here are a few pointers to relevant documentation:</p>
<ul class="small-gap">
<li><a class="reference external" href="/webstore">CWS Overview</a></li>
<li><a class="reference external" href="/webstore/choosing">Choosing an App Type</a></li>
<li><a class="reference external" href="/apps/about_apps">Getting started with packaged apps</a></li>
<li><a class="reference external" href="https://developers.google.com/chrome/apps/docs/developers_guide">Hosted apps</a></li>
<li><a class="reference external" href="/extensions">Chrome extensions</a></li>
</ul>
<p>In this document, we&#8217;ll focus only on distribution issues specific to
applications that contain NaCl modules.</p>
<h3 id="packaged-application"><span id="distributing-packaged"></span>Packaged application</h3>
<p>A packaged application is a special zip file (with a .crx extension) hosted in
the Chrome Web Store. This file contains all of the application parts: A Chrome
Web Store manifest file (manifest.json), an icon, and all of the regular Native
Client application files. Refer to
<a class="reference external" href="/apps/about_apps">Packaged Apps</a>
for more information about creating a packaged application.</p>
<h4 id="reducing-the-size-of-the-user-download-package">Reducing the size of the user download package</h4>
<aside class="note">
<strong>Tip:</strong>
Packaging an app in a multi-platform zip file can significantly reduce the
download and storage requirements for the app.
</aside>
<p>As described above, to upload a packaged app to the CWS you have to create a zip
file with all the resources that your app needs, including .nexe files for
multiple architectures (x86-64, x86-32, and ARM). Prior to Chrome 28, when users
installed your app they had to download a .crx file from the CWS with all the
included .nexe files.</p>
<p>Starting with Chrome 28, the Chrome Web Store includes a feature called
<strong>multi-platform zip files.</strong> This feature lets you structure your application
directory and zip file in a way that reduces the size of the user download
package.  Here&#8217;s how this feature works:</p>
<ul class="small-gap">
<li>You still include all the .nexe files in the zip file that you upload to
the CWS, but you designate specific .nexe files (and other files if
appropriate) for specific architectures.</li>
<li>The Chrome Web Store re-packages your app, so that users only download
the files that they need for their specific architecture.</li>
</ul>
<p>Here is how to use this feature:</p>
<ol class="arabic">
<li><p class="first">Create a directory called <code>_platform_specific</code>.
Put this directory at the same level where your CWS manifest file,
<code>manifest.json</code>, is located.</p>
</li>
<li><p class="first">Create a subdirectory for each specific architecture that you support,
and add the files for each architecture in the relevant subdirectory.</p>
<p>Here is a sample app directory structure:</p>
<pre>
|-- my_app_directory/
|       |-- manifest.json
|       |-- my_app.html
|       |-- my_module.nmf
|       +-- css/
|       +-- images/
|       +-- scripts/
|       |-- _platform_specific/
|       |       |-- x86-64/
|       |       |       |-- my_module_x86_64.nexe
|       |       |-- x86-32/
|       |       |       |-- my_module_x86_32.nexe
|       |       |-- arm/
|       |       |       |-- my_module_arm.nexe
|       |       |-- all/
|       |       |       |-- my_module_x86_64.nexe
|       |       |       |-- my_module_x86_64.nexe
|       |       |       |-- my_module_x86_32.nexe
</pre>
<p>Please note a few important points about the app directory structure:</p>
<ul class="small-gap">
<li><p class="first">The architecture-specific subdirectories:</p>
<ul class="small-gap">
<li><p class="first">can have arbitrary names;</p>
</li>
<li><p class="first">must be directly under the <code>_platform_specific</code> directory; and</p>
</li>
<li><p class="first">must be listed in the CWS manifest file (see step 3 below).</p>
</li>
</ul>
</li>
<li><p class="first">You can include a fallback subdirectory that provides a download package
with all the architecture-specific files.  (In the example above this
is the <code>all/</code> subdirectory.) This folder is used if the user has an
earlier version of Chrome (prior to Chrome 28) that does not support
multi-platform zip files.</p>
</li>
<li><p class="first">You cannot include any files directly in the folder
<code>_platform_specific</code>.  All architecture-specific files
must be under one of the architecture-specific subdirectories.</p>
</li>
<li><p class="first">Files that are not under the <code>_platform_specific</code> directory are
included in all download packages.  (In the example above, that
includes <code>my_app.html</code>, <code>my_module.nmf</code>,
and the <code>css/</code>, <code>images/</code>, and <code>scripts/</code> directories.)</p>
</li>
</ul>
</li>
<li><p class="first">Modify the CWS manifest file, <code>manifest.json</code>, so that it specifies which
subdirectory under <code>_platform_specific</code> corresponds to which architecture.</p>
<p>The CWS manifest file must include a new name/value pair, where the name
is <code>platforms</code> and the value is an array.  The array has an object for
each Native Client architecture with two name/value pairs:</p>
<table border="1" class="docutils">
<colgroup>
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Name</th>
<th class="head">Value</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><code>nacl_arch</code></td>
<td><code>x86-64</code>, <code>x86-32</code>, or <code>arm</code></td>
</tr>
<tr class="row-odd"><td><code>sub_package_path</code></td>
<td>the path of the directory (starting
with <code>_platform_specific</code>) that
contains the files for the designated
NaCl architecture</td>
</tr>
</tbody>
</table>
<p>Here is a sample <code>manifest.json</code> file:</p>
<pre>
{
  &quot;name&quot;: &quot;My Reminder App&quot;,
  &quot;description&quot;: &quot;A reminder app that syncs across Chrome browsers.&quot;,
  &quot;manifest_version&quot;: 2,
  &quot;minimum_chrome_version&quot;: &quot;28&quot;,
  &quot;offline_enabled&quot;: true,
  &quot;version&quot;: &quot;0.3&quot;,
  &quot;permissions&quot;: [
    {&quot;fileSystem&quot;: [&quot;write&quot;]},
    &quot;alarms&quot;,
    &quot;storage&quot;
  ],
  &quot;app&quot;: {
    &quot;background&quot;: {
      &quot;scripts&quot;: [&quot;scripts/background.js&quot;]
    }
  },
  &quot;icons&quot;: {
    &quot;16&quot;: &quot;images/icon-16x16.png&quot;,
    &quot;128&quot;: &quot;images/icon-128x128.png&quot;
  },
  &quot;platforms&quot;: [
    {
      &quot;nacl_arch&quot;: &quot;x86-64&quot;,
      &quot;sub_package_path&quot;: &quot;_platform_specific/x86-64/&quot;
    },
    {
      &quot;nacl_arch&quot;: &quot;x86-32&quot;,
      &quot;sub_package_path&quot;: &quot;_platform_specific/x86-32/&quot;
    },
    {
      &quot;nacl_arch&quot;: &quot;arm&quot;,
      &quot;sub_package_path&quot;: &quot;_platform_specific/arm/&quot;
    },
    {
      &quot;sub_package_path&quot;: &quot;_platform_specific/all/&quot;
    }
  ]
}
</pre>
<p>Note the last entry in the CWS manifest file above, which specifies a
<code>sub_package_path</code> without a corresponding <code>nacl_arch</code>. This entry
identifies the fallback directory, which is included in the download
package if the user architecture does not match any of the listed NaCl
architectures, or if the user is using an older version of Chrome that
does not support multi-platform zip files.</p>
</li>
<li><p class="first">Modify your application as necessary so that it uses the files for the
correct user architecture.</p>
<p>To reference architecture-specific files, use the JavaScript API
<a class="reference external" href="/extensions/runtime.html#method-getPlatformInfo">chrome.runtime.getPlatformInfo()</a>.
As an example, if you have architecture-specific files in the directories
<code>x86-64</code>, <code>x86-32</code>, and <code>arm</code>, you can use the following JavaScript
code to create a path for the files:</p>
<pre class="prettyprint">
function getPath(name) {
  return '_platform_specific/' +
    chrome.runtime.getPlatformInfo().nacl_arch +
    '/' + name;
}
</pre>
</li>
<li><p class="first">Test your app, create a zip file, and upload the app to the CWS as before.</p>
</li>
</ol>
<h4 id="additional-considerations-for-a-packaged-application"><span id="additional-considerations-packaged"></span>Additional considerations for a packaged application</h4>
<ul class="small-gap">
<li>In the description of your application in the CWS, make sure to mention that
your application is a Native Client application that only works with the
Chrome browser. Also make sure to identify the minimum version of Chrome
that your application requires.</li>
<li><p class="first">Hosted and packaged applications have a &#8220;launch&#8221; parameter in the CWS
manifest. This parameter is present only in apps (not extensions), and it
tells Google Chrome what to show when a user starts an installed app. For
example:</p>
<pre>
&quot;launch&quot;: {
  &quot;web_url&quot;: &quot;http://mail.google.com/mail/&quot;
}
</pre>
</li>
<li>If you want to write local data using the Pepper
<a class="reference external" href="/native-client/peppercpp/classpp_1_1_file_i_o">FileIO</a>
API, you must set the &#8216;unlimitedStorage&#8217; permission in your Chrome Web
Store manifest file, just as you would for a JavaScript application that
uses the HTML5 File API.</li>
<li>For packaged applications, you can only use in-app purchases.</li>
<li>You can place your application in the Google Web Store with access only to
certain people for testing. See <a class="reference external" href="/webstore/publish">Publishing to test accounts</a> for more information.</li>
</ul>
<h3 id="extension">Extension</h3>
<p>The NaCl-specific notes for a <a class="reference internal" href="#distributing-packaged"><em>package application</em></a>
apply to extensions as well.</p>
<h3 id="hosted-application">Hosted application</h3>
<p>The .html file, .nmf file (Native Client manifest file), and .nexe files must
be served from the same domain, and the Chrome Web Store manifest file must
specify the correct, verified domain. Other files can be served from the same
or another domain.</p>
<p>In addition, see <a class="reference internal" href="#additional-considerations-packaged"><em>Additional considerations for a packaged application</em></a>.</p>
<h3 id="registering-native-client-modules-to-handle-mime-types">Registering Native Client modules to handle MIME types</h3>
<p>If you want Chrome to use a Native Client module to display a particular type
of content, you can associate the MIME type of that content with the Native
Client module. Use the <code>nacl_modules</code> attribute in the Chrome Web Store
manifest file to register a Native Client module as the handler for one or more
specific MIME types. For example, the bold code in the snippet below registers
a Native Client module as the content handler for the OpenOffice spreadsheet
MIME type:</p>
<pre>
{
   &quot;name&quot;: &quot;My Native Client Spreadsheet Viewer&quot;,
   &quot;version&quot;: &quot;0.1&quot;,
   &quot;description&quot;: &quot;Open spreadsheets right in your browser.&quot;,
   &quot;nacl_modules&quot;: [{
      &quot;path&quot;: &quot;SpreadsheetViewer.nmf&quot;,
      &quot;mime_type&quot;: &quot;application/vnd.oasis.opendocument.spreadsheet&quot;
   }]
}
</pre>
<p>The value of &#8220;path&#8221; is the location of a Native Client manifest file (.nmf)
within the application directory. For more information on Native Client
manifest files, see <a class="reference internal" href="/native-client/devguide/coding/application-structure.html#manifest-file"><em>Manifest Files</em></a>.</p>
<p>The value of &#8220;mime_type&#8221; is a specific MIME type that you want the Native
Client module to handle. Each MIME type can be associated with only one .nmf
file, but a single .nmf file might handle multiple MIME types. The following
example shows an extension with two .nmf files that handle three MIME types.</p>
<pre>
{
   &quot;name&quot;: &quot;My Native Client Spreadsheet and Document Viewer&quot;,
   &quot;version&quot;: &quot;0.1&quot;,
   &quot;description&quot;: &quot;Open spreadsheets and documents right in your browser.&quot;,
   &quot;nacl_modules&quot;: [{
     &quot;path&quot;: &quot;SpreadsheetViewer.nmf&quot;,
     &quot;mime_type&quot;: &quot;application/vnd.oasis.opendocument.spreadsheet&quot;
   },
   {
      &quot;path&quot;: &quot;SpreadsheetViewer.nmf&quot;,
      &quot;mime_type&quot;: &quot;application/vnd.oasis.opendocument.spreadsheet-template&quot;
   },
   {
      &quot;path&quot;: &quot;DocumentViewer.nmf&quot;,
      &quot;mime_type&quot;: &quot;application/vnd.oasis.opendocument.text&quot;
   }]
}
</pre>
<p>The <code>nacl_modules</code> attribute is optional&#8212;specify this attribute only if
you want Chrome to use a Native Client module to display a particular type of
content.</p>
</section>

{{/partials.standard_nacl_article}}