| 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; | |
| 9 import android.content.Intent; | |
| 10 import android.content.pm.ApplicationInfo; | |
| 11 import android.content.pm.PackageManager; | |
| 12 import android.content.pm.PackageManager.NameNotFoundException; | |
| 13 import android.os.Build; | 8 import android.os.Build; |
| 14 import android.os.Bundle; | 9 import android.os.Bundle; |
| 15 import android.os.Handler; | 10 import android.os.Handler; |
| 16 import android.support.v7.app.ActionBar.OnMenuVisibilityListener; | 11 import android.support.v7.app.ActionBar.OnMenuVisibilityListener; |
| 17 import android.support.v7.app.AlertDialog; | |
| 18 import android.support.v7.app.AppCompatActivity; | 12 import android.support.v7.app.AppCompatActivity; |
| 19 import android.support.v7.widget.Toolbar; | 13 import android.support.v7.widget.Toolbar; |
| 20 import android.view.KeyEvent; | 14 import android.view.KeyEvent; |
| 21 import android.view.Menu; | 15 import android.view.Menu; |
| 22 import android.view.MenuItem; | 16 import android.view.MenuItem; |
| 23 import android.view.MotionEvent; | 17 import android.view.MotionEvent; |
| 24 import android.view.View; | 18 import android.view.View; |
| 25 import android.view.View.OnLayoutChangeListener; | 19 import android.view.View.OnLayoutChangeListener; |
| 26 import android.view.View.OnTouchListener; | 20 import android.view.View.OnTouchListener; |
| 27 import android.view.ViewGroup; | 21 import android.view.ViewGroup; |
| 28 import android.view.inputmethod.InputMethodManager; | 22 import android.view.inputmethod.InputMethodManager; |
| 29 | 23 |
| 30 import org.chromium.chromoting.cardboard.DesktopActivity; | |
| 31 import org.chromium.chromoting.help.HelpContext; | 24 import org.chromium.chromoting.help.HelpContext; |
| 32 import org.chromium.chromoting.help.HelpSingleton; | 25 import org.chromium.chromoting.help.HelpSingleton; |
| 33 import org.chromium.chromoting.jni.Client; | 26 import org.chromium.chromoting.jni.Client; |
| 34 | 27 |
| 35 import java.util.List; | 28 import java.util.List; |
| 36 | 29 |
| 37 /** | 30 /** |
| 38 * A simple screen that does nothing except display a DesktopView and notify it
of rotations. | 31 * A simple screen that does nothing except display a DesktopView and notify it
of rotations. |
| 39 */ | 32 */ |
| 40 public class Desktop | 33 public class Desktop |
| 41 extends AppCompatActivity implements View.OnSystemUiVisibilityChangeList
ener, | 34 extends AppCompatActivity implements View.OnSystemUiVisibilityChangeList
ener, |
| 42 CapabilityManager.CapabilitiesChang
edListener { | 35 CapabilityManager.CapabilitiesChang
edListener { |
| 43 /** Used to set/store the selected input mode. */ | 36 /** Used to set/store the selected input mode. */ |
| 44 public enum InputMode { | 37 public enum InputMode { |
| 45 UNKNOWN, | 38 UNKNOWN, |
| 46 TRACKPAD, | 39 TRACKPAD, |
| 47 TOUCH; | 40 TOUCH; |
| 48 | 41 |
| 49 public boolean isSet() { | 42 public boolean isSet() { |
| 50 return this != UNKNOWN; | 43 return this != UNKNOWN; |
| 51 } | 44 } |
| 52 } | 45 } |
| 53 | 46 |
| 54 /** | |
| 55 * Preference used for displaying an interestitial dialog only when the user
first accesses the | |
| 56 * Cardboard function. | |
| 57 */ | |
| 58 private static final String PREFERENCE_CARDBOARD_DIALOG_SEEN = "cardboard_di
alog_seen"; | |
| 59 | |
| 60 /** Preference used to track the last input mode selected by the user. */ | 47 /** Preference used to track the last input mode selected by the user. */ |
| 61 private static final String PREFERENCE_INPUT_MODE = "input_mode"; | 48 private static final String PREFERENCE_INPUT_MODE = "input_mode"; |
| 62 | 49 |
| 63 /** The amount of time to wait to hide the ActionBar after user input is see
n. */ | 50 /** The amount of time to wait to hide the ActionBar after user input is see
n. */ |
| 64 private static final int ACTIONBAR_AUTO_HIDE_DELAY_MS = 3000; | 51 private static final int ACTIONBAR_AUTO_HIDE_DELAY_MS = 3000; |
| 65 | 52 |
| 66 private final Event.Raisable<SystemUiVisibilityChangedEventParameter> | 53 private final Event.Raisable<SystemUiVisibilityChangedEventParameter> |
| 67 mOnSystemUiVisibilityChanged = new Event.Raisable<>(); | 54 mOnSystemUiVisibilityChanged = new Event.Raisable<>(); |
| 68 | 55 |
| 69 private final Event.Raisable<InputModeChangedEventParameter> mOnInputModeCha
nged = | 56 private final Event.Raisable<InputModeChangedEventParameter> mOnInputModeCha
nged = |
| 70 new Event.Raisable<>(); | 57 new Event.Raisable<>(); |
| 71 | 58 |
| 72 private Client mClient; | 59 private Client mClient; |
| 73 private InputEventSender mInjector; | 60 private InputEventSender mInjector; |
| 74 | 61 |
| 75 private ActivityLifecycleListener mActivityLifecycleListener; | 62 private ActivityLifecycleListener mActivityLifecycleListener; |
| 76 | 63 |
| 77 /** Flag to indicate whether the current activity is switching to Cardboard
desktop activity. */ | |
| 78 private boolean mSwitchToCardboardDesktopActivity; | |
| 79 | |
| 80 /** Indicates whether a Soft Input UI (such as a keyboard) is visible. */ | 64 /** Indicates whether a Soft Input UI (such as a keyboard) is visible. */ |
| 81 private boolean mSoftInputVisible = false; | 65 private boolean mSoftInputVisible = false; |
| 82 | 66 |
| 83 /** Holds the scheduled task object which will be called to hide the ActionB
ar. */ | 67 /** Holds the scheduled task object which will be called to hide the ActionB
ar. */ |
| 84 private Runnable mActionBarAutoHideTask; | 68 private Runnable mActionBarAutoHideTask; |
| 85 | 69 |
| 86 /** The Toolbar instance backing our SupportActionBar. */ | 70 /** The Toolbar instance backing our SupportActionBar. */ |
| 87 private Toolbar mToolbar; | 71 private Toolbar mToolbar; |
| 88 | 72 |
| 89 /** Tracks the current input mode (e.g. trackpad/touch). */ | 73 /** Tracks the current input mode (e.g. trackpad/touch). */ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 102 mClient = Client.getInstance(); | 86 mClient = Client.getInstance(); |
| 103 mInjector = new InputEventSender(mClient); | 87 mInjector = new InputEventSender(mClient); |
| 104 | 88 |
| 105 mToolbar = (Toolbar) findViewById(R.id.toolbar); | 89 mToolbar = (Toolbar) findViewById(R.id.toolbar); |
| 106 setSupportActionBar(mToolbar); | 90 setSupportActionBar(mToolbar); |
| 107 | 91 |
| 108 AbstractDesktopView remoteHostDesktop = mClient.createDesktopView(this,
mClient); | 92 AbstractDesktopView remoteHostDesktop = mClient.createDesktopView(this,
mClient); |
| 109 remoteHostDesktop.setLayoutParams(new ViewGroup.LayoutParams( | 93 remoteHostDesktop.setLayoutParams(new ViewGroup.LayoutParams( |
| 110 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATC
H_PARENT)); | 94 ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATC
H_PARENT)); |
| 111 ((ViewGroup) findViewById(R.id.desktop_view_placeholder)).addView(remote
HostDesktop); | 95 ((ViewGroup) findViewById(R.id.desktop_view_placeholder)).addView(remote
HostDesktop); |
| 112 mSwitchToCardboardDesktopActivity = false; | |
| 113 | 96 |
| 114 getSupportActionBar().setDisplayShowTitleEnabled(false); | 97 getSupportActionBar().setDisplayShowTitleEnabled(false); |
| 115 getSupportActionBar().setDisplayHomeAsUpEnabled(true); | 98 getSupportActionBar().setDisplayHomeAsUpEnabled(true); |
| 116 | 99 |
| 117 // For this Activity, the home button in the action bar acts as a Discon
nect button, so | 100 // For this Activity, the home button in the action bar acts as a Discon
nect button, so |
| 118 // set the description for accessibility/screen readers. | 101 // set the description for accessibility/screen readers. |
| 119 getSupportActionBar().setHomeActionContentDescription(R.string.disconnec
t_myself_button); | 102 getSupportActionBar().setHomeActionContentDescription(R.string.disconnec
t_myself_button); |
| 120 | 103 |
| 121 // The action bar is already shown when the activity is started however
calling the | 104 // The action bar is already shown when the activity is started however
calling the |
| 122 // function below will set our preferred system UI flags which will adju
st the layout | 105 // function below will set our preferred system UI flags which will adju
st the layout |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 super.onStart(); | 149 super.onStart(); |
| 167 mActivityLifecycleListener.onActivityStarted(this); | 150 mActivityLifecycleListener.onActivityStarted(this); |
| 168 mClient.enableVideoChannel(true); | 151 mClient.enableVideoChannel(true); |
| 169 mClient.getCapabilityManager().addListener(this); | 152 mClient.getCapabilityManager().addListener(this); |
| 170 } | 153 } |
| 171 | 154 |
| 172 @Override | 155 @Override |
| 173 protected void onPause() { | 156 protected void onPause() { |
| 174 if (isFinishing()) mActivityLifecycleListener.onActivityPaused(this); | 157 if (isFinishing()) mActivityLifecycleListener.onActivityPaused(this); |
| 175 super.onPause(); | 158 super.onPause(); |
| 176 if (!mSwitchToCardboardDesktopActivity) { | 159 mClient.enableVideoChannel(false); |
| 177 mClient.enableVideoChannel(false); | |
| 178 } | |
| 179 stopActionBarAutoHideTimer(); | 160 stopActionBarAutoHideTimer(); |
| 180 } | 161 } |
| 181 | 162 |
| 182 @Override | 163 @Override |
| 183 public void onResume() { | 164 public void onResume() { |
| 184 super.onResume(); | 165 super.onResume(); |
| 185 mActivityLifecycleListener.onActivityResumed(this); | 166 mActivityLifecycleListener.onActivityResumed(this); |
| 186 mClient.enableVideoChannel(true); | 167 mClient.enableVideoChannel(true); |
| 187 syncActionBarToSystemUiState(); | 168 syncActionBarToSystemUiState(); |
| 188 } | 169 } |
| 189 | 170 |
| 190 @Override | 171 @Override |
| 191 protected void onStop() { | 172 protected void onStop() { |
| 192 mClient.getCapabilityManager().removeListener(this); | 173 mClient.getCapabilityManager().removeListener(this); |
| 193 mActivityLifecycleListener.onActivityStopped(this); | 174 mActivityLifecycleListener.onActivityStopped(this); |
| 194 super.onStop(); | 175 super.onStop(); |
| 195 if (mSwitchToCardboardDesktopActivity) { | 176 mClient.enableVideoChannel(false); |
| 196 mSwitchToCardboardDesktopActivity = false; | |
| 197 } else { | |
| 198 mClient.enableVideoChannel(false); | |
| 199 } | |
| 200 } | 177 } |
| 201 | 178 |
| 202 /** Called to initialize the action bar. */ | 179 /** Called to initialize the action bar. */ |
| 203 @Override | 180 @Override |
| 204 public boolean onCreateOptionsMenu(Menu menu) { | 181 public boolean onCreateOptionsMenu(Menu menu) { |
| 205 getMenuInflater().inflate(R.menu.desktop_actionbar, menu); | 182 getMenuInflater().inflate(R.menu.desktop_actionbar, menu); |
| 206 | 183 |
| 207 mActivityLifecycleListener.onActivityCreatedOptionsMenu(this, menu); | 184 mActivityLifecycleListener.onActivityCreatedOptionsMenu(this, menu); |
| 208 | 185 |
| 209 boolean enableCardboard = false; | |
| 210 try { | |
| 211 ApplicationInfo ai = getPackageManager() | |
| 212 .getApplicationInfo(getPackageName(), PackageManager.GET_MET
A_DATA); | |
| 213 Bundle bundle = ai.metaData; | |
| 214 enableCardboard = bundle.getInt("enable_cardboard") == 1; | |
| 215 } catch (NameNotFoundException e) { | |
| 216 // Does nothing since by default Cardboard activity is turned off. | |
| 217 } | |
| 218 | |
| 219 MenuItem item = menu.findItem(R.id.actionbar_cardboard); | |
| 220 item.setVisible(enableCardboard); | |
| 221 | |
| 222 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | 186 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { |
| 223 // We don't need to show a hide ActionBar button if immersive fullsc
reen is supported. | 187 // We don't need to show a hide ActionBar button if immersive fullsc
reen is supported. |
| 224 menu.findItem(R.id.actionbar_hide).setVisible(false); | 188 menu.findItem(R.id.actionbar_hide).setVisible(false); |
| 225 | 189 |
| 226 // Although the MenuItems are being created here, they do not have a
ny backing Views yet | 190 // Although the MenuItems are being created here, they do not have a
ny backing Views yet |
| 227 // as those are created just after this method exits. We post an as
ync task to the UI | 191 // as those are created just after this method exits. We post an as
ync task to the UI |
| 228 // thread here so that we can attach our interaction listeners short
ly after the views | 192 // thread here so that we can attach our interaction listeners short
ly after the views |
| 229 // have been created. | 193 // have been created. |
| 230 final Menu menuFinal = menu; | 194 final Menu menuFinal = menu; |
| 231 new Handler().post(new Runnable() { | 195 new Handler().post(new Runnable() { |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 stopActionBarAutoHideTimer(); | 434 stopActionBarAutoHideTimer(); |
| 471 } | 435 } |
| 472 | 436 |
| 473 /** Called whenever an action bar button is pressed. */ | 437 /** Called whenever an action bar button is pressed. */ |
| 474 @Override | 438 @Override |
| 475 public boolean onOptionsItemSelected(MenuItem item) { | 439 public boolean onOptionsItemSelected(MenuItem item) { |
| 476 int id = item.getItemId(); | 440 int id = item.getItemId(); |
| 477 | 441 |
| 478 mActivityLifecycleListener.onActivityOptionsItemSelected(this, item); | 442 mActivityLifecycleListener.onActivityOptionsItemSelected(this, item); |
| 479 | 443 |
| 480 if (id == R.id.actionbar_cardboard) { | |
| 481 onCardboardItemSelected(); | |
| 482 return true; | |
| 483 } | |
| 484 if (id == R.id.actionbar_trackpad_mode) { | 444 if (id == R.id.actionbar_trackpad_mode) { |
| 485 // When the trackpad icon is tapped, we want to switch the input mod
e to touch. | 445 // When the trackpad icon is tapped, we want to switch the input mod
e to touch. |
| 486 setInputMode(InputMode.TOUCH); | 446 setInputMode(InputMode.TOUCH); |
| 487 return true; | 447 return true; |
| 488 } | 448 } |
| 489 if (id == R.id.actionbar_touch_mode) { | 449 if (id == R.id.actionbar_touch_mode) { |
| 490 // When the touch icon is tapped, we want to switch the input mode t
o trackpad. | 450 // When the touch icon is tapped, we want to switch the input mode t
o trackpad. |
| 491 setInputMode(InputMode.TRACKPAD); | 451 setInputMode(InputMode.TRACKPAD); |
| 492 return true; | 452 return true; |
| 493 } | 453 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 if (!mSoftInputVisible && !isActionBarVisible()) { | 518 if (!mSoftInputVisible && !isActionBarVisible()) { |
| 559 hideSystemUi(); | 519 hideSystemUi(); |
| 560 } | 520 } |
| 561 } | 521 } |
| 562 }); | 522 }); |
| 563 } | 523 } |
| 564 } | 524 } |
| 565 }); | 525 }); |
| 566 } | 526 } |
| 567 | 527 |
| 568 private void onCardboardItemSelected() { | |
| 569 if (getPreferences(MODE_PRIVATE).getBoolean(PREFERENCE_CARDBOARD_DIALOG_
SEEN, false)) { | |
| 570 switchToCardboardMode(); | |
| 571 return; | |
| 572 } | |
| 573 | |
| 574 new AlertDialog.Builder(this) | |
| 575 .setTitle(getTitle()) | |
| 576 .setMessage(R.string.cardboard_warning_message) | |
| 577 .setIcon(R.drawable.ic_cardboard) | |
| 578 .setPositiveButton(android.R.string.ok, new DialogInterface.OnCl
ickListener() { | |
| 579 @Override | |
| 580 public void onClick(DialogInterface dialog, int id) { | |
| 581 getPreferences(MODE_PRIVATE) | |
| 582 .edit() | |
| 583 .putBoolean(PREFERENCE_CARDBOARD_DIALOG_SEEN, tr
ue) | |
| 584 .apply(); | |
| 585 switchToCardboardMode(); | |
| 586 } | |
| 587 }) | |
| 588 .setNegativeButton(android.R.string.cancel, new DialogInterface.
OnClickListener() { | |
| 589 @Override | |
| 590 public void onClick(DialogInterface dialog, int id) { | |
| 591 } | |
| 592 }) | |
| 593 .create() | |
| 594 .show(); | |
| 595 } | |
| 596 | |
| 597 private void switchToCardboardMode() { | |
| 598 mSwitchToCardboardDesktopActivity = true; | |
| 599 Intent intent = new Intent(this, DesktopActivity.class); | |
| 600 startActivityForResult(intent, Chromoting.CARDBOARD_DESKTOP_ACTIVITY); | |
| 601 } | |
| 602 | |
| 603 /** | 528 /** |
| 604 * Called once when a keyboard key is pressed, then again when that same key
is released. This | 529 * Called once when a keyboard key is pressed, then again when that same key
is released. This |
| 605 * is not guaranteed to be notified of all soft keyboard events: certian key
boards might not | 530 * is not guaranteed to be notified of all soft keyboard events: certian key
boards might not |
| 606 * call it at all, while others might skip it in certain situations (e.g. sw
ipe input). | 531 * call it at all, while others might skip it in certain situations (e.g. sw
ipe input). |
| 607 */ | 532 */ |
| 608 @Override | 533 @Override |
| 609 public boolean dispatchKeyEvent(KeyEvent event) { | 534 public boolean dispatchKeyEvent(KeyEvent event) { |
| 610 if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { | 535 if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { |
| 611 mClient.destroy(); | 536 mClient.destroy(); |
| 612 return super.dispatchKeyEvent(event); | 537 return super.dispatchKeyEvent(event); |
| 613 } | 538 } |
| 614 | 539 |
| 615 return mInjector.sendKeyEvent(event); | 540 return mInjector.sendKeyEvent(event); |
| 616 } | 541 } |
| 617 } | 542 } |
| OLD | NEW |