|
|
|
@ -99,6 +99,29 @@ public class DownloaderService extends Service {
|
|
|
|
|
private static final String ACTION_QUEUE = "org.fdroid.fdroid.net.DownloaderService.action.QUEUE";
|
|
|
|
|
private static final String ACTION_CANCEL = "org.fdroid.fdroid.net.DownloaderService.action.CANCEL";
|
|
|
|
|
|
|
|
|
|
public static final String ACTION_STARTED = "org.fdroid.fdroid.net.Downloader.action.STARTED";
|
|
|
|
|
public static final String ACTION_PROGRESS = "org.fdroid.fdroid.net.Downloader.action.PROGRESS";
|
|
|
|
|
public static final String ACTION_INTERRUPTED = "org.fdroid.fdroid.net.Downloader.action.INTERRUPTED";
|
|
|
|
|
public static final String ACTION_CONNECTION_FAILED = "org.fdroid.fdroid.net.Downloader.action.CONNECTION_FAILED";
|
|
|
|
|
public static final String ACTION_COMPLETE = "org.fdroid.fdroid.net.Downloader.action.COMPLETE";
|
|
|
|
|
|
|
|
|
|
public static final String EXTRA_DOWNLOAD_PATH = "org.fdroid.fdroid.net.Downloader.extra.DOWNLOAD_PATH";
|
|
|
|
|
public static final String EXTRA_BYTES_READ = "org.fdroid.fdroid.net.Downloader.extra.BYTES_READ";
|
|
|
|
|
public static final String EXTRA_TOTAL_BYTES = "org.fdroid.fdroid.net.Downloader.extra.TOTAL_BYTES";
|
|
|
|
|
public static final String EXTRA_ERROR_MESSAGE = "org.fdroid.fdroid.net.Downloader.extra.ERROR_MESSAGE";
|
|
|
|
|
public static final String EXTRA_REPO_ID = "org.fdroid.fdroid.net.Downloader.extra.REPO_ID";
|
|
|
|
|
public static final String EXTRA_MIRROR_URL = "org.fdroid.fdroid.net.Downloader.extra.MIRROR_URL";
|
|
|
|
|
/**
|
|
|
|
|
* Unique ID used to represent this specific package's install process,
|
|
|
|
|
* including {@link android.app.Notification}s, also known as {@code canonicalUrl}.
|
|
|
|
|
* Careful about types, this should always be a {@link String}, so it can
|
|
|
|
|
* be handled on the receiving side by {@link android.content.Intent#getStringArrayExtra(String)}.
|
|
|
|
|
*
|
|
|
|
|
* @see org.fdroid.fdroid.installer.InstallManagerService
|
|
|
|
|
* @see android.content.Intent#EXTRA_ORIGINATING_URI
|
|
|
|
|
*/
|
|
|
|
|
public static final String EXTRA_CANONICAL_URL = "org.fdroid.fdroid.net.Downloader.extra.CANONICAL_URL";
|
|
|
|
|
|
|
|
|
|
private volatile Looper serviceLooper;
|
|
|
|
|
private static volatile ServiceHandler serviceHandler;
|
|
|
|
|
private static volatile Downloader downloader;
|
|
|
|
@ -149,7 +172,7 @@ public class DownloaderService extends Service {
|
|
|
|
|
Utils.debugLog(TAG, "Received Intent with no URI: " + intent);
|
|
|
|
|
return START_NOT_STICKY;
|
|
|
|
|
}
|
|
|
|
|
String canonicalUrl = intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL);
|
|
|
|
|
String canonicalUrl = intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL);
|
|
|
|
|
if (canonicalUrl == null) {
|
|
|
|
|
Utils.debugLog(TAG, "Received Intent with no EXTRA_CANONICAL_URL: " + intent);
|
|
|
|
|
return START_NOT_STICKY;
|
|
|
|
@ -218,10 +241,10 @@ public class DownloaderService extends Service {
|
|
|
|
|
*/
|
|
|
|
|
private void handleIntent(Intent intent) {
|
|
|
|
|
final Uri uri = intent.getData();
|
|
|
|
|
final long repoId = intent.getLongExtra(Downloader.EXTRA_REPO_ID, 0);
|
|
|
|
|
final Uri canonicalUrl = Uri.parse(intent.getStringExtra(Downloader.EXTRA_CANONICAL_URL));
|
|
|
|
|
final long repoId = intent.getLongExtra(DownloaderService.EXTRA_REPO_ID, 0);
|
|
|
|
|
final Uri canonicalUrl = Uri.parse(intent.getStringExtra(DownloaderService.EXTRA_CANONICAL_URL));
|
|
|
|
|
final SanitizedFile localFile = ApkCache.getApkDownloadPath(this, canonicalUrl);
|
|
|
|
|
sendBroadcast(uri, Downloader.ACTION_STARTED, localFile, repoId, canonicalUrl);
|
|
|
|
|
sendBroadcast(uri, DownloaderService.ACTION_STARTED, localFile, repoId, canonicalUrl);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
activeCanonicalUrl = canonicalUrl.toString();
|
|
|
|
@ -230,26 +253,26 @@ public class DownloaderService extends Service {
|
|
|
|
|
downloader.setListener(new ProgressListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onProgress(long bytesRead, long totalBytes) {
|
|
|
|
|
Intent intent = new Intent(Downloader.ACTION_PROGRESS);
|
|
|
|
|
Intent intent = new Intent(DownloaderService.ACTION_PROGRESS);
|
|
|
|
|
intent.setData(canonicalUrl);
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_BYTES_READ, bytesRead);
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_TOTAL_BYTES, totalBytes);
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_BYTES_READ, bytesRead);
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_TOTAL_BYTES, totalBytes);
|
|
|
|
|
localBroadcastManager.sendBroadcast(intent);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
downloader.download();
|
|
|
|
|
sendBroadcast(uri, Downloader.ACTION_COMPLETE, localFile, repoId, canonicalUrl);
|
|
|
|
|
sendBroadcast(uri, DownloaderService.ACTION_COMPLETE, localFile, repoId, canonicalUrl);
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile, repoId, canonicalUrl);
|
|
|
|
|
sendBroadcast(uri, DownloaderService.ACTION_INTERRUPTED, localFile, repoId, canonicalUrl);
|
|
|
|
|
} catch (ConnectException | HttpRetryException | NoRouteToHostException | SocketTimeoutException
|
|
|
|
|
| SSLHandshakeException | SSLKeyException | SSLPeerUnverifiedException | SSLProtocolException
|
|
|
|
|
| ProtocolException | UnknownHostException e) {
|
|
|
|
|
// if the above list of exceptions changes, also change it in IndexV1Updater.update()
|
|
|
|
|
Log.e(TAG, "CONNECTION_FAILED: " + e.getLocalizedMessage());
|
|
|
|
|
sendBroadcast(uri, Downloader.ACTION_CONNECTION_FAILED, localFile, repoId, canonicalUrl);
|
|
|
|
|
sendBroadcast(uri, DownloaderService.ACTION_CONNECTION_FAILED, localFile, repoId, canonicalUrl);
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile,
|
|
|
|
|
sendBroadcast(uri, DownloaderService.ACTION_INTERRUPTED, localFile,
|
|
|
|
|
e.getLocalizedMessage(), repoId, canonicalUrl);
|
|
|
|
|
} finally {
|
|
|
|
|
if (downloader != null) {
|
|
|
|
@ -261,7 +284,7 @@ public class DownloaderService extends Service {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void sendCancelledBroadcast(Uri uri, String canonicalUrl) {
|
|
|
|
|
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, null, 0, Uri.parse(canonicalUrl));
|
|
|
|
|
sendBroadcast(uri, DownloaderService.ACTION_INTERRUPTED, null, 0, Uri.parse(canonicalUrl));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void sendBroadcast(Uri uri, String action, File file, long repoId, Uri canonicalUrl) {
|
|
|
|
@ -275,13 +298,13 @@ public class DownloaderService extends Service {
|
|
|
|
|
intent.setData(canonicalUrl);
|
|
|
|
|
}
|
|
|
|
|
if (file != null) {
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_DOWNLOAD_PATH, file.getAbsolutePath());
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_DOWNLOAD_PATH, file.getAbsolutePath());
|
|
|
|
|
}
|
|
|
|
|
if (!TextUtils.isEmpty(errorMessage)) {
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_ERROR_MESSAGE, errorMessage);
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_ERROR_MESSAGE, errorMessage);
|
|
|
|
|
}
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_REPO_ID, repoId);
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_MIRROR_URL, uri.toString());
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_REPO_ID, repoId);
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_MIRROR_URL, uri.toString());
|
|
|
|
|
localBroadcastManager.sendBroadcast(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -303,8 +326,8 @@ public class DownloaderService extends Service {
|
|
|
|
|
Intent intent = new Intent(context, DownloaderService.class);
|
|
|
|
|
intent.setAction(ACTION_QUEUE);
|
|
|
|
|
intent.setData(Uri.parse(canonicalUrl));
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_REPO_ID, repoId);
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUrl);
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_REPO_ID, repoId);
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUrl);
|
|
|
|
|
context.startService(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -325,7 +348,7 @@ public class DownloaderService extends Service {
|
|
|
|
|
Intent intent = new Intent(context, DownloaderService.class);
|
|
|
|
|
intent.setAction(ACTION_CANCEL);
|
|
|
|
|
intent.setData(Uri.parse(canonicalUrl));
|
|
|
|
|
intent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUrl);
|
|
|
|
|
intent.putExtra(DownloaderService.EXTRA_CANONICAL_URL, canonicalUrl);
|
|
|
|
|
context.startService(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -359,11 +382,11 @@ public class DownloaderService extends Service {
|
|
|
|
|
public static IntentFilter getIntentFilter(String canonicalUrl) {
|
|
|
|
|
Uri uri = Uri.parse(canonicalUrl);
|
|
|
|
|
IntentFilter intentFilter = new IntentFilter();
|
|
|
|
|
intentFilter.addAction(Downloader.ACTION_STARTED);
|
|
|
|
|
intentFilter.addAction(Downloader.ACTION_PROGRESS);
|
|
|
|
|
intentFilter.addAction(Downloader.ACTION_COMPLETE);
|
|
|
|
|
intentFilter.addAction(Downloader.ACTION_INTERRUPTED);
|
|
|
|
|
intentFilter.addAction(Downloader.ACTION_CONNECTION_FAILED);
|
|
|
|
|
intentFilter.addAction(DownloaderService.ACTION_STARTED);
|
|
|
|
|
intentFilter.addAction(DownloaderService.ACTION_PROGRESS);
|
|
|
|
|
intentFilter.addAction(DownloaderService.ACTION_COMPLETE);
|
|
|
|
|
intentFilter.addAction(DownloaderService.ACTION_INTERRUPTED);
|
|
|
|
|
intentFilter.addAction(DownloaderService.ACTION_CONNECTION_FAILED);
|
|
|
|
|
intentFilter.addDataScheme(uri.getScheme());
|
|
|
|
|
intentFilter.addDataAuthority(uri.getHost(), String.valueOf(uri.getPort()));
|
|
|
|
|
intentFilter.addDataPath(uri.getPath(), PatternMatcher.PATTERN_LITERAL);
|
|
|
|
|