UNPKG

com.rd11.remote-controls

Version:

iOS lock-screen remote-controls and now playing display.

406 lines (350 loc) 19.4 kB
/* * * 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. * */ /*jshint -W030 */ /*global Windows, WinJS*/ /*global module, require*/ var FTErr = require('./FileTransferError'), ProgressEvent = require('org.apache.cordova.file.ProgressEvent'), FileUploadResult = require('org.apache.cordova.file.FileUploadResult'), FileProxy = require('org.apache.cordova.file.FileProxy'), FileEntry = require('org.apache.cordova.file.FileEntry'); var appData = Windows.Storage.ApplicationData.current; // Some private helper functions, hidden by the module function cordovaPathToNative(path) { var cleanPath = String(path); // turn / into \\ cleanPath = cleanPath.replace(/\//g, '\\'); // turn \\ into \ cleanPath = cleanPath.replace(/\\\\/g, '\\'); // strip end \\ characters cleanPath = cleanPath.replace(/\\+$/g, ''); return cleanPath; } function nativePathToCordova(path) { return String(path).replace(/\\/g, '/'); } var fileTransferOps = []; function FileTransferOperation(state, promise) { this.state = state; this.promise = promise; } FileTransferOperation.PENDING = 0; FileTransferOperation.DONE = 1; FileTransferOperation.CANCELLED = 2; module.exports = { /* exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]); */ upload:function(successCallback, errorCallback, options) { var filePath = options[0]; var server = options[1]; var fileKey = options[2] || 'source'; var fileName = options[3]; var mimeType = options[4]; var params = options[5]; // var trustAllHosts = options[6]; // todo // var chunkedMode = options[7]; // todo var headers = options[8] || {}; var uploadId = options[9]; if (!filePath || (typeof filePath !== 'string')) { errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR,null,server)); return; } if (filePath.substr(0, 8) === "file:///") { filePath = appData.localFolder.path + filePath.substr(8).split("/").join("\\"); } else if (filePath.indexOf('ms-appdata:///') === 0) { // Handle 'ms-appdata' scheme filePath = filePath.replace('ms-appdata:///local', appData.localFolder.path) .replace('ms-appdata:///temp', appData.temporaryFolder.path); } // normalize path separators filePath = cordovaPathToNative(filePath); // Create internal download operation object fileTransferOps[uploadId] = new FileTransferOperation(FileTransferOperation.PENDING, null); Windows.Storage.StorageFile.getFileFromPathAsync(filePath) .then(function (storageFile) { if(!fileName) { fileName = storageFile.name; } if(!mimeType) { // use the actual content type of the file, probably this should be the default way. // other platforms probably can't look this up. mimeType = storageFile.contentType; } // check if download isn't already cancelled var uploadOp = fileTransferOps[uploadId]; if (uploadOp && uploadOp.state === FileTransferOperation.CANCELLED) { // Here we should call errorCB with ABORT_ERR error errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server)); return; } // setting request headers for uploader var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader(); for (var header in headers) { if (headers.hasOwnProperty(header)) { uploader.setRequestHeader(header, headers[header]); } } // adding params supplied to request payload var transferParts = []; for (var key in params) { if (params.hasOwnProperty(key)) { var contentPart = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart(); contentPart.setHeader("Content-Disposition", "form-data; name=\"" + key + "\""); contentPart.setText(params[key]); transferParts.push(contentPart); } } // Adding file to upload to request payload var fileToUploadPart = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart(fileKey, fileName); fileToUploadPart.setFile(storageFile); transferParts.push(fileToUploadPart); // create download object. This will throw an exception if URL is malformed var uri = new Windows.Foundation.Uri(server); try { uploader.createUploadAsync(uri, transferParts).then( function (upload) { // update internal TransferOperation object with newly created promise var uploadOperation = upload.startAsync(); fileTransferOps[uploadId].promise = uploadOperation; uploadOperation.then( function (result) { // Update TransferOperation object with new state, delete promise property // since it is not actual anymore var currentUploadOp = fileTransferOps[uploadId]; if (currentUploadOp) { currentUploadOp.state = FileTransferOperation.DONE; currentUploadOp.promise = null; } var response = result.getResponseInformation(); // creating a data reader, attached to response stream to get server's response var reader = new Windows.Storage.Streams.DataReader(result.getResultStreamAt(0)); reader.loadAsync(result.progress.bytesReceived).then(function(size) { var responseText = reader.readString(size); var ftResult = new FileUploadResult(size, response.statusCode, responseText); successCallback(ftResult); reader.close(); }); }, function (error) { var source = nativePathToCordova(filePath); // Handle download error here. // Wrap this routines into promise due to some async methods var getTransferError = new WinJS.Promise(function(resolve) { if (error.message === 'Canceled') { // If download was cancelled, message property will be specified resolve(new FTErr(FTErr.ABORT_ERR, source, server, null, null, error)); } else { // in the other way, try to get response property var response = upload.getResponseInformation(); if (!response) { resolve(new FTErr(FTErr.CONNECTION_ERR, source, server)); } else { var reader = new Windows.Storage.Streams.DataReader(upload.getResultStreamAt(0)); reader.loadAsync(upload.progress.bytesReceived).then(function (size) { var responseText = reader.readString(size); resolve(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, server, response.statusCode, responseText, error)); reader.close(); }); } } }); // Update TransferOperation object with new state, delete promise property // since it is not actual anymore var currentUploadOp = fileTransferOps[uploadId]; if (currentUploadOp) { currentUploadOp.state = FileTransferOperation.CANCELLED; currentUploadOp.promise = null; } // Cleanup, remove incompleted file getTransferError.then(function(transferError) { storageFile.deleteAsync().then(function() { errorCallback(transferError); }); }); }, function (evt) { var progressEvent = new ProgressEvent('progress', { loaded: evt.progress.bytesSent, total: evt.progress.totalBytesToSend, target: evt.resultFile }); progressEvent.lengthComputable = true; successCallback(progressEvent, { keepCallback: true }); } ); }, function (err) { var errorObj = new FTErr(FTErr.INVALID_URL_ERR); errorObj.exception = err; errorCallback(errorObj); } ); } catch (e) { errorCallback(new FTErr(FTErr.INVALID_URL_ERR)); } }, function(err) { errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, server, server, null, null, err)); }); }, // [source, target, trustAllHosts, id, headers] download:function(successCallback, errorCallback, options) { var source = options[0]; var target = options[1]; var downloadId = options[3]; var headers = options[4] || {}; if (!target) { errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR)); return; } if (target.substr(0, 8) === "file:///") { target = appData.localFolder.path + target.substr(8).split("/").join("\\"); } else if (target.indexOf('ms-appdata:///') === 0) { // Handle 'ms-appdata' scheme target = target.replace('ms-appdata:///local', appData.localFolder.path) .replace('ms-appdata:///temp', appData.temporaryFolder.path); } target = cordovaPathToNative(target); var path = target.substr(0, target.lastIndexOf("\\")); var fileName = target.substr(target.lastIndexOf("\\") + 1); if (path === null || fileName === null) { errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR)); return; } var download = null; // Create internal download operation object fileTransferOps[downloadId] = new FileTransferOperation(FileTransferOperation.PENDING, null); var downloadCallback = function(storageFolder) { storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.generateUniqueName).then(function(storageFile) { // check if download isn't already cancelled var downloadOp = fileTransferOps[downloadId]; if (downloadOp && downloadOp.state === FileTransferOperation.CANCELLED) { // Here we should call errorCB with ABORT_ERR error errorCallback(new FTErr(FTErr.ABORT_ERR, source, target)); return; } // if download isn't cancelled, contunue with creating and preparing download operation var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader(); for (var header in headers) { if (headers.hasOwnProperty(header)) { downloader.setRequestHeader(header, headers[header]); } } // create download object. This will throw an exception if URL is malformed try { var uri = Windows.Foundation.Uri(source); download = downloader.createDownload(uri, storageFile); } catch (e) { // so we handle this and call errorCallback errorCallback(new FTErr(FTErr.INVALID_URL_ERR)); return; } var downloadOperation = download.startAsync(); // update internal TransferOperation object with newly created promise fileTransferOps[downloadId].promise = downloadOperation; downloadOperation.then(function () { // Update TransferOperation object with new state, delete promise property // since it is not actual anymore var currentDownloadOp = fileTransferOps[downloadId]; if (currentDownloadOp) { currentDownloadOp.state = FileTransferOperation.DONE; currentDownloadOp.promise = null; } var nativeURI = storageFile.path.replace(appData.localFolder.path, 'ms-appdata:///local') .replace(appData.temporaryFolder.path, 'ms-appdata:///temp') .replace('\\', '/'); // Passing null as error callback here because downloaded file should exist in any case // otherwise the error callback will be hit during file creation in another place FileProxy.resolveLocalFileSystemURI(successCallback, null, [nativeURI]); }, function(error) { var getTransferError = new WinJS.Promise(function (resolve) { // Handle download error here. If download was cancelled, // message property will be specified if (error.message === 'Canceled') { resolve(new FTErr(FTErr.ABORT_ERR, source, target, null, null, error)); } else { // in the other way, try to get response property var response = download.getResponseInformation(); if (!response) { resolve(new FTErr(FTErr.CONNECTION_ERR, source, target)); } else { var reader = new Windows.Storage.Streams.DataReader(download.getResultStreamAt(0)); reader.loadAsync(download.progress.bytesReceived).then(function (bytesLoaded) { var payload = reader.readString(bytesLoaded); resolve(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, response.statusCode, payload, error)); }); } } }); getTransferError.then(function (fileTransferError) { // Update TransferOperation object with new state, delete promise property // since it is not actual anymore var currentDownloadOp = fileTransferOps[downloadId]; if (currentDownloadOp) { currentDownloadOp.state = FileTransferOperation.CANCELLED; currentDownloadOp.promise = null; } // Cleanup, remove incompleted file storageFile.deleteAsync().then(function() { errorCallback(fileTransferError); }); }); }, function(evt) { var progressEvent = new ProgressEvent('progress', { loaded: evt.progress.bytesReceived, total: evt.progress.totalBytesToReceive, target: evt.resultFile }); progressEvent.lengthComputable = true; successCallback(progressEvent, { keepCallback: true }); }); }, function(error) { errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, null, null, error)); }); }; var fileNotFoundErrorCallback = function(error) { errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, null, null, error)); }; Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(downloadCallback, function (error) { // Handle non-existent directory if (error.number === -2147024894) { var parent = path.substr(0, path.lastIndexOf('\\')), folderNameToCreate = path.substr(path.lastIndexOf('\\') + 1); Windows.Storage.StorageFolder.getFolderFromPathAsync(parent).then(function(parentFolder) { parentFolder.createFolderAsync(folderNameToCreate).then(downloadCallback, fileNotFoundErrorCallback); }, fileNotFoundErrorCallback); } else { fileNotFoundErrorCallback(); } }); }, abort: function (successCallback, error, options) { var fileTransferOpId = options[0]; // Try to find transferOperation with id specified, and cancel its' promise var currentOp = fileTransferOps[fileTransferOpId]; if (currentOp) { currentOp.state = FileTransferOperation.CANCELLED; currentOp.promise && currentOp.promise.cancel(); } } }; require("cordova/exec/proxy").add("FileTransfer",module.exports);