Merge lp:~phablet-team/media-hub/add-logger into lp:media-hub

Proposed by Jim Hodapp
Status: Superseded
Proposed branch: lp:~phablet-team/media-hub/add-logger
Merge into: lp:media-hub
Diff against target: 2780 lines (+819/-331)
32 files modified
CMakeLists.txt (+1/-1)
debian/bileto_pre_release_hook (+21/-52)
debian/control (+6/-6)
debian/control.in (+1/-0)
debian/get-versions.sh (+5/-3)
debian/rules (+1/-1)
include/core/media/player.h (+23/-0)
src/core/media/CMakeLists.txt (+9/-0)
src/core/media/apparmor/ubuntu.cpp (+7/-6)
src/core/media/audio/pulse_audio_output_observer.cpp (+10/-8)
src/core/media/gstreamer/engine.cpp (+30/-29)
src/core/media/gstreamer/playbin.cpp (+39/-46)
src/core/media/logger/logger.cpp (+161/-0)
src/core/media/logger/logger.h (+131/-0)
src/core/media/non_copyable.h (+36/-0)
src/core/media/player_implementation.cpp (+39/-38)
src/core/media/player_skeleton.cpp (+6/-4)
src/core/media/player_stub.cpp (+10/-6)
src/core/media/power/state_controller.cpp (+13/-13)
src/core/media/server/server.cpp (+34/-0)
src/core/media/service.cpp (+3/-1)
src/core/media/service_implementation.cpp (+27/-26)
src/core/media/service_skeleton.cpp (+20/-19)
src/core/media/telephony/CMakeLists.txt (+1/-0)
src/core/media/telephony/call_monitor.cpp (+9/-7)
src/core/media/telephony/qtbridge.cpp (+0/-2)
src/core/media/track_list_implementation.cpp (+25/-23)
src/core/media/track_list_skeleton.cpp (+31/-32)
src/core/media/track_list_stub.cpp (+9/-7)
src/core/media/util/utils.cpp (+41/-0)
src/core/media/util/utils.h (+69/-0)
src/core/media/video/platform_default_sink.cpp (+1/-1)
To merge this branch: bzr merge lp:~phablet-team/media-hub/add-logger
Reviewer Review Type Date Requested Status
Alfonso Sanchez-Beato Approve
Konrad Zapałowicz (community) code Approve
Review via email: mp+291010@code.launchpad.net

This proposal has been superseded by a proposal from 2016-04-06.

Commit message

Add a proper logger to media-hub that includes traces, timestamps and other conveniences and no longer rely on cout/cerr.

Description of the change

Add a proper logger to media-hub that includes traces, timestamps and other conveniences and no longer rely on cout/cerr.

To post a comment you must log in.
Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

Not many issues compared to the length of the diff and frankly I'm mostly concerned about the own noncopyable class.

There is also one thing which is not bad however I would like to highlight it. I did not like the need to create stringstream in so many cases to log a line as basically this is repeating.

review: Needs Fixing (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

I have some concerns with this MP:

* I do not really like moving to the printf way of doing things. Why should be drop type safeness? It would be better to use the boost logger more "natively" with "<<" operators, changing the wrapper class to something similar to what Qt does (qDebug() << message, etc.). Even more, using printf way in the end we need to resort to using stringstream in several places where it was not needed before.

* I still see cout and cerr being used in many places. But please do not change that yet until we have an agreement on how the class Logger should be used.

* I do not think we should introduce functions in the Utils namespace that we do not use. Specially taking into account that I would prefer to avoid using the only one that seems to be used, Sprintf :)

* Line sizes in new files are > 100 in many cases

There are also a couple of inline comments.

review: Needs Fixing
Revision history for this message
Jim Hodapp (jhodapp) wrote :

> Not many issues compared to the length of the diff and frankly I'm mostly
> concerned about the own noncopyable class.

I am using this same logger which comes from aethercast. It relies on it's own noncopyable class, so just maintaing consistency. Really, this logger should be brought into a standard library for everyone to use, but that's out of the scope of this story.

>
> There is also one thing which is not bad however I would like to highlight it.
> I did not like the need to create stringstream in so many cases to log a line
> as basically this is repeating.

Revision history for this message
Jim Hodapp (jhodapp) wrote :

> I have some concerns with this MP:
>
> * I do not really like moving to the printf way of doing things. Why should be
> drop type safeness? It would be better to use the boost logger more "natively"
> with "<<" operators, changing the wrapper class to something similar to what
> Qt does (qDebug() << message, etc.). Even more, using printf way in the end we
> need to resort to using stringstream in several places where it was not needed
> before.

Boost still maintains complete type safety with using the printf style. See the Boost::Log docs about this if you have any questions. This private Boost::Log interface implementation comes from tvoss and we're starting to standardize on it. Not sure why it doesn't use streams but that's outside anything I can really control without rewriting the private logger interface.

>
> * I still see cout and cerr being used in many places. But please do not
> change that yet until we have an agreement on how the class Logger should be
> used.

There are some that will need to remain, but otherwise I've made sure that all superfluous ones have now been removed.

>
> * I do not think we should introduce functions in the Utils namespace that we
> do not use. Specially taking into account that I would prefer to avoid using
> the only one that seems to be used, Sprintf :)

Fixed

>
> * Line sizes in new files are > 100 in many cases

I tried not to do that, any specific ones?

>
> There are also a couple of inline comments.

Revision history for this message
Jim Hodapp (jhodapp) wrote :

Replied/addressed inline comments.

Revision history for this message
Konrad Zapałowicz (kzapalowicz) wrote :

Thanks for fixes & explanations, ack.

review: Approve (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Thanks for the changes. LGTM, although I do not agree with how the Logger is designed. As discussed, we need to rethink it and come back to this when we do so.

review: Approve
194. By Jim Hodapp

Merged with prereq to get this to build in a silo until silo 51 lands

195. By Jim Hodapp

Make sure everything is licensed under LGPL v3

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-12-16 16:55:51 +0000
3+++ CMakeLists.txt 2016-04-06 19:07:29 +0000
4@@ -43,7 +43,7 @@
5 include(GNUInstallDirs)
6
7 find_package(PkgConfig)
8-find_package(Boost COMPONENTS filesystem system program_options REQUIRED)
9+find_package(Boost COMPONENTS filesystem log system thread program_options REQUIRED)
10 find_package(GLog)
11 pkg_check_modules(DBUS dbus-1 REQUIRED)
12 pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED)
13
14=== renamed file 'debian/gen-debian-files.sh' => 'debian/bileto_pre_release_hook'
15--- debian/gen-debian-files.sh 2015-11-22 21:01:02 +0000
16+++ debian/bileto_pre_release_hook 2016-04-06 19:07:29 +0000
17@@ -16,6 +16,7 @@
18 #
19 # Authored by: Michi Henning <michi.henning@canonical.com>
20 # Thomas Voß <thomas.voss@canonical.com>
21+# Robert Bruce Park <robert.park@canonical.com>
22
23 #
24 # Script to generate debian files for dual landing in Vivid (gcc 4.9 ABI)
25@@ -24,79 +25,47 @@
26 # This script is called from debian/rules and generates:
27 #
28 # - control
29-# - libtrust-store${soversion}.install.${target_arch}
30-#
31-# For all but control, this is a straight substition and/or renaming exercise for each file.
32-# For control, if building on Wily or later, we also fix the "Replaces:" and "Conflicts:"
33-# entries, so we don't end up with two packages claiming ownership of the same places
34-# in the file system.
35+# - libmedia-hub-client${MEDIA_HUB_SOVERSION}.install
36+# - libmedia-hub-common${MEDIA_HUB_SOVERSION}.install
37 #
38 # Because the debian files for the different distributions are generated on the fly,
39-# this allows us to keep a single source tree for both distributions. See ../HACKING
40-# for more explanations.
41+# this allows us to keep a single source tree for both distributions.
42 #
43
44 set -e # Fail if any command fails.
45
46 progname=$(basename $0)
47
48-[ $# -ne 1 ] && {
49- echo "usage: $progname path-to-debian-dir" >&2
50+[ $# -gt 1 ] && {
51+ echo "usage: $progname [path-to-debian-dir]" >&2
52 exit 1
53 }
54+version_dir=$(mktemp -d)
55 dir=$1
56-version_dir=$(mktemp -d)
57+
58+[ -n "$dir" ] || dir="./debian"
59
60 # Dump version numbers into files and initialize vars from those files.
61-
62 sh ${dir}/get-versions.sh ${dir} ${version_dir}
63
64-full_version=$(cat "${version_dir}"/libmedia-hub.full-version)
65-major_minor=$(cat "${version_dir}"/libmedia-hub.major-minor-version)
66-soversion=$(cat "${version_dir}"/libmedia-hub.soversion)
67-vivid_soversion=$(cat "${version_dir}"/libmedia-hub.vivid-soversion)
68-
69-warning=$(mktemp -t gen-debian-files-msg.XXX)
70-
71-trap "rm -fr $warning $version_dir" 0 INT TERM QUIT
72-
73-warning_msg()
74+export MEDIA_HUB_SOVERSION=$(cat "$version_dir/libmedia-hub.soversion")
75+
76+trap "rm -fr $version_dir" 0 INT TERM QUIT
77+
78+process()
79 {
80- cat >$warning <<EOF
81+ cat <<EOF
82 # This file is autogenerated. DO NOT EDIT!
83 #
84 # Modifications should be made to $(basename "$1") instead.
85 # This file is regenerated automatically in the clean target.
86 #
87 EOF
88-}
89-
90-# Generate debian/control from debian/control.in, substituting the soversion for both libs.
91-# For wily onwards, we also add an entry for the vivid versions to "Conflicts:" and "Replaces:".
92-
93-infile="${dir}"/control.in
94-outfile="${dir}"/control
95-warning_msg $infile
96-cat $warning $infile \
97- | sed -e "s/@MEDIA_HUB_SOVERSION@/${soversion}/" > "$outfile"
98-
99-[ "$distro" != "vivid" ] && {
100- sed -i -e "/Replaces: libdbus-cpp4,/a\
101-\ libdbus-cpp${vivid_soversion}," \
102- "$outfile"
103-}
104-
105-# Generate the install files, naming them according to the soversion.
106-
107-# Install file for binary package
108-infile="${dir}"/libmedia-hub-client.install.in
109-outfile="${dir}"/libmedia-hub-client${soversion}.install
110-warning_msg "$infile"
111-cat $warning "$infile" >"$outfile"
112-
113-infile="${dir}"/libmedia-hub-common.install.in
114-outfile="${dir}"/libmedia-hub-common${soversion}.install
115-warning_msg "$infile"
116-cat $warning "$infile" >"$outfile"
117+ perl -pe 's/@([A-Z_]+)@/$ENV{$1} or die "$1 undefined"/eg' <"$1"
118+}
119+
120+process "$dir/control.in" >"$dir/control"
121+process "$dir/libmedia-hub-client.install.in" >"$dir/libmedia-hub-client${MEDIA_HUB_SOVERSION}.install"
122+process "$dir/libmedia-hub-common.install.in" >"$dir/libmedia-hub-common${MEDIA_HUB_SOVERSION}.install"
123
124 exit 0
125
126=== modified file 'debian/control'
127--- debian/control 2016-03-04 18:17:11 +0000
128+++ debian/control 2016-04-06 19:07:29 +0000
129@@ -20,9 +20,9 @@
130 libboost-program-options-dev (>=1.53),
131 libboost-system-dev (>=1.53),
132 libdbus-1-dev,
133- libdbus-cpp-dev (>= 5.0.0),
134+ libdbus-cpp-dev (>= 4.3.0),
135 libgoogle-glog-dev,
136- libhybris-dev,
137+ libhybris-dev (>=0.1.0+git20131207+e452e83-0ubuntu30),
138 libprocess-cpp-dev,
139 libproperties-cpp-dev,
140 libgstreamer1.0-dev,
141@@ -42,8 +42,8 @@
142 Section: libdevel
143 Architecture: any
144 Multi-Arch: same
145-Depends: libmedia-hub-common4 (= ${binary:Version}),
146- libmedia-hub-client4 (= ${binary:Version}),
147+Depends: libmedia-hub-common5 (= ${binary:Version}),
148+ libmedia-hub-client5 (= ${binary:Version}),
149 ${misc:Depends},
150 libproperties-cpp-dev,
151 Suggests: libmedia-hub-doc
152@@ -64,7 +64,7 @@
153 .
154 This package contains the runtime.
155
156-Package: libmedia-hub-common4
157+Package: libmedia-hub-common5
158 Architecture: any
159 Multi-Arch: same
160 Depends: ${misc:Depends},
161@@ -75,7 +75,7 @@
162 .
163 This package contains the common libraries.
164
165-Package: libmedia-hub-client4
166+Package: libmedia-hub-client5
167 Architecture: any
168 Multi-Arch: same
169 Depends: ${misc:Depends},
170
171=== modified file 'debian/control.in'
172--- debian/control.in 2015-11-22 21:01:02 +0000
173+++ debian/control.in 2016-04-06 19:07:29 +0000
174@@ -12,6 +12,7 @@
175 gstreamer1.0-plugins-good,
176 libboost-dev (>=1.53),
177 libboost-filesystem-dev (>=1.53),
178+ libboost-log-dev (>=1.53),
179 libboost-program-options-dev (>=1.53),
180 libboost-system-dev (>=1.53),
181 libdbus-1-dev,
182
183=== modified file 'debian/get-versions.sh'
184--- debian/get-versions.sh 2015-11-22 21:01:02 +0000
185+++ debian/get-versions.sh 2016-04-06 19:07:29 +0000
186@@ -38,7 +38,7 @@
187 # Write the various version numbers into a bunch of files. This allows
188 # us to easily pick them up from both gen-debian-files.sh and CMakeLists.txt.
189
190-distro=$(lsb_release -c -s)
191+[ -n "$SERIES" ] || SERIES="$(lsb_release -c -s)"
192
193 full_version=$(cat "${dir}"/VERSION)
194
195@@ -51,13 +51,15 @@
196 vivid_major=$(echo $vivid_full_version | cut -d'.' -f1)
197 vivid_soversion=$vivid_major
198
199-if [ "$distro" = "vivid" ]
200+if [ "$SERIES" = "vivid" ]
201 then
202 soversion=${vivid_soversion}
203 else
204 soversion="${major}"
205 fi
206-[ -n $soversion ]
207+[ -n "$soversion" ]
208+
209+echo "Using SOVERSION $soversion in $SERIES." >&2
210
211 echo ${full_version} >${output_dir}/libmedia-hub.full-version
212 echo ${major} >${output_dir}/libmedia-hub.major-version
213
214=== modified file 'debian/rules'
215--- debian/rules 2015-11-22 21:01:02 +0000
216+++ debian/rules 2016-04-06 19:07:29 +0000
217@@ -34,5 +34,5 @@
218 dh_installdeb
219
220 override_dh_auto_clean:
221- /bin/sh $(CURDIR)/debian/gen-debian-files.sh $(CURDIR)/debian
222+ /bin/sh $(CURDIR)/debian/bileto_pre_release_hook
223 dh_auto_clean
224
225=== modified file 'include/core/media/player.h'
226--- include/core/media/player.h 2016-02-19 16:14:42 +0000
227+++ include/core/media/player.h 2016-04-06 19:07:29 +0000
228@@ -229,6 +229,29 @@
229 return out;
230 }
231
232+inline std::ostream& operator<<(std::ostream& out, Player::Error e)
233+{
234+ switch (e)
235+ {
236+ case Player::Error::no_error:
237+ return out << "Error::no_error";
238+ case Player::Error::resource_error:
239+ return out << "Error::resource_error";
240+ case Player::Error::format_error:
241+ return out << "Error::format_error";
242+ case Player::Error::network_error:
243+ return out << "Error::network_error";
244+ case Player::Error::access_denied_error:
245+ return out << "Error::access_denied_error";
246+ case Player::Error::service_missing_error:
247+ return out << "Error::service_missing_error";
248+ default:
249+ return out << "Unsupported Player error: " << e;
250+ }
251+
252+ return out;
253+}
254+
255 }
256 }
257 }
258
259=== modified file 'src/core/media/CMakeLists.txt'
260--- src/core/media/CMakeLists.txt 2015-09-04 18:46:08 +0000
261+++ src/core/media/CMakeLists.txt 2016-04-06 19:07:29 +0000
262@@ -18,6 +18,7 @@
263 media-hub-common SHARED
264
265 the_session_bus.cpp
266+ util/utils.cpp
267 )
268
269 target_link_libraries(
270@@ -42,6 +43,8 @@
271
272 ${MEDIA_HUB_HEADERS}
273
274+ logger/logger.cpp
275+
276 player.cpp
277 service.cpp
278 track.cpp
279@@ -70,6 +73,8 @@
280
281 media-hub-common
282
283+ ${Boost_LDFLAGS}
284+ ${Boost_LIBRARIES}
285 ${DBUS_LIBRARIES}
286 ${DBUS_CPP_LDFLAGS}
287 ${GLog_LIBRARY}
288@@ -87,6 +92,8 @@
289 ${MEDIA_HUB_HEADERS}
290 ${MPRIS_HEADERS}
291
292+ logger/logger.cpp
293+
294 client_death_observer.cpp
295 hashed_keyed_player_store.cpp
296 hybris_client_death_observer.cpp
297@@ -123,6 +130,8 @@
298 media-hub-client
299 media-hub-common
300 call-monitor
301+ ${Boost_LDFLAGS}
302+ ${Boost_LIBRARIES}
303 ${DBUS_LIBRARIES}
304 ${DBUS_CPP_LDFLAGS}
305 ${GLog_LIBRARY}
306
307=== modified file 'src/core/media/apparmor/ubuntu.cpp'
308--- src/core/media/apparmor/ubuntu.cpp 2016-02-23 14:17:04 +0000
309+++ src/core/media/apparmor/ubuntu.cpp 2016-04-06 19:07:29 +0000
310@@ -20,7 +20,8 @@
311
312 #include <core/media/external_services.h>
313
314-#include <iostream>
315+#include "core/media/logger/logger.h"
316+
317 #include <regex>
318
319 namespace apparmor = core::ubuntu::media::apparmor;
320@@ -107,9 +108,9 @@
321 unity_{name == unity_name},
322 has_package_name_{process_context_name(str(), match_, pkg_name_)}
323 {
324- std::cout << "apparmor profile name: " << name;
325- std::cout << ", is_unconfined(): " << is_unconfined();
326- std::cout << ", has_package_name(): " << has_package_name() << std::endl;
327+ MH_DEBUG("apparmor profile name: %s", name);
328+ MH_DEBUG("is_unconfined(): %s", (is_unconfined() ? "true" : "false"));
329+ MH_DEBUG("has_package_name(): %s", (has_package_name() ? "true" : "false"));
330 if (not is_unconfined() and not is_unity() and not has_package_name())
331 throw std::logic_error
332 {
333@@ -163,8 +164,8 @@
334
335 Uri parsed_uri = parse_uri(uri);
336
337- std::cout << "context.profile_name(): " << context.profile_name() << std::endl;
338- std::cout << "parsed_uri.path: " << parsed_uri.path << std::endl;
339+ MH_DEBUG("context.profile_name(): %s", context.profile_name());
340+ MH_DEBUG("parsed_uri.path: %s", parsed_uri.path);
341
342 // All confined apps can access their own files
343 if (parsed_uri.path.find(std::string(".local/share/" + context.package_name() + "/")) != std::string::npos ||
344
345=== modified file 'src/core/media/audio/pulse_audio_output_observer.cpp'
346--- src/core/media/audio/pulse_audio_output_observer.cpp 2015-03-19 00:04:12 +0000
347+++ src/core/media/audio/pulse_audio_output_observer.cpp 2016-04-06 19:07:29 +0000
348@@ -21,6 +21,8 @@
349
350 #include <pulse/pulseaudio.h>
351
352+#include "core/media/logger/logger.h"
353+
354 #include <cstdint>
355
356 #include <map>
357@@ -245,7 +247,7 @@
358 std::get<1>(outputs.back()) | properties.external_output_state;
359 std::get<1>(outputs.back()).changed().connect([](media::audio::OutputState state)
360 {
361- std::cout << "Connection state for port changed to: " << state << std::endl;
362+ MH_DEBUG("Connection state for port changed to: %s", state);
363 });
364 }
365
366@@ -289,8 +291,8 @@
367 void on_sink_event_with_index(std::int32_t index)
368 {
369 config.reporter->sink_event_with_index(index);
370-
371- // Update server info (active sink)
372+
373+ // Update server info (active sink)
374 pa::get_server_info_async(context, main_loop, Private::query_for_server_info_finished, this);
375
376 }
377@@ -317,15 +319,15 @@
378 if (std::get<0>(active_sink) != info->index)
379 continue;
380
381- std::cout << "Checking if port is available " << " -> " << std::boolalpha << pa::is_port_available_on_sink(info, std::get<0>(element)) << std::endl;
382- bool available = pa::is_port_available_on_sink(info, std::get<0>(element));
383-
384+ MH_INFO("Checking if port is available -> %s",
385+ pa::is_port_available_on_sink(info, std::get<0>(element)));
386+ const bool available = pa::is_port_available_on_sink(info, std::get<0>(element));
387 if (available)
388 {
389 std::get<1>(element) = audio::OutputState::Earpiece;
390 continue;
391 }
392-
393+
394 audio::OutputState state;
395 if (info->index == primary_sink_index)
396 state = audio::OutputState::Speaker;
397@@ -386,7 +388,7 @@
398 }
399 }
400
401- PulseAudioOutputObserver::Configuration config;
402+ PulseAudioOutputObserver::Configuration config;
403 pa::ThreadedMainLoopPtr main_loop;
404 pa::ContextPtr context;
405 std::int32_t primary_sink_index;
406
407=== modified file 'src/core/media/gstreamer/engine.cpp'
408--- src/core/media/gstreamer/engine.cpp 2016-02-19 16:14:42 +0000
409+++ src/core/media/gstreamer/engine.cpp 2016-04-06 19:07:29 +0000
410@@ -25,6 +25,8 @@
411 #include "meta_data_extractor.h"
412 #include "playbin.h"
413
414+#include "core/media/logger/logger.h"
415+
416 #include <cassert>
417
418 namespace media = core::ubuntu::media;
419@@ -67,8 +69,8 @@
420 {
421 if (p.second == "playbin")
422 {
423- std::cout << "State changed on playbin: "
424- << gst_element_state_get_name(p.first.new_state) << std::endl;
425+ MH_INFO("State changed on playbin: %s",
426+ gst_element_state_get_name(p.first.new_state));
427 const auto status = gst_state_to_player_status(p.first);
428 /*
429 * When state moves to "paused" the pipeline is already set. We check that we
430@@ -76,7 +78,7 @@
431 */
432 if (status == media::Player::PlaybackStatus::paused &&
433 !playbin.can_play_streams()) {
434- std::cerr << "** Cannot play: some codecs are missing" << std::endl;
435+ MH_ERROR("** Cannot play: some codecs are missing");
436 playbin.reset();
437 const media::Player::Error e = media::Player::Error::format_error;
438 error(e);
439@@ -96,20 +98,20 @@
440 switch (ewi.error->code)
441 {
442 case GST_CORE_ERROR_FAILED:
443- std::cerr << "** Encountered a GST_CORE_ERROR_FAILED" << std::endl;
444+ MH_ERROR("** Encountered a GST_CORE_ERROR_FAILED");
445 ret_error = media::Player::Error::resource_error;
446 break;
447 case GST_CORE_ERROR_NEGOTIATION:
448- std::cerr << "** Encountered a GST_CORE_ERROR_NEGOTIATION" << std::endl;
449+ MH_ERROR("** Encountered a GST_CORE_ERROR_NEGOTIATION");
450 ret_error = media::Player::Error::resource_error;
451 break;
452 case GST_CORE_ERROR_MISSING_PLUGIN:
453- std::cerr << "** Encountered a GST_CORE_ERROR_MISSING_PLUGIN" << std::endl;
454+ MH_ERROR("** Encountered a GST_CORE_ERROR_MISSING_PLUGIN");
455 ret_error = media::Player::Error::format_error;
456 break;
457 default:
458- std::cerr << "** Encountered an unhandled core error: '"
459- << ewi.debug << "' (code: " << ewi.error->code << ")" << std::endl;
460+ MH_ERROR("** Encountered an unhandled core error: '%s' (code: %d)",
461+ ewi.debug, ewi.error->code);
462 ret_error = media::Player::Error::no_error;
463 break;
464 }
465@@ -119,36 +121,36 @@
466 switch (ewi.error->code)
467 {
468 case GST_RESOURCE_ERROR_FAILED:
469- std::cerr << "** Encountered a GST_RESOURCE_ERROR_FAILED" << std::endl;
470+ MH_ERROR("** Encountered a GST_RESOURCE_ERROR_FAILED");
471 ret_error = media::Player::Error::resource_error;
472 break;
473 case GST_RESOURCE_ERROR_NOT_FOUND:
474- std::cerr << "** Encountered a GST_RESOURCE_ERROR_NOT_FOUND" << std::endl;
475+ MH_ERROR("** Encountered a GST_RESOURCE_ERROR_NOT_FOUND");
476 ret_error = media::Player::Error::resource_error;
477 break;
478 case GST_RESOURCE_ERROR_OPEN_READ:
479- std::cerr << "** Encountered a GST_RESOURCE_ERROR_OPEN_READ" << std::endl;
480+ MH_ERROR("** Encountered a GST_RESOURCE_ERROR_OPEN_READ");
481 ret_error = media::Player::Error::resource_error;
482 break;
483 case GST_RESOURCE_ERROR_OPEN_WRITE:
484- std::cerr << "** Encountered a GST_RESOURCE_ERROR_OPEN_WRITE" << std::endl;
485+ MH_ERROR("** Encountered a GST_RESOURCE_ERROR_OPEN_WRITE");
486 ret_error = media::Player::Error::resource_error;
487 break;
488 case GST_RESOURCE_ERROR_READ:
489- std::cerr << "** Encountered a GST_RESOURCE_ERROR_READ" << std::endl;
490+ MH_ERROR("** Encountered a GST_RESOURCE_ERROR_READ");
491 ret_error = media::Player::Error::resource_error;
492 break;
493 case GST_RESOURCE_ERROR_WRITE:
494- std::cerr << "** Encountered a GST_RESOURCE_ERROR_WRITE" << std::endl;
495+ MH_ERROR("** Encountered a GST_RESOURCE_ERROR_WRITE");
496 ret_error = media::Player::Error::resource_error;
497 break;
498 case GST_RESOURCE_ERROR_NOT_AUTHORIZED:
499- std::cerr << "** Encountered a GST_RESOURCE_ERROR_NOT_AUTHORIZED" << std::endl;
500+ MH_ERROR("** Encountered a GST_RESOURCE_ERROR_NOT_AUTHORIZED");
501 ret_error = media::Player::Error::access_denied_error;
502 break;
503 default:
504- std::cerr << "** Encountered an unhandled resource error: '"
505- << ewi.debug << "' (code: " << ewi.error->code << ")" << std::endl;
506+ MH_ERROR("** Encountered an unhandled resource error: '%s' (code: %d)",
507+ ewi.debug, ewi.error->code);
508 ret_error = media::Player::Error::no_error;
509 break;
510 }
511@@ -158,28 +160,28 @@
512 switch (ewi.error->code)
513 {
514 case GST_STREAM_ERROR_FAILED:
515- std::cerr << "** Encountered a GST_STREAM_ERROR_FAILED" << std::endl;
516+ MH_ERROR("** Encountered a GST_STREAM_ERROR_FAILED");
517 ret_error = media::Player::Error::resource_error;
518 break;
519 case GST_STREAM_ERROR_CODEC_NOT_FOUND:
520- std::cerr << "** Encountered a GST_STREAM_ERROR_CODEC_NOT_FOUND" << std::endl;
521+ MH_ERROR("** Encountered a GST_STREAM_ERROR_CODEC_NOT_FOUND");
522 // Missing codecs are handled later, when state switches to "paused"
523 ret_error = media::Player::Error::no_error;
524 break;
525 case GST_STREAM_ERROR_DECODE:
526- std::cerr << "** Encountered a GST_STREAM_ERROR_DECODE" << std::endl;
527+ MH_ERROR("** Encountered a GST_STREAM_ERROR_DECODE");
528 ret_error = media::Player::Error::format_error;
529 break;
530 default:
531- std::cerr << "** Encountered an unhandled stream error: '"
532- << ewi.debug << "' (code: " << ewi.error->code << ")" << std::endl;
533+ MH_ERROR("** Encountered an unhandled stream error: '%s' code(%d)",
534+ ewi.debug, ewi.error->code);
535 ret_error = media::Player::Error::no_error;
536 break;
537 }
538 }
539
540 if (ret_error != media::Player::Error::no_error) {
541- std::cerr << "Resetting playbin pipeline after unrecoverable error" << std::endl;
542+ MH_ERROR("Resetting playbin pipeline after unrecoverable error");
543 playbin.reset();
544 }
545 return ret_error;
546@@ -201,7 +203,7 @@
547
548 void on_playbin_info(const gstreamer::Bus::Message::Detail::ErrorWarningInfo& ewi)
549 {
550- std::cerr << "Got a playbin info message (no action taken): " << ewi.debug << std::endl;
551+ MH_DEBUG("Got a playbin info message (no action taken): %s", ewi.debug);
552 }
553
554 void on_tag_available(const gstreamer::Bus::Message::Detail::Tag& tag)
555@@ -437,8 +439,7 @@
556 if (result)
557 {
558 d->state = media::Engine::State::playing;
559- cout << __PRETTY_FUNCTION__ << endl;
560- cout << "Engine: playing uri: " << d->playbin.uri() << endl;
561+ MH_INFO("Engine: playing uri: %s", d->playbin.uri());
562 d->playback_status_changed(media::Player::PlaybackStatus::playing);
563 }
564
565@@ -450,7 +451,7 @@
566 // No need to wait, and we can immediately return.
567 if (d->state == media::Engine::State::stopped)
568 {
569- std::cerr << "Current player state is already stopped - no need to change state to stopped" << std::endl;
570+ MH_DEBUG("Current player state is already stopped - no need to change state to stopped");
571 return true;
572 }
573
574@@ -458,7 +459,7 @@
575 if (result)
576 {
577 d->state = media::Engine::State::stopped;
578- cout << __PRETTY_FUNCTION__ << endl;
579+ MH_TRACE("");
580 d->playback_status_changed(media::Player::PlaybackStatus::stopped);
581 }
582
583@@ -472,7 +473,7 @@
584 if (result)
585 {
586 d->state = media::Engine::State::paused;
587- cout << __PRETTY_FUNCTION__ << endl;
588+ MH_TRACE("");
589 d->playback_status_changed(media::Player::PlaybackStatus::paused);
590 }
591
592
593=== modified file 'src/core/media/gstreamer/playbin.cpp'
594--- src/core/media/gstreamer/playbin.cpp 2016-03-07 21:05:26 +0000
595+++ src/core/media/gstreamer/playbin.cpp 2016-04-06 19:07:29 +0000
596@@ -25,7 +25,8 @@
597 #include <hybris/media/surface_texture_client_hybris.h>
598 #include <hybris/media/media_codec_layer.h>
599
600-#include "../util/uri_check.h"
601+#include "core/media/logger/logger.h"
602+#include "core/media/util/uri_check.h"
603
604 #include <utility>
605
606@@ -154,13 +155,13 @@
607 {
608 using namespace std;
609
610- cout << func << endl;
611+ MH_DEBUG("%s", func);
612 if (pb.pipeline)
613- cout << "pipeline: " << GST_OBJECT_REFCOUNT(pb.pipeline) << endl;
614+ MH_DEBUG("pipeline: %d", GST_OBJECT_REFCOUNT(pb.pipeline));
615 if (pb.video_sink)
616- cout << "video_sink: " << GST_OBJECT_REFCOUNT(pb.video_sink) << endl;
617+ MH_DEBUG("video_sink: %d", GST_OBJECT_REFCOUNT(pb.video_sink));
618 if (pb.audio_sink)
619- cout << "audio_sink: " << GST_OBJECT_REFCOUNT(pb.audio_sink) << endl;
620+ MH_DEBUG("audio_sink: %d", GST_OBJECT_REFCOUNT(pb.audio_sink));
621 }
622 #endif
623
624@@ -183,7 +184,7 @@
625
626 void gstreamer::Playbin::reset()
627 {
628- std::cout << "Client died, resetting pipeline" << std::endl;
629+ MH_INFO("Client died, resetting pipeline");
630 // When the client dies, tear down the current pipeline and get it
631 // in a state that is ready for the next client that connects to the
632 // service
633@@ -198,19 +199,19 @@
634
635 void gstreamer::Playbin::reset_pipeline()
636 {
637- std::cout << __PRETTY_FUNCTION__ << std::endl;
638- auto ret = gst_element_set_state(pipeline, GST_STATE_NULL);
639- switch(ret)
640+ MH_TRACE("");
641+ const auto ret = gst_element_set_state(pipeline, GST_STATE_NULL);
642+ switch (ret)
643 {
644 case GST_STATE_CHANGE_FAILURE:
645- std::cout << "Failed to reset the pipeline state. Client reconnect may not function properly." << std::endl;
646+ MH_WARNING("Failed to reset the pipeline state. Client reconnect may not function properly.");
647 break;
648 case GST_STATE_CHANGE_NO_PREROLL:
649 case GST_STATE_CHANGE_SUCCESS:
650 case GST_STATE_CHANGE_ASYNC:
651 break;
652 default:
653- std::cout << "Failed to reset the pipeline state. Client reconnect may not function properly." << std::endl;
654+ MH_WARNING("Failed to reset the pipeline state. Client reconnect may not function properly.");
655 }
656 file_type = MEDIA_FILE_TYPE_NONE;
657 is_missing_audio_codec = false;
658@@ -225,7 +226,7 @@
659 return;
660
661 gchar *desc = gst_missing_plugin_message_get_description(message);
662- std::cerr << "Missing plugin: " << desc << std::endl;
663+ MH_WARNING("Missing plugin: %s", desc);
664 g_free(desc);
665
666 const GstStructure *msg_data = gst_message_get_structure(message);
667@@ -234,13 +235,13 @@
668
669 GstCaps *caps;
670 if (!gst_structure_get(msg_data, "detail", GST_TYPE_CAPS, &caps, NULL)) {
671- std::cerr << __PRETTY_FUNCTION__ << ": No detail" << std::endl;
672+ MH_ERROR("No detail");
673 return;
674 }
675
676 GstStructure *caps_data = gst_caps_get_structure(caps, 0);
677 if (!caps_data) {
678- std::cerr << __PRETTY_FUNCTION__ << ": No caps data" << std::endl;
679+ MH_ERROR("No caps data");
680 return;
681 }
682
683@@ -250,7 +251,7 @@
684 else if (strstr(mime, "video"))
685 is_missing_video_codec = true;
686
687- std::cerr << "Missing decoder for " << mime << std::endl;
688+ MH_ERROR("Missing decoder for %s", mime);
689 }
690
691 void gstreamer::Playbin::on_new_message_async(const Bus::Message& message)
692@@ -324,7 +325,7 @@
693 ::getenv("CORE_UBUNTU_MEDIA_SERVICE_AUDIO_SINK_NAME"),
694 "audio-sink");
695
696- std::cout << "audio_sink: " << ::getenv("CORE_UBUNTU_MEDIA_SERVICE_AUDIO_SINK_NAME") << std::endl;
697+ MH_INFO("audio_sink: %s", ::getenv("CORE_UBUNTU_MEDIA_SERVICE_AUDIO_SINK_NAME"));
698
699 g_object_set (
700 pipeline,
701@@ -339,7 +340,7 @@
702 ::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME"),
703 "video-sink");
704
705- std::cout << "video_sink: " << ::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME") << std::endl;
706+ MH_INFO("video_sink: %s", ::getenv("CORE_UBUNTU_MEDIA_SERVICE_VIDEO_SINK_NAME"));
707
708 g_object_set (
709 pipeline,
710@@ -404,16 +405,17 @@
711 /** Sets the new audio stream role on the pulsesink in playbin */
712 void gstreamer::Playbin::set_audio_stream_role(media::Player::AudioStreamRole new_audio_role)
713 {
714- std::string role_str("props,media.role=" + get_audio_role_str(new_audio_role));
715- std::cout << "Audio stream role: " << role_str << std::endl;
716+ const std::string role_str("props,media.role=" + get_audio_role_str(new_audio_role));
717+ MH_INFO("Audio stream role: %s", role_str);
718
719 GstStructure *props = gst_structure_from_string (role_str.c_str(), NULL);
720- if (audio_sink != nullptr && props != nullptr) {
721+ if (audio_sink != nullptr && props != nullptr)
722+ {
723 g_object_set (audio_sink, "stream-properties", props, NULL);
724- } else {
725- std::cerr <<
726- "Warning: couldn't set audio stream role - couldn't get audio_sink from pipeline" <<
727- std::endl;
728+ }
729+ else
730+ {
731+ MH_WARNING("Couldn't set audio stream role - couldn't get audio_sink from pipeline");
732 }
733
734 gst_structure_free (props);
735@@ -475,9 +477,7 @@
736 {
737 // First decode the URI just in case it's partially encoded already
738 tmp_uri = decode_uri(uri);
739-#ifdef VERBOSE_DEBUG
740- std::cout << "File URI was encoded, now decoded: " << tmp_uri << std::endl;
741-#endif
742+ MH_DEBUG("File URI was encoded, now decoded: %s", tmp_uri);
743 }
744 tmp_uri = encode_uri(tmp_uri);
745 }
746@@ -538,7 +538,7 @@
747
748 auto ret = gst_element_set_state(pipeline, new_state);
749
750- std::cout << __PRETTY_FUNCTION__ << ": requested state change." << std::endl;
751+ MH_DEBUG("Requested state change.");
752
753 bool result = false; GstState current, pending;
754 switch(ret)
755@@ -570,15 +570,15 @@
756 }
757 catch (const std::exception& e)
758 {
759- std::cerr << "Problem querying video dimensions: " << e.what() << std::endl;
760+ MH_WARNING("Problem querying video dimensions: %s", e.what());
761 }
762 catch (...)
763 {
764- std::cerr << "Problem querying video dimensions." << std::endl;
765+ MH_WARNING("Problem querying video dimensions.");
766 }
767
768 #ifdef DEBUG_GST_PIPELINE
769- std::cout << "Dumping pipeline dot file" << std::endl;
770+ MH_DEBUG("Dumping pipeline dot file");
771 GST_DEBUG_BIN_TO_DOT_FILE((GstBin*)pipeline, GST_DEBUG_GRAPH_SHOW_ALL, "pipeline");
772 #endif
773 }
774@@ -656,17 +656,13 @@
775 // We have a URI and it is already percent encoded
776 if (uri_scheme and strlen(uri_scheme) > 0 and uri_check->is_encoded())
777 {
778-#ifdef VERBOSE_DEBUG
779- std::cout << "Is a URI and is already percent encoded" << std::endl;
780-#endif
781+ MH_DEBUG("Is a URI and is already percent encoded");
782 encoded_uri = uri;
783 }
784 // We have a URI but it's not already percent encoded
785 else if (uri_scheme and strlen(uri_scheme) > 0 and !uri_check->is_encoded())
786 {
787-#ifdef VERBOSE_DEBUG
788- std::cout << "Is a URI and is not already percent encoded" << std::endl;
789-#endif
790+ MH_DEBUG("Is a URI and is not already percent encoded");
791 gchar *encoded = g_uri_escape_string(uri.c_str(),
792 "!$&'()*+,;=:/?[]@", // reserved chars
793 TRUE); // Allow UTF-8 chars
794@@ -681,9 +677,7 @@
795 else // We have a path and not a URI. Turn it into a full URI and encode it
796 {
797 GError *error = nullptr;
798-#ifdef VERBOSE_DEBUG
799- std::cout << "Is a path and is not already percent encoded" << std::endl;
800-#endif
801+ MH_DEBUG("Is a path and is not already percent encoded");
802 gchar *str = g_filename_to_uri(uri.c_str(), nullptr, &error);
803 if (!str)
804 {
805@@ -694,8 +688,7 @@
806 g_free(str);
807 if (error != nullptr)
808 {
809- std::cerr << "Warning: failed to get actual track content type: " << error->message
810- << std::endl;
811+ MH_WARNING("Failed to get actual track content type: %s", error->message);
812 g_error_free(error);
813 g_free(str);
814 g_free(uri_scheme);
815@@ -742,11 +735,11 @@
816 const std::string content_type {file_info_from_uri(encoded_uri)};
817 if (content_type.empty())
818 {
819- std::cerr << "Warning: failed to get actual track content type" << std::endl;
820+ MH_WARNING("Failed to get actual track content type");
821 return std::string("audio/video/");
822 }
823
824- std::cout << "Found content type: " << content_type << std::endl;
825+ MH_INFO("Found content type: %s", content_type);
826
827 return content_type;
828 }
829@@ -758,7 +751,7 @@
830
831 if (get_file_content_type(uri).find("audio/") == 0)
832 {
833- std::cout << "Found audio content" << std::endl;
834+ MH_INFO("Found audio content");
835 return true;
836 }
837
838@@ -772,7 +765,7 @@
839
840 if (get_file_content_type(uri).find("video/") == 0)
841 {
842- std::cout << "Found video content" << std::endl;
843+ MH_INFO("Found video content");
844 return true;
845 }
846
847
848=== added directory 'src/core/media/logger'
849=== added file 'src/core/media/logger/logger.cpp'
850--- src/core/media/logger/logger.cpp 1970-01-01 00:00:00 +0000
851+++ src/core/media/logger/logger.cpp 2016-04-06 19:07:29 +0000
852@@ -0,0 +1,161 @@
853+/*
854+ * Copyright (C) 2015 Canonical, Ltd.
855+ *
856+ * This program is free software: you can redistribute it and/or modify it
857+ * under the terms of the GNU General Public License version 3, as published
858+ * by the Free Software Foundation.
859+ *
860+ * This program is distributed in the hope that it will be useful, but
861+ * WITHOUT ANY WARRANTY; without even the implied warranties of
862+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
863+ * PURPOSE. See the GNU General Public License for more details.
864+ *
865+ * You should have received a copy of the GNU General Public License along
866+ * with this program. If not, see <http://www.gnu.org/licenses/>.
867+ *
868+ */
869+
870+#include <thread>
871+
872+#include "logger.h"
873+
874+#define BOOST_LOG_DYN_LINK
875+#include <boost/date_time.hpp>
876+#include <boost/filesystem.hpp>
877+#include <boost/log/trivial.hpp>
878+#include <boost/log/expressions.hpp>
879+#include <boost/log/support/date_time.hpp>
880+#include <boost/log/utility/manipulators.hpp>
881+#include <boost/log/utility/setup.hpp>
882+
883+namespace media = core::ubuntu::media;
884+
885+namespace {
886+namespace attrs {
887+BOOST_LOG_ATTRIBUTE_KEYWORD(Severity, "core::ubuntu::media::Severity", media::Logger::Severity)
888+BOOST_LOG_ATTRIBUTE_KEYWORD(Location, "Location", media::Logger::Location)
889+BOOST_LOG_ATTRIBUTE_KEYWORD(Timestamp, "Timestamp", boost::posix_time::ptime)
890+}
891+
892+struct BoostLogLogger : public media::Logger {
893+ BoostLogLogger() :
894+ initialized_(false) {
895+ }
896+
897+ void Init(const media::Logger::Severity &severity = media::Logger::Severity::kWarning) override {
898+ if (initialized_)
899+ return;
900+
901+ boost::log::formatter formatter = boost::log::expressions::stream
902+ << "[" << attrs::Severity << " "
903+ << boost::log::expressions::format_date_time< boost::posix_time::ptime >("Timestamp", "%Y-%m-%d %H:%M:%S.%f")
904+ << "] "
905+ << boost::log::expressions::if_(boost::log::expressions::has_attr(attrs::Location))
906+ [
907+ boost::log::expressions::stream << "[" << attrs::Location << "] "
908+ ]
909+ << boost::log::expressions::smessage;
910+
911+ boost::log::core::get()->remove_all_sinks();
912+ auto logger = boost::log::add_console_log(std::cout);
913+ logger->set_formatter(formatter);
914+
915+ // FIXME need to enable this once we found how we wrap this
916+ // properly into our service architecture. For now left as
917+ // it is.
918+ boost::ignore_unused_variable_warning(severity);
919+ // logger->set_filter(attrs::Severity < severity);
920+
921+ initialized_ = true;
922+ }
923+
924+ void Log(Severity severity, const std::string& message, const boost::optional<Location> &loc) {
925+ if (!initialized_)
926+ Init();
927+
928+ if (auto rec = boost::log::trivial::logger::get().open_record()) {
929+ boost::log::record_ostream out{rec};
930+ out << boost::log::add_value(attrs::Severity, severity)
931+ << boost::log::add_value(attrs::Timestamp, boost::posix_time::microsec_clock::universal_time())
932+ << message;
933+
934+ if (loc) {
935+ // We have to pass in a temporary as boost::log (<= 1.55) expects a
936+ // mutable reference to be passed to boost::log::add_value(...).
937+ auto tmp = *loc;
938+ out << boost::log::add_value(attrs::Location, tmp);
939+ }
940+
941+ boost::log::trivial::logger::get().push_record(std::move(rec));
942+ }
943+ }
944+
945+private:
946+ bool initialized_;
947+};
948+
949+std::shared_ptr<media::Logger>& MutableInstance() {
950+ static std::shared_ptr<media::Logger> instance{new BoostLogLogger()};
951+ return instance;
952+}
953+
954+void SetInstance(const std::shared_ptr<media::Logger>& logger) {
955+ MutableInstance() = logger;
956+}
957+}
958+
959+void media::Logger::Trace(const std::string& message, const boost::optional<Location>& location) {
960+ Log(Severity::kTrace, message, location);
961+}
962+
963+void media::Logger::Debug(const std::string& message, const boost::optional<Location>& location) {
964+ Log(Severity::kDebug, message, location);
965+}
966+
967+void media::Logger::Info(const std::string& message, const boost::optional<Location>& location) {
968+ Log(Severity::kInfo, message, location);
969+}
970+
971+void media::Logger::Warning(const std::string& message, const boost::optional<Location>& location) {
972+ Log(Severity::kWarning, message, location);
973+}
974+
975+void media::Logger::Error(const std::string& message, const boost::optional<Location>& location) {
976+ Log(Severity::kError, message, location);
977+}
978+
979+void media::Logger::Fatal(const std::string& message, const boost::optional<Location>& location) {
980+ Log(Severity::kFatal, message, location);
981+}
982+
983+namespace core {
984+namespace ubuntu {
985+namespace media {
986+
987+std::ostream& operator<<(std::ostream& strm, Logger::Severity severity) {
988+ switch (severity) {
989+ case media::Logger::Severity::kTrace: return strm << "TT";
990+ case media::Logger::Severity::kDebug: return strm << "DD";
991+ case media::Logger::Severity::kInfo: return strm << "II";
992+ case media::Logger::Severity::kWarning: return strm << "WW";
993+ case media::Logger::Severity::kError: return strm << "EE";
994+ case media::Logger::Severity::kFatal: return strm << "FF";
995+ default: return strm << static_cast<uint>(severity);
996+ }
997+}
998+
999+std::ostream& operator<<(std::ostream& out, const Logger::Location &location) {
1000+ return out << Utils::Sprintf("%s:%d@%s", boost::filesystem::path(location.file).filename().string(), location.line, location.function);
1001+}
1002+
1003+Logger& Log() {
1004+ return *MutableInstance();
1005+}
1006+
1007+void SetLogger(const std::shared_ptr<Logger>& logger) {
1008+ SetInstance(logger);
1009+}
1010+
1011+} // namespace media
1012+} // namespace ubuntu
1013+} // namespace core
1014
1015=== added file 'src/core/media/logger/logger.h'
1016--- src/core/media/logger/logger.h 1970-01-01 00:00:00 +0000
1017+++ src/core/media/logger/logger.h 2016-04-06 19:07:29 +0000
1018@@ -0,0 +1,131 @@
1019+/*
1020+ * Copyright (C) 2015 Canonical, Ltd.
1021+ *
1022+ * This program is free software: you can redistribute it and/or modify it
1023+ * under the terms of the GNU General Public License version 3, as published
1024+ * by the Free Software Foundation.
1025+ *
1026+ * This program is distributed in the hope that it will be useful, but
1027+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1028+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1029+ * PURPOSE. See the GNU General Public License for more details.
1030+ *
1031+ * You should have received a copy of the GNU General Public License along
1032+ * with this program. If not, see <http://www.gnu.org/licenses/>.
1033+ *
1034+ */
1035+
1036+#ifndef LOGGER_H_
1037+#define LOGGER_H_
1038+
1039+#include "core/media/non_copyable.h"
1040+#include "core/media/util/utils.h"
1041+
1042+#include <boost/optional.hpp>
1043+
1044+#include <string>
1045+
1046+namespace core {
1047+namespace ubuntu {
1048+namespace media {
1049+// A Logger enables persisting of messages describing & explaining the
1050+// state of the system.
1051+class Logger : public core::ubuntu::media::NonCopyable {
1052+public:
1053+ // Severity enumerates all known severity levels
1054+ // applicable to log messages.
1055+ enum class Severity {
1056+ kTrace,
1057+ kDebug,
1058+ kInfo,
1059+ kWarning,
1060+ kError,
1061+ kFatal
1062+ };
1063+
1064+ // A Location describes the origin of a log message.
1065+ struct Location {
1066+ std::string file; // The name of the file that contains the log message.
1067+ std::string function; // The function that contains the log message.
1068+ std::uint32_t line; // The line in file that resulted in the log message.
1069+ };
1070+
1071+ virtual void Init(const core::ubuntu::media::Logger::Severity &severity = core::ubuntu::media::Logger::Severity::kWarning) = 0;
1072+
1073+ virtual void Log(Severity severity, const std::string &message, const boost::optional<Location>& location) = 0;
1074+
1075+ virtual void Trace(const std::string& message, const boost::optional<Location>& location = boost::optional<Location>{});
1076+ virtual void Debug(const std::string& message, const boost::optional<Location>& location = boost::optional<Location>{});
1077+ virtual void Info(const std::string& message, const boost::optional<Location>& location = boost::optional<Location>{});
1078+ virtual void Warning(const std::string& message, const boost::optional<Location>& location = boost::optional<Location>{});
1079+ virtual void Error(const std::string& message, const boost::optional<Location>& location = boost::optional<Location>{});
1080+ virtual void Fatal(const std::string& message, const boost::optional<Location>& location = boost::optional<Location>{});
1081+
1082+
1083+ template<typename... T>
1084+ void Tracef(const boost::optional<Location>& location, const std::string& pattern, T&&...args) {
1085+ Trace(Utils::Sprintf(pattern, std::forward<T>(args)...), location);
1086+ }
1087+
1088+ template<typename... T>
1089+ void Debugf(const boost::optional<Location>& location, const std::string& pattern, T&&...args) {
1090+ Debug(Utils::Sprintf(pattern, std::forward<T>(args)...), location);
1091+ }
1092+
1093+ template<typename... T>
1094+ void Infof(const boost::optional<Location>& location, const std::string& pattern, T&&...args) {
1095+ Info(Utils::Sprintf(pattern, std::forward<T>(args)...), location);
1096+ }
1097+
1098+ template<typename... T>
1099+ void Warningf(const boost::optional<Location>& location, const std::string& pattern, T&&...args) {
1100+ Warning(Utils::Sprintf(pattern, std::forward<T>(args)...), location);
1101+ }
1102+
1103+ template<typename... T>
1104+ void Errorf(const boost::optional<Location>& location, const std::string& pattern, T&&...args) {
1105+ Error(Utils::Sprintf(pattern, std::forward<T>(args)...), location);
1106+ }
1107+
1108+ template<typename... T>
1109+ void Fatalf(const boost::optional<Location>& location, const std::string& pattern, T&&...args) {
1110+ Fatal(Utils::Sprintf(pattern, std::forward<T>(args)...), location);
1111+ }
1112+
1113+protected:
1114+ Logger() = default;
1115+};
1116+
1117+// operator<< inserts severity into out.
1118+std::ostream& operator<<(std::ostream& out, Logger::Severity severity);
1119+
1120+// operator<< inserts location into out.
1121+std::ostream& operator<<(std::ostream& out, const Logger::Location &location);
1122+
1123+// Log returns the core::ubuntu::media-wide configured logger instance.
1124+// Save to call before/after main.
1125+Logger& Log();
1126+// SetLog installs the given logger as core::ubuntu::media-wide default logger.
1127+void SetLogger(const std::shared_ptr<Logger>& logger);
1128+
1129+#define TRACE(...) Log().Tracef(Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1130+#define DEBUG(...) Log().Debugf(Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1131+#define INFO(...) Log().Infof(Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1132+#define WARNING(...) Log().Warningf(Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1133+#define ERROR(...) Log().Errorf(Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1134+#define FATAL(...) Log().Fatalf(Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1135+} // namespace media
1136+} // namespace ubuntu
1137+} // namespace core
1138+
1139+#define MH_TRACE(...) core::ubuntu::media::Log().Tracef(\
1140+ core::ubuntu::media::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1141+#define MH_DEBUG(...) core::ubuntu::media::Log().Debugf(\
1142+ core::ubuntu::media::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1143+#define MH_INFO(...) core::ubuntu::media::Log().Infof(\
1144+ core::ubuntu::media::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1145+#define MH_WARNING(...) core::ubuntu::media::Log().Warningf(core::ubuntu::media::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1146+#define MH_ERROR(...) core::ubuntu::media::Log().Errorf(core::ubuntu::media::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1147+#define MH_FATAL(...) core::ubuntu::media::Log().Fatalf(core::ubuntu::media::Logger::Location{__FILE__, __FUNCTION__, __LINE__}, __VA_ARGS__)
1148+
1149+#endif
1150
1151=== added file 'src/core/media/non_copyable.h'
1152--- src/core/media/non_copyable.h 1970-01-01 00:00:00 +0000
1153+++ src/core/media/non_copyable.h 2016-04-06 19:07:29 +0000
1154@@ -0,0 +1,36 @@
1155+/*
1156+ * Copyright (C) 2015 Canonical, Ltd.
1157+ *
1158+ * This program is free software: you can redistribute it and/or modify it
1159+ * under the terms of the GNU General Public License version 3, as published
1160+ * by the Free Software Foundation.
1161+ *
1162+ * This program is distributed in the hope that it will be useful, but
1163+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1164+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1165+ * PURPOSE. See the GNU General Public License for more details.
1166+ *
1167+ * You should have received a copy of the GNU General Public License along
1168+ * with this program. If not, see <http://www.gnu.org/licenses/>.
1169+ *
1170+ */
1171+
1172+#ifndef NON_COPYABLE_H_
1173+#define NON_COPYABLE_H_
1174+
1175+namespace core {
1176+namespace ubuntu {
1177+namespace media {
1178+// The alert reader might wonder why we don't use boost::noncopyable. The reason
1179+// is simple: We would like to have a convenient virtual d'tor available.
1180+struct NonCopyable {
1181+ NonCopyable() = default;
1182+ NonCopyable(const NonCopyable&) = delete;
1183+ virtual ~NonCopyable() = default;
1184+ NonCopyable& operator=(const NonCopyable&) = delete;
1185+};
1186+}
1187+}
1188+}
1189+
1190+#endif
1191
1192=== modified file 'src/core/media/player_implementation.cpp'
1193--- src/core/media/player_implementation.cpp 2016-02-19 16:14:42 +0000
1194+++ src/core/media/player_implementation.cpp 2016-04-06 19:07:29 +0000
1195@@ -28,9 +28,10 @@
1196
1197 #include "gstreamer/engine.h"
1198
1199+#include "core/media/logger/logger.h"
1200+
1201 #include <memory>
1202 #include <exception>
1203-#include <iostream>
1204 #include <mutex>
1205
1206 #define UNUSED __attribute__((unused))
1207@@ -75,22 +76,22 @@
1208 // Poor man's logging of release/acquire events.
1209 display_state_lock->acquired().connect([](media::power::DisplayState state)
1210 {
1211- std::cout << "Acquired new display state: " << state << std::endl;
1212+ MH_INFO("Acquired new display state: %s", state);
1213 });
1214
1215 display_state_lock->released().connect([](media::power::DisplayState state)
1216 {
1217- std::cout << "Released display state: " << state << std::endl;
1218+ MH_INFO("Released display state: %s", state);
1219 });
1220
1221 system_state_lock->acquired().connect([](media::power::SystemState state)
1222 {
1223- std::cout << "Acquired new system state: " << state << std::endl;
1224+ MH_INFO("Acquired new system state: %s", state);
1225 });
1226
1227 system_state_lock->released().connect([](media::power::SystemState state)
1228 {
1229- std::cout << "Released system state: " << state << std::endl;
1230+ MH_INFO("Released system state: %s", state);
1231 });
1232 }
1233
1234@@ -120,7 +121,7 @@
1235 */
1236 return [this](const Engine::State& state)
1237 {
1238- std::cout << "Setting state for parent: " << parent << std::endl;
1239+ MH_DEBUG("Setting state for parent: %s", parent);
1240 switch(state)
1241 {
1242 case Engine::State::ready:
1243@@ -139,7 +140,7 @@
1244 parent->meta_data_for_current_track().set(std::get<1>(engine->track_meta_data().get()));
1245 // And update our playback status.
1246 parent->playback_status().set(media::Player::playing);
1247- std::cout << "Requesting power state" << std::endl;
1248+ MH_INFO("Requesting power state");
1249 request_power_state();
1250 break;
1251 }
1252@@ -174,45 +175,44 @@
1253 {
1254 return [this](const media::Player::PlaybackStatus& status)
1255 {
1256- std::cout << "Emiting playback_status_changed signal: " << status << std::endl;
1257+ MH_INFO("Emiting playback_status_changed signal: %s", status);
1258 parent->emit_playback_status_changed(status);
1259 };
1260 }
1261
1262 void request_power_state()
1263 {
1264- std::cout << __PRETTY_FUNCTION__ << std::endl;
1265+ MH_TRACE("");
1266 try
1267 {
1268 if (parent->is_video_source())
1269 {
1270 if (++display_wakelock_count == 1)
1271 {
1272- std::cout << "Requesting new display wakelock." << std::endl;
1273+ MH_INFO("Requesting new display wakelock.");
1274 display_state_lock->request_acquire(media::power::DisplayState::on);
1275- std::cout << "Requested new display wakelock." << std::endl;
1276+ MH_INFO("Requested new display wakelock.");
1277 }
1278 }
1279 else
1280 {
1281 if (++system_wakelock_count == 1)
1282 {
1283- std::cout << "Requesting new system wakelock." << std::endl;
1284+ MH_INFO("Requesting new system wakelock.");
1285 system_state_lock->request_acquire(media::power::SystemState::active);
1286- std::cout << "Requested new system wakelock." << std::endl;
1287+ MH_INFO("Requested new system wakelock.");
1288 }
1289 }
1290 }
1291 catch(const std::exception& e)
1292 {
1293- std::cerr << "Warning: failed to request power state: ";
1294- std::cerr << e.what() << std::endl;
1295+ MH_WARNING("Failed to request power state: %s", e.what());
1296 }
1297 }
1298
1299 void clear_wakelock(const wakelock_clear_t &wakelock)
1300 {
1301- cout << __PRETTY_FUNCTION__ << endl;
1302+ MH_TRACE("");
1303 try
1304 {
1305 switch (wakelock)
1306@@ -223,7 +223,7 @@
1307 // Only actually clear the system wakelock once the count reaches zero
1308 if (--system_wakelock_count == 0)
1309 {
1310- std::cout << "Clearing system wakelock." << std::endl;
1311+ MH_INFO("Clearing system wakelock.");
1312 system_state_lock->request_release(media::power::SystemState::active);
1313 }
1314 break;
1315@@ -231,19 +231,18 @@
1316 // Only actually clear the display wakelock once the count reaches zero
1317 if (--display_wakelock_count == 0)
1318 {
1319- std::cout << "Clearing display wakelock." << std::endl;
1320+ MH_INFO("Clearing display wakelock.");
1321 display_state_lock->request_release(media::power::DisplayState::on);
1322 }
1323 break;
1324 case wakelock_clear_t::WAKELOCK_CLEAR_INVALID:
1325 default:
1326- cerr << "Can't clear invalid wakelock type" << endl;
1327+ MH_WARNING("Can't clear invalid wakelock type");
1328 }
1329 }
1330 catch(const std::exception& e)
1331 {
1332- std::cerr << "Warning: failed to clear power state: ";
1333- std::cerr << e.what() << std::endl;
1334+ MH_WARNING("Failed to request clear power state: %s", e.what());
1335 }
1336 }
1337
1338@@ -294,9 +293,9 @@
1339 {
1340 // Using a TrackList for playback, added tracks via add_track(), but open_uri hasn't
1341 // been called yet to load a media resource
1342- std::cout << "Calling d->engine->open_resource_for_uri() for first track added only: "
1343- << uri << std::endl;
1344- std::cout << "\twith a Track::Id: " << id << std::endl;
1345+ MH_INFO("Calling d->engine->open_resource_for_uri() for first track added only: %s",
1346+ uri);
1347+ MH_INFO("\twith a Track::Id: %s", id);
1348 static const bool do_pipeline_reset = false;
1349 engine->open_resource_for_uri(uri, do_pipeline_reset);
1350 }
1351@@ -311,10 +310,10 @@
1352 auto n_tracks = track_list->tracks()->size();
1353 bool has_tracks = (n_tracks > 0) ? true : false;
1354
1355- std::cout << "Updating MPRIS TrackList properties"
1356- << "; Tracks: " << n_tracks
1357- << ", has_previous: " << has_previous
1358- << ", has_next: " << has_next << std::endl;
1359+ MH_INFO("Updating MPRIS TrackList properties:");
1360+ MH_INFO("\tTracks: %d", n_tracks);
1361+ MH_INFO("\thas_previous: %d", has_previous);
1362+ MH_INFO("\thas_next: %d", has_next);
1363
1364 // Update properties
1365 parent->can_play().set(has_tracks);
1366@@ -418,7 +417,7 @@
1367 // When the client changes the loop status, make sure to update the TrackList
1368 Parent::loop_status().changed().connect([this](media::Player::LoopStatus loop_status)
1369 {
1370- std::cout << "LoopStatus: " << loop_status << std::endl;
1371+ MH_INFO("LoopStatus: %s", loop_status);
1372 d->track_list->on_loop_status_changed(loop_status);
1373 });
1374
1375@@ -465,7 +464,7 @@
1376 const Track::UriType uri = d->track_list->query_uri_for_track(d->track_list->next());
1377 if (prev_track_id != d->track_list->current() && !uri.empty())
1378 {
1379- std::cout << "Advancing to next track on playbin: " << uri << std::endl;
1380+ MH_INFO("Advancing to next track on playbin: %s", uri);
1381 static const bool do_pipeline_reset = false;
1382 d->engine->open_resource_for_uri(uri, do_pipeline_reset);
1383 }
1384@@ -508,7 +507,7 @@
1385 if (d->engine->state() != gstreamer::Engine::State::ready
1386 && d->engine->state() != gstreamer::Engine::State::stopped)
1387 {
1388- std::cout << "End of tracklist reached, stopping playback" << std::endl;
1389+ MH_INFO("End of tracklist reached, stopping playback");
1390 d->engine->stop();
1391 }
1392 });
1393@@ -528,15 +527,15 @@
1394 const Track::UriType uri = d->track_list->query_uri_for_track(id);
1395 if (!uri.empty())
1396 {
1397- std::cout << "Setting next track on playbin (on_go_to_track signal): " << uri << std::endl;
1398- std::cout << "\twith a Track::Id: " << id << std::endl;
1399+ MH_INFO("Setting next track on playbin (on_go_to_track signal): %s", uri);
1400+ MH_INFO("\twith a Track::Id: %s", id);
1401 static const bool do_pipeline_reset = true;
1402 d->engine->open_resource_for_uri(uri, do_pipeline_reset);
1403 }
1404
1405 if (auto_play)
1406 {
1407- std::cout << "Restoring playing state in on_go_to_track()" << std::endl;
1408+ MH_DEBUG("Restoring playing state");
1409 d->engine->play();
1410 }
1411
1412@@ -545,7 +544,7 @@
1413
1414 d->track_list->on_track_added().connect([this](const media::Track::Id& id)
1415 {
1416- std::cout << "** Track was added, handling in PlayerImplementation" << std::endl;
1417+ MH_TRACE("** Track was added, handling in PlayerImplementation");
1418 if (d->track_list->tracks()->size() == 1)
1419 d->open_first_track_from_tracklist(id);
1420
1421@@ -554,7 +553,7 @@
1422
1423 d->track_list->on_tracks_added().connect([this](const media::TrackList::ContainerURI& tracks)
1424 {
1425- std::cout << "** Track was added, handling in PlayerImplementation" << std::endl;
1426+ MH_TRACE("** Track was added, handling in PlayerImplementation");
1427 // If the two sizes are the same, that means the TrackList was previously empty and we need
1428 // to open the first track in the TrackList so that is_audio_source() and is_video_source()
1429 // will function correctly.
1430@@ -689,7 +688,7 @@
1431
1432 // If empty uri, give the same meaning as QMediaPlayer::setMedia("")
1433 if (uri.empty()) {
1434- cout << __PRETTY_FUNCTION__ << ": resetting current media" << endl;
1435+ MH_DEBUG("Resetting current media");
1436 return true;
1437 }
1438
1439@@ -722,19 +721,21 @@
1440 template<typename Parent>
1441 void media::PlayerImplementation<Parent>::play()
1442 {
1443+ MH_TRACE("");
1444 d->engine->play();
1445 }
1446
1447 template<typename Parent>
1448 void media::PlayerImplementation<Parent>::pause()
1449 {
1450+ MH_TRACE("");
1451 d->engine->pause();
1452 }
1453
1454 template<typename Parent>
1455 void media::PlayerImplementation<Parent>::stop()
1456 {
1457- std::cout << __PRETTY_FUNCTION__ << std::endl;
1458+ MH_TRACE("");
1459 d->engine->stop();
1460 }
1461
1462
1463=== modified file 'src/core/media/player_skeleton.cpp'
1464--- src/core/media/player_skeleton.cpp 2016-02-19 16:14:42 +0000
1465+++ src/core/media/player_skeleton.cpp 2016-04-06 19:07:29 +0000
1466@@ -31,6 +31,8 @@
1467 #include "mpris/metadata.h"
1468 #include "mpris/player.h"
1469 #include "mpris/playlists.h"
1470+
1471+#include "core/media/logger/logger.h"
1472 #include "util/uri_check.h"
1473
1474 #include <core/dbus/object.h>
1475@@ -189,7 +191,7 @@
1476 {
1477 const std::string err_str = {"Warning: Failed to open uri " + uri +
1478 " because it can't be found."};
1479- std::cerr << err_str << std::endl;
1480+ MH_ERROR("%s", err_str);
1481 reply = dbus::Message::make_error(
1482 in,
1483 mpris::Player::Error::UriNotFound::name,
1484@@ -207,7 +209,7 @@
1485 {
1486 const std::string err_str = {"Warning: Failed to authenticate necessary "
1487 "apparmor permissions to open uri: " + std::get<1>(result)};
1488- std::cerr << err_str << std::endl;
1489+ MH_ERROR("%s", err_str);
1490 reply = dbus::Message::make_error(
1491 in,
1492 mpris::Player::Error::InsufficientAppArmorPermissions::name,
1493@@ -236,7 +238,7 @@
1494 {
1495 const std::string err_str = {"Warning: Failed to open uri " + uri +
1496 " because it can't be found."};
1497- std::cerr << err_str << std::endl;
1498+ MH_ERROR("%s", err_str);
1499 reply = dbus::Message::make_error(
1500 in,
1501 mpris::Player::Error::UriNotFound::name,
1502@@ -254,7 +256,7 @@
1503 {
1504 const std::string err_str = {"Warning: Failed to authenticate necessary "
1505 "apparmor permissions to open uri: " + std::get<1>(result)};
1506- std::cerr << err_str << std::endl;
1507+ MH_ERROR("%s", err_str);
1508 reply = dbus::Message::make_error(
1509 in,
1510 mpris::Player::Error::InsufficientAppArmorPermissions::name,
1511
1512=== modified file 'src/core/media/player_stub.cpp'
1513--- src/core/media/player_stub.cpp 2016-02-19 16:14:42 +0000
1514+++ src/core/media/player_stub.cpp 2016-04-06 19:07:29 +0000
1515@@ -30,10 +30,13 @@
1516
1517 #include "mpris/player.h"
1518
1519+#include "core/media/logger/logger.h"
1520+
1521 #include <core/dbus/property.h>
1522 #include <core/dbus/types/object_path.h>
1523
1524 #include <limits>
1525+#include <sstream>
1526
1527 #define UNUSED __attribute__((unused))
1528
1529@@ -159,37 +162,38 @@
1530 {
1531 dbus.seeked_to->connect([this](std::uint64_t value)
1532 {
1533- std::cout << "SeekedTo signal arrived via the bus." << std::endl;
1534+ MH_DEBUG("SeekedTo signal arrived via the bus.");
1535 seeked_to(value);
1536 });
1537
1538 dbus.about_to_finish->connect([this]()
1539 {
1540- std::cout << "AboutToFinish signal arrived via the bus." << std::endl;
1541+ MH_DEBUG("AboutToFinish signal arrived via the bus.");
1542 about_to_finish();
1543 });
1544
1545 dbus.end_of_stream->connect([this]()
1546 {
1547- std::cout << "EndOfStream signal arrived via the bus." << std::endl;
1548+ MH_DEBUG("EndOfStream signal arrived via the bus.");
1549 end_of_stream();
1550 });
1551
1552 dbus.playback_status_changed->connect([this](const media::Player::PlaybackStatus& status)
1553 {
1554- std::cout << "PlaybackStatusChanged signal arrived via the bus (Status: " << status << ")" << std::endl;
1555+ MH_DEBUG("PlaybackStatusChanged signal arrived via the bus (status: %s)",
1556+ status);
1557 playback_status_changed(status);
1558 });
1559
1560 dbus.video_dimension_changed->connect([this](const media::video::Dimensions dimensions)
1561 {
1562- std::cout << "VideoDimensionChanged signal arrived via the bus." << std::endl;
1563+ MH_DEBUG("VideoDimensionChanged signal arrived via the bus.");
1564 video_dimension_changed(dimensions);
1565 });
1566
1567 dbus.error->connect([this](const media::Player::Error& e)
1568 {
1569- std::cout << "Error signal arrived via the bus (Error: " << e << ")" << std::endl;
1570+ MH_DEBUG("Error signal arrived via the bus (error: %s)", e);
1571 error(e);
1572 });
1573 }
1574
1575=== modified file 'src/core/media/power/state_controller.cpp'
1576--- src/core/media/power/state_controller.cpp 2015-05-27 18:37:24 +0000
1577+++ src/core/media/power/state_controller.cpp 2016-04-06 19:07:29 +0000
1578@@ -16,13 +16,13 @@
1579 * Authored by: Thomas Voß <thomas.voss@canonical.com>
1580 */
1581
1582+#include "core/media/logger/logger.h"
1583+
1584 #include <core/media/power/state_controller.h>
1585
1586 #include <core/dbus/macros.h>
1587 #include <core/dbus/object.h>
1588
1589-#include <iostream>
1590-
1591 namespace media = core::ubuntu::media;
1592
1593 namespace com { namespace canonical {
1594@@ -98,7 +98,7 @@
1595 // From core::ubuntu::media::power::StateController::Lock<DisplayState>
1596 void request_acquire(media::power::DisplayState state) override
1597 {
1598- std::cout << __PRETTY_FUNCTION__ << std::endl;
1599+ MH_TRACE("");
1600
1601 if (state == media::power::DisplayState::off)
1602 return;
1603@@ -110,7 +110,7 @@
1604 {
1605 if (result.is_error())
1606 {
1607- std::cerr << result.error().print() << std::endl;
1608+ MH_ERROR("%s", result.error().print());
1609 return;
1610 }
1611
1612@@ -149,7 +149,7 @@
1613 {
1614 if (result.is_error())
1615 {
1616- std::cerr << result.error().print() << std::endl;
1617+ MH_ERROR("%s", result.error().print());
1618 return;
1619 }
1620
1621@@ -207,7 +207,7 @@
1622 // the system to stay active.
1623 void request_acquire(media::power::SystemState state) override
1624 {
1625- std::cout << __PRETTY_FUNCTION__ << std::endl;
1626+ MH_TRACE("");
1627
1628 if (state == media::power::SystemState::suspend)
1629 return;
1630@@ -223,7 +223,7 @@
1631 }
1632 else
1633 {
1634- std::cerr << "Failed to lock system_state_cookie_store_guard and check system lock state" << std::endl;
1635+ MH_WARNING("Failed to lock system_state_cookie_store_guard and check system lock state");
1636 // Prevent system_state_cookie_store.count(state) and the actual call to requestSysState below from
1637 // getting out of sync.
1638 return;
1639@@ -236,7 +236,7 @@
1640 {
1641 if (result.is_error())
1642 {
1643- std::cerr << result.error().print() << std::endl;
1644+ MH_ERROR("%s", result.error().print());
1645 return;
1646 }
1647
1648@@ -249,7 +249,7 @@
1649 if (ul.owns_lock())
1650 sp->system_state_cookie_store[state] = result.value();
1651 else
1652- std::cerr << "Failed to lock system_state_cookie_store_guard and update system lock state" << std::endl;
1653+ MH_WARNING("Failed to lock system_state_cookie_store_guard and update system lock state");
1654 }
1655
1656 sp->signals.acquired(state);
1657@@ -275,7 +275,7 @@
1658 }
1659 else
1660 {
1661- std::cerr << "Failed to lock system_state_cookie_store_guard and check system lock state" << std::endl;
1662+ MH_WARNING("Failed to lock system_state_cookie_store_guard and check system lock state");
1663 // Prevent system_state_cookie_store.count(state) and the actual call to clearSysState below from
1664 // getting out of sync.
1665 return;
1666@@ -287,7 +287,7 @@
1667 object->invoke_method_asynchronously_with_callback<com::canonical::powerd::Interface::clearSysState, void>([this, wp, state](const core::dbus::Result<void>& result)
1668 {
1669 if (result.is_error())
1670- std::cerr << result.error().print() << std::endl;
1671+ MH_ERROR("%s", result.error().print());
1672
1673 if (auto sp = wp.lock())
1674 {
1675@@ -297,7 +297,7 @@
1676 if (ul.owns_lock())
1677 sp->system_state_cookie_store.erase(state);
1678 else
1679- std::cerr << "Failed to lock system_state_cookie_store_guard and erase system lock state" << std::endl;
1680+ MH_WARNING("Failed to lock system_state_cookie_store_guard and erase system lock state");
1681 }
1682
1683 sp->signals.released(state);
1684@@ -369,7 +369,7 @@
1685
1686 media::power::StateController::Ptr media::power::make_platform_default_state_controller(core::ubuntu::media::helper::ExternalServices& external_services)
1687 {
1688- return std::make_shared<impl::StateController>(external_services);
1689+ return std::make_shared<::impl::StateController>(external_services);
1690 }
1691
1692 // operator<< pretty prints the given display state to the given output stream.
1693
1694=== modified file 'src/core/media/server/server.cpp'
1695--- src/core/media/server/server.cpp 2015-04-10 16:13:55 +0000
1696+++ src/core/media/server/server.cpp 2016-04-06 19:07:29 +0000
1697@@ -21,6 +21,7 @@
1698 #include <core/media/track_list.h>
1699
1700 #include "core/media/hashed_keyed_player_store.h"
1701+#include "core/media/logger/logger.h"
1702 #include "core/media/service_implementation.h"
1703
1704 #include <core/posix/signal.h>
1705@@ -36,6 +37,37 @@
1706
1707 namespace
1708 {
1709+void logger_init()
1710+{
1711+ const char *level = ::getenv("MH_LOG_LEVEL");
1712+ // Default level is kInfo
1713+ media::Logger::Severity severity{media::Logger::Severity::kInfo};
1714+ if (level)
1715+ {
1716+ if (strcmp(level, "trace") == 0)
1717+ severity = media::Logger::Severity::kTrace;
1718+ else if (strcmp(level, "debug") == 0)
1719+ severity = media::Logger::Severity::kDebug;
1720+ else if (strcmp(level, "info") == 0)
1721+ severity = media::Logger::Severity::kInfo;
1722+ else if (strcmp(level, "warning") == 0)
1723+ severity = media::Logger::Severity::kWarning;
1724+ else if (strcmp(level, "error") == 0)
1725+ severity = media::Logger::Severity::kError;
1726+ else if (strcmp(level, "fatal") == 0)
1727+ severity = media::Logger::Severity::kFatal;
1728+ else
1729+ std::cerr << "Invalid log level \"" << level
1730+ << "\", setting to info. Valid options: [trace, debug, info, warning, error, fatal]. "
1731+ << std::endl;
1732+ }
1733+ else
1734+ std::cout << "Using default log level: info" << std::endl;
1735+
1736+ media::Log().Init(severity);
1737+ cout << "Log level: " << severity << std::endl;
1738+}
1739+
1740 // All platform-specific initialization routines go here.
1741 void platform_init()
1742 {
1743@@ -66,6 +98,8 @@
1744 trap->stop();
1745 });
1746
1747+ logger_init();
1748+
1749 // Init platform-specific functionality.
1750 platform_init();
1751
1752
1753=== modified file 'src/core/media/service.cpp'
1754--- src/core/media/service.cpp 2014-04-09 14:05:55 +0000
1755+++ src/core/media/service.cpp 2016-04-06 19:07:29 +0000
1756@@ -18,13 +18,15 @@
1757
1758 #include <core/media/service.h>
1759
1760+#include "core/media/logger/logger.h"
1761+
1762 #include "service_stub.h"
1763
1764 namespace media = core::ubuntu::media;
1765
1766 const std::shared_ptr<media::Service> media::Service::Client::instance()
1767 {
1768- std::cout << "Creating a new static Service instance" << std::endl;
1769+ MH_TRACE("");
1770 static std::shared_ptr<media::Service> instance{new media::ServiceStub()};
1771 return instance;
1772 }
1773
1774=== modified file 'src/core/media/service_implementation.cpp'
1775--- src/core/media/service_implementation.cpp 2016-03-02 18:32:46 +0000
1776+++ src/core/media/service_implementation.cpp 2016-04-06 19:07:29 +0000
1777@@ -33,6 +33,9 @@
1778 #include "recorder_observer.h"
1779 #include "telephony/call_monitor.h"
1780
1781+#include "util/timeout.h"
1782+#include "core/media/logger/logger.h"
1783+
1784 #include <boost/asio.hpp>
1785
1786 #include <string>
1787@@ -45,8 +48,6 @@
1788
1789 #include <pulse/pulseaudio.h>
1790
1791-#include "util/timeout.h"
1792-
1793 namespace media = core::ubuntu::media;
1794
1795 using namespace std;
1796@@ -126,16 +127,16 @@
1797 switch (state)
1798 {
1799 case audio::OutputState::Earpiece:
1800- std::cout << "AudioOutputObserver reports that output is now Headphones/Headset." << std::endl;
1801+ MH_INFO("AudioOutputObserver reports that output is now Headphones/Headset.");
1802 break;
1803 case audio::OutputState::Speaker:
1804- std::cout << "AudioOutputObserver reports that output is now Speaker." << std::endl;
1805+ MH_INFO("AudioOutputObserver reports that output is now Speaker.");
1806 // Whatever player session is currently playing, make sure it is NOT resumed after
1807 // a phonecall is hung up
1808 pause_all_multimedia_sessions(resume_play_after_phonecall);
1809 break;
1810 case audio::OutputState::External:
1811- std::cout << "AudioOutputObserver reports that output is now External." << std::endl;
1812+ MH_INFO("AudioOutputObserver reports that output is now External.");
1813 break;
1814 }
1815 d->audio_output_state = state;
1816@@ -146,13 +147,13 @@
1817 const bool resume_play_after_phonecall = true;
1818 switch (state) {
1819 case media::telephony::CallMonitor::State::OffHook:
1820- std::cout << "Got call started signal, pausing all multimedia sessions" << std::endl;
1821+ MH_INFO("Got call started signal, pausing all multimedia sessions");
1822 // Whatever player session is currently playing, make sure it gets resumed after
1823 // a phonecall is hung up
1824 pause_all_multimedia_sessions(resume_play_after_phonecall);
1825 break;
1826 case media::telephony::CallMonitor::State::OnHook:
1827- std::cout << "Got call ended signal, resuming paused multimedia sessions" << std::endl;
1828+ MH_INFO("Got call ended signal, resuming paused multimedia sessions");
1829 resume_paused_multimedia_sessions(false);
1830 break;
1831 }
1832@@ -217,10 +218,10 @@
1833 d->configuration.player_store->remove_player_for_key(key);
1834 }
1835 catch (const std::out_of_range &e) {
1836- std::cerr << "Failed to look up Player instance for key " << key
1837- << ", no valid Player instance for that key value. Removal of Player from Player store"
1838- << " might not have completed. This most likely means that media-hub-server has"
1839- << " crashed and restarted." << std::endl;
1840+ MH_WARNING("Failed to look up Player instance for key %d"
1841+ ", no valid Player instance for that key value. Removal of Player from Player store"
1842+ " might not have completed. This most likely means that media-hub-server has"
1843+ " crashed and restarted.", key);
1844 return;
1845 }
1846 });
1847@@ -264,11 +265,11 @@
1848
1849 void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key)
1850 {
1851- std::cout << __PRETTY_FUNCTION__ << std::endl;
1852+ MH_TRACE("");
1853
1854 if (not d->configuration.player_store->has_player_for_key(key))
1855 {
1856- cerr << "Could not find Player by key: " << key << endl;
1857+ MH_WARNING("Could not find Player by key: %d", key);
1858 return;
1859 }
1860
1861@@ -291,7 +292,7 @@
1862 current_player->audio_stream_role() == media::Player::multimedia &&
1863 other_player->audio_stream_role() == media::Player::multimedia)
1864 {
1865- cout << "Pausing Player with key: " << other_key << endl;
1866+ MH_INFO("Pausing Player with key: %d", other_key);
1867 other_player->pause();
1868 }
1869 });
1870@@ -306,8 +307,8 @@
1871 {
1872 auto paused_player_pair = std::make_pair(key, resume_play_after_phonecall);
1873 d->paused_sessions.push_back(paused_player_pair);
1874- std::cout << "Pausing Player with key: " << key << ", resuming after phone call? "
1875- << (resume_play_after_phonecall ? "yes" : "no") << std::endl;
1876+ MH_INFO("Pausing Player with key: %d, resuming after phone call? %s", key,
1877+ (resume_play_after_phonecall ? "yes" : "no"));
1878 player->pause();
1879 }
1880 });
1881@@ -324,17 +325,17 @@
1882 player = d->configuration.player_store->player_for_key(key);
1883 }
1884 catch (const std::out_of_range &e) {
1885- std::cerr << "Failed to look up Player instance for key " << key
1886- << ", no valid Player instance for that key value and cannot automatically resume"
1887- << " paused players. This most likely means that media-hub-server has crashed and"
1888- << " restarted." << std::endl;
1889+ MH_WARNING("Failed to look up Player instance for key %d"
1890+ ", no valid Player instance for that key value and cannot automatically resume"
1891+ " paused players. This most likely means that media-hub-server has crashed and"
1892+ " restarted.", key);
1893 return;
1894 }
1895 // Only resume video playback if explicitly desired
1896 if ((resume_video_sessions || player->is_audio_source()) && resume_play_after_phonecall)
1897 player->play();
1898 else
1899- std::cout << "Not auto-resuming video player session or other type of player session." << std::endl;
1900+ MH_INFO("Not auto-resuming video player session or other type of player session.");
1901 });
1902
1903 d->paused_sessions.clear();
1904@@ -350,16 +351,16 @@
1905 player = d->configuration.player_store->player_for_key(d->resume_key);
1906 }
1907 catch (const std::out_of_range &e) {
1908- std::cerr << "Failed to look up Player instance for key " << d->resume_key
1909- << ", no valid Player instance for that key value and cannot automatically resume"
1910- << " paused Player. This most likely means that media-hub-server has crashed and"
1911- << " restarted." << std::endl;
1912+ MH_WARNING("Failed to look up Player instance for key %d"
1913+ ", no valid Player instance for that key value and cannot automatically resume"
1914+ " paused Player. This most likely means that media-hub-server has crashed and"
1915+ " restarted.", d->resume_key);
1916 return;
1917 }
1918
1919 if (player->playback_status() == Player::paused)
1920 {
1921- cout << "Resuming playback of Player with key: " << d->resume_key << endl;
1922+ MH_INFO("Resuming playback of Player with key: %d", d->resume_key);
1923 player->play();
1924 d->resume_key = std::numeric_limits<std::uint32_t>::max();
1925 }
1926
1927=== modified file 'src/core/media/service_skeleton.cpp'
1928--- src/core/media/service_skeleton.cpp 2016-03-02 18:32:46 +0000
1929+++ src/core/media/service_skeleton.cpp 2016-04-06 19:07:29 +0000
1930@@ -29,6 +29,8 @@
1931 #include "the_session_bus.h"
1932 #include "xesam.h"
1933
1934+#include "core/media/logger/logger.h"
1935+
1936 #include <core/dbus/message.h>
1937 #include <core/dbus/object.h>
1938 #include <core/dbus/types/object_path.h>
1939@@ -134,9 +136,8 @@
1940 impl->access_service()->add_object_for_path(op)
1941 };
1942
1943- cout << "Session created by request of: " << msg->sender()
1944- << ", key: " << key << ", uuid: " << uuid
1945- << ", path:" << op << std::endl;
1946+ MH_DEBUG("Session created by request of: %s, key: %d, uuid: %d, path: %s",
1947+ msg->sender(), key, uuid, op);
1948
1949 try
1950 {
1951@@ -147,7 +148,7 @@
1952 request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(),
1953 [this, key, msg](const media::apparmor::ubuntu::Context& context)
1954 {
1955- fprintf(stderr, "%s():%d -- app_name='%s', attached\n", __func__, __LINE__, context.str().c_str());
1956+ MH_DEBUG(" -- app_name='%s', attached", context.str());
1957 player_owner_map.emplace(std::make_pair(key, std::make_tuple(context.str(), true, msg->sender())));
1958 });
1959
1960@@ -231,7 +232,8 @@
1961 [this, msg, key, op](const media::apparmor::ubuntu::Context& context)
1962 {
1963 auto info = player_owner_map.at(key);
1964- fprintf(stderr, "%s():%d -- reattach app_name='%s', info='%s', '%s'\n", __func__, __LINE__, context.str().c_str(), std::get<0>(info).c_str(), std::get<2>(info).c_str());
1965+ MH_DEBUG(" -- reattach app_name='%s', info='%s', '%s'",
1966+ context.str(), std::get<0>(info), std::get<2>(info));
1967 if (std::get<0>(info) == context.str()) {
1968 std::get<1>(info) = true; // Set to Attached
1969 std::get<2>(info) = msg->sender(); // Register new owner
1970@@ -242,7 +244,7 @@
1971 // We only care to allow the MPRIS controls to apply to multimedia player (i.e. audio, video)
1972 if (player->audio_stream_role() == media::Player::AudioStreamRole::multimedia)
1973 {
1974- std::cout << "Setting current_player" << std::endl;
1975+ MH_TRACE("Setting current_player");
1976 exported.set_current_player(player);
1977 }
1978
1979@@ -305,7 +307,8 @@
1980 [this, msg, key](const media::apparmor::ubuntu::Context& context)
1981 {
1982 auto info = player_owner_map.at(key);
1983- fprintf(stderr, "%s():%d -- Destroying app_name='%s', info='%s', '%s'\n", __func__, __LINE__, context.str().c_str(), std::get<0>(info).c_str(), std::get<2>(info).c_str());
1984+ MH_DEBUG(" -- Destroying app_name='%s', info='%s', '%s'",
1985+ context.str(), std::get<0>(info), std::get<2>(info));
1986 if (std::get<0>(info) == context.str()) {
1987 player_owner_map.erase(key);
1988
1989@@ -454,7 +457,7 @@
1990 core::dbus::Message::Ptr reply;
1991 if (not configuration.player_store->has_player_for_key(key))
1992 {
1993- std::cerr << __PRETTY_FUNCTION__ << " player key not found - " << key << std::endl;
1994+ MH_WARNING("Player key not found: %d", key);
1995 reply = dbus::Message::make_error(
1996 msg,
1997 mpris::Service::Errors::PlayerKeyNotFound::name(),
1998@@ -467,10 +470,9 @@
1999 reply = dbus::Message::make_method_return(msg);
2000 }
2001 catch (const std::out_of_range &e) {
2002- std::cerr << "Failed to look up Player instance for key " << key
2003- << ", no valid Player instance for that key value and cannot set current player."
2004- << " This most likely means that media-hub-server has crashed and restarted."
2005- << std::endl;
2006+ MH_WARNING("Failed to look up Player instance for key %d\
2007+ , no valid Player instance for that key value and cannot set current player.\
2008+ This most likely means that media-hub-server has crashed and restarted.", key);
2009 reply = dbus::Message::make_error(
2010 msg,
2011 mpris::Service::Errors::PlayerKeyNotFound::name(),
2012@@ -491,10 +493,9 @@
2013 reply = dbus::Message::make_method_return(msg);
2014 }
2015 catch (const std::out_of_range &e) {
2016- std::cerr << "Failed to look up Player instance for key " << key
2017- << ", no valid Player instance for that key value and cannot pause other Players."
2018- << " This most likely means that media-hub-server has crashed and restarted."
2019- << std::endl;
2020+ MH_WARNING("Failed to look up Player instance for key %d\
2021+ , no valid Player instance for that key value and cannot set current player.\
2022+ This most likely means that media-hub-server has crashed and restarted.", key);
2023 reply = dbus::Message::make_error(
2024 msg,
2025 mpris::Service::Errors::PlayerKeyNotFound::name(),
2026@@ -529,7 +530,7 @@
2027 // TODO(tvoss): These three elements really should be configurable.
2028 defaults.identity = "core::media::Hub";
2029 defaults.desktop_entry = "mediaplayer-app";
2030- defaults.supported_mime_types = {"audio/mpeg3"};
2031+ defaults.supported_mime_types = {"audio/mpeg3", "video/mpeg4"};
2032
2033 return defaults;
2034 }
2035@@ -668,7 +669,7 @@
2036
2037 void set_current_player(const std::shared_ptr<media::Player>& cp)
2038 {
2039- std::cout << "*** " << __PRETTY_FUNCTION__ << std::endl;
2040+ MH_TRACE("");
2041 // We will not keep the object alive.
2042 current_player = cp;
2043
2044@@ -784,7 +785,7 @@
2045
2046 void reset_current_player()
2047 {
2048- std::cout << __PRETTY_FUNCTION__ << std::endl;
2049+ MH_TRACE("");
2050 // And announce that we can no longer be controlled.
2051 player.properties.can_control->set(false);
2052 current_player.reset();
2053
2054=== modified file 'src/core/media/telephony/CMakeLists.txt'
2055--- src/core/media/telephony/CMakeLists.txt 2014-10-31 07:49:33 +0000
2056+++ src/core/media/telephony/CMakeLists.txt 2016-04-06 19:07:29 +0000
2057@@ -9,6 +9,7 @@
2058
2059 include_directories(
2060 ${TP_QT5_INCLUDE_DIRS}
2061+ ${PROJECT_SOURCE_DIR}/src/
2062 )
2063
2064 add_library(call-monitor STATIC
2065
2066=== modified file 'src/core/media/telephony/call_monitor.cpp'
2067--- src/core/media/telephony/call_monitor.cpp 2015-01-26 11:01:02 +0000
2068+++ src/core/media/telephony/call_monitor.cpp 2016-04-06 19:07:29 +0000
2069@@ -19,6 +19,8 @@
2070
2071 #include "call_monitor.h"
2072
2073+#include "core/media/logger/logger.h"
2074+
2075 #include "qtbridge.h"
2076 #include <TelepathyQt/AccountManager>
2077 #include <TelepathyQt/SimpleCallObserver>
2078@@ -95,7 +97,7 @@
2079
2080 void accountManagerReady(Tp::PendingOperation* operation) {
2081 if (operation->isError()) {
2082- std::cerr << "TelepathyBridge: Operation failed (accountManagerReady)" << std::endl;
2083+ MH_ERROR("TelepathyBridge: Operation failed (accountManagerReady)");
2084 QTimer::singleShot(1000, this, SLOT(accountManagerSetup())); // again
2085 return;
2086 }
2087@@ -118,13 +120,13 @@
2088
2089 void accountReady(Tp::PendingOperation* operation) {
2090 if (operation->isError()) {
2091- std::cerr << "TelepathyAccount: Operation failed (accountReady)" << std::endl;
2092+ MH_ERROR("TelepathyAccount: Operation failed (accountReady)");
2093 return;
2094 }
2095
2096 Tp::PendingReady* pendingReady = qobject_cast<Tp::PendingReady*>(operation);
2097 if (pendingReady == 0) {
2098- std::cerr << "Rejecting account because could not understand ready status" << std::endl;
2099+ MH_ERROR("Rejecting account because could not understand ready status");
2100 return;
2101 }
2102
2103@@ -176,16 +178,16 @@
2104 {
2105 qt::core::world::enter_with_task([this]()
2106 {
2107- std::cout << "CallMonitor: Creating TelepathyBridge" << std::endl;
2108+ MH_DEBUG("CallMonitor: Creating TelepathyBridge");
2109 mBridge = new TelepathyBridge();
2110 cv.notify_all();
2111 });
2112 });
2113 }));
2114 } catch(const std::system_error& error) {
2115- std::cerr << "exception(std::system_error) in CallMonitor thread start" << error.what() << std::endl;
2116+ MH_ERROR("exception(std::system_error) in CallMonitor thread start %s", error.what());
2117 } catch(...) {
2118- std::cerr << "exception(...) in CallMonitor thread start" << std::endl;
2119+ MH_ERROR("exception(...) in CallMonitor thread start");
2120 }
2121
2122 // Wait until telepathy bridge is set, so we can hook up the change signals
2123@@ -234,7 +236,7 @@
2124
2125 media::telephony::CallMonitor::Ptr media::telephony::make_platform_default_call_monitor()
2126 {
2127- return std::make_shared<impl::CallMonitor>();
2128+ return std::make_shared<::impl::CallMonitor>();
2129 }
2130
2131 #include "call_monitor.moc"
2132
2133=== modified file 'src/core/media/telephony/qtbridge.cpp'
2134--- src/core/media/telephony/qtbridge.cpp 2014-10-31 07:49:33 +0000
2135+++ src/core/media/telephony/qtbridge.cpp 2016-04-06 19:07:29 +0000
2136@@ -26,8 +26,6 @@
2137 #include<QThread>
2138 #include<QDebug>
2139
2140-#include <iostream>
2141-
2142 namespace
2143 {
2144 QCoreApplication* app = nullptr;
2145
2146=== modified file 'src/core/media/track_list_implementation.cpp'
2147--- src/core/media/track_list_implementation.cpp 2016-02-22 18:58:52 +0000
2148+++ src/core/media/track_list_implementation.cpp 2016-04-06 19:07:29 +0000
2149@@ -18,6 +18,7 @@
2150
2151 #include <algorithm>
2152 #include <random>
2153+#include <sstream>
2154 #include <stdio.h>
2155 #include <stdlib.h>
2156 #include <tuple>
2157@@ -29,6 +30,8 @@
2158
2159 #include "engine.h"
2160
2161+#include "core/media/logger/logger.h"
2162+
2163 namespace dbus = core::dbus;
2164 namespace media = core::ubuntu::media;
2165
2166@@ -125,14 +128,14 @@
2167 const media::Track::Id& position,
2168 bool make_current)
2169 {
2170- std::cout << __PRETTY_FUNCTION__ << std::endl;
2171+ MH_TRACE("");
2172
2173 std::stringstream ss;
2174 ss << d->object->path().as_string() << "/" << d->track_counter++;
2175 Track::Id id{ss.str()};
2176
2177- std::cout << "Adding Track::Id: " << id << std::endl;
2178- std::cout << "\tURI: " << uri << std::endl;
2179+ MH_DEBUG("Adding Track::Id: %s", id);
2180+ MH_DEBUG("\tURI: %s", uri);
2181
2182 const auto current = get_current_track();
2183
2184@@ -159,7 +162,7 @@
2185 set_current_track(current);
2186 }
2187
2188- std::cout << "Signaling that we just added track id: " << id << std::endl;
2189+ MH_DEBUG("Signaling that we just added track id: %s", id);
2190 // Signal to the client that a track was added to the TrackList
2191 on_track_added()(id);
2192
2193@@ -172,7 +175,7 @@
2194
2195 void media::TrackListImplementation::add_tracks_with_uri_at(const ContainerURI& uris, const Track::Id& position)
2196 {
2197- std::cout << __PRETTY_FUNCTION__ << std::endl;
2198+ MH_TRACE("");
2199
2200 const auto current = get_current_track();
2201
2202@@ -184,8 +187,8 @@
2203 std::stringstream ss;
2204 ss << d->object->path().as_string() << "/" << d->track_counter++;
2205 Track::Id id{ss.str()};
2206- std::cout << "Adding Track::Id: " << id << std::endl;
2207- std::cout << "\tURI: " << uri << std::endl;
2208+ MH_DEBUG("Adding Track::Id: %s", id);
2209+ MH_DEBUG("\tURI: %s", uri);
2210
2211 tmp.push_back(id);
2212
2213@@ -217,7 +220,7 @@
2214
2215 set_current_track(current);
2216
2217- std::cout << "Signaling that we just added " << tmp.size() << " tracks to the TrackList" << std::endl;
2218+ MH_DEBUG("Signaling that we just added %d tracks to the TrackList", tmp.size());
2219 on_tracks_added()(tmp);
2220
2221 if (!current_id.empty())
2222@@ -227,30 +230,30 @@
2223 bool media::TrackListImplementation::move_track(const media::Track::Id& id,
2224 const media::Track::Id& to)
2225 {
2226- std::cout << __PRETTY_FUNCTION__ << std::endl;
2227+ MH_TRACE("");
2228
2229- std::cout << "-----------------------------------------------------" << std::endl;
2230+ MH_DEBUG("-----------------------------------------------------");
2231 if (id.empty() or to.empty())
2232 {
2233- std::cerr << "Can't move track since 'id' or 'to' are empty" << std::endl;
2234+ MH_ERROR("Can't move track since 'id' or 'to' are empty");
2235 return false;
2236 }
2237
2238 if (id == to)
2239 {
2240- std::cerr << "Can't move track to it's same position" << std::endl;
2241+ MH_ERROR("Can't move track to it's same position");
2242 return false;
2243 }
2244
2245 if (tracks().get().size() == 1)
2246 {
2247- std::cerr << "Can't move track since TrackList contains only one track" << std::endl;
2248+ MH_ERROR("Can't move track since TrackList contains only one track");
2249 return false;
2250 }
2251
2252 bool ret = false;
2253 const media::Track::Id current_id = *current_iterator();
2254- std::cout << "current_track id: " << current_id << std::endl;
2255+ MH_DEBUG("current_track id: %s", current_id);
2256 // Get an iterator that points to the track that is the insertion point
2257 auto insert_point_it = std::find(tracks().get().begin(), tracks().get().end(), to);
2258 if (insert_point_it != tracks().get().end())
2259@@ -260,7 +263,6 @@
2260 {
2261 // Get an iterator that points to the track to move within the TrackList
2262 auto to_move_it = std::find(tracks().get().begin(), tracks().get().end(), id);
2263- std::cout << "Erasing old track position: " << *to_move_it << std::endl;
2264 if (to_move_it != tracks().get().end())
2265 {
2266 container.erase(to_move_it);
2267@@ -282,11 +284,11 @@
2268 {
2269 throw media::TrackList::Errors::FailedToMoveTrack();
2270 }
2271- std::cout << "*** Updated current_iterator, id: " << *current_iterator() << std::endl;
2272+ MH_DEBUG("*** Updated current_iterator, id: %s", *current_iterator());
2273 }
2274 else
2275 {
2276- std::cerr << "Can't update current_iterator - failed to find track after move" << std::endl;
2277+ MH_ERROR("Can't update current_iterator - failed to find track after move");
2278 throw media::TrackList::Errors::FailedToMoveTrack();
2279 }
2280
2281@@ -295,10 +297,10 @@
2282
2283 if (result)
2284 {
2285- std::cout << "TrackList after move" << std::endl;
2286- for(auto track : tracks().get())
2287+ MH_DEBUG("TrackList after move");
2288+ for(const auto track : tracks().get())
2289 {
2290- std::cout << track << std::endl;
2291+ MH_DEBUG("%s", track);
2292 }
2293 const media::TrackList::TrackIdTuple ids = std::make_tuple(id, to);
2294 // Signal to the client that track 'id' was moved within the TrackList
2295@@ -312,7 +314,7 @@
2296 ("Failed to find source track " + id);
2297 }
2298
2299- std::cout << "-----------------------------------------------------" << std::endl;
2300+ MH_DEBUG("-----------------------------------------------------");
2301
2302 return ret;
2303 }
2304@@ -345,7 +347,7 @@
2305
2306 void media::TrackListImplementation::go_to(const media::Track::Id& track)
2307 {
2308- std::cout << __PRETTY_FUNCTION__ << std::endl;
2309+ MH_TRACE("");
2310 // Signal the Player instance to go to a specific track for playback
2311 on_go_to_track()(track);
2312 on_track_changed()(track);
2313@@ -373,7 +375,7 @@
2314
2315 void media::TrackListImplementation::reset()
2316 {
2317- std::cout << __PRETTY_FUNCTION__ << std::endl;
2318+ MH_TRACE("");
2319
2320 // Make sure playback stops
2321 on_end_of_tracklist()();
2322
2323=== modified file 'src/core/media/track_list_skeleton.cpp'
2324--- src/core/media/track_list_skeleton.cpp 2016-02-22 16:16:52 +0000
2325+++ src/core/media/track_list_skeleton.cpp 2016-04-06 19:07:29 +0000
2326@@ -29,7 +29,9 @@
2327
2328 #include "mpris/player.h"
2329 #include "mpris/track_list.h"
2330+
2331 #include "util/uri_check.h"
2332+#include "core/media/logger/logger.h"
2333
2334 #include <core/dbus/object.h>
2335 #include <core/dbus/property.h>
2336@@ -40,7 +42,6 @@
2337
2338 #include <iostream>
2339 #include <limits>
2340-#include <sstream>
2341 #include <cstdint>
2342
2343 namespace dbus = core::dbus;
2344@@ -104,7 +105,7 @@
2345
2346 void handle_add_track_with_uri_at(const core::dbus::Message::Ptr& msg)
2347 {
2348- std::cout << "*** " << __PRETTY_FUNCTION__ << std::endl;
2349+ MH_TRACE("");
2350 request_context_resolver->resolve_context_for_dbus_name_async
2351 (msg->sender(), [this, msg](const media::apparmor::ubuntu::Context& context)
2352 {
2353@@ -124,7 +125,7 @@
2354 {
2355 const std::string err_str = {"Warning: Not adding track " + uri +
2356 " to TrackList because it can't be found."};
2357- std::cerr << err_str << std::endl;
2358+ MH_WARNING("%s", err_str.c_str());
2359 reply = dbus::Message::make_error(
2360 msg,
2361 mpris::Player::Error::UriNotFound::name,
2362@@ -141,7 +142,7 @@
2363 {
2364 const std::string err_str = {"Warning: Not adding track " + uri +
2365 " to TrackList because of inadequate client apparmor permissions."};
2366- std::cerr << err_str << std::endl;
2367+ MH_WARNING("%s", err_str.c_str());
2368 reply = dbus::Message::make_error(
2369 msg,
2370 mpris::TrackList::Error::InsufficientPermissionsToAddTrack::name,
2371@@ -155,7 +156,7 @@
2372
2373 void handle_add_tracks_with_uri_at(const core::dbus::Message::Ptr& msg)
2374 {
2375- std::cout << "*** " << __PRETTY_FUNCTION__ << std::endl;
2376+ MH_TRACE("");
2377 request_context_resolver->resolve_context_for_dbus_name_async
2378 (msg->sender(), [this, msg](const media::apparmor::ubuntu::Context& context)
2379 {
2380@@ -176,7 +177,7 @@
2381 {
2382 uri_err_str = {"Warning: Not adding track " + uri +
2383 " to TrackList because it can't be found."};
2384- std::cerr << uri_err_str << std::endl;
2385+ MH_WARNING("%s", uri_err_str.c_str());
2386 reply = dbus::Message::make_error(
2387 msg,
2388 mpris::Player::Error::UriNotFound::name,
2389@@ -201,7 +202,7 @@
2390 }
2391 else
2392 {
2393- std::cerr << err_str << std::endl;
2394+ MH_WARNING("%s", err_str.c_str());
2395 reply = dbus::Message::make_error(
2396 msg,
2397 mpris::TrackList::Error::InsufficientPermissionsToAddTrack::name,
2398@@ -225,7 +226,7 @@
2399 {
2400 const std::string err_str = {"Error: Not moving track " + id +
2401 " to destination " + to};
2402- std::cerr << err_str << std::endl;
2403+ MH_WARNING("%s", err_str.c_str());
2404 reply = dbus::Message::make_error(
2405 msg,
2406 mpris::TrackList::Error::FailedToMoveTrack::name,
2407@@ -262,9 +263,9 @@
2408
2409 auto id_it = find(impl->tracks().get().begin(), impl->tracks().get().end(), track);
2410 if (id_it == impl->tracks().get().end()) {
2411- ostringstream err_str;
2412+ stringstream err_str;
2413 err_str << "Track " << track << " not found in track list";
2414- cout << __PRETTY_FUNCTION__ << " WARNING " << err_str.str() << endl;
2415+ MH_WARNING("%s", err_str.str());
2416 auto reply = dbus::Message::make_error(
2417 msg,
2418 mpris::TrackList::Error::TrackNotFound::name,
2419@@ -278,7 +279,7 @@
2420
2421 if (id_it == impl->current_iterator())
2422 {
2423- cout << "Removing current track" << endl;
2424+ MH_DEBUG("Removing current track");
2425 deleting_current = true;
2426
2427 if (current_track != empty_iterator)
2428@@ -537,10 +538,10 @@
2429
2430 media::Track::Id media::TrackListSkeleton::next()
2431 {
2432- std::cout << __PRETTY_FUNCTION__ << std::endl;
2433+ MH_TRACE("");
2434 if (tracks().get().empty()) {
2435 // TODO Change ServiceSkeleton to return with error from DBus call
2436- std::cerr << "ERROR: no tracks, cannot go to next" << std::endl;
2437+ MH_ERROR("No tracks, cannot go to next");
2438 return media::Track::Id{};
2439 }
2440
2441@@ -549,13 +550,13 @@
2442 // End of the track reached so loop around to the beginning of the track
2443 if (d->loop_status == media::Player::LoopStatus::track)
2444 {
2445- std::cout << "Looping on the current track since LoopStatus is set to track" << std::endl;
2446+ MH_INFO("Looping on the current track since LoopStatus is set to track");
2447 go_to_track = true;
2448 }
2449 // End of the tracklist reached so loop around to the beginning of the tracklist
2450 else if (d->loop_status == media::Player::LoopStatus::playlist && not has_next())
2451 {
2452- std::cout << "Looping on the tracklist since LoopStatus is set to playlist" << std::endl;
2453+ MH_INFO("Looping on the tracklist since LoopStatus is set to playlist");
2454
2455 if (shuffle())
2456 {
2457@@ -574,7 +575,7 @@
2458 {
2459 auto it = get_current_shuffled();
2460 if (++it != shuffled_tracks().end()) {
2461- cout << "Advancing to next track: " << *it << endl;
2462+ MH_INFO("Advancing to next track: %s", *it);
2463 set_current_track(*it);
2464 go_to_track = true;
2465 }
2466@@ -584,7 +585,7 @@
2467 const auto it = std::next(current_iterator());
2468 if (not is_last_track(it))
2469 {
2470- cout << "Advancing to next track: " << *it << endl;
2471+ MH_INFO("Advancing to next track: %s", *it);
2472 d->current_track = it;
2473 go_to_track = true;
2474 }
2475@@ -594,7 +595,7 @@
2476
2477 if (go_to_track)
2478 {
2479- cout << "next track id is " << *(current_iterator()) << endl;
2480+ MH_DEBUG("next track id is %s", *(current_iterator()));
2481 on_track_changed()(*(current_iterator()));
2482 const media::Track::Id id = *(current_iterator());
2483 // Signal the PlayerImplementation to play the next track
2484@@ -603,7 +604,7 @@
2485 else
2486 {
2487 // At the end of the tracklist and not set to loop
2488- cout << "End of tracklist reached" << endl;
2489+ MH_INFO("End of tracklist reached");
2490 on_end_of_tracklist()();
2491 }
2492
2493@@ -612,10 +613,10 @@
2494
2495 media::Track::Id media::TrackListSkeleton::previous()
2496 {
2497- std::cout << __PRETTY_FUNCTION__ << std::endl;
2498+ MH_TRACE("");
2499 if (tracks().get().empty()) {
2500 // TODO Change ServiceSkeleton to return with error from DBus call
2501- std::cerr << "ERROR: no tracks, cannot go to previous" << std::endl;
2502+ MH_ERROR("No tracks, cannot go to previous");
2503 return media::Track::Id{};
2504 }
2505
2506@@ -627,19 +628,19 @@
2507 // repeat it from the beginning
2508 if (d->current_position > max_position)
2509 {
2510- std::cout << "Repeating current track..." << std::endl;
2511+ MH_INFO("Repeating current track...");
2512 go_to_track = true;
2513 }
2514 // Loop on the current track forever
2515 else if (d->loop_status == media::Player::LoopStatus::track)
2516 {
2517- std::cout << "Looping on the current track..." << std::endl;
2518+ MH_INFO("Looping on the current track...");
2519 go_to_track = true;
2520 }
2521 // Loop over the whole playlist and repeat
2522 else if (d->loop_status == media::Player::LoopStatus::playlist && not has_previous())
2523 {
2524- std::cout << "Looping on the entire TrackList..." << std::endl;
2525+ MH_INFO("Looping on the entire TrackList...");
2526
2527 if (shuffle())
2528 {
2529@@ -680,7 +681,7 @@
2530 else
2531 {
2532 // At the beginning of the tracklist and not set to loop
2533- cout << "Beginning of tracklist reached" << endl;
2534+ MH_INFO("Beginning of tracklist reached");
2535 on_end_of_tracklist()();
2536 }
2537
2538@@ -698,12 +699,12 @@
2539 // a segfault when calling current()
2540 if (tracks().get().size() && (d->current_track == d->empty_iterator))
2541 {
2542- std::cout << "Wrapping d->current_track back to begin()" << std::endl;
2543+ MH_DEBUG("Wrapping d->current_track back to begin()");
2544 d->current_track = d->skeleton.properties.tracks->get().begin();
2545 }
2546 else if (tracks().get().empty())
2547 {
2548- std::cerr << "TrackList is empty therefore there is no valid current track" << std::endl;
2549+ MH_ERROR("TrackList is empty therefore there is no valid current track");
2550 }
2551
2552 return d->current_track;
2553@@ -711,11 +712,10 @@
2554
2555 bool media::TrackListSkeleton::update_current_iterator(const TrackList::ConstIterator &it)
2556 {
2557- std::cout << __PRETTY_FUNCTION__ << std::endl;
2558+ MH_TRACE("");
2559 if (it == tracks().get().end())
2560 return false;
2561
2562- std::cout << "Updating current_track iterator" << std::endl;
2563 d->current_track = it;
2564
2565 return true;
2566@@ -780,8 +780,7 @@
2567
2568 void media::TrackListSkeleton::on_shuffle_changed(bool shuffle)
2569 {
2570- cout << __PRETTY_FUNCTION__ << endl;
2571-
2572+ MH_TRACE("");
2573 set_shuffle(shuffle);
2574 }
2575
2576@@ -793,7 +792,7 @@
2577 const core::Signal<media::TrackList::ContainerTrackIdTuple>& media::TrackListSkeleton::on_track_list_replaced() const
2578 {
2579 // Print the TrackList instance
2580- std::cout << *this << std::endl;
2581+ MH_DEBUG("%s", *this);
2582 return d->signals.on_track_list_replaced;
2583 }
2584
2585
2586=== modified file 'src/core/media/track_list_stub.cpp'
2587--- src/core/media/track_list_stub.cpp 2016-02-19 16:14:42 +0000
2588+++ src/core/media/track_list_stub.cpp 2016-04-06 19:07:29 +0000
2589@@ -28,6 +28,8 @@
2590 #include "mpris/player.h"
2591 #include "mpris/track_list.h"
2592
2593+#include "core/media/logger/logger.h"
2594+
2595 #include <core/dbus/property.h>
2596 #include <core/dbus/types/object_path.h>
2597 #include <core/dbus/types/variant.h>
2598@@ -111,43 +113,43 @@
2599 {
2600 dbus.on_track_added->connect([this](const Track::Id& id)
2601 {
2602- std::cout << "OnTrackAdded signal arrived via the bus." << std::endl;
2603+ MH_DEBUG("OnTrackAdded signal arrived via the bus.");
2604 on_track_added(id);
2605 });
2606
2607 dbus.on_tracks_added->connect([this](const media::TrackList::ContainerURI& tracks)
2608 {
2609- std::cout << "OnTracksAdded signal arrived via the bus." << std::endl;
2610+ MH_DEBUG("OnTracksAdded signal arrived via the bus.");
2611 on_tracks_added(tracks);
2612 });
2613
2614 dbus.on_track_moved->connect([this](const media::TrackList::TrackIdTuple& ids)
2615 {
2616- std::cout << "OnTrackMoved signal arrived via the bus." << std::endl;
2617+ MH_DEBUG("OnTrackMoved signal arrived via the bus.");
2618 on_track_moved(ids);
2619 });
2620
2621 dbus.on_track_removed->connect([this](const Track::Id& id)
2622 {
2623- std::cout << "OnTrackRemoved signal arrived via the bus." << std::endl;
2624+ MH_DEBUG("OnTrackRemoved signal arrived via the bus.");
2625 on_track_removed(id);
2626 });
2627
2628 dbus.on_track_list_reset->connect([this](void)
2629 {
2630- std::cout << "OnTrackListReset signal arrived via the bus." << std::endl;
2631+ MH_DEBUG("OnTrackListReset signal arrived via the bus.");
2632 on_track_list_reset();
2633 });
2634
2635 dbus.on_track_list_replaced->connect([this](const media::TrackList::ContainerTrackIdTuple& list)
2636 {
2637- std::cout << "OnTrackListReplaced signal arrived via the bus." << std::endl;
2638+ MH_DEBUG("OnTrackListReplaced signal arrived via the bus.");
2639 on_track_list_replaced(list);
2640 });
2641
2642 dbus.on_track_changed->connect([this](const Track::Id& id)
2643 {
2644- std::cout << "OnTrackChanged signal arrived via the bus." << std::endl;
2645+ MH_DEBUG("OnTrackChanged signal arrived via the bus.");
2646 on_track_changed(id);
2647 });
2648 }
2649
2650=== added file 'src/core/media/util/utils.cpp'
2651--- src/core/media/util/utils.cpp 1970-01-01 00:00:00 +0000
2652+++ src/core/media/util/utils.cpp 2016-04-06 19:07:29 +0000
2653@@ -0,0 +1,41 @@
2654+/*
2655+ * Copyright (C) 2016 Canonical, Ltd.
2656+ *
2657+ * This program is free software: you can redistribute it and/or modify it
2658+ * under the terms of the GNU General Public License version 3, as published
2659+ * by the Free Software Foundation.
2660+ *
2661+ * This program is distributed in the hope that it will be useful, but
2662+ * WITHOUT ANY WARRANTY; without even the implied warranties of
2663+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2664+ * PURPOSE. See the GNU General Public License for more details.
2665+ *
2666+ * You should have received a copy of the GNU General Public License along
2667+ * with this program. If not, see <http://www.gnu.org/licenses/>.
2668+ *
2669+ */
2670+
2671+#include <boost/filesystem.hpp>
2672+#include <boost/algorithm/string.hpp>
2673+
2674+#include <memory>
2675+#include <fstream>
2676+#include <sstream>
2677+
2678+#include <cstring>
2679+#include <cstdarg>
2680+
2681+#include "utils.h"
2682+
2683+namespace media = core::ubuntu::media;
2684+
2685+uint64_t media::Utils::GetNowNs() {
2686+ struct timespec ts;
2687+ memset(&ts, 0, sizeof(ts));
2688+ clock_gettime(CLOCK_MONOTONIC, &ts);
2689+ return ts.tv_sec * 1000000000LL + ts.tv_nsec;
2690+}
2691+
2692+uint64_t media::Utils::GetNowUs() {
2693+ return GetNowNs() / 1000;
2694+}
2695
2696=== added file 'src/core/media/util/utils.h'
2697--- src/core/media/util/utils.h 1970-01-01 00:00:00 +0000
2698+++ src/core/media/util/utils.h 2016-04-06 19:07:29 +0000
2699@@ -0,0 +1,69 @@
2700+/*
2701+ * Copyright (C) 2016 Canonical, Ltd.
2702+ *
2703+ * This program is free software: you can redistribute it and/or modify it
2704+ * under the terms of the GNU General Public License version 3, as published
2705+ * by the Free Software Foundation.
2706+ *
2707+ * This program is distributed in the hope that it will be useful, but
2708+ * WITHOUT ANY WARRANTY; without even the implied warranties of
2709+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2710+ * PURPOSE. See the GNU General Public License for more details.
2711+ *
2712+ * You should have received a copy of the GNU General Public License along
2713+ * with this program. If not, see <http://www.gnu.org/licenses/>.
2714+ *
2715+ */
2716+
2717+#ifndef UTILS_H_
2718+#define UTILS_H_
2719+
2720+#include <boost/format.hpp>
2721+
2722+#include <string>
2723+#include <vector>
2724+
2725+#define MCS_STR_VALUE(str) #str
2726+
2727+namespace core {
2728+namespace ubuntu {
2729+namespace media {
2730+typedef int64_t TimestampNs;
2731+typedef int64_t TimestampUs;
2732+struct Utils
2733+{
2734+ // Merely used as a namespace.
2735+ Utils() = delete;
2736+
2737+ // Sprintf - much like what you would expect :)
2738+ template<typename... Types>
2739+ static std::string Sprintf(const std::string& fmt_str, Types&&... args);
2740+ // GetEnv - returns a variable value from the environment
2741+ static uint64_t GetNowNs();
2742+ // GetNowUs - get a timestamp in microseconds
2743+ static uint64_t GetNowUs();
2744+};
2745+
2746+namespace impl {
2747+// Base case, just return the passed in boost::format instance.
2748+inline boost::format& Sprintf(boost::format& f)
2749+{
2750+ return f;
2751+}
2752+// Sprintf recursively walks the parameter pack at compile time.
2753+template <typename Head, typename... Tail>
2754+inline boost::format& Sprintf(boost::format& f, Head const& head, Tail&&... tail) {
2755+ return Sprintf(f % head, std::forward<Tail>(tail)...);
2756+}
2757+} // namespace impl
2758+} // namespace media
2759+} // namespace ubuntu
2760+} // namespace core
2761+
2762+template <typename... Types>
2763+inline std::string core::ubuntu::media::Utils::Sprintf(const std::string& format, Types&&... args) {
2764+ boost::format f(format);
2765+ return core::ubuntu::media::impl::Sprintf(f, std::forward<Types>(args)...).str();
2766+}
2767+
2768+#endif
2769
2770=== modified file 'src/core/media/video/platform_default_sink.cpp'
2771--- src/core/media/video/platform_default_sink.cpp 2015-01-29 12:12:43 +0000
2772+++ src/core/media/video/platform_default_sink.cpp 2016-04-06 19:07:29 +0000
2773@@ -36,7 +36,7 @@
2774 // and returns true or returns false and leaves 'matrix' unchanged in case
2775 // of issues.
2776 bool transformation_matrix(float*) const
2777- {
2778+ {
2779 return true;
2780 }
2781

Subscribers

People subscribed via source and target branches

to all changes: