pátek 21. listopadu 2014

Camera Confidentiality Conundrum

One of BABEL's features allows you to capture a photograph using your device's camera then send the image as an attachment. This ability is important for users so they can send images of documents or developing events to their contacts. Originally BABEL would use the device's native camera application to take the photo, however we discovered a serious security flaw with this approach. On many Android devices the native camera app would automatically save photos taken by BABEL, and if the user had cloud backup enabled would also upload them to their cloud service. Obviously this is an unacceptable privacy violation for BABEL so we needed to implement a solution.

The solution we came up with was to develop our own simple camera activity which BABEL could use to capture images. By controlling the image capturing process we can ensure that the photo stays private and is not saved outside of BABEL. This was not a simple task unfortunately, to recreate the vast set of features available in native camera apps would take an enormous amount of development time. So we had to aim to include only the most important camera features in our app.

The features we decided to include were auto-focus, zoom and flash. Auto-focus and Flash were relatively simple to implement using the Android camera API, but the zoom was slightly more complicated. Anybody used to touch-screen devices recognizes the pinch to zoom gesture, surprisingly there is no standard utility in the Android framework for this. So firstly we needed to implement a gesture detector for this that would control the camera's zoom level. Another issue we encountered was a large variance in the number of zoom levels available on each device, some cameras we tested supported 3-4 times as many zoom levels as others! To normalize the zoom behaviour across all devices we added scaling to our zoom gesture detector. Now if the user does a 'pinch' that travels half the length of the screen, the device will perform the maximum zoom change with smaller gestures performing a zoom relative to this maximum.

So with this new camera activity included in BABEL's next release can be confident that photos sent as attachments will remain private and not be accidentally leaked by a third party app. The need for a custom camera was an unanticipated problem which demonstrates the importance of our rigorous testing for each release. In the future we may revisit this custom camera to offer a better, more fully featured camera to BABEL users.

pátek 7. listopadu 2014

UIDocumentInteractionController in landscape mode

The whole iOS version of Babel works in portrait mode, but since we implemented attachments, we wanted to display attachment previews in landscape mode also. We tried it at first with UIDocumentInteractionController, which is displayed modally on UINavigationController.

So the whole app is in portrait mode and only UIDocumentInteractionController is in both portrait and landscape. It worked great, but when you at first turn the iphone to landscape and then display UIDocumentInteractionController, you will see the preview, but the navigation bar is missing. So you cannot get out of this screen, in iOS 8, it looks like this:




In iOS 7, it's ok:


We tried using QLPreviewViewController, but displaying it modally on UINavigationController was the same. Then we tried to push it on the navigation stack with pushViewController:animated and finally it worked on both iOS versions 7 and 8.


However there is one issue with QLPreviewViewController that only occurs in iOS 8 (iOS7 is ok). When you try to play some sound in this preview and turn to landscape, then when you go back (dismiss QLPreviewViewController), the sound continues playing. If you do the same thing in portrait, it stops playing.