| 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.app.ProgressDialog; | 9 import android.app.ProgressDialog; |
| 10 import android.content.DialogInterface; | 10 import android.content.DialogInterface; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 | 71 |
| 72 /** Helper for fetching the host list. */ | 72 /** Helper for fetching the host list. */ |
| 73 private HostListLoader mHostListLoader; | 73 private HostListLoader mHostListLoader; |
| 74 | 74 |
| 75 /** List of hosts. */ | 75 /** List of hosts. */ |
| 76 private HostInfo[] mHosts = new HostInfo[0]; | 76 private HostInfo[] mHosts = new HostInfo[0]; |
| 77 | 77 |
| 78 /** Refresh button. */ | 78 /** Refresh button. */ |
| 79 private MenuItem mRefreshButton; | 79 private MenuItem mRefreshButton; |
| 80 | 80 |
| 81 /** Host list as it appears to the user. */ | 81 /** Host list chooser view shown when at least one host is configured. */ |
| 82 private ListView mHostListView; | 82 private ListView mHostListView; |
| 83 | 83 |
| 84 /** View shown when the user has no configured hosts or host list couldn't b
e retrieved. */ |
| 85 private View mEmptyView; |
| 86 |
| 84 /** Progress view shown instead of the host list when the host list is loadi
ng. */ | 87 /** Progress view shown instead of the host list when the host list is loadi
ng. */ |
| 85 private View mProgressView; | 88 private View mProgressView; |
| 86 | 89 |
| 87 /** Dialog for reporting connection progress. */ | 90 /** Dialog for reporting connection progress. */ |
| 88 private ProgressDialog mProgressIndicator; | 91 private ProgressDialog mProgressIndicator; |
| 89 | 92 |
| 90 /** | 93 /** |
| 91 * Helper used by SessionConnection for session authentication. Receives onN
ewIntent() | 94 * Helper used by SessionConnection for session authentication. Receives onN
ewIntent() |
| 92 * notifications to handle third-party authentication. | 95 * notifications to handle third-party authentication. |
| 93 */ | 96 */ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 @Override | 144 @Override |
| 142 public void onCancel(DialogInterface dialog) { | 145 public void onCancel(DialogInterface dialog) { |
| 143 finish(); | 146 finish(); |
| 144 } | 147 } |
| 145 }); | 148 }); |
| 146 | 149 |
| 147 AlertDialog dialog = builder.create(); | 150 AlertDialog dialog = builder.create(); |
| 148 dialog.show(); | 151 dialog.show(); |
| 149 } | 152 } |
| 150 | 153 |
| 151 /** Shows or hides the progress indicator for loading the host list. */ | 154 /** |
| 152 private void setHostListProgressVisible(boolean visible) { | 155 * Displays the loading indicator. Currently this also hides the host list,
but that may |
| 153 mHostListView.setVisibility(visible ? View.GONE : View.VISIBLE); | 156 * change. |
| 154 mProgressView.setVisibility(visible ? View.VISIBLE : View.GONE); | 157 */ |
| 155 | 158 private void showHostListLoadingIndicator() { |
| 156 // Hiding the host-list does not automatically hide the empty view, so d
o that here. | 159 mHostListView.setVisibility(View.GONE); |
| 157 if (visible) { | 160 mEmptyView.setVisibility(View.GONE); |
| 158 mHostListView.getEmptyView().setVisibility(View.GONE); | 161 mProgressView.setVisibility(View.VISIBLE); |
| 159 } | |
| 160 } | 162 } |
| 161 | 163 |
| 162 /** | 164 /** |
| 165 * Shows the appropriate view for the host list and hides the loading indica
tor. Shows either |
| 166 * the host list chooser or the host list empty view, depending on whether m
Hosts contains any |
| 167 * hosts. |
| 168 */ |
| 169 private void updateHostListView() { |
| 170 mHostListView.setVisibility(mHosts.length == 0 ? View.GONE : View.VISIBL
E); |
| 171 mEmptyView.setVisibility(mHosts.length == 0 ? View.VISIBLE : View.GONE); |
| 172 mProgressView.setVisibility(View.GONE); |
| 173 } |
| 174 |
| 175 /** |
| 163 * Called when the activity is first created. Loads the native library and r
equests an | 176 * Called when the activity is first created. Loads the native library and r
equests an |
| 164 * authentication token from the system. | 177 * authentication token from the system. |
| 165 */ | 178 */ |
| 166 @Override | 179 @Override |
| 167 public void onCreate(Bundle savedInstanceState) { | 180 public void onCreate(Bundle savedInstanceState) { |
| 168 super.onCreate(savedInstanceState); | 181 super.onCreate(savedInstanceState); |
| 169 setContentView(R.layout.main); | 182 setContentView(R.layout.main); |
| 170 | 183 |
| 171 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); | 184 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); |
| 172 setSupportActionBar(toolbar); | 185 setSupportActionBar(toolbar); |
| 173 | 186 |
| 174 mTriedNewAuthToken = false; | 187 mTriedNewAuthToken = false; |
| 175 mHostListLoader = new HostListLoader(); | 188 mHostListLoader = new HostListLoader(); |
| 176 | 189 |
| 177 // Get ahold of our view widgets. | 190 // Get ahold of our view widgets. |
| 178 mHostListView = (ListView) findViewById(R.id.hostList_chooser); | 191 mHostListView = (ListView) findViewById(R.id.hostList_chooser); |
| 179 mHostListView.setEmptyView(findViewById(R.id.hostList_empty)); | 192 mEmptyView = findViewById(R.id.hostList_empty); |
| 180 mHostListView.setOnItemClickListener( | 193 mHostListView.setOnItemClickListener( |
| 181 new AdapterView.OnItemClickListener() { | 194 new AdapterView.OnItemClickListener() { |
| 182 @Override | 195 @Override |
| 183 public void onItemClick(AdapterView<?> parent, View view, in
t position, | 196 public void onItemClick(AdapterView<?> parent, View view, in
t position, |
| 184 long id) { | 197 long id) { |
| 185 onHostClicked(position); | 198 onHostClicked(position); |
| 186 } | 199 } |
| 187 }); | 200 }); |
| 188 | 201 |
| 189 mProgressView = findViewById(R.id.hostList_progress); | 202 mProgressView = findViewById(R.id.hostList_progress); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 mAccountSwitcher.onActivityResult(requestCode, resultCode, data); | 358 mAccountSwitcher.onActivityResult(requestCode, resultCode, data); |
| 346 | 359 |
| 347 if (requestCode == OAuthTokenFetcher.REQUEST_CODE_RECOVER_FROM_OAUTH_ERR
OR) { | 360 if (requestCode == OAuthTokenFetcher.REQUEST_CODE_RECOVER_FROM_OAUTH_ERR
OR) { |
| 348 if (resultCode == RESULT_OK) { | 361 if (resultCode == RESULT_OK) { |
| 349 // User gave OAuth permission to this app (or recovered from any
OAuth failure), | 362 // User gave OAuth permission to this app (or recovered from any
OAuth failure), |
| 350 // so retry fetching the token. | 363 // so retry fetching the token. |
| 351 requestAuthToken(false); | 364 requestAuthToken(false); |
| 352 } else { | 365 } else { |
| 353 // User denied permission or cancelled the dialog, so cancel the
request. | 366 // User denied permission or cancelled the dialog, so cancel the
request. |
| 354 mWaitingForAuthToken = false; | 367 mWaitingForAuthToken = false; |
| 355 setHostListProgressVisible(false); | 368 updateHostListView(); |
| 356 } | 369 } |
| 357 } | 370 } |
| 358 } | 371 } |
| 359 | 372 |
| 360 /** Called when a permissions request has returned. */ | 373 /** Called when a permissions request has returned. */ |
| 361 @Override | 374 @Override |
| 362 public void onRequestPermissionsResult(int requestCode, String[] permissions
, | 375 public void onRequestPermissionsResult(int requestCode, String[] permissions
, |
| 363 int[] grantResults) { | 376 int[] grantResults) { |
| 364 // This is currently only used by AccountSwitcherBasic. | 377 // This is currently only used by AccountSwitcherBasic. |
| 365 // Check that the user has granted the needed permission, and reload the
accounts. | 378 // Check that the user has granted the needed permission, and reload the
accounts. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 mAuthenticator = new SessionAuthenticator(this, host); | 459 mAuthenticator = new SessionAuthenticator(this, host); |
| 447 connector.connectToHost(mAccount, mToken, host, mAuthenticator); | 460 connector.connectToHost(mAccount, mToken, host, mAuthenticator); |
| 448 } | 461 } |
| 449 | 462 |
| 450 private void refreshHostList() { | 463 private void refreshHostList() { |
| 451 if (mWaitingForAuthToken) { | 464 if (mWaitingForAuthToken) { |
| 452 return; | 465 return; |
| 453 } | 466 } |
| 454 | 467 |
| 455 mTriedNewAuthToken = false; | 468 mTriedNewAuthToken = false; |
| 456 setHostListProgressVisible(true); | 469 showHostListLoadingIndicator(); |
| 457 | 470 |
| 458 // The refresh button simply makes use of the currently-chosen account. | 471 // The refresh button simply makes use of the currently-chosen account. |
| 459 requestAuthToken(false); | 472 requestAuthToken(false); |
| 460 } | 473 } |
| 461 | 474 |
| 462 private void requestAuthToken(boolean expireCurrentToken) { | 475 private void requestAuthToken(boolean expireCurrentToken) { |
| 463 mWaitingForAuthToken = true; | 476 mWaitingForAuthToken = true; |
| 464 | 477 |
| 465 OAuthTokenFetcher fetcher = new OAuthTokenFetcher(this, mAccount, | 478 OAuthTokenFetcher fetcher = new OAuthTokenFetcher(this, mAccount, |
| 466 new OAuthTokenFetcher.Callback() { | 479 new OAuthTokenFetcher.Callback() { |
| 467 @Override | 480 @Override |
| 468 public void onTokenFetched(String token) { | 481 public void onTokenFetched(String token) { |
| 469 mWaitingForAuthToken = false; | 482 mWaitingForAuthToken = false; |
| 470 mToken = token; | 483 mToken = token; |
| 471 mHostListLoader.retrieveHostList(mToken, Chromoting.this
); | 484 mHostListLoader.retrieveHostList(mToken, Chromoting.this
); |
| 472 } | 485 } |
| 473 | 486 |
| 474 @Override | 487 @Override |
| 475 public void onError(int errorResource) { | 488 public void onError(int errorResource) { |
| 476 mWaitingForAuthToken = false; | 489 mWaitingForAuthToken = false; |
| 477 setHostListProgressVisible(false); | 490 updateHostListView(); |
| 478 String explanation = getString(errorResource); | 491 String explanation = getString(errorResource); |
| 479 Toast.makeText(Chromoting.this, explanation, Toast.LENGT
H_LONG).show(); | 492 Toast.makeText(Chromoting.this, explanation, Toast.LENGT
H_LONG).show(); |
| 480 } | 493 } |
| 481 }); | 494 }); |
| 482 | 495 |
| 483 if (expireCurrentToken) { | 496 if (expireCurrentToken) { |
| 484 fetcher.clearAndFetch(mToken); | 497 fetcher.clearAndFetch(mToken); |
| 485 mToken = null; | 498 mToken = null; |
| 486 } else { | 499 } else { |
| 487 fetcher.fetch(); | 500 fetcher.fetch(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 506 @Override | 519 @Override |
| 507 public void onRequestCloseDrawer() { | 520 public void onRequestCloseDrawer() { |
| 508 mDrawerLayout.closeDrawers(); | 521 mDrawerLayout.closeDrawers(); |
| 509 } | 522 } |
| 510 | 523 |
| 511 @Override | 524 @Override |
| 512 public void onHostListReceived(HostInfo[] hosts) { | 525 public void onHostListReceived(HostInfo[] hosts) { |
| 513 // Store a copy of the array, so that it can't be mutated by the HostLis
tLoader. HostInfo | 526 // Store a copy of the array, so that it can't be mutated by the HostLis
tLoader. HostInfo |
| 514 // is an immutable type, so a shallow copy of the array is sufficient he
re. | 527 // is an immutable type, so a shallow copy of the array is sufficient he
re. |
| 515 mHosts = Arrays.copyOf(hosts, hosts.length); | 528 mHosts = Arrays.copyOf(hosts, hosts.length); |
| 516 setHostListProgressVisible(false); | 529 updateHostListView(); |
| 517 updateUi(); | 530 updateUi(); |
| 518 } | 531 } |
| 519 | 532 |
| 520 @Override | 533 @Override |
| 521 public void onError(HostListLoader.Error error) { | 534 public void onError(HostListLoader.Error error) { |
| 522 String explanation = null; | 535 String explanation = null; |
| 523 switch (error) { | 536 switch (error) { |
| 524 case AUTH_FAILED: | 537 case AUTH_FAILED: |
| 525 break; | 538 break; |
| 526 case NETWORK_ERROR: | 539 case NETWORK_ERROR: |
| 527 explanation = getString(R.string.error_network_error); | 540 explanation = getString(R.string.error_network_error); |
| 528 break; | 541 break; |
| 529 case UNEXPECTED_RESPONSE: | 542 case UNEXPECTED_RESPONSE: |
| 530 case SERVICE_UNAVAILABLE: | 543 case SERVICE_UNAVAILABLE: |
| 531 case UNKNOWN: | 544 case UNKNOWN: |
| 532 explanation = getString(R.string.error_unexpected); | 545 explanation = getString(R.string.error_unexpected); |
| 533 break; | 546 break; |
| 534 default: | 547 default: |
| 535 // Unreachable. | 548 // Unreachable. |
| 536 return; | 549 return; |
| 537 } | 550 } |
| 538 | 551 |
| 539 if (explanation != null) { | 552 if (explanation != null) { |
| 540 Toast.makeText(this, explanation, Toast.LENGTH_LONG).show(); | 553 Toast.makeText(this, explanation, Toast.LENGTH_LONG).show(); |
| 541 setHostListProgressVisible(false); | 554 updateHostListView(); |
| 542 return; | 555 return; |
| 543 } | 556 } |
| 544 | 557 |
| 545 // This is the AUTH_FAILED case. | 558 // This is the AUTH_FAILED case. |
| 546 | 559 |
| 547 if (!mTriedNewAuthToken) { | 560 if (!mTriedNewAuthToken) { |
| 548 // This was our first connection attempt. | 561 // This was our first connection attempt. |
| 549 mTriedNewAuthToken = true; | 562 mTriedNewAuthToken = true; |
| 550 requestAuthToken(true); | 563 requestAuthToken(true); |
| 551 | 564 |
| 552 // We're not in an error state *yet*. | 565 // We're not in an error state *yet*. |
| 553 return; | 566 return; |
| 554 } else { | 567 } else { |
| 555 // Authentication truly failed. | 568 // Authentication truly failed. |
| 556 Log.e(TAG, "Fresh auth token was rejected."); | 569 Log.e(TAG, "Fresh auth token was rejected."); |
| 557 explanation = getString(R.string.error_authentication_failed); | 570 explanation = getString(R.string.error_authentication_failed); |
| 558 Toast.makeText(this, explanation, Toast.LENGTH_LONG).show(); | 571 Toast.makeText(this, explanation, Toast.LENGTH_LONG).show(); |
| 559 setHostListProgressVisible(false); | 572 updateHostListView(); |
| 560 } | 573 } |
| 561 } | 574 } |
| 562 | 575 |
| 563 /** | 576 /** |
| 564 * Updates the infotext and host list display. | 577 * Updates the infotext and host list display. |
| 565 */ | 578 */ |
| 566 private void updateUi() { | 579 private void updateUi() { |
| 567 if (mRefreshButton != null) { | 580 if (mRefreshButton != null) { |
| 568 mRefreshButton.setEnabled(mAccount != null); | 581 mRefreshButton.setEnabled(mAccount != null); |
| 569 } | 582 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 // Unreachable, but required by Google Java style and findbugs. | 619 // Unreachable, but required by Google Java style and findbugs. |
| 607 assert false : "Unreached"; | 620 assert false : "Unreached"; |
| 608 } | 621 } |
| 609 | 622 |
| 610 if (dismissProgress && mProgressIndicator != null) { | 623 if (dismissProgress && mProgressIndicator != null) { |
| 611 mProgressIndicator.dismiss(); | 624 mProgressIndicator.dismiss(); |
| 612 mProgressIndicator = null; | 625 mProgressIndicator = null; |
| 613 } | 626 } |
| 614 } | 627 } |
| 615 } | 628 } |
| OLD | NEW |