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

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/Desktop.java

Issue 303443004: Send TextEvent for keyboard event generated by software keyboard. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chromoting; 5 package org.chromium.chromoting;
6 6
7 import android.annotation.SuppressLint; 7 import android.annotation.SuppressLint;
8 import android.app.Activity; 8 import android.app.Activity;
9 import android.content.res.Configuration; 9 import android.content.res.Configuration;
10 import android.os.Build; 10 import android.os.Build;
11 import android.os.Bundle; 11 import android.os.Bundle;
12 import android.view.KeyCharacterMap;
12 import android.view.KeyEvent; 13 import android.view.KeyEvent;
13 import android.view.Menu; 14 import android.view.Menu;
14 import android.view.MenuItem; 15 import android.view.MenuItem;
15 import android.view.View; 16 import android.view.View;
16 import android.view.inputmethod.InputMethodManager; 17 import android.view.inputmethod.InputMethodManager;
17 import android.widget.ImageButton; 18 import android.widget.ImageButton;
18 19
19 import org.chromium.chromoting.jni.JniInterface; 20 import org.chromium.chromoting.jni.JniInterface;
20 21
22 import java.util.Set;
23 import java.util.TreeSet;
24
21 /** 25 /**
22 * A simple screen that does nothing except display a DesktopView and notify it of rotations. 26 * A simple screen that does nothing except display a DesktopView and notify it of rotations.
23 */ 27 */
24 public class Desktop extends Activity implements View.OnSystemUiVisibilityChange Listener { 28 public class Desktop extends Activity implements View.OnSystemUiVisibilityChange Listener {
25 /** Web page to be displayed in the Help screen when launched from this acti vity. */ 29 /** Web page to be displayed in the Help screen when launched from this acti vity. */
26 private static final String HELP_URL = 30 private static final String HELP_URL =
27 "http://support.google.com/chrome/?p=mobile_crd_connecthost"; 31 "http://support.google.com/chrome/?p=mobile_crd_connecthost";
28 32
29 /** The surface that displays the remote host's desktop feed. */ 33 /** The surface that displays the remote host's desktop feed. */
30 private DesktopView mRemoteHostDesktop; 34 private DesktopView mRemoteHostDesktop;
31 35
32 /** The button used to show the action bar. */ 36 /** The button used to show the action bar. */
33 private ImageButton mOverlayButton; 37 private ImageButton mOverlayButton;
34 38
39 /** Set of pressed keys for which we've sent TextEvent. */
40 private Set<Integer> mPressedTextKeys = new TreeSet<Integer>();
41
35 /** Called when the activity is first created. */ 42 /** Called when the activity is first created. */
36 @Override 43 @Override
37 public void onCreate(Bundle savedInstanceState) { 44 public void onCreate(Bundle savedInstanceState) {
38 super.onCreate(savedInstanceState); 45 super.onCreate(savedInstanceState);
39 setContentView(R.layout.desktop); 46 setContentView(R.layout.desktop);
40 mRemoteHostDesktop = (DesktopView)findViewById(R.id.desktop_view); 47 mRemoteHostDesktop = (DesktopView)findViewById(R.id.desktop_view);
41 mOverlayButton = (ImageButton)findViewById(R.id.desktop_overlay_button); 48 mOverlayButton = (ImageButton)findViewById(R.id.desktop_overlay_button);
42 mRemoteHostDesktop.setDesktop(this); 49 mRemoteHostDesktop.setDesktop(this);
43 50
44 // Ensure the button is initially hidden. 51 // Ensure the button is initially hidden.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 return super.onOptionsItemSelected(item); 176 return super.onOptionsItemSelected(item);
170 } 177 }
171 178
172 /** 179 /**
173 * Called once when a keyboard key is pressed, then again when that same key is released. This 180 * Called once when a keyboard key is pressed, then again when that same key is released. This
174 * is not guaranteed to be notified of all soft keyboard events: certian key boards might not 181 * is not guaranteed to be notified of all soft keyboard events: certian key boards might not
175 * call it at all, while others might skip it in certain situations (e.g. sw ipe input). 182 * call it at all, while others might skip it in certain situations (e.g. sw ipe input).
176 */ 183 */
177 @Override 184 @Override
178 public boolean dispatchKeyEvent(KeyEvent event) { 185 public boolean dispatchKeyEvent(KeyEvent event) {
179 // Send ACTION_MULTIPLE event as TextEvent. 186 // Send TextEvent in two cases:
180 // 187 // 1. This is an ACTION_MULTIPLE event.
181 // TODO(sergeyu): For all keys on English keyboard Android generates 188 // 2. The event was generated by on-screen keyboard and Ctrl, Alt and
182 // ACTION_DOWN/ACTION_UP events, so they are sent as KeyEvent instead of 189 // Meta are not pressed.
183 // TextEvent. As result the host may handle them as non-English chars 190 // This ensures that on-screen keyboard always inject input that
Lambros 2014/05/28 22:32:28 s/inject/injects
Sergey Ulanov 2014/06/06 18:43:45 Done.
184 // when it has non-English layout selected, which might be confusing for 191 // correspond to what user sees on the screen, while physical keyboard
185 // the user. This code should be fixed to send all text input events as 192 // acts as if it is connected to the remote host.
186 // TextEvent, but it cannot be done now because not all hosts support
187 // TextEvent. Also, to handle keyboard shortcuts properly this code will
188 // need to track the state of modifier keys (such as Ctrl or Alt) and
189 // send KeyEvents in the case any of the modifier keys are pressed.
190 if (event.getAction() == KeyEvent.ACTION_MULTIPLE) { 193 if (event.getAction() == KeyEvent.ACTION_MULTIPLE) {
191 JniInterface.sendTextEvent(event.getCharacters()); 194 JniInterface.sendTextEvent(event.getCharacters());
192 return super.dispatchKeyEvent(event); 195 return super.dispatchKeyEvent(event);
193 } 196 }
194 197
195 boolean depressed = event.getAction() == KeyEvent.ACTION_DOWN; 198 int keyCode = event.getKeyCode();
199 boolean pressed = event.getAction() == KeyEvent.ACTION_DOWN;
196 200
197 switch (event.getKeyCode()) { 201 // For Enter getUnicodeChar() returns 10 (line feed), but we still
202 // want to send it as KeyEvent.
Lambros 2014/05/28 22:32:28 What about Backspace - will that work as expected?
Sergey Ulanov 2014/06/06 18:43:45 Yes. getCharacter() is not set for Backspace.
203 int unicode = keyCode != KeyEvent.KEYCODE_ENTER ? event.getUnicodeChar() : 0;
204
205 boolean no_modifiers = !event.isAltPressed() &&
206 !event.isCtrlPressed() && !event.isMetaPressed();
207
208 if (event.getDeviceId() == KeyCharacterMap.VIRTUAL_KEYBOARD &&
209 pressed && unicode != 0 && no_modifiers) {
210 mPressedTextKeys.add(keyCode);
211 int[] codePoints = new int[1];
Lambros 2014/05/28 22:32:28 This could be: int[] codePoints = { unicode } but
Sergey Ulanov 2014/06/06 18:43:45 Done.
212 codePoints[0] = unicode;
213 JniInterface.sendTextEvent(new String(codePoints, 0, 1));
Lambros 2014/05/28 22:32:28 You can convert to string like this: String.valueO
Sergey Ulanov 2014/06/06 18:43:45 In Java char is 16 bits and can encode only plane
214 return super.dispatchKeyEvent(event);
215 }
216
217 if (!pressed && mPressedTextKeys.contains(keyCode)) {
218 mPressedTextKeys.remove(keyCode);
219 return super.dispatchKeyEvent(event);
220 }
221
222 switch (keyCode) {
198 case KeyEvent.KEYCODE_AT: 223 case KeyEvent.KEYCODE_AT:
199 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, depressed ); 224 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
200 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_2, depressed); 225 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_2, pressed);
201 break; 226 break;
202 227
203 case KeyEvent.KEYCODE_POUND: 228 case KeyEvent.KEYCODE_POUND:
204 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, depressed ); 229 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
205 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_3, depressed); 230 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_3, pressed);
206 break; 231 break;
207 232
208 case KeyEvent.KEYCODE_STAR: 233 case KeyEvent.KEYCODE_STAR:
209 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, depressed ); 234 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
210 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_8, depressed); 235 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_8, pressed);
211 break; 236 break;
212 237
213 case KeyEvent.KEYCODE_PLUS: 238 case KeyEvent.KEYCODE_PLUS:
214 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, depressed ); 239 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
215 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_EQUALS, depressed); 240 JniInterface.sendKeyEvent(KeyEvent.KEYCODE_EQUALS, pressed);
216 break; 241 break;
217 242
218 default: 243 default:
219 // We try to send all other key codes to the host directly. 244 // We try to send all other key codes to the host directly.
220 JniInterface.sendKeyEvent(event.getKeyCode(), depressed); 245 JniInterface.sendKeyEvent(keyCode, pressed);
221 } 246 }
222 247
223 return super.dispatchKeyEvent(event); 248 return super.dispatchKeyEvent(event);
224 } 249 }
225 } 250 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698