1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169

content / browser / android / ime_adapter_android.h [blame]

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_ANDROID_IME_ADAPTER_ANDROID_H_
#define CONTENT_BROWSER_ANDROID_IME_ADAPTER_ANDROID_H_

#include <jni.h>

#include <vector>

#include "base/android/jni_weak_ref.h"
#include "base/memory/raw_ptr.h"
#include "content/browser/android/render_widget_host_connector.h"
#include "content/common/content_export.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"

namespace ui {

namespace mojom {
class TextInputState;
}  // namespace mojom

struct ImeTextSpan;

}  // namespace ui

namespace blink {
namespace mojom {

class FrameWidgetInputHandler;

}  // namespace mojom
}  // namespace blink

namespace content {

class RenderFrameHost;
class RenderWidgetHostImpl;
class RenderWidgetHostViewAndroid;

// This class is in charge of dispatching key events from the java side
// and forward to renderer along with input method results via
// corresponding host view.
class CONTENT_EXPORT ImeAdapterAndroid : public RenderWidgetHostConnector {
 public:
  ImeAdapterAndroid(JNIEnv* env,
                    const base::android::JavaParamRef<jobject>& obj,
                    WebContents* web_contents);
  ~ImeAdapterAndroid() override;

  // Called from java -> native
  bool SendKeyEvent(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>&,
      const base::android::JavaParamRef<jobject>& original_key_event,
      int type,
      int modifiers,
      jlong time_ms,
      int key_code,
      int scan_code,
      bool is_system_key,
      int unicode_text);
  void SetComposingText(JNIEnv* env,
                        const base::android::JavaParamRef<jobject>& obj,
                        const base::android::JavaParamRef<jobject>& text,
                        const base::android::JavaParamRef<jstring>& text_str,
                        int relative_cursor_pos);
  void CommitText(JNIEnv* env,
                  const base::android::JavaParamRef<jobject>& obj,
                  const base::android::JavaParamRef<jobject>& text,
                  const base::android::JavaParamRef<jstring>& text_str,
                  int relative_cursor_pos);
  void FinishComposingText(JNIEnv* env,
                           const base::android::JavaParamRef<jobject>&);
  void SetEditableSelectionOffsets(JNIEnv*,
                                   const base::android::JavaParamRef<jobject>&,
                                   int start,
                                   int end);
  void SetComposingRegion(JNIEnv*,
                          const base::android::JavaParamRef<jobject>&,
                          int start,
                          int end);
  void DeleteSurroundingText(JNIEnv*,
                             const base::android::JavaParamRef<jobject>&,
                             int before,
                             int after);
  void DeleteSurroundingTextInCodePoints(
      JNIEnv*,
      const base::android::JavaParamRef<jobject>&,
      int before,
      int after);
  void RequestCursorUpdate(JNIEnv*,
                           const base::android::JavaParamRef<jobject>&,
                           bool immediateRequest,
                           bool monitorRequest);
  bool RequestTextInputStateUpdate(JNIEnv*,
                                   const base::android::JavaParamRef<jobject>&);
  void HandleStylusWritingGestureAction(
      JNIEnv*,
      const base::android::JavaParamRef<jobject>&,
      const jint,
      const base::android::JavaParamRef<jobject>&);

  void OnStylusWritingGestureActionCompleted(
      int,
      blink::mojom::HandwritingGestureResult);

  void SetImeRenderWidgetHost();

  // RendetWidgetHostConnector implementation.
  void UpdateRenderProcessConnection(
      RenderWidgetHostViewAndroid* old_rwhva,
      RenderWidgetHostViewAndroid* new_rhwva) override;

  void UpdateFrameInfo(const gfx::SelectionBound& selection_start,
                       float dip_scale,
                       float content_offset_ypix);
  void OnRenderFrameMetadataChangedAfterActivation(const gfx::SizeF& new_size);

  // Called from native -> java
  void CancelComposition();
  void FocusedNodeChanged(bool is_editable_node,
                          const gfx::Rect& node_bounds_in_screen);
  // Update the composition character bounds, the visible line bounds or both.
  void SetBounds(const std::vector<gfx::Rect>& character_bounds,
                 const bool character_bounds_changed,
                 const std::optional<std::vector<gfx::Rect>>& line_bounds);
  // Check if stylus writing can be started.
  bool ShouldInitiateStylusWriting();

  void OnEditElementFocusedForStylusWriting(
      const gfx::Rect& focused_edit_bounds,
      const gfx::Rect& caret_bounds);

  base::android::ScopedJavaLocalRef<jobject> java_ime_adapter_for_testing(
      JNIEnv* env) {
    return java_ime_adapter_.get(env);
  }

  void UpdateState(const ui::mojom::TextInputState& state);
  void UpdateOnTouchDown();

  void AdvanceFocusForIME(JNIEnv*,
                          const base::android::JavaParamRef<jobject>&,
                          jint);

 private:
  RenderWidgetHostImpl* GetFocusedWidget();
  RenderFrameHost* GetFocusedFrame();
  blink::mojom::FrameWidgetInputHandler* GetFocusedFrameWidgetInputHandler();
  std::vector<ui::ImeTextSpan> GetImeTextSpansFromJava(
      JNIEnv* env,
      const base::android::JavaParamRef<jobject>& obj,
      const base::android::JavaParamRef<jobject>& text,
      const std::u16string& text16);

  gfx::SizeF old_viewport_size_;

  // Current RenderWidgetHostView connected to this instance. Can be null.
  raw_ptr<RenderWidgetHostViewAndroid> rwhva_;
  JavaObjectWeakGlobalRef java_ime_adapter_;
  base::WeakPtrFactory<ImeAdapterAndroid> weak_factory_{this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_ANDROID_IME_ADAPTER_ANDROID_H_