Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(android): allow TiDownloadManager to fire fail listener #11575

Merged
merged 4 commits into from
Apr 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -86,9 +84,9 @@ public void download(URI uri, TiDownloadListener listener)
* @return
* Returns a stream to the file/content being downloaded.
* <p>
* 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)
public InputStream blockingDownload(final URI uri) throws Exception
garymathews marked this conversation as resolved.
Show resolved Hide resolved
{
// Validate.
if (uri == null) {
Expand All @@ -113,46 +111,36 @@ public InputStream blockingDownload(final URI uri)
// 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> 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;
}

garymathews marked this conversation as resolved.
Show resolved Hide resolved
// 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;
Expand Down Expand Up @@ -215,9 +203,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)) {
Expand Down Expand Up @@ -356,7 +341,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());
}
}
}
Expand Down
55 changes: 55 additions & 0 deletions tests/Resources/ti.ui.imageview.addontest.js
Original file line number Diff line number Diff line change
@@ -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();
});
});