• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _distributing:
2
3#############################
4Distributing Your Application
5#############################
6
7.. contents::
8  :local:
9  :backlinks: none
10  :depth: 2
11
12This document describes how to distribute Portable Native Client applications
13on the web, and Native Client applications through the
14`Chrome Web Store </webstore>`_ (CWS).
15
16Portable Native Client
17======================
18
19Portable Native Client is enabled by default for web pages, so no separate
20distribution step is requred. Making PNaCl a part of your web application is as
21simple as embedding a manifest file that points to a **pexe**. See the
22:doc:`technical overview <../overview>` for more details.
23
24.. image:: /images/nacl-in-a-web-app.png
25
26The only constraint for distributing PNaCl modules with a web application is
27abiding by the `Same-origin policy
28<http://en.wikipedia.org/wiki/Same_origin_policy>`_. The PNaCl manifest and
29**pexe** must either be served from the same domain with the HTML, or the `CORS
30mechanism <http://en.wikipedia.org/wiki/Cross-origin_resource_sharing>`_ should
31be used to safely host them on a different domain.
32
33Non-portable Native Client
34==========================
35
36NaCl modules are only allowed for applications distributed through the `Chrome
37Web Store (CWS) <https://chrome.google.com/webstore/category/apps>`_
38The CWS requirement is in place to prevent the proliferation of Native Client
39executables (**nexe**\s) compiled for specific architecures (e.g., x86-32,
40x86-64, or ARM).
41
42In general, the considerations and guidelines for distributing applications
43through the Chrome Web Store apply to applications that contain NaCl modules as
44well. Here are a few pointers to relevant documentation:
45
46* `CWS Overview </webstore>`_
47* `Choosing an App Type </webstore/choosing>`_
48* `Getting started with packaged apps </apps/about_apps>`_
49* `Hosted apps <https://developers.google.com/chrome/apps/docs/developers_guide>`_
50* `Chrome extensions </extensions>`_
51
52In this document, we'll focus only on distribution issues specific to
53applications that contain NaCl modules.
54
55.. _distributing_packaged:
56
57Packaged application
58--------------------
59
60A packaged application is a special zip file (with a .crx extension) hosted in
61the Chrome Web Store. This file contains all of the application parts: A Chrome
62Web Store manifest file (manifest.json), an icon, and all of the regular Native
63Client application files. Refer to
64`Packaged Apps </apps/about_apps>`_
65for more information about creating a packaged application.
66
67Reducing the size of the user download package
68^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
69
70.. Note::
71   :class: note
72
73   **Tip:**
74   Packaging an app in a multi-platform zip file can significantly reduce the
75   download and storage requirements for the app.
76
77As described above, to upload a packaged app to the CWS you have to create a zip
78file with all the resources that your app needs, including .nexe files for
79multiple architectures (x86-64, x86-32, and ARM). Prior to Chrome 28, when users
80installed your app they had to download a .crx file from the CWS with all the
81included .nexe files.
82
83Starting with Chrome 28, the Chrome Web Store includes a feature called
84**multi-platform zip files.** This feature lets you structure your application
85directory and zip file in a way that reduces the size of the user download
86package.  Here's how this feature works:
87
88* You still include all the .nexe files in the zip file that you upload to
89  the CWS, but you designate specific .nexe files (and other files if
90  appropriate) for specific architectures.
91* The Chrome Web Store re-packages your app, so that users only download
92  the files that they need for their specific architecture.
93
94Here is how to use this feature:
95
96#. Create a directory called ``_platform_specific``.
97   Put this directory at the same level where your CWS manifest file,
98   ``manifest.json``, is located.
99
100#. Create a subdirectory for each specific architecture that you support,
101   and add the files for each architecture in the relevant subdirectory.
102
103   Here is a sample app directory structure:
104
105   .. naclcode::
106     :prettyprint: 0
107
108     |-- my_app_directory/
109     |       |-- manifest.json
110     |       |-- my_app.html
111     |       |-- my_module.nmf
112     |       +-- css/
113     |       +-- images/
114     |       +-- scripts/
115     |       |-- _platform_specific/
116     |       |       |-- x86-64/
117     |       |       |       |-- my_module_x86_64.nexe
118     |       |       |-- x86-32/
119     |       |       |       |-- my_module_x86_32.nexe
120     |       |       |-- arm/
121     |       |       |       |-- my_module_arm.nexe
122     |       |       |-- all/
123     |       |       |       |-- my_module_x86_64.nexe
124     |       |       |       |-- my_module_x86_64.nexe
125     |       |       |       |-- my_module_x86_32.nexe
126
127   Please note a few important points about the app directory structure:
128
129   * The architecture-specific subdirectories:
130
131     * can have arbitrary names;
132     * must be directly under the ``_platform_specific`` directory; and
133     * must be listed in the CWS manifest file (see step 3 below).
134
135   * You can include a fallback subdirectory that provides a download package
136     with all the architecture-specific files.  (In the example above this
137     is the ``all/`` subdirectory.) This folder is used if the user has an
138     earlier version of Chrome (prior to Chrome 28) that does not support
139     multi-platform zip files.
140
141   * You cannot include any files directly in the folder
142     ``_platform_specific``.  All architecture-specific files
143     must be under one of the architecture-specific subdirectories.
144
145   * Files that are not under the ``_platform_specific`` directory are
146     included in all download packages.  (In the example above, that
147     includes ``my_app.html``, ``my_module.nmf``,
148     and the ``css/``, ``images/``, and ``scripts/`` directories.)
149
150
151#. Modify the CWS manifest file, ``manifest.json``, so that it specifies which
152   subdirectory under ``_platform_specific`` corresponds to which architecture.
153
154   The CWS manifest file must include a new name/value pair, where the name
155   is ``platforms`` and the value is an array.  The array has an object for
156   each Native Client architecture with two name/value pairs:
157
158   +----------------------+---------------------------------------+
159   | Name                 | Value                                 |
160   +======================+=======================================+
161   | ``nacl_arch``        | ``x86-64``, ``x86-32``, or ``arm``    |
162   +----------------------+---------------------------------------+
163   | ``sub_package_path`` | the path of the directory (starting   |
164   |                      | with ``_platform_specific``) that     |
165   |                      | contains the files for the designated |
166   |                      | NaCl architecture                     |
167   +----------------------+---------------------------------------+
168
169   Here is a sample ``manifest.json`` file:
170
171   .. naclcode::
172     :prettyprint: 0
173
174     {
175       "name": "My Reminder App",
176       "description": "A reminder app that syncs across Chrome browsers.",
177       "manifest_version": 2,
178       "minimum_chrome_version": "28",
179       "offline_enabled": true,
180       "version": "0.3",
181       "permissions": [
182         {"fileSystem": ["write"]},
183         "alarms",
184         "storage"
185       ],
186       "app": {
187         "background": {
188           "scripts": ["scripts/background.js"]
189         }
190       },
191       "icons": {
192         "16": "images/icon-16x16.png",
193         "128": "images/icon-128x128.png"
194       },
195       "platforms": [
196         {
197           "nacl_arch": "x86-64",
198           "sub_package_path": "_platform_specific/x86-64/"
199         },
200         {
201           "nacl_arch": "x86-32",
202           "sub_package_path": "_platform_specific/x86-32/"
203         },
204         {
205           "nacl_arch": "arm",
206           "sub_package_path": "_platform_specific/arm/"
207         },
208         {
209           "sub_package_path": "_platform_specific/all/"
210         }
211       ]
212     }
213
214   Note the last entry in the CWS manifest file above, which specifies a
215   ``sub_package_path`` without a corresponding ``nacl_arch``. This entry
216   identifies the fallback directory, which is included in the download
217   package if the user architecture does not match any of the listed NaCl
218   architectures, or if the user is using an older version of Chrome that
219   does not support multi-platform zip files.
220
221#. Modify your application as necessary so that it uses the files for the
222   correct user architecture.
223
224   To reference architecture-specific files, use the JavaScript API
225   `chrome.runtime.getPlatformInfo() </extensions/runtime.html#method-getPlatformInfo>`_.
226   As an example, if you have architecture-specific files in the directories
227   ``x86-64``, ``x86-32``, and ``arm``, you can use the following JavaScript
228   code to create a path for the files:
229
230   .. naclcode::
231
232      function getPath(name) {
233        return '_platform_specific/' +
234          chrome.runtime.getPlatformInfo().nacl_arch +
235          '/' + name;
236      }
237
238#. Test your app, create a zip file, and upload the app to the CWS as before.
239
240.. _additional_considerations_packaged:
241
242Additional considerations for a packaged application
243^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
244
245* In the description of your application in the CWS, make sure to mention that
246  your application is a Native Client application that only works with the
247  Chrome browser. Also make sure to identify the minimum version of Chrome
248  that your application requires.
249* Hosted and packaged applications have a "launch" parameter in the CWS
250  manifest. This parameter is present only in apps (not extensions), and it
251  tells Google Chrome what to show when a user starts an installed app. For
252  example:
253
254  .. naclcode::
255    :prettyprint: 0
256
257    "launch": {
258      "web_url": "http://mail.google.com/mail/"
259    }
260
261* If you want to write local data using the Pepper
262  `FileIO </native-client/peppercpp/classpp_1_1_file_i_o>`_
263  API, you must set the 'unlimitedStorage' permission in your Chrome Web
264  Store manifest file, just as you would for a JavaScript application that
265  uses the HTML5 File API.
266* For packaged applications, you can only use in-app purchases.
267* You can place your application in the Google Web Store with access only to
268  certain people for testing. See `Publishing to test accounts
269  </webstore/publish>`_ for more information.
270
271Extension
272---------
273
274The NaCl-specific notes for a :ref:`package application <distributing_packaged>`
275apply to extensions as well.
276
277Hosted application
278------------------
279
280The .html file, .nmf file (Native Client manifest file), and .nexe files must
281be served from the same domain, and the Chrome Web Store manifest file must
282specify the correct, verified domain. Other files can be served from the same
283or another domain.
284
285In addition, see :ref:`Additional considerations for a packaged application <additional_considerations_packaged>`.
286
287Registering Native Client modules to handle MIME types
288------------------------------------------------------
289
290If you want Chrome to use a Native Client module to display a particular type
291of content, you can associate the MIME type of that content with the Native
292Client module. Use the ``nacl_modules`` attribute in the Chrome Web Store
293manifest file to register a Native Client module as the handler for one or more
294specific MIME types. For example, the bold code in the snippet below registers
295a Native Client module as the content handler for the OpenOffice spreadsheet
296MIME type:
297
298.. naclcode::
299  :prettyprint: 0
300
301  {
302     "name": "My Native Client Spreadsheet Viewer",
303     "version": "0.1",
304     "description": "Open spreadsheets right in your browser.",
305     "nacl_modules": [{
306        "path": "SpreadsheetViewer.nmf",
307        "mime_type": "application/vnd.oasis.opendocument.spreadsheet"
308     }]
309  }
310
311The value of "path" is the location of a Native Client manifest file (.nmf)
312within the application directory. For more information on Native Client
313manifest files, see :ref:`Manifest Files <manifest_file>`.
314
315The value of "mime_type" is a specific MIME type that you want the Native
316Client module to handle. Each MIME type can be associated with only one .nmf
317file, but a single .nmf file might handle multiple MIME types. The following
318example shows an extension with two .nmf files that handle three MIME types.
319
320.. naclcode::
321  :prettyprint: 0
322
323  {
324     "name": "My Native Client Spreadsheet and Document Viewer",
325     "version": "0.1",
326     "description": "Open spreadsheets and documents right in your browser.",
327     "nacl_modules": [{
328       "path": "SpreadsheetViewer.nmf",
329       "mime_type": "application/vnd.oasis.opendocument.spreadsheet"
330     },
331     {
332        "path": "SpreadsheetViewer.nmf",
333        "mime_type": "application/vnd.oasis.opendocument.spreadsheet-template"
334     },
335     {
336        "path": "DocumentViewer.nmf",
337        "mime_type": "application/vnd.oasis.opendocument.text"
338     }]
339  }
340
341The ``nacl_modules`` attribute is optional---specify this attribute only if
342you want Chrome to use a Native Client module to display a particular type of
343content.
344
345