Matthew Hodgson

157 posts tagged with "Matthew Hodgson" (See all Author)

3D Video Calling with Matrix, WebRTC and WebVR at FOSDEM 2018!

05.02.2018 00:00 — General Matthew Hodgson

TL;DR: We built a proof-of-concept for FOSDEM of the world's first(?) 3D video calling using Matrix and the iPhone X... and it looks like this!!

Last year we spent a few weeks putting together a proof of concept of using Matrix as an open, interoperable communication layer for VR/AR - showing how you can use it as an open signalling protocol to connect users within (and between) virtual worlds, with full-mesh E2E encrypted video conferencing in VR; WebRTC calls overlaid on 360 degree video, and other fun stuff. The reasons for building the demo were quite eclectic:

  1. Try to highlight that Matrix is about much more than just about instant messaging or team chat
  2. Try to encourage the community to jump in and build out more interesting use cases
  3. Learn where the state of the art in WebVR + WebGL is
  4. Kick off the process of encouraging folks to think about storing world geometry and physics in Matrix
  5. Have a fun visual demo we could show to excite potential investors in New Vector (which comically backfired when the investment community spontaneously decided that VR is still too early).
In the end it succeeded on some points (highlighting exotic uses of Matrix; learning all about WebVR) and failed on others (a surge in Matrix-for-VR) - although we did have a lot of fun showing it off at the ETHLDN meetup back in October. (Eagle eyed viewers may be amused to spot team Status & Matrix sitting together in the audience ;)

However, we still believe that Matrix is the missing link for decentralised communication within VR/AR, and we were lucky enough to get a talk about Matrix+WebRTC+WebVR accepted to the Real-Time Communications Devroom at FOSDEM 2018! So, given a new chance to show the world how cool Matrix-powered comms could be in VR/AR, myself and Dave Baker went on a (very) quick detour to update the demo a little...

One of the issues of the original demo is that the video calling bits were just putting plain old video planes into the scene - floating television screens of 2D video content, if you will. This is better than nothing, but it's sort of missing the whole point of VR/AR: surely you want to see who you're talking to in 3D? Ideally they should have the same presence as if they were physically in your virtual space. This could also be a big step towards fixing one of the oldest problems of video calling: gaze correction. We've been obsessed about gaze correction since our early days (pre-Matrix) building mobile video calling stacks: gaze correction tries to fix the fact that the break in eye contact caused by staring at the screen (rather than the camera) has a terrible impact on the emotional connection of a video call. But if the person you are talking to is 3D, you can always rotate them in 3D space (or reposition yourself) to correct their line of sight - to re-align their gaze so they're actually looking (in VR) at the thing they're looking at in real life!

Back in early 2017 it would have been wildly ambitious to build an off-the-shelf 3D video calling app - but this changed overnight in late 2017 with the introduction of the iPhone X and its TrueDepth infrared-dot-projector based depth camera; effectively a mini-Kinect. Suddenly we have a mainstream high quality depth+video camera perfectly optimised for 3D video calling, with excellent API support from Apple. So we decided to see if we could be first in the world (as far as we know) to do 3D video calling using the iPhone X, using Matrix to signal the WebRTC media and using our WebVR demo as the viewing environment!

Step 1: Hack on WebRTC to add support for the iPhone X depth camera as a capture device. This is pretty easy, at least if you're just swapping WebRTC's AVFoundationVideoCapturer to request the depth camera instead of the video camera: https://github.com/matrix-org/webrtc/commit/c3044670d87c305d8f8ee72751939e281bf5223f is the starting point.

Step 2: Build a custom Riot/iOS with the right WebRTC SDK.  This is relatively easy thanks to Riot/iOS using CocoaPods and Google shipping a pod for WebRTC these days - it was a matter of tweaking Google's pod so it could be referred to directly as a local project by Riot/iOS (and so that it provided debug symbols in the form CocoaPods expects). Brief notes are at https://github.com/matrix-org/webrtc/blob/matthew/depth/matrix/build_instructions.txt - many thanks to Manu for helping on this :)

Step 3: Decide how to encode the depth buffer. Now, the official WebRTC working group quite correctly insists that depth data should be treated as a first class citizen which is modelled and compressed in its own right. However, it looks like nobody has added first-class depth support to official WebRTC yet - and if we want to be able to easily display 3D calls on generic browsers capable of running WebVR+WebRTC+Matrix, we have no choice but do the ugly thing and encode the depth into a video signal which can be compressed with VP8/VP8/H.264 etc.

A quick search showed that some folks had already proposed a method for encoding depth data into a video signal, back in the days of the Kinect: https://reality.cs.ucl.ac.uk/projects/depth-streaming/depth-streaming.pdf. The paper outlines a fairly simple approach: you encode the 16-bit depth data into the three 8-bit colour channels; putting the coarse depth data into Blue, and then finer-grained depth data into Red and Green, encoding it as a periodic triangle wave:

In practice this means that as an object gets closer towards you, it gets gradually more blue - and meanwhile it pulses through a sequence of red and green so you can refine the precise depth more easily. So we went and implemented this, building a 16-bit lookup-table to encode the half-precision floating point 16-bit depth measurements the camera yields into video: https://github.com/matrix-org/webrtc/compare/c3044670d87c305d8f8ee72751939e281bf5223f...0258a4ef14c11a0161f078c970c64574629761c2.

Placing a video call through to another Matrix client then coughed up a video stream that looks like this:

As you can see, closer things (my head) are bluer than further things (the wall), and everything's covered with trippy red & green stripes to refine the fine detail.  For the record, the iPhone TrueDepth camera emits 640x480 depth frames at around 24Hz.

Step 4: extend matrix-vr-demo to view a dot cloud, displaced using a WebGL vertex shader based on the encoded depth info.  Dave kindly did the honours: https://github.com/matrix-org/matrix-vr-demo/commit/b14cdda605d3807080049e84181b46706cec553e

Unfortunately, it showed that the depth encoding really wasn't working very well... you can just about make out my head, but there are dots flying around all over the place, and when you view it in profile the 3D effect was almost entirely missing.

The main problems seem to be:

  • Whenever there's a big jump in depth, the stripes get incredibly noisy and don't compress at all well, generating completely corrupt data at edges of objects (e.g. the sides of my head)
  • The complexity of the pattern as a whole isn't particularly compression-friendly
  • The contrast of the red/green stripes tends to dominate, causing the arguably more important blue to get overpowered during compression.
  • Converting from 4:4:4 RGB to 4:2:0 YUV (NV12) as required by WebRTC and then back to RGB inevitably entangles the colours - meaning that the extreme contrast of the red/green stripes is very visible on the blue channel after round-tripping due to sampling artefacts.
  • I probably made a mistake by bitwise casting the 16-bit half-precision floating point depth values directly onto the 16-bit unsigned int lookup index, rather than interpreting the float as a number and building a new index into the lookup table based on its numeric value.  As a result, depth values being encoded ended up having a much lower range than they should.
  • There are probably other bugs too.

Step 5: Give up on the fancy depth encoding (for now): https://github.com/matrix-org/webrtc/commit/2f5d29352ce5d80727639991b1480f610cbdd54c.  In practice, simply picking a range of the 16-bit half-precision floats to fit in the integer range [0,255] turns out to be good enough for a quick demo (i.e. 8-bit depth buffer, but over a small subset of the 16-bit depth space) - the dot cloud suddenly looked a lot more 3D and recognisable:

Step 6: Clearly this needs colour as well as depth.  This means asking WebRTC to add VideoTracks for both video and depth to your call's MediaStream.  Firstly, we added a simple 'matrixDepth' constraint to WebRTC to tell a video source whether to capture depth or not.  (Yes, I know there's a specced way to do this, but given nothing else here is on spec, we went for the simplest approach).  However, it turns out that only one WebRTC's AVFoundationVideoCapturer can run at a time, because it manages its own AVCaptureSession and you can only have one of those at a time in a given app.  As a result, the two capturers (one per video track) collided, with the second session killing the first session.  As a quick fix, we modified RTCAVFoundationVideoSource to accept an existing AVCaptureSession (and AVCaptureDeviceInput) so that the application itself can handle the capture session and select the device, which can then be shared between multiple capturers: https://github.com/matrix-org/webrtc/commit/9c58465ada08018b1238fb8c5d784b5570f9246b.  Finally, just needed a few lines to matrix-ios-sdk to set the constraint and send the depth as well as video... https://github.com/matrix-org/matrix-ios-sdk/compare/fa9a24a6914b207389bacdd9ad08d5386fd0644a...5947d634ae8d722133ecdbde94cccf60bb88f11d, and adding playback of both channels to the vrdemo (https://github.com/matrix-org/matrix-vr-demo/commit/4059ab671d13bb4d4eb19dd2f534d9a387e47b81 and https://github.com/matrix-org/matrix-js-sdk/commit/f3f1524fcd46d2e772fd5cd022364018c8889364) ...and it worked!

However, the dot cloud obviously has some limitations - especially when you zoom in like this.

Step 7: Replace the dot cloud with a displacement-mapped mesh so that it's solid.  So as a final tweak for the demo, Dave switched out the dot cloud for a simple A-Frame plane with 640x480 vertices, keeping the same vertex shader.  Ironically this is where we hit some nasty problems, as for some reason the video texture started being applied to the depth texture (albeit flickering a bit) - eventually we realised that the flickering was the vertex shader inexplicably flapping between using the depth and the video texture for the displacement map.  At this point we compared it between laptops, and it turns out that for some reason the integrated Intel graphics on Dave's Macbook Pro was choking on the two video textures, whereas a AMD Radeon R9 M370X got it right.  It's unclear if this was actually a GPU bug or an A-Frame or Three.js or WebGL or Chrome bug.  Eitherway, on switching laptop to one with discrete graphics it started working perfectly!  Finally, we tweaked the shader to try to reduce smearing, by discarding vertices where there are big discontinuities in depth (through looking at the partial derivatives of the depth texture).  This isn't perfect yet but it's better than nothing.  https://github.com/matrix-org/matrix-vr-demo/compare/bbd460e81ff1336cd63468e707d858d47261ea42...06abe34957732ba8c728b99f198d987fe48d0420

And here's the end result! (complete with trancey soundtrack as the audio we recorded at FOSDEM was unusable)

Conclusion:

Hopefully this gives a bit of a taste of what proper 3D video calling could be like in VR, and how (relatively) easy it was at the Matrix level to add it in.  If anyone wants to follow along at home, the various hacky branches are:

If you'd like to get involved with hacking on Matrix in VR, please come hang out at #vr:matrix.org.

Also, New Vector (where most of the core team work) is also hiring for VoIP/VR specialists right now, so if you'd like to work on this sort of thing fulltime, please contact us at [email protected] asap!

Matthew

Update: Slides from the FOSDEM talk (adapted from this blog post by Amandine) are available at https://matrix.org/~matthew/2018-02-04%20FOSDEM%20-%20VR.pdf

Update 2: The full FOSDEM talk recording is now up already at the RTC dev room at https://video.fosdem.org/2018/H.1309/!

Status partners up with New Vector, fueling decentralised comms and the Matrix ecosystem!

29.01.2018 00:00 — General Matthew Hodgson

Hi all,

We're delighted to announce that our friends at Status have made a major strategic investment ($5M) in New Vector: the company which currently employs most of the Matrix.org core team.  This means that we now have the financial backing to let us focus entirely on improving the Matrix ecosystem and getting the protocol out of beta… and beyond!!

First up - massive, massive thanks to everyone who has supported us over the last 6 months since our funding situation changed: as of the end of 2017 we had enough Patreon / Liberapay / IBAN / BTC / ETH donations and sponsorship (for Matrix.org) and enough paid consulting work (for New Vector) that we've been able to keep almost the whole core team working on Matrix as their day job.  Simply: the core Matrix team could not have continued in its current form without the support of the community - so we will be forever indebted to everyone who has supported us: especially all our donating supporters on Patreon/Liberapay/etc, our customers at New Vector, and our big $ sponsors, including UpCloud.com (who provide incredible hosting for Matrix.org), PrivateInternetAccess.com, INBlockchain.com, OmiseGO and Tendermint.

The investment from Status that we're announcing today is a massive step change as it gives us the resources to grow the team and to focus fully on Matrix's key problem areas without distractions (whilst still supporting paid New Vector work). Please note that donations are still very appreciated however: we are in the process of setting up the Matrix.org Foundation (at last!) as the non-profit target for all future donations, such that Matrix itself has a financial means to support pure Matrix work independently of any other companies (including New Vector).

Many folks will be familiar with Status already as one of the leading projects in the Ethereum ecosystem: building a beautiful usability-focused browser for decentralised apps (DApps) which run on the Ethereum Virtual Machine - as well as providing cryptocurrency payments and chat functionality (via the Whisper protocol).  It effectively lets users access Ethereum as a usable meaningful operating system - a bit like how Riot attempts to be a flagship ‘browser' for the Matrix ecosystem.  The reason Status is investing in Matrix is primarily to accelerate decentralisation technology and open protocols in general - and also because there are some pretty obvious advantages to the collaboration, potentially including:

  • Bridging between Matrix and Whisper (Ethereum's own real-time communication protocol) - exposing all of the Matrix ecosystem into Ethereum and vice versa
  • Bundling up Status DApps as Matrix Widgets
  • Exposing Matrix Widgets into Status
  • Supporting Olm/Megolm such that it could be used for E2E encryption in Status
  • Collaboration on the decentralised reputation systems needed to combat abuse in both Matrix & Ethereum
  • Utilize the Status Network token within Riot.im by enabling crypto assets.
  • ...and more!

We've spent a lot of time working with Status over the last few months whilst arranging this partnership, and we've been really impressed by Jarrad and Carl and the team (they even have their own golang Double Ratchet Implementation!).  It's fair to say that Status are very much aligned with Matrix's vision, and the projects and can help each other a lot.

It's also worth noting that Status and Matrix are really quite complementary: Whisper (as used by Status) is entirely p2p and focuses on protecting metadata and is tightly coupled to Ethereum, whereas Matrix is standalone and more feature rich but currently lacks metadata protection.  We both have fledgling app ecosystems; Matrix through Widgets and Status through Ethereum DApps. That said, Matrix and Status are going to continue on their own paths, and Matrix will of course remain controlled by Matrix.org - but we are looking forward to learning more about each other's tech and driving decentralisation forward in general!

Meanwhile, on the core Matrix side, the investment lets us focus immediately on the following priorities:

  • Improving Riot's usability. As of today we are urgently hiring for a Lead Designer to join the team fulltime to revamp and address Riot's usability issues, as this is one of the single biggest things getting in the way of Matrix uptake today.  Hit up [email protected] if you're interested!
  • At the same time, we're excited to ramp up our investment in Riot's performance and overall polish (as well as achieving feature parity with Slack/Discord and friends) - that means we're looking for React, Android & iOS folks to join the core team full-time asap to take the apps to the next level.  Again, [email protected] if this sounds like you!
  • Getting End-to-end Encryption out of beta. We know what we need to do to push E2E out of beta (incremental key backup; cross-signing devices; improved device verification) - Status' investment means we can build the team to get it done! Decentralised end-to-end encryption is not for the faint-hearted, but if you're up for the challenge please get in touch at [email protected].
  • Finishing Dendrite. Dendrite (our next-gen golang homeserver implementation) is a hugely ambitious project and right now the only folks working on it are Rich and Erik… who also happen to be supporting Synapse too.  The good news is that the community has been helping considerably with Dendrite, but it would be even better if we had more people supported to work on it full time.  If you love Go, and you love massively scalable decentralised systems, please hit up [email protected]!
  • Supporting Synapse.There is massive scope for performance improvements to Synapse, and there are thousands of deployments out there today, so we really want to improve support for Synapse.  If you love Python and Twisted, and interesting performance/profiling and efficiency work, please hit up [email protected] too!
  • Maintaining the Spec. If Matrix is anything it is the spec, and maintenance of the spec is key to the project's success. In 2018 we intend to invest heavily in its maintenance and address outstanding API proposals, documenting APIs, not to mention updating the general technical documentation (guides, FAQ etc) on Matrix.org in general.  If you are a developer who loves spec work, we need you over at [email protected] immediately! :)
Beyond these immediate priorities, we have a long feature roadmap lined up too (highest priority first): Reactions, Message Editing, improved Widgets (e.g. Sticker Packs), Threading, Decentralised Accounts, Decentralised Identity, Decentralised Reputation, Peer-to-peer Matrix and more.  However, right now our focus has to be on improving the quality and stability of what we have today and getting it out of beta before we open yet more battlefronts.  In other words: we're not adding more features (modulo emergencies) until the current features are polished!

So: exciting times ahead!  Never before has Matrix had the resources to fully realise its potential, and we'd like to say enormous thanks to Carl, Jarrad, Yessin and Nabil at Status for their patience and support while sorting out the investment.  We'd also like to say thanks to everyone else who offered us investment: in the end we had several viable offers on the table - and we owe sincere thanks to those who invested the time and faith to make an offer which we've ended up turning down.

For now, however, it's back to work: making Riot slicker than Slack; making Synapse go faster and use less RAM; making Dendrite federate; making E2E encryption transparent and indestructible; making sure that it's possible to implement Matrix purely by referring to the Spec.

2018 is going to be an interesting year indeed :)  Thank you all for supporting Matrix - and thanks, once again, to Status for helping to take us to the next level.

Matthew, Amandine & the whole team.

Update 1: VentureBeat is covering the news over at https://venturebeat.com/2018/01/29/status-invests-5-million-in-matrix-to-create-a-blockchain-messaging-superpower/

Update 2: IBTimes is also covering it at http://www.ibtimes.co.uk/matrix-status-ico-gains-support-non-blockchain-decentralisation-technology-1656183!

...and you can see Status's side of the story over at https://blog.status.im/status-invests-5m-in-riot-im-4e3026a8bd50!

Synapse 0.26 released!

05.01.2018 00:00 — Tech Matthew Hodgson

Hi folks,

Synapse 0.26 is here (with no changes since RC1 which we released just before Christmas).  It's a general maintenance release, albeit with a few new features but mainly lots of bugfixes and general refinements.  Enjoy!

As always, you can get it from https://github.com/matrix-org/synapse/releases/tag/v0.26.0.

Changes in synapse v0.26.0 (2018-01-05)

No changes since v0.26.0-rc1

Changes in synapse v0.26.0-rc1 (2017-12-13)

Features:

  • Add ability for ASes to publicise groups for their users (PR #2686)
  • Add all local users to the user_directory and optionally search them (PR #2723)
  • Add support for custom login types for validating users (PR #2729)
Changes:
  • Update example Prometheus config to new format (PR #2648) Thanks to @krombel!
  • Rename redact_content option to include_content in Push API (PR #2650)
  • Declare support for r0.3.0 (PR #2677)
  • Improve upserts (PR #2684#2688#2689#2713)
  • Improve documentation of workers (PR #2700)
  • Improve tracebacks on exceptions (PR #2705)
  • Allow guest access to group APIs for reading (PR #2715)
  • Support for posting content in federation_client script (PR #2716)
  • Delete devices and pushers on logouts etc (PR #2722)
Bug fixes:
  • Fix database port script (PR #2673)
  • Fix internal server error on login with ldap_auth_provider (PR #2678) Thanks to @jkolo!
  • Fix error on sqlite 3.7 (PR #2697)
  • Fix OPTIONS on preview_url (PR #2707)
  • Fix error handling on dns lookup (PR #2711)
  • Fix wrong avatars when inviting multiple users when creating room (PR #2717)
  • Fix 500 when joining matrix-dev (PR #2719)

The Matrix Holiday Mini-Special (2017 edition)

25.12.2017 00:00 — General Matthew Hodgson

Hi folks,

Since we began Matrix it's been a sort of tradition to do a huge update on Christmas Eve to reflect on the past year and tease the future - you can check out the 2016 edition or the 2015 edition and a sort of proto-update for 2014 too if you're feeling nostalgic.  This year I'm going to try to keep it short though, as I'm hoping to write a Very Big Update related to long-term-funding progress in the relatively near future.

2017 has been a weird year for us: progress in the core team has been relatively badly impacted by the mission to secure long-term funding, with myself (Matthew) & Amandine spending the vast majority of our time handling the meta-problem of keeping the core team secure rather than actually working on the project itself.  Meanwhile we've lost a few of the original team during the disruption, which has particularly impacted Spec, E2E and Dendrite progress (such are the risks of running a very lean team in the first place!).  However, against the odds, we have (hopefully) prevailed - and this is almost entirely due to the massive support we've seen through donations via Patreon, Liberapay, Ethereum, Bitcoin and PayPal, and some much-appreciated paid consulting work.

Simply put, without the donation support we would have not been able to pay the core team over the last 3 months, and we would not be able to pay for the legal costs of setting up the team as an independent company, and we would be completely screwed for securing large-scale long-term funding if we couldn't point to the community's support as evidence that Matrix is worthy of funding.  So: we sincerely owe our thanks to those who heeded the call to arms and are supporting us.  We've also been pretty lucky in benefiting from the skyrocketing value of Ethereum and Bitcoin donations.  And even if/when long-term funding is secured for New Vector (the company we formed in July to hire the core team), donations will continue to be vital to support the Matrix.org Foundation itself as an independent non-profit entity - as it's obviously not in Matrix.org's interests to be entirely financially dependent on New Vector.  Hopefully this whole episode will end up being a bit like a Save Star Trek scenario - where something fun and amazing almost gets almost wiped out when it's only a few years old due to corporate factors... only for the community to band together to save it, and then for it to go from strength to strength for the next 50 years or more! :D

That said, we've made some major progress this year anyway: the addition of Widgets to Matrix; the addition of Communities (aka Groups) and Flair; major improvements to E2E encryption (even though it's not out of beta yet); lots of progress on Dendrite (the minimum-viable phase 1 is now about 75% complete); switching everything over to Jitsi for group video conferencing; rewriting onboarding for Riot/Web; Antiscam/spam support for cryptocommunities; the whole VR proof-of-concept of Matrix+WebVR+WebRTC video and voip calling; Version 0.3 of the Matrix spec; and a whole lot more which I'm probably forgetting right now.  And meanwhile the community has been more active than ever, with major new clients like Nheko hitting the scene with a large and loyal community of open source contributors (over the last few weeks I've literally seen more nheko PRs fly past than Riot ones!) - and we've also been incredibly glad of community contributions towards Dendrite.  Dendrite is already way ahead of Synapse in terms of % community contributed code - we have hope that it will end up being a model FOSS project :)

So what lies ahead?  It's hard to predict the level of progress we're going to make in the core team, as it really depends on long-term funding.  Whatever happens, one of our top priorities is to improve our governance so that everyone can better contribute in places that have historically been more blocked on the core team (i.e. the spec; synapse)... whilst still maintaining coherency across the project.  Ideally we'll end up with more folks pushing Matrix forwards from both the wider world and the core team however, and right now the main priorities are:

  • Phase 2 of Communities: letting users filter their current view of Matrix to rooms associated with a given subset of communities (if desired), for Slack/Discord-style semantics
  • Fixing the remaining end-to-end encryption failures (although the majority of them have now been solved)
  • Finalising proper UI/UX for end-to-end encryption (at last), including the option to transparently back up your room keys if desired.
  • Dendrite Phase 1
  • Performance in Riot (on all platforms)
  • Editable messages
  • Reactions
  • Making widgets much more useful
  • Paid integrations and hosting options to help avoid further funding nightmares.
Looking at the bigger picture, what we'd really love for 2018 would be to finally get to a 1.0 release of the Matrix Spec (i.e. catching up on our massive backlog of merging unstable spec drafts & proposals into the spec) - and for Dendrite to start to replace Synapse as the reference home server from Matrix.org and become really ubiquitous, and for E2E encryption be turned on by default in private rooms.  Beyond the above list, we don't really have any other features urgently planned (threading, for instance, is on hold until we have the rest of the above sorted) - but we believe that if we stabilise everything we have today (plus that list), then there is no reason for Matrix to not fulfil its full potential as a true global open decentralised communications standard.  And then it's on to threading, P2P matrix, decentralised reputation and all that good stuff!

It's going to be a crazy year ahead, either way: so thank you, once again, for supporting Matrix - whether that's financially, or by contributing code, or running a server, or just using the protocol as a user.  We literally wouldn't be here without you!! :)

Matthew, Amandine & the whole core team.

Synapse 0.25 is out... as is Matrix Specification 0.3(!!!)

15.11.2017 00:00 — Tech Matthew Hodgson

Hi all,

Today is a crazy release day here - not only do we have Synapse 0.25, but we've also made a formal release of the Matrix Specification (CS API) for the first time in 16 months!

Matrix CS API 0.3

Talking first about the spec update: the workflow of the Matrix spec is that new experimental features get added to an /unstable API prefix, and then whenever we release the Matrix spec, these get moved over to being part of the /r0 prefix (or whatever version we happen to be on).  We've been very constrained on manpower to work on the spec over the last ~18 months, but we've been keeping it up-to-date on a best effort basis, with a bit of help from the wider community.   As such, this latest release does not contain all the latest APIs (and certainly not experimental ones like Groups/Communities which are still evolving), but it does release all of the unstable ones which we've managed to document and which are considered stable enough to become part of the 'r0' prefix.  Going forwards, we're hoping that the wider community will help us fill in the remaining gaps (i.e. propose PRs against the matrix-org/matrix-doc repository to formalise the various spec drafts flying around the place) - and we're also hoping (if/when funding crisis is abated) to locate full-time folk to work on the spec.

The full changelog for 0.3 of the spec is:

  • Breaking changes:
    • Change the rule kind of .m.rule.contains_display_name from underride to override. This works with all known clients which support push rules, but any other clients implementing the push rules API should be aware of this change. This makes it simple to mute rooms correctly in the API (#373).
    • Remove /tokenrefresh from the API (#395).
    • Remove requirement that tokens used in token-based login be macaroons (#395).
  • Changes to the API which will be backwards-compatible for clients:
    • Add filename parameter to POST /_matrix/media/r0/upload (#364).
    • Document CAS-based client login and the use of m.login.token in /login (#367).
    • Make origin_server_ts a mandatory field of room events (#379).
    • Add top-level account_data key to the responses to GET /sync and GET /initialSync (#380).
    • Add is_direct flag to POST /createRoom and invite member event. Add 'Direct Messaging' module (#389).
    • Add contains_url option to RoomEventFilter (#390).
    • Add filter optional query param to /messages (#390).
    • Add 'Send-to-Device messaging' module (#386).
    • Add 'Device management' module (#402).
    • Require that User-Interactive auth fallback pages call window.postMessage to notify apps of completion (#398).
    • Add pagination and filter support to /publicRooms. Change response to omit fields rather than return null. Add estimate of total number of rooms in list. (#388).
    • Allow guest accounts to use a number of endpoints which are required for end-to-end encryption. (#751).
    • Add key distribution APIs, for use with end-to-end encryption. (#894).
    • Add m.room.pinned_events state event for rooms. (#1007).
    • Add mention of ability to send Access Token via an Authorization Header.
    • New endpoints:
      • GET /joined_rooms (#999).
      • GET /rooms/{'{'}roomId{'}'}/joined_members  (#999).
      • GET /account/whoami (#1063).
      • GET /media/{'{'}version{'}'}/preview_url  (#1064).
  • Spec clarifications:
    • Add endpoints and logic for invites and third-party invites to the federation spec and update the JSON of the request sent by the identity server upon 3PID binding (#997)
    • Fix "membership" property on third-party invite upgrade example (#995)
    • Fix response format and 404 example for room alias lookup (#960)
    • Fix examples of m.room.member event and room state change, and added a clarification on the membership event sent upon profile update (#950).
    • Spell out the way that state is handled by POST /createRoom (#362).
    • Clarify the fields which are applicable to different types of push rule (#365).
    • A number of clarifications to authentication (#371).
    • Correct references to user_id which should have been sender (#376).
    • Correct inconsistent specification of redacted_because fields and their values (#378).
    • Mark required fields in response objects as such (#394).
    • Make m.notice description a bit harder in its phrasing to try to dissuade the same issues that occurred with IRC (#750).
    • GET /user/{'{'}userId{'}'}/filter/{'{'}filterId{'}'}  requires authentication (#1003).
    • Add some clarifying notes on the behaviour of rooms with no m.room.power_levels event (#1026).
    • Clarify the relationship between username and user_id in the /register API (#1032).
    • Clarify rate limiting and security for content repository. (#1064).
...and you can read the spec itself of course over at https://matrix.org/docs/spec.  It's worth noting that we have slightly bent the rules by including three very minor 'breaking changes' in 0.3, but all for features which to our knowledge nobody is depending on in the wild.  Technically this should mean bumping the major version prefix (i.e. moving to r1), but given how minor and nonimpacting these are we're turning a blind eye this time.

Meanwhile, Synapse 0.25 is out!

This is a medium-sized release; the main thing being to support configurable room visibility within groups (so that whenever you add a room to a group, you're not forced into sharing their existence with the general public, but can choose to just tell group members about them).  There's also a bunch of useful bug fixes and some performance improvements, including lots of contributions from the community this release (thank you!).  Full release notes are:

Changes in synapse v0.25.0 (2017-11-15)

Bug fixes:

  • Fix port script (PR #2673)
Changes in synapse v0.25.0-rc1 (2017-11-14)

Features:

Changes:
  • Ignore tags when generating URL preview descriptions (PR #2576) Thanks to @maximevaillancourt!
  • Register some /unstable endpoints in /r0 as well (PR #2579) Thanks to @krombel!
  • Support /keys/upload on /r0 as well as /unstable (PR #2585)
  • Front-end proxy: pass through auth header (PR #2586)
  • Allow ASes to deactivate their own users (PR #2589)
  • Remove refresh tokens (PR #2613)
  • Automatically set default displayname on register (PR #2617)
  • Log login requests (PR #2618)
  • Always return is_public in the /groups/:group_id/rooms API (PR #2630)
  • Avoid no-op media deletes (PR #2637) Thanks to @spantaleev!
  • Fix various embarrassing typos around user_directory and add some doc. (PR #2643)
  • Return whether a user is an admin within a group (PR #2647)
  • Namespace visibility options for groups (PR #2657)
  • Downcase UserIDs on registration (PR #2662)
  • Cache failures when fetching URL previews (PR #2669)
Bug fixes:
  • Fix port script (PR #2577)
  • Fix error when running synapse with no logfile (PR #2581)
  • Fix UI auth when deleting devices (PR #2591)
  • Fix typo when checking if user is invited to group (PR #2599)
  • Fix the port script to drop NUL values in all tables (PR #2611)
  • Fix appservices being backlogged and not receiving new events due to a bug in notify_interested_services (PR #2631) Thanks to @xyzz!
  • Fix updating rooms avatar/display name when modified by admin (PR #2636) Thanks to @farialima!
  • Fix bug in state group storage (PR #2649)
  • Fix 500 on invalid utf-8 in request (PR #2663)

Finally...

If you haven't noticed already, Riot/Web 0.13 is out today, as is Riot/iOS 0.6.2 and Riot/Android 0.7.4.  These contain massive improvements across the board - particularly mainstream Communities support at last on Riot/Web; CallKit/PushKit on Riot/iOS thanks to Denis Morozov (GSoC 2017 student for Matrix) and Share Extension on iOS thanks to Aram Sargsyan (also GSoC 2017 student!); and End-to-end Key Sharing on Riot/Android and a full rewrite of the VoIP calling subsystem on Android.

Rather than going on about it here, though, there's a full write-up over on the Riot Blog.

And so there you go - new releases for eeeeeeeeveryone!  Enjoy! :)

--Matthew, Amandine & the team.

Synapse 0.24 is here!

24.10.2017 00:00 — Releases Matthew Hodgson

Hi folks,

Synapse 0.24 is out (currently at 0.24.1)! This is a pretty big release as it includes initial support for Groups, also known as Communities (UI for which is landing currently on Riot/Web and later Riot/Mobile). Groups let you associate together a set of users and rooms, letting you define a community - e.g. +matrix:matrix.org is the community of the core Matrix project itself (whose users are the core Matrix.org team, and whose public rooms are the rooms we officially manage/moderate as Matrix.org).  We'll yell more about Groups once the UI is ready for action in the near future, but the good news is that Synapse should be ready to go (although the API is still fairly experimental and very much evolving).

Other stuff worth calling out in this release includes: massive performance improvements on receiving federation traffic (we now process federation traffic for different rooms in parallel); fixing a major cause of performance issues (caused when processing spurious events for rooms you've actually left); modularising and improving the the spamchecker; @room notification support; backup media repository support; and finally the ability to autojoin new users to a set of rooms on the server!

You can get the latest release from Github as usual; have fun - and thanks for flying Matrix :)

Changes in synapse v0.24.1 (2017-10-24)

Bug fixes:

  • Fix updating group profiles over federation (PR #2567)

Changes in synapse v0.24.0 (2017-10-23)

No changes since v0.24.0-rc1

Changes in synapse v0.24.0-rc1 (2017-10-19)

Features:

Changes:
  • Make the spam checker a module (PR #2474)
  • Delete expired url cache data (PR #2478)
  • Ignore incoming events for rooms that we have left (PR #2490)
  • Allow spam checker to reject invites too (PR #2492)
  • Add room creation checks to spam checker (PR #2495)
  • Spam checking: add the invitee to user_may_invite (PR #2502)
  • Process events from federation for different rooms in parallel (PR #2520)
  • Allow error strings from spam checker (PR #2531)
  • Improve error handling for missing files in config (PR #2551)
Bug fixes:
  • Fix handling SERVFAILs when doing AAAA lookups for federation (PR #2477)
  • Fix incompatibility with newer versions of ujson (PR #2483) Thanks to @jeremycline!
  • Fix notification keywords that start/end with non-word chars (PR #2500)
  • Fix stack overflow and logcontexts from linearizer (PR #2532)
  • Fix 500 error when fields missing from power_levels event (PR #2552)
  • Fix 500 error when we get an error handling a PDU (PR #2553)

Announcing Matrix meetup in Berlin - Thursday October 19th!!

12.10.2017 00:00 — General Matthew Hodgson

Hi folks,

On October 19th (next Thursday, as of the time of writing) we're going to be back in Berlin for various meetings - and we're incredibly excited that BlueYard have offered to host the world's first ever official Matrix and Decentralised Communications Meetup at their offices in Kreuzberg!  Matthew, Amandine and maybe others will be attending and speaking from the core team, and giving a VIP tour of the long-long-long-awaited Groups/Communities features in Matrix and Riot as well as some of the other good stuff in the pipeline - and we're also excited to have Exul joining us from the community to talk about his recent Matrix<->Rocket.Chat bridging adventures.  We're also expecting some exciting folks to join us from the Ethereum community to talk about decentralised realtime comms in their ecosystem - plus if anyone wants to talk about other Matrix/XMPP/Tox/Briar/Richochet or similar projects please ping us and let us know asap!

Update: we're excited to announce that Jack Fransham from Polkadot (who are very active Riot/Matrix users - and just raised >$130M in their token generation event yesterday) will also be joining us to tell us all about how Polkadot bridges together different blockchains!. (The original speaker was Marek Kotewicz, but availability didn't work out).

Update 2: and our final speaker is confirmed as Maximilian Möhring, CEO of Keyp, who's going to talk about their self-sovereign decentralised identity system.

Update 3: ...and we have a last minute addition for a lightning talk from Secushare (Psyc + GNUnet, fully decentralised p2p encrypted comms)!!

Space is limited to 70 attendees, so please register on Eventbrite asap if you'd like to come!

As a taster: the official video of our massive talk from the ETHLDN meetup a few weeks ago was just released (see below).  The meetup in Berlin will have different content and be more free-form, letting folks ask their own questions and steer the conversation and discussion as you see fit: so please come hang out in person, grab pizza and beer courtesy of BlueYard, and find the answers to all the deepest Matrix questions you never knew you even had...!

See you next week! :D

Synapse 0.23 is out!

02.10.2017 00:00 — General Matthew Hodgson

We've just released Synapse 0.23 - which contains a bunch of significant performance improvements, bug and stability fixes - as well as a few new features: basic spam checking (the ability to configure your homeserver to reject events which match arbitrary rules, both from users and other servers) - and long-awaited support for privacy-preserving ('event_id_only') push notifications.  This means that apps can choose to register themselves to receive push notifications which do not contain any information about the actual push, but instead act as a simple "wake up!" event, which triggers the app to then sync via the client-server API in order to display the actual push notification details.  This is particularly useful for push notifications for E2E encrypted rooms, as it means the client has a chance of decrypting the message in order to display the push notification details in the UI (if the user wants that).  matrix-ios-sdk and matrix-android-sdk are in the process of being moved over to use the new 'event_id_only' push format.

Long-awaited Communities/Groups will land in Synapse 0.24, which should come quite soon (we're almost ready to merge it to develop, but it's a major update so we wanted to get 0.23 out the door first).

As always, you can get your latest Synapse from https://github.com/matrix-org/synapse or a OS repository of your choice (we've just released the official Debian packages).

Full details of Synapse 0.23:

Features:

  • Add a frontend proxy worker (PR #2344)
  • Add support for event_id_only push format (PR #2450)
  • Add a PoC for filtering spammy events (PR #2456)
  • Add a config option to block all room invites (PR #2457)
Changes:
  • Use bcrypt module instead of py-bcrypt (PR #2288) Thanks to @kyrias!
  • Improve performance of generating push notifications (PR #2343#2357#2365, #2366#2371)
  • Improve DB performance for device list handling in sync (PR #2362)
  • Include a sample prometheus config (PR #2416)
  • Document known to work postgres version (PR #2433) Thanks to @ptman!
Bug fixes:
  • Fix caching error in the push evaluator (PR #2332)
  • Fix bug where pusherpool didn't start and broke some rooms (PR #2342)
  • Fix port script for user directory tables (PR #2375)
  • Fix device lists notifications when user rejoins a room (PR #2443#2449)
  • Fix sync to always send down current state events in timeline (PR #2451)
  • Fix bug where guest users were incorrectly kicked (PR #2453)
  • Fix bug talking to IPv6 only servers using SRV records (PR #2462)
  • Fix regression in performance of syncs (PR #2470)

Matrix "Live"!

29.09.2017 00:00 — General Matthew Hodgson

Occasionally folks ask why we don't update the blog more often - we're infamous in only doing big formal updates once every 3 months, unless there's something very specific to yell about.  However, it's possible that some readers don't realise that we have been publishing a weekly status update blog since July - albeit a video blog: Matrix Live!  The episodes are published on YouTube (for now, although in future we're going to use Matrix to distribute them), and are first made available to Quadratic ($5+) Patreon supporters.  After a week we make them public to everyone though and add them to the YouTube Playlist.  The videos also have very brief bullet-point summaries of the contents in the description for those who don't have time to watch and just want to skim for interesting stuff.

We appreciate that video blogs are unusual for a FOSS project relative to written blogs - but we've chosen to go down this path because counterintuitively it takes much less time to just speak about what's going on than write it down; for whatever reason my blogposts always seem to take hours to write as I get sucked into the details and try to be as comprehensive and accurate as possible.  Whereas just chatting about it with Amandine is much easier, and given that we do it anyway; why not film it for everyone's benefit?  We always film the show in one continuous take (hence the "live"), so it's literally only eating 10-15 mins out of our week.

Eitherway, just wanted to remind anyone who reads this blog that the video blog exists, and to gently encourage folks to donate at Patreon or Liberapay if they want to get access to the videos on the day they air, rather than having to wait for a week!  Finally, we'd suggest that folks subscribe to the playlist itself on YouTube even if they don't donate, so they can be reminded about new eps.

So, without further ado, here's an alarming montage of Matthew & Amandine geeking about Matrix, in case you've missed the show so far!

Experiments with Matrix for the Purism Librem5, starring Ubports and Nheko

28.09.2017 00:00 — General Matthew Hodgson

TL;DR: If you love FOSS-friendly hardware and if you love Matrix, please preorder a Purism Librem5 Matrix-native smartphone, so we can fully bring native Matrix communication to both phones and desktop!

It's been just over a month since Purism announced the campaign to fund the Matrix-native Librem5 FOSS smartphone - and the campaign is doing pretty well, with 54% of its target reached as of the time of writing!  So in a shameless attempt to whet everyone's appetite and encourage everyone to fund the remaining 50%, we thought we'd share some of the experiments we've been doing with running native Matrix clients on a pure Linux phone.

Unfortunately the Librem5 doesn't exist yet, but we do happen to have an BQ Aquaris E5 Ubuntu Phone hanging around - so we wondered: Is it possible to run a native desktop Matrix client like mujx's Nheko on a Linux phone, given all the latest Qt voodoo? And just how hard is it anyway to update the Qt platform abstractions (or GTK for that matter) for a given platform?  In retrospect, we probably should have just run uMatriks on it - a proper dedicated Ubuntu Touch Matrix Client, but then we wouldn't have had a useful tour of maintaining the guts of a Qt distribution on mobile :)

So the core problem of running a client like Nheko on Ubuntu Touch is that it uses lots of fun glossy stuff from Qt 5.9, whereas Ubuntu Touch is still on Qt 5.4, which is over 2 years old now.  Also, it's been written as a desktop client so needs a bit of tuning to support a 'fat-finger' mobile form factor, although this is just a simple matter of programming and is a very similar problem to ensuring the desktop app has a nice responsive design on small screen window sizes (similar to how the telegram desktop client handles it).  In the end, we focused on solving the Qt problem: building a custom Qt 5.9 for Ubports (the community project who do a fantastic job of continuing Ubuntu Touch development since Canonical pulled out), while for simplicity building it on top of the current ubports distribution (which is effectively still Ubuntu 15.04).  The reason for all this Ubuntu stuff rather than using PureOS is simply that it's not far enough along, and we don't physically have a Librem5 dev kit yet to play with!

In practice, this has been a fascinating process: setting up a crosscompiler to build all of Qt5.9, and then porting the ubuntumirclient Qt Platform Abstraction to work with Qt5.9, as well as (finally) working out how to build a Qt5.9-compatible custom Maliit input context platform plugin to get the onscreen keyboard (OSK) up and running.  But we got there in the end, and it was rather fun to finally see the Nheko splash screen popping up on the Aquaris E5! :D

There was then a bit of a nightmare to get the OSK to work, thanks to https://bugreports.qt.io/browse/QTBUG-46009 causing the plugin to be silently not updated - but could then log in and the app worked great (albeit a bit slow thanks to being a debug build on the energy-efficient but slow Mediatek MT6582 SoC):

   
Now the next step here would obviously be to tweak the app properly to layout on a phone (bigger fonts; bigger buttons; resize the window to make room for the OSK; separate the Left Panel from the timeline view; etc) - but the point here was more to show a fully fledged native Matrix client running on a current Linux Phone environment and see how it feels.  And we're happy to say that it leaves us dying to get our hands on a proper Librem5 so we can work with Nheko, uMatriks, libqmatrixclient and all the other native Matrix client projects to see how we can get the best possible native client experience running in PureOS for the phone!!

Finally, there doesn't seem to be much documentation out there on how to do a heavy customisation of Ubports like this, so for the sake of posterity, here's the guide if anyone else is crazy enough to try this (or for when Ubports gets around to doing an official update to Qt 5.9 for their OS!).  A versioned copy of this lives over at this gist.

Thanks for reading, and don't forget to preorder!

Matthew

Recipe: Librem5 experiments with an Ubuntu Phone and Nheko

Starting point: one old BQ Aquaris E5 ubuntu phone, running some old version of Ubuntu Touch which had got completely stuck (UI only unfreezing for 2-3 seconds every 2-3 minutes).

Step one: flash to latest UBPorts image:

sudo add-apt-repository ppa:ubuntu-sdk-team/ppa
sudo apt-get update
sudo apt-get install ubuntu-device-flash
sudo apt-get install phablet-tools
  • Grab an adb-compatible recovery image (yes, seems like the right place is someone's personal webspace...)
wget http://people.canonical.com/~jhm/barajas/recovery-vegetahd.img
  • If your Ubuntu desktop is running in a VM, make sure you have USB 2.0 or 3.0 support enabled (in Virtualbox this needs the extension pack installed). USB 1 is too slow and the flash will timeout, semi-bricking the phone.
  • Press volume-up and power on the phone during boot to get at the bootloader. Make sure it's not plugged into USB
  • Select fastboot
  • Plug into USB
  • Flash the recovery image and latest UBPorts OS:
sudo ubuntu-device-flash --server=http://system-image.ubports.com touch --device=vegetahd \\
                         --channel=15.04/stable --bootstrap --recovery-image=recovery-vegetahd.img \\
                         --developer-mode --password=secret
  • Ensure the system OS is writable. (Ubuntu Touch runs the OS partition read-only by default to protect users. In this case, you can always re-flash it if all goes wrong.)
sudo phablet-config writable-image
  • Get an SSH server running on the phone before you go insane
adb shell
sudo /etc/init.d/ssh start # password is as set when flashing.
Step two: cross-compile latest Qt 5.9 for the phone.

Ubuntu 15.04 shipped with 5.4, which is pretty old now, and too old for nheko. Based on https://rm5248.com/cross-compile-qt-for-arm/

# grab the source for Qt5
git clone git://code.qt.io/qt/qt5.git
cd qt5
./init-repository

# grab the right dev headers (as qtubuntu needs dbus & atspi support)
ssh phablet@phone "sudo apt-get install libdbus-1-dev libatspi2.0-dev libssl-dev"

# grab a copy of the root filesystem on the phone for the cross-compile to run against.
# you could also sshfs mount or something if you could be bothered.
mkdir ~/phone
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \\
           --exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
export ROOTFS=~/phone

# install the crosscompiler.
# We probably have to use GCC 4.9 so that it can link ok against the older system libraries
# (libstdc++ etc) on Ubuntu Touch 15.04
sudo apt-get install arm-linux-gnueabihf-g++-4.9

# fix up the absolute symlinks (important!)
cd ~
git clone https://github.com/rm5248/cross-compile-tools.git
./cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9

# define a mkspec target for armhf
cd ~/qt5
cp -a qtbase/mkspecs/linux-arm-gnueabi-g++ qtbase/mkspecs/linux-arm-gnueabihf-g++
cat > qtbase/mkspecs/linux-arm-gnueabihf-g++/qmake.conf <<EOT
#
# qmake configuration for building with arm-linux-gnueabihf-g++
#

MAKEFILE_GENERATOR      = UNIX
CONFIG                 += incremental
QMAKE_INCREMENTAL_STYLE = sublib

include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)

# modifications to g++.conf
QMAKE_CC                = arm-linux-gnueabihf-gcc-4.9
QMAKE_CXX               = arm-linux-gnueabihf-g++-4.9
QMAKE_LINK              = arm-linux-gnueabihf-g++-4.9
QMAKE_LINK_SHLIB        = arm-linux-gnueabihf-g++-4.9

# modifications to linux.conf
QMAKE_AR                = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY           = arm-linux-gnueabihf-objcopy
QMAKE_NM                = arm-linux-gnueabihf-nm -P
QMAKE_STRIP             = arm-linux-gnueabihf-strip

!host_build {'{'}
        QMAKE_INCDIR_OPENGL     = $ROOTFS/usr/include/GL
        QMAKE_LIBDIR_OPENGL     = $ROOTFS/usr/lib/arm-linux-gnueabihf
        # GCC 4.9 apparently doesn't know where its own libstdc++ headers are when cross-compiling...
        QMAKE_INCDIR            = /usr/arm-linux-gnueabihf/include/c++/4.9.3 \\
                                  /usr/arm-linux-gnueabihf/include/c++/4.9.3/arm-linux-gnueabihf
{'}'}

load(qt_config)
EOT

# build it!
./configure \\
    -v \\
    -confirm-license \\
    -prefix /opt/qt5-arm \\
    -sysroot $ROOTFS \\
    -opensource \\
    -nomake examples \\
    -nomake tests \\
    -opengl es2 \\
    -qpa ubuntumirclient \\
    -xplatform linux-arm-gnueabihf-g++ \\
    -platform linux-g++ \\
    -feature-accessibility \\
    -feature-accessibility-atspi-bridge \\
    -feature-webrtc \\
    -feature-proprietary-codecs \\
    -reduce-exports

make -j8

# go to lunch

make install

If anything goes wrong, a good bet (having backed up your new mkspec target) is to git clean everything:

git submodule foreach --recursive "git clean -dfx"
git clean -dfx

Step 3: compile qtubuntu for Ubuntu-specific Qt stuff like the integration with the Mir display server (hey, at this point it feels like we're building our very own zombie Ubuntu Touch 17.04... :/)

# grab dev package deps
ssh phablet@phone "sudo apt-get install libubuntu-application-api-dev libudev-dev"
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \\
           --exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
~/cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9

# grab the qtubuntu source
bzr branch lp:qtubuntu

# find an version old enough that it builds against the old mir in 15.04
bzr revert -r 345

# cherrypick patches so it builds against qt 5.9...
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/354
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/372
http://bazaar.launchpad.net/~phablet-team/qtubuntu/trunk/revision/394
# ...we probably need others too.

/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++

# we probably should have told Qt about more pkgconfig libraries when we built it, so as to not have to do it manually here...
export PKG_CONFIG_LIBDIR=$ROOTFS/usr/lib/pkgconfig:$ROOTFS/usr/share/pkgconfig:\\
$ROOTFS/usr/lib/arm-linux-gnueabihf/pkgconfig/:$ROOTFS/opt/qt5-arm/lib/pkgconfig/
export PKG_CONFIG_SYSROOT_DIR=$ROOTFS

# might need to manually explicitify the --sysroot definitions in qt's qconfig.pri
# as otherwise QT_SYSROOT seems not to be getting picked up for reasons unknown

make -j4
cp src/ubuntumirclient/libqpa-ubuntumirclient.so $ROOTFS/opt/qt5-arm/plugins/platforms/

# Need to build our own libmaliitphabletplatforminputcontextplugin.so for onscreen keyboard, as
# you can't mix Qt platform plugins between versions - see https://bugreports.qt.io/browse/QTBUG-46009
cd
bzr branch lp:ubuntu/vivid/maliit-framework
cd maliit-framework
# add QMAKE_LFLAGS+='-lQt5Network -lGLESv2' to config.pri

# technically don't need to build all of maliit - only the platform inputcontext plugin is required
export QMAKEMODULES=/mnt/build/qt5/qtdeclarative/mkspecs/modules 
/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++
make -j4

# build the input-context plugin
cd input-context
# change the version of the plugin in main.cpp so that it's picked up by Qt 5.9 (the API hasn't changed;
# it's just the difference between an explicit and implicit version):
# Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface.5.1" FILE "maliit.json")
/mnt/build/qt5/qtbase/bin/qmake -spec /mnt/build/qt5/qtbase/mkspecs/linux-arm-gnueabihf-g++

make -j4
make install

# rsync our beautiful new Qt5.9 over to the phone, including the qtubuntu plugin
rsync -avz $ROOTFS/opt/qt5-arm root@phone:/opt/

Step 4: cross-compile nheko as an experiment

# check it out
git clone --recursive git+ssh://[email protected]/mujx/nheko
cd nheko

# define a cross-compile toolchain (https://cmake.org/Wiki/CMake_Cross_Compiling)
cat > Toolchain-arm-linux-gnueabihf.cmake <<EOT
# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
# this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
# needed to get the right flavour of ARM
SET(CMAKE_SYSTEM_PROCESSOR armv7)

# specify the cross compiler
SET(CMAKE_C_COMPILER   /usr/bin/arm-linux-gnueabihf-gcc-4.9)
SET(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++-4.9)

# where is the target environment
SET(CMAKE_SYSROOT  $ROOTFS)
SET(CMAKE_FIND_ROOT_PATH  $ROOTFS)

# sort out our includes...
SET(CMAKE_CXX_FLAGS "${'{'}CMAKE_CXX_FLAGS{'}'} \\
    -I$ROOTFS/usr/include/c++/4.9 \\
    -I$ROOTFS/usr/include/arm-linux-gnueabihf \\
    -I$ROOTFS/usr/include/arm-linux-gnueabihf/c++/4.9")

SET(CMAKE_EXE_LINKER_FLAGS "${'{'}CMAKE_EXE_LINKER_FLAGS{'}'} \\
  $ROOTFS/lib/arm-linux-gnueabihf/libc.so.6 \\
  $ROOTFS/usr/lib/arm-linux-gnueabihf/libm.so \\
  $ROOTFS/usr/lib/arm-linux-gnueabihf/libhybris-egl/libGLESv2.so.2")

# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

SET(CMAKE_PREFIX_PATH $ROOTFS/opt/qt5-arm)
EOT

# grab its dependencies on the phone and sync them over to your local phone FS copy
ssh phablet@phone 'sudo apt-get install liblmdb-dev'
rsync -avz --exclude /proc --exclude /run --exclude /sys --exclude /dev \\
           --exclude /android --exclude /var/lib/lxc phablet@phone:/ ~/phone/system
~/cross-compile-tools/fixQualifiedLibraryPaths $ROOTFS /usr/bin/arm-linux-gnueabihf-g++-4.9

# gen the makefile
sudo apt-get install cmake
cmake -DLMDB_LIBRARY=$ROOTFS/usr/lib/arm-linux-gnueabihf/liblmdb.so \\
      -DCMAKE_TOOLCHAIN_FILE=`pwd`/Toolchain-arm-linux-gnueabihf.cmake \\
      -H. -Bbuild -DCMAKE_BUILD_TYPE=Release
# remove -march=native from CMakeLists.txt

# build it
VERBOSE=1 make -C build -j4

# XXX: you might need to touch the Toolchain file and then run again to pick up
# the CXX_FLAGS correctly for some reason.

# run it!
rsync -avz $ROOTFS/home/phablet/nheko phablet@phone:/home/phablet
ssh phablet@phone "export MIR_SOCKET=/run/user/32011/mir_socket;
                   ./build/nheko --desktop_file_hint=unity8"

# N.B. if debugging under gdb, use `handle SIGILL nostop`

Step 5: Package nheko

# make sure you have a manifest.json, nheko.png, nheko.apparmor and nheko.desktop.
# If you don't have an icon, the app won't show up.
# you can grab it from the matthew/mobile branch of github.com/matrix-org/nheko
click build ./
scp im.vector.nheko_0.1_all.click phablet@phone:

# install it
ssh phablet@phone pkcon install-local --allow-untrusted im.vector.nheko_0.1_all.click

# ...and then swipe down on the app listing to hopefully see the app there.
# if that doesn't work, you can manually launch it with:
ssh phablet@phone ubuntu-app-launch im.vector.nheko_nheko_0.1