1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file.
4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/android/java/gin_java_method_invocation_helper.h"
6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/android/jni_android.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/android/java/jni_helper.h"
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/common/android/gin_java_bridge_value.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace content {
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace {
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class NullObjectDelegate
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : public GinJavaMethodInvocationHelper::ObjectDelegate {
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NullObjectDelegate() {}
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~NullObjectDelegate() {}
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual base::android::ScopedJavaLocalRef<jobject> GetLocalRef(
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      JNIEnv* env) OVERRIDE {
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return base::android::ScopedJavaLocalRef<jobject>();
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual base::android::ScopedJavaLocalRef<jclass> GetLocalClassRef(
296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      JNIEnv* env) OVERRIDE {
306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return base::android::ScopedJavaLocalRef<jclass>();
316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual const JavaMethod* FindMethod(const std::string& method_name,
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                       size_t num_parameters) OVERRIDE {
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return NULL;
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual bool IsObjectGetClassMethod(const JavaMethod* method) OVERRIDE {
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return false;
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual const base::android::JavaRef<jclass>& GetSafeAnnotationClass()
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      OVERRIDE {
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return safe_annotation_class_;
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jclass> safe_annotation_class_;
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NullObjectDelegate);
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class NullDispatcherDelegate
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : public GinJavaMethodInvocationHelper::DispatcherDelegate {
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NullDispatcherDelegate() {}
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~NullDispatcherDelegate() {}
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual JavaObjectWeakGlobalRef GetObjectWeakRef(
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      GinJavaBoundObject::ObjectID object_id) OVERRIDE {
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return JavaObjectWeakGlobalRef();
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NullDispatcherDelegate);
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class GinJavaMethodInvocationHelperTest : public testing::Test {
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace {
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class CountingDispatcherDelegate
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : public GinJavaMethodInvocationHelper::DispatcherDelegate {
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CountingDispatcherDelegate() {}
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~CountingDispatcherDelegate() {}
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual JavaObjectWeakGlobalRef GetObjectWeakRef(
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      GinJavaBoundObject::ObjectID object_id) OVERRIDE {
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    counters_[object_id]++;
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return JavaObjectWeakGlobalRef();
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void AssertInvocationsCount(GinJavaBoundObject::ObjectID begin_object_id,
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              GinJavaBoundObject::ObjectID end_object_id) {
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(end_object_id - begin_object_id,
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              static_cast<int>(counters_.size()));
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    for (GinJavaBoundObject::ObjectID i = begin_object_id;
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         i < end_object_id; ++i) {
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_LT(0, counters_[i]) << "ObjectID: " << i;
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  typedef std::map<GinJavaBoundObject::ObjectID, int> Counters;
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Counters counters_;
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CountingDispatcherDelegate);
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(GinJavaMethodInvocationHelperTest, RetrievalOfObjectsNoObjects) {
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ListValue no_objects;
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (int i = 0; i < 10; ++i) {
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    no_objects.AppendInteger(i);
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<GinJavaMethodInvocationHelper> helper =
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new GinJavaMethodInvocationHelper(
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          scoped_ptr<GinJavaMethodInvocationHelper::ObjectDelegate>(
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              new NullObjectDelegate()),
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "foo",
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          no_objects);
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CountingDispatcherDelegate counter;
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  helper->Init(&counter);
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  counter.AssertInvocationsCount(0, 0);
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(GinJavaMethodInvocationHelperTest, RetrievalOfObjectsHaveObjects) {
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ListValue objects;
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  objects.AppendInteger(100);
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  objects.Append(GinJavaBridgeValue::CreateObjectIDValue(1).release());
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ListValue* sub_list = new base::ListValue();
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sub_list->AppendInteger(200);
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sub_list->Append(GinJavaBridgeValue::CreateObjectIDValue(2).release());
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  objects.Append(sub_list);
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::DictionaryValue* sub_dict = new base::DictionaryValue();
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sub_dict->SetInteger("1", 300);
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sub_dict->Set("2", GinJavaBridgeValue::CreateObjectIDValue(3).release());
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  objects.Append(sub_dict);
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ListValue* sub_list_with_dict = new base::ListValue();
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::DictionaryValue* sub_sub_dict = new base::DictionaryValue();
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sub_sub_dict->Set("1", GinJavaBridgeValue::CreateObjectIDValue(4).release());
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sub_list_with_dict->Append(sub_sub_dict);
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  objects.Append(sub_list_with_dict);
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::DictionaryValue* sub_dict_with_list = new base::DictionaryValue();
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ListValue* sub_sub_list = new base::ListValue();
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sub_sub_list->Append(GinJavaBridgeValue::CreateObjectIDValue(5).release());
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sub_dict_with_list->Set("1", sub_sub_list);
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  objects.Append(sub_dict_with_list);
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<GinJavaMethodInvocationHelper> helper =
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new GinJavaMethodInvocationHelper(
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          scoped_ptr<GinJavaMethodInvocationHelper::ObjectDelegate>(
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              new NullObjectDelegate()),
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "foo",
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          objects);
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CountingDispatcherDelegate counter;
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  helper->Init(&counter);
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  counter.AssertInvocationsCount(1, 6);
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass ObjectIsGoneObjectDelegate : public NullObjectDelegate {
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ObjectIsGoneObjectDelegate() :
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      get_local_ref_called_(false) {
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // We need a Java Method object to create a valid JavaMethod instance.
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    JNIEnv* env = base::android::AttachCurrentThread();
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    jmethodID method_id =
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GetMethodIDFromClassName(env, "java/lang/Object", "hashCode", "()I");
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_TRUE(method_id);
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::android::ScopedJavaLocalRef<jobject> method_obj(
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        env,
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        env->ToReflectedMethod(
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            base::android::GetClass(env, "java/lang/Object").obj(),
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            method_id,
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            false));
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_TRUE(method_obj.obj());
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    method_.reset(new JavaMethod(method_obj));
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~ObjectIsGoneObjectDelegate() {}
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual base::android::ScopedJavaLocalRef<jobject> GetLocalRef(
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      JNIEnv* env) OVERRIDE {
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    get_local_ref_called_ = true;
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return NullObjectDelegate::GetLocalRef(env);
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual const JavaMethod* FindMethod(const std::string& method_name,
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                       size_t num_parameters) OVERRIDE {
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return method_.get();
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool get_local_ref_called() { return get_local_ref_called_; }
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const std::string& get_method_name() { return method_->name(); }
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch protected:
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<JavaMethod> method_;
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool get_local_ref_called_;
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ObjectIsGoneObjectDelegate);
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(GinJavaMethodInvocationHelperTest, HandleObjectIsGone) {
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ListValue no_objects;
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ObjectIsGoneObjectDelegate* object_delegate =
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new ObjectIsGoneObjectDelegate();
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<GinJavaMethodInvocationHelper> helper =
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new GinJavaMethodInvocationHelper(
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          scoped_ptr<GinJavaMethodInvocationHelper::ObjectDelegate>(
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              object_delegate),
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          object_delegate->get_method_name(),
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          no_objects);
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NullDispatcherDelegate dispatcher;
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  helper->Init(&dispatcher);
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(object_delegate->get_local_ref_called());
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(kGinJavaBridgeNoError, helper->GetInvocationError());
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  helper->Invoke();
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(object_delegate->get_local_ref_called());
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(helper->HoldsPrimitiveResult());
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(helper->GetPrimitiveResult().empty());
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(kGinJavaBridgeObjectIsGone, helper->GetInvocationError());
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace {
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class MethodNotFoundObjectDelegate : public NullObjectDelegate {
230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  MethodNotFoundObjectDelegate() : find_method_called_(false) {}
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~MethodNotFoundObjectDelegate() {}
234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual base::android::ScopedJavaLocalRef<jobject> GetLocalRef(
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      JNIEnv* env) OVERRIDE {
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return base::android::ScopedJavaLocalRef<jobject>(
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        env, static_cast<jobject>(env->FindClass("java/lang/String")));
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual const JavaMethod* FindMethod(const std::string& method_name,
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                       size_t num_parameters) OVERRIDE {
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    find_method_called_ = true;
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return NULL;
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool find_method_called() const { return find_method_called_; }
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) protected:
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool find_method_called_;
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MethodNotFoundObjectDelegate);
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(GinJavaMethodInvocationHelperTest, HandleMethodNotFound) {
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ListValue no_objects;
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  MethodNotFoundObjectDelegate* object_delegate =
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new MethodNotFoundObjectDelegate();
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<GinJavaMethodInvocationHelper> helper =
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new GinJavaMethodInvocationHelper(
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          scoped_ptr<GinJavaMethodInvocationHelper::ObjectDelegate>(
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              object_delegate),
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "foo",
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          no_objects);
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NullDispatcherDelegate dispatcher;
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  helper->Init(&dispatcher);
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(object_delegate->find_method_called());
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(kGinJavaBridgeNoError, helper->GetInvocationError());
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  helper->Invoke();
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(object_delegate->find_method_called());
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(helper->HoldsPrimitiveResult());
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(helper->GetPrimitiveResult().empty());
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(kGinJavaBridgeMethodNotFound, helper->GetInvocationError());
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace {
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class GetClassObjectDelegate : public MethodNotFoundObjectDelegate {
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GetClassObjectDelegate() : get_class_called_(false) {}
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~GetClassObjectDelegate() {}
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual const JavaMethod* FindMethod(const std::string& method_name,
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                       size_t num_parameters) OVERRIDE {
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    find_method_called_ = true;
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return kFakeGetClass;
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual bool IsObjectGetClassMethod(const JavaMethod* method) OVERRIDE {
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    get_class_called_ = true;
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return kFakeGetClass == method;
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool get_class_called() const { return get_class_called_; }
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  static const JavaMethod* kFakeGetClass;
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool get_class_called_;
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GetClassObjectDelegate);
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// We don't expect GinJavaMethodInvocationHelper to actually invoke the
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// method, since the point of the test is to verify whether calls to
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// 'getClass' get blocked.
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const JavaMethod* GetClassObjectDelegate::kFakeGetClass =
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    (JavaMethod*)0xdeadbeef;
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(GinJavaMethodInvocationHelperTest, HandleGetClassInvocation) {
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::ListValue no_objects;
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GetClassObjectDelegate* object_delegate =
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new GetClassObjectDelegate();
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_refptr<GinJavaMethodInvocationHelper> helper =
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new GinJavaMethodInvocationHelper(
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          scoped_ptr<GinJavaMethodInvocationHelper::ObjectDelegate>(
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              object_delegate),
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          "foo",
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          no_objects);
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NullDispatcherDelegate dispatcher;
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  helper->Init(&dispatcher);
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(object_delegate->find_method_called());
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(object_delegate->get_class_called());
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(kGinJavaBridgeNoError, helper->GetInvocationError());
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  helper->Invoke();
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(object_delegate->find_method_called());
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(object_delegate->get_class_called());
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(helper->HoldsPrimitiveResult());
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(helper->GetPrimitiveResult().empty());
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(kGinJavaBridgeAccessToObjectGetClassIsBlocked,
336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            helper->GetInvocationError());
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace content
340