UploadsStorageManager.java 25 KB

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