From 140600d0ea8d9ed6bad1e4dc7512d6ec0b549174 Mon Sep 17 00:00:00 2001 From: Gary Mathews Date: Thu, 26 Mar 2020 16:34:34 -0700 Subject: [PATCH 1/4] fix(android): allow TiDownloadManager to fire fail listener --- .../titanium/util/TiDownloadManager.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java b/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java index 1d950931124..76abf8fb0a0 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java +++ b/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java @@ -6,6 +6,7 @@ */ package org.appcelerator.titanium.util; +import java.io.IOException; import java.io.InputStream; import java.lang.ref.SoftReference; import java.lang.reflect.Constructor; @@ -88,7 +89,7 @@ public void download(URI uri, TiDownloadListener listener) *

* Returns null if failed to download content or if given an invalid argument. */ - public InputStream blockingDownload(final URI uri) + public InputStream blockingDownload(final URI uri) throws Exception { // Validate. if (uri == null) { @@ -146,13 +147,7 @@ public void run() // Convert the given URI to a URL object. // Note: This object will validate the string and throw an exception if malformed. - URL url = null; - try { - url = new URL(uri.toString()); - } catch (Exception ex) { - Log.e(TAG, "Failed to parse URL: " + uri.toString(), ex); - return null; - } + URL url = new URL(uri.toString()); // Attempt to download the file. URLConnection connection = null; @@ -215,9 +210,6 @@ public void run() } break; } - } catch (Exception ex) { - // Failed to download file/content. - Log.e(TAG, "Failed to download from: " + uri.toString(), ex); } finally { // Close the connection if we don't have a stream to the response body. (Nothing to download.) if ((inputStream == null) && (connection instanceof HttpURLConnection)) { @@ -356,7 +348,7 @@ public void run() // fire a download fail event if we are unable to download sendMessage(uri, MSG_FIRE_DOWNLOAD_FAILED); - Log.e(TAG, "Exception downloading from: " + uri, e); + Log.e(TAG, "Exception downloading from: " + uri + "\n" + e.getMessage()); } } } From 03f5228022a721bba6ca15d703d9d89f5d6b2d9d Mon Sep 17 00:00:00 2001 From: Gary Mathews Date: Thu, 26 Mar 2020 16:42:38 -0700 Subject: [PATCH 2/4] fix(android): remove redundant import --- .../java/org/appcelerator/titanium/util/TiDownloadManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java b/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java index 76abf8fb0a0..6c44a82bb65 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java +++ b/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java @@ -6,7 +6,6 @@ */ package org.appcelerator.titanium.util; -import java.io.IOException; import java.io.InputStream; import java.lang.ref.SoftReference; import java.lang.reflect.Constructor; From e754615fe4d8143926fb9e8d58002ed8a10f341f Mon Sep 17 00:00:00 2001 From: Gary Mathews Date: Wed, 8 Apr 2020 17:33:42 -0700 Subject: [PATCH 3/4] test: include error event test --- tests/Resources/ti.ui.imageview.addontest.js | 55 ++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/Resources/ti.ui.imageview.addontest.js diff --git a/tests/Resources/ti.ui.imageview.addontest.js b/tests/Resources/ti.ui.imageview.addontest.js new file mode 100644 index 00000000000..df8e39f8d94 --- /dev/null +++ b/tests/Resources/ti.ui.imageview.addontest.js @@ -0,0 +1,55 @@ +/* + * Appcelerator Titanium Mobile + * Copyright (c) 2011-Present by Appcelerator, Inc. All Rights Reserved. + * Licensed under the terms of the Apache Public License + * Please see the LICENSE included with this distribution for details. + */ +/* eslint-env mocha */ +/* eslint no-unused-expressions: "off" */ +'use strict'; + +describe('Titanium.UI.ImageView', function () { + var win; + this.timeout(5000); + + afterEach(function (done) { + if (win) { + // If `win` is already closed, we're done. + let t = setTimeout(function () { + if (win) { + win = null; + done(); + } + }, 3000); + + win.addEventListener('close', function listener () { + clearTimeout(t); + + if (win) { + win.removeEventListener('close', listener); + } + win = null; + done(); + }); + win.close(); + } else { + win = null; + done(); + } + }); + + it('image error event', function (finish) { + win = Ti.UI.createWindow(); + + const img = Ti.UI.createImageView({ + image: 'https://invalid.host.com/image.jpg' + }); + + img.addEventListener('error', () => { + finish(); + }); + + win.add(img); + win.open(); + }); +}); From 3c8e3dec7ce3e9ee65a1d38ba2ef2b401f7596fb Mon Sep 17 00:00:00 2001 From: Gary Mathews Date: Wed, 15 Apr 2020 11:20:14 -0700 Subject: [PATCH 4/4] fix(android): throw exception from background thread --- .../titanium/util/TiDownloadManager.java | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java b/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java index 6c44a82bb65..7f9febc43ac 100644 --- a/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java +++ b/android/titanium/src/java/org/appcelerator/titanium/util/TiDownloadManager.java @@ -6,6 +6,9 @@ */ package org.appcelerator.titanium.util; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import java.io.InputStream; import java.lang.ref.SoftReference; import java.lang.reflect.Constructor; @@ -18,18 +21,13 @@ import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; - +import java.util.concurrent.atomic.AtomicReference; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; import org.appcelerator.kroll.common.Log; import org.appcelerator.kroll.util.KrollStreamHelper; -import org.appcelerator.titanium.io.TiInputStreamWrapper; import org.appcelerator.titanium.TiApplication; - -import android.os.Handler; -import android.os.Looper; -import android.os.Message; - -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSocketFactory; +import org.appcelerator.titanium.io.TiInputStreamWrapper; /** * Manages the asynchronous opening of InputStreams from URIs so that @@ -86,7 +84,7 @@ public void download(URI uri, TiDownloadListener listener) * @return * Returns a stream to the file/content being downloaded. *

- * Returns null if failed to download content or if given an invalid argument. + * Throws exception if failed to download content. */ public InputStream blockingDownload(final URI uri) throws Exception { @@ -113,33 +111,29 @@ public InputStream blockingDownload(final URI uri) throws Exception // Note: Using "HttpUrlConnection" on UI thread will cause a "NetworkOnMainThreadException" to be thrown. if (TiApplication.isUIThread()) { // Perform the blocking download on another thread. - // Downloaded content will be made available via Titanium's "TiResponseCache". - try { - Thread thread = new Thread(new Runnable() { - @Override - public void run() - { - try (InputStream stream = blockingDownload(uri)) { - if (stream != null) { - KrollStreamHelper.pump(stream, null); - } - } catch (Exception ex) { - Log.e(TAG, "Exception downloading from: " + uri.toString(), ex); - } + // Downloaded content will be made available via Titanium's "TiResponseCache" + AtomicReference exception = new AtomicReference<>(null); + Thread thread = new Thread(() -> { + try (InputStream stream = blockingDownload(uri)) { + if (stream != null) { + KrollStreamHelper.pump(stream, null); } - }); - thread.start(); - thread.join(); - } catch (Exception ex) { + } catch (Exception ex) { + exception.set(ex); + } + }); + thread.start(); + thread.join(); + + // Handle download thread exception. + if (exception.get() != null) { + throw exception.get(); } // Return a stream to the downloaded file/content via our response cache. URI cachedUri = TiResponseCache.fetchEndpointFollowingRedirects(uri); if (cachedUri != null) { - try { - inputStream = TiResponseCache.openCachedStream(cachedUri); - } catch (Exception ex) { - } + inputStream = TiResponseCache.openCachedStream(cachedUri); } return inputStream; }