Loading CHANGELOG.md +3 −0 Original line number Diff line number Diff line # 72.0.3626.87 * update bookmarks view after import # 72.0.3626.81 * serve empty content for blocked scripts/images (fixes https://github.com/bromite/bromite/issues/238) * keep support of Jelly Bean (workaround for upstream https://bugs.chromium.org/p/chromium/issues/detail?id=923477) Loading build/filters/adblock_entries.h +946 −176 File changed.File size exceeds preview limit. View original file View changed file build/patches/Add-bookmark-import-export-actions-in-bookmarks-activity-and-page.patch→build/patches/Add-bookmark-import-export-actions.patch +210 −55 Original line number Diff line number Diff line From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Wed, 1 Aug 2018 09:19:40 +0200 Subject: Add bookmark import/export actions in bookmarks activity and page Subject: Add bookmark import/export actions Thanks to Arnaud for the snippet on how to add toast notifications Add bookmark import/export actions in bookmarks activity and page Reduce permissions needed for bookmarks import/export Completely remove contacts picker permission from the file dialog --- chrome/android/java/AndroidManifest.xml | 1 - .../java/res/menu/bookmark_action_bar_menu.xml | 14 ++ .../browser/bookmarks/BookmarkActionBar.java | 12 ++ .../chrome/browser/bookmarks/BookmarkActivity.java | 19 ++ .../chrome/browser/bookmarks/BookmarkBridge.java | 56 ++++++ .../chrome/browser/bookmarks/BookmarkActivity.java | 15 ++ .../chrome/browser/bookmarks/BookmarkBridge.java | 46 +++++ .../chrome/browser/bookmarks/BookmarkDelegate.java | 10 + .../chrome/browser/bookmarks/BookmarkManager.java | 20 ++ .../chrome/browser/bookmarks/BookmarkPage.java | 1 + Loading @@ -15,12 +18,28 @@ Thanks to Arnaud for the snippet on how to add toast notifications chrome/browser/BUILD.gn | 8 +- .../browser/android/bookmarks/bookmark_bridge.cc | 215 +++++++++++++++++++++ chrome/browser/android/bookmarks/bookmark_bridge.h | 20 +- chrome/browser/importer/profile_writer.cc | 2 + chrome/browser/importer/profile_writer.cc | 12 ++ chrome/browser/importer/profile_writer.h | 6 + chrome/common/BUILD.gn | 3 + chrome/utility/BUILD.gn | 7 +- chrome/utility/importer/bookmark_html_reader.cc | 27 ++- chrome/utility/importer/bookmark_html_reader.h | 9 + 16 files changed, 419 insertions(+), 10 deletions(-) .../src/org/chromium/ui/base/SelectFileDialog.java | 18 +- ui/shell_dialogs/select_file_dialog.h | 2 + ui/shell_dialogs/select_file_dialog_android.cc | 6 + ui/shell_dialogs/select_file_dialog_android.h | 2 + 22 files changed, 445 insertions(+), 15 deletions(-) diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml @@ -35,7 +35,6 @@ by a child template that "extends" this file. {% endif %} <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH"/> <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH_ADMIN"/> - <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS"/> <uses-permission-sdk-23 android:name="android.permission.REORDER_TASKS"/> <uses-permission-sdk-23 android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> diff --git a/chrome/android/java/res/menu/bookmark_action_bar_menu.xml b/chrome/android/java/res/menu/bookmark_action_bar_menu.xml --- a/chrome/android/java/res/menu/bookmark_action_bar_menu.xml Loading @@ -30,7 +49,7 @@ diff --git a/chrome/android/java/res/menu/bookmark_action_bar_menu.xml b/chrome/ app:iconTint="@color/dark_mode_tint" /> <item + android:id="@+id/import_menu_id" + android:icon="@drawable/add_circle_blue" + android:icon="@drawable/ic_folder_blue_24dp" + android:title="@string/import_bookmarks" + android:visible="true" + app:showAsAction="ifRoom" Loading Loading @@ -108,7 +127,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm static final int EDIT_BOOKMARK_REQUEST_CODE = 14; public static final String INTENT_VISIT_BOOKMARK_ID = "BookmarkEditActivity.VisitBookmarkId"; @@ -32,6 +34,22 @@ public class BookmarkActivity extends SnackbarActivity { @@ -32,6 +34,18 @@ public class BookmarkActivity extends SnackbarActivity { if (TextUtils.isEmpty(url)) url = UrlConstants.BOOKMARKS_URL; mBookmarkManager.updateForUrl(url); setContentView(mBookmarkManager.getView()); Loading @@ -117,10 +136,6 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm + mWindowAndroid = new ActivityWindowAndroid(this, listenToActivityState); + mWindowAndroid.restoreInstanceState(savedInstanceState); + mBookmarkManager.setWindow(mWindowAndroid); + // Set up the animation placeholder to be the SurfaceView. This disables the + // SurfaceView's 'hole' clipping during animations that are notified to the window. +// mWindowAndroid.setAnimationPlaceholderView( +// mBookmarkManager.getContentViewRenderView().getSurfaceView()); + } + + @Override Loading @@ -131,7 +146,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm } @Override @@ -48,6 +66,7 @@ public class BookmarkActivity extends SnackbarActivity { @@ -48,6 +62,7 @@ public class BookmarkActivity extends SnackbarActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Loading @@ -154,7 +169,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm import android.text.TextUtils; import android.util.Pair; @@ -13,11 +17,16 @@ import org.chromium.base.ObserverList; @@ -13,11 +17,15 @@ import org.chromium.base.ObserverList; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.metrics.RecordHistogram; Loading @@ -167,11 +182,10 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.ui.base.PageTransition; +import org.chromium.ui.base.WindowAndroid; +import org.chromium.ui.widget.Toast; import java.util.ArrayList; import java.util.List; @@ -508,6 +517,24 @@ public class BookmarkBridge { @@ -508,6 +516,24 @@ public class BookmarkBridge { } /** Loading @@ -196,19 +210,10 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm * Synchronously gets a list of bookmarks that match the specified search query. * @param query Keyword used for searching bookmarks. * @param maxNumberOfResult Maximum number of result to fetch. @@ -840,6 +867,33 @@ public class BookmarkBridge { @@ -840,6 +866,24 @@ public class BookmarkBridge { depthList.add(depth); } + + @CalledByNative + public void bookmarksImported() { + Context context = ContextUtils.getApplicationContext(); + + //TODO: call this after actual import + //Toast.makeText(ContextUtils.getApplicationContext(), "Bookmarks imported", Toast.LENGTH_LONG).show(); + } + + @CalledByNative + public void bookmarksExported(String bookmarksPath) { + Context context = ContextUtils.getApplicationContext(); Loading @@ -230,7 +235,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm private static List<Pair<Integer, Integer>> createPairsList(int[] left, int[] right) { List<Pair<Integer, Integer>> pairList = new ArrayList<Pair<Integer, Integer>>(); for (int i = 0; i < left.length; i++) { @@ -906,6 +960,8 @@ public class BookmarkBridge { @@ -906,6 +950,8 @@ public class BookmarkBridge { boolean getFolders, boolean getBookmarks, List<BookmarkId> bookmarksList); private native BookmarkId nativeGetChildAt(long nativeBookmarkBridge, long id, int type, int index); Loading Loading @@ -509,27 +514,25 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + select_file_dialog_ = ui::SelectFileDialog::Create( + this, std::make_unique<ChromeSelectFilePolicy>(nullptr)); + + //NOTE: extension and description are not used on Android + //NOTE: extension and description are not used on Android, thus not set + ui::SelectFileDialog::FileTypeInfo file_type_info; + file_type_info.extensions.resize(1); + file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html")); + file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("htm")); + file_type_info.extension_description_overrides.push_back(base::ASCIIToUTF16("Netscape Bookmark")); + file_type_info.allowed_paths = + ui::SelectFileDialog::FileTypeInfo::NATIVE_OR_DRIVE_PATH; + + static const std::vector<base::string16> v_accept_types = { base::UTF8ToUTF16("text/html") }; + + // Android needs the original MIME types and an additional capture value. + std::pair<std::vector<base::string16>, bool> accept_types = + std::make_pair(v_accept_types, /* use_media_capture */ false); + + select_file_dialog_->SelectFile( + ui::SelectFileDialog::SELECT_OPEN_FILE, + base::string16(), + import_path_, + export_path_, + &file_type_info, + 0, + base::FilePath::StringType(), + window, + NULL); + + //NOTE: this should be called after the actual import + Java_BookmarkBridge_bookmarksImported(env, obj); + &accept_types + ); +} + +void BookmarkBridge::ExportBookmarks(JNIEnv* env, Loading @@ -537,20 +540,20 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + DCHECK(IsLoaded()); + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (import_path_.empty()) { + if (!base::android::GetDownloadsDirectory(&import_path_)) { + if (export_path_.empty()) { + if (!base::android::GetDownloadsDirectory(&export_path_)) { + LOG(ERROR) << "Could not retrieve downloads directory for bookmarks export"; + return; + } + import_path_ = import_path_.Append(FILE_PATH_LITERAL("bookmarks.html")); + export_path_ = export_path_.Append(FILE_PATH_LITERAL("bookmarks.html")); + } + + bookmark_html_writer::WriteBookmarks(profile_, import_path_, NULL); + bookmark_html_writer::WriteBookmarks(profile_, export_path_, NULL); + + //NOTE: nothing will be written if write permission has not been granted before + LOG(INFO) << "Bookmarks exported successfully in " << import_path_; + Java_BookmarkBridge_bookmarksExported(env, obj, ConvertUTF8ToJavaString(env, export_path_.MaybeAsASCII())); + + Java_BookmarkBridge_bookmarksExported(env, obj, ConvertUTF8ToJavaString(env, import_path_.MaybeAsASCII())); + //NOTE: nothing will be written if write permission has not been granted before + LOG(INFO) << "Bookmarks exported successfully to " << export_path_; +} + +// Attempts to create a TemplateURL from the provided data. |title| is optional. Loading Loading @@ -578,29 +581,29 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + file.Initialize(path, base::File::FLAG_OPEN | base::File::FLAG_READ); + } + if (!file.IsValid()) { + LOG(ERROR) << "Cannot open bookmarks file for import"; + select_file_dialog_->ShowToast("Cannot open bookmarks file for import"); + return; + } + + auto fileLength = file.GetLength(); + if (-1 == fileLength) { + LOG(ERROR) << "Cannot read bookmarks file length"; + select_file_dialog_->ShowToast("Cannot read bookmarks file length"); + return; + } + + if (fileLength > 10 * 1024 * 1024) { + LOG(ERROR) << "Bookmarks file is too big"; + select_file_dialog_->ShowToast("Bookmark file is bigger than 10MB"); + return; + } + + std::vector<char> buffer(fileLength); + if (-1 == file.ReadAtCurrentPos(buffer.data(), fileLength)) { + LOG(ERROR) << "Could not read bookmarks file"; + select_file_dialog_->ShowToast("Could not read bookmarks file"); + return; + } + + if (buffer.empty()) { + LOG(ERROR) << "Empty bookmarks file"; + select_file_dialog_->ShowToast("Empty bookmarks file"); + return; + } + Loading @@ -618,11 +621,11 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + &search_engines, + nullptr); + + // writing to profile will begin extensive changes and use the same bookmarks model for persisting changes + auto *writer = new ProfileWriter(profile_); + + if (!bookmarks.empty()) { + writer->AddBookmarks(bookmarks, base::ASCIIToUTF16("Imported")); + // adding bookmarks will begin extensive changes to the model + writer->AddBookmarksWithModel(bookmark_model_, bookmarks, base::ASCIIToUTF16("Imported")); + } + if (!search_engines.empty()) { + TemplateURLService::OwnedTemplateURLVector owned_template_urls; Loading @@ -635,8 +638,10 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + writer->AddKeywords(std::move(owned_template_urls), false); + } + + select_file_dialog_->ShowToast("Bookmarks import complete"); + + LOG(INFO) << "Imported " << bookmarks.size() << " bookmarks and " << + search_engines.size() << " search engines from " << import_path_; + search_engines.size() << " search engines from " << path.MaybeAsASCII(); +} + +void BookmarkBridge::FileSelectionCanceled(void* params) { Loading Loading @@ -698,7 +703,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser void ShimBeingDeleted(PartnerBookmarksShim* shim) override; Profile* profile_; + base::FilePath import_path_; + base::FilePath export_path_; JavaObjectWeakGlobalRef weak_java_ref_; bookmarks::BookmarkModel* bookmark_model_; // weak bookmarks::ManagedBookmarkService* managed_bookmark_service_; // weak Loading Loading @@ -727,6 +732,46 @@ diff --git a/chrome/browser/importer/profile_writer.cc b/chrome/browser/importer } void ProfileWriter::AddHomepage(const GURL& home_page) { @@ -123,6 +125,16 @@ void ProfileWriter::AddBookmarks( return; BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile_); + AddBookmarksWithModel(model, bookmarks, top_level_folder_name); +} + +void ProfileWriter::AddBookmarksWithModel( + BookmarkModel* model, + const std::vector<ImportedBookmarkEntry>& bookmarks, + const base::string16& top_level_folder_name) { + if (bookmarks.empty()) + return; + DCHECK(model->loaded()); // If the bookmark bar is currently empty, we should import directly to it. diff --git a/chrome/browser/importer/profile_writer.h b/chrome/browser/importer/profile_writer.h --- a/chrome/browser/importer/profile_writer.h +++ b/chrome/browser/importer/profile_writer.h @@ -12,6 +12,7 @@ #include "base/strings/string16.h" #include "base/time/time.h" #include "build/build_config.h" +#include "components/bookmarks/browser/bookmark_model.h" #include "components/favicon_base/favicon_usage_data.h" #include "components/history/core/browser/history_types.h" #include "components/search_engines/template_url_service.h" @@ -67,6 +68,11 @@ class ProfileWriter : public base::RefCountedThreadSafe<ProfileWriter> { const std::vector<ImportedBookmarkEntry>& bookmarks, const base::string16& top_level_folder_name); + virtual void AddBookmarksWithModel( + bookmarks::BookmarkModel* model, + const std::vector<ImportedBookmarkEntry>& bookmarks, + const base::string16& top_level_folder_name); + virtual void AddFavicons(const favicon_base::FaviconUsageDataList& favicons); // Adds the TemplateURLs in |template_urls| to the local store. diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn Loading Loading @@ -870,6 +915,116 @@ diff --git a/chrome/utility/importer/bookmark_html_reader.h b/chrome/utility/imp // Returns true if |url| should be imported as a search engine, i.e. because it // has replacement terms. Chrome treats such bookmarks as search engines rather // than true bookmarks. diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java @@ -32,6 +32,7 @@ import org.chromium.base.task.AsyncTask; import org.chromium.ui.ContactsPickerListener; import org.chromium.ui.PhotoPickerListener; import org.chromium.ui.R; +import org.chromium.ui.widget.Toast; import org.chromium.ui.UiUtils; import java.io.File; @@ -52,6 +53,7 @@ public class SelectFileDialog private static final String IMAGE_TYPE = "image/"; private static final String VIDEO_TYPE = "video/"; private static final String AUDIO_TYPE = "audio/"; + private static final String HTML_TYPE = "text/html"; private static final String ALL_IMAGE_TYPES = IMAGE_TYPE + "*"; private static final String ALL_VIDEO_TYPES = VIDEO_TYPE + "*"; private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*"; @@ -130,6 +132,11 @@ public class SelectFileDialog mFileTypes = fileTypes; } + @CalledByNative + private void showToast(String message) { + Toast.makeText(ContextUtils.getApplicationContext(), message, Toast.LENGTH_LONG).show(); + } + /** * Creates and starts an intent based on the passed fileTypes and capture value. * @param fileTypes MIME types requested (i.e. "image/*") @@ -159,7 +166,7 @@ public class SelectFileDialog if (!window.hasPermission(Manifest.permission.READ_CONTACTS)) { missingPermissions.add(Manifest.permission.READ_CONTACTS); } - } else if (shouldUsePhotoPicker()) { + } else if (shouldUsePhotoPicker() || shouldShowHtmlTypes()) { if (!window.hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) { missingPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); } @@ -324,9 +331,7 @@ public class SelectFileDialog * 3.) There is a valid Android Activity associated with the file request. */ private boolean shouldUseContactsPicker() { - if (mFileTypes.size() != 1) return false; - if (!mFileTypes.get(0).equals("text/json+contacts")) return false; - return UiUtils.shouldShowContactsPicker() && mWindowAndroid.getActivity().get() != null; + return false; } /** @@ -347,6 +352,7 @@ public class SelectFileDialog } if (!mimeTypes.contains(mimeType)) mimeTypes.add(mimeType); } + if (mimeTypes.size() == 0) return null; return mimeTypes; } @@ -649,6 +655,10 @@ public class SelectFileDialog return countAcceptTypesFor(specificType) > 0; } + private boolean shouldShowHtmlTypes() { + return countAcceptTypesFor(HTML_TYPE) > 0; + } + private boolean shouldShowImageTypes() { return shouldShowTypes(ALL_IMAGE_TYPES, IMAGE_TYPE); } diff --git a/ui/shell_dialogs/select_file_dialog.h b/ui/shell_dialogs/select_file_dialog.h --- a/ui/shell_dialogs/select_file_dialog.h +++ b/ui/shell_dialogs/select_file_dialog.h @@ -187,6 +187,8 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog void* params); bool HasMultipleFileTypeChoices(); + virtual void ShowToast(const std::string& message) = 0; + protected: friend class base::RefCountedThreadSafe<SelectFileDialog>; diff --git a/ui/shell_dialogs/select_file_dialog_android.cc b/ui/shell_dialogs/select_file_dialog_android.cc --- a/ui/shell_dialogs/select_file_dialog_android.cc +++ b/ui/shell_dialogs/select_file_dialog_android.cc @@ -139,6 +139,12 @@ void SelectFileDialogImpl::SelectFileImpl( owning_window->GetJavaObject()); } +void SelectFileDialogImpl::ShowToast(const std::string& message) { + JNIEnv* env = base::android::AttachCurrentThread(); + + Java_SelectFileDialog_showToast(env, java_object_, base::android::ConvertUTF8ToJavaString(env, message)); +} + SelectFileDialogImpl::~SelectFileDialogImpl() { } diff --git a/ui/shell_dialogs/select_file_dialog_android.h b/ui/shell_dialogs/select_file_dialog_android.h --- a/ui/shell_dialogs/select_file_dialog_android.h +++ b/ui/shell_dialogs/select_file_dialog_android.h @@ -55,6 +55,8 @@ class SelectFileDialogImpl : public SelectFileDialog { gfx::NativeWindow owning_window, void* params) override; + void ShowToast(const std::string& message) override; + protected: ~SelectFileDialogImpl() override; -- 2.11.0 build/patches/Reduce-permissions-needed-for-bookmarks-import-export.patchdeleted 100644 → 0 +0 −118 Original line number Diff line number Diff line From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Sat, 10 Nov 2018 16:09:26 +0100 Subject: Reduce permissions needed for bookmarks import/export Completely remove contacts picker permission from the file dialog --- chrome/android/java/AndroidManifest.xml | 1 - chrome/browser/android/bookmarks/bookmark_bridge.cc | 20 +++++++++++++++++--- .../src/org/chromium/ui/base/SelectFileDialog.java | 12 ++++++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml @@ -35,7 +35,6 @@ by a child template that "extends" this file. {% endif %} <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH"/> <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH_ADMIN"/> - <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS"/> <uses-permission-sdk-23 android:name="android.permission.REORDER_TASKS"/> <uses-permission-sdk-23 android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc --- a/chrome/browser/android/bookmarks/bookmark_bridge.cc +++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc @@ -552,14 +552,23 @@ void BookmarkBridge::ImportBookmarks(JNIEnv* env, select_file_dialog_ = ui::SelectFileDialog::Create( this, std::make_unique<ChromeSelectFilePolicy>(nullptr)); - //NOTE: extension and description are not used on Android + //NOTE: extension and description are not used on Android, thus not set ui::SelectFileDialog::FileTypeInfo file_type_info; + +#if defined(OS_ANDROID) + static const std::vector<base::string16> v_accept_types = { base::UTF8ToUTF16("text/html") }; + + // Android needs the original MIME types and an additional capture value. + std::pair<std::vector<base::string16>, bool> accept_types = + std::make_pair(v_accept_types, /* use_media_capture */ false); +#else file_type_info.extensions.resize(1); file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html")); file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("htm")); file_type_info.extension_description_overrides.push_back(base::ASCIIToUTF16("Netscape Bookmark")); file_type_info.allowed_paths = - ui::SelectFileDialog::FileTypeInfo::NATIVE_OR_DRIVE_PATH; + ui::SelectFileDialog::FileTypeInfo::ANY_PATH; +#endif select_file_dialog_->SelectFile( ui::SelectFileDialog::SELECT_OPEN_FILE, @@ -569,7 +578,12 @@ void BookmarkBridge::ImportBookmarks(JNIEnv* env, 0, base::FilePath::StringType(), window, - NULL); +#if defined(OS_ANDROID) + &accept_types +#else + NULL +#endif +); //NOTE: this should be called after the actual import Java_BookmarkBridge_bookmarksImported(env, obj); diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java @@ -52,6 +52,7 @@ public class SelectFileDialog private static final String IMAGE_TYPE = "image/"; private static final String VIDEO_TYPE = "video/"; private static final String AUDIO_TYPE = "audio/"; + private static final String HTML_TYPE = "text/html"; private static final String ALL_IMAGE_TYPES = IMAGE_TYPE + "*"; private static final String ALL_VIDEO_TYPES = VIDEO_TYPE + "*"; private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*"; @@ -159,7 +160,7 @@ public class SelectFileDialog if (!window.hasPermission(Manifest.permission.READ_CONTACTS)) { missingPermissions.add(Manifest.permission.READ_CONTACTS); } - } else if (shouldUsePhotoPicker()) { + } else if (shouldUsePhotoPicker() || shouldShowHtmlTypes()) { if (!window.hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) { missingPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); } @@ -324,9 +325,7 @@ public class SelectFileDialog * 3.) There is a valid Android Activity associated with the file request. */ private boolean shouldUseContactsPicker() { - if (mFileTypes.size() != 1) return false; - if (!mFileTypes.get(0).equals("text/json+contacts")) return false; - return UiUtils.shouldShowContactsPicker() && mWindowAndroid.getActivity().get() != null; + return false; } /** @@ -347,6 +346,7 @@ public class SelectFileDialog } if (!mimeTypes.contains(mimeType)) mimeTypes.add(mimeType); } + if (mimeTypes.size() == 0) return null; return mimeTypes; } @@ -649,6 +649,10 @@ public class SelectFileDialog return countAcceptTypesFor(specificType) > 0; } + private boolean shouldShowHtmlTypes() { + return countAcceptTypesFor(HTML_TYPE) > 0; + } + private boolean shouldShowImageTypes() { return shouldShowTypes(ALL_IMAGE_TYPES, IMAGE_TYPE); } -- 2.11.0 build/patches/Rollback-android-minSdkVersion-from-19-KitKat-to-16-JellyBean.patch +1 −1 Original line number Diff line number Diff line From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Tue, 29 Jan 2019 01:02:07 +0100 Subject: Rollback android:minSdkVersion from 19 (KitKat) to 16 (JellyBean)." Subject: Rollback android:minSdkVersion from 19 (KitKat) to 16 (JellyBean) This reverts commit 9a48587dbd1988cf5066b454e7d09ae35d124366. --- Loading Loading
CHANGELOG.md +3 −0 Original line number Diff line number Diff line # 72.0.3626.87 * update bookmarks view after import # 72.0.3626.81 * serve empty content for blocked scripts/images (fixes https://github.com/bromite/bromite/issues/238) * keep support of Jelly Bean (workaround for upstream https://bugs.chromium.org/p/chromium/issues/detail?id=923477) Loading
build/filters/adblock_entries.h +946 −176 File changed.File size exceeds preview limit. View original file View changed file
build/patches/Add-bookmark-import-export-actions-in-bookmarks-activity-and-page.patch→build/patches/Add-bookmark-import-export-actions.patch +210 −55 Original line number Diff line number Diff line From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Wed, 1 Aug 2018 09:19:40 +0200 Subject: Add bookmark import/export actions in bookmarks activity and page Subject: Add bookmark import/export actions Thanks to Arnaud for the snippet on how to add toast notifications Add bookmark import/export actions in bookmarks activity and page Reduce permissions needed for bookmarks import/export Completely remove contacts picker permission from the file dialog --- chrome/android/java/AndroidManifest.xml | 1 - .../java/res/menu/bookmark_action_bar_menu.xml | 14 ++ .../browser/bookmarks/BookmarkActionBar.java | 12 ++ .../chrome/browser/bookmarks/BookmarkActivity.java | 19 ++ .../chrome/browser/bookmarks/BookmarkBridge.java | 56 ++++++ .../chrome/browser/bookmarks/BookmarkActivity.java | 15 ++ .../chrome/browser/bookmarks/BookmarkBridge.java | 46 +++++ .../chrome/browser/bookmarks/BookmarkDelegate.java | 10 + .../chrome/browser/bookmarks/BookmarkManager.java | 20 ++ .../chrome/browser/bookmarks/BookmarkPage.java | 1 + Loading @@ -15,12 +18,28 @@ Thanks to Arnaud for the snippet on how to add toast notifications chrome/browser/BUILD.gn | 8 +- .../browser/android/bookmarks/bookmark_bridge.cc | 215 +++++++++++++++++++++ chrome/browser/android/bookmarks/bookmark_bridge.h | 20 +- chrome/browser/importer/profile_writer.cc | 2 + chrome/browser/importer/profile_writer.cc | 12 ++ chrome/browser/importer/profile_writer.h | 6 + chrome/common/BUILD.gn | 3 + chrome/utility/BUILD.gn | 7 +- chrome/utility/importer/bookmark_html_reader.cc | 27 ++- chrome/utility/importer/bookmark_html_reader.h | 9 + 16 files changed, 419 insertions(+), 10 deletions(-) .../src/org/chromium/ui/base/SelectFileDialog.java | 18 +- ui/shell_dialogs/select_file_dialog.h | 2 + ui/shell_dialogs/select_file_dialog_android.cc | 6 + ui/shell_dialogs/select_file_dialog_android.h | 2 + 22 files changed, 445 insertions(+), 15 deletions(-) diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml @@ -35,7 +35,6 @@ by a child template that "extends" this file. {% endif %} <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH"/> <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH_ADMIN"/> - <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS"/> <uses-permission-sdk-23 android:name="android.permission.REORDER_TASKS"/> <uses-permission-sdk-23 android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> diff --git a/chrome/android/java/res/menu/bookmark_action_bar_menu.xml b/chrome/android/java/res/menu/bookmark_action_bar_menu.xml --- a/chrome/android/java/res/menu/bookmark_action_bar_menu.xml Loading @@ -30,7 +49,7 @@ diff --git a/chrome/android/java/res/menu/bookmark_action_bar_menu.xml b/chrome/ app:iconTint="@color/dark_mode_tint" /> <item + android:id="@+id/import_menu_id" + android:icon="@drawable/add_circle_blue" + android:icon="@drawable/ic_folder_blue_24dp" + android:title="@string/import_bookmarks" + android:visible="true" + app:showAsAction="ifRoom" Loading Loading @@ -108,7 +127,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm static final int EDIT_BOOKMARK_REQUEST_CODE = 14; public static final String INTENT_VISIT_BOOKMARK_ID = "BookmarkEditActivity.VisitBookmarkId"; @@ -32,6 +34,22 @@ public class BookmarkActivity extends SnackbarActivity { @@ -32,6 +34,18 @@ public class BookmarkActivity extends SnackbarActivity { if (TextUtils.isEmpty(url)) url = UrlConstants.BOOKMARKS_URL; mBookmarkManager.updateForUrl(url); setContentView(mBookmarkManager.getView()); Loading @@ -117,10 +136,6 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm + mWindowAndroid = new ActivityWindowAndroid(this, listenToActivityState); + mWindowAndroid.restoreInstanceState(savedInstanceState); + mBookmarkManager.setWindow(mWindowAndroid); + // Set up the animation placeholder to be the SurfaceView. This disables the + // SurfaceView's 'hole' clipping during animations that are notified to the window. +// mWindowAndroid.setAnimationPlaceholderView( +// mBookmarkManager.getContentViewRenderView().getSurfaceView()); + } + + @Override Loading @@ -131,7 +146,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm } @Override @@ -48,6 +66,7 @@ public class BookmarkActivity extends SnackbarActivity { @@ -48,6 +62,7 @@ public class BookmarkActivity extends SnackbarActivity { @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Loading @@ -154,7 +169,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm import android.text.TextUtils; import android.util.Pair; @@ -13,11 +17,16 @@ import org.chromium.base.ObserverList; @@ -13,11 +17,15 @@ import org.chromium.base.ObserverList; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.metrics.RecordHistogram; Loading @@ -167,11 +182,10 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm import org.chromium.components.url_formatter.UrlFormatter; +import org.chromium.ui.base.PageTransition; +import org.chromium.ui.base.WindowAndroid; +import org.chromium.ui.widget.Toast; import java.util.ArrayList; import java.util.List; @@ -508,6 +517,24 @@ public class BookmarkBridge { @@ -508,6 +516,24 @@ public class BookmarkBridge { } /** Loading @@ -196,19 +210,10 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm * Synchronously gets a list of bookmarks that match the specified search query. * @param query Keyword used for searching bookmarks. * @param maxNumberOfResult Maximum number of result to fetch. @@ -840,6 +867,33 @@ public class BookmarkBridge { @@ -840,6 +866,24 @@ public class BookmarkBridge { depthList.add(depth); } + + @CalledByNative + public void bookmarksImported() { + Context context = ContextUtils.getApplicationContext(); + + //TODO: call this after actual import + //Toast.makeText(ContextUtils.getApplicationContext(), "Bookmarks imported", Toast.LENGTH_LONG).show(); + } + + @CalledByNative + public void bookmarksExported(String bookmarksPath) { + Context context = ContextUtils.getApplicationContext(); Loading @@ -230,7 +235,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm private static List<Pair<Integer, Integer>> createPairsList(int[] left, int[] right) { List<Pair<Integer, Integer>> pairList = new ArrayList<Pair<Integer, Integer>>(); for (int i = 0; i < left.length; i++) { @@ -906,6 +960,8 @@ public class BookmarkBridge { @@ -906,6 +950,8 @@ public class BookmarkBridge { boolean getFolders, boolean getBookmarks, List<BookmarkId> bookmarksList); private native BookmarkId nativeGetChildAt(long nativeBookmarkBridge, long id, int type, int index); Loading Loading @@ -509,27 +514,25 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + select_file_dialog_ = ui::SelectFileDialog::Create( + this, std::make_unique<ChromeSelectFilePolicy>(nullptr)); + + //NOTE: extension and description are not used on Android + //NOTE: extension and description are not used on Android, thus not set + ui::SelectFileDialog::FileTypeInfo file_type_info; + file_type_info.extensions.resize(1); + file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html")); + file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("htm")); + file_type_info.extension_description_overrides.push_back(base::ASCIIToUTF16("Netscape Bookmark")); + file_type_info.allowed_paths = + ui::SelectFileDialog::FileTypeInfo::NATIVE_OR_DRIVE_PATH; + + static const std::vector<base::string16> v_accept_types = { base::UTF8ToUTF16("text/html") }; + + // Android needs the original MIME types and an additional capture value. + std::pair<std::vector<base::string16>, bool> accept_types = + std::make_pair(v_accept_types, /* use_media_capture */ false); + + select_file_dialog_->SelectFile( + ui::SelectFileDialog::SELECT_OPEN_FILE, + base::string16(), + import_path_, + export_path_, + &file_type_info, + 0, + base::FilePath::StringType(), + window, + NULL); + + //NOTE: this should be called after the actual import + Java_BookmarkBridge_bookmarksImported(env, obj); + &accept_types + ); +} + +void BookmarkBridge::ExportBookmarks(JNIEnv* env, Loading @@ -537,20 +540,20 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + DCHECK(IsLoaded()); + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (import_path_.empty()) { + if (!base::android::GetDownloadsDirectory(&import_path_)) { + if (export_path_.empty()) { + if (!base::android::GetDownloadsDirectory(&export_path_)) { + LOG(ERROR) << "Could not retrieve downloads directory for bookmarks export"; + return; + } + import_path_ = import_path_.Append(FILE_PATH_LITERAL("bookmarks.html")); + export_path_ = export_path_.Append(FILE_PATH_LITERAL("bookmarks.html")); + } + + bookmark_html_writer::WriteBookmarks(profile_, import_path_, NULL); + bookmark_html_writer::WriteBookmarks(profile_, export_path_, NULL); + + //NOTE: nothing will be written if write permission has not been granted before + LOG(INFO) << "Bookmarks exported successfully in " << import_path_; + Java_BookmarkBridge_bookmarksExported(env, obj, ConvertUTF8ToJavaString(env, export_path_.MaybeAsASCII())); + + Java_BookmarkBridge_bookmarksExported(env, obj, ConvertUTF8ToJavaString(env, import_path_.MaybeAsASCII())); + //NOTE: nothing will be written if write permission has not been granted before + LOG(INFO) << "Bookmarks exported successfully to " << export_path_; +} + +// Attempts to create a TemplateURL from the provided data. |title| is optional. Loading Loading @@ -578,29 +581,29 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + file.Initialize(path, base::File::FLAG_OPEN | base::File::FLAG_READ); + } + if (!file.IsValid()) { + LOG(ERROR) << "Cannot open bookmarks file for import"; + select_file_dialog_->ShowToast("Cannot open bookmarks file for import"); + return; + } + + auto fileLength = file.GetLength(); + if (-1 == fileLength) { + LOG(ERROR) << "Cannot read bookmarks file length"; + select_file_dialog_->ShowToast("Cannot read bookmarks file length"); + return; + } + + if (fileLength > 10 * 1024 * 1024) { + LOG(ERROR) << "Bookmarks file is too big"; + select_file_dialog_->ShowToast("Bookmark file is bigger than 10MB"); + return; + } + + std::vector<char> buffer(fileLength); + if (-1 == file.ReadAtCurrentPos(buffer.data(), fileLength)) { + LOG(ERROR) << "Could not read bookmarks file"; + select_file_dialog_->ShowToast("Could not read bookmarks file"); + return; + } + + if (buffer.empty()) { + LOG(ERROR) << "Empty bookmarks file"; + select_file_dialog_->ShowToast("Empty bookmarks file"); + return; + } + Loading @@ -618,11 +621,11 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + &search_engines, + nullptr); + + // writing to profile will begin extensive changes and use the same bookmarks model for persisting changes + auto *writer = new ProfileWriter(profile_); + + if (!bookmarks.empty()) { + writer->AddBookmarks(bookmarks, base::ASCIIToUTF16("Imported")); + // adding bookmarks will begin extensive changes to the model + writer->AddBookmarksWithModel(bookmark_model_, bookmarks, base::ASCIIToUTF16("Imported")); + } + if (!search_engines.empty()) { + TemplateURLService::OwnedTemplateURLVector owned_template_urls; Loading @@ -635,8 +638,10 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse + writer->AddKeywords(std::move(owned_template_urls), false); + } + + select_file_dialog_->ShowToast("Bookmarks import complete"); + + LOG(INFO) << "Imported " << bookmarks.size() << " bookmarks and " << + search_engines.size() << " search engines from " << import_path_; + search_engines.size() << " search engines from " << path.MaybeAsASCII(); +} + +void BookmarkBridge::FileSelectionCanceled(void* params) { Loading Loading @@ -698,7 +703,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser void ShimBeingDeleted(PartnerBookmarksShim* shim) override; Profile* profile_; + base::FilePath import_path_; + base::FilePath export_path_; JavaObjectWeakGlobalRef weak_java_ref_; bookmarks::BookmarkModel* bookmark_model_; // weak bookmarks::ManagedBookmarkService* managed_bookmark_service_; // weak Loading Loading @@ -727,6 +732,46 @@ diff --git a/chrome/browser/importer/profile_writer.cc b/chrome/browser/importer } void ProfileWriter::AddHomepage(const GURL& home_page) { @@ -123,6 +125,16 @@ void ProfileWriter::AddBookmarks( return; BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile_); + AddBookmarksWithModel(model, bookmarks, top_level_folder_name); +} + +void ProfileWriter::AddBookmarksWithModel( + BookmarkModel* model, + const std::vector<ImportedBookmarkEntry>& bookmarks, + const base::string16& top_level_folder_name) { + if (bookmarks.empty()) + return; + DCHECK(model->loaded()); // If the bookmark bar is currently empty, we should import directly to it. diff --git a/chrome/browser/importer/profile_writer.h b/chrome/browser/importer/profile_writer.h --- a/chrome/browser/importer/profile_writer.h +++ b/chrome/browser/importer/profile_writer.h @@ -12,6 +12,7 @@ #include "base/strings/string16.h" #include "base/time/time.h" #include "build/build_config.h" +#include "components/bookmarks/browser/bookmark_model.h" #include "components/favicon_base/favicon_usage_data.h" #include "components/history/core/browser/history_types.h" #include "components/search_engines/template_url_service.h" @@ -67,6 +68,11 @@ class ProfileWriter : public base::RefCountedThreadSafe<ProfileWriter> { const std::vector<ImportedBookmarkEntry>& bookmarks, const base::string16& top_level_folder_name); + virtual void AddBookmarksWithModel( + bookmarks::BookmarkModel* model, + const std::vector<ImportedBookmarkEntry>& bookmarks, + const base::string16& top_level_folder_name); + virtual void AddFavicons(const favicon_base::FaviconUsageDataList& favicons); // Adds the TemplateURLs in |template_urls| to the local store. diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn Loading Loading @@ -870,6 +915,116 @@ diff --git a/chrome/utility/importer/bookmark_html_reader.h b/chrome/utility/imp // Returns true if |url| should be imported as a search engine, i.e. because it // has replacement terms. Chrome treats such bookmarks as search engines rather // than true bookmarks. diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java @@ -32,6 +32,7 @@ import org.chromium.base.task.AsyncTask; import org.chromium.ui.ContactsPickerListener; import org.chromium.ui.PhotoPickerListener; import org.chromium.ui.R; +import org.chromium.ui.widget.Toast; import org.chromium.ui.UiUtils; import java.io.File; @@ -52,6 +53,7 @@ public class SelectFileDialog private static final String IMAGE_TYPE = "image/"; private static final String VIDEO_TYPE = "video/"; private static final String AUDIO_TYPE = "audio/"; + private static final String HTML_TYPE = "text/html"; private static final String ALL_IMAGE_TYPES = IMAGE_TYPE + "*"; private static final String ALL_VIDEO_TYPES = VIDEO_TYPE + "*"; private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*"; @@ -130,6 +132,11 @@ public class SelectFileDialog mFileTypes = fileTypes; } + @CalledByNative + private void showToast(String message) { + Toast.makeText(ContextUtils.getApplicationContext(), message, Toast.LENGTH_LONG).show(); + } + /** * Creates and starts an intent based on the passed fileTypes and capture value. * @param fileTypes MIME types requested (i.e. "image/*") @@ -159,7 +166,7 @@ public class SelectFileDialog if (!window.hasPermission(Manifest.permission.READ_CONTACTS)) { missingPermissions.add(Manifest.permission.READ_CONTACTS); } - } else if (shouldUsePhotoPicker()) { + } else if (shouldUsePhotoPicker() || shouldShowHtmlTypes()) { if (!window.hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) { missingPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); } @@ -324,9 +331,7 @@ public class SelectFileDialog * 3.) There is a valid Android Activity associated with the file request. */ private boolean shouldUseContactsPicker() { - if (mFileTypes.size() != 1) return false; - if (!mFileTypes.get(0).equals("text/json+contacts")) return false; - return UiUtils.shouldShowContactsPicker() && mWindowAndroid.getActivity().get() != null; + return false; } /** @@ -347,6 +352,7 @@ public class SelectFileDialog } if (!mimeTypes.contains(mimeType)) mimeTypes.add(mimeType); } + if (mimeTypes.size() == 0) return null; return mimeTypes; } @@ -649,6 +655,10 @@ public class SelectFileDialog return countAcceptTypesFor(specificType) > 0; } + private boolean shouldShowHtmlTypes() { + return countAcceptTypesFor(HTML_TYPE) > 0; + } + private boolean shouldShowImageTypes() { return shouldShowTypes(ALL_IMAGE_TYPES, IMAGE_TYPE); } diff --git a/ui/shell_dialogs/select_file_dialog.h b/ui/shell_dialogs/select_file_dialog.h --- a/ui/shell_dialogs/select_file_dialog.h +++ b/ui/shell_dialogs/select_file_dialog.h @@ -187,6 +187,8 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog void* params); bool HasMultipleFileTypeChoices(); + virtual void ShowToast(const std::string& message) = 0; + protected: friend class base::RefCountedThreadSafe<SelectFileDialog>; diff --git a/ui/shell_dialogs/select_file_dialog_android.cc b/ui/shell_dialogs/select_file_dialog_android.cc --- a/ui/shell_dialogs/select_file_dialog_android.cc +++ b/ui/shell_dialogs/select_file_dialog_android.cc @@ -139,6 +139,12 @@ void SelectFileDialogImpl::SelectFileImpl( owning_window->GetJavaObject()); } +void SelectFileDialogImpl::ShowToast(const std::string& message) { + JNIEnv* env = base::android::AttachCurrentThread(); + + Java_SelectFileDialog_showToast(env, java_object_, base::android::ConvertUTF8ToJavaString(env, message)); +} + SelectFileDialogImpl::~SelectFileDialogImpl() { } diff --git a/ui/shell_dialogs/select_file_dialog_android.h b/ui/shell_dialogs/select_file_dialog_android.h --- a/ui/shell_dialogs/select_file_dialog_android.h +++ b/ui/shell_dialogs/select_file_dialog_android.h @@ -55,6 +55,8 @@ class SelectFileDialogImpl : public SelectFileDialog { gfx::NativeWindow owning_window, void* params) override; + void ShowToast(const std::string& message) override; + protected: ~SelectFileDialogImpl() override; -- 2.11.0
build/patches/Reduce-permissions-needed-for-bookmarks-import-export.patchdeleted 100644 → 0 +0 −118 Original line number Diff line number Diff line From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Sat, 10 Nov 2018 16:09:26 +0100 Subject: Reduce permissions needed for bookmarks import/export Completely remove contacts picker permission from the file dialog --- chrome/android/java/AndroidManifest.xml | 1 - chrome/browser/android/bookmarks/bookmark_bridge.cc | 20 +++++++++++++++++--- .../src/org/chromium/ui/base/SelectFileDialog.java | 12 ++++++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml @@ -35,7 +35,6 @@ by a child template that "extends" this file. {% endif %} <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH"/> <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH_ADMIN"/> - <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS"/> <uses-permission-sdk-23 android:name="android.permission.REORDER_TASKS"/> <uses-permission-sdk-23 android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc --- a/chrome/browser/android/bookmarks/bookmark_bridge.cc +++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc @@ -552,14 +552,23 @@ void BookmarkBridge::ImportBookmarks(JNIEnv* env, select_file_dialog_ = ui::SelectFileDialog::Create( this, std::make_unique<ChromeSelectFilePolicy>(nullptr)); - //NOTE: extension and description are not used on Android + //NOTE: extension and description are not used on Android, thus not set ui::SelectFileDialog::FileTypeInfo file_type_info; + +#if defined(OS_ANDROID) + static const std::vector<base::string16> v_accept_types = { base::UTF8ToUTF16("text/html") }; + + // Android needs the original MIME types and an additional capture value. + std::pair<std::vector<base::string16>, bool> accept_types = + std::make_pair(v_accept_types, /* use_media_capture */ false); +#else file_type_info.extensions.resize(1); file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html")); file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("htm")); file_type_info.extension_description_overrides.push_back(base::ASCIIToUTF16("Netscape Bookmark")); file_type_info.allowed_paths = - ui::SelectFileDialog::FileTypeInfo::NATIVE_OR_DRIVE_PATH; + ui::SelectFileDialog::FileTypeInfo::ANY_PATH; +#endif select_file_dialog_->SelectFile( ui::SelectFileDialog::SELECT_OPEN_FILE, @@ -569,7 +578,12 @@ void BookmarkBridge::ImportBookmarks(JNIEnv* env, 0, base::FilePath::StringType(), window, - NULL); +#if defined(OS_ANDROID) + &accept_types +#else + NULL +#endif +); //NOTE: this should be called after the actual import Java_BookmarkBridge_bookmarksImported(env, obj); diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java @@ -52,6 +52,7 @@ public class SelectFileDialog private static final String IMAGE_TYPE = "image/"; private static final String VIDEO_TYPE = "video/"; private static final String AUDIO_TYPE = "audio/"; + private static final String HTML_TYPE = "text/html"; private static final String ALL_IMAGE_TYPES = IMAGE_TYPE + "*"; private static final String ALL_VIDEO_TYPES = VIDEO_TYPE + "*"; private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*"; @@ -159,7 +160,7 @@ public class SelectFileDialog if (!window.hasPermission(Manifest.permission.READ_CONTACTS)) { missingPermissions.add(Manifest.permission.READ_CONTACTS); } - } else if (shouldUsePhotoPicker()) { + } else if (shouldUsePhotoPicker() || shouldShowHtmlTypes()) { if (!window.hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) { missingPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); } @@ -324,9 +325,7 @@ public class SelectFileDialog * 3.) There is a valid Android Activity associated with the file request. */ private boolean shouldUseContactsPicker() { - if (mFileTypes.size() != 1) return false; - if (!mFileTypes.get(0).equals("text/json+contacts")) return false; - return UiUtils.shouldShowContactsPicker() && mWindowAndroid.getActivity().get() != null; + return false; } /** @@ -347,6 +346,7 @@ public class SelectFileDialog } if (!mimeTypes.contains(mimeType)) mimeTypes.add(mimeType); } + if (mimeTypes.size() == 0) return null; return mimeTypes; } @@ -649,6 +649,10 @@ public class SelectFileDialog return countAcceptTypesFor(specificType) > 0; } + private boolean shouldShowHtmlTypes() { + return countAcceptTypesFor(HTML_TYPE) > 0; + } + private boolean shouldShowImageTypes() { return shouldShowTypes(ALL_IMAGE_TYPES, IMAGE_TYPE); } -- 2.11.0
build/patches/Rollback-android-minSdkVersion-from-19-KitKat-to-16-JellyBean.patch +1 −1 Original line number Diff line number Diff line From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Tue, 29 Jan 2019 01:02:07 +0100 Subject: Rollback android:minSdkVersion from 19 (KitKat) to 16 (JellyBean)." Subject: Rollback android:minSdkVersion from 19 (KitKat) to 16 (JellyBean) This reverts commit 9a48587dbd1988cf5066b454e7d09ae35d124366. --- Loading