[M120 Migration][VD] Add ewk_file_chooser_request APIs 37/307037/3
authorjiangyuwei <yuwei.jiang@samsung.com>
Mon, 4 Mar 2024 22:33:47 +0000 (06:33 +0800)
committerBot Blink <blinkbot@samsung.com>
Mon, 4 Mar 2024 09:31:15 +0000 (09:31 +0000)
Evas smart callback, "file,chooser,request", has not been supported
since Tizen 3.0. This patch implements ewk_file_chooser_request APIs
to suport "file,chooser,request". API spec is same as Tizen 2.4(WebKit).

- ewk_file_chooser_request_allow_multiple_files_get
- ewk_file_chooser_request_accepted_mimetypes_get
- ewk_file_chooser_request_cancel
- ewk_file_chooser_request_files_choose
- ewk_file_chooser_request_file_choose

Reference:
 - https://review.tizen.org/gerrit/#/c/292148/

Change-Id: I62bb4192d615099f84766b2be5a29af0387ab3ee
Signed-off-by: jiangyuwei <yuwei.jiang@samsung.com>
22 files changed:
third_party/blink/renderer/core/page/chrome_client_impl.cc
tizen_src/ewk/efl_integration/BUILD.gn
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view.h
tizen_src/ewk/efl_integration/eweb_view_callbacks.h
tizen_src/ewk/efl_integration/file_chooser_controller_efl.cc
tizen_src/ewk/efl_integration/file_chooser_controller_efl.h
tizen_src/ewk/efl_integration/private/ewk_file_chooser_request_private.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/private/ewk_file_chooser_request_private.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/public/EWebKit_product.h
tizen_src/ewk/efl_integration/public/ewk_file_chooser_request.cc [new file with mode: 0644]
tizen_src/ewk/efl_integration/public/ewk_file_chooser_request_product.h [new file with mode: 0644]
tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc
tizen_src/ewk/unittest/BUILD.gn
tizen_src/ewk/unittest/resources/ewk_file_chooser_request/file_chooser.html [new file with mode: 0644]
tizen_src/ewk/unittest/utc_blink_ewk_base.cpp
tizen_src/ewk/unittest/utc_blink_ewk_base.h
tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_accepted_mimetypes_get_func.cpp [new file with mode: 0644]
tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_allow_multiple_files_get_func.cpp [new file with mode: 0644]
tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_cancel_func.cpp [new file with mode: 0644]
tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_file_choose_func.cpp [new file with mode: 0644]
tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_files_choose_func.cpp [new file with mode: 0644]

index b7b83e0..bb97131 100644 (file)
@@ -764,6 +764,9 @@ void ChromeClientImpl::OpenFileChooser(
   NotifyPopupOpeningObservers();
 
   static const wtf_size_t kMaximumPendingFileChooseRequests = 4;
+#if BUILDFLAG(IS_TIZEN_TV)
+  LOG(INFO) << "OpenFileChooser, queue size : " << file_chooser_queue_.size();
+#endif
   if (file_chooser_queue_.size() > kMaximumPendingFileChooseRequests) {
     // This check prevents too many file choose requests from getting
     // queued which could DoS the user. Getting these is most likely a
@@ -778,14 +781,22 @@ void ChromeClientImpl::OpenFileChooser(
   file_chooser_queue_.push_back(file_chooser.get());
   if (file_chooser_queue_.size() == 1) {
     // Actually show the browse dialog when this is the first request.
-    if (file_chooser->OpenFileChooser(*this))
+    if (file_chooser->OpenFileChooser(*this)) {
+#if BUILDFLAG(IS_TIZEN_TV)
+      file_chooser_queue_.EraseAt(0);
+#endif
       return;
+    }
     // Choosing failed, so try the next chooser.
     DidCompleteFileChooser(*file_chooser);
   }
 }
 
 void ChromeClientImpl::DidCompleteFileChooser(FileChooser& chooser) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  if (file_chooser_queue_.empty())
+    return;
+#endif
   if (!file_chooser_queue_.empty() &&
       file_chooser_queue_.front().get() != &chooser) {
     // This function is called even if |chooser| wasn't stored in
index 2a48e3e..aebebfd 100644 (file)
@@ -278,6 +278,8 @@ shared_library("chromium-ewk") {
     "eweb_view_callbacks.h",
     "ewk_global_data.cc",
     "ewk_global_data.h",
+    "file_chooser_controller_efl.cc",
+    "file_chooser_controller_efl.h",
     "geolocation_permission_popup.cc",
     "geolocation_permission_popup.h",
     "http_user_agent_settings_efl.cc",
@@ -415,6 +417,8 @@ shared_library("chromium-ewk") {
     "private/ewk_error_private.cc",
     "private/ewk_error_private.h",
     "private/ewk_favicon_database_private.h",
+    "private/ewk_file_chooser_request_private.cc",
+    "private/ewk_file_chooser_request_private.h",
     "private/ewk_frame_private.cc",
     "private/ewk_frame_private.h",
     "private/ewk_geolocation_private.cc",
@@ -508,6 +512,8 @@ shared_library("chromium-ewk") {
     "public/ewk_export.h",
     "public/ewk_favicon_database.cc",
     "public/ewk_favicon_database_internal.h",
+    "public/ewk_file_chooser_request.cc",
+    "public/ewk_file_chooser_request_product.h",
     "public/ewk_form_repost_decision.cc",
     "public/ewk_form_repost_decision_product.h",
     "public/ewk_frame.cc",
@@ -690,8 +696,6 @@ shared_library("chromium-ewk") {
       "browser/quota_permission_context_efl.cc",
       "browser/quota_permission_context_efl.h",
       "chromium_ewk.gypi",
-      "file_chooser_controller_efl.cc",
-      "file_chooser_controller_efl.h",
       "renderer/plugins/hole_layer.cc",
       "renderer/plugins/hole_layer.h",
       "renderer/plugins/plugin_placeholder_avplayer.cc",
index bef9a78..98e9661 100644 (file)
@@ -9,7 +9,6 @@
 #include <Elementary.h>
 
 #include "base/command_line.h"
-#include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/functional/bind.h"
 #include "base/json/json_string_value_serializer.h"
 #endif
 
 #if BUILDFLAG(IS_TIZEN_TV)
+#include "browser/mixed_content_observer.h"
 #include "common/application_type.h"
 #include "devtools_port_manager.h"
+#include "private/ewk_file_chooser_request_private.h"
 #include "public/ewk_media_downloadable_font_info.h"
 #include "public/ewk_user_media_internal.h"
-#include "browser/mixed_content_observer.h"
 #endif
 
 #if defined(TIZEN_PEPPER_EXTENSIONS)
@@ -2512,28 +2512,20 @@ bool EWebView::IsDragging() const {
   return wcva()->wcva_helper()->IsDragging();
 }
 
-void EWebView::ShowFileChooser(content::RenderFrameHost* render_frame_host,
-                               const blink::mojom::FileChooserParams& params) {
+void EWebView::ShowFileChooser(
+    scoped_refptr<content::FileSelectListener> listener,
+    const blink::mojom::FileChooserParams& params) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  LOG(INFO) << "File chooser request callback.";
+  file_chooser_request_.reset(new _Ewk_File_Chooser_Request(
+      std::move(listener), params.accept_types, params.mode));
+  SmartCallback<EWebViewCallbacks::FileChooserRequest>().call(
+      file_chooser_request_.get());
+#else
   if (!IsMobileProfile() && !IsWearableProfile())
     return;
-
-#if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
-  if (params.capture) {
-    const std::string capture_types[] = {"video/*", "audio/*", "image/*"};
-    unsigned int capture_types_num =
-        sizeof(capture_types) / sizeof(*capture_types);
-    for (unsigned int i = 0; i < capture_types_num; ++i) {
-      for (unsigned int j = 0; j < params.accept_types.size(); ++j) {
-        if (UTF16ToUTF8(params.accept_types[j]) == capture_types[i]) {
-          filechooser_mode_ = params.mode;
-          LaunchCamera(params.accept_types[j]);
-          return;
-        }
-      }
-    }
-  }
   file_chooser_.reset(
-      new content::FileChooserControllerEfl(render_frame_host, &params));
+      new content::FileChooserControllerEfl(std::move(listener), params));
   file_chooser_->Open();
 #endif
 }
@@ -2880,71 +2872,6 @@ void EWebView::InitializeWindowTreeHost() {
     host_view->SetSize(bounds.size());
 }
 
-#if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
-void EWebView::cameraResultCb(service_h request,
-                              service_h reply,
-                              service_result_e result,
-                              void* data) {
-  if (!IsMobileProfile() && !IsWearableProfile())
-    return;
-
-  EWebView* webview = static_cast<EWebView*>(data);
-  RenderViewHost* render_view_host =
-      webview->web_contents_->GetRenderViewHost();
-  if (result == SERVICE_RESULT_SUCCEEDED) {
-    int ret = -1;
-    char** filesarray;
-    int number;
-    ret = service_get_extra_data_array(reply, SERVICE_DATA_SELECTED,
-                                       &filesarray, &number);
-    if (filesarray) {
-      for (int i = 0; i < number; i++) {
-        std::vector<ui::SelectedFileInfo> files;
-        if (!render_view_host) {
-          return;
-        }
-        if (filesarray[i]) {
-          GURL url(filesarray[i]);
-          if (!url.is_valid()) {
-            base::FilePath path(url.SchemeIsFile() ? url.path()
-                                                   : filesarray[i]);
-            files.push_back(ui::SelectedFileInfo(path, base::FilePath()));
-          }
-        }
-        render_view_host->FilesSelectedInChooser(files,
-                                                 webview->filechooser_mode_);
-      }
-    }
-  } else {
-    std::vector<ui::SelectedFileInfo> files;
-    if (render_view_host) {
-      render_view_host->FilesSelectedInChooser(files,
-                                               webview->filechooser_mode_);
-    }
-  }
-}
-
-bool EWebView::LaunchCamera(std::u16string mimetype) {
-  service_h svcHandle = 0;
-  if (service_create(&svcHandle) < 0 || !svcHandle) {
-    LOG(ERROR) << __FUNCTION__ << " Service Creation Failed ";
-    return false;
-  }
-  service_set_operation(svcHandle, SERVICE_OPERATION_CREATE_CONTENT);
-  service_set_mime(svcHandle, UTF16ToUTF8(mimetype).c_str());
-  service_add_extra_data(svcHandle, "CALLER", "Browser");
-
-  int ret = service_send_launch_request(svcHandle, cameraResultCb, this);
-  if (ret != SERVICE_ERROR_NONE) {
-    LOG(ERROR) << __FUNCTION__ << " Service Launch Failed ";
-    service_destroy(svcHandle);
-    return false;
-  }
-  service_destroy(svcHandle);
-  return true;
-}
-#endif
-
 void EWebView::UrlRequestSet(
     const char* url,
     content::NavigationController::LoadURLType loadtype,
index 1662c18..f870b65 100644 (file)
@@ -86,6 +86,10 @@ class _Ewk_Hit_Test;
 class Ewk_Context;
 class _Ewk_Quota_Permission_Request;
 
+#if BUILDFLAG(IS_TIZEN_TV)
+struct _Ewk_File_Chooser_Request;
+#endif
+
 #if defined(TIZEN_ATK_SUPPORT)
 class EWebAccessibility;
 #endif
@@ -589,7 +593,7 @@ class EWebView {
 
   void GetSessionData(const char** data, unsigned* length) const;
   bool RestoreFromSessionData(const char* data, unsigned length);
-  void ShowFileChooser(content::RenderFrameHost* render_frame_host,
+  void ShowFileChooser(scoped_refptr<content::FileSelectListener> listener,
                        const blink::mojom::FileChooserParams&);
   void SetBrowserFont();
   bool IsDragging() const;
@@ -777,15 +781,6 @@ class EWebView {
   void RunPendingSetFocus(Eina_Bool focus);
 #endif
 
-#if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP)
-  static void cameraResultCb(service_h request,
-                             service_h reply,
-                             service_result_e result,
-                             void* data);
-
-  bool LaunchCamera(std::u16string mimetype);
-#endif
-
   JavaScriptDialogManagerEfl* GetJavaScriptDialogManagerEfl();
 
   // Changes viewport without resizing Evas_Object representing webview
@@ -842,7 +837,9 @@ class EWebView {
   std::string selected_text_cached_;
 
   std::unique_ptr<content::ContextMenuControllerEfl> context_menu_;
-#if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
+#if BUILDFLAG(IS_TIZEN_TV)
+  std::unique_ptr<_Ewk_File_Chooser_Request> file_chooser_request_;
+#else
   std::unique_ptr<content::FileChooserControllerEfl> file_chooser_;
 #endif
   std::unique_ptr<content::PopupControllerEfl> popup_controller_;
index be7eaf7..8b5b2e2 100644 (file)
@@ -34,9 +34,9 @@
 #include "private/ewk_geolocation_private.h"
 #include "private/ewk_policy_decision_private.h"
 #include "private/ewk_user_media_private.h"
-
 #if BUILDFLAG(IS_TIZEN_TV)
 #include "private/ewk_autofill_profile_private.h"
+#include "private/ewk_file_chooser_request_private.h"
 #endif
 
 typedef struct EwkObject Ewk_Auth_Request;
@@ -61,7 +61,6 @@ enum CallbackType {
   DownloadJobFailed,
   DownloadJobFinished,
   DownloadJobRequested,
-  FileChooserRequest,
   NewFormSubmissionRequest,
   FaviconChanged,
   LoadError,
@@ -161,6 +160,7 @@ enum CallbackType {
   LoginFormSubmitted,
   LoginFields,
   DidBlockInsecureContent,
+  FileChooserRequest,
 #endif
   URIChanged,
   DidNotAllowScript,
@@ -235,7 +235,6 @@ DECLARE_EWK_VIEW_CALLBACK(Vibrate, "vibrate", uint32_t*);
 
 // Note: type 'void' means that no arguments are expected.
 
-DECLARE_EWK_VIEW_CALLBACK(FileChooserRequest, "file,chooser,request", Ewk_File_Chooser_Request*);
 DECLARE_EWK_VIEW_CALLBACK(FormSubmit, "form,submit", const char*);
 DECLARE_EWK_VIEW_CALLBACK(LoadFinished, "load,finished", void);
 DECLARE_EWK_VIEW_CALLBACK(LoadStarted, "load,started", void);
@@ -344,6 +343,9 @@ DECLARE_EWK_VIEW_CALLBACK(LoginFields,
 DECLARE_EWK_VIEW_CALLBACK(DidBlockInsecureContent,
                           "did,block,insecure,content",
                           void);
+DECLARE_EWK_VIEW_CALLBACK(FileChooserRequest,
+                          "file,chooser,request",
+                          _Ewk_File_Chooser_Request*);
 #endif
 
 DECLARE_EWK_VIEW_CALLBACK(ContentsSizeChanged, "contents,size,changed", void);
index e287f76..3a6efc0 100644 (file)
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/common/file_chooser_file_info.h"
 #include "file_chooser_controller_efl.h"
-#include <Eina.h>
 #include <Elementary.h>
 
+#if BUILDFLAG(IS_TIZEN)
+#include <app_control.h>
+#endif
+
 #include "base/files/file_path.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/file_select_listener.h"
+#include "tizen/system_info.h"
+
+using blink::mojom::FileChooserFileInfoPtr;
+using blink::mojom::FileChooserParams;
 
 namespace content {
 
-static void _fs_done(void* data, Evas_Object* obj, void* event_info) {
-  FileChooserControllerEfl* inst = static_cast<FileChooserControllerEfl*>(data);
-  RenderFrameHost* render_frame_host = inst->GetRenderFrameHost();
+namespace {
 
-  if (!render_frame_host)
-    return;
+const char kDefaultTitleOpen[] = "Open";
+const char kDefaultTitleSave[] = "Save";
+const char kDefaultFileName[] = "/tmp";
+
+const char kMimeTypeAudio[] = "audio/*";
+const char kMimeTypeImage[] = "image/*";
+const char kMimeTypeVideo[] = "video/*";
+
+#if BUILDFLAG(IS_TIZEN)
+static void DestroyAppHandle(app_control_h* handle) {
+  std::ignore = app_control_destroy(*handle);
+}
+
+static void FileChooserResultCb(app_control_h request,
+                                app_control_h reply,
+                                app_control_result_e result,
+                                void* data) {
+  auto* fcc = static_cast<FileChooserControllerEfl*>(data);
+  scoped_refptr<content::FileSelectListener> listener =
+      fcc->GetFileSelectListener();
+
+  std::vector<FileChooserFileInfoPtr> files;
+
+  if (result == APP_CONTROL_RESULT_SUCCEEDED) {
+    char** selected_files = nullptr;
+    int file_count = 0;
+    int ret = app_control_get_extra_data_array(reply, APP_CONTROL_DATA_SELECTED,
+                                               &selected_files, &file_count);
+
+    if (ret == APP_CONTROL_ERROR_NONE && file_count > 0) {
+      for (int i = 0; i < file_count; i++) {
+        base::FilePath path(selected_files[i]);
+        auto file_info = blink::mojom::NativeFileInfo::New();
+        file_info->file_path = path;
+        files.push_back(blink::mojom::FileChooserFileInfo::NewNativeFile(
+            std::move(file_info)));
+        free(selected_files[i]);
+      }
+      free(selected_files);
+    } else {
+      LOG(ERROR) << __PRETTY_FUNCTION__ << " : "
+                 << "Failed to get extra data array. Error code: " << ret;
+    }
+  } else {
+    LOG(ERROR) << __PRETTY_FUNCTION__ << " : "
+               << "Failed to launch file chooser application. Error code: "
+               << result;
+  }
+
+  listener->FileSelected(std::move(files), base::FilePath(),
+                         fcc->GetParams()->mode);
+}
+
+static void CameraResultCb(app_control_h request,
+                           app_control_h reply,
+                           app_control_result_e result,
+                           void* data) {
+  auto* fcc = static_cast<FileChooserControllerEfl*>(data);
+  scoped_refptr<content::FileSelectListener> listener =
+      fcc->GetFileSelectListener();
+
+  std::vector<FileChooserFileInfoPtr> files;
+
+  if (result == APP_CONTROL_RESULT_SUCCEEDED) {
+    char** return_paths = nullptr;
+    int array_length = 0;
+    int ret = app_control_get_extra_data_array(reply, APP_CONTROL_DATA_SELECTED,
+                                               &return_paths, &array_length);
+    if (ret == APP_CONTROL_ERROR_NONE && array_length > 0) {
+      for (int i = 0; i < array_length; ++i) {
+        auto file_info = blink::mojom::NativeFileInfo::New();
+        file_info->file_path = base::FilePath(return_paths[i]);
+        files.push_back(blink::mojom::FileChooserFileInfo::NewNativeFile(
+            std::move(file_info)));
+        free(return_paths[i]);
+      }
+      free(return_paths);
+    } else {
+      LOG(ERROR) << __PRETTY_FUNCTION__
+                 << "Fail to get selected data. ERR: " << ret;
+    }
+  } else {
+    LOG(ERROR) << __PRETTY_FUNCTION__
+               << "Fail or cancel app control. ERR: " << result;
+  }
+
+  listener->FileSelected(std::move(files), base::FilePath(),
+                         fcc->GetParams()->mode);
+}
+#endif  // IS_TIZEN
+
+static void FileSelectionDoneCb(void* data,
+                                Evas_Object* obj,
+                                void* event_info) {
+  FileChooserControllerEfl* inst = static_cast<FileChooserControllerEfl*>(data);
+  scoped_refptr<content::FileSelectListener> listener =
+      inst->GetFileSelectListener();
+  std::vector<FileChooserFileInfoPtr> files;
 
-  std::vector<content::FileChooserFileInfo> files;
   const char* sel_path = static_cast<char*>(event_info);
   if (sel_path) {
-    GURL url(sel_path);
-    if (!url.is_valid()) {
-      base::FilePath path(url.SchemeIsFile() ? url.path() : sel_path);
-      content::FileChooserFileInfo file_info;
-      file_info.file_path = path;
-      files.push_back(file_info);
-    }
+    base::FilePath path(sel_path);
+    auto file_info = blink::mojom::NativeFileInfo::New();
+    file_info->file_path = path;
+    files.push_back(
+        blink::mojom::FileChooserFileInfo::NewNativeFile(std::move(file_info)));
   }
 
-  render_frame_host->FilesSelectedInChooser(files, inst->GetParams()->mode);
+  listener->FileSelected(std::move(files), base::FilePath(),
+                         inst->GetParams()->mode);
   evas_object_del(elm_object_top_widget_get(obj));
 }
 
+}  // namespace
+
+FileChooserControllerEfl::FileChooserControllerEfl(
+    scoped_refptr<content::FileSelectListener> listener,
+    const FileChooserParams& params)
+    : params_(params.Clone()) {
+  file_select_listener_ = std::move(listener);
+  ParseParams();
+}
+
 void FileChooserControllerEfl::ParseParams() {
-  title_ = DEF_TITLE_OPEN;
-  def_file_name_ = DEF_FILE_NAME;
+  title_ = kDefaultTitleOpen;
+  file_name_ = kDefaultFileName;
   is_save_file_ = EINA_FALSE;
   folder_only_ = EINA_FALSE;
 
@@ -46,16 +154,16 @@ void FileChooserControllerEfl::ParseParams() {
       return;
 
   switch (params_->mode) {
-    case FileChooserParams::Open:
+    case FileChooserParams::Mode::kOpen:
       break;
-    case FileChooserParams::OpenMultiple:
+    case FileChooserParams::Mode::kOpenMultiple:
       // only since elementary 1.8
       break;
-    case FileChooserParams::UploadFolder:
+    case FileChooserParams::Mode::kUploadFolder:
       folder_only_ = EINA_TRUE;
       break;
-    case FileChooserParams::Save:
-      title_ = DEF_TITLE_SAVE;
+    case FileChooserParams::Mode::kSave:
+      title_ = kDefaultTitleSave;
       is_save_file_ = EINA_TRUE;
       break;
     default:
@@ -65,15 +173,53 @@ void FileChooserControllerEfl::ParseParams() {
   if (!params_->title.empty())
     title_ = base::UTF16ToUTF8(params_->title);
 
-  if (!params_->default_file_name.empty()) {
-    if (params_->default_file_name.EndsWithSeparator())
-      def_file_name_ = params_->default_file_name.value();
-    else
-      def_file_name_ = params_->default_file_name.DirName().value();
-  }
+  if (params_->default_file_name.empty())
+    return;
+
+  if (params_->default_file_name.EndsWithSeparator())
+    file_name_ = params_->default_file_name.value();
+  else
+    file_name_ = params_->default_file_name.DirName().value();
+}
+
+scoped_refptr<content::FileSelectListener>
+FileChooserControllerEfl::GetFileSelectListener() {
+  return std::move(file_select_listener_);
 }
 
 void FileChooserControllerEfl::Open() {
+#if BUILDFLAG(IS_TIZEN)
+  if (IsMobileProfile() && params_->use_media_capture) {
+    bool ret = false;
+    for (const auto& type : params_->accept_types) {
+      const std::string type_utf8 = base::UTF16ToUTF8(type);
+      if (type_utf8 == kMimeTypeImage || type_utf8 == kMimeTypeVideo) {
+        ret = LaunchCamera(type_utf8);
+        break;
+      }
+    }
+    if (!ret) {
+      GetFileSelectListener()->FileSelected(
+          std::vector<FileChooserFileInfoPtr>(), base::FilePath(),
+          params_->mode);
+    }
+    return;
+  }
+#endif
+
+  if ((IsMobileProfile() || IsWearableProfile()) && !LaunchFileChooser()) {
+    GetFileSelectListener()->FileSelected(std::vector<FileChooserFileInfoPtr>(),
+                                          base::FilePath(), params_->mode);
+  } else {
+    CreateAndShowFileChooser();
+  }
+}
+
+const blink::mojom::FileChooserParamsPtr FileChooserControllerEfl::GetParams() {
+  return std::move(params_);
+}
+
+void FileChooserControllerEfl::CreateAndShowFileChooser() {
   Evas_Object* win = elm_win_util_standard_add("fileselector", title_.c_str());
   elm_win_modal_set(win, EINA_TRUE);
 
@@ -89,7 +235,7 @@ void FileChooserControllerEfl::Open() {
   elm_fileselector_expandable_set(fs, EINA_FALSE);
 
   /* start the fileselector in proper dir */
-  elm_fileselector_path_set(fs, def_file_name_.c_str());
+  elm_fileselector_path_set(fs, file_name_.c_str());
 
   evas_object_size_hint_weight_set(fs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
   evas_object_size_hint_align_set(fs, EVAS_HINT_FILL, EVAS_HINT_FILL);
@@ -97,11 +243,125 @@ void FileChooserControllerEfl::Open() {
   evas_object_show(fs);
 
   /* the 'done' cb is called when the user presses ok/cancel */
-  evas_object_smart_callback_add(fs, "done", _fs_done, this);
+  evas_object_smart_callback_add(fs, "done", FileSelectionDoneCb, this);
 
   evas_object_resize(win, 400, 400);
   evas_object_show(win);
 }
 
-} //namespace
+bool FileChooserControllerEfl::LaunchFileChooser() {
+#if BUILDFLAG(IS_TIZEN)
+  if (!IsMobileProfile() && !IsWearableProfile())
+    return false;
+
+  app_control_h service_handle = nullptr;
+
+  int ret = app_control_create(&service_handle);
+  if (ret != APP_CONTROL_ERROR_NONE || !service_handle) {
+    LOG(ERROR) << __PRETTY_FUNCTION__ << " : "
+               << "Failed to create file chooser service. Error code: " << ret;
+    return false;
+  }
+
+  std::unique_ptr<app_control_h, decltype(&DestroyAppHandle)>
+      service_handle_ptr(&service_handle, DestroyAppHandle);
+
+  ret = app_control_set_operation(service_handle, APP_CONTROL_OPERATION_PICK);
+  if (ret != APP_CONTROL_ERROR_NONE) {
+    LOG(ERROR) << __PRETTY_FUNCTION__ << " : "
+               << "Failed to set operation. Error code: " << ret;
+    return false;
+  }
+
+  // If there is more than one valid MIME type or file extension supported,
+  // do not restrict selectable files to any specific type. The reason for this
+  // is that app_control does not support multiple MIME types, that is,
+  // each MIME type is associated with a particular external Tizen Application.
+  if (params_->accept_types.size() == 1) {
+    ret = app_control_set_mime(
+        service_handle, base::UTF16ToUTF8(params_->accept_types[0]).c_str());
+  } else {
+    ret = app_control_set_mime(service_handle, "*/*");
+  }
+  if (ret != APP_CONTROL_ERROR_NONE) {
+    LOG(ERROR) << __PRETTY_FUNCTION__ << " : "
+               << "Failed to set specified mime type. Error code: " << ret;
+    return false;
+  }
+
+  switch (params_->mode) {
+    case FileChooserParams::Mode::kOpen:
+      app_control_add_extra_data(service_handle,
+                                 APP_CONTROL_DATA_SELECTION_MODE, "single");
+      break;
+    case FileChooserParams::Mode::kOpenMultiple:
+      app_control_add_extra_data(service_handle,
+                                 APP_CONTROL_DATA_SELECTION_MODE, "multiple");
+      break;
+    default:
+      // cancel file chooser request
+      LOG(ERROR) << __PRETTY_FUNCTION__ << " : "
+                 << "Unsupported file chooser mode. Mode: " << params_->mode;
+      return false;
+  }
+
+  app_control_add_extra_data(service_handle, APP_CONTROL_DATA_TYPE, "vcf");
+
+  ret = app_control_send_launch_request(service_handle, FileChooserResultCb,
+                                        this);
+  if (ret != APP_CONTROL_ERROR_NONE) {
+    LOG(ERROR) << __PRETTY_FUNCTION__ << " : "
+               << "Failed to send launch request. Error code: " << ret;
+    return false;
+  }
+
+  return true;
+#else
+  NOTIMPLEMENTED() << "This is only available on Tizen.";
+  return false;
+#endif
+}
+
+bool FileChooserControllerEfl::LaunchCamera(const std::string& mime_type) {
+#if BUILDFLAG(IS_TIZEN)
+  if (!IsMobileProfile())
+    return false;
+
+  app_control_h handle = nullptr;
+  int ret = app_control_create(&handle);
+  if (ret != APP_CONTROL_ERROR_NONE || !handle) {
+    LOG(ERROR) << __PRETTY_FUNCTION__
+               << "Fail to create app control. ERR: " << ret;
+    return false;
+  }
+
+  std::unique_ptr<app_control_h, decltype(&DestroyAppHandle)> handle_ptr(
+      &handle, DestroyAppHandle);
 
+  ret = app_control_set_operation(handle, APP_CONTROL_OPERATION_CREATE_CONTENT);
+  if (ret != APP_CONTROL_ERROR_NONE) {
+    LOG(ERROR) << __PRETTY_FUNCTION__ << "Fail to set operation. ERR: " << ret;
+    return false;
+  }
+
+  ret = app_control_set_mime(handle, mime_type.c_str());
+  if (ret != APP_CONTROL_ERROR_NONE) {
+    LOG(ERROR) << __PRETTY_FUNCTION__ << "Fail to set mime. ERR: " << ret;
+    return false;
+  }
+
+  ret = app_control_send_launch_request(handle, CameraResultCb, this);
+  if (ret != APP_CONTROL_ERROR_NONE) {
+    LOG(ERROR) << __PRETTY_FUNCTION__
+               << "Fail to send launch request. ERR: " << ret;
+    return false;
+  }
+
+  return true;
+#else
+  NOTIMPLEMENTED() << "This is only available on Tizen.";
+  return false;
+#endif
+}
+
+} //namespace
index 3fb5eb6..322e07c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2014 Samsung Electronics. All rights reserved.
+// Copyright 2014-2017 Samsung Electronics. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -6,51 +6,33 @@
 #define file_chooser_controller_efl_h
 
 #include <Evas.h>
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
 
 namespace content {
 
-class RenderFrameHost;
-
-#define DEF_TITLE_OPEN "Open";
-#define DEF_TITLE_SAVE "Save";
-#define DEF_FILE_NAME "/tmp";
-
+class FileSelectListener;
 class FileChooserControllerEfl {
  public:
-  FileChooserControllerEfl() : render_frame_host_(nullptr), params_(nullptr) {
-    ParseParams();
-  }
-
-  FileChooserControllerEfl(RenderFrameHost* render_frame_host,
-                           const blink::mojom::FileChooserParams* params)
-      : render_frame_host_(render_frame_host), params_(params) {
-    ParseParams();
-  }
-  ~FileChooserControllerEfl() { }
+  FileChooserControllerEfl(scoped_refptr<content::FileSelectListener> listener,
+                           const blink::mojom::FileChooserParams& params);
+  ~FileChooserControllerEfl() {}
 
   void Open();
 
-  const blink::mojom::FileChooserParams* GetParams() { return params_; }
+  const blink::mojom::FileChooserParamsPtr GetParams();
 
-  void SetParams(const blink::mojom::FileChooserParams* params) {
-    params_ = params;
-  }
-
-  RenderFrameHost* GetRenderFrameHost() {
-    return render_frame_host_;
-  }
-
-  void SetRenderFrameHost(RenderFrameHost* render_frame_host) {
-    render_frame_host_ = render_frame_host;
-  }
+  scoped_refptr<content::FileSelectListener> GetFileSelectListener();
 
  private:
   void ParseParams();
+  void CreateAndShowFileChooser();
+  bool LaunchFileChooser();
+  bool LaunchCamera(const std::string& mime_type);
 
-  RenderFrameHost* render_frame_host_;
-  const blink::mojom::FileChooserParams* params_;
+  scoped_refptr<content::FileSelectListener> file_select_listener_;
+  blink::mojom::FileChooserParamsPtr params_;
   std::string title_;
-  std::string def_file_name_;
+  std::string file_name_;
   Eina_Bool is_save_file_;
   Eina_Bool folder_only_;
 };
@@ -58,4 +40,3 @@ class FileChooserControllerEfl {
 } // namespace
 
 #endif // file_chooser_controller_efl_h
-
diff --git a/tizen_src/ewk/efl_integration/private/ewk_file_chooser_request_private.cc b/tizen_src/ewk/efl_integration/private/ewk_file_chooser_request_private.cc
new file mode 100644 (file)
index 0000000..74ac5e8
--- /dev/null
@@ -0,0 +1,74 @@
+#include "ewk_file_chooser_request_private.h"
+
+#include "base/files/file_path.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/file_select_listener.h"
+
+using blink::mojom::FileChooserFileInfo;
+using blink::mojom::FileChooserFileInfoPtr;
+using blink::mojom::FileChooserParams;
+using blink::mojom::NativeFileInfo;
+
+_Ewk_File_Chooser_Request::_Ewk_File_Chooser_Request(
+    scoped_refptr<content::FileSelectListener> listener,
+    const std::vector<std::u16string>& accept_types,
+    FileChooserParams::Mode mode)
+    : listener_(std::move(listener)),
+      accept_types_(accept_types),
+      mode_(mode) {}
+
+_Ewk_File_Chooser_Request::~_Ewk_File_Chooser_Request() {
+  if (!is_handled_)
+    FileSelectionCanceled();
+}
+
+Eina_List* _Ewk_File_Chooser_Request::GetAcceptTypes() const {
+  Eina_List* type_list = NULL;
+  for (const auto& type : accept_types_) {
+    type_list = eina_list_append(
+        type_list, eina_stringshare_add(base::UTF16ToASCII(type).c_str()));
+  }
+  return type_list;
+}
+
+bool _Ewk_File_Chooser_Request::AllowMultipleSelection() const {
+  return mode_ == FileChooserParams::Mode::kOpenMultiple;
+}
+
+void _Ewk_File_Chooser_Request::FileSelected(const Eina_List* files) {
+  size_t count = eina_list_count(files);
+  if (count > 1 && !AllowMultipleSelection()) {
+    LOG(INFO) << "Multiple selection is not allowed, "
+                 "only the first file will be selected.";
+    FileSelected(static_cast<char*>(eina_list_nth(files, 0)));
+    return;
+  }
+
+  std::vector<FileChooserFileInfoPtr> file_info;
+  for (size_t i = 0; i < count; i++) {
+    auto path = base::FilePath(static_cast<char*>(eina_list_nth(files, i)));
+    file_info.push_back(FileChooserFileInfo::NewNativeFile(
+        NativeFileInfo::New(path, path.BaseName().AsUTF16Unsafe())));
+  }
+  FileSelectedInternal(std::move(file_info));
+}
+
+void _Ewk_File_Chooser_Request::FileSelected(const char* file) {
+  std::vector<FileChooserFileInfoPtr> file_info;
+  auto path = base::FilePath(file);
+  file_info.push_back(FileChooserFileInfo::NewNativeFile(
+      NativeFileInfo::New(path, path.BaseName().AsUTF16Unsafe())));
+  FileSelectedInternal(std::move(file_info));
+}
+
+void _Ewk_File_Chooser_Request::FileSelectedInternal(
+    std::vector<FileChooserFileInfoPtr> files) {
+  listener_->FileSelected(std::move(files), base::FilePath(), mode_);
+  is_handled_ = true;
+}
+
+void _Ewk_File_Chooser_Request::FileSelectionCanceled() {
+  listener_->FileSelected(std::vector<FileChooserFileInfoPtr>(),
+                          base::FilePath(), mode_);
+  is_handled_ = true;
+}
diff --git a/tizen_src/ewk/efl_integration/private/ewk_file_chooser_request_private.h b/tizen_src/ewk/efl_integration/private/ewk_file_chooser_request_private.h
new file mode 100644 (file)
index 0000000..129e3b1
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright 2020 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EWK_EFL_INTEGRATION_PRIVATE_EWK_FILE_CHOOSER_REQUEST_PRIVATE_H_
+#define EWK_EFL_INTEGRATION_PRIVATE_EWK_FILE_CHOOSER_REQUEST_PRIVATE_H_
+
+#include <Eina.h>
+
+#include <memory>
+#include <vector>
+
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
+
+namespace content {
+class FileSelectListener;
+}
+
+struct _Ewk_File_Chooser_Request {
+ public:
+  _Ewk_File_Chooser_Request(scoped_refptr<content::FileSelectListener> listener,
+                            const std::vector<std::u16string>& accept_types,
+                            blink::mojom::FileChooserParams::Mode mode);
+  ~_Ewk_File_Chooser_Request();
+
+  Eina_List* GetAcceptTypes() const;
+  bool AllowMultipleSelection() const;
+  void FileSelected(const Eina_List* files);
+  void FileSelected(const char* file);
+  void FileSelectionCanceled();
+
+  bool is_handled() const { return is_handled_; }
+
+ private:
+  void FileSelectedInternal(
+      std::vector<blink::mojom::FileChooserFileInfoPtr> files);
+
+  scoped_refptr<content::FileSelectListener> listener_;
+  std::vector<std::u16string> accept_types_;
+  blink::mojom::FileChooserParams::Mode mode_;
+  bool is_handled_ = false;
+};
+
+#endif  // EWK_EFL_INTEGRATION_PRIVATE_EWK_FILE_CHOOSER_REQUEST_PRIVATE_H_
index 83ffcdc..4af251d 100644 (file)
@@ -37,6 +37,7 @@
 #include "ewk_context_menu_product.h"
 #include "ewk_context_product.h"
 #include "ewk_cookie_manager_product.h"
+#include "ewk_file_chooser_request_product.h"
 #include "ewk_form_repost_decision_product.h"
 #include "ewk_highcontrast_product.h"
 #include "ewk_media_downloadable_font_info_product.h"
diff --git a/tizen_src/ewk/efl_integration/public/ewk_file_chooser_request.cc b/tizen_src/ewk/efl_integration/public/ewk_file_chooser_request.cc
new file mode 100644 (file)
index 0000000..259c22d
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2020 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ewk_file_chooser_request_product.h"
+
+#include "private/ewk_file_chooser_request_private.h"
+
+/* LCOV_EXCL_START */
+EXPORT_API Eina_Bool ewk_file_chooser_request_allow_multiple_files_get(const Ewk_File_Chooser_Request* request)
+{
+  EINA_SAFETY_ON_NULL_RETURN_VAL(request, EINA_FALSE);
+  return request->AllowMultipleSelection();
+}
+
+EXPORT_API Eina_List* ewk_file_chooser_request_accepted_mimetypes_get(const Ewk_File_Chooser_Request* request)
+{
+  EINA_SAFETY_ON_NULL_RETURN_VAL(request, NULL);
+  return request->GetAcceptTypes();
+}
+
+EXPORT_API Eina_Bool ewk_file_chooser_request_cancel(Ewk_File_Chooser_Request* request)
+{
+  EINA_SAFETY_ON_NULL_RETURN_VAL(request, EINA_FALSE);
+  EINA_SAFETY_ON_TRUE_RETURN_VAL(request->is_handled(), EINA_FALSE);
+  request->FileSelectionCanceled();
+  return EINA_TRUE;
+
+}
+
+EXPORT_API Eina_Bool ewk_file_chooser_request_files_choose(Ewk_File_Chooser_Request* request, const Eina_List* chosen_files)
+{
+  EINA_SAFETY_ON_NULL_RETURN_VAL(request, EINA_FALSE);
+  EINA_SAFETY_ON_TRUE_RETURN_VAL(request->is_handled(), EINA_FALSE);
+  EINA_SAFETY_ON_NULL_RETURN_VAL(chosen_files, EINA_FALSE);
+  request->FileSelected(chosen_files);
+  return EINA_FALSE;
+}
+
+EXPORT_API Eina_Bool ewk_file_chooser_request_file_choose(Ewk_File_Chooser_Request* request, const char* chosen_file)
+{
+  EINA_SAFETY_ON_NULL_RETURN_VAL(request, EINA_FALSE);
+  EINA_SAFETY_ON_TRUE_RETURN_VAL(request->is_handled(), EINA_FALSE);
+  EINA_SAFETY_ON_NULL_RETURN_VAL(chosen_file, EINA_FALSE);
+  request->FileSelected(chosen_file);
+  return EINA_FALSE;
+}
+/* LCOV_EXCL_STOP */
diff --git a/tizen_src/ewk/efl_integration/public/ewk_file_chooser_request_product.h b/tizen_src/ewk/efl_integration/public/ewk_file_chooser_request_product.h
new file mode 100644 (file)
index 0000000..3c84086
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2020 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file    ewk_file_chooser_request_product.h
+ * @brief   Describes the Ewk File Chooser API.
+ */
+
+#ifndef EWK_EFL_INTEGRATION_PUBLIC_EWK_FILE_CHOOSER_REQUEST_PRODUCT_H_
+#define EWK_EFL_INTEGRATION_PUBLIC_EWK_FILE_CHOOSER_REQUEST_PRODUCT_H_
+
+#include <Eina.h>
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Creates a type name for Ewk_File_Chooser_Request */
+typedef struct _Ewk_File_Chooser_Request Ewk_File_Chooser_Request;
+
+/**
+ * Queries if it is allowed to select multiple files or not.
+ *
+ * @param request request object to query
+ *
+ * @return @c EINA_TRUE if it is allowed to select multiple files,
+ *         @c EINA_FALSE otherwise
+ */
+EXPORT_API Eina_Bool ewk_file_chooser_request_allow_multiple_files_get(const Ewk_File_Chooser_Request* request);
+
+/**
+ * Queries the list of accepted MIME types.
+ *
+ * Possible MIME types are:
+ * - "audio\/\*": All sound files are accepted
+ * - "video\/\*": All video files are accepted
+ * - "image\/\*": All image files are accepted
+ * - standard IANA MIME type (see http://www.iana.org/assignments/media-types/ for a complete list)
+ *
+ * @param request request object to query
+ *
+ * @return The list of accepted MIME types. The list items are guaranteed to be stringshared.
+ * The caller needs to free the list and its items after use
+ */
+EXPORT_API Eina_List* ewk_file_chooser_request_accepted_mimetypes_get(const Ewk_File_Chooser_Request* request);
+
+/**
+ * Cancels the file chooser request.
+ *
+ * @param request request object to cancel
+ *
+ * @return @c EINA_TRUE if successful, @c EINA_FALSE otherwise
+ */
+EXPORT_API Eina_Bool ewk_file_chooser_request_cancel(Ewk_File_Chooser_Request* request);
+
+/**
+ * Sets the files chosen by the user.
+ *
+ * @param request request object to update
+ *
+ * @return @c EINA_TRUE if successful, @c EINA_FALSE otherwise
+ *
+ * @see ewk_file_chooser_request_file_choose()
+ */
+EXPORT_API Eina_Bool ewk_file_chooser_request_files_choose(Ewk_File_Chooser_Request* request, const Eina_List* chosen_files);
+
+/**
+ * Sets the file chosen by the user.
+ *
+ * This is a convenience function in case only one file needs to be set.
+ *
+ * @param request request object to update
+ *
+ * @return @c EINA_TRUE if successful, @c EINA_FALSE otherwise
+ *
+ * @see ewk_file_chooser_request_files_choose()
+ */
+EXPORT_API Eina_Bool ewk_file_chooser_request_file_choose(Ewk_File_Chooser_Request* request, const char* chosen_file);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // EWK_EFL_INTEGRATION_PUBLIC_EWK_FILE_CHOOSER_REQUEST_PRODUCT_H_
index 18fb985..5435c2e 100644 (file)
@@ -643,7 +643,7 @@ void WebContentsDelegateEfl::RunFileChooser(
     RenderFrameHost* render_frame_host,
     scoped_refptr<FileSelectListener> listener,
     const blink::mojom::FileChooserParams& params) {
-  web_view_->ShowFileChooser(render_frame_host, params);
+  web_view_->ShowFileChooser(std::move(listener), params);
 }
 
 std::unique_ptr<ColorChooser> WebContentsDelegateEfl::OpenColorChooser(
index 4eb6573..3e170a2 100644 (file)
@@ -166,6 +166,11 @@ test("ewk_unittests") {
     "utc_blink_ewk_error_type_get_func.cpp",
     "utc_blink_ewk_error_url_get_func.cpp",
     "utc_blink_ewk_favicon_database_icon_get_func.cpp",
+    "utc_blink_ewk_file_chooser_request_accepted_mimetypes_get_func.cpp",
+    "utc_blink_ewk_file_chooser_request_allow_multiple_files_get_func.cpp",
+    "utc_blink_ewk_file_chooser_request_cancel_func.cpp",
+    "utc_blink_ewk_file_chooser_request_file_choose_func.cpp",
+    "utc_blink_ewk_file_chooser_request_files_choose_func.cpp",
     "utc_blink_ewk_frame_is_main_frame_func.cpp",
     "utc_blink_ewk_geolocation_permission_reply_func.cpp",
     "utc_blink_ewk_geolocation_permission_request_origin_get_func.cpp",
diff --git a/tizen_src/ewk/unittest/resources/ewk_file_chooser_request/file_chooser.html b/tizen_src/ewk/unittest/resources/ewk_file_chooser_request/file_chooser.html
new file mode 100644 (file)
index 0000000..59d2e2a
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>File chooser test</title>
+</head>
+<body>
+<input type="file" id="myInput" name="Upload image" multiple accept="image/png, image/jpeg" style="top: 10; left: 10;">
+</body>
+</html>
+
index cf4e9ca..eed33a3 100644 (file)
@@ -378,6 +378,17 @@ void utc_blink_ewk_base::EwkDeinit()
     ewk_webview = NULL;
 }
 
+void utc_blink_ewk_base::FeedMouseClick(int x, int y, int button) {
+  if (!ewk_evas)
+    return;
+
+  evas_event_feed_mouse_move(ewk_evas, x, y, ecore_time_get(), 0);
+  evas_event_feed_mouse_down(ewk_evas, button, EVAS_BUTTON_NONE,
+                             ecore_time_get(), 0);
+  evas_event_feed_mouse_up(ewk_evas, button, EVAS_BUTTON_NONE, ecore_time_get(),
+                           0);
+}
+
 void utc_log(UtcLogSeverity severity, const char* format, ...) {
   static UtcLogSeverity minLogSeverity = -1;
   if (minLogSeverity == -1) {
index 17d7c84..2efd0b7 100644 (file)
@@ -345,7 +345,9 @@ protected:
     inline Evas_Object* GetEwkWindow() const { return ewk_window; }
     inline Evas* GetEwkEvas() const { return ewk_evas; }
 
-private:
+    void FeedMouseClick(int x, int y, int button);
+
+  private:
     /**
      * Default "load,started" event callback, will call LoadStarted method
      *
diff --git a/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_accepted_mimetypes_get_func.cpp b/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_accepted_mimetypes_get_func.cpp
new file mode 100644 (file)
index 0000000..9931d3e
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright 2020 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "utc_blink_ewk_base.h"
+
+static const char kUrl[] = "ewk_file_chooser_request/file_chooser.html";
+
+class utc_blink_ewk_file_chooser_request_accepted_mimetypes_get_func
+    : public utc_blink_ewk_base {
+ protected:
+  void PostSetUp() override {
+    evas_object_smart_callback_add(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest, this);
+  }
+
+  void PreTearDown() override {
+    evas_object_smart_callback_del(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest);
+  }
+
+  void LoadFinished(Evas_Object* webview) override {
+    FeedMouseClick(15, 15, 1);
+  }
+
+  static void OnFileChooserRequest(void* data,
+                                   Evas_Object* webview,
+                                   void* arg) {
+    ASSERT_TRUE(arg != NULL);
+    ASSERT_TRUE(data != NULL);
+    auto* owner = static_cast<
+        utc_blink_ewk_file_chooser_request_accepted_mimetypes_get_func*>(data);
+    auto* request = static_cast<Ewk_File_Chooser_Request*>(arg);
+    owner->mime_types_ =
+        ewk_file_chooser_request_accepted_mimetypes_get(request);
+    owner->EventLoopStop(Success);
+  }
+
+  Eina_List* mime_types_ = NULL;
+};
+
+/**
+ * @brief Checking whether the function returns a valid value.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_accepted_mimetypes_get_func,
+       POS_TEST) {
+  ASSERT_TRUE(ewk_view_url_set(GetEwkWebView(), GetResourceUrl(kUrl).c_str()));
+  EXPECT_EQ(Success, EventLoopStart());
+  ASSERT_TRUE(NULL != mime_types_);
+  ASSERT_EQ(2u, eina_list_count(mime_types_));
+  EXPECT_STREQ("image/png", static_cast<char*>(eina_list_nth(mime_types_, 0)));
+  EXPECT_STREQ("image/jpeg", static_cast<char*>(eina_list_nth(mime_types_, 1)));
+  void* mime_type;
+  EINA_LIST_FREE(mime_types_, mime_type) {
+    eina_stringshare_del(static_cast<char*>(mime_type));
+  }
+}
+
+/**
+ * @brief Checking whether the function works properly in case of NULL request.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_accepted_mimetypes_get_func,
+       NEG_TEST) {
+  mime_types_ = ewk_file_chooser_request_accepted_mimetypes_get(NULL);
+  ASSERT_TRUE(NULL == mime_types_);
+}
diff --git a/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_allow_multiple_files_get_func.cpp b/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_allow_multiple_files_get_func.cpp
new file mode 100644 (file)
index 0000000..0262270
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2020 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "utc_blink_ewk_base.h"
+
+static const char kUrl[] = "ewk_file_chooser_request/file_chooser.html";
+
+class utc_blink_ewk_file_chooser_request_allow_multiple_files_get_func
+    : public utc_blink_ewk_base {
+ protected:
+  void PostSetUp() override {
+    evas_object_smart_callback_add(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest, this);
+  }
+
+  void PreTearDown() override {
+    evas_object_smart_callback_del(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest);
+  }
+
+  void LoadFinished(Evas_Object* webview) override {
+    FeedMouseClick(15, 15, 1);
+  }
+
+  static void OnFileChooserRequest(void* data,
+                                   Evas_Object* webview,
+                                   void* arg) {
+    ASSERT_TRUE(arg != NULL);
+    ASSERT_TRUE(data != NULL);
+    auto* owner = static_cast<
+        utc_blink_ewk_file_chooser_request_allow_multiple_files_get_func*>(
+        data);
+    auto* request = static_cast<Ewk_File_Chooser_Request*>(arg);
+    owner->allow_multiple_ =
+        ewk_file_chooser_request_allow_multiple_files_get(request);
+    owner->EventLoopStop(Success);
+  }
+
+  Eina_Bool allow_multiple_ = false;
+};
+
+/**
+ * @brief Checking whether the function returns a valid value.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_allow_multiple_files_get_func,
+       POS_TEST) {
+  ASSERT_TRUE(ewk_view_url_set(GetEwkWebView(), GetResourceUrl(kUrl).c_str()));
+  EXPECT_EQ(Success, EventLoopStart());
+  ASSERT_EQ(EINA_TRUE, allow_multiple_);
+}
+
+/**
+ * @brief Checking whether the function works properly in case of NULL request.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_allow_multiple_files_get_func,
+       NEG_TEST) {
+  ASSERT_EQ(EINA_FALSE,
+            ewk_file_chooser_request_allow_multiple_files_get(NULL));
+}
diff --git a/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_cancel_func.cpp b/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_cancel_func.cpp
new file mode 100644 (file)
index 0000000..3e9ec65
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2020 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "utc_blink_ewk_base.h"
+
+static const char kUrl[] = "ewk_file_chooser_request/file_chooser.html";
+
+class utc_blink_ewk_file_chooser_request_cancel_func
+    : public utc_blink_ewk_base {
+ protected:
+  void PostSetUp() override {
+    evas_object_smart_callback_add(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest, this);
+  }
+
+  void PreTearDown() override {
+    evas_object_smart_callback_del(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest);
+  }
+
+  void LoadFinished(Evas_Object* webview) override {
+    FeedMouseClick(15, 15, 1);
+  }
+
+  static void OnFileChooserRequest(void* data,
+                                   Evas_Object* webview,
+                                   void* arg) {
+    ASSERT_TRUE(arg != NULL);
+    ASSERT_TRUE(data != NULL);
+    auto* owner =
+        static_cast<utc_blink_ewk_file_chooser_request_cancel_func*>(data);
+    auto* request = static_cast<Ewk_File_Chooser_Request*>(arg);
+    ASSERT_TRUE(ewk_file_chooser_request_cancel(request));
+    owner->EventLoopStop(Success);
+  }
+};
+
+/**
+ * @brief Checking whether the function returns a valid value.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_cancel_func, POS_TEST) {
+  ASSERT_TRUE(ewk_view_url_set(GetEwkWebView(), GetResourceUrl(kUrl).c_str()));
+  EXPECT_EQ(Success, EventLoopStart());
+}
+
+/**
+ * @brief Checking whether the function works properly in case of NULL request.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_cancel_func, NEG_TEST) {
+  ASSERT_EQ(EINA_FALSE, ewk_file_chooser_request_cancel(NULL));
+}
diff --git a/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_file_choose_func.cpp b/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_file_choose_func.cpp
new file mode 100644 (file)
index 0000000..a9e58f6
--- /dev/null
@@ -0,0 +1,53 @@
+// Copyright 2020 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "utc_blink_ewk_base.h"
+
+static const char kUrl[] = "ewk_file_chooser_request/file_chooser.html";
+
+class utc_blink_ewk_file_chooser_request_file_choose_func
+    : public utc_blink_ewk_base {
+ protected:
+  void PostSetUp() override {
+    evas_object_smart_callback_add(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest, this);
+  }
+
+  void PreTearDown() override {
+    evas_object_smart_callback_del(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest);
+  }
+
+  void LoadFinished(Evas_Object* webview) override {
+    FeedMouseClick(15, 15, 1);
+  }
+
+  static void OnFileChooserRequest(void* data,
+                                   Evas_Object* webview,
+                                   void* arg) {
+    ASSERT_TRUE(arg != NULL);
+    ASSERT_TRUE(data != NULL);
+    auto* owner =
+        static_cast<utc_blink_ewk_file_chooser_request_file_choose_func*>(data);
+    auto* request = static_cast<Ewk_File_Chooser_Request*>(arg);
+    ASSERT_EQ(EINA_TRUE,
+              ewk_file_chooser_request_file_choose(request, "tmp/foo.png"));
+    owner->EventLoopStop(Success);
+  }
+};
+
+/**
+ * @brief Checking whether the function returns a valid value.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_file_choose_func, POS_TEST) {
+  ASSERT_TRUE(ewk_view_url_set(GetEwkWebView(), GetResourceUrl(kUrl).c_str()));
+  EXPECT_EQ(Success, EventLoopStart());
+}
+
+/**
+ * @brief Checking whether the function works properly in case of NULL request.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_file_choose_func, NEG_TEST) {
+  ASSERT_EQ(EINA_FALSE, ewk_file_chooser_request_file_choose(NULL, NULL));
+}
diff --git a/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_files_choose_func.cpp b/tizen_src/ewk/unittest/utc_blink_ewk_file_chooser_request_files_choose_func.cpp
new file mode 100644 (file)
index 0000000..aea54a4
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2020 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "utc_blink_ewk_base.h"
+
+static const char kUrl[] = "ewk_file_chooser_request/file_chooser.html";
+
+class utc_blink_ewk_file_chooser_request_files_choose_func
+    : public utc_blink_ewk_base {
+ protected:
+  void PostSetUp() override {
+    evas_object_smart_callback_add(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest, this);
+  }
+
+  void PreTearDown() override {
+    evas_object_smart_callback_del(GetEwkWebView(), "file,chooser,request",
+                                   OnFileChooserRequest);
+  }
+
+  void LoadFinished(Evas_Object* webview) override {
+    FeedMouseClick(15, 15, 1);
+  }
+
+  static void OnFileChooserRequest(void* data,
+                                   Evas_Object* webview,
+                                   void* arg) {
+    ASSERT_TRUE(arg != NULL);
+    ASSERT_TRUE(data != NULL);
+    auto* owner =
+        static_cast<utc_blink_ewk_file_chooser_request_files_choose_func*>(
+            data);
+    auto* request = static_cast<Ewk_File_Chooser_Request*>(arg);
+    Eina_List* files = NULL;
+    files = eina_list_append(files, eina_stringshare_add("/tmp/foo.png"));
+    files = eina_list_append(files, eina_stringshare_add("/tmp/bar.png"));
+    ASSERT_EQ(EINA_TRUE, ewk_file_chooser_request_files_choose(request, files));
+    void* file;
+    EINA_LIST_FREE(files, file) {
+      eina_stringshare_del(static_cast<char*>(file));
+    }
+    owner->EventLoopStop(Success);
+  }
+};
+
+/**
+ * @brief Checking whether the function returns a valid value.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_files_choose_func, POS_TEST) {
+  ASSERT_TRUE(ewk_view_url_set(GetEwkWebView(), GetResourceUrl(kUrl).c_str()));
+  EXPECT_EQ(Success, EventLoopStart());
+}
+
+/**
+ * @brief Checking whether the function works properly in case of NULL request.
+ */
+TEST_F(utc_blink_ewk_file_chooser_request_files_choose_func, NEG_TEST) {
+  ASSERT_EQ(EINA_FALSE, ewk_file_chooser_request_files_choose(NULL, NULL));
+}