Merge lp:~jamesh/thumbnailer/no-fallback-albumart into lp:thumbnailer/devel

Proposed by James Henstridge
Status: Merged
Merged at revision: 343
Proposed branch: lp:~jamesh/thumbnailer/no-fallback-albumart
Merge into: lp:thumbnailer/devel
Diff against target: 606 lines (+152/-134)
19 files modified
data/CMakeLists.txt (+0/-8)
data/thumbnailer.in (+1/-6)
debian/control (+2/-11)
debian/thumbnailer-common.install (+0/-2)
debian/thumbnailer-service.install (+1/-0)
plugins/Ubuntu/Thumbnailer.0.1/albumartgenerator.cpp (+3/-11)
plugins/Ubuntu/Thumbnailer.0.1/artistartgenerator.cpp (+3/-11)
plugins/Ubuntu/Thumbnailer.0.1/thumbnailerimageresponse.cpp (+13/-19)
plugins/Ubuntu/Thumbnailer.0.1/thumbnailerimageresponse.h (+4/-10)
plugins/Ubuntu/Thumbnailer.0.1/thumbnailgenerator.cpp (+2/-29)
tests/image-provider/image-provider_test.cpp (+82/-0)
tests/qml/CMakeLists.txt (+4/-0)
tests/qml/Fixture.qml (+8/-10)
tests/qml/tst_albumart.qml (+13/-14)
tests/qml/tst_photo.qml (+1/-1)
tests/testsetup.h.in (+0/-1)
tests/utils/artserver.cpp (+0/-1)
tests/utils/testutils.cpp (+11/-0)
tests/utils/testutils.h (+4/-0)
To merge this branch: bzr merge lp:~jamesh/thumbnailer/no-fallback-albumart
Reviewer Review Type Date Requested Status
Michi Henning (community) Approve
PS Jenkins bot (community) continuous-integration Approve
James Henstridge Pending
Review via email: mp+263216@code.launchpad.net

This proposal supersedes a proposal from 2014-05-14.

Commit message

When a thumbnail can not be loaded, return an error from the image provider rather than substituting in a fallback image. Users can detect the problem via the status property of the QML Image component and provide their own fallback handling.

Description of the change

Rather than providing a fallback image from the albumart ImageProvider, return a null QImage object. When used with the QML Image component, this sets the status to Image.Error which allows applications to handle the fallback themselves.

This was requested by the music-app guys, but I haven't yet verified behaviour in the dash.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:85
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~jamesh/thumbnailer/no-fallback-albumart/+merge/219460/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/thumbnailer-ci/59/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/thumbnailer-utopic-amd64-ci/1
    SUCCESS: http://jenkins.qa.ubuntu.com/job/thumbnailer-utopic-armhf-ci/1
        deb: http://jenkins.qa.ubuntu.com/job/thumbnailer-utopic-armhf-ci/1/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/thumbnailer-utopic-i386-ci/1

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/thumbnailer-ci/59/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Jussi Pakkanen (jpakkane) wrote : Posted in a previous version of this proposal

Looks good.

review: Approve
Revision history for this message
James Henstridge (jamesh) wrote : Posted in a previous version of this proposal

It looks like this does cause problems for the dash: I get an empty space in the carousel where a song without album art sits.

We'll need some kind of fix for this on the Unity8 side before this can be merged.

review: Needs Fixing
Revision history for this message
James Henstridge (jamesh) wrote : Posted in a previous version of this proposal

I've filed a bug 1324142 on Unity8 about getting it to handle the error state correctly.

Revision history for this message
Jussi Pakkanen (jpakkane) wrote : Posted in a previous version of this proposal

This has lingered for quite a while. What shall we do with this?

89. By James Henstridge

Include the ID in the errors from album/artist art generators.

Revision history for this message
James Henstridge (jamesh) wrote :

This currently segfaults due to bug 1469611 in libQt5Quick.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
90. By James Henstridge

Merge from devel

91. By James Henstridge

Fix up tests for removal of fallback art.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
92. By James Henstridge

Remove fallback images.

93. By James Henstridge

Remove the default image override code from tests.

94. By James Henstridge

Remove the thumbnailer-common binary package:
 * Move the apport blacklist file to thumbnailer-service (only listing
   current architecture now, since it is arch specific).
 * Remove the fallback images entirely, since they are no longer used.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
95. By James Henstridge

Merge from devel, fixing massive conflicts.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michi Henning (michihenning) wrote :

Looks good to me. A few minor quibbles:

In thumbnailerimageresponse.cpp, there is a stale comment in textureFactory().

The test writes to ~/.cache/unity-thumbnailer. It would be good to write to a different cache dir. (Setting XDG_CACHE_HOME for the test should take care of it.)

In Fixture.qml. line 113:

return Qt.rgba(data[pos] / 255, data[pos+1] / 255, data[pos+2] / 255, data[pos+3] / 255);

Might this be behind the failure on big-ending machines?

review: Needs Fixing
96. By James Henstridge

Fix up QML tests.

97. By James Henstridge

Add direct image provider tests for error conditions.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
James Henstridge (jamesh) wrote :

> Looks good to me. A few minor quibbles:
>
> In thumbnailerimageresponse.cpp, there is a stale comment in textureFactory().

Fixed.

>
> The test writes to ~/.cache/unity-thumbnailer. It would be good to write to a
> different cache dir. (Setting XDG_CACHE_HOME for the test should take care of
> it.)

Which test are you referring to?

> In Fixture.qml. line 113:
>
> return Qt.rgba(data[pos] / 255, data[pos+1] / 255, data[pos+2] / 255,
> data[pos+3] / 255);
>
> Might this be behind the failure on big-ending machines?

The data is documented to be in RGBA order, which matches the order of the arguments to Qt.rgba():

http://doc.qt.io/qt-5/qml-qtquick-canvasimagedata.html#data-prop

Even this data was in an endian dependent format, it wouldn't explain why we're reading out black pixels on the problem architectures.

98. By James Henstridge

Remove obsolete comment from textureFactory() method.

99. By James Henstridge

Remove error logging in requestFinished() method.

We now expose the error message via the errorString() method, which Qt
itself will log.

Revision history for this message
Michi Henning (michihenning) wrote :

Oops, it's the QML test that writes to $HOME.

OK, I wasn't sure of this, so endian-ness is not the problem here.

I compiled this on the powerpc porter box, and we are getting 0,0,0,0 back each and every time, so the problem is below the qml level somewhere. I'll have another look tomorrow.

This MR looks fine to me, thanks!

review: Approve
Revision history for this message
James Henstridge (jamesh) wrote :

So, the QML tests are already setting XDG_CACHE_HOME.

I was having some trouble with those tests failing locally while passing in Jenkins, which I think I have solved since you made your original comment. In my environment I had QT_QPA_PLATFORMTHEME=appmenu-qt5, which seemed to be initialising the D-Bus connection prior to me replacing it with libqtdbustest. This meant the test was running against the installed copy of thumbnailer-service.

With the updates in the branch, ctest will blank out this environment variable when running the test, which made those tests pass reliably for me.

Revision history for this message
Michi Henning (michihenning) wrote :

Hmmm... So, when I tried running your test, it was still failing due to the incorrect signal spy. I fixed the offending source line (spy vs statusSpy, from memory), and ran the test again. This time, the test failed with lots of FAILED PREVIOUSLY errors. (I have no thumbnailer installed locally.) When I looked, I found cache files under ~/.cache/unity-thumbnailer. After deleting that directory, I ran the test again, and the FAILED_PREVIOUSLY messages disappeared, but the ~/.cache/unity-thumbnailer directory re-appeared.

It looks like some is indeed creating files under $HOME/.cache. Hmmm... Aargh...

The environment variably problem affects only the client-side, not the server side?

Revision history for this message
Michi Henning (michihenning) wrote :

Ah, no, I take that back. I was looking at the wrong VM. This happened on a VM where I had the thumbnailer installed locally.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
James Henstridge (jamesh) wrote :

Some results from testing:

* Gallery seems to be unaffected (not surprising since it should be able to load all the images/videos camera-app writes).

* music-app shows new fallback art with the change (white music note on orange/purple background).

* My Music scope is a mixed bag.

   * Tracks dept correctly shows the music note fallback

   * Albums dept shows blank square for fallbacks

   * Artists dept shows an Ubuntu logo fallback (not to be confused with the grey silhouette sometimes returned by 7digital).

So the scope might require some additional work before this can be merged. Nothing crashed and burned though, so that's promising.

Revision history for this message
James Henstridge (jamesh) wrote :

Also, we don't seem to be showing fallback images in the my music previews. The results showing fallback images just got a cross in the preview.

Revision history for this message
James Henstridge (jamesh) wrote :

The My Music scope seems to be working with this unity-scope-mediascanner branch applied:

https://code.launchpad.net/~jamesh/unity-scope-mediascanner/fallback-art-fixes/+merge/282396

I'm seeing the fallback images occasionally disappear though, for which I can't determine the cause.

Revision history for this message
Michi Henning (michihenning) wrote :

Disappearing fallback images? How? How can I reproduce?

Seeing that you set the commit message, I take that this is good to go for the time being?

I'm happy with what is there now. I suggest that we merge to devel, but hold off with the silo until after OTA-9. That'll give us time to sort out what's going with the disappearing fallback images, and also give us time for more testing, seeing that lots of other components are affected by this change. (A few hours ago, there were still comments flying past regarding fallback images in the dash, for example.)

If you agree, please top-approve yourself.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/CMakeLists.txt'
--- data/CMakeLists.txt 2015-05-22 03:13:47 +0000
+++ data/CMakeLists.txt 2016-01-12 09:29:54 +0000
@@ -4,14 +4,6 @@
4execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_comple_schemas OUTPUT_STRIP_TRAILING_WHITESPACE)4execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_comple_schemas OUTPUT_STRIP_TRAILING_WHITESPACE)
5execute_process (COMMAND ${_glib_comple_schemas} ${CMAKE_CURRENT_SOURCE_DIR} --targetdir=${CMAKE_CURRENT_BINARY_DIR} OUTPUT_STRIP_TRAILING_WHITESPACE)5execute_process (COMMAND ${_glib_comple_schemas} ${CMAKE_CURRENT_SOURCE_DIR} --targetdir=${CMAKE_CURRENT_BINARY_DIR} OUTPUT_STRIP_TRAILING_WHITESPACE)
66
7install(
8 FILES
9 album_missing.png
10 video_missing.png
11 DESTINATION
12 ${CMAKE_INSTALL_DATADIR}/thumbnailer/icons
13)
14
15configure_file(7configure_file(
16 thumbnailer.in8 thumbnailer.in
17 thumbnailer9 thumbnailer
1810
=== removed file 'data/album_missing.png'
19Binary files data/album_missing.png 2014-09-25 09:47:05 +0000 and data/album_missing.png 1970-01-01 00:00:00 +0000 differ11Binary files data/album_missing.png 2014-09-25 09:47:05 +0000 and data/album_missing.png 1970-01-01 00:00:00 +0000 differ
=== modified file 'data/thumbnailer.in'
--- data/thumbnailer.in 2014-09-26 11:24:27 +0000
+++ data/thumbnailer.in 2016-01-12 09:29:54 +0000
@@ -1,6 +1,1 @@
1@CMAKE_INSTALL_PREFIX@/lib/x86_64-linux-gnu/thumbnailer/vs-thumb1@CMAKE_INSTALL_FULL_LIBDIR@/thumbnailer/vs-thumb
2@CMAKE_INSTALL_PREFIX@/lib/i386-linux-gnu/thumbnailer/vs-thumb
3@CMAKE_INSTALL_PREFIX@/lib/powerpc-linux-gnu/thumbnailer/vs-thumb
4@CMAKE_INSTALL_PREFIX@/lib/powerpc64le-linux-gnu/thumbnailer/vs-thumb
5@CMAKE_INSTALL_PREFIX@/lib/arm-linux-gnueabihf/thumbnailer/vs-thumb
6@CMAKE_INSTALL_PREFIX@/lib/aarch64-linux-gnu/thumbnailer/vs-thumb
72
=== removed file 'data/video_missing.png'
8Binary files data/video_missing.png 2014-09-25 09:47:05 +0000 and data/video_missing.png 1970-01-01 00:00:00 +0000 differ3Binary files data/video_missing.png 2014-09-25 09:47:05 +0000 and data/video_missing.png 1970-01-01 00:00:00 +0000 differ
=== modified file 'debian/control'
--- debian/control 2015-12-21 07:07:46 +0000
+++ debian/control 2016-01-12 09:29:54 +0000
@@ -47,8 +47,8 @@
47Pre-Depends: ${misc:Pre-Depends},47Pre-Depends: ${misc:Pre-Depends},
48Depends: ${misc:Depends},48Depends: ${misc:Depends},
49 ${shlibs:Depends},49 ${shlibs:Depends},
50Conflicts: libthumbnailer050Conflicts: libthumbnailer0, thumbnailer-common
51Replaces: libthumbnailer051Replaces: libthumbnailer0, thumbnailer-common
52Description: D-Bus service for out of process thumbnailing52Description: D-Bus service for out of process thumbnailing
53 This package provides a D-Bus service that can provide thumbnails on53 This package provides a D-Bus service that can provide thumbnails on
54 behalf of another process.54 behalf of another process.
@@ -73,7 +73,6 @@
73Depends: ${misc:Depends},73Depends: ${misc:Depends},
74 ${shlibs:Depends},74 ${shlibs:Depends},
75 libthumbnailer-qt1.0 (= ${binary:Version}),75 libthumbnailer-qt1.0 (= ${binary:Version}),
76 thumbnailer-common (= ${source:Version}),
77Provides: ubuntu-thumbnailer-impl,76Provides: ubuntu-thumbnailer-impl,
78 ubuntu-thumbnailer-impl-0,77 ubuntu-thumbnailer-impl-0,
79Recommends: thumbnailer-service (= ${binary:Version}),78Recommends: thumbnailer-service (= ${binary:Version}),
@@ -83,14 +82,6 @@
83 This package provides image providers that allow access to the82 This package provides image providers that allow access to the
84 thumbnailer from Qt Quick 2 / QML applications.83 thumbnailer from Qt Quick 2 / QML applications.
8584
86Package: thumbnailer-common
87Architecture: all
88Multi-Arch: foreign
89Depends: ${misc:Depends},
90Description: Common files for the thumbnailer service.
91 This package provides common files for the thumbnailer service, such
92 as default icons.
93
94Package: libthumbnailer-qt1.085Package: libthumbnailer-qt1.0
95Architecture: any86Architecture: any
96Multi-Arch: same87Multi-Arch: same
9788
=== removed file 'debian/thumbnailer-common.install'
--- debian/thumbnailer-common.install 2014-09-26 11:24:27 +0000
+++ debian/thumbnailer-common.install 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
1usr/share/thumbnailer/icons/*
2etc/apport/blacklist.d/thumbnailer
30
=== modified file 'debian/thumbnailer-service.install'
--- debian/thumbnailer-service.install 2015-08-06 05:08:47 +0000
+++ debian/thumbnailer-service.install 2016-01-12 09:29:54 +0000
@@ -1,3 +1,4 @@
1etc/apport/blacklist.d/thumbnailer
1usr/bin/thumbnailer-admin2usr/bin/thumbnailer-admin
2usr/lib/*/thumbnailer/thumbnailer-service3usr/lib/*/thumbnailer/thumbnailer-service
3usr/lib/*/thumbnailer/vs-thumb4usr/lib/*/thumbnailer/vs-thumb
45
=== modified file 'plugins/Ubuntu/Thumbnailer.0.1/albumartgenerator.cpp'
--- plugins/Ubuntu/Thumbnailer.0.1/albumartgenerator.cpp 2015-12-09 02:39:32 +0000
+++ plugins/Ubuntu/Thumbnailer.0.1/albumartgenerator.cpp 2016-01-12 09:29:54 +0000
@@ -24,13 +24,6 @@
2424
25#include "thumbnailerimageresponse.h"25#include "thumbnailerimageresponse.h"
2626
27namespace
28{
29
30const char DEFAULT_ALBUM_ART[] = "/usr/share/thumbnailer/icons/album_missing.png";
31
32} // namespace
33
34namespace unity27namespace unity
35{28{
3629
@@ -48,19 +41,18 @@
4841
49QQuickImageResponse* AlbumArtGenerator::requestImageResponse(const QString& id, const QSize& requestedSize)42QQuickImageResponse* AlbumArtGenerator::requestImageResponse(const QString& id, const QSize& requestedSize)
50{43{
51 QSize size = requestedSize;
52 QUrlQuery query(id);44 QUrlQuery query(id);
53 if (!query.hasQueryItem(QStringLiteral("artist")) || !query.hasQueryItem(QStringLiteral("album")))45 if (!query.hasQueryItem(QStringLiteral("artist")) || !query.hasQueryItem(QStringLiteral("album")))
54 {46 {
55 qWarning() << "AlbumArtGenerator::requestImageResponse(): Invalid albumart uri:" << id;47 qWarning() << "AlbumArtGenerator::requestImageResponse(): Invalid albumart uri:" << id;
56 return new ThumbnailerImageResponse(requestedSize, DEFAULT_ALBUM_ART);48 return new ThumbnailerImageResponse("Invalid albumart ID: " + id);
57 }49 }
5850
59 const QString artist = query.queryItemValue(QStringLiteral("artist"), QUrl::FullyDecoded);51 const QString artist = query.queryItemValue(QStringLiteral("artist"), QUrl::FullyDecoded);
60 const QString album = query.queryItemValue(QStringLiteral("album"), QUrl::FullyDecoded);52 const QString album = query.queryItemValue(QStringLiteral("album"), QUrl::FullyDecoded);
6153
62 auto request = thumbnailer->getAlbumArt(artist, album, size);54 auto request = thumbnailer->getAlbumArt(artist, album, requestedSize);
63 return new ThumbnailerImageResponse(size, DEFAULT_ALBUM_ART, request);55 return new ThumbnailerImageResponse(request);
64}56}
6557
66} // namespace qml58} // namespace qml
6759
=== modified file 'plugins/Ubuntu/Thumbnailer.0.1/artistartgenerator.cpp'
--- plugins/Ubuntu/Thumbnailer.0.1/artistartgenerator.cpp 2015-11-04 07:16:12 +0000
+++ plugins/Ubuntu/Thumbnailer.0.1/artistartgenerator.cpp 2016-01-12 09:29:54 +0000
@@ -25,13 +25,6 @@
2525
26#include "thumbnailerimageresponse.h"26#include "thumbnailerimageresponse.h"
2727
28namespace
29{
30
31const char DEFAULT_ARTIST_ART[] = "/usr/share/thumbnailer/icons/album_missing.png";
32
33} // namespace
34
35namespace unity28namespace unity
36{29{
3730
@@ -49,19 +42,18 @@
4942
50QQuickImageResponse* ArtistArtGenerator::requestImageResponse(const QString& id, const QSize& requestedSize)43QQuickImageResponse* ArtistArtGenerator::requestImageResponse(const QString& id, const QSize& requestedSize)
51{44{
52 QSize size = requestedSize;
53 QUrlQuery query(id);45 QUrlQuery query(id);
54 if (!query.hasQueryItem(QStringLiteral("artist")) || !query.hasQueryItem(QStringLiteral("album")))46 if (!query.hasQueryItem(QStringLiteral("artist")) || !query.hasQueryItem(QStringLiteral("album")))
55 {47 {
56 qWarning() << "ArtistArtGenerator::requestImageResponse(): Invalid artistart uri:" << id;48 qWarning() << "ArtistArtGenerator::requestImageResponse(): Invalid artistart uri:" << id;
57 return new ThumbnailerImageResponse(requestedSize, DEFAULT_ARTIST_ART);49 return new ThumbnailerImageResponse("Invalid artistart ID: " + id);
58 }50 }
5951
60 const QString artist = query.queryItemValue(QStringLiteral("artist"), QUrl::FullyDecoded);52 const QString artist = query.queryItemValue(QStringLiteral("artist"), QUrl::FullyDecoded);
61 const QString album = query.queryItemValue(QStringLiteral("album"), QUrl::FullyDecoded);53 const QString album = query.queryItemValue(QStringLiteral("album"), QUrl::FullyDecoded);
6254
63 auto request = thumbnailer->getArtistArt(artist, album, size);55 auto request = thumbnailer->getArtistArt(artist, album, requestedSize);
64 return new ThumbnailerImageResponse(size, DEFAULT_ARTIST_ART, request);56 return new ThumbnailerImageResponse(request);
65}57}
6658
67} // namespace qml59} // namespace qml
6860
=== modified file 'plugins/Ubuntu/Thumbnailer.0.1/thumbnailerimageresponse.cpp'
--- plugins/Ubuntu/Thumbnailer.0.1/thumbnailerimageresponse.cpp 2015-12-17 00:25:10 +0000
+++ plugins/Ubuntu/Thumbnailer.0.1/thumbnailerimageresponse.cpp 2016-01-12 09:29:54 +0000
@@ -31,21 +31,15 @@
31namespace qml31namespace qml
32{32{
3333
34ThumbnailerImageResponse::ThumbnailerImageResponse(QSize const& requested_size,34ThumbnailerImageResponse::ThumbnailerImageResponse(QSharedPointer<thumb_qt::Request> const& request)
35 QString const& default_image,35 : request_(request)
36 QSharedPointer<thumb_qt::Request> const& request)
37 : requested_size_(requested_size)
38 , request_(request)
39 , default_image_(default_image)
40{36{
41 Q_ASSERT(request);37 Q_ASSERT(request);
42 connect(request_.data(), &thumb_qt::Request::finished, this, &ThumbnailerImageResponse::requestFinished);38 connect(request_.data(), &thumb_qt::Request::finished, this, &ThumbnailerImageResponse::requestFinished);
43}39}
4440
45ThumbnailerImageResponse::ThumbnailerImageResponse(QSize const& requested_size,41ThumbnailerImageResponse::ThumbnailerImageResponse(QString const& error_message)
46 QString const& default_image)42 : error_message_(error_message)
47 : requested_size_(requested_size)
48 , default_image_(default_image)
49{43{
50 // Queue the signal emission so there is time for the caller to connect.44 // Queue the signal emission so there is time for the caller to connect.
51 QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);45 QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
@@ -58,22 +52,22 @@
5852
59QQuickTextureFactory* ThumbnailerImageResponse::textureFactory() const53QQuickTextureFactory* ThumbnailerImageResponse::textureFactory() const
60{54{
61 // TODO: Once we remove fallback image support, this test for request_ != nullptr
62 // (here and elsewhere) needs to be removed because request_ is nullptr
63 // only if the default image constructor above was called.
64 if (request_ && request_->isValid())55 if (request_ && request_->isValid())
65 {56 {
66 return QQuickTextureFactory::textureFactoryForImage(request_->image());57 return QQuickTextureFactory::textureFactoryForImage(request_->image());
67 }58 }
68 else59 else
69 {60 {
70 char const* env_default = getenv("THUMBNAILER_TEST_DEFAULT_IMAGE");61 qWarning() << "ThumbnailerImageResponse::textureFactory(): method called without valid request.";
71 QImage aux;62 return nullptr;
72 aux.load(env_default ? QString(env_default) : default_image_);
73 return QQuickTextureFactory::textureFactoryForImage(aux);
74 }63 }
75}64}
7665
66QString ThumbnailerImageResponse::errorString() const
67{
68 return error_message_;
69}
70
77void ThumbnailerImageResponse::cancel()71void ThumbnailerImageResponse::cancel()
78{72{
79 if (request_ && !request_->isFinished() && !request_->isCancelled())73 if (request_ && !request_->isFinished() && !request_->isCancelled())
@@ -84,9 +78,9 @@
8478
85void ThumbnailerImageResponse::requestFinished()79void ThumbnailerImageResponse::requestFinished()
86{80{
87 if (!request_->isValid() && !request_->isCancelled())81 if (!request_->isValid())
88 {82 {
89 qWarning() << "ThumbnailerImageResponse::dbusCallFinished(): D-Bus error: " << request_->errorMessage();83 error_message_ = request_->errorMessage();
90 }84 }
91 Q_EMIT finished();85 Q_EMIT finished();
92}86}
9387
=== modified file 'plugins/Ubuntu/Thumbnailer.0.1/thumbnailerimageresponse.h'
--- plugins/Ubuntu/Thumbnailer.0.1/thumbnailerimageresponse.h 2015-09-30 10:08:20 +0000
+++ plugins/Ubuntu/Thumbnailer.0.1/thumbnailerimageresponse.h 2016-01-12 09:29:54 +0000
@@ -20,8 +20,6 @@
2020
21#include <QQuickImageProvider>21#include <QQuickImageProvider>
2222
23#include <memory>
24
25#include <unity/thumbnailer/qt/thumbnailer-qt.h>23#include <unity/thumbnailer/qt/thumbnailer-qt.h>
2624
27namespace unity25namespace unity
@@ -46,24 +44,20 @@
46public:44public:
47 Q_DISABLE_COPY(ThumbnailerImageResponse)45 Q_DISABLE_COPY(ThumbnailerImageResponse)
4846
49 ThumbnailerImageResponse(QSize const& requested_size,47 ThumbnailerImageResponse(QSharedPointer<unity::thumbnailer::qt::Request> const& request);
50 QString const& default_image,48 ThumbnailerImageResponse(QString const& error_message);
51 QSharedPointer<unity::thumbnailer::qt::Request> const& request);
52 ThumbnailerImageResponse(QSize const& requested_size,
53 QString const& default_image);
54 ~ThumbnailerImageResponse();49 ~ThumbnailerImageResponse();
5550
56 QQuickTextureFactory* textureFactory() const override;51 QQuickTextureFactory* textureFactory() const override;
52 QString errorString() const override;
57 void cancel() override;53 void cancel() override;
5854
59private Q_SLOTS:55private Q_SLOTS:
60 void requestFinished();56 void requestFinished();
6157
62private:58private:
63 QString id_;
64 QSize requested_size_;
65 QSharedPointer<unity::thumbnailer::qt::Request> request_;59 QSharedPointer<unity::thumbnailer::qt::Request> request_;
66 QString default_image_;60 QString error_message_;
67};61};
6862
69} // namespace qml63} // namespace qml
7064
=== modified file 'plugins/Ubuntu/Thumbnailer.0.1/thumbnailgenerator.cpp'
--- plugins/Ubuntu/Thumbnailer.0.1/thumbnailgenerator.cpp 2015-11-04 07:16:12 +0000
+++ plugins/Ubuntu/Thumbnailer.0.1/thumbnailgenerator.cpp 2016-01-12 09:29:54 +0000
@@ -19,36 +19,11 @@
19#include "thumbnailgenerator.h"19#include "thumbnailgenerator.h"
2020
21#include <QDebug>21#include <QDebug>
22#include <QMimeDatabase>
23#include <QUrl>22#include <QUrl>
2423
25#include <settings.h>24#include <settings.h>
26#include "thumbnailerimageresponse.h"25#include "thumbnailerimageresponse.h"
2726
28namespace
29{
30
31const char* DEFAULT_VIDEO_ART = "/usr/share/thumbnailer/icons/video_missing.png";
32const char* DEFAULT_ALBUM_ART = "/usr/share/thumbnailer/icons/album_missing.png";
33
34QString default_image_based_on_mime(QString const &id)
35{
36 QMimeDatabase db;
37 QMimeType mime = db.mimeTypeForFile(id);
38
39 if (mime.name().contains(QStringLiteral("audio")))
40 {
41 return DEFAULT_ALBUM_ART;
42 }
43 else if (mime.name().contains(QStringLiteral("video")))
44 {
45 return DEFAULT_VIDEO_ART; // LCOV_EXCL_LINE // Being lazy here: default art is about to go away.
46 }
47 return DEFAULT_ALBUM_ART;
48}
49
50} // namespace
51
52namespace unity27namespace unity
53{28{
5429
@@ -66,8 +41,6 @@
6641
67QQuickImageResponse* ThumbnailGenerator::requestImageResponse(const QString& id, const QSize& requestedSize)42QQuickImageResponse* ThumbnailGenerator::requestImageResponse(const QString& id, const QSize& requestedSize)
68{43{
69 QSize size = requestedSize;
70
71 /* Allow appending a query string (e.g. ?something=timestamp)44 /* Allow appending a query string (e.g. ?something=timestamp)
72 * to the id and then ignore it.45 * to the id and then ignore it.
73 * This is workaround to force reloading a thumbnail when it has46 * This is workaround to force reloading a thumbnail when it has
@@ -79,8 +52,8 @@
79 * is the only way around the issue for now. */52 * is the only way around the issue for now. */
80 QString src_path = QUrl(id).path();53 QString src_path = QUrl(id).path();
8154
82 auto request = thumbnailer->getThumbnail(src_path, size);55 auto request = thumbnailer->getThumbnail(src_path, requestedSize);
83 return new ThumbnailerImageResponse(size, default_image_based_on_mime(id), request);56 return new ThumbnailerImageResponse(request);
84}57}
8558
86} // namespace qml59} // namespace qml
8760
=== modified file 'tests/image-provider/image-provider_test.cpp'
--- tests/image-provider/image-provider_test.cpp 2015-12-23 03:04:01 +0000
+++ tests/image-provider/image-provider_test.cpp 2016-01-12 09:29:54 +0000
@@ -99,6 +99,7 @@
99 ASSERT_EQ("", response->errorString());99 ASSERT_EQ("", response->errorString());
100100
101 unique_ptr<QQuickTextureFactory> factory(response->textureFactory());101 unique_ptr<QQuickTextureFactory> factory(response->textureFactory());
102 ASSERT_NE(nullptr, factory.get());
102 QImage image = factory->image();103 QImage image = factory->image();
103104
104 EXPECT_EQ(128, image.width());105 EXPECT_EQ(128, image.width());
@@ -118,6 +119,87 @@
118 provider.requestImageResponse(filename, QSize(128, 128)));119 provider.requestImageResponse(filename, QSize(128, 128)));
119 response->cancel();120 response->cancel();
120 wait(response.get());121 wait(response.get());
122 EXPECT_EQ("Request cancelled", response->errorString());
123}
124
125TEST_F(ProviderTest, thumbnail_missing)
126{
127 const char* filename = TESTDATADIR "/no-such-file.jpg";
128
129 ThumbnailGenerator provider(thumbnailer_);
130 unique_ptr<QQuickImageResponse> response(
131 provider.requestImageResponse(filename, QSize(128, 128)));
132 wait(response.get());
133 string error = response->errorString().toStdString();
134 EXPECT_NE(string::npos, error.find("No such file or directory")) << error;
135}
136
137TEST_F(ProviderTest, albumart)
138{
139 const char* id = "artist=metallica&album=load";
140
141 AlbumArtGenerator provider(thumbnailer_);
142 unique_ptr<QQuickImageResponse> response(
143 provider.requestImageResponse(id, QSize(128, 128)));
144 wait(response.get());
145 EXPECT_EQ("", response->errorString());
146
147 unique_ptr<QQuickTextureFactory> factory(response->textureFactory());
148 ASSERT_NE(nullptr, factory.get());
149 QImage image = factory->image();
150
151 EXPECT_EQ(48, image.width());
152 EXPECT_EQ(48, image.height());
153 EXPECT_EQ(QColor("#C80000").rgb(), image.pixel(0, 0));
154 EXPECT_EQ(QColor("#00D200").rgb(), image.pixel(47, 0));
155 EXPECT_EQ(QColor("#0000DC").rgb(), image.pixel(0, 47));
156 EXPECT_EQ(QColor("#646E78").rgb(), image.pixel(47, 47));
157}
158
159TEST_F(ProviderTest, albumart_missing)
160{
161 const char* id = "artist=no-such-artist&album=no-such-album";
162
163 AlbumArtGenerator provider(thumbnailer_);
164 unique_ptr<QQuickImageResponse> response(
165 provider.requestImageResponse(id, QSize(128, 128)));
166 wait(response.get());
167 string error = response->errorString().toStdString();
168 EXPECT_NE(string::npos, error.find("could not get thumbnail for album")) << error;
169}
170
171TEST_F(ProviderTest, artistart)
172{
173 const char* id = "artist=beck&album=odelay";
174
175 ArtistArtGenerator provider(thumbnailer_);
176 unique_ptr<QQuickImageResponse> response(
177 provider.requestImageResponse(id, QSize(128, 128)));
178 wait(response.get());
179 EXPECT_EQ("", response->errorString());
180
181 unique_ptr<QQuickTextureFactory> factory(response->textureFactory());
182 ASSERT_NE(nullptr, factory.get());
183 QImage image = factory->image();
184
185 EXPECT_EQ(128, image.width());
186 EXPECT_EQ(96, image.height());
187 EXPECT_EQ(QColor("#FE0000").rgb(), image.pixel(0, 0));
188 EXPECT_EQ(QColor("#FFFF00").rgb(), image.pixel(127, 0));
189 EXPECT_EQ(QColor("#0000FE").rgb(), image.pixel(0, 95));
190 EXPECT_EQ(QColor("#00FF01").rgb(), image.pixel(127, 95));
191}
192
193TEST_F(ProviderTest, artistart_missing)
194{
195 const char* id = "artist=no-such-artist&album=no-such-album";
196
197 ArtistArtGenerator provider(thumbnailer_);
198 unique_ptr<QQuickImageResponse> response(
199 provider.requestImageResponse(id, QSize(128, 128)));
200 wait(response.get());
201 string error = response->errorString().toStdString();
202 EXPECT_NE(string::npos, error.find("could not get thumbnail for artist")) << error;
121}203}
122204
123int main(int argc, char **argv)205int main(int argc, char **argv)
124206
=== modified file 'tests/qml/CMakeLists.txt'
--- tests/qml/CMakeLists.txt 2015-12-18 02:09:49 +0000
+++ tests/qml/CMakeLists.txt 2016-01-12 09:29:54 +0000
@@ -9,3 +9,7 @@
9)9)
10add_dependencies(qml_test thumbnailer-service thumbnailer-qml)10add_dependencies(qml_test thumbnailer-service thumbnailer-qml)
11add_test(qml ${CMAKE_SOURCE_DIR}/tools/run-xvfb.sh ./qml_test -import ${CMAKE_BINARY_DIR}/plugins)11add_test(qml ${CMAKE_SOURCE_DIR}/tools/run-xvfb.sh ./qml_test -import ${CMAKE_BINARY_DIR}/plugins)
12# Clear some environment variables that can interfere with the tests
13set_tests_properties(qml PROPERTIES
14 ENVIRONMENT "DBUS_SESSION_BUS_ADDRESS=;QT_QPA_PLATFORMTHEME="
15)
1216
=== modified file 'tests/qml/Fixture.qml'
--- tests/qml/Fixture.qml 2015-12-12 00:25:57 +0000
+++ tests/qml/Fixture.qml 2016-01-12 09:29:54 +0000
@@ -69,16 +69,6 @@
69 encodeURIComponent(album));69 encodeURIComponent(album));
70 }70 }
7171
72 function loadBadAlbumUrl(artist) {
73 load("image://albumart/artist=" +
74 encodeURIComponent(artist));
75 }
76
77 function loadBadArtistUrl(album) {
78 load("image://artistart/album=" +
79 encodeURIComponent(album));
80 }
81
82 function load(url) {72 function load(url) {
83 // Have the image component load the image73 // Have the image component load the image
84 image.source = url;74 image.source = url;
@@ -109,6 +99,14 @@
109 imageData = canvas.context.createImageData(dumpfile);99 imageData = canvas.context.createImageData(dumpfile);
110 }100 }
111101
102 function expectLoadError(url) {
103 image.source = url;
104 while (image.status === Image.Loading) {
105 statusSpy.wait();
106 }
107 compare(image.status, Image.Error);
108 }
109
112 function pixel(x, y) {110 function pixel(x, y) {
113 var pos = (imageData.width * y + x) * 4;111 var pos = (imageData.width * y + x) * 4;
114 var data = imageData.data;112 var data = imageData.data;
115113
=== modified file 'tests/qml/tst_albumart.qml'
--- tests/qml/tst_albumart.qml 2015-12-09 02:32:38 +0000
+++ tests/qml/tst_albumart.qml 2016-01-12 09:29:54 +0000
@@ -22,22 +22,21 @@
22 }22 }
2323
24 function test_artistart_not_found() {24 function test_artistart_not_found() {
25 loadArtistArt("beck2", "odelay")25 expectLoadError("image://artistart/artist=beck2&album=odelay");
26 compare(size.width, 96);
27 compare(size.height, 96);
28 }26 }
2927
30 function test_albumart_not_found() {28 function test_albumart_not_found() {
31 loadAlbumArt("beck2", "odelay")29 expectLoadError("image://albumart/artist=beck2&album=odelay");
32 compare(size.width, 96);30 }
33 compare(size.height, 96);31
34 }32 function test_missing_parameter() {
3533 expectLoadError("image://albumart/");
36 function test_bad_artist_art_url() {34 expectLoadError("image://albumart/foo");
37 loadBadArtistUrl("load")35 expectLoadError("image://albumart/artist=X");
38 }36 expectLoadError("image://albumart/album=Y");
3937 expectLoadError("image://artistart/");
40 function test_bad_album_art_url() {38 expectLoadError("image://artistart/foo");
41 loadBadAlbumUrl("metallica")39 expectLoadError("image://artistart/artist=X");
40 expectLoadError("image://artistart/album=Y");
42 }41 }
43}42}
4443
=== modified file 'tests/qml/tst_photo.qml'
--- tests/qml/tst_photo.qml 2015-12-12 00:25:57 +0000
+++ tests/qml/tst_photo.qml 2016-01-12 09:29:54 +0000
@@ -54,6 +54,6 @@
54 }54 }
5555
56 function test_no_such_photo() {56 function test_no_such_photo() {
57 loadThumbnail("no_such_photo.jpg");57 expectLoadError("image://thumbnailer/file:///no_such_photo.jpg");
58 }58 }
59}59}
6060
=== modified file 'tests/testsetup.h.in'
--- tests/testsetup.h.in 2015-10-14 03:57:29 +0000
+++ tests/testsetup.h.in 2016-01-12 09:29:54 +0000
@@ -29,6 +29,5 @@
2929
30#define THUMBNAILER_SERVICE "@CMAKE_BINARY_DIR@/src/service/thumbnailer-service"30#define THUMBNAILER_SERVICE "@CMAKE_BINARY_DIR@/src/service/thumbnailer-service"
31#define FAKE_ART_SERVER "@CMAKE_CURRENT_SOURCE_DIR@/server/server.py"31#define FAKE_ART_SERVER "@CMAKE_CURRENT_SOURCE_DIR@/server/server.py"
32#define THUMBNAILER_TEST_DEFAULT_IMAGE "@CMAKE_SOURCE_DIR@/data/album_missing.png"
3332
34#define THUMBNAILER_ADMIN "@CMAKE_BINARY_DIR@/src/thumbnailer-admin/thumbnailer-admin"33#define THUMBNAILER_ADMIN "@CMAKE_BINARY_DIR@/src/thumbnailer-admin/thumbnailer-admin"
3534
=== modified file 'tests/utils/artserver.cpp'
--- tests/utils/artserver.cpp 2015-12-12 02:06:41 +0000
+++ tests/utils/artserver.cpp 2016-01-12 09:29:54 +0000
@@ -69,7 +69,6 @@
69 }69 }
70 blocked_server_url_ = "http://127.0.0.1:" + std::to_string(addr.sin_port);70 blocked_server_url_ = "http://127.0.0.1:" + std::to_string(addr.sin_port);
7171
72 setenv("THUMBNAILER_TEST_DEFAULT_IMAGE", THUMBNAILER_TEST_DEFAULT_IMAGE, true);
73 update_env();72 update_env();
74}73}
7574
7675
=== modified file 'tests/utils/testutils.cpp'
--- tests/utils/testutils.cpp 2015-12-14 01:27:29 +0000
+++ tests/utils/testutils.cpp 2016-01-12 09:29:54 +0000
@@ -19,6 +19,7 @@
19#include "testutils.h"19#include "testutils.h"
2020
21#include <QString>21#include <QString>
22#include <ostream>
2223
23using namespace std;24using namespace std;
2425
@@ -26,3 +27,13 @@
26{27{
27 return stream << s.toUtf8().constData();28 return stream << s.toUtf8().constData();
28}29}
30
31ostream& operator<<(ostream& stream, const char* s)
32{
33 return std::operator<<(stream, s);
34}
35
36void PrintTo(const QString& s, ostream* stream)
37{
38 *stream << s;
39}
2940
=== modified file 'tests/utils/testutils.h'
--- tests/utils/testutils.h 2015-12-14 01:27:29 +0000
+++ tests/utils/testutils.h 2016-01-12 09:29:54 +0000
@@ -24,3 +24,7 @@
2424
25// Helper for gtest to allow us to insert QString into a stream.25// Helper for gtest to allow us to insert QString into a stream.
26std::ostream& operator<<(std::ostream& stream, const QString& s);26std::ostream& operator<<(std::ostream& stream, const QString& s);
27// Needed because the QString version will take precedence over the std:: one
28std::ostream& operator<<(std::ostream& stream, const char* s);
29
30void PrintTo(const QString& s, std::ostream* stream);

Subscribers

People subscribed via source and target branches

to all changes: