FileOperationsHelper.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /**
  2. * ownCloud Android client application
  3. *
  4. * @author masensio
  5. * @author David A. Velasco
  6. * Copyright (C) 2015 ownCloud Inc.
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2,
  10. * as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. package com.owncloud.android.files;
  22. import org.apache.http.protocol.HTTP;
  23. import android.accounts.Account;
  24. import android.content.Intent;
  25. import android.net.Uri;
  26. import android.support.v4.app.DialogFragment;
  27. import android.webkit.MimeTypeMap;
  28. import android.widget.Toast;
  29. import com.owncloud.android.R;
  30. import com.owncloud.android.authentication.AccountUtils;
  31. import com.owncloud.android.datamodel.OCFile;
  32. import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
  33. import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
  34. import com.owncloud.android.lib.common.network.WebdavUtils;
  35. import com.owncloud.android.lib.common.utils.Log_OC;
  36. import com.owncloud.android.lib.resources.status.OwnCloudVersion;
  37. import com.owncloud.android.services.OperationsService;
  38. import com.owncloud.android.ui.activity.FileActivity;
  39. import com.owncloud.android.ui.dialog.ShareLinkToDialog;
  40. /**
  41. *
  42. */
  43. public class FileOperationsHelper {
  44. private static final String TAG = FileOperationsHelper.class.getName();
  45. private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG";
  46. protected FileActivity mFileActivity = null;
  47. /// Identifier of operation in progress which result shouldn't be lost
  48. private long mWaitingForOpId = Long.MAX_VALUE;
  49. public FileOperationsHelper(FileActivity fileActivity) {
  50. mFileActivity = fileActivity;
  51. }
  52. public void openFile(OCFile file) {
  53. if (file != null) {
  54. String storagePath = file.getStoragePath();
  55. String encodedStoragePath = WebdavUtils.encodePath(storagePath);
  56. Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW);
  57. intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype());
  58. intentForSavedMimeType.setFlags(
  59. Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
  60. );
  61. Intent intentForGuessedMimeType = null;
  62. if (storagePath.lastIndexOf('.') >= 0) {
  63. String guessedMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
  64. storagePath.substring(storagePath.lastIndexOf('.') + 1)
  65. );
  66. if (guessedMimeType != null && !guessedMimeType.equals(file.getMimetype())) {
  67. intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW);
  68. intentForGuessedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), guessedMimeType);
  69. intentForGuessedMimeType.setFlags(
  70. Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
  71. );
  72. }
  73. }
  74. Intent chooserIntent;
  75. if (intentForGuessedMimeType != null) {
  76. chooserIntent = Intent.createChooser(intentForGuessedMimeType, mFileActivity.getString(R.string.actionbar_open_with));
  77. } else {
  78. chooserIntent = Intent.createChooser(intentForSavedMimeType, mFileActivity.getString(R.string.actionbar_open_with));
  79. }
  80. mFileActivity.startActivity(chooserIntent);
  81. } else {
  82. Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
  83. }
  84. }
  85. public void shareFileWithLink(OCFile file) {
  86. if (isSharedSupported()) {
  87. if (file != null) {
  88. String link = "https://fake.url";
  89. Intent intent = createShareWithLinkIntent(link);
  90. String[] packagesToExclude = new String[] { mFileActivity.getPackageName() };
  91. DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intent, packagesToExclude, file);
  92. chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
  93. } else {
  94. Log_OC.wtf(TAG, "Trying to share a NULL OCFile");
  95. }
  96. } else {
  97. // Show a Message
  98. Toast t = Toast.makeText(
  99. mFileActivity, mFileActivity.getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG
  100. );
  101. t.show();
  102. }
  103. }
  104. public void shareFileWithLinkToApp(OCFile file, String password, Intent sendIntent) {
  105. if (file != null) {
  106. mFileActivity.showLoadingDialog();
  107. Intent service = new Intent(mFileActivity, OperationsService.class);
  108. service.setAction(OperationsService.ACTION_CREATE_SHARE);
  109. service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
  110. service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
  111. service.putExtra(OperationsService.EXTRA_PASSWORD_SHARE, password);
  112. service.putExtra(OperationsService.EXTRA_SEND_INTENT, sendIntent);
  113. mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
  114. } else {
  115. Log_OC.wtf(TAG, "Trying to open a NULL OCFile");
  116. }
  117. }
  118. private Intent createShareWithLinkIntent(String link) {
  119. Intent intentToShareLink = new Intent(Intent.ACTION_SEND);
  120. intentToShareLink.putExtra(Intent.EXTRA_TEXT, link);
  121. intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE);
  122. return intentToShareLink;
  123. }
  124. /**
  125. * @return 'True' if the server supports the Share API
  126. */
  127. public boolean isSharedSupported() {
  128. if (mFileActivity.getAccount() != null) {
  129. OwnCloudVersion serverVersion = AccountUtils.getServerVersion(mFileActivity.getAccount());
  130. return (serverVersion != null && serverVersion.isSharedSupported());
  131. }
  132. return false;
  133. }
  134. public void unshareFileWithLink(OCFile file) {
  135. if (isSharedSupported()) {
  136. // Unshare the file
  137. Intent service = new Intent(mFileActivity, OperationsService.class);
  138. service.setAction(OperationsService.ACTION_UNSHARE);
  139. service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
  140. service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
  141. mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
  142. mFileActivity.showLoadingDialog();
  143. } else {
  144. // Show a Message
  145. Toast t = Toast.makeText(mFileActivity, mFileActivity.getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG);
  146. t.show();
  147. }
  148. }
  149. public void sendDownloadedFile(OCFile file) {
  150. if (file != null) {
  151. String storagePath = file.getStoragePath();
  152. String encodedStoragePath = WebdavUtils.encodePath(storagePath);
  153. Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
  154. // set MimeType
  155. sendIntent.setType(file.getMimetype());
  156. sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + encodedStoragePath));
  157. sendIntent.putExtra(Intent.ACTION_SEND, true); // Send Action
  158. // Show dialog, without the own app
  159. String[] packagesToExclude = new String[] { mFileActivity.getPackageName() };
  160. DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file);
  161. chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
  162. } else {
  163. Log_OC.wtf(TAG, "Trying to send a NULL OCFile");
  164. }
  165. }
  166. public void syncFile(OCFile file) {
  167. if (!file.isFolder()){
  168. Intent intent = new Intent(mFileActivity, OperationsService.class);
  169. intent.setAction(OperationsService.ACTION_SYNC_FILE);
  170. intent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
  171. intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
  172. intent.putExtra(OperationsService.EXTRA_SYNC_FILE_CONTENTS, true);
  173. mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(intent);
  174. mFileActivity.showLoadingDialog();
  175. } else {
  176. Intent intent = new Intent(mFileActivity, OperationsService.class);
  177. intent.setAction(OperationsService.ACTION_SYNC_FOLDER);
  178. intent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
  179. intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
  180. mFileActivity.startService(intent);
  181. }
  182. }
  183. public void renameFile(OCFile file, String newFilename) {
  184. // RenameFile
  185. Intent service = new Intent(mFileActivity, OperationsService.class);
  186. service.setAction(OperationsService.ACTION_RENAME);
  187. service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
  188. service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
  189. service.putExtra(OperationsService.EXTRA_NEWNAME, newFilename);
  190. mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
  191. mFileActivity.showLoadingDialog();
  192. }
  193. public void removeFile(OCFile file, boolean onlyLocalCopy) {
  194. // RemoveFile
  195. Intent service = new Intent(mFileActivity, OperationsService.class);
  196. service.setAction(OperationsService.ACTION_REMOVE);
  197. service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
  198. service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
  199. service.putExtra(OperationsService.EXTRA_REMOVE_ONLY_LOCAL, onlyLocalCopy);
  200. mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
  201. mFileActivity.showLoadingDialog();
  202. }
  203. public void createFolder(String remotePath, boolean createFullPath) {
  204. // Create Folder
  205. Intent service = new Intent(mFileActivity, OperationsService.class);
  206. service.setAction(OperationsService.ACTION_CREATE_FOLDER);
  207. service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
  208. service.putExtra(OperationsService.EXTRA_REMOTE_PATH, remotePath);
  209. service.putExtra(OperationsService.EXTRA_CREATE_FULL_PATH, createFullPath);
  210. mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
  211. mFileActivity.showLoadingDialog();
  212. }
  213. /**
  214. * Cancel the transference in downloads (files/folders) and file uploads
  215. * @param file OCFile
  216. */
  217. public void cancelTransference(OCFile file) {
  218. Account account = mFileActivity.getAccount();
  219. if (file.isFolder()) {
  220. OperationsService.OperationsServiceBinder opsBinder = mFileActivity.getOperationsServiceBinder();
  221. if (opsBinder != null) {
  222. opsBinder.cancel(account, file);
  223. }
  224. }
  225. // for both files and folders
  226. FileDownloaderBinder downloaderBinder = mFileActivity.getFileDownloaderBinder();
  227. FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder();
  228. if (downloaderBinder != null && downloaderBinder.isDownloading(account, file)) {
  229. downloaderBinder.cancel(account, file);
  230. // TODO - review why is this here, and solve in a better way
  231. // Remove etag for parent, if file is a keep_in_sync
  232. if (file.keepInSync()) {
  233. OCFile parent = mFileActivity.getStorageManager().getFileById(file.getParentId());
  234. parent.setEtag("");
  235. mFileActivity.getStorageManager().saveFile(parent);
  236. }
  237. } else if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) {
  238. uploaderBinder.cancel(account, file);
  239. }
  240. }
  241. /**
  242. * Start move file operation
  243. * @param newfile File where it is going to be moved
  244. * @param currentFile File with the previous info
  245. */
  246. public void moveFile(OCFile newfile, OCFile currentFile) {
  247. // Move files
  248. Intent service = new Intent(mFileActivity, OperationsService.class);
  249. service.setAction(OperationsService.ACTION_MOVE_FILE);
  250. service.putExtra(OperationsService.EXTRA_NEW_PARENT_PATH, newfile.getRemotePath());
  251. service.putExtra(OperationsService.EXTRA_REMOTE_PATH, currentFile.getRemotePath());
  252. service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
  253. mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
  254. mFileActivity.showLoadingDialog();
  255. }
  256. public long getOpIdWaitingFor() {
  257. return mWaitingForOpId;
  258. }
  259. public void setOpIdWaitingFor(long waitingForOpId) {
  260. mWaitingForOpId = waitingForOpId;
  261. }
  262. /**
  263. * @return 'True' if the server doesn't need to check forbidden characters
  264. */
  265. public boolean isVersionWithForbiddenCharacters() {
  266. if (mFileActivity.getAccount() != null) {
  267. OwnCloudVersion serverVersion = AccountUtils.getServerVersion(mFileActivity.getAccount());
  268. return (serverVersion != null && serverVersion.isVersionWithForbiddenCharacters());
  269. }
  270. return false;
  271. }
  272. }