{"id":6486,"date":"2013-06-13T01:00:20","date_gmt":"2013-06-13T08:00:20","guid":{"rendered":"http:\/\/blog.mozilla.org\/addons\/?p=6486"},"modified":"2013-06-13T09:01:56","modified_gmt":"2013-06-13T16:01:56","slug":"jetpack-fennec-and-nativewindow","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/","title":{"rendered":"Jetpack, Fennec and NativeWindow"},"content":{"rendered":"<p>Mobile Firefox add-on development is getting more and more relevant. As Firefox for Android steadily adds users and continues to be <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=org.mozilla.firefox&amp;hl=en\" target=\"_blank\">top-rated<\/a> on Google&#8217;s Play Store we are also seeing increased traffic from millions of Android users on the Add-ons site looking for themes and extensions. We&#8217;re even <a href=\"https:\/\/hacks.mozilla.org\/?p=21053\">running a contest<\/a> to get developers interested in writing mobile extensions!<\/p>\n<p>The trouble is, we don&#8217;t have that many add-ons, in fact as of this writing there are only currently 122 extensions that are compatible with Firefox for Android. I suspect part of the problem is that Firefox on Android is different:<\/p>\n<ul>\n<li>There is no XUL on Android.<\/li>\n<li>All addons on Android need to be &#8216;restartless&#8217;.<\/li>\n<\/ul>\n<p>Needless to say, Mobile Firefox extensions are <em>different<\/em>, and so some developers may be a bit wary of jumping in with both feet. This post is a guide to show you some of the main capabilities available to you on Android in particular around UI integration and tooling.<\/p>\n<h3>Prerequisites<\/h3>\n<p>If you want to do Android-oriented development you&#8217;re going to need to install the Android SDK in order to get the <em>Android Debug Bridge<\/em> ( aka &#8216;adb&#8217; ). Head on over to the <a href=\"http:\/\/developer.android.com\/sdk\/index.html\" target=\"_blank\">Android developer portal<\/a> and follow their install instructions, and be warned it is a hefty download.<\/p>\n<p>If you don&#8217;t have an android device handy, it should be possible to run the Android emulator and install Fennec into it. In practice we&#8217;ve found this to be quite slow, using the arm emulator &#8211; one workaround might be to use the x86 emulator and x86 builds of Fennec, <a href=\"http:\/\/ftp.mozilla.org\/pub\/mozilla.org\/mobile\/nightly\/latest-mozilla-central-android-x86\/\" target=\"_blank\">which are now available<\/a>.<\/p>\n<p>In both cases, you will need to enable &#8216;USB Debugging&#8217; in the developer options &#8211; if you are running Jelly Bean ( 4.2 ) you will need to first <a href=\"http:\/\/forum.xda-developers.com\/showthread.php?t=1989777\" target=\"_blank\">read about the trick<\/a> to get the developer options to show up in settings.<\/p>\n<h3>UI Integration<\/h3>\n<p>Integrating with the Firefox for Android ( Fennec ) UI is fundamentally different than with traditional XUL add-ons due to the use of Android&#8217;s native UI. To help with this, the Fennec team has provided extension developers with two global objects they can use to do common tasks: BrowserApp and NativeWindow.<\/p>\n<p><strong>BrowserApp<\/strong> is a utility object that allows you to enumerate, fetch, open and close tabs, interact with user preferences and even quit the browser! While there is no exciting UI or system integration here, BrowserApp provides key functionality in a simple and usable way. Some annotated code samples:<\/p>\n<pre lang=\"javascript\">\/\/ Add a tab\r\nlet tab = BrowserApp.addTab();\r\n\r\n\/\/ Log the titles of all open tabs\r\nfunction logTabTitles(window) {\r\n  var tabs = window.BrowserApp.tabs;\r\n  tabs.forEach(function(tab) {\r\n    window.console.log(tab.window.document.title);\r\n  });\r\n}\r\n\r\n\/\/ Listening for tab events\r\nfunction watchTab(aEvent) {\r\n  \/\/ the target is a XUL browser element\r\n  let browser = aEvent.target;\r\n}\r\n\r\nBrowserApp.deck.addEventListener(\"TabOpen\", watchTab, false);\r\nBrowserApp.deck.addEventListener(\"TabClose\", watchTab, false);\r\nBrowserApp.deck.addEventListener(\"TabSelect\", watchTab, false);<\/pre>\n<p><em>More examples and documentation <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Extensions\/Mobile\/API\/BrowserApp\" target=\"_blank\">can be found on MDN<\/a>.<\/em><\/p>\n<p><strong>NativeWindow<\/strong> is where all the cool kids hang out.<\/p>\n<p>NativeWindow&#8217;s primary purpose is to allow developers to easily extend Fennec&#8217;s UI, via four key utilities:<\/p>\n<ul>\n<li>menu: add items to Fennec&#8217;s main menu<\/li>\n<li>doorhanger: user interactions via native doorhanger UI<\/li>\n<li>contextmenus: exactly what you think it is<\/li>\n<li>toast: not bread-related, but instead a light-weight way of doing native in-app notifications.<\/li>\n<\/ul>\n<pre lang=\"javascript\">\/\/ Add a menu item\r\nmenuID = NativeWindow.menu.add(label, icon, callback);\r\n\r\n\/\/ Show a doorhanger\r\nNativeWindow.doorhanger.show(message, value, buttons, tabID, options);\r\n\r\n\/\/ add a context menu item\r\nmenuID = NativeWindow.contextmenu.add(label, selector, callback);\r\n\r\n\/\/ show a 'toast' notification \r\nNativeWindow.toast.show(message, duration);<\/pre>\n<h3>Using the Add-on SDK<\/h3>\n<p>The Add-on SDK, which has built-in support for running and testing extensions with a device, as well as Fennec support for most relevant SDK modules. The great thing about this that if you are used to using the SDK, most modules will work as expected. For a complete of what is and isn&#8217;t supported, <a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/latest\/dev-guide\/tutorials\/mobile.html#modules-compatibility\" target=\"_blank\">please see the documentation<\/a>.<\/p>\n<p><strong>Deployment<\/strong>: just use cfx! You will need to add some mobile specific arguments to your cfx command-line though. To help with this, I&#8217;ve written a quick UNIX shell script that should help:<\/p>\n<pre lang=\"javascript\">#!\/bin\/bash\r\n\r\ncfx -b \/usr\/local\/bin\/adb --mobile-app=fennec --app=fennec-on-device --force-mobile -v -o $1<\/pre>\n<p>The above command-line assumes you are using a Firefox nightly build on your android device, other options include firefox, firefox_beta and fennec_aurora.<\/p>\n<p>While there is no built-in support for NativeWindow in the SDK, it is pretty simple to get access to it and mix and match NativeWindow&#8217;s capabilities with those included already in the SDK:<\/p>\n<pre lang=\"javascript\">\/\/ get a global window reference\r\nconst utils = require('api-utils\/window\/utils');\r\nconst recent = utils.getMostRecentBrowserWindow();\r\n\r\n\/\/ show a Toast notification\r\nrecent.NativeWindow.toast.show(\"Hello world!\", \"short\");<\/pre>\n<p>For more extensive examples of mixing the SDK with NativeWindow calls, check out my <a href=\"https:\/\/github.com\/canuckistani\/fennec-plus\/\" target=\"_blank\">&#8216;Fennec+&#8217; example extension<\/a> on Github.<\/p>\n<div class=\"wp-caption alignright\" style=\"width: 190px;\"><a href=\"https:\/\/www.dropbox.com\/sc\/m7w1osk8s3rd3tb\/efeo_gEELD#\/\" target=\"_blank\"><img decoding=\"async\" loading=\"lazy\" alt=\"\" src=\"http:\/\/blog.mozilla.org\/addons\/files\/2013\/06\/ai2Z0pLY1XDYVbvSlgXPn689txXRTk9DKlQQcbaRCmY-620x1102.png\" width=\"180\" height=\"320\" \/><\/a><\/p>\n<p class=\"wp-caption-text\">Click on the thumbnail to open a gallery in a new tab.<\/p>\n<\/div>\n<h3>The Bare-bones Approach<\/h3>\n<p>If you&#8217;re more comfortable developing a restartless add-on Mark Finkle from the Firefox for Android team has created a great template <a href=\"https:\/\/github.com\/mfinkle\/skeleton-addon-fxandroid\" target=\"_blank\">as a Github repo<\/a> to get you started. The template includes a full bootstrap.js implementation and examples of how to use NativeWindow and BrowserApp as well some simple scripts for building your extension and pushing it to a device or emulator via adb.<\/p>\n<h3>Pretty Pictures<\/h3>\n<p>To give you an idea what UI integration looks like on Android, I&#8217;ve added some screenshots to show off the various types of things:<\/p>\n<h3>Additional Resource<\/h3>\n<ul>\n<li><a href=\"https:\/\/addons.mozilla.org\/en-US\/developers\/docs\/sdk\/latest\/dev-guide\/tutorials\/mobile.html\" target=\"_blank\">Add-on SDK mobile development docs<\/a><\/li>\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Extensions\/Mobile\" target=\"_blank\">MDN Mobile Add-on docs<\/a><\/li>\n<li><a href=\"http:\/\/developer.android.com\/sdk\/index.html\" target=\"_blank\">Android SDK site<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Mobile Firefox add-on development is getting more and more relevant. As Firefox for Android steadily adds users and continues to be top-rated on Google&#8217;s Play Store we are also seeing &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/\">Read more<\/a><\/p>\n","protected":false},"author":316,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6744,44,588,124,742],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Jetpack, Fennec and NativeWindow - Mozilla Add-ons Community Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeff Griffiths\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/\",\"url\":\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/\",\"name\":\"Jetpack, Fennec and NativeWindow - Mozilla Add-ons Community Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/blog.mozilla.org\/addons\/files\/2013\/06\/ai2Z0pLY1XDYVbvSlgXPn689txXRTk9DKlQQcbaRCmY-620x1102.png\",\"datePublished\":\"2013-06-13T08:00:20+00:00\",\"dateModified\":\"2013-06-13T16:01:56+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/e2f4c71eb45392ea29162432c3f1d433\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#primaryimage\",\"url\":\"http:\/\/blog.mozilla.org\/addons\/files\/2013\/06\/ai2Z0pLY1XDYVbvSlgXPn689txXRTk9DKlQQcbaRCmY-620x1102.png\",\"contentUrl\":\"http:\/\/blog.mozilla.org\/addons\/files\/2013\/06\/ai2Z0pLY1XDYVbvSlgXPn689txXRTk9DKlQQcbaRCmY-620x1102.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/addons\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Jetpack, Fennec and NativeWindow\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/addons\/\",\"name\":\"Mozilla Add-ons Community Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/addons\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/e2f4c71eb45392ea29162432c3f1d433\",\"name\":\"Jeff Griffiths\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/b07ae75dd1a5414bf30d7f773ccfc894?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/b07ae75dd1a5414bf30d7f773ccfc894?s=96&d=mm&r=g\",\"caption\":\"Jeff Griffiths\"},\"description\":\"Jeff is Product Manager for the Firefox Developer Tools and occasional Open Web hacker, based in Vancouver, BC.\",\"sameAs\":[\"http:\/\/canuckistani.ca\/\",\"https:\/\/x.com\/canuckistani\"],\"url\":\"https:\/\/blog.mozilla.org\/addons\/author\/jgriffithsmozilla-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Jetpack, Fennec and NativeWindow - Mozilla Add-ons Community Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/","twitter_misc":{"Written by":"Jeff Griffiths","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/","url":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/","name":"Jetpack, Fennec and NativeWindow - Mozilla Add-ons Community Blog","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/addons\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#primaryimage"},"image":{"@id":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#primaryimage"},"thumbnailUrl":"http:\/\/blog.mozilla.org\/addons\/files\/2013\/06\/ai2Z0pLY1XDYVbvSlgXPn689txXRTk9DKlQQcbaRCmY-620x1102.png","datePublished":"2013-06-13T08:00:20+00:00","dateModified":"2013-06-13T16:01:56+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/e2f4c71eb45392ea29162432c3f1d433"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#primaryimage","url":"http:\/\/blog.mozilla.org\/addons\/files\/2013\/06\/ai2Z0pLY1XDYVbvSlgXPn689txXRTk9DKlQQcbaRCmY-620x1102.png","contentUrl":"http:\/\/blog.mozilla.org\/addons\/files\/2013\/06\/ai2Z0pLY1XDYVbvSlgXPn689txXRTk9DKlQQcbaRCmY-620x1102.png"},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/addons\/2013\/06\/13\/jetpack-fennec-and-nativewindow\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/addons\/"},{"@type":"ListItem","position":2,"name":"Jetpack, Fennec and NativeWindow"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/addons\/#website","url":"https:\/\/blog.mozilla.org\/addons\/","name":"Mozilla Add-ons Community Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/addons\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/e2f4c71eb45392ea29162432c3f1d433","name":"Jeff Griffiths","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/addons\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/b07ae75dd1a5414bf30d7f773ccfc894?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b07ae75dd1a5414bf30d7f773ccfc894?s=96&d=mm&r=g","caption":"Jeff Griffiths"},"description":"Jeff is Product Manager for the Firefox Developer Tools and occasional Open Web hacker, based in Vancouver, BC.","sameAs":["http:\/\/canuckistani.ca\/","https:\/\/x.com\/canuckistani"],"url":"https:\/\/blog.mozilla.org\/addons\/author\/jgriffithsmozilla-com\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts\/6486"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/users\/316"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/comments?post=6486"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/posts\/6486\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/media?parent=6486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/categories?post=6486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/addons\/wp-json\/wp\/v2\/tags?post=6486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}