Home | History | Annotate | Download | only in devguide
      1 .. _distributing:
      2 
      3 #############################
      4 Distributing Your Application
      5 #############################
      6 
      7 .. contents::
      8   :local:
      9   :backlinks: none
     10   :depth: 2
     11 
     12 This document describes how to distribute Portable Native Client applications
     13 on the web, and Native Client applications through the
     14 `Chrome Web Store </webstore>`_ (CWS).
     15 
     16 Portable Native Client
     17 ======================
     18 
     19 Portable Native Client is enabled by default for web pages, so no separate
     20 distribution step is requred. Making PNaCl a part of your web application is as
     21 simple 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 
     26 The only constraint for distributing PNaCl modules with a web application is
     27 abiding 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
     30 mechanism <http://en.wikipedia.org/wiki/Cross-origin_resource_sharing>`_ should
     31 be used to safely host them on a different domain.
     32 
     33 Non-portable Native Client
     34 ==========================
     35 
     36 NaCl modules are only allowed for applications distributed through the `Chrome
     37 Web Store (CWS) <https://chrome.google.com/webstore/category/apps>`_
     38 The CWS requirement is in place to prevent the proliferation of Native Client
     39 executables (**nexe**\s) compiled for specific architecures (e.g., x86-32,
     40 x86-64, or ARM).
     41 
     42 In general, the considerations and guidelines for distributing applications
     43 through the Chrome Web Store apply to applications that contain NaCl modules as
     44 well. 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 
     52 In this document, we'll focus only on distribution issues specific to
     53 applications that contain NaCl modules.
     54 
     55 .. _distributing_packaged:
     56 
     57 Packaged application
     58 --------------------
     59 
     60 A packaged application is a special zip file (with a .crx extension) hosted in
     61 the Chrome Web Store. This file contains all of the application parts: A Chrome
     62 Web Store manifest file (manifest.json), an icon, and all of the regular Native
     63 Client application files. Refer to
     64 `Packaged Apps </apps/about_apps>`_
     65 for more information about creating a packaged application.
     66 
     67 Reducing 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 
     77 As described above, to upload a packaged app to the CWS you have to create a zip
     78 file with all the resources that your app needs, including .nexe files for
     79 multiple architectures (x86-64, x86-32, and ARM). Prior to Chrome 28, when users
     80 installed your app they had to download a .crx file from the CWS with all the
     81 included .nexe files.
     82 
     83 Starting with Chrome 28, the Chrome Web Store includes a feature called
     84 **multi-platform zip files.** This feature lets you structure your application
     85 directory and zip file in a way that reduces the size of the user download
     86 package.  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 
     94 Here 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 
    242 Additional 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 
    271 Extension
    272 ---------
    273 
    274 The NaCl-specific notes for a :ref:`package application <distributing_packaged>`
    275 apply to extensions as well.
    276 
    277 Hosted application
    278 ------------------
    279 
    280 The .html file, .nmf file (Native Client manifest file), and .nexe files must
    281 be served from the same domain, and the Chrome Web Store manifest file must
    282 specify the correct, verified domain. Other files can be served from the same
    283 or another domain.
    284 
    285 In addition, see :ref:`Additional considerations for a packaged application <additional_considerations_packaged>`.
    286 
    287 Registering Native Client modules to handle MIME types
    288 ------------------------------------------------------
    289 
    290 If you want Chrome to use a Native Client module to display a particular type
    291 of content, you can associate the MIME type of that content with the Native
    292 Client module. Use the ``nacl_modules`` attribute in the Chrome Web Store
    293 manifest file to register a Native Client module as the handler for one or more
    294 specific MIME types. For example, the bold code in the snippet below registers
    295 a Native Client module as the content handler for the OpenOffice spreadsheet
    296 MIME 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 
    311 The value of "path" is the location of a Native Client manifest file (.nmf)
    312 within the application directory. For more information on Native Client
    313 manifest files, see :ref:`Manifest Files <manifest_file>`.
    314 
    315 The value of "mime_type" is a specific MIME type that you want the Native
    316 Client module to handle. Each MIME type can be associated with only one .nmf
    317 file, but a single .nmf file might handle multiple MIME types. The following
    318 example 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 
    341 The ``nacl_modules`` attribute is optional---specify this attribute only if
    342 you want Chrome to use a Native Client module to display a particular type of
    343 content.
    344 
    345