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