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.app.AlertDialog; | 8 import android.app.AlertDialog; |
9 import android.content.DialogInterface; | 9 import android.content.DialogInterface; |
10 import android.content.Intent; | 10 import android.content.Intent; |
11 import android.content.pm.ApplicationInfo; | 11 import android.content.pm.ApplicationInfo; |
12 import android.content.pm.PackageManager; | 12 import android.content.pm.PackageManager; |
13 import android.content.pm.PackageManager.NameNotFoundException; | 13 import android.content.pm.PackageManager.NameNotFoundException; |
14 import android.graphics.Rect; | |
14 import android.os.Build; | 15 import android.os.Build; |
15 import android.os.Bundle; | 16 import android.os.Bundle; |
16 import android.support.v7.app.AppCompatActivity; | 17 import android.support.v7.app.AppCompatActivity; |
17 import android.support.v7.widget.Toolbar; | 18 import android.support.v7.widget.Toolbar; |
18 import android.view.KeyCharacterMap; | 19 import android.view.KeyCharacterMap; |
19 import android.view.KeyEvent; | 20 import android.view.KeyEvent; |
20 import android.view.Menu; | 21 import android.view.Menu; |
21 import android.view.MenuItem; | 22 import android.view.MenuItem; |
22 import android.view.View; | 23 import android.view.View; |
24 import android.view.View.OnLayoutChangeListener; | |
23 import android.view.inputmethod.InputMethodManager; | 25 import android.view.inputmethod.InputMethodManager; |
24 | 26 |
25 import org.chromium.chromoting.cardboard.DesktopActivity; | 27 import org.chromium.chromoting.cardboard.DesktopActivity; |
26 import org.chromium.chromoting.jni.JniInterface; | 28 import org.chromium.chromoting.jni.JniInterface; |
27 | 29 |
28 import java.util.Set; | 30 import java.util.Set; |
29 import java.util.TreeSet; | 31 import java.util.TreeSet; |
30 | 32 |
31 /** | 33 /** |
32 * A simple screen that does nothing except display a DesktopView and notify it of rotations. | 34 * A simple screen that does nothing except display a DesktopView and notify it of rotations. |
33 */ | 35 */ |
34 public class Desktop extends AppCompatActivity implements View.OnSystemUiVisibil ityChangeListener { | 36 public class Desktop extends AppCompatActivity implements View.OnSystemUiVisibil ityChangeListener { |
35 /** Web page to be displayed in the Help screen when launched from this acti vity. */ | 37 /** Web page to be displayed in the Help screen when launched from this acti vity. */ |
36 private static final String HELP_URL = | 38 private static final String HELP_URL = |
37 "https://support.google.com/chrome/?p=mobile_crd_connecthost"; | 39 "https://support.google.com/chrome/?p=mobile_crd_connecthost"; |
38 | 40 |
39 /** | 41 /** |
40 * Preference used for displaying an interestitial dialog only when the user first accesses the | 42 * Preference used for displaying an interestitial dialog only when the user first accesses the |
41 * Cardboard function. | 43 * Cardboard function. |
42 */ | 44 */ |
43 private static final String PREFERENCE_CARDBOARD_DIALOG_SEEN = | 45 private static final String PREFERENCE_CARDBOARD_DIALOG_SEEN = "cardboard_di alog_seen"; |
44 "cardboard_dialog_seen"; | 46 |
47 /** The amount of time to wait to hide the Actionbar after user input is see n. */ | |
48 private static final int ACTIONBAR_AUTO_HIDE_DELAY_MS = 3000; | |
45 | 49 |
46 /** The surface that displays the remote host's desktop feed. */ | 50 /** The surface that displays the remote host's desktop feed. */ |
47 private DesktopView mRemoteHostDesktop; | 51 private DesktopView mRemoteHostDesktop; |
48 | 52 |
49 /** Set of pressed keys for which we've sent TextEvent. */ | 53 /** Set of pressed keys for which we've sent TextEvent. */ |
50 private Set<Integer> mPressedTextKeys = new TreeSet<Integer>(); | 54 private Set<Integer> mPressedTextKeys = new TreeSet<Integer>(); |
51 | 55 |
52 private ActivityLifecycleListener mActivityLifecycleListener; | 56 private ActivityLifecycleListener mActivityLifecycleListener; |
53 | 57 |
54 // Flag to indicate whether the current activity is going to switch to Cardb oard | 58 /** Flag to indicate whether the current activity is switching to Cardboard desktop activity. */ |
55 // desktop activity. | |
56 private boolean mSwitchToCardboardDesktopActivity; | 59 private boolean mSwitchToCardboardDesktopActivity; |
57 | 60 |
61 /** Indicates whether a Soft Input UI (such as a keyboard) is visible. */ | |
62 private boolean mSoftInputVisible = false; | |
63 | |
64 /** Holds the scheduled task object which will be called to hide the ActionB ar. */ | |
65 private Runnable mActionBarAutoHideTask; | |
66 | |
58 /** Called when the activity is first created. */ | 67 /** Called when the activity is first created. */ |
59 @Override | 68 @Override |
60 public void onCreate(Bundle savedInstanceState) { | 69 public void onCreate(Bundle savedInstanceState) { |
61 super.onCreate(savedInstanceState); | 70 super.onCreate(savedInstanceState); |
62 setContentView(R.layout.desktop); | 71 setContentView(R.layout.desktop); |
63 | 72 |
64 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); | 73 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); |
65 setSupportActionBar(toolbar); | 74 setSupportActionBar(toolbar); |
66 | 75 |
67 mRemoteHostDesktop = (DesktopView) findViewById(R.id.desktop_view); | 76 mRemoteHostDesktop = (DesktopView) findViewById(R.id.desktop_view); |
68 mRemoteHostDesktop.setDesktop(this); | 77 mRemoteHostDesktop.setDesktop(this); |
69 mSwitchToCardboardDesktopActivity = false; | 78 mSwitchToCardboardDesktopActivity = false; |
70 | 79 |
71 getSupportActionBar().setDisplayShowTitleEnabled(false); | 80 getSupportActionBar().setDisplayShowTitleEnabled(false); |
72 getSupportActionBar().setDisplayHomeAsUpEnabled(true); | 81 getSupportActionBar().setDisplayHomeAsUpEnabled(true); |
73 | 82 |
74 // For this Activity, the home button in the action bar acts as a Discon nect button, so | 83 // For this Activity, the home button in the action bar acts as a Discon nect button, so |
75 // set the description for accessibility/screen readers. | 84 // set the description for accessibility/screen readers. |
76 getSupportActionBar().setHomeActionContentDescription(R.string.disconnec t_myself_button); | 85 getSupportActionBar().setHomeActionContentDescription(R.string.disconnec t_myself_button); |
77 | 86 |
87 // The action bar is already shown when the activity is started however calling the | |
88 // function below will set our preferred system UI flags which will adju st the layout | |
89 // size of the canvas and we can avoid an initial resize event. | |
90 showActionBar(); | |
91 | |
78 View decorView = getWindow().getDecorView(); | 92 View decorView = getWindow().getDecorView(); |
79 decorView.setOnSystemUiVisibilityChangeListener(this); | 93 decorView.setOnSystemUiVisibilityChangeListener(this); |
80 | 94 |
81 mActivityLifecycleListener = CapabilityManager.getInstance() | 95 mActivityLifecycleListener = CapabilityManager.getInstance() |
82 .onActivityAcceptingListener(this, Capabilities.CAST_CAPABILITY); | 96 .onActivityAcceptingListener(this, Capabilities.CAST_CAPABILITY) ; |
83 mActivityLifecycleListener.onActivityCreated(this, savedInstanceState); | 97 mActivityLifecycleListener.onActivityCreated(this, savedInstanceState); |
98 | |
99 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
100 attachKeyboardVisibilityListener(); | |
101 | |
102 // Only create an Autohide task if the system supports immersive ful lscreen mode. Older | |
103 // versions of the OS benefit less from this functionality and we do n't want to change | |
104 // the experience for them. | |
105 mActionBarAutoHideTask = new Runnable() { | |
106 public void run() { | |
107 hideActionBar(); | |
108 } | |
109 }; | |
110 } else { | |
111 mRemoteHostDesktop.setFitsSystemWindows(true); | |
112 } | |
84 } | 113 } |
85 | 114 |
86 @Override | 115 @Override |
87 protected void onStart() { | 116 protected void onStart() { |
88 super.onStart(); | 117 super.onStart(); |
89 mActivityLifecycleListener.onActivityStarted(this); | 118 mActivityLifecycleListener.onActivityStarted(this); |
90 JniInterface.enableVideoChannel(true); | 119 JniInterface.enableVideoChannel(true); |
91 mRemoteHostDesktop.attachRedrawCallback(); | 120 mRemoteHostDesktop.attachRedrawCallback(); |
92 } | 121 } |
93 | 122 |
94 @Override | 123 @Override |
95 protected void onPause() { | 124 protected void onPause() { |
96 if (isFinishing()) mActivityLifecycleListener.onActivityPaused(this); | 125 if (isFinishing()) mActivityLifecycleListener.onActivityPaused(this); |
97 super.onPause(); | 126 super.onPause(); |
98 if (!mSwitchToCardboardDesktopActivity) { | 127 if (!mSwitchToCardboardDesktopActivity) { |
99 JniInterface.enableVideoChannel(false); | 128 JniInterface.enableVideoChannel(false); |
100 } | 129 } |
130 stopActionBarAutoHideTimer(); | |
101 } | 131 } |
102 | 132 |
103 @Override | 133 @Override |
104 public void onResume() { | 134 public void onResume() { |
105 super.onResume(); | 135 super.onResume(); |
106 mActivityLifecycleListener.onActivityResumed(this); | 136 mActivityLifecycleListener.onActivityResumed(this); |
107 JniInterface.enableVideoChannel(true); | 137 JniInterface.enableVideoChannel(true); |
138 startActionBarAutoHideTimer(); | |
108 } | 139 } |
109 | 140 |
110 @Override | 141 @Override |
111 protected void onStop() { | 142 protected void onStop() { |
112 mActivityLifecycleListener.onActivityStopped(this); | 143 mActivityLifecycleListener.onActivityStopped(this); |
113 super.onStop(); | 144 super.onStop(); |
114 if (mSwitchToCardboardDesktopActivity) { | 145 if (mSwitchToCardboardDesktopActivity) { |
115 mSwitchToCardboardDesktopActivity = false; | 146 mSwitchToCardboardDesktopActivity = false; |
116 } else { | 147 } else { |
117 JniInterface.enableVideoChannel(false); | 148 JniInterface.enableVideoChannel(false); |
(...skipping 13 matching lines...) Expand all Loading... | |
131 .getApplicationInfo(getPackageName(), PackageManager.GET_MET A_DATA); | 162 .getApplicationInfo(getPackageName(), PackageManager.GET_MET A_DATA); |
132 Bundle bundle = ai.metaData; | 163 Bundle bundle = ai.metaData; |
133 enableCardboard = bundle.getInt("enable_cardboard") == 1; | 164 enableCardboard = bundle.getInt("enable_cardboard") == 1; |
134 } catch (NameNotFoundException e) { | 165 } catch (NameNotFoundException e) { |
135 // Does nothing since by default Cardboard activity is turned off. | 166 // Does nothing since by default Cardboard activity is turned off. |
136 } | 167 } |
137 | 168 |
138 MenuItem item = menu.findItem(R.id.actionbar_cardboard); | 169 MenuItem item = menu.findItem(R.id.actionbar_cardboard); |
139 item.setVisible(enableCardboard); | 170 item.setVisible(enableCardboard); |
140 | 171 |
172 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
173 // We don't need to show a hide ActionBar button if immersive fullsc reen is supported. | |
174 menu.findItem(R.id.actionbar_hide).setVisible(false); | |
175 } | |
176 | |
141 ChromotingUtil.tintMenuIcons(this, menu); | 177 ChromotingUtil.tintMenuIcons(this, menu); |
142 | 178 |
143 return super.onCreateOptionsMenu(menu); | 179 return super.onCreateOptionsMenu(menu); |
144 } | 180 } |
145 | 181 |
182 // Posts a deplayed task to hide the ActionBar. If an existing task has alr eady been scheduled, | |
183 // then the previous task is removed and the new one scheduled, effectively resetting the timer. | |
184 private void startActionBarAutoHideTimer() { | |
185 if (mActionBarAutoHideTask == null) { | |
186 return; | |
187 } | |
188 | |
189 stopActionBarAutoHideTimer(); | |
190 | |
191 View decorView = getWindow().getDecorView(); | |
192 decorView.postDelayed(mActionBarAutoHideTask, ACTIONBAR_AUTO_HIDE_DELAY_ MS); | |
193 } | |
194 | |
195 // Clear all existing delayed tasks to prevent the ActionBar from being hidd en. | |
196 private void stopActionBarAutoHideTimer() { | |
197 if (mActionBarAutoHideTask == null) { | |
198 return; | |
199 } | |
200 | |
201 View decorView = getWindow().getDecorView(); | |
Lambros
2015/11/02 19:48:54
optional: getWindow().getDecorView().removeCallbac
| |
202 decorView.removeCallbacks(mActionBarAutoHideTask); | |
203 } | |
204 | |
146 /** Called whenever the visibility of the system status bar or navigation ba r changes. */ | 205 /** Called whenever the visibility of the system status bar or navigation ba r changes. */ |
147 @Override | 206 @Override |
148 public void onSystemUiVisibilityChange(int visibility) { | 207 public void onSystemUiVisibilityChange(int visibility) { |
149 // Ensure the action-bar's visibility matches that of the system control s. This | 208 // Ensure the action-bar's visibility matches that of the system control s. This |
150 // minimizes the number of states the UI can be in, to keep things simpl e for the user. | 209 // minimizes the number of states the UI can be in, to keep things simpl e for the user. |
151 | 210 |
152 // Determine if the system is in fullscreen/lights-out mode. LOW_PROFILE is needed since | 211 // Determine if the system is in fullscreen/lights-out mode. LOW_PROFILE is needed since |
153 // it's the only flag supported in 4.0. But it is not sufficient in itse lf; when | 212 // it's the only flag supported in 4.0. But it is not sufficient in itse lf; when |
154 // IMMERSIVE_STICKY mode is used, the system clears this flag (leaving t he FULLSCREEN flag | 213 // IMMERSIVE_STICKY mode is used, the system clears this flag (leaving t he FULLSCREEN flag |
155 // set) when the user swipes the edge to reveal the bars temporarily. Wh en this happens, | 214 // set) when the user swipes the edge to reveal the bars temporarily. Wh en this happens, |
156 // the action-bar should remain hidden. | 215 // the action-bar should remain hidden. |
157 int fullscreenFlags = getSystemUiFlags(); | 216 int fullscreenFlags = getFullscreenFlags(); |
158 if ((visibility & fullscreenFlags) != 0) { | 217 if ((visibility & fullscreenFlags) != 0) { |
159 hideActionBarWithoutSystemUi(); | 218 hideActionBarWithoutSystemUi(); |
160 } else { | 219 } else { |
161 showActionBarWithoutSystemUi(); | 220 showActionBarWithoutSystemUi(); |
162 } | 221 } |
163 } | 222 } |
164 | 223 |
165 @SuppressLint("InlinedApi") | 224 @SuppressLint("InlinedApi") |
166 private int getSystemUiFlags() { | 225 private static int getFullscreenFlags() { |
167 int flags = View.SYSTEM_UI_FLAG_LOW_PROFILE; | 226 int flags = View.SYSTEM_UI_FLAG_LOW_PROFILE; |
168 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { | 227 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { |
169 flags |= View.SYSTEM_UI_FLAG_FULLSCREEN; | 228 flags |= View.SYSTEM_UI_FLAG_FULLSCREEN; |
170 } | 229 } |
171 return flags; | 230 return flags; |
172 } | 231 } |
173 | 232 |
233 @SuppressLint("InlinedApi") | |
234 private static int getImmersiveLayoutFlags() { | |
235 int flags = 0; | |
236 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
237 flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; | |
238 flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; | |
239 flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE; | |
240 } | |
241 return flags; | |
242 } | |
243 | |
174 public void showActionBar() { | 244 public void showActionBar() { |
175 // Request exit from any fullscreen mode. The action-bar controls will b e shown in response | 245 // Request exit from any fullscreen mode. The action-bar controls will b e shown in response |
176 // to the SystemUiVisibility notification. The visibility of the action- bar should be tied | 246 // to the SystemUiVisibility notification. The visibility of the action- bar should be tied |
177 // to the fullscreen state of the system, so there's no need to explicit ly show it here. | 247 // to the fullscreen state of the system, so there's no need to explicit ly show it here. |
178 View decorView = getWindow().getDecorView(); | 248 View decorView = getWindow().getDecorView(); |
179 decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); | 249 int flags = View.SYSTEM_UI_FLAG_VISIBLE; |
250 flags |= getImmersiveLayoutFlags(); | |
Lambros
2015/11/02 19:48:54
optional:
int flags = getImmersiveLayoutFlags() |
| |
251 decorView.setSystemUiVisibility(flags); | |
Lambros
2015/11/02 19:48:54
optional: remove |decorView| temporary.
| |
252 | |
253 // The OS will not call onSystemUiVisibilityChange() if the keyboard is visible which means | |
254 // our ActionBar will not be visible until then. This check allows us t o work around this | |
255 // issue and still allow the system to show the ActionBar normally with the soft keyboard. | |
256 if (mSoftInputVisible) { | |
257 showActionBarWithoutSystemUi(); | |
258 } | |
180 } | 259 } |
181 | 260 |
182 /** Shows the action bar without changing SystemUiVisibility. */ | 261 /** Shows the action bar without changing SystemUiVisibility. */ |
183 private void showActionBarWithoutSystemUi() { | 262 private void showActionBarWithoutSystemUi() { |
184 getSupportActionBar().show(); | 263 getSupportActionBar().show(); |
264 startActionBarAutoHideTimer(); | |
185 } | 265 } |
186 | 266 |
187 @SuppressLint("InlinedApi") | 267 @SuppressLint("InlinedApi") |
188 public void hideActionBar() { | 268 public void hideActionBar() { |
189 // Request the device to enter fullscreen mode. Don't hide the controls yet, because the | 269 // Request the device to enter fullscreen mode. Don't hide the controls yet, because the |
190 // system might not honor the fullscreen request immediately (for exampl e, if the | 270 // system might not honor the fullscreen request immediately (for exampl e, if the |
191 // keyboard is visible, the system might delay fullscreen until the keyb oard is hidden). | 271 // keyboard is visible, the system might delay fullscreen until the keyb oard is hidden). |
192 // The controls will be hidden in response to the SystemUiVisibility not ification. | 272 // The controls will be hidden in response to the SystemUiVisibility not ification. |
193 // This helps ensure that the visibility of the controls is synchronized with the | 273 // This helps ensure that the visibility of the controls is synchronized with the |
194 // fullscreen state. | 274 // fullscreen state. |
195 View decorView = getWindow().getDecorView(); | 275 View decorView = getWindow().getDecorView(); |
196 | 276 |
197 // LOW_PROFILE gives the status and navigation bars a "lights-out" appea rance. | 277 // LOW_PROFILE gives the status and navigation bars a "lights-out" appea rance. |
198 // FULLSCREEN hides the status bar on supported devices (4.1 and above). | 278 // FULLSCREEN hides the status bar on supported devices (4.1 and above). |
199 int flags = getSystemUiFlags(); | 279 int flags = getFullscreenFlags(); |
200 | 280 |
201 // HIDE_NAVIGATION hides the navigation bar. However, if the user touche s the screen, the | 281 // HIDE_NAVIGATION hides the navigation bar. However, if the user touche s the screen, the |
202 // event is not seen by the application and instead the navigation bar i s re-shown. | 282 // event is not seen by the application and instead the navigation bar i s re-shown. |
203 // IMMERSIVE(_STICKY) fixes this problem and allows the user to interact with the app while | 283 // IMMERSIVE(_STICKY) fixes this problem and allows the user to interact with the app while |
204 // keeping the navigation controls hidden. This flag was introduced in 4 .4, later than | 284 // keeping the navigation controls hidden. This flag was introduced in 4 .4, later than |
205 // HIDE_NAVIGATION, and so a runtime check is needed before setting eith er of these flags. | 285 // HIDE_NAVIGATION, and so a runtime check is needed before setting eith er of these flags. |
206 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | 286 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { |
207 flags |= (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_ IMMERSIVE); | 287 flags |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; |
288 flags |= View.SYSTEM_UI_FLAG_IMMERSIVE; | |
289 flags |= getImmersiveLayoutFlags(); | |
208 } | 290 } |
209 | 291 |
210 decorView.setSystemUiVisibility(flags); | 292 decorView.setSystemUiVisibility(flags); |
293 | |
294 // The OS will not call onSystemUiVisibilityChange() until the keyboard has been dismissed | |
295 // which means our ActionBar will still be visible. This check allows u s to work around | |
296 // this issue when the keyboard is visible and the user wants additional space on the screen | |
297 // and still allow the system to hide the ActionBar normally when no key board is present. | |
298 if (mSoftInputVisible) { | |
299 hideActionBarWithoutSystemUi(); | |
300 } | |
211 } | 301 } |
212 | 302 |
213 /** Hides the action bar without changing SystemUiVisibility. */ | 303 /** Hides the action bar without changing SystemUiVisibility. */ |
214 private void hideActionBarWithoutSystemUi() { | 304 private void hideActionBarWithoutSystemUi() { |
215 getSupportActionBar().hide(); | 305 getSupportActionBar().hide(); |
306 stopActionBarAutoHideTimer(); | |
216 } | 307 } |
217 | 308 |
218 /** Called whenever an action bar button is pressed. */ | 309 /** Called whenever an action bar button is pressed. */ |
219 @Override | 310 @Override |
220 public boolean onOptionsItemSelected(MenuItem item) { | 311 public boolean onOptionsItemSelected(MenuItem item) { |
221 int id = item.getItemId(); | 312 int id = item.getItemId(); |
222 | 313 |
223 mActivityLifecycleListener.onActivityOptionsItemSelected(this, item); | 314 mActivityLifecycleListener.onActivityOptionsItemSelected(this, item); |
224 | 315 |
316 // Whenever a user selects an option from the ActionBar, reset the auto- hide timer. | |
317 startActionBarAutoHideTimer(); | |
318 | |
225 if (id == R.id.actionbar_cardboard) { | 319 if (id == R.id.actionbar_cardboard) { |
226 onCardboardItemSelected(); | 320 onCardboardItemSelected(); |
227 return true; | 321 return true; |
228 } | 322 } |
229 if (id == R.id.actionbar_keyboard) { | 323 if (id == R.id.actionbar_keyboard) { |
230 ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).toggle SoftInput(0, 0); | 324 ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).toggle SoftInput(0, 0); |
231 return true; | 325 return true; |
232 } | 326 } |
233 if (id == R.id.actionbar_hide) { | 327 if (id == R.id.actionbar_hide) { |
234 hideActionBar(); | 328 hideActionBar(); |
(...skipping 17 matching lines...) Expand all Loading... | |
252 } | 346 } |
253 return true; | 347 return true; |
254 } | 348 } |
255 if (id == R.id.actionbar_help) { | 349 if (id == R.id.actionbar_help) { |
256 HelpActivity.launch(this, HELP_URL); | 350 HelpActivity.launch(this, HELP_URL); |
257 return true; | 351 return true; |
258 } | 352 } |
259 return super.onOptionsItemSelected(item); | 353 return super.onOptionsItemSelected(item); |
260 } | 354 } |
261 | 355 |
356 private void attachKeyboardVisibilityListener() { | |
357 View keyboardVisibilityDetector = findViewById(R.id.resize_detector); | |
358 keyboardVisibilityDetector.addOnLayoutChangeListener(new OnLayoutChangeL istener() { | |
359 // Tracks the maximum 'bottom' value seen during layout changes. Th is value represents | |
360 // the top of the SystemUI displayed at the bottom of the screen. | |
361 // Note: This value is a screen coordinate so a larger value means l ower on the screen. | |
362 private int mInitialBottomValue = 0; | |
Lambros
2015/11/02 19:48:54
Maybe rename to mMaximumBottomValue ?
Lambros
2015/11/02 19:48:54
optional: remove '= 0', int members are 0 by defau
| |
363 | |
364 @Override | |
365 public void onLayoutChange(View v, int left, int top, int right, int bottom, | |
366 int oldLeft, int oldTop, int oldRight, int oldBottom) { | |
367 // As the activity is started, a number of layout changes will f low through. If | |
368 // this is a fresh start, then we will see one layout change whi ch will represent | |
369 // the steady state of the UI and will include an accurate 'bott om' value. If we | |
370 // are transitioning from another activity/orientation, then the re may be several | |
371 // layout change events as the view is updated (i.e. the OSK mig ht have been | |
372 // displayed previously but is being dismissed). Therefore we w ant to track the | |
373 // largest value we have seen and use it to determine if a new s ystem UI (such as | |
374 // the OSK) is being displayed. | |
375 if (mInitialBottomValue < bottom) { | |
376 mInitialBottomValue = bottom; | |
377 return; | |
378 } | |
379 | |
380 // If the delta between lowest bound we have seen (should be a s ystemUI such as | |
381 // the navigation bar) and the current bound does not match, the n we have a form | |
382 // of soft input displayed. Note that the size of a soft input device can change | |
383 // when the input method is changed so we want to send updates t o the image canvas | |
384 // whenever they occur. | |
385 mSoftInputVisible = (bottom < mInitialBottomValue); | |
386 mRemoteHostDesktop.onSoftInputMethodVisibilityChanged( | |
387 mSoftInputVisible, new Rect(left, top, right, bottom)); | |
388 } | |
389 }); | |
390 } | |
391 | |
262 private void onCardboardItemSelected() { | 392 private void onCardboardItemSelected() { |
263 if (getPreferences(MODE_PRIVATE).getBoolean(PREFERENCE_CARDBOARD_DIALOG_ SEEN, false)) { | 393 if (getPreferences(MODE_PRIVATE).getBoolean(PREFERENCE_CARDBOARD_DIALOG_ SEEN, false)) { |
264 switchToCardboardMode(); | 394 switchToCardboardMode(); |
265 return; | 395 return; |
266 } | 396 } |
267 | 397 |
268 new AlertDialog.Builder(this) | 398 new AlertDialog.Builder(this) |
269 .setTitle(getTitle()) | 399 .setTitle(getTitle()) |
270 .setMessage(R.string.cardboard_warning_message) | 400 .setMessage(R.string.cardboard_warning_message) |
271 .setIcon(R.drawable.ic_cardboard) | 401 .setIcon(R.drawable.ic_cardboard) |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
375 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, presse d); | 505 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, presse d); |
376 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_EQUALS, pressed); | 506 JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_EQUALS, pressed); |
377 return true; | 507 return true; |
378 | 508 |
379 default: | 509 default: |
380 // We try to send all other key codes to the host directly. | 510 // We try to send all other key codes to the host directly. |
381 return JniInterface.sendKeyEvent(0, keyCode, pressed); | 511 return JniInterface.sendKeyEvent(0, keyCode, pressed); |
382 } | 512 } |
383 } | 513 } |
384 } | 514 } |
OLD | NEW |