Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java

Issue 1278593004: Introduce ThreadedInputConnection behind a switch (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase and fix nits Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 package org.chromium.content.browser.input;
6
7 import android.os.Handler;
8 import android.os.HandlerThread;
9 import android.view.View;
10 import android.view.inputmethod.EditorInfo;
11
12 import org.chromium.base.CommandLine;
13 import org.chromium.base.Log;
14 import org.chromium.base.ThreadUtils;
15 import org.chromium.base.metrics.RecordHistogram;
16 import org.chromium.content.common.ContentSwitches;
17
18 /**
19 * A factory class for {@link ThreadedInputConnection}. The class also includes triggering
20 * mechanism (hack) to run our InputConnection on non-UI thread.
21 */
22 public class ThreadedInputConnectionFactory implements ChromiumBaseInputConnecti on.Factory {
23 private static final String TAG = "cr_Ime";
24 private static final boolean DEBUG_LOGS = true;
Ted C 2016/02/19 18:26:17 don't forget to set this to false before committin
Changwan Ryu 2016/02/22 06:28:24 Done.
25
26 private final Handler mHandler;
27 private final InputMethodManagerWrapper mInputMethodManagerWrapper;
28 private final ImeAdapter mImeAdapter;
29 private ThreadedInputConnectionProxyView mProxyView;
30 private ThreadedInputConnection mThreadedInputConnection;
31
32 ThreadedInputConnectionFactory(
33 InputMethodManagerWrapper inputMethodManagerWrapper, ImeAdapter imeA dapter) {
34 mImeAdapter = imeAdapter;
35 HandlerThread thread =
36 new HandlerThread("InputConnectionHandlerThread", HandlerThread. NORM_PRIORITY);
37 thread.start();
38 mHandler = new Handler(thread.getLooper());
39 mInputMethodManagerWrapper = inputMethodManagerWrapper;
40 }
41
42 private boolean shouldTriggerDelayedOnCreateInputConnection() {
43 for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
44 String className = ste.getClassName();
45 if (className != null
46 && (className.contains(ThreadedInputConnectionProxyView.clas s.getName())
47 || className.contains("TestInputMethodManagerWrapper"))) {
48 return false;
49 }
50 }
51 return true;
52 }
53
54 @Override
55 public ChromiumBaseInputConnection initializeAndGet(
56 View view, ImeAdapter imeAdapter, int inputType, int inputFlags, int selectionStart,
57 int selectionEnd, EditorInfo outAttrs) {
58 ImeUtils.checkOnUiThread();
59 if (shouldTriggerDelayedOnCreateInputConnection()) {
60 triggerDelayedOnCreateInputConnection(view);
61 return null;
62 }
63 if (DEBUG_LOGS) Log.w(TAG, "initializeAndGet: called from proxy view");
64 if (mThreadedInputConnection == null) {
65 if (DEBUG_LOGS) Log.w(TAG, "Creating ThreadedInputConnection...");
66 mThreadedInputConnection = new ThreadedInputConnection(imeAdapter, m Handler);
67 }
68 mThreadedInputConnection.initializeOutAttrsOnUiThread(inputType, inputFl ags,
69 selectionStart, selectionEnd, outAttrs);
70 return mThreadedInputConnection;
71 }
72
73 private void triggerDelayedOnCreateInputConnection(final View view) {
74 if (DEBUG_LOGS) Log.w(TAG, "triggerDelayedOnCreateInputConnection");
75 if (mProxyView == null) {
76 mProxyView = new ThreadedInputConnectionProxyView(view.getContext(), mHandler, view);
77 }
78 mProxyView.requestFocus();
79 view.getHandler().post(new Runnable() {
80 @Override
81 public void run() {
82 // This is a hack to make InputMethodManager believe that the pr oxy view
83 // now has a focus. As a result, InputMethodManager will think t hat mProxyView
84 // is focused, and will call getHandler() of the view when creat ing input
85 // connection.
86
87 // Step 1: Set mProxyView as InputMethodManager#mNextServedView.
88 // mProxyView.onWindowFocusChanged(true);
89
90 // Step 2: Have InputMethodManager focus in on mNextServedView.
91 // As a result, IMM will call onCreateInputConnection() on mProx yView on the same
92 // thread as mProxyView.getHandler(). It will also call subseque nt InputConnection
93 // methods on this IME thread.
94 mInputMethodManagerWrapper.isActive(view);
95
96 // Step 3: Check that the above hack worked.
97 mHandler.post(new Runnable() {
98 @Override
99 public void run() {
100 // Some other view already took focus. Container view sh ould be active
101 // otherwise regardless of whether proxy view is registe red or not.
102 if (!mInputMethodManagerWrapper.isActive(view)) return;
103
104 // Success.
105 if (mInputMethodManagerWrapper.isActive(mProxyView)) {
106 RecordHistogram.recordEnumeratedHistogram(
107 InputMethodUma.UMA_REGISTER_PROXYVIEW,
108 InputMethodUma.UMA_PROXYVIEW_SUCCESS,
109 InputMethodUma.UMA_PROXYVIEW_COUNT);
110 return;
111 }
112
113 if (mThreadedInputConnection == null) {
114 // First time and failed. It is highly likely that t his does not work
115 // systematically.
116 onProxyViewFailedToRegisterOnFirstTry(view);
117 } else {
118 // Most likely that we already lost view focus.
119 RecordHistogram.recordEnumeratedHistogram(
120 InputMethodUma.UMA_REGISTER_PROXYVIEW,
121 InputMethodUma.UMA_PROXYVIEW_DETECTION_FAILU RE,
122 InputMethodUma.UMA_PROXYVIEW_COUNT);
123 }
124 }
125 });
126 }
127 });
128 }
129
130 private void onProxyViewFailedToRegisterOnFirstTry(final View view) {
Ted C 2016/02/19 18:26:17 would it be possible add a test for this (i.e. the
Changwan Ryu 2016/02/22 06:28:24 Hmm.. We're not using real InputMethodManager in t
131 Log.w(TAG, "Failed to register proxy view. Falling back to ReplicaInputC onnection...");
132 ThreadUtils.postOnUiThread(new Runnable() {
133 @Override
134 public void run() {
135 RecordHistogram.recordEnumeratedHistogram(InputMethodUma.UMA_REG ISTER_PROXYVIEW,
136 InputMethodUma.UMA_PROXYVIEW_FAILURE, InputMethodUma.UMA _PROXYVIEW_COUNT);
137 // Disable IME thread until Chrome gets closed. Note that this i s not a permanent
138 // change.
Ted C 2016/02/19 18:26:18 what about it isn't permanent? are you clearing t
Changwan Ryu 2016/02/19 22:17:11 I just wanted to comment that switch enabled by ap
139 CommandLine.getInstance().appendSwitch(ContentSwitches.DISABLE_I ME_THREAD);
140 mImeAdapter.resetInputConnectionFactory();
141 mInputMethodManagerWrapper.restartInput(view);
142 }
143
144 });
145 }
146
147 @Override
148 public Handler getHandler() {
149 return mHandler;
150 }
151 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698