Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / android / xwalk_contents_client_bridge.cc
index 3998cc0..5cb998d 100644 (file)
@@ -10,6 +10,7 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/callback.h"
+#include "base/containers/scoped_ptr_hash_map.h"
 #include "base/guid.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/desktop_notification_delegate.h"
@@ -17,6 +18,7 @@
 #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_file_info.h"
 #include "content/public/common/file_chooser_params.h"
 #include "content/public/common/show_desktop_notification_params.h"
 #include "jni/XWalkContentsClientBridge_jni.h"
@@ -32,6 +34,7 @@ using base::android::ConvertUTF8ToJavaString;
 using base::android::ConvertUTF16ToJavaString;
 using base::android::JavaRef;
 using base::android::ScopedJavaLocalRef;
+using base::ScopedPtrHashMap;
 using content::BrowserThread;
 using content::FileChooserParams;
 using content::RenderViewHost;
@@ -41,25 +44,22 @@ namespace xwalk {
 
 namespace {
 
-void RunUpdateNotificationIconOnUIThread(
-    int notification_id,
-    content::RenderFrameHost* render_frame_host,
-    const SkBitmap& icon) {
-  XWalkContentsClientBridgeBase* bridge =
-      XWalkContentsClientBridgeBase::FromRenderFrameHost(render_frame_host);
-  if (bridge)
-    bridge->UpdateNotificationIcon(notification_id, icon);
-}
+int g_next_notification_id_ = 1;
+
+ScopedPtrHashMap<int, content::DesktopNotificationDelegate> g_notification_map_;
 
 }  // namespace
 
-static IDMap<content::DesktopNotificationDelegate> notifications_;
 
-XWalkContentsClientBridge::XWalkContentsClientBridge(JNIEnv* env, jobject obj)
-    : java_ref_(env, obj) {
+XWalkContentsClientBridge::XWalkContentsClientBridge(
+    JNIEnv* env, jobject obj,
+    content::WebContents* web_contents)
+    : java_ref_(env, obj),
+      icon_helper_(new XWalkIconHelper(web_contents)) {
   DCHECK(obj);
   Java_XWalkContentsClientBridge_setNativeContentsClientBridge(
       env, obj, reinterpret_cast<intptr_t>(this));
+  icon_helper_->SetListener(this);
 }
 
 XWalkContentsClientBridge::~XWalkContentsClientBridge() {
@@ -89,7 +89,9 @@ void XWalkContentsClientBridge::AllowCertificateError(
     return;
 
   std::string der_string;
-  net::X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_string);
+  if (!net::X509Certificate::GetDEREncoded(cert->os_cert_handle(),
+      &der_string))
+    return;
   ScopedJavaLocalRef<jbyteArray> jcert = base::android::ToJavaByteArray(
       env,
       reinterpret_cast<const uint8*>(der_string.data()),
@@ -203,55 +205,8 @@ bool XWalkContentsClientBridge::OnReceivedHttpAuthRequest(
   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())
-      return;
-
-    int notification_id = iter->second.first;
-    content::RenderFrameHost* render_frame_host = iter->second.second;
-    // 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,
-                   render_frame_host,
-                   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());
-}
-
 static void CancelNotification(
-    JavaObjectWeakGlobalRef java_ref,
-    int notification_id, content::DesktopNotificationDelegate* delegate) {
+    JavaObjectWeakGlobalRef java_ref, int notification_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   JNIEnv* env = AttachCurrentThread();
   ScopedJavaLocalRef<jobject> obj = java_ref.get(env);
@@ -259,13 +214,12 @@ static void CancelNotification(
     return;
 
   Java_XWalkContentsClientBridge_cancelNotification(
-      env, obj.obj(), notification_id, reinterpret_cast<intptr_t>(delegate));
+      env, obj.obj(), notification_id);
 }
 
 void XWalkContentsClientBridge::ShowNotification(
     const content::ShowDesktopNotificationHostMsgParams& params,
-    content::RenderFrameHost* render_frame_host,
-    content::DesktopNotificationDelegate* delegate,
+    scoped_ptr<content::DesktopNotificationDelegate> delegate,
     base::Closure* cancel_callback) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   JNIEnv* env = AttachCurrentThread();
@@ -280,33 +234,17 @@ void XWalkContentsClientBridge::ShowNotification(
     ConvertUTF16ToJavaString(env, params.body));
   ScopedJavaLocalRef<jstring> jreplace_id(
     ConvertUTF16ToJavaString(env, params.replace_id));
+  ScopedJavaLocalRef<jobject> jicon = gfx::ConvertToJavaBitmap(&params.icon);
 
-  int notification_id = notifications_.Add(delegate);
+  int notification_id = g_next_notification_id_++;
+  g_notification_map_.set(notification_id, delegate.Pass());
   Java_XWalkContentsClientBridge_showNotification(
       env, obj.obj(), jtitle.obj(), jbody.obj(),
-      jreplace_id.obj(), notification_id,
-      reinterpret_cast<intptr_t>(delegate));
+      jreplace_id.obj(), jicon.obj(), notification_id);
 
   if (cancel_callback)
-    *cancel_callback =
-        base::Bind(&CancelNotification, java_ref_, notification_id, delegate);
-
-  if (params.icon_url.is_valid()) {
-    WebContents* web_contents =
-      WebContents::FromRenderFrameHost(render_frame_host);
-    if (web_contents) {
-      int download_request_id = web_contents->DownloadImage(
-          params.icon_url,
-          false,
-          0,
-          base::Bind(
-              &XWalkContentsClientBridge::OnNotificationIconDownloaded,
-              base::Unretained(this)));
-      NotificationDownloadRequestInfos info =
-          std::make_pair(notification_id, render_frame_host);
-      downloading_icon_notifications_[download_request_id] = info;
-    }
-  }
+    *cancel_callback = base::Bind(
+        &CancelNotification, java_ref_, notification_id);
 }
 
 void XWalkContentsClientBridge::OnWebLayoutPageScaleFactorChanged(
@@ -357,37 +295,30 @@ void XWalkContentsClientBridge::ExitFullscreen(
 }
 
 void XWalkContentsClientBridge::NotificationDisplayed(
-    JNIEnv*, jobject, jlong delegate) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  content::DesktopNotificationDelegate* notification_delegate =
-    reinterpret_cast<content::DesktopNotificationDelegate*> (delegate);
-  notification_delegate->NotificationDisplayed();
-}
-
-void XWalkContentsClientBridge::NotificationError(
-    JNIEnv* env, jobject, jlong delegate) {
+    JNIEnv*, jobject, jint notification_id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   content::DesktopNotificationDelegate* notification_delegate =
-    reinterpret_cast<content::DesktopNotificationDelegate*> (delegate);
-  notification_delegate->NotificationError();
+      g_notification_map_.get(notification_id);
+  if (notification_delegate)
+    notification_delegate->NotificationDisplayed();
 }
 
 void XWalkContentsClientBridge::NotificationClicked(
-    JNIEnv*, jobject, jint id, jlong delegate) {
+    JNIEnv*, jobject, jint id) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  notifications_.Remove(id);
-  content::DesktopNotificationDelegate* notification_delegate =
-    reinterpret_cast<content::DesktopNotificationDelegate*> (delegate);
-  notification_delegate->NotificationClick();
+  scoped_ptr<content::DesktopNotificationDelegate> notification_delegate =
+      g_notification_map_.take_and_erase(id);
+  if (notification_delegate.get())
+    notification_delegate->NotificationClick();
 }
 
 void XWalkContentsClientBridge::NotificationClosed(
-    JNIEnv*, jobject, jint id, bool by_user, jlong delegate) {
+    JNIEnv*, jobject, jint id, bool by_user) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  notifications_.Remove(id);
-  content::DesktopNotificationDelegate* notification_delegate =
-    reinterpret_cast<content::DesktopNotificationDelegate*> (delegate);
-  notification_delegate->NotificationClosed(by_user);
+  scoped_ptr<content::DesktopNotificationDelegate> notification_delegate =
+      g_notification_map_.take_and_erase(id);
+  if (notification_delegate.get())
+    notification_delegate->NotificationClosed(by_user);
 }
 
 void XWalkContentsClientBridge::OnFilesSelected(
@@ -402,12 +333,11 @@ void XWalkContentsClientBridge::OnFilesSelected(
   std::string file_name =
       base::android::ConvertJavaStringToUTF8(env, display_name);
   base::FilePath file_path = base::FilePath(path);
-  ui::SelectedFileInfo file_info;
+  content::FileChooserFileInfo 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;
+  std::vector<content::FileChooserFileInfo> files;
   files.push_back(file_info);
 
   rvh->FilesSelectedInChooser(
@@ -421,14 +351,46 @@ void XWalkContentsClientBridge::OnFilesNotSelected(
   if (!rvh)
     return;
 
-  std::vector<ui::SelectedFileInfo> files;
+  std::vector<content::FileChooserFileInfo> files;
 
   rvh->FilesSelectedInChooser(
       files, static_cast<content::FileChooserParams::Mode>(mode));
 }
 
+void XWalkContentsClientBridge::DownloadIcon(JNIEnv* env,
+                                             jobject obj,
+                                             jstring url) {
+  std::string url_str = base::android::ConvertJavaStringToUTF8(env, url);
+  icon_helper_->DownloadIcon(GURL(url_str));
+}
+
+void XWalkContentsClientBridge::OnIconAvailable(const GURL& icon_url) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+
+  ScopedJavaLocalRef<jstring> jurl(
+      ConvertUTF8ToJavaString(env, icon_url.spec()));
+
+  Java_XWalkContentsClientBridge_onIconAvailable(env, obj.obj(), jurl.obj());
+}
+
+void XWalkContentsClientBridge::OnReceivedIcon(const GURL& icon_url,
+                                               const SkBitmap& bitmap) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+
+  ScopedJavaLocalRef<jstring> jurl(
+      ConvertUTF8ToJavaString(env, icon_url.spec()));
+  ScopedJavaLocalRef<jobject> jicon = gfx::ConvertToJavaBitmap(&bitmap);
+
+  Java_XWalkContentsClientBridge_onReceivedIcon(
+      env, obj.obj(), jurl.obj(), jicon.obj());
+}
+
 bool RegisterXWalkContentsClientBridge(JNIEnv* env) {
-  return RegisterNativesImpl(env) >= 0;
+  return RegisterNativesImpl(env);
 }
 
 }  // namespace xwalk