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

Unified Diff: remoting/host/win/rdp_client_window.cc

Issue 2600623002: Adding retry logic for applying desktop resolution changes to RDP session. (Closed)
Patch Set: Merging with ToT Created 4 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « remoting/host/win/rdp_client_window.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/host/win/rdp_client_window.cc
diff --git a/remoting/host/win/rdp_client_window.cc b/remoting/host/win/rdp_client_window.cc
index 47a50b30f92e66fc9ea7fc82ee70d079286b58e1..aab871de4248ce205c10eb16666276d01c7253c4 100644
--- a/remoting/host/win/rdp_client_window.cc
+++ b/remoting/host/win/rdp_client_window.cc
@@ -8,7 +8,9 @@
#include <list>
+#include "base/bind.h"
#include "base/lazy_instance.h"
+#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string16.h"
@@ -36,6 +38,12 @@ constexpr BYTE kKeyPressedFlag = 0x80;
constexpr int kKeyboardStateLength = 256;
+constexpr base::TimeDelta kReapplyResolutionPeriod =
+ base::TimeDelta::FromMilliseconds(250);
+
+// We want to try to reapply resolution changes for ~5 seconds (20 * 250ms).
+constexpr int kMaxResolutionReapplyAttempts = 20;
+
// The RDP control creates 'IHWindowClass' window to handle keyboard input.
constexpr wchar_t kRdpInputWindowClass[] = L"IHWindowClass";
@@ -215,8 +223,14 @@ void RdpClientWindow::InjectSas() {
}
void RdpClientWindow::ChangeResolution(const ScreenResolution& resolution) {
+ // Stop any pending resolution changes.
+ apply_resolution_timer_.Stop();
screen_resolution_ = resolution;
- UpdateDesktopResolution();
+ HRESULT result = UpdateDesktopResolution();
+ if (FAILED(result)) {
+ LOG(ERROR) << "UpdateSessionDisplaySettings() failed: 0x" << std::hex
+ << result << std::dec;
Sergey Ulanov 2016/12/27 21:16:13 I don't think you need std::dec here. Each LOG() c
joedow 2017/01/04 15:47:44 Done.
+ }
}
void RdpClientWindow::OnClose() {
@@ -390,6 +404,7 @@ void RdpClientWindow::OnDestroy() {
client_.Release();
client_9_.Release();
client_settings_.Release();
+ apply_resolution_timer_.Stop();
}
HRESULT RdpClientWindow::OnAuthenticationWarningDisplayed() {
@@ -421,8 +436,14 @@ HRESULT RdpClientWindow::OnLoginComplete() {
user_logged_in_ = true;
- // Apply pending screen size changes to the desktop.
- UpdateDesktopResolution();
+ // Set up a timer to apply pending screen size changes to the desktop after a
+ // brief timeout. Attempting to set the resolution now seems to fail
+ // consistently, but succeeds after a brief timeout.
+ if (client_9_) {
+ apply_resolution_timer_.Start(FROM_HERE,
+ kReapplyResolutionPeriod,
+ base::Bind(&RdpClientWindow::ReapplyDesktopResolution, this, 0));
+ }
return S_OK;
}
@@ -502,9 +523,9 @@ void RdpClientWindow::NotifyDisconnected() {
}
}
-void RdpClientWindow::UpdateDesktopResolution() {
+HRESULT RdpClientWindow::UpdateDesktopResolution() {
if (!client_9_ || !user_logged_in_) {
- return;
+ return S_FALSE;
}
// UpdateSessionDisplaySettings() is poorly documented in MSDN and has a few
@@ -512,8 +533,7 @@ void RdpClientWindow::UpdateDesktopResolution() {
// 1.) This method will only work when the user is logged into their session.
// 2.) The method may return E_UNEXPECTED until some amount of time (seconds)
// have elapsed after logging in to the user's session.
- // TODO(joedow): Investigate adding retry logic for applying the settings.
- HRESULT result = client_9_->UpdateSessionDisplaySettings(
+ return client_9_->UpdateSessionDisplaySettings(
screen_resolution_.dimensions().width(),
screen_resolution_.dimensions().height(),
screen_resolution_.dimensions().width(),
@@ -521,9 +541,27 @@ void RdpClientWindow::UpdateDesktopResolution() {
/*ulOrientation=*/0,
screen_resolution_.dpi().x(),
screen_resolution_.dpi().y());
+}
+
+void RdpClientWindow::ReapplyDesktopResolution(int attempt_count) {
+ if (attempt_count > kMaxResolutionReapplyAttempts) {
Sergey Ulanov 2016/12/27 21:16:13 Maybe just don't post the task after kMaxResolutio
joedow 2017/01/04 15:47:44 Done.
+ LOG(WARNING) << "Unable to apply desktop resolution changes.";
+ return;
+ }
+
+ HRESULT result = UpdateDesktopResolution();
if (FAILED(result)) {
- LOG(ERROR) << "UpdateSessionDisplaySettings() failed: 0x" << std::hex
- << result << std::dec;
+ // Only log errors on the last attempt to reduce log spam since a few errors
+ // can be expected and don't signal an actual failure.
+ if (attempt_count == kMaxResolutionReapplyAttempts) {
+ LOG(ERROR) << "UpdateSessionDisplaySettings() failed: 0x" << std::hex
+ << result << std::dec;
+ }
+
+ apply_resolution_timer_.Start(FROM_HERE,
Sergey Ulanov 2016/12/27 21:16:13 It may be easier to start a repeating timer and th
joedow 2017/01/04 15:47:44 I think that's a good call. I've updated it to us
+ kReapplyResolutionPeriod,
+ base::Bind(&RdpClientWindow::ReapplyDesktopResolution, this,
+ attempt_count + 1));
}
}
« no previous file with comments | « remoting/host/win/rdp_client_window.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698