UploadsStorageManager.java 25 KB

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