| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 | /*jshint node: true *//* global Q, resolveLocalFileSystemURL, Camera, cordova *//* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements.  See the NOTICE file * distributed with this work for additional information * regarding copyright ownership.  The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License.  You may obtain a copy of the License at * *   http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied.  See the License for the * specific language governing permissions and limitations * under the License. **/'use strict';var cameraConstants = require('../../www/CameraConstants');function findKeyByValue(set, value) {   for (var k in set) {      if (set.hasOwnProperty(k)) {         if (set[k] == value) {            return k;         }      }   }   return undefined;}function getDescription(spec) {    var desc = '';    desc += 'sourceType: ' + findKeyByValue(cameraConstants.PictureSourceType, spec.options.sourceType);    desc += ', destinationType: ' + findKeyByValue(cameraConstants.DestinationType, spec.options.destinationType);    desc += ', encodingType: ' + findKeyByValue(cameraConstants.EncodingType, spec.options.encodingType);    desc += ', allowEdit: ' + spec.options.allowEdit.toString();    desc += ', correctOrientation: ' + spec.options.correctOrientation.toString();    return desc;}module.exports.generateSpecs = function (sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions) {    var destinationType,        sourceType,        encodingType,        allowEdit,        correctOrientation,        specs = [],        id = 1;    for (destinationType in destinationTypes) {        if (destinationTypes.hasOwnProperty(destinationType)) {            for (sourceType in sourceTypes) {                if (sourceTypes.hasOwnProperty(sourceType)) {                    for (encodingType in encodingTypes) {                        if (encodingTypes.hasOwnProperty(encodingType)) {                            for (allowEdit in allowEditOptions) {                                if (allowEditOptions.hasOwnProperty(allowEdit)) {                                    for (correctOrientation in correctOrientationOptions) {                                        // if taking picture from photolibrary, don't vary 'correctOrientation' option                                        if ((sourceTypes[sourceType] === cameraConstants.PictureSourceType.PHOTOLIBRARY ||                                            sourceTypes[sourceType] === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM) &&                                            correctOrientation === true) { continue; }                                        var spec = {                                            'id': id++,                                            'options': {                                                'destinationType': destinationTypes[destinationType],                                                'sourceType': sourceTypes[sourceType],                                                'encodingType': encodingTypes[encodingType],                                                'allowEdit': allowEditOptions[allowEdit],                                                'saveToPhotoAlbum': false,                                                'correctOrientation': correctOrientationOptions[correctOrientation]                                            }                                        };                                        spec.description = getDescription(spec);                                        specs.push(spec);                                    }                                }                            }                        }                    }                }            }        }    }    return specs;};// calls getPicture() and saves the result in promise// note that this function is executed in the context of tested app// and not in the context of testsmodule.exports.getPicture = function (opts, pid) {    if (navigator._appiumPromises[pid - 1]) {        navigator._appiumPromises[pid - 1] = null;    }    navigator._appiumPromises[pid] = Q.defer();    navigator.camera.getPicture(function (result) {        navigator._appiumPromises[pid].resolve(result);    }, function (err) {        navigator._appiumPromises[pid].reject(err);    }, opts);};// verifies taken picture when the promise is resolved,// calls a callback with 'OK' if everything is good,// calls a callback with 'ERROR: <error message>' if something is wrong// note that this function is executed in the context of tested app// and not in the context of testsmodule.exports.checkPicture = function (pid, options, cb) {    var isIos = cordova.platformId === "ios";    var isAndroid = cordova.platformId === "android";    // skip image type check if it's unmodified on Android:    // https://github.com/apache/cordova-plugin-camera/#android-quirks-1    var skipFileTypeCheckAndroid = isAndroid && options.quality === 100 &&        !options.targetWidth && !options.targetHeight &&        !options.correctOrientation;    // Skip image type check if destination is NATIVE_URI and source - device's photoalbum    // https://github.com/apache/cordova-plugin-camera/#ios-quirks-1    var skipFileTypeCheckiOS = isIos && options.destinationType === Camera.DestinationType.NATIVE_URI &&        (options.sourceType === Camera.PictureSourceType.PHOTOLIBRARY ||         options.sourceType === Camera.PictureSourceType.SAVEDPHOTOALBUM);    var skipFileTypeCheck = skipFileTypeCheckAndroid || skipFileTypeCheckiOS;    var desiredType = 'JPEG';    var mimeType = 'image/jpeg';    if (options.encodingType === Camera.EncodingType.PNG) {        desiredType = 'PNG';        mimeType = 'image/png';    }    function errorCallback(msg) {        if (msg.hasOwnProperty('message')) {            msg = msg.message;        }        cb('ERROR: ' + msg);    }    // verifies the image we get from plugin    function verifyResult(result) {        if (result.length === 0) {            errorCallback('The result is empty.');            return;        } else if (isIos && options.destinationType === Camera.DestinationType.NATIVE_URI && result.indexOf('assets-library:') !== 0) {            errorCallback('Expected "' + result.substring(0, 150) + '"to start with "assets-library:"');            return;        } else if (isIos && options.destinationType === Camera.DestinationType.FILE_URI && result.indexOf('file:') !== 0) {            errorCallback('Expected "' + result.substring(0, 150) + '"to start with "file:"');            return;        }        try {            window.atob(result);            // if we got here it is a base64 string (DATA_URL)            result = "data:" + mimeType + ";base64," + result;        } catch (e) {            // not DATA_URL            if (options.destinationType === Camera.DestinationType.DATA_URL) {                errorCallback('Expected ' + result.substring(0, 150) + 'not to be DATA_URL');                return;            }        }        try {            if (result.indexOf('file:') === 0 ||                result.indexOf('content:') === 0 ||                result.indexOf('assets-library:') === 0) {                if (!window.resolveLocalFileSystemURL) {                    errorCallback('Cannot read file. Please install cordova-plugin-file to fix this.');                    return;                }                resolveLocalFileSystemURL(result, function (entry) {                    if (skipFileTypeCheck) {                        displayFile(entry);                    } else {                        verifyFile(entry);                    }                });            } else {                displayImage(result);            }        } catch (e) {            errorCallback(e);        }    }    // verifies that the file type matches the requested type    function verifyFile(entry) {        try {            var reader = new FileReader();            reader.onloadend = function(e) {                var arr = (new Uint8Array(e.target.result)).subarray(0, 4);                var header = '';                for(var i = 0; i < arr.length; i++) {                    header += arr[i].toString(16);                }                var actualType = 'unknown';                switch (header) {                    case "89504e47":                        actualType = 'PNG';                        break;                    case 'ffd8ffe0':                    case 'ffd8ffe1':                    case 'ffd8ffe2':                        actualType = 'JPEG';                        break;                }                if (actualType === desiredType) {                    displayFile(entry);                } else {                    errorCallback('File type mismatch. Expected ' + desiredType + ', got ' + actualType);                }            };            reader.onerror = function (e) {                errorCallback(e);            };            entry.file(function (file) {                reader.readAsArrayBuffer(file);            }, function (e) {                errorCallback(e);            });        } catch (e) {            errorCallback(e);        }    }    // reads the file, then displays the image    function displayFile(entry) {        function onFileReceived(file) {            var reader = new FileReader();            reader.onerror = function (e) {                errorCallback(e);            };            reader.onloadend = function (evt) {                displayImage(evt.target.result);            };            reader.readAsDataURL(file);        }        entry.file(onFileReceived, function (e) {            errorCallback(e);        });    }    function displayImage(image) {        try {            var imgEl = document.getElementById('camera_test_image');            if (!imgEl) {                imgEl = document.createElement('img');                imgEl.id = 'camera_test_image';                document.body.appendChild(imgEl);            }            var timedOut = false;            var loadTimeout = setTimeout(function () {                timedOut = true;                imgEl.src = '';                errorCallback('The image did not load: ' + image.substring(0, 150));            }, 10000);            var done = function (status) {                if (!timedOut) {                    clearTimeout(loadTimeout);                    imgEl.src = '';                    cb(status);                }            };            imgEl.onload = function () {                try {                    // aspect ratio is preserved so only one dimension should match                    if ((typeof options.targetWidth === 'number' && imgEl.naturalWidth !== options.targetWidth) &&                        (typeof options.targetHeight === 'number' && imgEl.naturalHeight !== options.targetHeight))                    {                        done('ERROR: Wrong image size: ' + imgEl.naturalWidth + 'x' + imgEl.naturalHeight +                            '. Requested size: ' + options.targetWidth + 'x' + options.targetHeight);                    } else {                        done('OK');                    }                } catch (e) {                    errorCallback(e);                }            };            imgEl.src = image;        } catch (e) {            errorCallback(e);        }    }    navigator._appiumPromises[pid].promise        .then(function (result) {            verifyResult(result);        })        .fail(function (e) {            errorCallback(e);        });};
 |