My GSoC Proposal: MTP Collection rewrite with emphasis on Android device support

Matěj Laitl matej at laitl.cz
Thu Apr 25 15:53:16 UTC 2013


Hi all,
this is a first draft of my GSoC project proposal. I'd be more than happy to 
see your comments, remarks, whether something is unclear or maybe where I'm 
too verbose.

P.S. to students waiting for review of a patch or GSoC proposal: I've been 
(pleasurably) busy with real life lately, but don't fear, it is all on my TODO 
list. Fortunately I'm not the only Amarok developer, I expect others to step 
in soonish. (kudos to Edward who started reviewing again - continue!) ;)

	Matěj

--------------------------------------------

Motivation for Proposal

Amarok 2 has supported MTP (Media Transfer Protocol) devices and showed them 
as collections since its initial release in 2008. Unfortunately, the original 
author ceased to maintain the code and because of the complexity of the 
MediaDevice framework that has been introduced and used by the code, its 
maintenance proved difficult for non-authors and bugs started to pile up.[7] In 
late 2011 Google released Android 4.0 Ice Cream Sandwich, the first Android 
version to support only MTP for file transfer.[1] It means that hundreds of 
millions of MTP devices have been sold since then. Amarok needs much more 
solid support for MTP in order to satisfy millions using the new semi-open 
platform with Linux-based desktops.
Project Goals

The goal of this project is to rewrite the MTP support in Amarok from ground-
up using much simpler approach, modern technologies (PortableMediaPlayer 
support in KDE's Solid etc.), threading (to keep the GUI responsive) and best 
C++ coding practices (RAII[2] etc). The result will be a dependable and bug-
free MTP device collection support in Amarok along with transcoding and 
playlists. Another advantage would be the possibility to remove the deprecated 
MediaDevice framework and a lot of support code it depends on.

This project will (re)implement:

    Collections backed by MTP devices, namely:
    Zero-configuration device detection and enumeration, plug & play.
    Enumeration of tracks and playlists on the devices along with their 
metadata.
    Playback of tracks stored on devices with on-demand background loading.
    Ability to transfer tracks out of and to MTP devices, with possibility to 
transcode.
    Full playlist management (for devices that support them).

What Will Not Be Done:

    Support for non-standard devices that significantly drift from the MTP 
Specification[3] (unless libmtp already has quirks for them).

The code will be tested with an Android phone; other MTP devices (many of them 
pre-dating Android) will be equally supported, but their testing will rely on 
crowd-sourcing.

The code will be developed for and tested on Linux (and other Unix-like OSes), 
with possibility of future compatibility with Windows kept in mind (but not 
part of the project itself).
Implementation Details

The rewritten MTP collection will keep to use the libmtp[4] library to do the 
low-level communication with the actual MTP device and to provide abstraction 
of tracks, albums & playlists. On Amarok side, the code will drastically 
change to reimplementation of standard abstract base classes rather than put-
it-all-into-MtpHandler approach; as it is standard for Amarok collection 
implementations it will reside in its own loadable shared library. The classes 
in rough order of involvement are:

MtpCollectionFactory will be a singleton instantiated after module load. It 
will enumerate connected MTP devices using KDE's Solid, it will also listen to 
Solid's signals for newly added devices and setup a MtpCollections for them. 
It will be very similar to UmsCollectionFactory and IPodCollectionFactory and 
will be a candidate for future deduplication.

MtpCollection will be the central part; it will contain pointer to libmtp 
device handle, coordinate track enumeration and implement all virtual 
functions of Collection::Collection. It will use existing MemoryCollection[5] 
utility class to keep track of tracks and other meta entities (albums, 
artists...) and it will use existing MemoryMeta::MapChanger helper class to 
facilitate entity changes, additions and removals. It will also employ present 
MemoryQueryMaker to implement lookups for meta entities.

Meta::MtpTrack will implement the Amarok track interface by wrapping 
LIBMTP_track_t pointer. Minimal MtpAlbum, MtpArtist, etc. classes will be made 
for MemoryMeta framework to use them. It will also cache advanced MTP track 
properties like last played time that are not directly available in the 
LIBMTP_track_t convenience structure. As MTP tracks are not directly playable 
by Phonon, special care will be taken: the prepareToPlay() method will 
initiate background transfer to local temporary file, returning as soon as 
let's say 5% + 200 KB of the file is loaded.

MtpCollectionLocation will implement abstract Collections::CollectionLocation 
class to allow copying tracks to the MTP collection and will support on-the-fly 
transcoding, combining Amarok transcode framework and libmtp functions for 
actual transfer. It will also facilitate copying tracks out of MTP collection 
and their removal. MtpPlaylistProvider will facilitate on-device playlist 
handling.

Attention will be taken not to hamper Amarok responsiveness; because libmtp 
API is blocking and many methods must be assumed to be long-running, all 
libmtp-interfacing code will only be called in non-main thread(s). On the 
other hand, libmtp documentation has no mention of thread-safety, therefore we 
must assume that access to its functions needs to be serialized (per each MTP 
device). MtpCollection will contain a QMutex to facilitate this.

One question may come to attentive reader's mind: why the implementation 
doesn't involve kio-mtp?[6] It is because kio-mtp doesn't use the track libmtp 
API (rather it uses the file API) - with track API we can query metadata like 
sample rate or artist without having to download the file at all. We could 
still use kio-mtp for actual track transfer, but as we already need to talk 
directly to libmtp and have relevant structures set up, actual transfer is 
then so easy that the kio-mtp dependency wouldn't be justifiable (and it would 
cause unnecessary overhead).

Tentative Timeline

Jun 17 - Jun 23 	Work in MtpCollectionFactory - detecting MTP devices as they 
connect & disconnect and their enumeration should be working. Dummy 
MtpCollections are created for plugged-in devices.
Jun 24 - Jun 30 	Work on MtpCollection: basics, track enumeration, threading, 
locking.
Jul 1 - Jul 7 	Introducing MtpTrack class (still rather basic), continued 
work on MtpCollection, especially managing tracks using MemoryCollection.
Jul 8 - Jul 14 	More work on MtpTrack - more metadata are being exposed, 
MtpAlbum, MtpArtist etc are introduced so that the proper structure shows up 
in Collection Browser.
Jul 15 - Jul 21 	Making MTP tracks directly playable in Amarok - loading 
them on demand, implementing threading and serialization involved, temporary 
file management.
Jul 22 - Jul 28 	Making metadata of MTP tracks editable, tweaking caching 
and updating behaviour of advanced metadata fields.
Mid-term Evaluation: MTP collection will show up for connected devices, tracks 
will be shown, playable and their metadata will be editable.
Jul 29 - Aug 4 	Implementing small configuration dialog for MTP collections, 
it will also show device capabilities and potential problems to aid with 
troubleshooting.
Aug 5 - Aug 11 	Implementing MtpCollectionLocation - i.e. transferring tracks 
to/from MTP device.
Aug 12 - Aug 18 	Continued work on MtpCollectionLocation - partially 
customizable folder structure on device, transcoding.
Aug 19 - Aug 25 	Bullet-proofing MtpCollectionLocation: extensive error 
reporting, ability to cope with concurrent requests to upload/download/play 
tracks.
Aug 26 - Sep 1 	Work on supporting playlists by introducing 
MtpPlaylistProvider, ability to show and edit on-device playlists, ability to 
transfer whole playlists to MTP device.
Sep 2 - Sep 8 	Polishing work: ensuring all components work together in the 
best possible way, checking for corner-cases, progress bars for longer 
operations, etc.
Sep 9 - Sep 15 	Bumper week for delays that may arise (need to improve/bugfix 
libmtp, unexpected real-life-introduced delays), else testing with various 
kind of devices; ensuring correct behaviour when the device is suddenly 
disconnected, etc.
Suggested pencils-down
Sep 16 - Sep 22 	Another cushion week for potential problems, else preparing 
the code for inclusion into mainline, proof-reading it, stripping debugging 
statements, submitting a review request, resolving any possible remarks.
Hard pencils-down
Sep 23 - Sep 29 	Festive removal of the MediaDevice framework, provided that 
a related AudioCD GSoC project materializes.
Long-term 	Maintenance of the MTP collection, fixing bugs found by early 
adopters.

Do you have other obligations during the summer?

If accepted, GSoC will be my main commitment during the summer and I'm 
prepared to work on it (and related Amarok tasks) 40 hours a week. My 
university semester ends before the coding period starts and I have just one 
remaining exam to pass. The first week of the coding period partially 
intersects with a sports week by my university (which I plan to participate 
in), but that will be compensated by starting the work even before the coding 
period. I also plan to have an about week-long vacation, but that will be well 
compensated by occasionally working on week-ends. I also plan to attend 
Akademy 2013.

About Me:

I'm a 25-year-old student of mathematical informatics from Prague, Czech 
Republic. I've been passionate about FLOSS since high school and in 2011 I 
started to be more & more a contributor to Gentoo Linux, KDE and mainly Amarok 
rather than a user.[8] In winter 2011/2012 I got motivated by Amarok's Bart 
Cerneels and rewrote the iPod collection from scratch[9] (a task similar to 
this one); the rewrite was released with Amarok 2.6. Thanks to the rewrite, 
iPod Amarok component on KDE Bugzilla now only has a couple of wishes and no 
open bugs. Later in 2012 I was accepted to Google Summer of Code (this is 
therefore my 2nd year applying) to work on Amarok to add Statistics 
synchronization for pluggable devices and Last.fm. After the project was 
successfully finished it was released with Amarok 2.7 and seems to be enjoyed 
my many.[10] I've been also particularly active on KDE's bugzilla[11] and 
reviewboard. I know C, C++, Python, Java, a bit of French (pun intended) and 
some other less relevant languages. Thanks to my work on Amarok I have solid 
experience in GUI and back-end programming in Qt & KDE libs.

I've chosen Amarok because I fell in love with it and Android (MTP) support 
because many of my friends (and me) now have Android devices and I want Amarok 
to rock for them, too. Solid Android support will keep Amarok relevant and one 
of the best FLOSS music players out there.

[1] http://www.androidcentral.com/ics-feature-mtp-what-it-why-use-it-and-how-set-it
[2] Resource Acquisition Is Initialization Pattern
[3] Media Transfer Protocol v1.1 Specs, 
http://www.usb.org/developers/devclass_docs
[4] http://libmtp.sourceforge.net/l
[5] Bad name, doesn't actually implement the Collections::Collection 
interface.
[6] http://www.afiestas.org/workspaces-gain-mtp-support/
[7] http://goo.gl/ZOr7i
[8] https://www.ohloh.net/accounts/strohel
[9] http://strohel.blogspot.com/2012/04/amaroks-rewritten-ipod-plugin-testers.html
[10] http://strohel.blogspot.com/2012/12/amarok-27-beta-to-be-released-soon-try.html
[11] http://goo.gl/afJN3


More information about the Amarok-devel mailing list