Upstream version 6.35.131.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / android / xwalk_contents_client_bridge.cc
index 24345d4..0450dad 100644 (file)
 #include "content/public/browser/browser_thread.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 "content/public/common/show_desktop_notification_params.h"
 #include "jni/XWalkContentsClientBridge_jni.h"
 #include "net/cert/x509_certificate.h"
+#include "third_party/skia/include/core/SkBitmap.h"
 #include "url/gurl.h"
+#include "ui/gfx/android/java_bitmap.h"
+#include "ui/shell_dialogs/selected_file_info.h"
 
 using base::android::AttachCurrentThread;
 using base::android::ConvertJavaStringToUTF16;
@@ -24,16 +29,32 @@ using base::android::ConvertUTF16ToJavaString;
 using base::android::JavaRef;
 using base::android::ScopedJavaLocalRef;
 using content::BrowserThread;
+using content::FileChooserParams;
 using content::RenderViewHost;
 using content::WebContents;
 
 namespace xwalk {
 
+namespace {
+
+void RunUpdateNotificationIconOnUIThread(
+    int notification_id,
+    int process_id,
+    int route_id,
+    const SkBitmap& icon) {
+  XWalkContentsClientBridgeBase* bridge =
+      XWalkContentsClientBridgeBase::FromRenderViewID(process_id, route_id);
+  if (bridge)
+    bridge->UpdateNotificationIcon(notification_id, icon);
+}
+
+}  // namespace
+
 XWalkContentsClientBridge::XWalkContentsClientBridge(JNIEnv* env, jobject obj)
     : java_ref_(env, obj) {
   DCHECK(obj);
   Java_XWalkContentsClientBridge_setNativeContentsClientBridge(
-      env, obj, reinterpret_cast<jint>(this));
+      env, obj, reinterpret_cast<intptr_t>(this));
 }
 
 XWalkContentsClientBridge::~XWalkContentsClientBridge() {
@@ -52,7 +73,7 @@ void XWalkContentsClientBridge::AllowCertificateError(
     int cert_error,
     net::X509Certificate* cert,
     const GURL& request_url,
-    const base::Callback<void(bool)>& callback,
+    const base::Callback<void(bool)>& callback, // NOLINT
     bool* cancel_request) {
 
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -97,8 +118,8 @@ void XWalkContentsClientBridge::ProceedSslError(JNIEnv* env, jobject obj,
 void XWalkContentsClientBridge::RunJavaScriptDialog(
     content::JavaScriptMessageType message_type,
     const GURL& origin_url,
-    const string16& message_text,
-    const string16& default_prompt_text,
+    const base::string16& message_text,
+    const base::string16& default_prompt_text,
     const content::JavaScriptDialogManager::DialogClosedCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   JNIEnv* env = AttachCurrentThread();
@@ -141,7 +162,7 @@ void XWalkContentsClientBridge::RunJavaScriptDialog(
 
 void XWalkContentsClientBridge::RunBeforeUnloadDialog(
     const GURL& origin_url,
-    const string16& message_text,
+    const base::string16& message_text,
     const content::JavaScriptDialogManager::DialogClosedCallback& callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   JNIEnv* env = AttachCurrentThread();
@@ -176,6 +197,118 @@ bool XWalkContentsClientBridge::OnReceivedHttpAuthRequest(
       env, obj.obj(), handler.obj(), jhost.obj(), jrealm.obj());
   return true;
 }
+
+void XWalkContentsClientBridge::OnNotificationIconDownloaded(
+    int id,
+    int http_status_code,
+    const GURL& icon_url,
+    const std::vector<SkBitmap>& bitmaps,
+    const std::vector<gfx::Size>& original_bitmap_sizes) {
+  if (bitmaps.empty() && http_status_code == 404) {
+    LOG(WARNING) << "Failed to download notification icon from "
+                 << icon_url.spec();
+  } else {
+    NotificationDownloadRequestIdMap::iterator iter =
+        downloading_icon_notifications_.find(id);
+    if (iter == downloading_icon_notifications_.end() ||
+        iter->second.size() != 3) {
+      return;
+    }
+    int notification_id = iter->second[0];
+    int process_id = iter->second[1];
+    int route_id = iter->second[2];
+    // This will lead to a second call of ShowNotification for the
+    // same notification id to update the icon. On Android, when
+    // the notification which is already shown is fired again, it will
+    // silently update the content only.
+    BrowserThread::PostTask(
+        BrowserThread::UI,
+        FROM_HERE,
+        base::Bind(&RunUpdateNotificationIconOnUIThread,
+                   notification_id,
+                   process_id,
+                   route_id,
+                   bitmaps[0]));
+  }
+  downloading_icon_notifications_.erase(id);
+}
+
+void XWalkContentsClientBridge::UpdateNotificationIcon(
+    int notification_id, const SkBitmap& icon) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  JNIEnv* env = AttachCurrentThread();
+
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  if (obj.is_null())
+    return;
+
+  ScopedJavaLocalRef<jobject> jicon = gfx::ConvertToJavaBitmap(&icon);
+  Java_XWalkContentsClientBridge_updateNotificationIcon(
+      env, obj.obj(), notification_id, jicon.obj());
+}
+
+void XWalkContentsClientBridge::ShowNotification(
+    const content::ShowDesktopNotificationHostMsgParams& params,
+    bool worker,
+    int process_id,
+    int route_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  JNIEnv* env = AttachCurrentThread();
+
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  if (obj.is_null())
+    return;
+
+  ScopedJavaLocalRef<jstring> jtitle(
+    ConvertUTF16ToJavaString(env, params.title));
+  ScopedJavaLocalRef<jstring> jbody(
+    ConvertUTF16ToJavaString(env, params.body));
+  ScopedJavaLocalRef<jstring> jreplace_id(
+    ConvertUTF16ToJavaString(env, params.replace_id));
+
+  Java_XWalkContentsClientBridge_showNotification(
+      env, obj.obj(), jtitle.obj(), jbody.obj(),
+      jreplace_id.obj(), params.notification_id,
+      process_id, route_id);
+
+  if (params.icon_url.is_valid()) {
+    RenderViewHost* rvh = RenderViewHost::FromID(process_id, route_id);
+    if (rvh) {
+      WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
+      if (web_contents) {
+        int download_request_id = web_contents->DownloadImage(
+            params.icon_url,
+            false,
+            0,
+            base::Bind(
+                &XWalkContentsClientBridge::OnNotificationIconDownloaded,
+                base::Unretained(this)));
+        std::vector<int> ids;
+        ids.push_back(params.notification_id);
+        ids.push_back(process_id);
+        ids.push_back(route_id);
+        downloading_icon_notifications_[download_request_id] = ids;
+      }
+    }
+  }
+}
+
+void XWalkContentsClientBridge::CancelNotification(
+    int notification_id,
+    int process_id,
+    int route_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  JNIEnv* env = AttachCurrentThread();
+
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+  if (obj.is_null())
+    return;
+
+  Java_XWalkContentsClientBridge_cancelNotification(
+      env, obj.obj(), notification_id,
+      process_id, route_id);
+}
+
 void XWalkContentsClientBridge::ConfirmJsResult(JNIEnv* env,
                                                 jobject,
                                                 int id,
@@ -183,7 +316,7 @@ void XWalkContentsClientBridge::ConfirmJsResult(JNIEnv* env,
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   content::JavaScriptDialogManager::DialogClosedCallback* callback =
       pending_js_dialog_callbacks_.Lookup(id);
-  string16 prompt_text;
+  base::string16 prompt_text;
   if (prompt) {
     prompt_text = ConvertJavaStringToUTF16(env, prompt);
   }
@@ -197,12 +330,12 @@ void XWalkContentsClientBridge::CancelJsResult(JNIEnv*, jobject, int id) {
   content::JavaScriptDialogManager::DialogClosedCallback* callback =
       pending_js_dialog_callbacks_.Lookup(id);
   if (callback)
-    callback->Run(false, string16());
+    callback->Run(false, base::string16());
   pending_js_dialog_callbacks_.Remove(id);
 }
 
 void XWalkContentsClientBridge::ExitFullscreen(
-    JNIEnv*, jobject, jint j_web_contents) {
+    JNIEnv*, jobject, jlong j_web_contents) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   WebContents* web_contents = reinterpret_cast<WebContents*>(j_web_contents);
   if (web_contents) {
@@ -212,6 +345,88 @@ void XWalkContentsClientBridge::ExitFullscreen(
   }
 }
 
+void XWalkContentsClientBridge::NotificationDisplayed(
+    JNIEnv*, jobject, int id, int process_id, int route_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  RenderViewHost* rvh = RenderViewHost::FromID(
+      process_id, route_id);
+  if (!rvh)
+    return;
+  rvh->DesktopNotificationPostDisplay(id);
+}
+
+void XWalkContentsClientBridge::NotificationError(
+    JNIEnv* env, jobject, int id, jstring error,
+    int process_id, int route_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  RenderViewHost* rvh = RenderViewHost::FromID(
+      process_id, route_id);
+  if (!rvh)
+    return;
+  base::string16 error_text;
+  if (error)
+    error_text = ConvertJavaStringToUTF16(env, error);
+  rvh->DesktopNotificationPostError(id, error_text);
+}
+
+void XWalkContentsClientBridge::NotificationClicked(
+    JNIEnv*, jobject, int id, int process_id, int route_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  RenderViewHost* rvh = RenderViewHost::FromID(
+      process_id, route_id);
+  if (!rvh)
+    return;
+  rvh->DesktopNotificationPostClick(id);
+}
+
+void XWalkContentsClientBridge::NotificationClosed(
+    JNIEnv*, jobject, int id, bool by_user,
+    int process_id, int route_id) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  RenderViewHost* rvh = RenderViewHost::FromID(
+      process_id, route_id);
+  if (!rvh)
+    return;
+  rvh->DesktopNotificationPostClose(id, by_user);
+}
+
+void XWalkContentsClientBridge::OnFilesSelected(
+    JNIEnv* env, jobject, int process_id, int render_id,
+    int mode, jstring filepath, jstring display_name) {
+  content::RenderViewHost* rvh =
+      content::RenderViewHost::FromID(process_id, render_id);
+  if (!rvh)
+    return;
+
+  std::string path = base::android::ConvertJavaStringToUTF8(env, filepath);
+  std::string file_name =
+      base::android::ConvertJavaStringToUTF8(env, display_name);
+  base::FilePath file_path = base::FilePath(path);
+  ui::SelectedFileInfo file_info;
+  file_info.file_path = file_path;
+  file_info.local_path = file_path;
+  if (!file_name.empty())
+    file_info.display_name = file_name;
+  std::vector<ui::SelectedFileInfo> files;
+  files.push_back(file_info);
+
+  rvh->FilesSelectedInChooser(
+      files, static_cast<content::FileChooserParams::Mode>(mode));
+}
+
+void XWalkContentsClientBridge::OnFilesNotSelected(
+    JNIEnv* env, jobject, int process_id, int render_id, int mode) {
+  content::RenderViewHost* rvh =
+      content::RenderViewHost::FromID(process_id, render_id);
+  if (!rvh)
+    return;
+
+  std::vector<ui::SelectedFileInfo> files;
+
+  rvh->FilesSelectedInChooser(
+      files, static_cast<content::FileChooserParams::Mode>(mode));
+}
+
 bool RegisterXWalkContentsClientBridge(JNIEnv* env) {
   return RegisterNativesImpl(env) >= 0;
 }