1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/ui/android/context_menu_helper.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/android/jni_android.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/android/jni_string.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/android/content_view_core.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/android/download_controller_android.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/common/context_menu_params.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "jni/ContextMenuHelper_jni.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "jni/ContextMenuParams_jni.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/point.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using base::android::ConvertUTF8ToJavaString;
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using base::android::ConvertUTF16ToJavaString;
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using base::android::ScopedJavaLocalRef;
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY(ContextMenuHelper);
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ContextMenuHelper::ContextMenuHelper(content::WebContents* web_contents)
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : web_contents_(web_contents) {
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  java_obj_.Reset(
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      env,
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      Java_ContextMenuHelper_create(env, reinterpret_cast<long>(this)).obj());
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(!java_obj_.is_null());
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ContextMenuHelper::~ContextMenuHelper() {
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Java_ContextMenuHelper_destroy(env, java_obj_.obj());
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ContextMenuHelper::ShowContextMenu(
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const content::ContextMenuParams& params) {
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::ContentViewCore* content_view_core =
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      content::ContentViewCore::FromWebContents(web_contents_);
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!content_view_core)
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  context_menu_params_ = params;
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Java_ContextMenuHelper_showContextMenu(
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      env,
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      java_obj_.obj(),
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      content_view_core->GetJavaObject().obj(),
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ContextMenuHelper::CreateJavaContextMenuParams(params).obj());
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Called to show a custom context menu. Used by the NTP.
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ContextMenuHelper::ShowCustomContextMenu(
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const content::ContextMenuParams& params,
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::Callback<void(int)>& callback) {
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  context_menu_callback_ = callback;
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ShowContextMenu(params);
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ContextMenuHelper::SetPopulator(jobject jpopulator) {
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Java_ContextMenuHelper_setPopulator(env, java_obj_.obj(), jpopulator);
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::android::ScopedJavaLocalRef<jobject>
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ContextMenuHelper::CreateJavaContextMenuParams(
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const content::ContextMenuParams& params) {
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> jmenu_info =
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ContextMenuParamsAndroid::Java_ContextMenuParams_create(
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          env,
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          params.media_type,
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          ConvertUTF8ToJavaString(env, params.link_url.spec()).obj(),
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          ConvertUTF16ToJavaString(env, params.link_text).obj(),
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          ConvertUTF8ToJavaString(env, params.unfiltered_link_url.spec()).obj(),
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          ConvertUTF8ToJavaString(env, params.src_url.spec()).obj(),
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          ConvertUTF16ToJavaString(env, params.selection_text).obj(),
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          params.is_editable);
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<content::MenuItem>::const_iterator i;
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (i = params.custom_items.begin(); i != params.custom_items.end(); ++i) {
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ContextMenuParamsAndroid::Java_ContextMenuParams_addCustomItem(
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        env,
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        jmenu_info.obj(),
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ConvertUTF16ToJavaString(env, i->label).obj(),
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        i->action);
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return jmenu_info;
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ContextMenuHelper::OnCustomItemSelected(JNIEnv* env,
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             jobject obj,
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             jint action) {
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!context_menu_callback_.is_null()) {
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    context_menu_callback_.Run(action);
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    context_menu_callback_.Reset();
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ContextMenuHelper::OnStartDownload(JNIEnv* env,
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        jobject obj,
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        jboolean jis_link) {
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::DownloadControllerAndroid::Get()->StartContextMenuDownload(
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      context_menu_params_,
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      web_contents_,
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      jis_link);
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool RegisterContextMenuHelper(JNIEnv* env) {
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return RegisterNativesImpl(env) &&
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)         ContextMenuParamsAndroid::RegisterNativesImpl(env);
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
115