UploadsStorageManager.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*
  2. * ownCloud Android client application
  3. *
  4. * @author LukeOwncloud
  5. * @author David A. Velasco
  6. * @author masensio
  7. * @author Chris Narkiewicz
  8. *
  9. * Copyright (C) 2016 ownCloud Inc.
  10. * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2,
  14. * as published by the Free Software Foundation.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. */
  24. package com.owncloud.android.datamodel;
  25. import android.accounts.Account;
  26. import android.content.ContentResolver;
  27. import android.content.ContentValues;
  28. import android.database.Cursor;
  29. import android.net.Uri;
  30. import com.nextcloud.client.account.CurrentAccountProvider;
  31. import com.owncloud.android.db.OCUpload;
  32. import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
  33. import com.owncloud.android.db.UploadResult;
  34. import com.owncloud.android.files.services.FileUploader;
  35. import com.owncloud.android.lib.common.operations.RemoteOperationResult;
  36. import com.owncloud.android.lib.common.utils.Log_OC;
  37. import com.owncloud.android.operations.UploadFileOperation;
  38. import java.util.Calendar;
  39. import java.util.Observable;
  40. import androidx.annotation.Nullable;
  41. /**
  42. * Database helper for storing list of files to be uploaded, including status
  43. * information for each file.
  44. */
  45. public class UploadsStorageManager extends Observable {
  46. private static final String TAG = UploadsStorageManager.class.getSimpleName();
  47. private static final String AND = " AND ";
  48. private static final int SINGLE_RESULT = 1;
  49. private ContentResolver mContentResolver;
  50. private CurrentAccountProvider currentAccountProvider;
  51. public UploadsStorageManager(
  52. CurrentAccountProvider currentAccountProvider,
  53. ContentResolver contentResolver
  54. ) {
  55. if (contentResolver == null) {
  56. throw new IllegalArgumentException("Cannot create an instance with a NULL contentResolver");
  57. }
  58. mContentResolver = contentResolver;
  59. this.currentAccountProvider = currentAccountProvider;
  60. }
  61. /**
  62. * Stores an upload object in DB.
  63. *
  64. * @param ocUpload Upload object to store
  65. * @return upload id, -1 if the insert process fails.
  66. */
  67. public long storeUpload(OCUpload ocUpload) {
  68. Log_OC.v(TAG, "Inserting " + ocUpload.getLocalPath() + " with status=" + ocUpload.getUploadStatus());
  69. ContentValues cv = new ContentValues();
  70. cv.put(ProviderTableMeta.UPLOADS_LOCAL_PATH, ocUpload.getLocalPath());
  71. cv.put(ProviderTableMeta.UPLOADS_REMOTE_PATH, ocUpload.getRemotePath());
  72. cv.put(ProviderTableMeta.UPLOADS_ACCOUNT_NAME, ocUpload.getAccountName());
  73. cv.put(ProviderTableMeta.UPLOADS_FILE_SIZE, ocUpload.getFileSize());
  74. cv.put(ProviderTableMeta.UPLOADS_STATUS, ocUpload.getUploadStatus().value);
  75. cv.put(ProviderTableMeta.UPLOADS_LOCAL_BEHAVIOUR, ocUpload.getLocalAction());
  76. cv.put(ProviderTableMeta.UPLOADS_FORCE_OVERWRITE, ocUpload.isForceOverwrite() ? 1 : 0);
  77. cv.put(ProviderTableMeta.UPLOADS_IS_CREATE_REMOTE_FOLDER, ocUpload.isCreateRemoteFolder() ? 1 : 0);
  78. cv.put(ProviderTableMeta.UPLOADS_LAST_RESULT, ocUpload.getLastResult().getValue());
  79. cv.put(ProviderTableMeta.UPLOADS_CREATED_BY, ocUpload.getCreatedBy());
  80. cv.put(ProviderTableMeta.UPLOADS_IS_WHILE_CHARGING_ONLY, ocUpload.isWhileChargingOnly() ? 1 : 0);
  81. cv.put(ProviderTableMeta.UPLOADS_IS_WIFI_ONLY, ocUpload.isUseWifiOnly() ? 1 : 0);
  82. cv.put(ProviderTableMeta.UPLOADS_FOLDER_UNLOCK_TOKEN, ocUpload.getFolderUnlockToken());
  83. Uri result = getDB().insert(ProviderTableMeta.CONTENT_URI_UPLOADS, cv);
  84. Log_OC.d(TAG, "storeUpload returns with: " + result + " for file: " + ocUpload.getLocalPath());
  85. if (result == null) {
  86. Log_OC.e(TAG, "Failed to insert item " + ocUpload.getLocalPath() + " into upload db.");
  87. return -1;
  88. } else {
  89. long new_id = Long.parseLong(result.getPathSegments().get(1));
  90. ocUpload.setUploadId(new_id);
  91. notifyObserversNow();
  92. return new_id;
  93. }
  94. }
  95. /**
  96. * Update an upload object in DB.
  97. *
  98. * @param ocUpload Upload object with state to update
  99. * @return num of updated uploads.
  100. */
  101. public int updateUpload(OCUpload ocUpload) {
  102. Log_OC.v(TAG, "Updating " + ocUpload.getLocalPath() + " with status=" + ocUpload.getUploadStatus());
  103. ContentValues cv = new ContentValues();
  104. cv.put(ProviderTableMeta.UPLOADS_LOCAL_PATH, ocUpload.getLocalPath());
  105. cv.put(ProviderTableMeta.UPLOADS_REMOTE_PATH, ocUpload.getRemotePath());
  106. cv.put(ProviderTableMeta.UPLOADS_ACCOUNT_NAME, ocUpload.getAccountName());
  107. cv.put(ProviderTableMeta.UPLOADS_STATUS, ocUpload.getUploadStatus().value);
  108. cv.put(ProviderTableMeta.UPLOADS_LAST_RESULT, ocUpload.getLastResult().getValue());
  109. cv.put(ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP, ocUpload.getUploadEndTimestamp());
  110. cv.put(ProviderTableMeta.UPLOADS_FILE_SIZE, ocUpload.getFileSize());
  111. cv.put(ProviderTableMeta.UPLOADS_FOLDER_UNLOCK_TOKEN, ocUpload.getFolderUnlockToken());
  112. int result = getDB().update(ProviderTableMeta.CONTENT_URI_UPLOADS,
  113. cv,
  114. ProviderTableMeta._ID + "=?",
  115. new String[]{String.valueOf(ocUpload.getUploadId())}
  116. );
  117. Log_OC.d(TAG, "updateUpload returns with: " + result + " for file: " + ocUpload.getLocalPath());
  118. if (result != SINGLE_RESULT) {
  119. Log_OC.e(TAG, "Failed to update item " + ocUpload.getLocalPath() + " into upload db.");
  120. } else {
  121. notifyObserversNow();
  122. }
  123. return result;
  124. }
  125. private int updateUploadInternal(Cursor c, UploadStatus status, UploadResult result, String remotePath,
  126. String localPath) {
  127. int r = 0;
  128. while (c.moveToNext()) {
  129. // read upload object and update
  130. OCUpload upload = createOCUploadFromCursor(c);
  131. String path = c.getString(c.getColumnIndex(ProviderTableMeta.UPLOADS_LOCAL_PATH));
  132. Log_OC.v(
  133. TAG,
  134. "Updating " + path + " with status:" + status + " and result:"
  135. + (result == null ? "null" : result.toString()) + " (old:"
  136. + upload.toFormattedString() + ")");
  137. upload.setUploadStatus(status);
  138. upload.setLastResult(result);
  139. upload.setRemotePath(remotePath);
  140. if (localPath != null) {
  141. upload.setLocalPath(localPath);
  142. }
  143. if (status == UploadStatus.UPLOAD_SUCCEEDED) {
  144. upload.setUploadEndTimestamp(Calendar.getInstance().getTimeInMillis());
  145. }
  146. // store update upload object to db
  147. r = updateUpload(upload);
  148. }
  149. return r;
  150. }
  151. /**
  152. * Update upload status of file uniquely referenced by id.
  153. *
  154. * @param id upload id.
  155. * @param status new status.
  156. * @param result new result of upload operation
  157. * @param remotePath path of the file to upload in the ownCloud storage
  158. * @param localPath path of the file to upload in the device storage
  159. * @return 1 if file status was updated, else 0.
  160. */
  161. private int updateUploadStatus(long id, UploadStatus status, UploadResult result, String remotePath,
  162. String localPath) {
  163. //Log_OC.v(TAG, "Updating "+filepath+" with uploadStatus="+status +" and result="+result);
  164. int returnValue = 0;
  165. Cursor c = getDB().query(
  166. ProviderTableMeta.CONTENT_URI_UPLOADS,
  167. null,
  168. ProviderTableMeta._ID + "=?",
  169. new String[]{String.valueOf(id)},
  170. null
  171. );
  172. if (c != null) {
  173. if (c.getCount() != SINGLE_RESULT) {
  174. Log_OC.e(TAG, c.getCount() + " items for id=" + id
  175. + " available in UploadDb. Expected 1. Failed to update upload db.");
  176. } else {
  177. returnValue = updateUploadInternal(c, status, result, remotePath, localPath);
  178. }
  179. c.close();
  180. } else {
  181. Log_OC.e(TAG, "Cursor is null");
  182. }
  183. return returnValue;
  184. }
  185. /**
  186. * Should be called when some value of this DB was changed. All observers
  187. * are informed.
  188. */
  189. public void notifyObserversNow() {
  190. Log_OC.d(TAG, "notifyObserversNow");
  191. setChanged();
  192. notifyObservers();
  193. }
  194. /**
  195. * Remove an upload from the uploads list, known its target account and remote path.
  196. *
  197. * @param upload Upload instance to remove from persisted storage.
  198. * @return true when the upload was stored and could be removed.
  199. */
  200. public int removeUpload(OCUpload upload) {
  201. int result = getDB().delete(
  202. ProviderTableMeta.CONTENT_URI_UPLOADS,
  203. ProviderTableMeta._ID + "=?",
  204. new String[]{Long.toString(upload.getUploadId())}
  205. );
  206. Log_OC.d(TAG, "delete returns " + result + " for upload " + upload);
  207. if (result > 0) {
  208. notifyObserversNow();
  209. }
  210. return result;
  211. }
  212. /**
  213. * Remove an upload from the uploads list, known its target account and remote path.
  214. *
  215. * @param accountName Name of the OC account target of the upload to remove.
  216. * @param remotePath Absolute path in the OC account target of the upload to remove.
  217. * @return true when one or more upload entries were removed
  218. */
  219. public int removeUpload(String accountName, String remotePath) {
  220. int result = getDB().delete(
  221. ProviderTableMeta.CONTENT_URI_UPLOADS,
  222. ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=? AND " + ProviderTableMeta.UPLOADS_REMOTE_PATH + "=?",
  223. new String[]{accountName, remotePath}
  224. );
  225. Log_OC.d(TAG, "delete returns " + result + " for file " + remotePath + " in " + accountName);
  226. if (result > 0) {
  227. notifyObserversNow();
  228. }
  229. return result;
  230. }
  231. /**
  232. * Remove all the uploads of a given account from the uploads list.
  233. *
  234. * @param accountName Name of the OC account target of the uploads to remove.
  235. * @return true when one or more upload entries were removed
  236. */
  237. public int removeUploads(String accountName) {
  238. int result = getDB().delete(
  239. ProviderTableMeta.CONTENT_URI_UPLOADS,
  240. ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=?",
  241. new String[]{accountName}
  242. );
  243. Log_OC.d(TAG, "delete returns " + result + " for uploads in " + accountName);
  244. if (result > 0) {
  245. notifyObserversNow();
  246. }
  247. return result;
  248. }
  249. public OCUpload[] getAllStoredUploads() {
  250. return getUploads(null, (String[]) null);
  251. }
  252. private OCUpload[] getUploads(@Nullable String selection, @Nullable String... selectionArgs) {
  253. OCUpload[] list;
  254. Cursor c = getDB().query(
  255. ProviderTableMeta.CONTENT_URI_UPLOADS,
  256. null,
  257. selection,
  258. selectionArgs,
  259. null
  260. );
  261. if (c != null) {
  262. list = new OCUpload[c.getCount()];
  263. if (c.moveToFirst()) {
  264. do {
  265. OCUpload upload = createOCUploadFromCursor(c);
  266. if (upload == null) {
  267. Log_OC.e(TAG, "OCUpload could not be created from cursor");
  268. } else {
  269. list[c.getPosition()] = upload;
  270. }
  271. } while (c.moveToNext());
  272. }
  273. c.close();
  274. } else {
  275. list = new OCUpload[0];
  276. }
  277. return list;
  278. }
  279. private OCUpload createOCUploadFromCursor(Cursor c) {
  280. OCUpload upload = null;
  281. if (c != null) {
  282. String localPath = c.getString(c.getColumnIndex(ProviderTableMeta.UPLOADS_LOCAL_PATH));
  283. String remotePath = c.getString(c.getColumnIndex(ProviderTableMeta.UPLOADS_REMOTE_PATH));
  284. String accountName = c.getString(c.getColumnIndex(ProviderTableMeta.UPLOADS_ACCOUNT_NAME));
  285. upload = new OCUpload(localPath, remotePath, accountName);
  286. upload.setFileSize(c.getLong(c.getColumnIndex(ProviderTableMeta.UPLOADS_FILE_SIZE)));
  287. upload.setUploadId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
  288. upload.setUploadStatus(
  289. UploadStatus.fromValue(c.getInt(c.getColumnIndex(ProviderTableMeta.UPLOADS_STATUS)))
  290. );
  291. upload.setLocalAction(c.getInt(c.getColumnIndex(ProviderTableMeta.UPLOADS_LOCAL_BEHAVIOUR)));
  292. upload.setForceOverwrite(c.getInt(
  293. c.getColumnIndex(ProviderTableMeta.UPLOADS_FORCE_OVERWRITE)) == 1);
  294. upload.setCreateRemoteFolder(c.getInt(
  295. c.getColumnIndex(ProviderTableMeta.UPLOADS_IS_CREATE_REMOTE_FOLDER)) == 1);
  296. upload.setUploadEndTimestamp(c.getLong(c.getColumnIndex(ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP)));
  297. upload.setLastResult(UploadResult.fromValue(
  298. c.getInt(c.getColumnIndex(ProviderTableMeta.UPLOADS_LAST_RESULT))));
  299. upload.setCreatedBy(c.getInt(c.getColumnIndex(ProviderTableMeta.UPLOADS_CREATED_BY)));
  300. upload.setUseWifiOnly(c.getInt(c.getColumnIndex(ProviderTableMeta.UPLOADS_IS_WIFI_ONLY)) == 1);
  301. upload.setWhileChargingOnly(c.getInt(c.getColumnIndex(ProviderTableMeta.UPLOADS_IS_WHILE_CHARGING_ONLY))
  302. == 1);
  303. upload.setFolderUnlockToken(c.getString(c.getColumnIndex(ProviderTableMeta.UPLOADS_FOLDER_UNLOCK_TOKEN)));
  304. }
  305. return upload;
  306. }
  307. public OCUpload[] getCurrentAndPendingUploadsForCurrentAccount() {
  308. Account account = currentAccountProvider.getCurrentAccount();
  309. if (account != null) {
  310. return getUploads(
  311. ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_IN_PROGRESS.value +
  312. " OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  313. "==" + UploadResult.DELAYED_FOR_WIFI.getValue() +
  314. " OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  315. "==" + UploadResult.LOCK_FAILED.getValue() +
  316. " OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  317. "==" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
  318. " OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  319. "==" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
  320. " AND " + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
  321. account.name);
  322. } else {
  323. return new OCUpload[0];
  324. }
  325. }
  326. /**
  327. * Get all failed uploads.
  328. */
  329. public OCUpload[] getFailedUploads() {
  330. return getUploads("(" + ProviderTableMeta.UPLOADS_STATUS + "== ?" +
  331. " OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  332. "==" + UploadResult.DELAYED_FOR_WIFI.getValue() +
  333. " OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  334. "==" + UploadResult.LOCK_FAILED.getValue() +
  335. " OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  336. "==" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
  337. " OR " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  338. "==" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
  339. " ) AND " + ProviderTableMeta.UPLOADS_LAST_RESULT +
  340. "!= " + UploadResult.VIRUS_DETECTED.getValue()
  341. , String.valueOf(UploadStatus.UPLOAD_FAILED.value));
  342. }
  343. public OCUpload[] getFinishedUploadsForCurrentAccount() {
  344. Account account = currentAccountProvider.getCurrentAccount();
  345. if (account != null) {
  346. return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value + AND +
  347. ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?", account.name);
  348. } else {
  349. return new OCUpload[0];
  350. }
  351. }
  352. /**
  353. * Get all uploads which where successfully completed.
  354. */
  355. public OCUpload[] getFinishedUploads() {
  356. return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value, (String[]) null);
  357. }
  358. public OCUpload[] getFailedButNotDelayedUploadsForCurrentAccount() {
  359. Account account = currentAccountProvider.getCurrentAccount();
  360. if (account != null) {
  361. return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value +
  362. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  363. "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() +
  364. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  365. "<>" + UploadResult.LOCK_FAILED.getValue() +
  366. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  367. "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
  368. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  369. "<>" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
  370. AND + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
  371. account.name);
  372. } else {
  373. return new OCUpload[0];
  374. }
  375. }
  376. /**
  377. * Get all failed uploads, except for those that were not performed due to lack of Wifi connection.
  378. *
  379. * @return Array of failed uploads, except for those that were not performed due to lack of Wifi connection.
  380. */
  381. public OCUpload[] getFailedButNotDelayedUploads() {
  382. return getUploads(ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value + AND +
  383. ProviderTableMeta.UPLOADS_LAST_RESULT + "<>" + UploadResult.LOCK_FAILED.getValue() +
  384. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  385. "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() +
  386. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  387. "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
  388. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  389. "<>" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue(),
  390. (String[]) null
  391. );
  392. }
  393. private ContentResolver getDB() {
  394. return mContentResolver;
  395. }
  396. public long clearFailedButNotDelayedUploads() {
  397. Account account = currentAccountProvider.getCurrentAccount();
  398. long result = 0;
  399. if (account != null) {
  400. result = getDB().delete(
  401. ProviderTableMeta.CONTENT_URI_UPLOADS,
  402. ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_FAILED.value +
  403. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  404. "<>" + UploadResult.LOCK_FAILED.getValue() +
  405. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  406. "<>" + UploadResult.DELAYED_FOR_WIFI.getValue() +
  407. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  408. "<>" + UploadResult.DELAYED_FOR_CHARGING.getValue() +
  409. AND + ProviderTableMeta.UPLOADS_LAST_RESULT +
  410. "<>" + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
  411. AND + ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?",
  412. new String[]{account.name}
  413. );
  414. }
  415. Log_OC.d(TAG, "delete all failed uploads but those delayed for Wifi");
  416. if (result > 0) {
  417. notifyObserversNow();
  418. }
  419. return result;
  420. }
  421. public long clearSuccessfulUploads() {
  422. Account account = currentAccountProvider.getCurrentAccount();
  423. long result = 0;
  424. if (account != null) {
  425. result = getDB().delete(
  426. ProviderTableMeta.CONTENT_URI_UPLOADS,
  427. ProviderTableMeta.UPLOADS_STATUS + "==" + UploadStatus.UPLOAD_SUCCEEDED.value + AND +
  428. ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "== ?", new String[]{account.name}
  429. );
  430. }
  431. Log_OC.d(TAG, "delete all successful uploads");
  432. if (result > 0) {
  433. notifyObserversNow();
  434. }
  435. return result;
  436. }
  437. /**
  438. * Updates the persistent upload database with upload result.
  439. */
  440. public void updateDatabaseUploadResult(RemoteOperationResult uploadResult, UploadFileOperation upload) {
  441. // result: success or fail notification
  442. Log_OC.d(TAG, "updateDatabaseUploadResult uploadResult: " + uploadResult + " upload: " + upload);
  443. if (uploadResult.isCancelled()) {
  444. removeUpload(
  445. upload.getAccount().name,
  446. upload.getRemotePath()
  447. );
  448. } else {
  449. String localPath = (FileUploader.LOCAL_BEHAVIOUR_MOVE == upload.getLocalBehaviour())
  450. ? upload.getStoragePath() : null;
  451. if (uploadResult.isSuccess()) {
  452. updateUploadStatus(
  453. upload.getOCUploadId(),
  454. UploadStatus.UPLOAD_SUCCEEDED,
  455. UploadResult.UPLOADED,
  456. upload.getRemotePath(),
  457. localPath
  458. );
  459. } else {
  460. updateUploadStatus(
  461. upload.getOCUploadId(),
  462. UploadStatus.UPLOAD_FAILED,
  463. UploadResult.fromOperationResult(uploadResult),
  464. upload.getRemotePath(),
  465. localPath
  466. );
  467. }
  468. }
  469. }
  470. /**
  471. * Updates the persistent upload database with an upload now in progress.
  472. */
  473. public void updateDatabaseUploadStart(UploadFileOperation upload) {
  474. String localPath = (FileUploader.LOCAL_BEHAVIOUR_MOVE == upload.getLocalBehaviour())
  475. ? upload.getStoragePath() : null;
  476. updateUploadStatus(
  477. upload.getOCUploadId(),
  478. UploadStatus.UPLOAD_IN_PROGRESS,
  479. UploadResult.UNKNOWN,
  480. upload.getRemotePath(),
  481. localPath
  482. );
  483. }
  484. /**
  485. * Changes the status of any in progress upload from UploadStatus.UPLOAD_IN_PROGRESS
  486. * to UploadStatus.UPLOAD_FAILED
  487. *
  488. * @return Number of uploads which status was changed.
  489. */
  490. public int failInProgressUploads(UploadResult fail) {
  491. Log_OC.v(TAG, "Updating state of any killed upload");
  492. ContentValues cv = new ContentValues();
  493. cv.put(ProviderTableMeta.UPLOADS_STATUS, UploadStatus.UPLOAD_FAILED.getValue());
  494. cv.put(
  495. ProviderTableMeta.UPLOADS_LAST_RESULT,
  496. fail != null ? fail.getValue() : UploadResult.UNKNOWN.getValue()
  497. );
  498. cv.put(ProviderTableMeta.UPLOADS_UPLOAD_END_TIMESTAMP, Calendar.getInstance().getTimeInMillis());
  499. int result = getDB().update(
  500. ProviderTableMeta.CONTENT_URI_UPLOADS,
  501. cv,
  502. ProviderTableMeta.UPLOADS_STATUS + "=?",
  503. new String[]{String.valueOf(UploadStatus.UPLOAD_IN_PROGRESS.getValue())}
  504. );
  505. if (result == 0) {
  506. Log_OC.v(TAG, "No upload was killed");
  507. } else {
  508. Log_OC.w(TAG, Integer.toString(result) + " uploads where abruptly interrupted");
  509. notifyObserversNow();
  510. }
  511. return result;
  512. }
  513. public int removeAccountUploads(Account account) {
  514. Log_OC.v(TAG, "Delete all uploads for account " + account.name);
  515. return getDB().delete(
  516. ProviderTableMeta.CONTENT_URI_UPLOADS,
  517. ProviderTableMeta.UPLOADS_ACCOUNT_NAME + "=?",
  518. new String[]{account.name});
  519. }
  520. public enum UploadStatus {
  521. /**
  522. * Upload currently in progress or scheduled to be executed.
  523. */
  524. UPLOAD_IN_PROGRESS(0),
  525. /**
  526. * Last upload failed.
  527. */
  528. UPLOAD_FAILED(1),
  529. /**
  530. * Upload was successful.
  531. */
  532. UPLOAD_SUCCEEDED(2);
  533. private final int value;
  534. UploadStatus(int value) {
  535. this.value = value;
  536. }
  537. public static UploadStatus fromValue(int value) {
  538. switch (value) {
  539. case 0:
  540. return UPLOAD_IN_PROGRESS;
  541. case 1:
  542. return UPLOAD_FAILED;
  543. case 2:
  544. return UPLOAD_SUCCEEDED;
  545. }
  546. return null;
  547. }
  548. public int getValue() {
  549. return value;
  550. }
  551. }
  552. }