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

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!

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!!

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

TADHack Global 2017 and THE Port 2017

TADHack Global 2017

At the end of September, TADHack Global was held where almost 150 teams spent their weekends hacking towards the $45k total prize money up for grabs. Luke spent the final day of the hack talking to teams hacking at IDEALondon in Shoreditch, meeting a few Matrix enthusiasts and long-time collaborators.

Out of 10 hacks, 2 of 4 local winners won prizes locally and went on to be global winners alongside 6 other teams using Matrix as part of their hacks. Checkout the TADHack London Wrap-up for details on all of the awesome hacks, especially Aviral Dasgupta‘s Pushtime and Polite.ai.

Well done to everyone who took part, and a special thanks to those flying Matrix :)

THE Port 2017

The following weekend was THE Port 2017, a humanitarian-themed hackathon held at CERN, Geneva in Switzerland. Among the 7 teams participating, the Matrix team consisted of a few software developers from Bity including Matrix enthusiast Alejandro Avilés (who very kindly helped us get a team into the hackathon). Luke and Dave from the Matrix London office also flew out to help the cause and by the end had a very stable, working prototype by the end of the competition.

The hack we made was a communications system backed by Matrix for use in refugee camps, an idea that hatched at the start of the hackathon (whereas the other projects were well established ideas up to 6 weeks before the event). Check out the code on GitHub if you’re interested in the client-side apps we made over the weekend.

It was another fun weekend for the Matrix team and we look forward to the next one. Stay tuned for updates on upcoming Matrix events!

Synapse 0.23 is out!

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”!

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

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://git@github.com/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

Matrix & Riot for Cryptocurrency Communities

Hi folks,

Over the last few weeks there’s been a huge movement in the cryptocurrency communities over needing to find a better communication medium than Slack.  Some of the biggest communities for projects like Status, Aragon, TenX, Tezos, OmiseGo, Polkadot and many others are getting overrun by phishing attacks where malicious users have set up bots which auto-DM users joining the room in order to try to extract private keys to steal funds.  Slack has very limited support for avoiding this sort of abuse (especially at the free service tiers), so the search is on for an alternative solution.  There seems to be some confusion over what Matrix & Riot can and can’t do to help the situation, so we thought we’d write a blog post about it (especially after we had so much fun at the ETHLDN meetup last week!).

To be clear: we see Ethereum, Bitcoin, Ripple, Stellar and all the other decentralised currencies as being very closely related to Matrix.  Just as distributed ledgers disrupt the fragmented oligopoly old-school banking industry, we want Matrix to disrupt the relatively old-school communications systems of today. And so we’d really rather like that Matrix and Riot rocked when it comes to supporting cryptocurrency communities, and this is something we intend to dedicate resources to long term: we’ve got some big plans.

Things Matrix provides:

Decentralisation. Rather than each community having its own silo, with users having to juggle accounts over all of them, Matrix decentralises rooms over all the different servers. Users can have a single account and still jump into all the other communities (as well as the rest of the Matrix universe). However, each community can run its own server instance (if they want to) and have complete control over its behaviour.

Encryption. Matrix has first-class end-to-end encryption (although the UX in Riot needs refinement and is technically still beta).  This is great for encrypting rooms which need privacy – although it does come at the expense of being able to do server-side content filtering, which is desirable for fixing phishing attacks. So you probably don’t want to turn on encryption for rooms which need phish filtering (or you could use a bot to decrypt and autoremove malicious content).

A standard real-time API. One bit of feedback we’ve heard recently is that “Riot has no realtime API”.  This is spectacularly untrue; Riot is a client for the Matrix protocol, which is in and of itself an open standard realtime API for messaging, which you can use for writing whatever bots and extensions your heart desires.

Finely grained permissions per room. Likewise there seems to be some confusion over Matrix’s access control model.  In Matrix, each user in a room has a ‘power level’ – typically a number between 0 and 100.  By convention, normal users who have just joined the room have 0; the room creator and ‘admins’ have 100; and ‘moderators’ have 50.  Pretty much every access you can do in a room then has a threshold which defines how much power a user needs to perform the action.  It doesn’t get much more finely grained than this!

Ability to disable DMs and room invites. Architecturally Matrix lets you prevent users who use a given server from receiving invites (the homeserver can just autoreject the invites, based on some set of rules).  We’re currently putting together a quick demo to show this off in the Synapse server implementation, but it boils down to having an option to cancel invites here (federated) and here (local). Check out the demo below!

Ability to filter content. Similarly, Matrix architecturally lets a given server filter out messages based on content or some other pattern from being received by its users.  We’re also putting together a demo of this too in Synapse, which boils down to redacting inappropriate events here (federated) and here (local).  The demo isn’t quite ready yet but we’ll update this & yell when it is. Check out the demo below!

UPDATE – the DM/invite disabling and spam/phish filtering code has now landed on the develop branch of Synapse, and we’ve deployed an demo example of it at https://phishfree.riot.im.  Messages containing the word ‘SPAM’ are filtered, and invites are disabled (unless you are the local server admin).

Other stuff. Matrix and Riot give loads of other fun stuff too:

  • Widgets – the ability to embed arbitrary apps into your rooms (video conferences; currency tickers; DApps; wallets; monitoring dashboards; etc.).
  • 100% Native clients on iOS & Android (including Jitsi video conferencing & Widgets, as of the develop branch!)
  • Read receipts! (how can you live without them on Slack?!)
  • Internationalised to 20+ languages (thanks to the community! :)
  • Bridges through to IRC, Slack, Gitter, and more.
  • All sorts of alternative clients (e.g. nheko, quaternion) and SDKs
  • Insanely scalable and performant next-generation server (Dendrite) on the horizon
  • An open spec for the protocol.
  • 100% Apache-licensed FLOSS.  Riot/Web is particularly easy to hack on and theme & customise as needed.
  • Ability to disable federation for a room if you really want to lock it down to the users & rules of a single server.

Things we need to improve:

Groups (aka Communities):  One of the biggest missing features in Matrix is the ability to define groups of users & rooms, similar to a Slack team or Discord server, which can be used to organise together a set of discussions and generally give a feeling of community.  We’ve been working hard at this and expect to see it land in Riot/Web in the next few weeks.  In the meanwhile, you can see some of the UX we’re aiming for here!

E2E UX (and Riot UX in general):  While the underlying encryption of Matrix is solid, the UX exposed by Riot needs considerable work – specifically to improve the device verification flow and automatically share keys between trusted devices.  We’re continuing to work on this over the next few months.  Likewise there are many areas for possible improvement in Riot’s overall UX and design that we’re working through as urgently as we can.

Active Application Services: The per-server filtering described above is good if you just want to protect users on a given server (e.g. the server you point your community at).  However, if you want to filter all the messages for a given room which may be federated over multiple servers, you need a way to define a centralised chokepoint to define the filtering rules.  Architecturally this is meant to be performed by an ‘Active Application Service’ in Matrix, but we’ve not yet defined or implemented this API.  The idea for the room to define a list of services that messages are filtered through by all servers before they may be accepted for the room.  This would be the ideal solution to the phishing-filtering problem, but in practice filtering just local users (and perhaps disabling federation for particularly sensitive rooms or servers) is probably good enough for the immediate problem here.

Hope this provides some much-needed clarity to the debate! If there are other features cryptocurrency communities need to thrive please let us know, as we’d like to actively help to support decentralized communities.  #matrix-dev:matrix.org is probably the best place for further questions :)

Finally: one thing that has come up a few times in this discussion has been “Matrix’s funding crisis means they may not be here to stay”.  All I can say is that Matrix is here to stay. Even if the core team ended up just being Matthew hacking away by himself funded by Patreon/Liberapay, we have a large and passionate wider dev community who aren’t going anywhere.  But more importantly (and not wishing to jinx it), in the last few weeks we have received offers of significant funding which may hopefully resolve the funding crisis for the foreseeable.  Nothing is signed yet, but watch this space, and meanwhile I strongly suggest betting on Matrix being here to stay!

–Matthew

The Librem 5 from Purism: A Matrix Native Smartphone.

Hi folks,

This is a big news week in Matrixland: hot on the heels of releasing Matrix Widgets and Riot 0.12, we have another massive announcement to make!

We’ve been approached by Purism to partner up to provide the communications subsystem for their upcoming Librem 5 smartphone – for which they are launching a crowdfunding campaign starting today! The whole idea of the phone is to provide unprecedented privacy, security and autonomy by running an entirely FOSS Debian-based GNU/Linux stack (even including CPU & GPU drivers!), and we are incredibly proud and overexcited that the folks at Purism have asked the Matrix core team to provide the native dialler and messaging app for the phone.  Yes, this means that the phone will literally boot by default into Matrix for all its primary communications (although, being FOSS, you could of course use a different dialler if you wanted).  The intention is to be a very usable and flexible phone for folks who value freedom, privacy and simplicity over the (relative) quagmire of iOS or Android – and of course jumping way ahead of where Apple or Google are in terms of integrating next-generation communications into the very heart of the device.

This is unbelievably exciting, as Matrix’s vision from the outset has been to provide an open, decentralised and encrypted alternative to the Public Telephone Network – and the idea of devices emerging which are native to Matrix is a dream come true. It also gives us the excuse that we’ve been looking for to produce a truly excellent lightweight native Matrix client, built to run on both handset and desktop devices, complete with end-to-end encryption.  We’re not sure whether this is going to end up being Qt or GTK based yet, but expect to see the Matrix team getting a lot more involved in the current native Matrix client projects (nheko, Quaternion, ruma-gtk, matrix-glib-sdk, qmatrixclient etc) in future!

Depending on the success of the crowdfunding campaign, it may also give us scope to finally build out proper carrier-grade Matrix<->PSTN bridges: letting Matrix clients terminate and originate VoIP calls on the public phone network.  It’s long been an embarrassment that Matrix hasn’t had this given that pre-Matrix we spent our lives building commercial SIP gateways and softphones for telcos, and the ability to use Matrix as a proper VoIP softphone on dedicated hardware is incredibly appealing.  Obviously the phone will also support GSM calling, but the intention is to default to WebRTC calling using Matrix whenever the phone has good IP connectivity – making it truly an IP-first smartphone.

Now, this is obviously a very ambitious project, but we believe that Purism is able to deliver based on the work they’ve done already with crowdfunding and shipping Librem 15 and 13 laptops, shipping with as open a FOSS stack as is possible on contemporary hardware, complete with unique privacy features such as hardware kill-switches for Camera, Wifi, Bluetooth etc.  We met with them at GUADEC 2017 and subsequently heard trusted reports from DebConf 2017 of the quality of the hardware.  It seems that as the company has gathered experience their ambitious goals have become more and more attainable – and it’s also interesting that their dev team is significantly made up of core Debian developers (including Chris Lamb, the Debian Project Leader for 2017).  We’re particularly excited from a philosophical perspective that the Librem 5 is targeting the NXP (Freescale) i.MX6 or i.MX8 ARM-based processor and Vivante GPU – both of which can be run without any proprietary microcode or proprietary drivers.  From everything we’ve heard, this is going to be a spectacularly FOSS-friendly device.

So, if you’re interested in being first to own the world’s first ever Matrix-native phone, or if you want to support the creation of a kick-ass native Matrix desktop/handset client, or perhaps if you want carrier-grade VoIP in Matrix… then please head over to Puri.sm and join the campaign!  Needless to say, if the campaign is successful it will also significantly help Matrix’s current funding situation.

Finally, for more context, here’s a special mid-week episode of Matrix “Live”, featuring Matthew and Todd Weaver, the CEO of Purism, discussing the Librem 5 and what it means for both Purism and Matrix!

As always, feedback on this project is very welcome – come tell us in #matrix:matrix.org what you think!  And thank you, if you choose to support this campaign :)

Matthew, Amandine & the team.

Introducing Matrix Widgets – including Jitsi video conferencing!

Hi all,

We’ve been working hard over the last few months on the brand new concept of Matrix “widgets” (sometimes called “apps”, but we’ll call them “widgets” here to be marginally less ambiguous) – and we’re super excited to see an initial implementation of them land today in Riot/Web 0.12 (alongside always-on Rich Text Editor – the culmination of huge amounts of work by Aviral Dasgupta in his GSoC 2016 project and Luke from the core Matrix team).  For user-focused details about Riot 0.12 you should probably head over to the Riot blog; meanwhile we’ll focus here on widgets from the developer perspective.

Widgets are a deceptively simple idea: the ability to pin small form-factor webapps (called widgets) into a given Matrix room, letting admins build up a dashboard of functionality which is then in common and automatically available to everyone who views that room.  You can think of it as being similar to installing an app onto a smartphone, but instead pulling it into a Matrix conversation.  This could be a Jitsi video conference, or a collaborative document editor, or a Grafana dashboard, or anything you can imagine really (assuming its security headers support embedding).  Here’s an example of a room with an ongoing Jitsi conference coupled with a Grafana graph, as you might use for a devops war room:

The URLs of the widgets are stored in the state of the room with some high-level layout hints, and the idea is that any Matrix client will be able to expose the widgets for the current room to a user.  For a simple command-line client this could just be listing the URLs of the widgets so the user can open them in a browser; for a web client like Riot/Web they’re embedded via iframes; for a native client like Riot/iOS they could be shown via a WebView – or there’s always the chance of the native client recognising the URL being requested and swapping it out for an optimised local native implementation instead.  For now, widgets don’t really have a way of communicating with the host Matrix client (other than by speaking Matrix to the homeserver!), although we’re looking at adding a PostMessage API to improve this.

Now, in an ideal world we would have enough bandwidth to have formally added widgets to the Matrix spec, but unfortunately we are way behind on spec work currently, thanks in part to our current funding problems. (Remember, if you like Matrix, please donate or get your company to donate otherwise we are at real risk of hitting a very big funding wall).  Rather than formal spec, we’ve focused on rushing an initial implementation out the door in matrix-react-sdk (and thus riot-web) to see how they work first in reality.  Riot/iOS and Riot/Android are coming soon – although we’ve special-cased the Jitsi video conferencing widget in iOS to be implemented natively, which is actually available already on develop(!)

Right now the widgets supported by Riot are prefixed behind the im.vector.modular.widgets state event, whose format is something like:

{
	type: "im.vector.modular.widgets",
	state_key: "widget1",
	content: {
		type: "grafana",
		url: "https://matrix.org/grafana/whatever",
		name: "matrix.org bridges dashboard"
	}
	room_id: "!foo:bar.com",
	sender: "@kegan:matrix.org"
}

Currently the only layout hint is that the order of the event determines the order in which the widget should be displayed on the page.  Riot/Web’s initial implementation is very naive and shows only up to two widgets per page, although we’re hoping to make this much more generic and flexible in future.  To add widgets in Riot/Web you can now hit the new widget manager button in the top right – and to show/hide existing ones in the room you can hit the show/hide app drawer button in the bottom right.

The UI for adding widgets to a room in Riot is currently via Modular – the new name for Riot’s SaaS integration hosting platform, formally codenamed Scalar.  This is a separate webapp loaded in an iframe which guides you through choosing widgets to embed which are hosted by Modular, although in the near future we’ll also add UI to let you specify widget URLs directly.  If you need this today, you’ll need to manually inject a state event like the one above into the room to provision the widget.

This is very much the minimum viable implementation of widgets: the stuff left to do includes:

  • Adding them to the spec, and getting clients other than Riot using them!
  • Supporting better layouts (especially to allow for more screen real-estate) and more than 2 widgets
  • Ability to add widgets directly, for situations where Modular isn’t available
  • Speccing APIs for widgets to interact directly with the host client – with the appropriate permissions model
  • Adding lots more prepackaged widgets to the Modular store!

Modular comes with 6 widgets ready to go: Grafana, Jitsi, Etherpad, YouTube, Google Docs and Custom Widget (which lets you add any arbitrary URL into the room). The most exciting of these is probably Jitsi, which provides Hangouts-style video conferencing into any room.  This provides a welcome alternative to our ‘native’ conferencing functionality which sadly got stuck in a permanent early beta – and includes full screensharing as well!  The only catch is that it hasn’t been released on iOS yet, and Android is still be to be implemented – but the experience is a still massive improvement over what we’ve had historically.  Here’s a screenshot of some of the core team doing a 6-way conference with the native Jitsi functionality now included in Riot/iOS!

Finally, if you want to write your own widget, just create a webapp and play with it via the Custom Widget interface.  If it’s something useful for other people then please ping us on #matrix-dev:matrix.org and we’ll see about getting it added as a preset application in Modular.

We think widgets are an awesome example of how Matrix can be used to coordinate collaboration between users in a room – for now it’s just simply ensuring that users are looking at the same set of webapps when in a room, but in future you can see how it could extend to co-browsing, co-editing, payment functionality, or generally using Matrix to coordinate things other than textual/voip chat.  The sky’s the limit, and we’re hoping the Modular store (and other app stores) will start overflowing with apps in the near future!

As always, feedback is very welcome on new experimental stuff like this – so please come tell us what you think in #matrix:matrix.org!  And finally: huge kudos to Rick, Kegan, Rob, and everyone else who have been working away bringing Widgets to life.  It’s the beginning of a new era :D

Matthew