Bug 708484 - Add camera capture stream provider for gonk (temporary solution) - get camera working in webpages [r=bz]
authorFabrice Desré <fabrice@mozilla.com>
Mon, 06 Feb 2012 22:48:50 -0800
changeset 86289 6234bb0a5f4255702b2737997feeeb62c3f8fd78
parent 86288 5620daafb931d04416b360e115a4cd738cab5756
child 86290 25edb41d01190137eb640019dbc23851f618ed6b
push id5774
push userfdesre@mozilla.com
push dateTue, 07 Feb 2012 06:49:18 +0000
treeherdermozilla-inbound@6234bb0a5f42 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs708484
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 708484 - Add camera capture stream provider for gonk (temporary solution) - get camera working in webpages [r=bz]
b2g/app/b2g.js
b2g/chrome/content/shell.js
b2g/components/B2GComponents.manifest
b2g/components/CameraContent.js
b2g/components/Makefile.in
b2g/components/b2g.idl
b2g/installer/package-manifest.in
netwerk/build/nsNetCID.h
netwerk/build/nsNetModule.cpp
netwerk/protocol/device/Makefile.in
netwerk/protocol/device/nsB2GProtocolHandler.cpp
netwerk/protocol/device/nsB2GProtocolHandler.h
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -408,16 +408,20 @@ pref("dom.mozBrowserFramesWhitelist", "h
 
 // Temporary permission hack for WebSMS
 pref("dom.sms.enabled", true);
 pref("dom.sms.whitelist", "file://,http://localhost:6666");
 
 // Ignore X-Frame-Options headers.
 pref("b2g.ignoreXFrameOptions", true);
 
+// controls if we want camera support
+pref("device.camera.enabled", true);
+pref("media.realtime_decoder.enabled", true);
+
 // "Preview" landing of bug 710563, which is bogged down in analysis
 // of talos regression.  This is a needed change for higher-framerate
 // CSS animations, and incidentally works around an apparent bug in
 // our handling of requestAnimationFrame() listeners, which are
 // supposed to enable this REPEATING_PRECISE_CAN_SKIP behavior.  The
 // secondary bug isn't really worth investigating since it's obseleted
 // by bug 710563.
 pref("layout.frame_rate.precise", true);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -74,19 +74,20 @@ function startupHttpd(baseDir, port) {
   server.registerDirectory('/', new LocalFile(baseDir));
   server.registerContentType('appcache', 'text/cache-manifest');
   server.start(port);
 }
 
 // FIXME Bug 707625
 // until we have a proper security model, add some rights to
 // the pre-installed web applications
+// XXX never grant 'content-camera' to non-gaia apps
 function addPermissions(urls) {
   let permissions = [
-    'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app'
+    'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app', 'content-camera'
   ];
   urls.forEach(function(url) {
     let uri = Services.io.newURI(url, null, null);
     let allow = Ci.nsIPermissionManager.ALLOW_ACTION;
 
     permissions.forEach(function(permission) {
       Services.perms.add(uri, permission, allow);
     });
--- a/b2g/components/B2GComponents.manifest
+++ b/b2g/components/B2GComponents.manifest
@@ -1,2 +1,7 @@
 # Scrollbars
 category agent-style-sheets browser-content-stylesheet chrome://browser/content/content.css
+
+# CameraContent.js
+component {eff4231b-abce-4f7f-a40a-d646e8fde3ce} CameraContent.js
+contract @mozilla.org/b2g-camera-content;1 {eff4231b-abce-4f7f-a40a-d646e8fde3ce}
+category JavaScript-navigator-property mozCamera @mozilla.org/b2g-camera-content;1
new file mode 100644
--- /dev/null
+++ b/b2g/components/CameraContent.js
@@ -0,0 +1,83 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+const kProtocolName = "b2g-camera:";
+
+let CameraContent = function() {
+  this.hasPrivileges = false;
+  this.mapping = [];
+}
+ 
+CameraContent.prototype = {
+  getCameraURI: function(aOptions) {
+    if (!this.hasPrivileges)
+      return null;
+
+    let options = aOptions || { };
+    if (!options.camera)
+      options.camera = 0;
+    if (!options.width)
+      options.width = 320;
+    if (!options.height)
+      options.height = 240;
+
+    let uuid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
+    uuid = uuid.substring(1, uuid.length - 2); // remove the brackets
+    this.mapping.push(uuid);
+    let uri = kProtocolName + "?camera=" + options.camera + 
+                              "&width=" + options.width +
+                              "&height=" + options.height +
+                              "&type=video/x-raw-yuv";
+    // XXX that's no e10s ready, but the camera inputstream itself is not...
+    Services.prefs.setCharPref("b2g.camera." + kProtocolName + "?" + uuid, uri);
+    return kProtocolName + "?" + uuid;
+  },
+  
+  observe: function(aSubject, aTopic, aData) {
+    if (aTopic == "inner-window-destroyed") {
+      let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
+      if (wId == this.innerWindowID) {
+        Services.obs.removeObserver(this, "inner-window-destroyed");
+        for (let aId in this.mapping)
+          Services.prefs.clearUserPref("b2g.camera." + kProtocolName + "?" + aId);
+        this.mapping = null;
+      }
+    }
+  },
+
+  init: function(aWindow) {
+    let principal = aWindow.document.nodePrincipal;
+    let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
+
+    let perm = principal == secMan.getSystemPrincipal() ? Ci.nsIPermissionManager.ALLOW_ACTION : Services.perms.testExactPermission(principal.URI, "content-camera");
+
+    //only pages with perm set and chrome pages can use the camera in content
+    this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION || from.schemeIs("chrome");
+
+    Services.obs.addObserver(this, "inner-window-destroyed", false);
+    let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+    this.innerWindowID = util.currentInnerWindowID;
+  },
+ 
+  classID: Components.ID("{eff4231b-abce-4f7f-a40a-d646e8fde3ce}"),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIB2GCameraContent, Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIObserver]),
+  
+  classInfo: XPCOMUtils.generateCI({classID: Components.ID("{eff4231b-abce-4f7f-a40a-d646e8fde3ce}"),
+                                    contractID: "@mozilla.org/b2g-camera-content;1",
+                                    interfaces: [Ci.nsIB2GCameraContent],
+                                    flags: Ci.nsIClassInfo.DOM_OBJECT,
+                                    classDescription: "B2G Camera Content Helper"})
+}
+ 
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([CameraContent]);
--- a/b2g/components/Makefile.in
+++ b/b2g/components/Makefile.in
@@ -39,13 +39,18 @@ topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = B2GComponents
 XPIDL_MODULE = B2GComponents
 
+XPIDLSRCS = \
+        b2g.idl \
+        $(NULL)
+
 EXTRA_PP_COMPONENTS = \
         B2GComponents.manifest \
+        CameraContent.js \
         $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/b2g/components/b2g.idl
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+
+[scriptable, uuid(3615a616-571d-4194-bf54-ccf546067b14)]
+interface nsIB2GCameraContent : nsISupports
+{
+    /* temporary solution, waiting for getUserMedia */
+	DOMString getCameraURI([optional] in jsval options);
+};
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -598,8 +598,9 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 #endif
 
 [b2g]
 @BINPATH@/chrome/icons/
 @BINPATH@/chrome/chrome@JAREXT@
 @BINPATH@/chrome/chrome.manifest
 @BINPATH@/components/B2GComponents.manifest
 @BINPATH@/components/B2GComponents.xpt
+@BINPATH@/components/CameraContent.js
--- a/netwerk/build/nsNetCID.h
+++ b/netwerk/build/nsNetCID.h
@@ -704,16 +704,27 @@
 #define NS_DEVICEPROTOCOLHANDLER_CID                 \
 { /* 6b0ffe9e-d114-486b-aeb7-da62e7273ed5 */         \
     0x60ffe9e,                                       \
     0xd114,                                          \
     0x486b,                                          \
     {0xae, 0xb7, 0xda, 0x62, 0xe7, 0x27, 0x3e, 0xd5} \
 }
 
+#ifdef MOZ_WIDGET_GONK
+#define NS_B2GPROTOCOLHANDLER_CLASSNAME \
+    "nsB2GProtocolHandler"
+#define NS_B2GPROTOCOLHANDLER_CID                    \
+{                                                    \
+/* {e50d101a-9db2-466f-977c-ae6af19e3b2f} */         \
+  0x50d101a, 0x9db2, 0x466f,                         \
+    {0x97, 0x7c, 0xae, 0x6a, 0xf1, 0x9e, 0x3b, 0x2f} \
+}
+#endif
+
 /******************************************************************************
  * netwerk/protocol/viewsource/ classes
  */
 
 // service implementing nsIProtocolHandler
 #define NS_VIEWSOURCEHANDLER_CID                     \
 { /* {0x9c7ec5d1-23f9-11d5-aea8-8fcc0793e97f} */     \
     0x9c7ec5d1,                                      \
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -259,16 +259,20 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDig
 #include "nsResProtocolHandler.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsResProtocolHandler, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsResURL)
 #endif
 
 #ifdef NECKO_PROTOCOL_device
 #include "nsDeviceProtocolHandler.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceProtocolHandler)
+#ifdef MOZ_WIDGET_GONK
+#include "nsB2GProtocolHandler.h"
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsB2GProtocolHandler)
+#endif
 #endif
 
 #ifdef NECKO_PROTOCOL_viewsource
 #include "nsViewSourceHandler.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSourceHandler)
 #endif
 
 #ifdef NECKO_PROTOCOL_data
@@ -774,16 +778,19 @@ NS_DEFINE_NAMED_CID(NS_COOKIESERVICE_CID
 #ifdef NECKO_WIFI
 NS_DEFINE_NAMED_CID(NS_WIFI_MONITOR_COMPONENT_CID);
 #endif
 #ifdef NECKO_PROTOCOL_data
 NS_DEFINE_NAMED_CID(NS_DATAPROTOCOLHANDLER_CID);
 #endif
 #ifdef NECKO_PROTOCOL_device
 NS_DEFINE_NAMED_CID(NS_DEVICEPROTOCOLHANDLER_CID);
+#ifdef MOZ_WIDGET_GONK
+NS_DEFINE_NAMED_CID(NS_B2GPROTOCOLHANDLER_CID);
+#endif
 #endif
 #ifdef NECKO_PROTOCOL_viewsource
 NS_DEFINE_NAMED_CID(NS_VIEWSOURCEHANDLER_CID);
 #endif
 #ifdef NECKO_PROTOCOL_wyciwyg
 NS_DEFINE_NAMED_CID(NS_WYCIWYGPROTOCOLHANDLER_CID);
 #endif
 #ifdef NECKO_PROTOCOL_websocket
@@ -905,16 +912,19 @@ static const mozilla::Module::CIDEntry k
 #ifdef NECKO_WIFI
     { &kNS_WIFI_MONITOR_COMPONENT_CID, false, NULL, nsWifiMonitorConstructor },
 #endif
 #ifdef NECKO_PROTOCOL_data
     { &kNS_DATAPROTOCOLHANDLER_CID, false, NULL, nsDataHandler::Create },
 #endif
 #ifdef NECKO_PROTOCOL_device
     { &kNS_DEVICEPROTOCOLHANDLER_CID, false, NULL, nsDeviceProtocolHandlerConstructor},
+#ifdef MOZ_WIDGET_GONK
+    { &kNS_B2GPROTOCOLHANDLER_CID, false, NULL, nsB2GProtocolHandlerConstructor},
+#endif
 #endif
 #ifdef NECKO_PROTOCOL_viewsource
     { &kNS_VIEWSOURCEHANDLER_CID, false, NULL, nsViewSourceHandlerConstructor },
 #endif
 #ifdef NECKO_PROTOCOL_wyciwyg
     { &kNS_WYCIWYGPROTOCOLHANDLER_CID, false, NULL, nsWyciwygProtocolHandlerConstructor },
 #endif
 #ifdef NECKO_PROTOCOL_websocket
@@ -1045,16 +1055,19 @@ static const mozilla::Module::ContractID
 #ifdef NECKO_WIFI
     { NS_WIFI_MONITOR_CONTRACTID, &kNS_WIFI_MONITOR_COMPONENT_CID },
 #endif
 #ifdef NECKO_PROTOCOL_data
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "data", &kNS_DATAPROTOCOLHANDLER_CID },
 #endif
 #ifdef NECKO_PROTOCOL_device
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "moz-device", &kNS_DEVICEPROTOCOLHANDLER_CID },
+#ifdef MOZ_WIDGET_GONK
+    { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "b2g-camera", &kNS_B2GPROTOCOLHANDLER_CID },
+#endif
 #endif
 #ifdef NECKO_PROTOCOL_viewsource
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "view-source", &kNS_VIEWSOURCEHANDLER_CID },
 #endif
 #ifdef NECKO_PROTOCOL_wyciwyg
     { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "wyciwyg", &kNS_WYCIWYGPROTOCOLHANDLER_CID },
 #endif
 #ifdef NECKO_PROTOCOL_websocket
--- a/netwerk/protocol/device/Makefile.in
+++ b/netwerk/protocol/device/Makefile.in
@@ -61,16 +61,17 @@ EXPORTS_NAMESPACES = mozilla/net
 EXPORTS_mozilla/net += \
   CameraStreamImpl.h  \
   $(NULL)
 
 endif
 
 ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += GonkCaptureProvider.cpp \
+           nsB2GProtocolHandler.cpp \
            $(NULL)
 endif
 
 LOCAL_INCLUDES = -I$(srcdir)/../../base/src/ \
                  $(NULL)
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/device/nsB2GProtocolHandler.cpp
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Camera.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Nino D'Aversa <ninodaversa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsB2GProtocolHandler.h"
+#include "nsDeviceChannel.h"
+#include "nsNetCID.h"
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
+#include "nsSimpleURI.h"
+#include "mozilla/Preferences.h"
+//-----------------------------------------------------------------------------
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsB2GProtocolHandler,
+                              nsIProtocolHandler)
+
+nsresult
+nsB2GProtocolHandler::Init(){
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsB2GProtocolHandler::GetScheme(nsACString &aResult)
+{
+  aResult.AssignLiteral("b2g-camera");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsB2GProtocolHandler::GetDefaultPort(PRInt32 *aResult)
+{
+  *aResult = -1;        // no port for b2g-camera: URLs
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsB2GProtocolHandler::GetProtocolFlags(PRUint32 *aResult)
+{
+  *aResult = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE | URI_IS_LOCAL_RESOURCE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsB2GProtocolHandler::NewURI(const nsACString &spec,
+                                const char *originCharset,
+                                nsIURI *baseURI,
+                                nsIURI **result)
+{
+  nsRefPtr<nsSimpleURI> uri = new nsSimpleURI();
+  nsresult rv;
+
+  // XXX get the "real" uri from the pref
+  // should use ipdl when we'll use e10s
+  nsCString key("b2g.camera.");
+  key.Append(spec);
+  nsCString pref;
+  rv = mozilla::Preferences::GetCString(key.get(), &pref);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = uri->SetSpec(pref);
+  mozilla::Preferences::ClearUser(key.BeginReading());
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return CallQueryInterface(uri, result);
+}
+
+NS_IMETHODIMP
+nsB2GProtocolHandler::NewChannel(nsIURI* aURI, nsIChannel **aResult)
+{
+  nsRefPtr<nsDeviceChannel> channel = new nsDeviceChannel();
+  nsresult rv = channel->Init(aURI);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return CallQueryInterface(channel, aResult);
+}
+
+NS_IMETHODIMP 
+nsB2GProtocolHandler::AllowPort(PRInt32 port,
+                                   const char *scheme,
+                                   bool *aResult)
+{
+  // don't override anything.  
+  *aResult = false;
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/netwerk/protocol/device/nsB2GProtocolHandler.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Camera.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Nino D'Aversa <ninodaversa@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsB2GProtocolHandler_h_
+#define nsB2GProtocolHandler_h_
+
+#include "nsIProtocolHandler.h"
+#include "nsString.h"
+
+// {e50d101a-9db2-466f-977c-ae6af19e3b2f}
+#define NS_B2GPROTOCOLHANDLER_CID                      \
+{ 0x50d101a, 0x9db2, 0x466f,                              \
+    {0x97, 0x7c, 0xae, 0x6a, 0xf1, 0x9e, 0x3b, 0x2f} }
+
+class nsB2GProtocolHandler : public nsIProtocolHandler {
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIPROTOCOLHANDLER
+
+  nsB2GProtocolHandler() {}
+  ~nsB2GProtocolHandler() {}
+
+  nsresult Init();
+};
+
+#endif