+ /**\r
+ * Returns True when the file described by 'file' in the ownCloud account 'account' is downloading or waiting to download.\r
+ * \r
+ * If 'file' is a directory, returns 'true' if some of its descendant files is downloading or waiting to download. \r
+ * \r
+ * @param account Owncloud account where the remote file is stored.\r
+ * @param file A file that could be in the queue of downloads.\r
+ */\r
+ public boolean isDownloading(Account account, OCFile file) {\r
+ if (account == null || file == null) return false;\r
+ String targetKey = buildRemoteName(account, file);\r
+ synchronized (mPendingDownloads) {\r
+ if (file.isDirectory()) {\r
+ // this can be slow if there are many downloads :(\r
+ Iterator<String> it = mPendingDownloads.keySet().iterator();\r
+ boolean found = false;\r
+ while (it.hasNext() && !found) {\r
+ found = it.next().startsWith(targetKey);\r
+ }\r
+ return found;\r
+ } else {\r
+ return (mPendingDownloads.containsKey(targetKey));\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ \r
+ /** \r
+ * Download worker. Performs the pending downloads in the order they were requested. \r
+ * \r
+ * Created with the Looper of a new thread, started in {@link FileUploader#onCreate()}. \r
+ */\r
+ private static class ServiceHandler extends Handler {\r
+ // don't make it a final class, and don't remove the static ; lint will warn about a possible memory leak\r
+ FileDownloader mService;\r
+ public ServiceHandler(Looper looper, FileDownloader service) {\r
+ super(looper);\r
+ if (service == null)\r
+ throw new IllegalArgumentException("Received invalid NULL in parameter 'service'");\r
+ mService = service;\r
+ }\r
+\r
+ @Override\r
+ public void handleMessage(Message msg) {\r
+ @SuppressWarnings("unchecked")\r
+ AbstractList<String> requestedDownloads = (AbstractList<String>) msg.obj;\r
+ if (msg.obj != null) {\r
+ Iterator<String> it = requestedDownloads.iterator();\r
+ while (it.hasNext()) {\r
+ mService.downloadFile(it.next());\r
+ }\r
+ }\r
+ mService.stopSelf(msg.arg1);\r
+ }\r
+ }\r
+ \r
+ \r
+\r
+ /**\r
+ * Core download method: requests a file to download and stores it.\r
+ * \r
+ * @param downloadKey Key to access the download to perform, contained in mPendingDownloads \r
+ */\r
+ private void downloadFile(String downloadKey) {\r
+ \r
+ synchronized(mPendingDownloads) {\r
+ mCurrentDownload = mPendingDownloads.get(downloadKey);\r
+ }\r
+ \r
+ if (mCurrentDownload != null) {\r
+ \r
+ notifyDownloadStart(mCurrentDownload);\r