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