| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/download/internal/common/android/download_collection_bridge.h" |
| |
| #include <utility> |
| |
| #include "base/android/jni_android.h" |
| #include "base/android/jni_string.h" |
| #include "base/files/file_util.h" |
| #include "base/metrics/field_trial_params.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "components/download/internal/common/jni_headers/DownloadCollectionBridge_jni.h" |
| #include "components/download/public/common/download_features.h" |
| #include "components/download/public/common/download_interrupt_reasons.h" |
| |
| using base::android::ConvertJavaStringToUTF8; |
| using base::android::ConvertUTF16ToJavaString; |
| using base::android::ConvertUTF8ToJavaString; |
| using base::android::JavaParamRef; |
| using base::android::ScopedJavaLocalRef; |
| |
| namespace download { |
| |
| namespace { |
| // Default value for |kDownloadExpirationDurationFinchKey|, when no parameter is |
| // specified. |
| const int kDefaultExpirationDurationInDays = 3; |
| |
| // Finch parameter key value of the duration in days for an intermediate |
| // download to expire. |
| constexpr char kDownloadExpirationDurationFinchKey[] = "expiration_duration"; |
| } // namespace |
| // static |
| base::FilePath DownloadCollectionBridge::CreateIntermediateUriForPublish( |
| const GURL& original_url, |
| const GURL& referrer_url, |
| const base::FilePath& file_name, |
| const std::string& mime_type) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> jurl = |
| ConvertUTF8ToJavaString(env, original_url.spec()); |
| ScopedJavaLocalRef<jstring> jreferrer = |
| ConvertUTF8ToJavaString(env, referrer_url.spec()); |
| ScopedJavaLocalRef<jstring> jfile_name = |
| ConvertUTF16ToJavaString(env, file_name.AsUTF16Unsafe()); |
| ScopedJavaLocalRef<jstring> jmime_type = |
| ConvertUTF8ToJavaString(env, mime_type); |
| ScopedJavaLocalRef<jstring> jcontent_uri = |
| Java_DownloadCollectionBridge_createIntermediateUriForPublish( |
| env, jfile_name, jmime_type, jurl, jreferrer); |
| if (jcontent_uri) { |
| std::string content_uri = ConvertJavaStringToUTF8(env, jcontent_uri); |
| return base::FilePath(content_uri); |
| } |
| return base::FilePath(); |
| } |
| |
| // static |
| bool DownloadCollectionBridge::ShouldPublishDownload( |
| const base::FilePath& file_path) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> jfile_path = |
| ConvertUTF16ToJavaString(env, file_path.AsUTF16Unsafe()); |
| return Java_DownloadCollectionBridge_shouldPublishDownload(env, jfile_path); |
| } |
| |
| // static |
| DownloadInterruptReason DownloadCollectionBridge::MoveFileToIntermediateUri( |
| const base::FilePath& source_path, |
| const base::FilePath& destination_uri) { |
| DCHECK(!source_path.IsContentUri()); |
| DCHECK(destination_uri.IsContentUri()); |
| |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> jsource = |
| ConvertUTF8ToJavaString(env, source_path.value()); |
| ScopedJavaLocalRef<jstring> jdestination = |
| ConvertUTF8ToJavaString(env, destination_uri.value()); |
| bool success = Java_DownloadCollectionBridge_copyFileToIntermediateUri( |
| env, jsource, jdestination); |
| base::DeleteFile(source_path, false); |
| return success ? DOWNLOAD_INTERRUPT_REASON_NONE |
| : DOWNLOAD_INTERRUPT_REASON_FILE_FAILED; |
| } |
| |
| // static |
| void DownloadCollectionBridge::DeleteIntermediateUri( |
| const base::FilePath& intermediate_uri) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> juri = |
| ConvertUTF8ToJavaString(env, intermediate_uri.value()); |
| Java_DownloadCollectionBridge_deleteIntermediateUri(env, juri); |
| } |
| |
| // static |
| base::FilePath DownloadCollectionBridge::PublishDownload( |
| const base::FilePath& intermediate_uri) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> jintermediate_uri = |
| ConvertUTF8ToJavaString(env, intermediate_uri.value()); |
| ScopedJavaLocalRef<jstring> jfinal_uri = |
| Java_DownloadCollectionBridge_publishDownload(env, jintermediate_uri); |
| if (jfinal_uri) { |
| std::string final_uri = ConvertJavaStringToUTF8(env, jfinal_uri); |
| return base::FilePath(final_uri); |
| } |
| return base::FilePath(); |
| } |
| |
| // static |
| base::File DownloadCollectionBridge::OpenIntermediateUri( |
| const base::FilePath& intermediate_uri) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> jintermediate_uri = |
| ConvertUTF8ToJavaString(env, intermediate_uri.value()); |
| int fd = |
| Java_DownloadCollectionBridge_openIntermediateUri(env, jintermediate_uri); |
| if (fd < 0) |
| return base::File(); |
| return base::File(fd); |
| } |
| |
| // static |
| bool DownloadCollectionBridge::FileNameExists(const base::FilePath& file_name) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> jfile_name = |
| ConvertUTF8ToJavaString(env, file_name.value()); |
| return Java_DownloadCollectionBridge_fileNameExists(env, jfile_name); |
| } |
| |
| // static |
| bool DownloadCollectionBridge::RenameDownloadUri( |
| const base::FilePath& download_uri, |
| const base::FilePath& new_display_name) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> jdownload_uri = |
| ConvertUTF8ToJavaString(env, download_uri.value()); |
| ScopedJavaLocalRef<jstring> jdisplay_name = |
| ConvertUTF8ToJavaString(env, new_display_name.value()); |
| return Java_DownloadCollectionBridge_renameDownloadUri(env, jdownload_uri, |
| jdisplay_name); |
| } |
| |
| // static |
| void DownloadCollectionBridge::GetDisplayNamesForDownloads( |
| GetDisplayNamesCallback cb) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jobjectArray> jdisplay_infos = |
| Java_DownloadCollectionBridge_getDisplayNamesForDownloads(env); |
| auto result = std::make_unique<std::map<std::string, base::FilePath>>(); |
| if (!jdisplay_infos) { |
| std::move(cb).Run(std::move(result)); |
| return; |
| } |
| for (auto jdisplay_info : jdisplay_infos.ReadElements<jobject>()) { |
| ScopedJavaLocalRef<jstring> juri = |
| Java_DisplayNameInfo_getDownloadUri(env, jdisplay_info); |
| ScopedJavaLocalRef<jstring> jdisplay_name = |
| Java_DisplayNameInfo_getDisplayName(env, jdisplay_info); |
| if (juri && jdisplay_name) { |
| std::string uri = ConvertJavaStringToUTF8(env, juri); |
| std::string display_name = ConvertJavaStringToUTF8(env, jdisplay_name); |
| result->emplace(uri, display_name); |
| } |
| } |
| std::move(cb).Run(std::move(result)); |
| } |
| |
| // static |
| bool DownloadCollectionBridge::NeedToRetrieveDisplayNames() { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| return Java_DownloadCollectionBridge_needToRetrieveDisplayNames(env); |
| } |
| |
| // static |
| base::FilePath DownloadCollectionBridge::GetDisplayName( |
| const base::FilePath& download_uri) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jstring> jdownload_uri = |
| ConvertUTF8ToJavaString(env, download_uri.value()); |
| ScopedJavaLocalRef<jstring> jdisplay_name = |
| Java_DownloadCollectionBridge_getDisplayName(env, jdownload_uri); |
| if (jdisplay_name) { |
| std::string display_name = ConvertJavaStringToUTF8(env, jdisplay_name); |
| return base::FilePath(display_name); |
| } |
| return base::FilePath(); |
| } |
| |
| jint JNI_DownloadCollectionBridge_GetExpirationDurationInDays(JNIEnv* env) { |
| std::string finch_value = base::GetFieldTrialParamValueByFeature( |
| features::kRefreshExpirationDate, kDownloadExpirationDurationFinchKey); |
| int days; |
| return base::StringToInt(finch_value, &days) |
| ? days |
| : kDefaultExpirationDurationInDays; |
| } |
| |
| } // namespace download |