Index: android_webview/native/aw_web_contents_delegate.cc |
diff --git a/android_webview/native/aw_web_contents_delegate.cc b/android_webview/native/aw_web_contents_delegate.cc |
index 91454ae28a3ca63d113b35352c45996b267405f6..ddd623d5d13ad31edc9b435c619deb88ae197494 100644 |
--- a/android_webview/native/aw_web_contents_delegate.cc |
+++ b/android_webview/native/aw_web_contents_delegate.cc |
@@ -7,20 +7,38 @@ |
#include "android_webview/browser/aw_javascript_dialog_manager.h" |
#include "android_webview/browser/find_helper.h" |
#include "android_webview/native/aw_contents.h" |
+#include "base/android/jni_array.h" |
+#include "base/android/jni_string.h" |
#include "base/android/scoped_java_ref.h" |
#include "base/lazy_instance.h" |
#include "base/message_loop/message_loop.h" |
+#include "base/strings/string_util.h" |
+#include "content/public/browser/render_process_host.h" |
+#include "content/public/browser/render_view_host.h" |
#include "content/public/browser/web_contents.h" |
+#include "content/public/common/file_chooser_params.h" |
#include "jni/AwWebContentsDelegate_jni.h" |
+#include "ui/shell_dialogs/selected_file_info.h" |
using base::android::AttachCurrentThread; |
+using base::android::ConvertUTF16ToJavaString; |
+using base::android::ConvertUTF8ToJavaString; |
using base::android::ScopedJavaLocalRef; |
+using content::FileChooserParams; |
using content::WebContents; |
namespace android_webview { |
-static base::LazyInstance<AwJavaScriptDialogManager>::Leaky |
+namespace { |
+ |
+// WARNING: these constants are exposed in the public interface Java side, so |
+// must remain in sync with what clients are expecting. |
+const int kFileChooserModeOpenMultiple = 1 << 0; |
+const int kFileChooserModeOpenFolder = 1 << 1; |
+ |
+base::LazyInstance<AwJavaScriptDialogManager>::Leaky |
g_javascript_dialog_manager = LAZY_INSTANCE_INITIALIZER; |
+} |
AwWebContentsDelegate::AwWebContentsDelegate( |
JNIEnv* env, |
@@ -63,8 +81,44 @@ void AwWebContentsDelegate::CanDownload( |
callback.Run(false); |
} |
-void AwWebContentsDelegate::AddNewContents(content::WebContents* source, |
- content::WebContents* new_contents, |
+void AwWebContentsDelegate::RunFileChooser(WebContents* web_contents, |
+ const FileChooserParams& params) { |
+ JNIEnv* env = AttachCurrentThread(); |
+ ScopedJavaLocalRef<jobject> java_delegate = GetJavaDelegate(env); |
+ if (!java_delegate.obj()) |
+ return; |
+ |
+ int mode_flags = 0; |
+ if (params.mode == FileChooserParams::OpenMultiple) { |
+ mode_flags |= kFileChooserModeOpenMultiple; |
+ } else if (params.mode == FileChooserParams::UploadFolder) { |
+ // Folder implies multiple in Chrome. |
+ mode_flags |= kFileChooserModeOpenMultiple | kFileChooserModeOpenFolder; |
+ } else if (params.mode == FileChooserParams::Save) { |
+ // Save not supported, so cancel it. |
+ web_contents->GetRenderViewHost()->FilesSelectedInChooser( |
+ std::vector<ui::SelectedFileInfo>(), |
+ params.mode); |
+ return; |
+ } else { |
+ DCHECK_EQ(FileChooserParams::Open, params.mode); |
+ } |
+ Java_AwWebContentsDelegate_runFileChooser(env, |
+ java_delegate.obj(), |
+ web_contents->GetRenderProcessHost()->GetID(), |
+ web_contents->GetRenderViewHost()->GetRoutingID(), |
+ mode_flags, |
+ ConvertUTF16ToJavaString(env, |
+ JoinString(params.accept_types, ',')).obj(), |
+ params.title.empty() ? NULL : |
+ ConvertUTF16ToJavaString(env, params.title).obj(), |
+ params.default_file_name.empty() ? NULL : |
+ ConvertUTF8ToJavaString(env, params.default_file_name.value()).obj(), |
+ params.capture); |
+} |
+ |
+void AwWebContentsDelegate::AddNewContents(WebContents* source, |
+ WebContents* new_contents, |
WindowOpenDisposition disposition, |
const gfx::Rect& initial_pos, |
bool user_gesture, |
@@ -104,7 +158,7 @@ void AwWebContentsDelegate::AddNewContents(content::WebContents* source, |
} |
} |
-void AwWebContentsDelegate::CloseContents(content::WebContents* source) { |
+void AwWebContentsDelegate::CloseContents(WebContents* source) { |
JNIEnv* env = AttachCurrentThread(); |
ScopedJavaLocalRef<jobject> java_delegate = GetJavaDelegate(env); |
@@ -113,7 +167,7 @@ void AwWebContentsDelegate::CloseContents(content::WebContents* source) { |
} |
} |
-void AwWebContentsDelegate::ActivateContents(content::WebContents* contents) { |
+void AwWebContentsDelegate::ActivateContents(WebContents* contents) { |
JNIEnv* env = AttachCurrentThread(); |
ScopedJavaLocalRef<jobject> java_delegate = GetJavaDelegate(env); |
@@ -133,6 +187,38 @@ void AwWebContentsDelegate::UpdatePreferredSize( |
env, obj.obj(), pref_size.width(), pref_size.height()); |
} |
+static void FilesSelectedInChooser( |
+ JNIEnv* env, jclass clazz, |
+ jint process_id, jint render_id, jint mode_flags, |
+ jobjectArray file_paths) { |
+ content::RenderViewHost* rvh = content::RenderViewHost::FromID(process_id, |
+ render_id); |
+ if (!rvh) |
+ return; |
+ |
+ std::vector<std::string> file_path_str; |
+ // Note file_paths maybe NULL, but this will just yield a zero-length vector. |
+ base::android::AppendJavaStringArrayToStringVector(env, file_paths, |
+ &file_path_str); |
+ std::vector<ui::SelectedFileInfo> files; |
+ files.reserve(file_path_str.size()); |
+ for (size_t i = 0; i < file_path_str.size(); ++i) { |
+ files.push_back(ui::SelectedFileInfo(base::FilePath(file_path_str[i]), |
+ base::FilePath())); |
+ } |
+ FileChooserParams::Mode mode; |
+ if (mode_flags & kFileChooserModeOpenFolder) { |
+ mode = FileChooserParams::UploadFolder; |
+ } else if (mode_flags & kFileChooserModeOpenMultiple) { |
+ mode = FileChooserParams::OpenMultiple; |
+ } else { |
+ mode = FileChooserParams::Open; |
+ } |
+ LOG(INFO) << "File Chooser result: mode = " << mode |
+ << ", file paths = " << JoinString(file_path_str, ":"); |
+ rvh->FilesSelectedInChooser(files, mode); |
+} |
+ |
bool RegisterAwWebContentsDelegate(JNIEnv* env) { |
return RegisterNativesImpl(env); |
} |