From 8bd324323841945c883503f5431dbdacfc5748d8 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 3 May 2022 08:56:26 +0200 Subject: [PATCH] Do not set custom user agent for Text/ProseMirror Use EditorUtils Signed-off-by: tobiasKaminsky --- .../android/files/FileMenuFilter.java | 44 ++--------------- .../ui/activity/ExternalSiteWebView.java | 6 ++- .../android/ui/activity/TextEditorWebView.kt | 31 +++++++----- .../ui/asynctasks/TextEditorLoadUrlTask.java | 4 +- .../fragment/OCFileListBottomSheetDialog.java | 10 ++-- .../ui/fragment/OCFileListFragment.java | 13 ++--- .../ui/helpers/FileOperationsHelper.java | 8 ++-- .../com/owncloud/android/utils/EditorUtils.kt | 48 +++++++++++++++++++ 8 files changed, 95 insertions(+), 69 deletions(-) create mode 100644 app/src/main/java/com/owncloud/android/utils/EditorUtils.kt diff --git a/app/src/main/java/com/owncloud/android/files/FileMenuFilter.java b/app/src/main/java/com/owncloud/android/files/FileMenuFilter.java index 56acf9b34d..6796d9d574 100644 --- a/app/src/main/java/com/owncloud/android/files/FileMenuFilter.java +++ b/app/src/main/java/com/owncloud/android/files/FileMenuFilter.java @@ -22,24 +22,20 @@ package com.owncloud.android.files; import android.accounts.AccountManager; -import android.content.ContentResolver; import android.content.Context; import android.view.Menu; import android.view.MenuItem; -import com.google.gson.Gson; import com.nextcloud.android.files.FileLockingHelper; import com.nextcloud.client.account.User; import com.owncloud.android.R; -import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; -import com.owncloud.android.lib.common.DirectEditing; -import com.owncloud.android.lib.common.Editor; import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.services.OperationsService.OperationsServiceBinder; import com.owncloud.android.ui.activity.ComponentsGetter; +import com.owncloud.android.utils.EditorUtils; import com.owncloud.android.utils.MimeTypeUtil; import com.owncloud.android.utils.NextcloudServer; @@ -49,8 +45,6 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -import androidx.annotation.Nullable; - /** * Filters out the file actions available in a given {@link Menu} for a given {@link OCFile} * according to the current state of the latest. @@ -352,44 +346,16 @@ public class FileMenuFilter { String mimeType = files.iterator().next().getMimeType(); - if (isRichDocumentEditingSupported(capability, mimeType) || isEditorAvailable(context.getContentResolver(), - user, - mimeType)) { + if (isRichDocumentEditingSupported(capability, mimeType) || + EditorUtils.isEditorAvailable(context.getContentResolver(), + user, + mimeType)) { toShow.add(R.id.action_edit); } else { toHide.add(R.id.action_edit); } } - public static boolean isEditorAvailable(ContentResolver contentResolver, User user, String mimeType) { - return getEditor(contentResolver, user, mimeType) != null; - } - - @Nullable - public static Editor getEditor(ContentResolver contentResolver, User user, String mimeType) { - String json = new ArbitraryDataProvider(contentResolver).getValue(user, ArbitraryDataProvider.DIRECT_EDITING); - - if (json.isEmpty()) { - return null; - } - - DirectEditing directEditing = new Gson().fromJson(json, DirectEditing.class); - - for (Editor editor : directEditing.getEditors().values()) { - if (editor.getMimetypes().contains(mimeType)) { - return editor; - } - } - - for (Editor editor : directEditing.getEditors().values()) { - if (editor.getOptionalMimetypes().contains(mimeType)) { - return editor; - } - } - - return null; - } - /** * This will be replaced by unified editor and can be removed once EOL of corresponding server version. */ diff --git a/app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java b/app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java index 03736ce9f5..ed545c382e 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/ExternalSiteWebView.java @@ -179,7 +179,7 @@ public class ExternalSiteWebView extends FileActivity { webSettings.setLoadWithOverviewMode(true); // user agent - webSettings.setUserAgentString(MainApp.getUserAgent()); + setUserAgentString(webSettings); // no private data storing webSettings.setSavePassword(false); @@ -199,6 +199,10 @@ public class ExternalSiteWebView extends FileActivity { } } + protected void setUserAgentString(WebSettings webSettings) { + webSettings.setUserAgentString(MainApp.getUserAgent()); + } + private void setupActionBar(String title) { ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/TextEditorWebView.kt b/app/src/main/java/com/owncloud/android/ui/activity/TextEditorWebView.kt index f0dfe7811f..e6db4790dd 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/TextEditorWebView.kt +++ b/app/src/main/java/com/owncloud/android/ui/activity/TextEditorWebView.kt @@ -23,14 +23,15 @@ package com.owncloud.android.ui.activity import android.annotation.SuppressLint import android.net.Uri +import android.webkit.WebSettings import android.widget.Toast import androidx.webkit.WebSettingsCompat import androidx.webkit.WebViewFeature import com.nextcloud.client.appinfo.AppInfo import com.nextcloud.client.device.DeviceInfo import com.owncloud.android.R -import com.owncloud.android.files.FileMenuFilter import com.owncloud.android.ui.asynctasks.TextEditorLoadUrlTask +import com.owncloud.android.utils.EditorUtils import com.owncloud.android.utils.theme.ThemeUtils import javax.inject.Inject @@ -53,29 +54,33 @@ class TextEditorWebView : EditorWebView() { finish() } - val editor = FileMenuFilter.getEditor(contentResolver, user.get(), file.mimeType) - - if (editor != null && editor.id == "onlyoffice") { - getWebView().settings.userAgentString = generateOnlyOfficeUserAgent() - } - - getWebView().addJavascriptInterface(MobileInterface(), "DirectEditingMobileInterface") + webView.addJavascriptInterface(MobileInterface(), "DirectEditingMobileInterface") if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) { WebSettingsCompat.setForceDarkStrategy( - getWebView().settings, + webView.settings, WebSettingsCompat.DARK_STRATEGY_WEB_THEME_DARKENING_ONLY ) } if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK) && themeUtils.isDarkModeActive(this)) { - WebSettingsCompat.setForceDark(getWebView().settings, WebSettingsCompat.FORCE_DARK_ON) + WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON) } - getWebView().setDownloadListener { url, _, _, _, _ -> downloadFile(Uri.parse(url)) } + webView.setDownloadListener { url, _, _, _, _ -> downloadFile(Uri.parse(url)) } loadUrl(intent.getStringExtra(ExternalSiteWebView.EXTRA_URL)) } + override fun setUserAgentString(webSettings: WebSettings?) { + val editor = EditorUtils.getEditor(contentResolver, user.get(), file.mimeType) + + if (editor != null && editor.id == ONLYOFFICE) { + webView.settings.userAgentString = generateOnlyOfficeUserAgent() + } + + // For Text/prosemirror we keep default user agent to not mess around with their special treatments + } + override fun loadUrl(url: String?) { if (url.isNullOrEmpty()) { TextEditorLoadUrlTask(this, user.get(), file).execute() @@ -87,4 +92,8 @@ class TextEditorWebView : EditorWebView() { return String.format(userAgent, deviceInfo.androidVersion, appInfo.getAppVersion(this)) } + + companion object { + const val ONLYOFFICE = "onlyoffice" + } } diff --git a/app/src/main/java/com/owncloud/android/ui/asynctasks/TextEditorLoadUrlTask.java b/app/src/main/java/com/owncloud/android/ui/asynctasks/TextEditorLoadUrlTask.java index 54ded9882c..7c2d4723a0 100644 --- a/app/src/main/java/com/owncloud/android/ui/asynctasks/TextEditorLoadUrlTask.java +++ b/app/src/main/java/com/owncloud/android/ui/asynctasks/TextEditorLoadUrlTask.java @@ -26,10 +26,10 @@ import android.os.AsyncTask; import com.nextcloud.android.lib.resources.directediting.DirectEditingOpenFileRemoteOperation; import com.nextcloud.client.account.User; import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.files.FileMenuFilter; import com.owncloud.android.lib.common.Editor; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.ui.activity.EditorWebView; +import com.owncloud.android.utils.EditorUtils; import java.lang.ref.WeakReference; @@ -55,7 +55,7 @@ public class TextEditorLoadUrlTask extends AsyncTask { return ""; } - Editor editor = FileMenuFilter.getEditor(editorWebView.getContentResolver(), user, file.getMimeType()); + Editor editor = EditorUtils.getEditor(editorWebView.getContentResolver(), user, file.getMimeType()); if (editor == null) { return ""; diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java index 741c09cb0c..9e2214bbac 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java @@ -35,19 +35,17 @@ import com.owncloud.android.databinding.FileListActionsBottomSheetCreatorBinding import com.owncloud.android.databinding.FileListActionsBottomSheetFragmentBinding; import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.files.FileMenuFilter; import com.owncloud.android.lib.common.Creator; import com.owncloud.android.lib.common.DirectEditing; import com.owncloud.android.lib.resources.status.OCCapability; import com.owncloud.android.ui.activity.AppScanActivity; import com.owncloud.android.ui.activity.FileActivity; +import com.owncloud.android.utils.EditorUtils; import com.owncloud.android.utils.MimeTypeUtil; import com.owncloud.android.utils.theme.ThemeColorUtils; import com.owncloud.android.utils.theme.ThemeDrawableUtils; import com.owncloud.android.utils.theme.ThemeUtils; -import javax.inject.Inject; - /** * FAB menu {@link android.app.Dialog} styled as a bottom sheet for main actions. */ @@ -155,9 +153,9 @@ public class OCFileListBottomSheetDialog extends BottomSheetDialog implements In } // create rich workspace - if (FileMenuFilter.isEditorAvailable(getContext().getContentResolver(), - user, - MimeTypeUtil.MIMETYPE_TEXT_MARKDOWN) && + if (EditorUtils.isEditorAvailable(getContext().getContentResolver(), + user, + MimeTypeUtil.MIMETYPE_TEXT_MARKDOWN) && file != null && !file.isEncrypted()) { // richWorkspace // == "": no info set -> show button diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 983189f625..65f6caa65b 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -104,6 +104,7 @@ import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.ui.preview.PreviewMediaFragment; import com.owncloud.android.ui.preview.PreviewTextFileFragment; import com.owncloud.android.utils.DisplayUtils; +import com.owncloud.android.utils.EditorUtils; import com.owncloud.android.utils.EncryptionUtils; import com.owncloud.android.utils.FileSortOrder; import com.owncloud.android.utils.FileStorageUtils; @@ -1062,9 +1063,9 @@ public class OCFileListFragment extends ExtendedListFragment implements setFabVisible(false); resetHeaderScrollingState(); ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true, true, true); - } else if (FileMenuFilter.isEditorAvailable(requireContext().getContentResolver(), - accountManager.getUser(), - file.getMimeType()) && + } else if (EditorUtils.isEditorAvailable(requireContext().getContentResolver(), + accountManager.getUser(), + file.getMimeType()) && !file.isEncrypted()) { mContainerActivity.getFileOperationsHelper().openFileWithTextEditor(file, getContext()); } else if (capability.getRichDocumentsMimeTypeList().contains(file.getMimeType()) && @@ -1131,9 +1132,9 @@ public class OCFileListFragment extends ExtendedListFragment implements return true; } else if (itemId == R.id.action_edit) { // should not be necessary, as menu item is filtered, but better play safe - if (FileMenuFilter.isEditorAvailable(requireContext().getContentResolver(), - accountManager.getUser(), - singleFile.getMimeType())) { + if (EditorUtils.isEditorAvailable(requireContext().getContentResolver(), + accountManager.getUser(), + singleFile.getMimeType())) { mContainerActivity.getFileOperationsHelper().openFileWithTextEditor(singleFile, getContext()); } else { mContainerActivity.getFileOperationsHelper().openFileAsRichDocument(singleFile, getContext()); diff --git a/app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java b/app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java index a2b5c20cc6..0491777d62 100755 --- a/app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java +++ b/app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java @@ -55,7 +55,6 @@ import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.datamodel.FileDataStorageManager; import com.owncloud.android.datamodel.OCFile; -import com.owncloud.android.files.FileMenuFilter; import com.owncloud.android.files.StreamMediaFileOperation; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; @@ -82,6 +81,7 @@ import com.owncloud.android.ui.events.FavoriteEvent; import com.owncloud.android.ui.events.FileLockEvent; import com.owncloud.android.ui.events.SyncEventFinished; import com.owncloud.android.utils.DisplayUtils; +import com.owncloud.android.utils.EditorUtils; import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.PermissionUtil; import com.owncloud.android.utils.UriUtils; @@ -302,9 +302,9 @@ public class FileOperationsHelper { if (launchables.isEmpty()) { Optional optionalUser = fileActivity.getUser(); - if (optionalUser.isPresent() && FileMenuFilter.isEditorAvailable(fileActivity.getContentResolver(), - optionalUser.get(), - file.getMimeType())) { + if (optionalUser.isPresent() && EditorUtils.isEditorAvailable(fileActivity.getContentResolver(), + optionalUser.get(), + file.getMimeType())) { openFileWithTextEditor(file, fileActivity); } else { Account account = fileActivity.getAccount(); diff --git a/app/src/main/java/com/owncloud/android/utils/EditorUtils.kt b/app/src/main/java/com/owncloud/android/utils/EditorUtils.kt new file mode 100644 index 0000000000..e776167f05 --- /dev/null +++ b/app/src/main/java/com/owncloud/android/utils/EditorUtils.kt @@ -0,0 +1,48 @@ +/* + * + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2022 Tobias Kaminsky + * Copyright (C) 2022 Nextcloud GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.owncloud.android.utils + +import android.content.ContentResolver +import com.google.gson.Gson +import com.nextcloud.client.account.User +import com.owncloud.android.datamodel.ArbitraryDataProvider +import com.owncloud.android.lib.common.DirectEditing +import com.owncloud.android.lib.common.Editor + +object EditorUtils { + @JvmStatic + fun isEditorAvailable(contentResolver: ContentResolver?, user: User?, mimeType: String?): Boolean { + return getEditor(contentResolver, user, mimeType) != null + } + + @JvmStatic + fun getEditor(contentResolver: ContentResolver?, user: User?, mimeType: String?): Editor? { + val json = ArbitraryDataProvider(contentResolver).getValue(user, ArbitraryDataProvider.DIRECT_EDITING) + if (json.isEmpty()) { + return null + } + val directEditing = Gson().fromJson(json, DirectEditing::class.java) + val editors = directEditing.editors.values + return editors.firstOrNull { it.mimetypes.contains(mimeType) || it.optionalMimetypes.contains(mimeType) } + } +}