Reworked and fixed pipeline error handling.
authorMohammed Sameer <msameer@foolab.org>
Mon, 24 Dec 2012 22:53:28 +0000 (00:53 +0200)
committerMohammed Sameer <msameer@foolab.org>
Mon, 24 Dec 2012 22:53:28 +0000 (00:53 +0200)
Each page can now implement cameraError() to do any cleanup when we get an error

qml/CameraPage.qml
qml/ImagePage.qml
qml/PipelineManager.qml
qml/RecordingPage.qml
qml/main.qml

index 6814d7f..5363a60 100644 (file)
@@ -43,6 +43,10 @@ Page {
 
         signal batteryLow
 
+        function cameraError() {
+                // Nothing
+        }
+
         function policyLost() {
                 // Nothing
         }
index 792d2c1..39e76d8 100644 (file)
@@ -34,6 +34,10 @@ CameraPage {
 
         orientationLock: PageOrientation.LockLandscape
 
+        function cameraError() {
+                mountProtector.unlock();
+        }
+
         function captureImage() {
                 if (!checkBattery()) {
                         showError(qsTr("Not enough battery to capture images."));
index e710a97..eb51bad 100644 (file)
@@ -36,6 +36,7 @@ Item {
 
         property Camera camera: null
         property Item currentPage: pageStack.currentPage
+        property bool error: false
 
         onCurrentPageChanged: {
                 if (state == "on" || state == "policyLost") {
@@ -48,6 +49,10 @@ Item {
         }
 
         function startCamera() {
+                if (error) {
+                        return;
+                }
+
                 if (!policy.acquire(currentPage.policyMode)) {
                         console.log("Failed to acquire policy resources");
                         return;
@@ -61,6 +66,7 @@ Item {
         function stopCamera() {
                 if (camera.stop(false)) {
                         policy.acquire(CameraResources.None);
+                        error = false;
                 }
         }
 
@@ -69,6 +75,7 @@ Item {
                 // when they become available
                 pageStack.currentPage.policyLost();
                 camera.stop(true);
+                error = false;
         }
 
         state: "off"
index a8ca768..eb0cc3d 100644 (file)
@@ -33,11 +33,23 @@ import "data.js" as Data
 CameraPage {
         id: page
         modesVisible: false
+        property bool error: false
+
+        policyMode: CameraResources.Recording
+
+        controlsVisible: cam.running && videoMode.recording && !cameraMode.animationRunning && !previewAnimationRunning && !error
+
+        orientationLock: PageOrientation.LockLandscape
 
         function policyLost() {
                 page.stopRecording();
         }
 
+        function cameraError() {
+                error = true;
+                page.stopRecording();
+        }
+
         Component.onDestruction: videoMode.stopRecording();
 
         onStatusChanged: {
@@ -76,15 +88,11 @@ CameraPage {
 
         function stopRecording() {
                 mountProtector.unlock();
-                pageStack.pop(undefined, true);
+                // Something is fishy here but if there is an error
+                // and we use immediate mode then the page never gets destroyed.
+                pageStack.pop(undefined, error ? false : true);
         }
 
-        policyMode: CameraResources.Recording
-
-        controlsVisible: cam.running && videoMode.recording && !cameraMode.animationRunning && !previewAnimationRunning
-
-        orientationLock: PageOrientation.LockLandscape
-
         DisplayState {
                 inhibitDim: true
         }
index 2a63321..3400488 100644 (file)
@@ -233,11 +233,21 @@ PageStackWindow {
                 }
 */
                 onError: {
-// TODO: seems we freeze here somehow
+                        if (pipelineManager.error) {
+                                // Ignore any subsequent errors.
+                                // Killing pulseaudio while recording will lead to an
+                                // infinite supply of errors which will break the UI
+                                // if we show a banner for each.
+                                return;
+                        }
+
+                        pipelineManager.error = true;
+                        pageStack.currentPage.cameraError();
                         console.log("Camera error (" + code + "): " + message + " " + debug);
                         showError(qsTr("Camera error. Please restart the application."));
-                        cam.stop();
-                        mountProtector.unlock();
+
+                        // We cannot stop camera here. Seems there is a race condition somewhere
+                        // which leads to a freeze if we do so.
                 }
 
                 onRunningChanged: {