1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_METHOD_INVOCATION_HELPER_H_
6#define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_METHOD_INVOCATION_HELPER_H_
7
8#include <map>
9
10#include "base/android/jni_weak_ref.h"
11#include "base/android/scoped_java_ref.h"
12#include "base/memory/ref_counted.h"
13#include "base/values.h"
14#include "content/browser/android/java/gin_java_bound_object.h"
15#include "content/browser/android/java/java_type.h"
16#include "content/common/android/gin_java_bridge_errors.h"
17#include "content/common/content_export.h"
18
19namespace content {
20
21class JavaMethod;
22
23// Instances of this class are created and used on the background thread.
24class CONTENT_EXPORT GinJavaMethodInvocationHelper
25    : public base::RefCountedThreadSafe<GinJavaMethodInvocationHelper> {
26 public:
27  class DispatcherDelegate {
28   public:
29    DispatcherDelegate() {}
30    virtual ~DispatcherDelegate() {}
31    virtual JavaObjectWeakGlobalRef GetObjectWeakRef(
32        GinJavaBoundObject::ObjectID object_id) = 0;
33
34   private:
35    DISALLOW_COPY_AND_ASSIGN(DispatcherDelegate);
36  };
37
38  class ObjectDelegate {
39   public:
40    ObjectDelegate() {}
41    virtual ~ObjectDelegate() {}
42    virtual base::android::ScopedJavaLocalRef<jobject> GetLocalRef(
43        JNIEnv* env) = 0;
44    virtual base::android::ScopedJavaLocalRef<jclass> GetLocalClassRef(
45        JNIEnv* env) = 0;
46    virtual const JavaMethod* FindMethod(const std::string& method_name,
47                                         size_t num_parameters) = 0;
48    virtual bool IsObjectGetClassMethod(const JavaMethod* method) = 0;
49    virtual const base::android::JavaRef<jclass>& GetSafeAnnotationClass() = 0;
50
51   private:
52    DISALLOW_COPY_AND_ASSIGN(ObjectDelegate);
53  };
54
55  GinJavaMethodInvocationHelper(scoped_ptr<ObjectDelegate> object,
56                                const std::string& method_name,
57                                const base::ListValue& arguments);
58  void Init(DispatcherDelegate* dispatcher);
59
60  void Invoke();
61
62  bool HoldsPrimitiveResult();
63  const base::ListValue& GetPrimitiveResult();
64  const base::android::JavaRef<jobject>& GetObjectResult();
65  const base::android::JavaRef<jclass>& GetSafeAnnotationClass();
66  const GinJavaBridgeError GetInvocationError();
67
68 private:
69  friend class base::RefCountedThreadSafe<GinJavaMethodInvocationHelper>;
70  ~GinJavaMethodInvocationHelper();
71
72  void BuildObjectRefsFromListValue(DispatcherDelegate* dispatcher,
73                                    const base::Value* list_value);
74  void BuildObjectRefsFromDictionaryValue(DispatcherDelegate* dispatcher,
75                                          const base::Value* dict_value);
76
77  bool AppendObjectRef(DispatcherDelegate* dispatcher,
78                       const base::Value* raw_value);
79
80  void InvokeMethod(jobject object,
81                    jclass clazz,
82                    const JavaType& return_type,
83                    jmethodID id,
84                    jvalue* parameters);
85  void SetInvocationError(GinJavaBridgeError error);
86  void SetPrimitiveResult(const base::ListValue& result_wrapper);
87  void SetObjectResult(
88      const base::android::JavaRef<jobject>& object,
89      const base::android::JavaRef<jclass>& safe_annotation_clazz);
90
91  typedef std::map<GinJavaBoundObject::ObjectID,
92                   JavaObjectWeakGlobalRef> ObjectRefs;
93
94  scoped_ptr<ObjectDelegate> object_;
95  const std::string method_name_;
96  scoped_ptr<base::ListValue> arguments_;
97  ObjectRefs object_refs_;
98  bool holds_primitive_result_;
99  scoped_ptr<base::ListValue> primitive_result_;
100  GinJavaBridgeError invocation_error_;
101  base::android::ScopedJavaGlobalRef<jobject> object_result_;
102  base::android::ScopedJavaGlobalRef<jclass> safe_annotation_clazz_;
103
104  DISALLOW_COPY_AND_ASSIGN(GinJavaMethodInvocationHelper);
105};
106
107}  // namespace content
108
109#endif  // CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_METHOD_INVOCATION_HELPER_H_
110