Implementing new WebAPIs
Upcoming SlideShare
Loading in...5
×
 

Implementing new WebAPIs

on

  • 1,776 views

This session gives a rough overview how to implement new WebAPIs in JS and C++.

This session gives a rough overview how to implement new WebAPIs in JS and C++.

Statistics

Views

Total Views
1,776
Views on SlideShare
1,776
Embed Views
0

Actions

Likes
0
Downloads
20
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Implementing new WebAPIs Implementing new WebAPIs Presentation Transcript

  • IMPLEMENTING NEW WEBAPIS Gregor Wagner (gwagner@mozilla.com) Julian Viereck (jviereck@mozilla.com)
  • DISCALIMER• No API designing/standadization here• Talk about making the implementation happen!• 55” not enough to get you going• Reach out to us and do “hands-on” hacking
  • OUTLINE• General Introduction• How To Implement New API • JS • C++• Make your work land• Q&A
  • GENERAL INTRODUCTION
  • GENERAL INTRODUCTION• Build on two previous presentations • JS: David Dahl’s “From Web Developer to Firefox Hacker” [1] • C++: Bobby Holley’s “Hacking Gecko” [2] • [1]: http://people.mozilla.com/~ddahl/pages/HackingFirefox/ template.html • [2]: http://people.mozilla.com/~bholley/hacking-gecko- fosdem2012/hacking-gecko.html
  • GENERAL INTRODUCTION• Need to build Firefox• Run build: • Linux/Windows: objdir/dist/bin/firefox • OSX: objdir/dist/AppName.app/Contents/ MacOS/firefox • options: -ProfileManager, -no-remote
  • GENERAL INTRODUCTION
  • GENERAL INTRODUCTION• Don’t get lost in the details• Ask for an implementation outline• There is documentation, overview• Über-Weapon: Ask for help • IRC: https://wiki.mozilla.org/IRC, #developers • Mailing list: https://lists.mozilla.org/listinfo, dev-webapi
  • FRIENDLY PEOPLE TO PING ON IRC
  • khuey (Kyle Huey)
  • ehsan (Ehsan Akhgari)
  • bholley (Bobby Holley)
  • jdm (Josh Matthews)
  • dholbert (Daniel Holbert)
  • Ms2ger (???)
  • GENERAL INTRODUCTION• whenever you do communication • try to be precise • give reasoning to your arguments • get only short answer - don’t take it wrong, people are really busy • dump whatever you have (crashback/patch...)
  • GENERAL INTRODUCTION• don’t be afraid to ping people• might get hint to ping someone else• tell people youre new to hacking JS/Gecko• look/ask for bugs that do similar things you try to solve
  • HTTPS://MXR.MOZILLA.ORG/
  • FIREFOX OS WEBAPI Wifi Browser Battery Telephony Settings Idle PowerContacts Bluetooth Vibrator Webapps many more to come.... https://wiki.mozilla.org/WebAPI/
  • INTERFACE + IMPLEMENTATION
  • IT ALL STARTS WITH AN INTERFACE XPIDL VS. WEBIDL
  • XPIDL VS. WEBIDL[scriptable, builtinclass, interface EventTarget {uuid(5a8294df-ffe4-48e5-803f-f57bebc29289)] void addEventListener(DOMString type,interface nsIDOMScreen : nsIDOMEventTarget EventListener? listener,{ optional boolean capture = false, readonly attribute long top; optional boolean? wantsUntrusted = null); readonly attribute DOMString mozOrientation; void removeEventListener(DOMString type, [implicit_jscontext] EventListener? listener, attribute jsval onmozorientationchange; optional boolean capture = false); boolean dispatchEvent(Event event); boolean mozLockOrientation(in DOMString orientation); }; void mozUnlockOrientation();}; https://developer.mozilla.org/en-US/docs/XPIDL https://developer.mozilla.org/en-US/docs/Mozilla/WebIDL_bindings
  • MAPPING JS VS C++• Read other APIs• Interfaces are defined in dom/interfaces• Implementations mostly in dom/*, content/*• c++ implementations use common inheritance• JS implementations use manifest file
  • TIME TO FILE A BUGBugzilla: DOM:Device Interfaces
  • HOW TO IMPLEMENT JS
  • WHY IN JS?• Prototyping• Lower entry point• WebDevs know JS • Also better for understanding!
  • INTERFACE EXAMPLEFor example dom/interfaces/helloworld/nsIHelloWorld.idl[scriptable, uuid(da0f7040-388b-11e1-b86c-0800200c9444)]interface nsIDOMHelloWorld : nsISupports{ void sayHello(in DOMString aName);};https://bugzilla.mozilla.org/show_bug.cgi?id=674720
  • HELLOWORLD.MANIFESTFor example dom/helloworld/HelloWorld.manifestcomponent {f5181640-89e8-11e1-b0c4-0800200c9444} HelloWorld.jscontract @mozilla.org/helloWorld;1 {f5181640-89e8-11e1-b0c4-0800200c9444}category JavaScript-navigator-property mozHelloWorld @mozilla.org/helloWorld;1
  • HELLOWORLD.JSFor example dom/helloworld/HelloWorld.jsconst Cc = Components.classes;const Ci = Components.interfaces;const Cu = Components.utils;Cu.import("resource://gre/modules/XPCOMUtils.jsm");function HelloWorld() {}HelloWorld.prototype = { init: function init(aWindow) {}, Text sayHello: function sayHello(aName) { dump("Hello " + aName + "n"); }, classID : Components.ID("{d88af7e0-a45f-11e1-b3dd-0800200c9444}"), QueryInterface : XPCOMUtils.generateQI([Components.interfaces.nsIDOMHelloWorld]), classInfo : XPCOMUtils.generateCI({classID: Components.ID("{d88af7e0-a45f-11e1-b3dd-0800200c9444}"), contractID: "@mozilla.org/helloWorld;1", classDescription: "HelloWorld", interfaces: [Components.interfaces.nsIDOMHelloWorld,Ci.nsIDOMGlobalPropertyInitializer], flags: Ci.nsIClassInfo.DOM_OBJECT})}const NSGetFactory = XPCOMUtils.generateNSGetFactory([HelloWorld]);
  • BOILERPLATE• Makefiles• Manifest• Packaging• Module Loading• Access Permission
  • EXPOSEDPROPSlet foo = new Foo();Foo.prototype = { __exposedProps__: { name: rw }}
  • FIREFOX OS PROCESS MODEL• Parent - Child • Nested process Processes structure not possible (yet)• Only one parent • Parent is trusted• Browser is in parent, content pages are • Child can be children compromised • Securitycritical code has to run in parent
  • SYSTEM MESSAGE MANAGER• Use for child-parent communication• Child:childProcessMessageManager.sendAsyncMessage("message-name", {"foo": 2});var response = sendSyncMessage("message-name", {"foo": 1}); Parent:•receiveMessage: function(aMessage) { switch (aMessage.name) { [...] parentProcessMessageManager.sendAsynMessage(“return-message-name”, [...]) } }
  • DOMREQUESTSvar pending = navigator.mozApps.install(manifestUrl);pending.onsuccess = function () {  // Save the App object that is returned  var appRecord = this.result;  alert(Installation successful!)};pending.onerror = function () {  // Display the name of the error  alert(Install failed, error: + this.error.name);};
  • PERMISSIONS
  • HOW TO IMPLEMENT C++
  • MAPPING JS/C++• IDL files → JS & C++• JS: ctx.lineWidth C++: ctx::GetLineWidth(float *width)• Need to implement C++ class for interface• NS_IMETHODIMP: returns NS_<status>• Expose object: nsDOMClassInfo.cpp/nsDOMClassInfoClasses.h
  • INTERFACES Attribute canvas.mozPrintCallback =Callback function(obj) { PrintState var ctx = obj.context; ctx.fillRect(0, 0, 100, 100); obj.done(); };
  • INTERFACES Taken from bug #745025 te [scriptable, uuid(a7062fca-41c6-4520-b777-3bb30fd77273)] interface nsIDOMHTMLCanvasElement : nsIDOMHTMLElement bu { tri [...]At // A Mozilla-only callback that is called during the printing process. attribute nsIPrintCallback mozPrintCallback; }; k ac [scriptable, function, uuid(8d5fb8a0-7782-11e1-b0c4-0800200c9a66)] llb interface nsIPrintCallback : nsISupportsCa { void render(in nsIDOMMozCanvasPrintState ctx); }; te ta [scriptable, builtinclass, uuid(8d5fb8a0-7782-11e1-b0c4-0800200c9a67)] tS interface nsIDOMMozCanvasPrintState : nsISupports in {Pr // A canvas rendering context. readonly attribute nsISupports context; // To be called when rendering to the context is done. void done(); };
  • class nsHTMLCanvasPrintState : public nsIDOMMozCanvasPrintState{public: nsHTMLCanvasPrintState(nsHTMLCanvasElement* aCanvas, nsICanvasRenderingContextInternal* aContext, nsITimerCallback* aCallback) : mIsDone(false), mPendingNotify(false), mCanvas(aCanvas), mContext(aContext), mCallback(aCallback) { } NS_IMETHOD GetContext(nsISupports** aContext) { NS_ADDREF(*aContext = mContext); return NS_OK; } NS_IMETHOD Done() { [...] Taken from return NS_OK; } bug #745025 [...]}
  • MEMORY MANAGEMENT• C++ doesn’t have a garbage collector :(• In Gecko: Reference counting & cycle collector• Reference counting: • nsCOMPtr (for interfaces), nsREFPtr • use getter_AddRefs • NS_IF_ADDREF & NS_IF_RELEASE
  • MEMORY MANAGEMENT• Reference counting doesn’t work always• Make use of Gecko’s cycle collector• Better cycle then maybe leak
  • DEBUGGING• Make sure to have a debug build• Enable logging (example)• Watch for assertion in logs• Insert printfs• There is documentation how to use debugger
  • OVERVIEW OF SOME TREES• Frame Tree: Frames on page• Content Tree: Content going with frames• View Tree: Connecting views
  • MAKE YOUR WORK LAND
  • TESTS TESTS TESTS
  • DIFFERENT TYPE OF TESTS• Reftests• Crashtests• XPCShell Tests• Mochitests• JS tests• Compiled code tests :-(• Marionette tests
  • MOCHITEST•/path/to/objdir $ TEST_PATH=dom/ contacts/tests make mochitest-plain•/path/to/objdir $ TEST_PATH=dom/ Text contacts/tests/test_contacts.html make mochitest-plain
  • TIME FOR REVIEW• Makesure the patch is • Whenuploading a newformatted according to version:the guidelines: • address *all* review •8 lines of context comments • correctcommitter • obsolete the old info (name + email) patch • correct checking • run tests again message
  • REVIEW• Make sure your patch is clean• Patch should be green on try-push• WIP: State what’s working/what not/what’s next• Review might take some time (~1 week?)• If longer, ping person, switch review person• Except r-, don’t worry!
  • Q&A
  • THINGS TO HACK ON• Implement vw/vh/vmin/vmax• "dirname" DOM attribute on form controls• Implement FileSaver