OLD | NEW |
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.content.DialogInterface; | 8 import android.content.DialogInterface; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.content.pm.ApplicationInfo; | 10 import android.content.pm.ApplicationInfo; |
11 import android.content.pm.PackageManager; | 11 import android.content.pm.PackageManager; |
12 import android.content.pm.PackageManager.NameNotFoundException; | 12 import android.content.pm.PackageManager.NameNotFoundException; |
13 import android.graphics.Rect; | |
14 import android.os.Build; | 13 import android.os.Build; |
15 import android.os.Bundle; | 14 import android.os.Bundle; |
16 import android.os.Handler; | 15 import android.os.Handler; |
17 import android.support.v7.app.ActionBar.OnMenuVisibilityListener; | 16 import android.support.v7.app.ActionBar.OnMenuVisibilityListener; |
18 import android.support.v7.app.AlertDialog; | 17 import android.support.v7.app.AlertDialog; |
19 import android.support.v7.app.AppCompatActivity; | 18 import android.support.v7.app.AppCompatActivity; |
20 import android.support.v7.widget.Toolbar; | 19 import android.support.v7.widget.Toolbar; |
21 import android.view.KeyCharacterMap; | 20 import android.view.KeyCharacterMap; |
22 import android.view.KeyEvent; | 21 import android.view.KeyEvent; |
23 import android.view.Menu; | 22 import android.view.Menu; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 * Cardboard function. | 58 * Cardboard function. |
60 */ | 59 */ |
61 private static final String PREFERENCE_CARDBOARD_DIALOG_SEEN = "cardboard_di
alog_seen"; | 60 private static final String PREFERENCE_CARDBOARD_DIALOG_SEEN = "cardboard_di
alog_seen"; |
62 | 61 |
63 /** Preference used to track the last input mode selected by the user. */ | 62 /** Preference used to track the last input mode selected by the user. */ |
64 private static final String PREFERENCE_INPUT_MODE = "input_mode"; | 63 private static final String PREFERENCE_INPUT_MODE = "input_mode"; |
65 | 64 |
66 /** The amount of time to wait to hide the Actionbar after user input is see
n. */ | 65 /** The amount of time to wait to hide the Actionbar after user input is see
n. */ |
67 private static final int ACTIONBAR_AUTO_HIDE_DELAY_MS = 3000; | 66 private static final int ACTIONBAR_AUTO_HIDE_DELAY_MS = 3000; |
68 | 67 |
69 /** The surface that displays the remote host's desktop feed. */ | 68 private final Event.Raisable<SoftInputMethodVisibilityChangedEventParameter> |
70 private DesktopView mRemoteHostDesktop; | 69 mOnSoftInputMethodVisibilityChanged = new Event.Raisable<>(); |
| 70 |
| 71 private final Event.Raisable<InputModeChangedEventParameter> mOnInputModeCha
nged = |
| 72 new Event.Raisable<>(); |
71 | 73 |
72 private Client mClient; | 74 private Client mClient; |
73 | 75 |
74 /** Set of pressed keys for which we've sent TextEvent. */ | 76 /** Set of pressed keys for which we've sent TextEvent. */ |
75 private Set<Integer> mPressedTextKeys = new TreeSet<Integer>(); | 77 private Set<Integer> mPressedTextKeys = new TreeSet<Integer>(); |
76 | 78 |
77 private ActivityLifecycleListener mActivityLifecycleListener; | 79 private ActivityLifecycleListener mActivityLifecycleListener; |
78 | 80 |
79 /** Flag to indicate whether the current activity is switching to Cardboard
desktop activity. */ | 81 /** Flag to indicate whether the current activity is switching to Cardboard
desktop activity. */ |
80 private boolean mSwitchToCardboardDesktopActivity; | 82 private boolean mSwitchToCardboardDesktopActivity; |
(...skipping 21 matching lines...) Expand all Loading... |
102 @Override | 104 @Override |
103 public void onCreate(Bundle savedInstanceState) { | 105 public void onCreate(Bundle savedInstanceState) { |
104 super.onCreate(savedInstanceState); | 106 super.onCreate(savedInstanceState); |
105 setContentView(R.layout.desktop); | 107 setContentView(R.layout.desktop); |
106 | 108 |
107 mClient = Client.getInstance(); | 109 mClient = Client.getInstance(); |
108 | 110 |
109 mToolbar = (Toolbar) findViewById(R.id.toolbar); | 111 mToolbar = (Toolbar) findViewById(R.id.toolbar); |
110 setSupportActionBar(mToolbar); | 112 setSupportActionBar(mToolbar); |
111 | 113 |
112 mRemoteHostDesktop = (DesktopView) findViewById(R.id.desktop_view); | 114 DesktopView remoteHostDesktop = (DesktopView) findViewById(R.id.desktop_
view); |
113 mRemoteHostDesktop.setDesktop(this); | 115 remoteHostDesktop.init(this, mClient); |
114 mRemoteHostDesktop.setClient(mClient); | |
115 mSwitchToCardboardDesktopActivity = false; | 116 mSwitchToCardboardDesktopActivity = false; |
116 | 117 |
117 getSupportActionBar().setDisplayShowTitleEnabled(false); | 118 getSupportActionBar().setDisplayShowTitleEnabled(false); |
118 getSupportActionBar().setDisplayHomeAsUpEnabled(true); | 119 getSupportActionBar().setDisplayHomeAsUpEnabled(true); |
119 | 120 |
120 // For this Activity, the home button in the action bar acts as a Discon
nect button, so | 121 // For this Activity, the home button in the action bar acts as a Discon
nect button, so |
121 // set the description for accessibility/screen readers. | 122 // set the description for accessibility/screen readers. |
122 getSupportActionBar().setHomeActionContentDescription(R.string.disconnec
t_myself_button); | 123 getSupportActionBar().setHomeActionContentDescription(R.string.disconnec
t_myself_button); |
123 | 124 |
124 // The action bar is already shown when the activity is started however
calling the | 125 // The action bar is already shown when the activity is started however
calling the |
(...skipping 28 matching lines...) Expand all Loading... |
153 getSupportActionBar().addOnMenuVisibilityListener(new OnMenuVisibili
tyListener() { | 154 getSupportActionBar().addOnMenuVisibilityListener(new OnMenuVisibili
tyListener() { |
154 public void onMenuVisibilityChanged(boolean isVisible) { | 155 public void onMenuVisibilityChanged(boolean isVisible) { |
155 if (isVisible) { | 156 if (isVisible) { |
156 stopActionBarAutoHideTimer(); | 157 stopActionBarAutoHideTimer(); |
157 } else { | 158 } else { |
158 startActionBarAutoHideTimer(); | 159 startActionBarAutoHideTimer(); |
159 } | 160 } |
160 } | 161 } |
161 }); | 162 }); |
162 } else { | 163 } else { |
163 mRemoteHostDesktop.setFitsSystemWindows(true); | 164 remoteHostDesktop.setFitsSystemWindows(true); |
164 } | 165 } |
165 } | 166 } |
166 | 167 |
167 @Override | 168 @Override |
168 protected void onStart() { | 169 protected void onStart() { |
169 super.onStart(); | 170 super.onStart(); |
170 mActivityLifecycleListener.onActivityStarted(this); | 171 mActivityLifecycleListener.onActivityStarted(this); |
171 mClient.enableVideoChannel(true); | 172 mClient.enableVideoChannel(true); |
172 mRemoteHostDesktop.attachRedrawCallback(); | 173 DesktopView desktopView = (DesktopView) findViewById(R.id.desktop_view); |
| 174 desktopView.attachRedrawCallback(); |
173 mClient.getCapabilityManager().addListener(this); | 175 mClient.getCapabilityManager().addListener(this); |
174 } | 176 } |
175 | 177 |
176 @Override | 178 @Override |
177 protected void onPause() { | 179 protected void onPause() { |
178 if (isFinishing()) mActivityLifecycleListener.onActivityPaused(this); | 180 if (isFinishing()) mActivityLifecycleListener.onActivityPaused(this); |
179 super.onPause(); | 181 super.onPause(); |
180 if (!mSwitchToCardboardDesktopActivity) { | 182 if (!mSwitchToCardboardDesktopActivity) { |
181 mClient.enableVideoChannel(false); | 183 mClient.enableVideoChannel(false); |
182 } | 184 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 } | 253 } |
252 | 254 |
253 ChromotingUtil.tintMenuIcons(this, menu); | 255 ChromotingUtil.tintMenuIcons(this, menu); |
254 | 256 |
255 // Wait to set the input mode until after the default tinting has been a
pplied. | 257 // Wait to set the input mode until after the default tinting has been a
pplied. |
256 setInputMode(mInputMode); | 258 setInputMode(mInputMode); |
257 | 259 |
258 return super.onCreateOptionsMenu(menu); | 260 return super.onCreateOptionsMenu(menu); |
259 } | 261 } |
260 | 262 |
| 263 public Event<SoftInputMethodVisibilityChangedEventParameter> |
| 264 onSoftInputMethodVisibilityChanged() { |
| 265 return mOnSoftInputMethodVisibilityChanged; |
| 266 } |
| 267 |
| 268 public Event<InputModeChangedEventParameter> onInputModeChanged() { |
| 269 return mOnInputModeChanged; |
| 270 } |
| 271 |
261 private InputMode getInitialInputModeValue() { | 272 private InputMode getInitialInputModeValue() { |
262 // Load the previously-selected input mode from Preferences. | 273 // Load the previously-selected input mode from Preferences. |
263 // TODO(joedow): Evaluate and determine if we should use a different inp
ut mode based on | 274 // TODO(joedow): Evaluate and determine if we should use a different inp
ut mode based on |
264 // a device characteristic such as screen size. | 275 // a device characteristic such as screen size. |
265 InputMode inputMode = InputMode.TRACKPAD; | 276 InputMode inputMode = InputMode.TRACKPAD; |
266 String previousInputMode = | 277 String previousInputMode = |
267 getPreferences(MODE_PRIVATE) | 278 getPreferences(MODE_PRIVATE) |
268 .getString(PREFERENCE_INPUT_MODE, inputMode.name()); | 279 .getString(PREFERENCE_INPUT_MODE, inputMode.name()); |
269 | 280 |
270 try { | 281 try { |
(...skipping 19 matching lines...) Expand all Loading... |
290 assert false : "Unreached"; | 301 assert false : "Unreached"; |
291 return; | 302 return; |
292 } | 303 } |
293 | 304 |
294 mInputMode = inputMode; | 305 mInputMode = inputMode; |
295 getPreferences(MODE_PRIVATE) | 306 getPreferences(MODE_PRIVATE) |
296 .edit() | 307 .edit() |
297 .putString(PREFERENCE_INPUT_MODE, mInputMode.name()) | 308 .putString(PREFERENCE_INPUT_MODE, mInputMode.name()) |
298 .apply(); | 309 .apply(); |
299 | 310 |
300 mRemoteHostDesktop.changeInputMode(mInputMode, mHostTouchCapability); | 311 mOnInputModeChanged.raise( |
| 312 new InputModeChangedEventParameter(mInputMode, mHostTouchCapabil
ity)); |
301 } | 313 } |
302 | 314 |
303 @Override | 315 @Override |
304 public void onCapabilitiesChanged(List<String> newCapabilities) { | 316 public void onCapabilitiesChanged(List<String> newCapabilities) { |
305 if (newCapabilities.contains(Capabilities.TOUCH_CAPABILITY)) { | 317 if (newCapabilities.contains(Capabilities.TOUCH_CAPABILITY)) { |
306 mHostTouchCapability = CapabilityManager.HostCapability.SUPPORTED; | 318 mHostTouchCapability = CapabilityManager.HostCapability.SUPPORTED; |
307 } else { | 319 } else { |
308 mHostTouchCapability = CapabilityManager.HostCapability.UNSUPPORTED; | 320 mHostTouchCapability = CapabilityManager.HostCapability.UNSUPPORTED; |
309 } | 321 } |
310 | 322 |
311 mRemoteHostDesktop.changeInputMode(mInputMode, mHostTouchCapability); | 323 mOnInputModeChanged.raise( |
| 324 new InputModeChangedEventParameter(mInputMode, mHostTouchCapabil
ity)); |
312 } | 325 } |
313 | 326 |
314 // Any time an onTouchListener is attached, a lint warning about filtering t
ouch events is | 327 // Any time an onTouchListener is attached, a lint warning about filtering t
ouch events is |
315 // generated. Since the function below is only used to listen to, not inter
cept, the events, | 328 // generated. Since the function below is only used to listen to, not inter
cept, the events, |
316 // the lint warning can be safely suppressed. | 329 // the lint warning can be safely suppressed. |
317 @SuppressLint("ClickableViewAccessibility") | 330 @SuppressLint("ClickableViewAccessibility") |
318 private void attachToolbarInteractionListenerToView(View view) { | 331 private void attachToolbarInteractionListenerToView(View view) { |
319 view.setOnTouchListener(new OnTouchListener() { | 332 view.setOnTouchListener(new OnTouchListener() { |
320 @Override | 333 @Override |
321 public boolean onTouch(View view, MotionEvent event) { | 334 public boolean onTouch(View view, MotionEvent event) { |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 mMaxBottomValue = bottom; | 554 mMaxBottomValue = bottom; |
542 return; | 555 return; |
543 } | 556 } |
544 | 557 |
545 // If the delta between lowest bound we have seen (should be a s
ystemUI such as | 558 // If the delta between lowest bound we have seen (should be a s
ystemUI such as |
546 // the navigation bar) and the current bound does not match, the
n we have a form | 559 // the navigation bar) and the current bound does not match, the
n we have a form |
547 // of soft input displayed. Note that the size of a soft input
device can change | 560 // of soft input displayed. Note that the size of a soft input
device can change |
548 // when the input method is changed so we want to send updates t
o the image canvas | 561 // when the input method is changed so we want to send updates t
o the image canvas |
549 // whenever they occur. | 562 // whenever they occur. |
550 mSoftInputVisible = (bottom < mMaxBottomValue); | 563 mSoftInputVisible = (bottom < mMaxBottomValue); |
551 mRemoteHostDesktop.onSoftInputMethodVisibilityChanged( | 564 mOnSoftInputMethodVisibilityChanged.raise( |
552 mSoftInputVisible, new Rect(left, top, right, bottom)); | 565 new SoftInputMethodVisibilityChangedEventParameter( |
| 566 mSoftInputVisible, left, top, right, bottom)); |
553 | 567 |
554 if (!mSoftInputVisible && mHideSystemUIOnSoftKeyboardDismiss) { | 568 if (!mSoftInputVisible && mHideSystemUIOnSoftKeyboardDismiss) { |
555 // Queue a task which will run after the current action (OSK
dismiss) has | 569 // Queue a task which will run after the current action (OSK
dismiss) has |
556 // completed, otherwise the hide request will not take effec
t. | 570 // completed, otherwise the hide request will not take effec
t. |
557 new Handler().post(new Runnable() { | 571 new Handler().post(new Runnable() { |
558 @Override | 572 @Override |
559 public void run() { | 573 public void run() { |
560 if (mHideSystemUIOnSoftKeyboardDismiss) { | 574 if (mHideSystemUIOnSoftKeyboardDismiss) { |
561 mHideSystemUIOnSoftKeyboardDismiss = false; | 575 mHideSystemUIOnSoftKeyboardDismiss = false; |
562 hideActionBar(); | 576 hideActionBar(); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 mClient.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed); | 698 mClient.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed); |
685 mClient.sendKeyEvent(0, KeyEvent.KEYCODE_EQUALS, pressed); | 699 mClient.sendKeyEvent(0, KeyEvent.KEYCODE_EQUALS, pressed); |
686 return true; | 700 return true; |
687 | 701 |
688 default: | 702 default: |
689 // We try to send all other key codes to the host directly. | 703 // We try to send all other key codes to the host directly. |
690 return mClient.sendKeyEvent(0, keyCode, pressed); | 704 return mClient.sendKeyEvent(0, keyCode, pressed); |
691 } | 705 } |
692 } | 706 } |
693 } | 707 } |
OLD | NEW |