Merge lp:~phablet-team/qtubuntu-camera/fix-trust-prompt-bugs into lp:qtubuntu-camera/stable

Proposed by Jim Hodapp
Status: Merged
Approved by: Jim Hodapp
Approved revision: 153
Merged at revision: 149
Proposed branch: lp:~phablet-team/qtubuntu-camera/fix-trust-prompt-bugs
Merge into: lp:qtubuntu-camera/stable
Diff against target: 595 lines (+152/-136)
7 files modified
debian/changelog (+3/-3)
debian/control (+1/-1)
src/aalmediarecordercontrol.cpp (+115/-86)
src/aalmediarecordercontrol.h (+9/-5)
src/audiocapture.cpp (+13/-26)
src/audiocapture.h (+6/-10)
unittests/stubs/audiocapture_stub.cpp (+5/-5)
To merge this branch: bzr merge lp:~phablet-team/qtubuntu-camera/fix-trust-prompt-bugs
Reviewer Review Type Date Requested Status
Jim Hodapp (community) code Approve
Review via email: mp+268776@code.launchpad.net

Commit message

Refactor media recorder code to:
- ensure proper cleanups
- prevent double start/stop of recordings
- allow for soundless recordings
- do not start recording before microphone access is allowed/forbidden by user

Description of the change

Refactor media recorder code to:
- ensure proper cleanups
- prevent double start/stop of recordings
- allow for soundless recordings
- do not start recording before microphone access is allowed/forbidden by user

Fixes:
Bug #1487126: Camera/mic trust: initial video corrupt
Bug #1487131: Camera/mic trust: mic denial in camera-app freezes camera
Bug #1487159: revoking mic permission in system-settings, camera appears to record but video is unplayable

To post a comment you must log in.
149. By Florian Boucault

Refactor media recorder code to:
- ensure proper cleanups
- prevent double start/stop of recordings
- allow for soundless recordings
- do not start recording before microphone access is allowed/forbidden by user

150. By Florian Boucault

Slightly clearer if/else

151. By Jim Hodapp

Fix package version and libqtubuntu-media-signals-dev dependency version.

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

A few comments/questions inline.

review: Needs Fixing (code)
152. By Florian Boucault

Small status fix

153. By Florian Boucault

Reset m_audioCaptureAvailable in cleanup.

Revision history for this message
Florian Boucault (fboucault) :
154. By Florian Boucault

In the case of a timeout error signalled by pulseaudio when trying to use the microphone, be smart and prevent any further recording.

Revision history for this message
Jim Hodapp (jhodapp) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2015-07-10 18:12:33 +0000
3+++ debian/changelog 2015-08-21 20:10:16 +0000
4@@ -1,4 +1,4 @@
5-qtubuntu-camera (0.3.3+15.10.20150710-0ubuntu1) wily; urgency=medium
6+qtubuntu-camera (0.3.3+15.04.20150710-0ubuntu1) vivid; urgency=medium
7
8 [ CI Train Bot ]
9 * New rebuild forced.
10@@ -9,7 +9,7 @@
11
12 -- CI Train Bot <ci-train-bot@canonical.com> Fri, 10 Jul 2015 18:12:33 +0000
13
14-qtubuntu-camera (0.3.3+15.10.20150706-0ubuntu1) wily; urgency=medium
15+qtubuntu-camera (0.3.3+15.04.20150706-0ubuntu1) vivid; urgency=medium
16
17 [ Alberto Aguirre ]
18 * Remove dependency on platform-api. Use QScreen instead to obtain
19@@ -20,7 +20,7 @@
20
21 -- CI Train Bot <ci-train-bot@canonical.com> Mon, 06 Jul 2015 18:22:45 +0000
22
23-qtubuntu-camera (0.3.3+15.10.20150629-0ubuntu1) wily; urgency=medium
24+qtubuntu-camera (0.3.3+15.04.20150629-0ubuntu1) vivid; urgency=medium
25
26 [ Florian Boucault ]
27 * Write GPS location even if no altitude is given. (LP: #1447689)
28
29=== modified file 'debian/control'
30--- debian/control 2015-07-10 18:07:53 +0000
31+++ debian/control 2015-08-21 20:10:16 +0000
32@@ -8,7 +8,7 @@
33 libhybris-dev (>= 0.1.0+git20131207+e452e83-0ubuntu34),
34 libpulse-dev,
35 libqt5opengl5-dev,
36- libqtubuntu-media-signals-dev (>=0.3+15.10.20150618.1-0ubuntu1),
37+ libqtubuntu-media-signals-dev (>=0.3+15.04.20141104-0ubuntu1),
38 pkg-config,
39 qt5-default,
40 qtmultimedia5-dev,
41
42=== modified file 'src/aalmediarecordercontrol.cpp'
43--- src/aalmediarecordercontrol.cpp 2015-01-26 16:21:39 +0000
44+++ src/aalmediarecordercontrol.cpp 2015-08-21 20:10:16 +0000
45@@ -25,7 +25,6 @@
46 #include <QDebug>
47 #include <QFile>
48 #include <QFileInfo>
49-#include <QThread>
50 #include <QTimer>
51
52 #include <hybris/camera/camera_compatibility_layer.h>
53@@ -65,7 +64,7 @@
54 m_currentState(QMediaRecorder::StoppedState),
55 m_currentStatus(QMediaRecorder::UnloadedStatus),
56 m_recordingTimer(0),
57- m_workerThread(0)
58+ m_audioCaptureAvailable(false)
59 {
60 }
61
62@@ -83,6 +82,8 @@
63 << errno << ")";
64 }
65 deleteRecorder();
66+ m_audioCaptureThread.quit();
67+ m_audioCaptureThread.wait();
68 }
69
70 /*!
71@@ -158,76 +159,44 @@
72 /*!
73 * \brief Starts the main microphone reader/writer loop in AudioCapture (run)
74 */
75-void AalMediaRecorderControl::onStartThread()
76+void AalMediaRecorderControl::startAudioCaptureThread()
77 {
78- qDebug() << "Starting microphone reader/writer worker thread";
79- // Start the microphone read/write worker thread
80- m_workerThread->start();
81- Q_EMIT startWorkerThread();
82+ qDebug() << "Starting microphone reader/writer thread";
83+ // Start the microphone read/write thread
84+ m_audioCaptureThread.start();
85+ Q_EMIT audioCaptureThreadStarted();
86 }
87
88 /*!
89 * \brief AalMediaRecorderControl::init makes sure the mediarecorder is
90 * initialized
91 */
92-void AalMediaRecorderControl::initRecorder()
93+bool AalMediaRecorderControl::initRecorder()
94 {
95 if (m_mediaRecorder == 0) {
96 m_mediaRecorder = android_media_new_recorder();
97-
98- m_audioCapture = new AudioCapture(m_mediaRecorder);
99- m_workerThread = new QThread;
100-
101- if (m_audioCapture == 0) {
102- qWarning() << "Unable to create new audio capture, audio recording won't function";
103- Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "Unable to create new audio capture, audio recording won't function");
104- }
105- else
106- {
107- bool ret = false;
108-
109- // Make sure that m_audioCapture is executed within the m_workerThread affinity
110- m_audioCapture->moveToThread(m_workerThread);
111-
112- // Finished signal is for when the workerThread is completed. Important to connect this so that
113- // resources are cleaned up in the proper order and not leaked
114- ret = connect(m_audioCapture, SIGNAL(finished()), m_workerThread, SLOT(quit()));
115- if (!ret)
116- qWarning() << "Failed to connect quit() to the m_audioCapture finished signal";
117- ret = connect(m_audioCapture, SIGNAL(finished()), m_audioCapture, SLOT(deleteLater()));
118- if (!ret)
119- qWarning() << "Failed to connect deleteLater() to the m_audioCapture finished signal";
120- // Clean up the worker thread after we finish recording
121- ret = connect(m_workerThread, SIGNAL(finished()), m_workerThread, SLOT(deleteLater()));
122- if (!ret)
123- qWarning() << "Failed to connect deleteLater() to the m_workerThread finished signal";
124- // startWorkerThread signal comes from an Android layer callback that resides down in
125- // the AudioRecordHybris class
126- ret = connect(this, SIGNAL(startWorkerThread()), m_audioCapture, SLOT(run()));
127- if (!ret)
128- qWarning() << "Failed to connect run() to the local startWorkerThread signal";
129-
130- // Call onStartThreadCb when the reader side of the named pipe has been setup
131- m_audioCapture->init(&AalMediaRecorderControl::onStartThreadCb, this);
132- }
133-
134 if (m_mediaRecorder == 0) {
135 qWarning() << "Unable to create new media recorder";
136 Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "Unable to create new media recorder");
137+ return false;
138+ }
139+
140+ int audioInitError = initAudioCapture();
141+ if (audioInitError == 0) {
142+ m_audioCaptureAvailable = true;
143 } else {
144- setStatus(QMediaRecorder::LoadedStatus);
145- android_recorder_set_error_cb(m_mediaRecorder, &AalMediaRecorderControl::errorCB, this);
146- android_camera_unlock(m_service->androidControl());
147+ m_audioCaptureAvailable = false;
148+ if (audioInitError == AudioCapture::AUDIO_CAPTURE_TIMEOUT_ERROR) {
149+ deleteRecorder();
150+ return false;
151+ }
152 }
153- }
154-
155- if (m_recordingTimer == 0) {
156- m_recordingTimer = new QTimer(this);
157- m_recordingTimer->setInterval(DURATION_UPDATE_INTERVAL);
158- m_recordingTimer->setSingleShot(false);
159- QObject::connect(m_recordingTimer, SIGNAL(timeout()),
160- this, SLOT(updateDuration()));
161- }
162+
163+ android_recorder_set_error_cb(m_mediaRecorder, &AalMediaRecorderControl::errorCB, this);
164+ android_camera_unlock(m_service->androidControl());
165+ }
166+
167+ return true;
168 }
169
170 /*!
171@@ -236,6 +205,8 @@
172 */
173 void AalMediaRecorderControl::deleteRecorder()
174 {
175+ deleteAudioCapture();
176+
177 if (m_mediaRecorder == 0)
178 return;
179
180@@ -245,6 +216,43 @@
181 setStatus(QMediaRecorder::UnloadedStatus);
182 }
183
184+int AalMediaRecorderControl::initAudioCapture()
185+{
186+ // setting up audio recording; m_audioCapture is executed within the m_workerThread affinity
187+ m_audioCapture = new AudioCapture(m_mediaRecorder);
188+ int audioInitError = m_audioCapture->setupMicrophoneStream();
189+ if (audioInitError != 0)
190+ {
191+ qWarning() << "Failed to setup PulseAudio microphone recording stream";
192+ delete m_audioCapture;
193+ m_audioCapture = 0;
194+ } else {
195+ m_audioCapture->moveToThread(&m_audioCaptureThread);
196+
197+ // startWorkerThread signal comes from an Android layer callback that resides down in
198+ // the AudioRecordHybris class
199+ connect(this, SIGNAL(audioCaptureThreadStarted()), m_audioCapture, SLOT(run()));
200+
201+ // Call recorderReadAudioCallback when the reader side of the named pipe has been setup
202+ m_audioCapture->init(&AalMediaRecorderControl::recorderReadAudioCallback, this);
203+ }
204+ return audioInitError;
205+}
206+
207+void AalMediaRecorderControl::deleteAudioCapture()
208+{
209+ if (m_audioCapture == 0)
210+ return;
211+
212+ m_audioCapture->stopCapture();
213+ m_audioCaptureThread.quit();
214+ m_audioCaptureThread.wait();
215+
216+ delete m_audioCapture;
217+ m_audioCapture = 0;
218+ m_audioCaptureAvailable = false;
219+}
220+
221 /*!
222 * \brief AalMediaRecorderControl::errorCB handles errors from the android layer
223 * \param context
224@@ -285,10 +293,7 @@
225
226 switch (state) {
227 case QMediaRecorder::RecordingState: {
228- int ret = startRecording();
229- if (ret == -1) {
230- setStatus(QMediaRecorder::LoadedStatus);
231- }
232+ startRecording();
233 break;
234 }
235 case QMediaRecorder::StoppedState: {
236@@ -349,17 +354,21 @@
237 return RECORDER_INITIALIZATION_ERROR;
238 }
239
240+ if (m_currentStatus != QMediaRecorder::UnloadedStatus) {
241+ qWarning() << "Can't start a recording while another one is in progess";
242+ return RECORDER_NOT_AVAILABLE_ERROR;
243+ }
244+
245+ setStatus(QMediaRecorder::LoadingStatus);
246+
247 m_duration = 0;
248 Q_EMIT durationChanged(m_duration);
249
250- initRecorder();
251- if (m_mediaRecorder == 0) {
252- deleteRecorder();
253+ if (!initRecorder()) {
254+ setStatus(QMediaRecorder::UnloadedStatus);
255 return RECORDER_NOT_AVAILABLE_ERROR;
256 }
257
258- setStatus(QMediaRecorder::StartingStatus);
259-
260 QVideoEncoderSettings videoSettings = m_service->videoEncoderControl()->videoSettings();
261
262 int ret;
263@@ -369,12 +378,15 @@
264 Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setCamera() failed\n");
265 return RECORDER_INITIALIZATION_ERROR;
266 }
267- //state initial / idle
268- ret = android_recorder_setAudioSource(m_mediaRecorder, ANDROID_AUDIO_SOURCE_CAMCORDER);
269- if (ret < 0) {
270- deleteRecorder();
271- Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setAudioSource() failed");
272- return RECORDER_INITIALIZATION_ERROR;
273+ // state initial / idle
274+ if (m_audioCaptureAvailable) {
275+ ret = android_recorder_setAudioSource(m_mediaRecorder, ANDROID_AUDIO_SOURCE_CAMCORDER);
276+ if (ret < 0) {
277+ deleteRecorder();
278+ Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setAudioSource() failed");
279+ return RECORDER_INITIALIZATION_ERROR;
280+ }
281+
282 }
283 ret = android_recorder_setVideoSource(m_mediaRecorder, ANDROID_VIDEO_SOURCE_CAMERA);
284 if (ret < 0) {
285@@ -382,19 +394,21 @@
286 Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setVideoSource() failed");
287 return RECORDER_INITIALIZATION_ERROR;
288 }
289- //state initialized
290+ // state initialized
291 ret = android_recorder_setOutputFormat(m_mediaRecorder, ANDROID_OUTPUT_FORMAT_MPEG_4);
292 if (ret < 0) {
293 deleteRecorder();
294 Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setOutputFormat() failed");
295 return RECORDER_INITIALIZATION_ERROR;
296 }
297- //state DataSourceConfigured
298- ret = android_recorder_setAudioEncoder(m_mediaRecorder, ANDROID_AUDIO_ENCODER_AAC);
299- if (ret < 0) {
300- deleteRecorder();
301- Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setAudioEncoder() failed");
302- return RECORDER_INITIALIZATION_ERROR;
303+ // state DataSourceConfigured
304+ if (m_audioCaptureAvailable) {
305+ ret = android_recorder_setAudioEncoder(m_mediaRecorder, ANDROID_AUDIO_ENCODER_AAC);
306+ if (ret < 0) {
307+ deleteRecorder();
308+ Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setAudioEncoder() failed");
309+ return RECORDER_INITIALIZATION_ERROR;
310+ }
311 }
312 // FIXME set codec from settings
313 ret = android_recorder_setVideoEncoder(m_mediaRecorder, ANDROID_VIDEO_ENCODER_H264);
314@@ -466,7 +480,11 @@
315 Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_prepare() failed");
316 return RECORDER_INITIALIZATION_ERROR;
317 }
318- //state prepared
319+
320+ setStatus(QMediaRecorder::LoadedStatus);
321+ setStatus(QMediaRecorder::StartingStatus);
322+
323+ // state prepared
324 ret = android_recorder_start(m_mediaRecorder);
325 if (ret < 0) {
326 close(m_outfd);
327@@ -481,6 +499,13 @@
328
329 setStatus(QMediaRecorder::RecordingStatus);
330
331+ if (m_recordingTimer == 0) {
332+ m_recordingTimer = new QTimer(this);
333+ m_recordingTimer->setInterval(DURATION_UPDATE_INTERVAL);
334+ m_recordingTimer->setSingleShot(false);
335+ QObject::connect(m_recordingTimer, SIGNAL(timeout()),
336+ this, SLOT(updateDuration()));
337+ }
338 m_recordingTimer->start();
339
340 return 0;
341@@ -496,8 +521,9 @@
342 qWarning() << "Can't stop recording properly, m_mediaRecorder is NULL";
343 return;
344 }
345- if (m_audioCapture == 0) {
346- qWarning() << "Can't stop recording properly, m_audioCapture is NULL";
347+
348+ if (m_currentStatus != QMediaRecorder::RecordingStatus) {
349+ qWarning() << "Can't stop a recording that has not started";
350 return;
351 }
352
353@@ -514,7 +540,9 @@
354 // NOTE: This must come after the android_recorder_stop call, otherwise the
355 // RecordThread instance will block the MPEG4Writer pthread_join when trying to
356 // cleanly stop recording.
357- m_audioCapture->stopCapture();
358+ if (m_audioCapture != 0) {
359+ m_audioCapture->stopCapture();
360+ }
361
362 android_recorder_reset(m_mediaRecorder);
363
364@@ -542,9 +570,10 @@
365 android_recorder_setParameters(m_mediaRecorder, param.toLocal8Bit().data());
366 }
367
368-void AalMediaRecorderControl::onStartThreadCb(void *context)
369+void AalMediaRecorderControl::recorderReadAudioCallback(void *context)
370 {
371 AalMediaRecorderControl *thiz = static_cast<AalMediaRecorderControl*>(context);
372- if (thiz != NULL)
373- thiz->onStartThread();
374+ if (thiz != NULL) {
375+ thiz->startAudioCaptureThread();
376+ }
377 }
378
379=== modified file 'src/aalmediarecordercontrol.h'
380--- src/aalmediarecordercontrol.h 2015-01-23 02:49:03 +0000
381+++ src/aalmediarecordercontrol.h 2015-08-21 20:10:16 +0000
382@@ -21,6 +21,7 @@
383 #include <QMediaRecorderControl>
384 #include <QSize>
385 #include <QUrl>
386+#include <QThread>
387
388 #include <stdint.h>
389
390@@ -58,23 +59,25 @@
391 virtual void setMuted(bool muted);
392 virtual void setState(QMediaRecorder::State state);
393 virtual void setVolume(qreal gain);
394- void onStartThread();
395+ void startAudioCaptureThread();
396
397 signals:
398- void startWorkerThread();
399+ void audioCaptureThreadStarted();
400
401 private Q_SLOTS:
402 virtual void updateDuration();
403 void handleError();
404+ void deleteAudioCapture();
405
406 private:
407- void initRecorder();
408+ bool initRecorder();
409 void deleteRecorder();
410+ int initAudioCapture();
411 void setStatus(QMediaRecorder::Status status);
412 int startRecording();
413 void stopRecording();
414 void setParameter(const QString &parameter, int value);
415- static void onStartThreadCb(void *context);
416+ static void recorderReadAudioCallback(void *context);
417
418 AalCameraService *m_service;
419 MediaRecorderWrapper *m_mediaRecorder;
420@@ -85,7 +88,8 @@
421 QMediaRecorder::State m_currentState;
422 QMediaRecorder::Status m_currentStatus;
423 QTimer *m_recordingTimer;
424- QThread *m_workerThread;
425+ QThread m_audioCaptureThread;
426+ bool m_audioCaptureAvailable;
427
428 static const int RECORDER_GENERAL_ERROR = -1;
429 static const int RECORDER_NOT_AVAILABLE_ERROR = -2;
430
431=== modified file 'src/audiocapture.cpp'
432--- src/audiocapture.cpp 2014-12-03 17:08:38 +0000
433+++ src/audiocapture.cpp 2015-08-21 20:10:16 +0000
434@@ -37,6 +37,8 @@
435
436 AudioCapture::~AudioCapture()
437 {
438+ android_recorder_set_audio_read_cb(m_mediaRecorder, NULL, NULL);
439+
440 if (m_audioPipe >= 0)
441 close(m_audioPipe);
442 if (m_paStream != NULL)
443@@ -46,10 +48,10 @@
444 /*!
445 * \brief Initializes AudioCapture so that it's ready to read microphone data from Pulseaudio
446 */
447-bool AudioCapture::init(StartWorkerThreadCb cb, void *context)
448+bool AudioCapture::init(RecorderReadAudioCallback callback, void *context)
449 {
450- // The MediaRecorderLayer will call method (cb) when it's ready to encode a new audio buffer
451- android_recorder_set_audio_read_cb(m_mediaRecorder, cb, context);
452+ // The MediaRecorderLayer will call method (callback) when it's ready to encode a new audio buffer
453+ android_recorder_set_audio_read_cb(m_mediaRecorder, callback, context);
454
455 return true;
456 }
457@@ -68,17 +70,12 @@
458 */
459 void AudioCapture::run()
460 {
461+ m_flagExit = false;
462 qDebug() << __PRETTY_FUNCTION__;
463
464 int bytesWritten = 0, bytesRead = 0;
465 const size_t readSize = sizeof(m_audioBuf);
466
467- if (!setupMicrophoneStream())
468- {
469- qWarning() << "Failed to setup PulseAudio microphone recording stream";
470- return;
471- }
472-
473 if (!setupPipe())
474 {
475 qWarning() << "Failed to open /dev/socket/micshm, cannot write data to pipe";
476@@ -101,8 +98,6 @@
477 pa_simple_free(m_paStream);
478 m_paStream = NULL;
479 }
480-
481- Q_EMIT finished();
482 }
483
484 /*!
485@@ -122,21 +117,9 @@
486 }
487
488 /*!
489- * \brief Signals AalMediaRecorderControl to start the main thread loop.
490- * \detail This is necessary due to thread contexts. Starting of the main thread loop
491- * for AudioCapture must be done in the main thread context and not in the AudioCapture
492- * thread context, otherwise the loop start signal will never be seen.
493- */
494-void AudioCapture::startThreadLoop()
495-{
496- Q_EMIT startThread();
497- qDebug() << "Emitted startThread(), should start reading from mic";
498-}
499-
500-/*!
501 * \brief Sets up the Pulseaudio microphone input channel
502 */
503-bool AudioCapture::setupMicrophoneStream()
504+int AudioCapture::setupMicrophoneStream()
505 {
506 // FIXME: Get these parameters more dynamically from the control
507 static const pa_sample_spec ss = {
508@@ -150,10 +133,14 @@
509 if (m_paStream == NULL)
510 {
511 qWarning() << "Failed to open a PulseAudio channel to read the microphone: " << pa_strerror(error);
512- return false;
513+ if (error == PA_ERR_TIMEOUT) {
514+ return AUDIO_CAPTURE_TIMEOUT_ERROR;
515+ } else {
516+ return AUDIO_CAPTURE_GENERAL_ERROR;
517+ }
518 }
519
520- return true;
521+ return 0;
522 }
523
524 /*!
525
526=== modified file 'src/audiocapture.h'
527--- src/audiocapture.h 2014-07-30 14:50:39 +0000
528+++ src/audiocapture.h 2015-08-21 20:10:16 +0000
529@@ -34,28 +34,24 @@
530 {
531 Q_OBJECT
532
533- typedef void (*StartWorkerThreadCb)(void *context);
534+ typedef void (*RecorderReadAudioCallback)(void *context);
535 public:
536+ static const int AUDIO_CAPTURE_GENERAL_ERROR = -1;
537+ static const int AUDIO_CAPTURE_TIMEOUT_ERROR = -2;
538+
539 explicit AudioCapture(MediaRecorderWrapper *mediaRecorder);
540 ~AudioCapture();
541
542- bool init(StartWorkerThreadCb cb, void *context);
543+ bool init(RecorderReadAudioCallback callback, void *context);
544 /* Terminates the Pulseaudio reader/writer QThread */
545+ int setupMicrophoneStream();
546 void stopCapture();
547
548-signals:
549- void startThread();
550- void finished();
551-
552 public Q_SLOTS:
553 void run();
554
555-private Q_SLOTS:
556- void startThreadLoop();
557-
558 private:
559 int readMicrophone();
560- bool setupMicrophoneStream();
561 bool setupPipe();
562 ssize_t loopWrite(int fd, const void *data, size_t len);
563 int writeDataToPipe();
564
565=== modified file 'unittests/stubs/audiocapture_stub.cpp'
566--- unittests/stubs/audiocapture_stub.cpp 2014-07-30 14:50:39 +0000
567+++ unittests/stubs/audiocapture_stub.cpp 2015-08-21 20:10:16 +0000
568@@ -29,7 +29,7 @@
569 {
570 }
571
572-bool AudioCapture::init(StartWorkerThreadCb cb, void *context)
573+bool AudioCapture::init(RecorderReadAudioCallback cb, void *context)
574 {
575 Q_UNUSED(cb);
576 Q_UNUSED(context);
577@@ -40,14 +40,14 @@
578 {
579 }
580
581+int AudioCapture::setupMicrophoneStream()
582+{
583+}
584+
585 void AudioCapture::run()
586 {
587 }
588
589-void AudioCapture::startThreadLoop()
590-{
591-}
592-
593 int AudioCapture::readMicrophone()
594 {
595 return 0;

Subscribers

People subscribed via source and target branches

to all changes: